/* Library interface to C++ front end.
   Copyright (C) 2014-2021 Free Software Foundation, Inc.

   This file is part of GCC.  As it interacts with GDB through libcc1,
   they all become a single program as regards the GNU GPL's requirements.

   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 "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 "cp-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 "decl.h"
#include "function.h"
#undef cfun // we want to assign to it, and function.h won't let us

#include "callbacks.hh"
#include "connection.hh"
#include "marshall-cp.hh"
#include "rpc.hh"
#include "context.hh"

#include <vector>

using namespace cc1_plugin;



static_assert (GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END,
	       "GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END");



static void
plugin_binding_oracle (enum cp_oracle_request kind, tree identifier)
{
  enum gcc_cp_oracle_request request;

  gcc_assert (current_context != NULL);

  switch (kind)
    {
    case CP_ORACLE_IDENTIFIER:
      request = GCC_CP_ORACLE_IDENTIFIER;
      break;
    default:
      abort ();
    }

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

static int push_count;

/* at_function_scope_p () tests cfun, indicating we're actually
   compiling the function, but we don't even set it when pretending to
   enter a function scope.  We use this distinction to tell these two
   cases apart: we don't want to define e.g. class names in the user
   expression function's scope, when they're local to the original
   function, because they'd get the wrong linkage name.  */

static bool
at_fake_function_scope_p ()
{
  return (!cfun || cfun->decl != current_function_decl)
    && current_scope () == current_function_decl;
}

static void
push_fake_function (tree fndecl, scope_kind kind = sk_function_parms)
{
  current_function_decl = fndecl;
  begin_scope (kind, fndecl);
  ++function_depth;
  begin_scope (sk_block, NULL);
}

static void
pop_scope ()
{
  if (toplevel_bindings_p () && current_namespace == global_namespace)
    pop_from_top_level ();
  else if (at_namespace_scope_p ())
    pop_namespace ();
  else if (at_class_scope_p ())
    popclass ();
  else
    {
      gcc_assert (at_fake_function_scope_p ());
      gcc_assert (!at_function_scope_p ());
      gcc_assert (current_binding_level->kind == sk_block
		  && current_binding_level->this_entity == NULL);
      leave_scope ();
      --function_depth;
      gcc_assert (current_binding_level->this_entity
		  == current_function_decl);
      leave_scope ();
      current_function_decl = NULL;
      for (cp_binding_level *scope = current_binding_level;
	   scope; scope = scope->level_chain)
	if (scope->kind == sk_function_parms)
	  {
	    current_function_decl = scope->this_entity;
	    break;
	  }
    }
}

static void
supplement_binding (cxx_binding *binding, tree decl)
{
  /* FIXME: this is pretty much a copy of supplement_binding_1 in
     ../gcc/cp/name-lookup.c; the few replaced/removed bits are marked
     with "// _1:".  */
  tree bval = binding->value;
  bool ok = true;
  tree target_bval = strip_using_decl (bval);
  tree target_decl = strip_using_decl (decl);

  if (TREE_CODE (target_decl) == TYPE_DECL && DECL_ARTIFICIAL (target_decl)
      && target_decl != target_bval
      && (TREE_CODE (target_bval) != TYPE_DECL
	  /* We allow pushing an enum multiple times in a class
	     template in order to handle late matching of underlying
	     type on an opaque-enum-declaration followed by an
	     enum-specifier.  */
	  || (processing_template_decl
	      && TREE_CODE (TREE_TYPE (target_decl)) == ENUMERAL_TYPE
	      && TREE_CODE (TREE_TYPE (target_bval)) == ENUMERAL_TYPE
	      && (dependent_type_p (ENUM_UNDERLYING_TYPE
				    (TREE_TYPE (target_decl)))
		  || dependent_type_p (ENUM_UNDERLYING_TYPE
				       (TREE_TYPE (target_bval)))))))
    /* The new name is the type name.  */
    binding->type = decl;
  else if (/* TARGET_BVAL is null when push_class_level_binding moves
	      an inherited type-binding out of the way to make room
	      for a new value binding.  */
	   !target_bval
	   /* TARGET_BVAL is error_mark_node when TARGET_DECL's name
	      has been used in a non-class scope prior declaration.
	      In that case, we should have already issued a
	      diagnostic; for graceful error recovery purpose, pretend
	      this was the intended declaration for that name.  */
	   || target_bval == error_mark_node
	   /* If TARGET_BVAL is anticipated but has not yet been
	      declared, pretend it is not there at all.  */
	   || (TREE_CODE (target_bval) == FUNCTION_DECL
	       && DECL_IS_UNDECLARED_BUILTIN (target_bval)))
    binding->value = decl;
  else if (TREE_CODE (target_bval) == TYPE_DECL
	   && DECL_ARTIFICIAL (target_bval)
	   && target_decl != target_bval
	   && (TREE_CODE (target_decl) != TYPE_DECL
	       || same_type_p (TREE_TYPE (target_decl),
			       TREE_TYPE (target_bval))))
    {
      /* The old binding was a type name.  It was placed in
	 VALUE field because it was thought, at the point it was
	 declared, to be the only entity with such a name.  Move the
	 type name into the type slot; it is now hidden by the new
	 binding.  */
      binding->type = bval;
      binding->value = decl;
      binding->value_is_inherited = false;
    }
  else if (TREE_CODE (target_bval) == TYPE_DECL
	   && TREE_CODE (target_decl) == TYPE_DECL
	   && DECL_NAME (target_decl) == DECL_NAME (target_bval)
	   && binding->scope->kind != sk_class
	   && (same_type_p (TREE_TYPE (target_decl), TREE_TYPE (target_bval))
	       /* If either type involves template parameters, we must
		  wait until instantiation.  */
	       || uses_template_parms (TREE_TYPE (target_decl))
	       || uses_template_parms (TREE_TYPE (target_bval))))
    /* We have two typedef-names, both naming the same type to have
       the same name.  In general, this is OK because of:

	 [dcl.typedef]

	 In a given scope, a typedef specifier can be used to redefine
	 the name of any type declared in that scope to refer to the
	 type to which it already refers.

       However, in class scopes, this rule does not apply due to the
       stricter language in [class.mem] prohibiting redeclarations of
       members.  */
    ok = false;
  /* There can be two block-scope declarations of the same variable,
     so long as they are `extern' declarations.  However, there cannot
     be two declarations of the same static data member:

       [class.mem]

       A member shall not be declared twice in the
       member-specification.  */
  else if (VAR_P (target_decl)
	   && VAR_P (target_bval)
	   && DECL_EXTERNAL (target_decl) && DECL_EXTERNAL (target_bval)
	   && !DECL_CLASS_SCOPE_P (target_decl))
    {
      duplicate_decls (decl, binding->value);
      ok = false;
    }
  else if (TREE_CODE (decl) == NAMESPACE_DECL
	   && TREE_CODE (bval) == NAMESPACE_DECL
	   && DECL_NAMESPACE_ALIAS (decl)
	   && DECL_NAMESPACE_ALIAS (bval)
	   && ORIGINAL_NAMESPACE (bval) == ORIGINAL_NAMESPACE (decl))
    /* [namespace.alias]

      In a declarative region, a namespace-alias-definition can be
      used to redefine a namespace-alias declared in that declarative
      region to refer only to the namespace to which it already
      refers.  */
    ok = false;
  else
    {
      // _1: diagnose_name_conflict (decl, bval);
      ok = false;
    }

  gcc_assert (ok); // _1: return ok;
}

static void
reactivate_decl (tree decl, cp_binding_level *b)
{
  bool in_function_p = TREE_CODE (b->this_entity) == FUNCTION_DECL;
  gcc_assert (in_function_p
	      || (b == current_binding_level
		  && !at_class_scope_p ()));

  tree id = DECL_NAME (decl);
  tree type = NULL_TREE;
  if (TREE_CODE (decl) == TYPE_DECL)
    type = TREE_TYPE (decl);

  if (type && TYPE_NAME (type) == decl
      && (RECORD_OR_UNION_CODE_P (TREE_CODE (type))
	  || TREE_CODE (type) == ENUMERAL_TYPE))
    {
      gcc_assert (in_function_p && DECL_CONTEXT (decl) == b->this_entity);
      type = TREE_TYPE (decl);
    }
  else
    {
      gcc_assert (DECL_CONTEXT (decl) == b->this_entity
		  || DECL_CONTEXT (decl) == global_namespace
		  || TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL);
      type = NULL_TREE;
    }

  /* Adjust IDENTIFIER_BINDING to what it would have been if we were
     at binding level B.  Save the binding chain up to that point in
     [binding, *chainp), and take note of the outermost bindings found
     before B.  */
  cxx_binding *binding = IDENTIFIER_BINDING (id), **chainp = NULL;
  tree *shadowing_type_p = NULL;
  if (binding)
    {
      cp_binding_level *bc = current_binding_level;
      for (cxx_binding *prev_binding = binding;
	   prev_binding; prev_binding = prev_binding->previous)
	{
	  while (bc != b && bc != prev_binding->scope)
	    bc = bc->level_chain;
	  if (bc == b)
	    {
	      if (!chainp)
		binding = NULL;
	      break;
	    }
	  chainp = &prev_binding->previous;
	  if (type)
	    for (tree tshadow = prev_binding->scope->type_shadowed;
		 tshadow; tshadow = TREE_CHAIN (tshadow))
	      if (TREE_PURPOSE (tshadow) == id)
		{
		  shadowing_type_p = &TREE_VALUE (tshadow);
		  break;
		}
	}
    }
  if (chainp)
    {
      IDENTIFIER_BINDING (id) = *chainp;
      *chainp = NULL;
    }

  /* Like push_local_binding, supplement or add a binding to the
     desired level.  */
  if (IDENTIFIER_BINDING (id) && IDENTIFIER_BINDING (id)->scope == b)
    supplement_binding (IDENTIFIER_BINDING (id), decl);
  else
    push_binding (id, decl, b);

  /* Now restore the binding chain we'd temporarily removed.  */
  if (chainp)
    {
      *chainp = IDENTIFIER_BINDING (id);
      IDENTIFIER_BINDING (id) = binding;

      if (type)
	{
	  /* Insert the new type binding in the shadowing_type_p
	     TREE_VALUE chain.  */
	  tree shadowed_type = NULL_TREE;
	  if (shadowing_type_p)
	    {
	      shadowed_type = *shadowing_type_p;
	      *shadowing_type_p = type;
	    }

	  b->type_shadowed = tree_cons (id, shadowed_type, b->type_shadowed);
	  TREE_TYPE (b->type_shadowed) = type;
	}
    }
  else if (type)
    {
      /* Our new binding is the active one, so shadow the earlier
	 binding.  */
      b->type_shadowed = tree_cons (id, REAL_IDENTIFIER_TYPE_VALUE (id),
				    b->type_shadowed);
      TREE_TYPE (b->type_shadowed) = type;
      SET_IDENTIFIER_TYPE_VALUE (id, type);
    }

  /* Record that we have a binding for ID, like add_decl_to_level.  */
  tree node = build_tree_list (NULL_TREE, decl);
  TREE_CHAIN (node) = b->names;
  b->names = node;
}

static void
plugin_pragma_push_user_expression (cpp_reader *)
{
  if (push_count++)
    return;

  gcc_assert (!current_class_ptr);
  gcc_assert (!current_class_ref);

  gcc_assert (!cp_binding_oracle);
  cp_binding_oracle = plugin_binding_oracle;

  /* Make the function containing the user expression a global
     friend, so as to bypass access controls in it.  */
  if (at_function_scope_p ())
    set_global_friend (current_function_decl);

  gcc_assert (at_function_scope_p ());
  function *save_cfun = cfun;
  cp_binding_level *orig_binding_level = current_binding_level;
  {
    int success;
    cc1_plugin::call (current_context, "enter_scope", &success);
  }
  gcc_assert (at_fake_function_scope_p () || at_function_scope_p ());

  function *unchanged_cfun = cfun;
  tree changed_func_decl = current_function_decl;

  gcc_assert (current_class_type == DECL_CONTEXT (current_function_decl)
	      || !(RECORD_OR_UNION_CODE_P
		   (TREE_CODE (DECL_CONTEXT (current_function_decl)))));
  push_fake_function (save_cfun->decl, sk_block);
  current_class_type = NULL_TREE;
  if (unchanged_cfun)
    {
      /* If we get here, GDB did NOT change the context.  */
      gcc_assert (cfun == save_cfun);
      gcc_assert (at_function_scope_p ());
      gcc_assert (orig_binding_level
		  == current_binding_level->level_chain->level_chain);
    }
  else
    {
      cfun = save_cfun;
      gcc_assert (at_function_scope_p ());

      cp_binding_level *b = current_binding_level->level_chain;
      gcc_assert (b->this_entity == cfun->decl);

      /* Reactivate local names from the previous context.  Use
	 IDENTIFIER_MARKED to avoid reactivating shadowed names.  */
      for (cp_binding_level *level = orig_binding_level;;)
	{
	  for (tree name = level->names;
	       name; name = TREE_CHAIN (name))
	    {
	      tree decl = name;
	      if (TREE_CODE (decl) == TREE_LIST)
		decl = TREE_VALUE (decl);
	      if (IDENTIFIER_MARKED (DECL_NAME (decl)))
		continue;
	      IDENTIFIER_MARKED (DECL_NAME (decl)) = 1;
	      reactivate_decl (decl, b);
	    }
	  if (level->kind == sk_function_parms
	      && level->this_entity == cfun->decl)
	    break;
	  gcc_assert (!level->this_entity);
	  level = level->level_chain;
	}

      /* Now, clear the markers.  */
      for (tree name = b->names; name; name = TREE_CHAIN (name))
	{
	  tree decl = name;
	  if (TREE_CODE (decl) == TREE_LIST)
	    decl = TREE_VALUE (decl);
	  gcc_assert (IDENTIFIER_MARKED (DECL_NAME (decl)));
	  IDENTIFIER_MARKED (DECL_NAME (decl)) = 0;
	}
    }

  if (unchanged_cfun || DECL_NONSTATIC_MEMBER_FUNCTION_P (changed_func_decl))
    {
      /* Check whether the oracle supplies us with a "this", and if
	 so, arrange for data members and this itself to be
	 usable.  */
      tree this_val = lookup_name (get_identifier ("this"));
      current_class_ref = !this_val ? NULL_TREE
	: cp_build_indirect_ref (input_location, this_val, RO_NULL,
				 tf_warning_or_error);
      current_class_ptr = this_val;
    }
}

static void
plugin_pragma_pop_user_expression (cpp_reader *)
{
  if (--push_count)
    return;

  gcc_assert (cp_binding_oracle);

  gcc_assert (at_function_scope_p ());
  function *save_cfun = cfun;
  current_class_ptr = NULL_TREE;
  current_class_ref = NULL_TREE;

  cfun = NULL;
  pop_scope ();
  if (RECORD_OR_UNION_CODE_P (TREE_CODE (DECL_CONTEXT (current_function_decl))))
    current_class_type = DECL_CONTEXT (current_function_decl);
  {
    int success;
    cc1_plugin::call (current_context, "leave_scope", &success);
  }
  if (!cfun)
    cfun = save_cfun;
  else
    gcc_assert (cfun == save_cfun);

  cp_binding_oracle = NULL;
  gcc_assert (at_function_scope_p ());
}

static void
plugin_init_extra_pragmas (void *, void *)
{
  c_register_pragma ("GCC", "push_user_expression", plugin_pragma_push_user_expression);
  c_register_pragma ("GCC", "pop_user_expression", plugin_pragma_pop_user_expression);
  /* FIXME: this one should go once we get GDB to use push and pop.  */
  c_register_pragma ("GCC", "user_expression", plugin_pragma_push_user_expression);
}



static decl_addr_value
build_decl_addr_value (tree decl, gcc_address address)
{
  decl_addr_value value = {
    decl,
    build_int_cst_type (ptr_type_node, address)
  };
  return value;
}

static decl_addr_value *
record_decl_address (plugin_context *ctx, decl_addr_value value)
{
  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;
  /* We don't want GCC to warn about e.g. static functions
     without a code definition.  */
  suppress_warning (value.decl);
  return *slot;
}

// 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)
      || TREE_CODE (*in) == NAMESPACE_DECL
      || 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 (HAS_DECL_ASSEMBLER_NAME_P (*in))
    {
      gcc_address address;

      if (!cc1_plugin::call (ctx, "address_oracle", &address,
			     IDENTIFIER_POINTER (DECL_ASSEMBLER_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 = build_decl_addr_value (value.decl, address);
      found_value = record_decl_address (ctx, value);
    }
  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);
}



static inline tree
safe_push_template_decl (tree decl)
{
  void (*save_oracle) (enum cp_oracle_request, tree identifier);

  save_oracle = cp_binding_oracle;
  cp_binding_oracle = NULL;

  tree ret = push_template_decl (decl);

  cp_binding_oracle = save_oracle;

  return ret;
}

static inline tree
safe_pushtag (tree name, tree type)
{
  void (*save_oracle) (enum cp_oracle_request, tree identifier);

  save_oracle = cp_binding_oracle;
  cp_binding_oracle = NULL;

  tree ret = pushtag (name, type);

  cp_binding_oracle = save_oracle;

  return ret;
}

static inline tree
safe_pushdecl (tree decl)
{
  void (*save_oracle) (enum cp_oracle_request, tree identifier);

  save_oracle = cp_binding_oracle;
  cp_binding_oracle = NULL;

  tree ret = pushdecl (decl);

  cp_binding_oracle = save_oracle;

  return ret;
}



int
plugin_push_namespace (cc1_plugin::connection *,
		       const char *name)
{
  if (name && !*name)
    push_to_top_level ();
  else
    push_namespace (name ? get_identifier (name) : NULL);

  return 1;
}

int
plugin_push_class (cc1_plugin::connection *,
		   gcc_type type_in)
{
  tree type = convert_in (type_in);
  gcc_assert (RECORD_OR_UNION_CODE_P (TREE_CODE (type)));
  gcc_assert (TYPE_CONTEXT (type) == FROB_CONTEXT (current_scope ()));

  pushclass (type);

  return 1;
}

int
plugin_push_function (cc1_plugin::connection *,
		      gcc_decl function_decl_in)
{
  tree fndecl = convert_in (function_decl_in);
  gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
  gcc_assert (DECL_CONTEXT (fndecl) == FROB_CONTEXT (current_scope ()));

  push_fake_function (fndecl);

  return 1;
}

int
plugin_pop_binding_level (cc1_plugin::connection *)
{
  pop_scope ();
  return 1;
}

int
plugin_reactivate_decl (cc1_plugin::connection *,
			gcc_decl decl_in,
			gcc_decl scope_in)
{
  tree decl = convert_in (decl_in);
  tree scope = convert_in (scope_in);
  gcc_assert (TREE_CODE (decl) == VAR_DECL
	      || TREE_CODE (decl) == FUNCTION_DECL
	      || TREE_CODE (decl) == TYPE_DECL);
  cp_binding_level *b;
  if (scope)
    {
      gcc_assert (TREE_CODE (scope) == FUNCTION_DECL);
      for (b = current_binding_level;
	   b->this_entity != scope;
	   b = b->level_chain)
	gcc_assert (b->this_entity != global_namespace);
    }
  else
    {
      gcc_assert (!at_class_scope_p ());
      b = current_binding_level;
    }

  reactivate_decl (decl, b);
  return 1;
}

static tree
get_current_scope ()
{
  tree decl;

  if (at_namespace_scope_p ())
    decl = current_namespace;
  else if (at_class_scope_p ())
    decl = TYPE_NAME (current_class_type);
  else if (at_fake_function_scope_p () || at_function_scope_p ())
    decl = current_function_decl;
  else
    gcc_unreachable ();

  return decl;
}

gcc_decl
plugin_get_current_binding_level_decl (cc1_plugin::connection *)
{
  tree decl = get_current_scope ();

  return convert_out (decl);
}

int
plugin_make_namespace_inline (cc1_plugin::connection *)
{
  tree inline_ns = current_namespace;

  gcc_assert (toplevel_bindings_p ());
  gcc_assert (inline_ns != global_namespace);

  tree parent_ns = CP_DECL_CONTEXT (inline_ns);

  if (DECL_NAMESPACE_INLINE_P (inline_ns))
    return 0;

  DECL_NAMESPACE_INLINE_P (inline_ns) = true;
  vec_safe_push (DECL_NAMESPACE_INLINEES (parent_ns), inline_ns);

  return 1;
}

int
plugin_add_using_namespace (cc1_plugin::connection *,
			    gcc_decl used_ns_in)
{
  tree used_ns = convert_in (used_ns_in);

  gcc_assert (TREE_CODE (used_ns) == NAMESPACE_DECL);

  finish_using_directive (used_ns, NULL_TREE);

  return 1;
}

int
plugin_add_namespace_alias (cc1_plugin::connection *,
			    const char *id,
			    gcc_decl target_in)
{
  tree name = get_identifier (id);
  tree target = convert_in (target_in);

  do_namespace_alias (name, target);

  return 1;
}

static inline void
set_access_flags (tree decl, enum gcc_cp_symbol_kind flags)
{
  gcc_assert (!(flags & GCC_CP_ACCESS_MASK) == !DECL_CLASS_SCOPE_P (decl));

  switch (flags & GCC_CP_ACCESS_MASK)
    {
    case GCC_CP_ACCESS_PRIVATE:
      TREE_PRIVATE (decl) = true;
      current_access_specifier = access_private_node;
      break;

    case GCC_CP_ACCESS_PROTECTED:
      TREE_PROTECTED (decl) = true;
      current_access_specifier = access_protected_node;
      break;

    case GCC_CP_ACCESS_PUBLIC:
      current_access_specifier = access_public_node;
      break;

    default:
      break;
    }
}

int
plugin_add_using_decl (cc1_plugin::connection *,
		       enum gcc_cp_symbol_kind flags,
		       gcc_decl target_in)
{
  tree target = convert_in (target_in);
  gcc_assert ((flags & GCC_CP_SYMBOL_MASK) == GCC_CP_SYMBOL_USING);
  gcc_assert (!(flags & GCC_CP_FLAG_MASK));
  enum gcc_cp_symbol_kind acc_flags;
  acc_flags = (enum gcc_cp_symbol_kind) (flags & GCC_CP_ACCESS_MASK);

  gcc_assert (!template_parm_scope_p ());

  bool class_member_p = at_class_scope_p ();
  gcc_assert (!(acc_flags & GCC_CP_ACCESS_MASK) == !class_member_p);

  tree identifier = DECL_NAME (target);
  tree tcontext = DECL_CONTEXT (target);

  if (UNSCOPED_ENUM_P (tcontext))
    tcontext = CP_TYPE_CONTEXT (tcontext);

  if (class_member_p)
    {
      tree decl = do_class_using_decl (tcontext, identifier);

      set_access_flags (decl, flags);

      finish_member_declaration (decl);
    }
  else
    {
      /* We can't be at local scope.  */
      gcc_assert (at_namespace_scope_p ());
      finish_nonmember_using_decl (tcontext, identifier);
    }

  return 1;
}

static tree
build_named_class_type (enum tree_code code,
			tree id,
			location_t loc)
{
  /* See at_fake_function_scope_p.  */
  gcc_assert (!at_function_scope_p ());
  tree type = make_class_type (code);
  tree type_decl = build_decl (loc, TYPE_DECL, id, type);
  TYPE_NAME (type) = type_decl;
  TYPE_STUB_DECL (type) = type_decl;
  DECL_CONTEXT (type_decl) = TYPE_CONTEXT (type);

  return type_decl;
}

/* Abuse an unused field of the dummy template parms entry to hold the
   parm list.  */
#define TP_PARM_LIST TREE_TYPE (current_template_parms)

gcc_decl
plugin_build_decl (cc1_plugin::connection *self,
		   const char *name,
		   enum gcc_cp_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);
  gcc_assert (!name || !strchr (name, ':')); // FIXME: this can go eventually.

  enum tree_code code;
  tree decl;
  tree sym_type = convert_in (sym_type_in);
  enum gcc_cp_symbol_kind sym_flags;
  sym_flags = (enum gcc_cp_symbol_kind) (sym_kind & GCC_CP_FLAG_MASK);
  enum gcc_cp_symbol_kind acc_flags;
  acc_flags = (enum gcc_cp_symbol_kind) (sym_kind & GCC_CP_ACCESS_MASK);
  sym_kind = (enum gcc_cp_symbol_kind) (sym_kind & GCC_CP_SYMBOL_MASK);

  switch (sym_kind)
    {
    case GCC_CP_SYMBOL_FUNCTION:
      code = FUNCTION_DECL;
      gcc_assert (!(sym_flags & ~GCC_CP_FLAG_MASK_FUNCTION));
      break;

    case GCC_CP_SYMBOL_VARIABLE:
      code = VAR_DECL;
      gcc_assert (!(sym_flags & ~GCC_CP_FLAG_MASK_VARIABLE));
      break;

    case GCC_CP_SYMBOL_TYPEDEF:
      code = TYPE_DECL;
      gcc_assert (!sym_flags);
      break;

    case GCC_CP_SYMBOL_CLASS:
      code = RECORD_TYPE;
      gcc_assert (!(sym_flags & ~GCC_CP_FLAG_MASK_CLASS));
      gcc_assert (!sym_type);
      break;

    case GCC_CP_SYMBOL_UNION:
      code = UNION_TYPE;
      gcc_assert (!sym_flags);
      gcc_assert (!sym_type);
      break;

    default:
      gcc_unreachable ();
    }

  bool template_decl_p = template_parm_scope_p ();

  if (template_decl_p)
    {
      gcc_assert (code == FUNCTION_DECL || code == RECORD_TYPE
		  || code == TYPE_DECL);

      /* Finish the template parm list that started this template parm.  */
      end_template_parm_list (TP_PARM_LIST);

      gcc_assert (!address);
      gcc_assert (!substitution_name);
    }

  location_t loc = ctx->get_location_t (filename, line_number);
  bool class_member_p = at_class_scope_p ();
  bool ctor = false, dtor = false, assop = false;
  tree_code opcode = ERROR_MARK;

  gcc_assert (!(acc_flags & GCC_CP_ACCESS_MASK) == !class_member_p);

  tree identifier;
  if (code != FUNCTION_DECL
      || !(sym_flags & GCC_CP_FLAG_SPECIAL_FUNCTION))
    {
      if (name)
	identifier = get_identifier (name);
      else
	{
	  gcc_assert (RECORD_OR_UNION_CODE_P (code));
	  identifier = make_anon_name ();
	}
    }

  if (code == FUNCTION_DECL)
    {
      if (sym_flags & GCC_CP_FLAG_SPECIAL_FUNCTION)
	{
#define CHARS2(f,s) (((unsigned char)f << CHAR_BIT) | (unsigned char)s)
	  switch (CHARS2 (name[0], name[1]))
	    {
	    case CHARS2 ('C', 0x0): // ctor base declaration
	    case CHARS2 ('C', ' '):
	    case CHARS2 ('C', '1'):
	    case CHARS2 ('C', '2'):
	    case CHARS2 ('C', '4'):
	      ctor = true;
	    cdtor:
	      gcc_assert (!address);
	      gcc_assert (!substitution_name);
	      identifier = DECL_NAME (TYPE_NAME (current_class_type));
	      break;
	    case CHARS2 ('D', 0x0): // dtor base declaration
	    case CHARS2 ('D', ' '):
	    case CHARS2 ('D', '0'):
	    case CHARS2 ('D', '1'):
	    case CHARS2 ('D', '2'):
	    case CHARS2 ('D', '4'):
	      gcc_assert (!template_decl_p);
	      dtor = true;
	      goto cdtor;
	    case CHARS2 ('n', 'w'): // operator new
	      opcode = NEW_EXPR;
	      break;
	    case CHARS2 ('n', 'a'): // operator new[]
	      opcode = VEC_NEW_EXPR;
	      break;
	    case CHARS2 ('d', 'l'): // operator delete
	      opcode = DELETE_EXPR;
	      break;
	    case CHARS2 ('d', 'a'): // operator delete[]
	      opcode = VEC_DELETE_EXPR;
	      break;
	    case CHARS2 ('p', 's'): // operator + (unary)
	      opcode = PLUS_EXPR;
	      break;
	    case CHARS2 ('n', 'g'): // operator - (unary)
	      opcode = MINUS_EXPR;
	      break;
	    case CHARS2 ('a', 'd'): // operator & (unary)
	      opcode = BIT_AND_EXPR;
	      break;
	    case CHARS2 ('d', 'e'): // operator * (unary)
	      opcode = MULT_EXPR;
	      break;
	    case CHARS2 ('c', 'o'): // operator ~
	      opcode = BIT_NOT_EXPR;
	      break;
	    case CHARS2 ('p', 'l'): // operator +
	      opcode = PLUS_EXPR;
	      break;
	    case CHARS2 ('m', 'i'): // operator -
	      opcode = MINUS_EXPR;
	      break;
	    case CHARS2 ('m', 'l'): // operator *
	      opcode = MULT_EXPR;
	      break;
	    case CHARS2 ('d', 'v'): // operator /
	      opcode = TRUNC_DIV_EXPR;
	      break;
	    case CHARS2 ('r', 'm'): // operator %
	      opcode = TRUNC_MOD_EXPR;
	      break;
	    case CHARS2 ('a', 'n'): // operator &
	      opcode = BIT_AND_EXPR;
	      break;
	    case CHARS2 ('o', 'r'): // operator |
	      opcode = BIT_IOR_EXPR;
	      break;
	    case CHARS2 ('e', 'o'): // operator ^
	      opcode = BIT_XOR_EXPR;
	      break;
	    case CHARS2 ('a', 'S'): // operator =
	      opcode = NOP_EXPR;
	      assop = true;
	      break;
	    case CHARS2 ('p', 'L'): // operator +=
	      opcode = PLUS_EXPR;
	      assop = true;
	      break;
	    case CHARS2 ('m', 'I'): // operator -=
	      opcode = MINUS_EXPR;
	      assop = true;
	      break;
	    case CHARS2 ('m', 'L'): // operator *=
	      opcode = MULT_EXPR;
	      assop = true;
	      break;
	    case CHARS2 ('d', 'V'): // operator /=
	      opcode = TRUNC_DIV_EXPR;
	      assop = true;
	      break;
	    case CHARS2 ('r', 'M'): // operator %=
	      opcode = TRUNC_MOD_EXPR;
	      assop = true;
	      break;
	    case CHARS2 ('a', 'N'): // operator &=
	      opcode = BIT_AND_EXPR;
	      assop = true;
	      break;
	    case CHARS2 ('o', 'R'): // operator |=
	      opcode = BIT_IOR_EXPR;
	      assop = true;
	      break;
	    case CHARS2 ('e', 'O'): // operator ^=
	      opcode = BIT_XOR_EXPR;
	      assop = true;
	      break;
	    case CHARS2 ('l', 's'): // operator <<
	      opcode = LSHIFT_EXPR;
	      break;
	    case CHARS2 ('r', 's'): // operator >>
	      opcode = RSHIFT_EXPR;
	      break;
	    case CHARS2 ('l', 'S'): // operator <<=
	      opcode = LSHIFT_EXPR;
	      assop = true;
	      break;
	    case CHARS2 ('r', 'S'): // operator >>=
	      opcode = RSHIFT_EXPR;
	      assop = true;
	      break;
	    case CHARS2 ('e', 'q'): // operator ==
	      opcode = EQ_EXPR;
	      break;
	    case CHARS2 ('n', 'e'): // operator !=
	      opcode = NE_EXPR;
	      break;
	    case CHARS2 ('l', 't'): // operator <
	      opcode = LT_EXPR;
	      break;
	    case CHARS2 ('g', 't'): // operator >
	      opcode = GT_EXPR;
	      break;
	    case CHARS2 ('l', 'e'): // operator <=
	      opcode = LE_EXPR;
	      break;
	    case CHARS2 ('g', 'e'): // operator >=
	      opcode = GE_EXPR;
	      break;
	    case CHARS2 ('n', 't'): // operator !
	      opcode = TRUTH_NOT_EXPR;
	      break;
	    case CHARS2 ('a', 'a'): // operator &&
	      opcode = TRUTH_ANDIF_EXPR;
	      break;
	    case CHARS2 ('o', 'o'): // operator ||
	      opcode = TRUTH_ORIF_EXPR;
	      break;
	    case CHARS2 ('p', 'p'): // operator ++
	      opcode = POSTINCREMENT_EXPR;
	      break;
	    case CHARS2 ('m', 'm'): // operator --
	      /* This stands for either one as an operator name, and
		 "pp" and "mm" stand for POST??CREMENT, but for some
		 reason the parser uses this opcode name for
		 operator--; let's follow their practice.  */
	      opcode = PREDECREMENT_EXPR;
	      break;
	    case CHARS2 ('c', 'm'): // operator ,
	      opcode = COMPOUND_EXPR;
	      break;
	    case CHARS2 ('p', 'm'): // operator ->*
	      opcode = MEMBER_REF;
	      break;
	    case CHARS2 ('p', 't'): // operator ->
	      opcode = COMPONENT_REF;
	      break;
	    case CHARS2 ('c', 'l'): // operator ()
	      opcode = CALL_EXPR;
	      break;
	    case CHARS2 ('i', 'x'): // operator []
	      opcode = ARRAY_REF;
	      break;
	    case CHARS2 ('c', 'v'): // operator <T> (conversion operator)
	      identifier = make_conv_op_name (TREE_TYPE (sym_type));
	      break;
	      // C++11-only:
	    case CHARS2 ('l', 'i'): // operator "" <id>
	      {
		char *id = (char *)name + 2;
		bool freeid = false;
		if (*id >= '0' && *id <= '9')
		  {
		    unsigned len = 0;
		    do
		      {
			len *= 10;
			len += id[0] - '0';
			id++;
		      }
		    while (*id && *id >= '0' && *id <= '9');
		    id = xstrndup (id, len);
		    freeid = true;
		  }
		identifier = cp_literal_operator_id (id);
		if (freeid)
		  free (id);
	      }
	      break;
	    case CHARS2 ('q', 'u'): // ternary operator, not overloadable.
	    default:
	      gcc_unreachable ();
	    }

	  if (opcode != ERROR_MARK)
	    identifier = ovl_op_identifier (assop, opcode);
	}
      decl = build_lang_decl_loc (loc, code, identifier, sym_type);
      /* FIXME: current_lang_name is lang_name_c while compiling an
	 extern "C" function, and we haven't switched to a global
	 context at this point, and this breaks function
	 overloading.  */
      SET_DECL_LANGUAGE (decl, lang_cplusplus);
      if (TREE_CODE (sym_type) == METHOD_TYPE)
	DECL_ARGUMENTS (decl) = build_this_parm (decl, current_class_type,
						 cp_type_quals (sym_type));
      for (tree arg = TREE_CODE (sym_type) == METHOD_TYPE
	     ? TREE_CHAIN (TYPE_ARG_TYPES (sym_type))
	     : TYPE_ARG_TYPES (sym_type);
	   arg && arg != void_list_node;
	   arg = TREE_CHAIN (arg))
	{
	  tree parm = cp_build_parm_decl (decl, NULL_TREE, TREE_VALUE (arg));
	  DECL_CHAIN (parm) = DECL_ARGUMENTS (decl);
	  DECL_ARGUMENTS (decl) = parm;
	}
      DECL_ARGUMENTS (decl) = nreverse (DECL_ARGUMENTS (decl));
      if (class_member_p)
	{
	  if (TREE_CODE (sym_type) == FUNCTION_TYPE)
	    DECL_STATIC_FUNCTION_P (decl) = 1;
	  if (sym_flags & GCC_CP_FLAG_VIRTUAL_FUNCTION)
	    {
	      DECL_VIRTUAL_P (decl) = 1;
	      if (sym_flags & GCC_CP_FLAG_PURE_VIRTUAL_FUNCTION)
		DECL_PURE_VIRTUAL_P (decl) = 1;
	      if (sym_flags & GCC_CP_FLAG_FINAL_VIRTUAL_FUNCTION)
		DECL_FINAL_P (decl) = 1;
	    }
	  else
	    gcc_assert (!(sym_flags & (GCC_CP_FLAG_PURE_VIRTUAL_FUNCTION
				       | GCC_CP_FLAG_FINAL_VIRTUAL_FUNCTION)));
	}
      else
	{
	  gcc_assert (!(sym_flags & (GCC_CP_FLAG_VIRTUAL_FUNCTION
				     | GCC_CP_FLAG_PURE_VIRTUAL_FUNCTION
				     | GCC_CP_FLAG_FINAL_VIRTUAL_FUNCTION)));
	  gcc_assert (!ctor && !dtor && !assop);
	}
      if (sym_flags & GCC_CP_FLAG_EXPLICIT_FUNCTION)
	DECL_NONCONVERTING_P (decl) = 1;
      if (sym_flags & GCC_CP_FLAG_DEFAULTED_FUNCTION)
	{
	  DECL_INITIAL (decl) = ridpointers[(int)RID_DEFAULT];
	  DECL_DEFAULTED_FN (decl) = 1;
	}
      if (sym_flags & GCC_CP_FLAG_DELETED_FUNCTION)
	{
	  // DECL_INITIAL (decl) = ridpointers[(int)RID_DELETE];
	  DECL_DELETED_FN (decl) = 1;
	  DECL_DECLARED_INLINE_P (decl) = 1;
	  DECL_INITIAL (decl) = error_mark_node;
	}

      if (ctor)
	DECL_CXX_CONSTRUCTOR_P (decl) = 1;
      else if (dtor)
	DECL_CXX_DESTRUCTOR_P (decl) = 1;
      else if ((sym_flags & GCC_CP_FLAG_SPECIAL_FUNCTION)
	       && opcode != ERROR_MARK)
	DECL_OVERLOADED_OPERATOR_CODE_RAW (decl) = ovl_op_mapping[opcode];
    }
  else if (RECORD_OR_UNION_CODE_P (code))
    {
      decl = build_named_class_type (code, identifier, loc);
      tree type = TREE_TYPE (decl);

      if (code == RECORD_TYPE
	  && !(sym_flags & GCC_CP_FLAG_CLASS_IS_STRUCT))
	CLASSTYPE_DECLARED_CLASS (type) = true;
    }
  else if (class_member_p)
    {
      decl = build_lang_decl_loc (loc, code, identifier, sym_type);

      if (TREE_CODE (decl) == VAR_DECL)
	{
	  DECL_THIS_STATIC (decl) = 1;
	  // The remainder of this block does the same as:
	  // set_linkage_for_static_data_member (decl);
	  TREE_PUBLIC (decl) = 1;
	  TREE_STATIC (decl) = 1;
	  DECL_INTERFACE_KNOWN (decl) = 1;

	  // FIXME: sym_flags & GCC_CP_FLAG_THREAD_LOCAL_VARIABLE
	  gcc_assert (!(sym_flags & GCC_CP_FLAG_THREAD_LOCAL_VARIABLE));

	  if (sym_flags & GCC_CP_FLAG_CONSTEXPR_VARIABLE)
	    DECL_DECLARED_CONSTEXPR_P (decl) = true;
	}
    }
  else
    {
      decl = build_decl (loc, code, identifier, sym_type);

      if (TREE_CODE (decl) == VAR_DECL)
	{
	  // FIXME: sym_flags & GCC_CP_FLAG_THREAD_LOCAL_VARIABLE
	  gcc_assert (!(sym_flags & GCC_CP_FLAG_THREAD_LOCAL_VARIABLE));

	  if (sym_flags & GCC_CP_FLAG_CONSTEXPR_VARIABLE)
	    DECL_DECLARED_CONSTEXPR_P (decl) = true;
	}
    }
  TREE_USED (decl) = 1;
  TREE_ADDRESSABLE (decl) = 1;

  if (class_member_p)
    DECL_CONTEXT (decl) = FROB_CONTEXT (current_class_type);
  else if (at_namespace_scope_p ())
    DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ());

  set_access_flags (decl, acc_flags);

  /* If this is the typedef that names an otherwise anonymous type,
     propagate the typedef name to the type.  In normal compilation,
     this is done in grokdeclarator.  */
  if (sym_kind == GCC_CP_SYMBOL_TYPEDEF
      && !template_decl_p
      && DECL_CONTEXT (decl) == TYPE_CONTEXT (sym_type)
      && TYPE_UNNAMED_P (sym_type))
    name_unnamed_type (sym_type, decl);

  if (sym_kind != GCC_CP_SYMBOL_TYPEDEF
      && sym_kind != GCC_CP_SYMBOL_CLASS
      && sym_kind != GCC_CP_SYMBOL_UNION
      && !template_decl_p && !ctor && !dtor)
    {
      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 if (address)
	value.address = build_int_cst_type (ptr_type_node, address);
      else
	value.address = NULL;
      if (value.address)
	record_decl_address (ctx, value);
    }

  if (class_member_p && code == FUNCTION_DECL)
    {
      if (ctor || dtor)
	maybe_retrofit_in_chrg (decl);

      grok_special_member_properties (decl);
    }

  if (template_decl_p)
    {
      if (RECORD_OR_UNION_CODE_P (code))
	safe_pushtag (identifier, TREE_TYPE (decl));
      else
	decl = safe_push_template_decl (decl);

      tree tdecl = NULL_TREE;
      if (class_member_p)
	tdecl = finish_member_template_decl (decl);

      end_template_decl ();

      /* We only support one level of templates, because we only
	 support declaring generics; actual definitions are only of
	 specializations.  */
      gcc_assert (!template_parm_scope_p ());

      if (class_member_p)
	finish_member_declaration (tdecl);
    }
  else if (RECORD_OR_UNION_CODE_P (code))
    safe_pushtag (identifier, TREE_TYPE (decl));
  else if (class_member_p)
    finish_member_declaration (decl);
  else
    decl = safe_pushdecl (decl);

  if ((ctor || dtor)
      /* Don't crash after a duplicate declaration of a cdtor.  */
      && TYPE_FIELDS (current_class_type) == decl)
    {
      /* ctors and dtors clones are chained after DECL.
	 However, we create the clones before TYPE_METHODS is
	 reversed.  We test for cloned methods after reversal,
	 however, and the test requires the clones to follow
	 DECL.  So, we reverse the chain of clones now, so
	 that it will come out in the right order after
	 reversal.  */
      tree save = DECL_CHAIN (decl);
      DECL_CHAIN (decl) = NULL_TREE;
      clone_cdtor (decl, /*update_methods=*/true);
      gcc_assert (TYPE_FIELDS (current_class_type) == decl);
      TYPE_FIELDS (current_class_type)
	= nreverse (TYPE_FIELDS (current_class_type));
      DECL_CHAIN (decl) = save;
    }

  rest_of_decl_compilation (decl, toplevel_bindings_p (), 0);

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

gcc_decl
plugin_define_cdtor_clone (cc1_plugin::connection *self,
			   const char *name,
			   gcc_decl cdtor_in,
			   gcc_address address)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree decl = convert_in (cdtor_in);
  bool ctor = false;
  bool dtor = false;
  tree identifier;

  switch (CHARS2 (name[0], name[1]))
    {
    case CHARS2 ('C', '1'): // in-charge constructor
      identifier = complete_ctor_identifier;
      ctor = true;
      break;
    case CHARS2 ('C', '2'): // not-in-charge constructor
      identifier = base_ctor_identifier;
      ctor = true;
      break;
    case CHARS2 ('C', '4'):
      identifier = ctor_identifier; // unified constructor
      ctor = true;
      break;
    case CHARS2 ('D', '0'): // deleting destructor
      identifier = deleting_dtor_identifier;
      dtor = true;
      break;
    case CHARS2 ('D', '1'): // in-charge destructor
      identifier = complete_dtor_identifier;
      dtor = true;
      break;
    case CHARS2 ('D', '2'): // not-in-charge destructor
      identifier = base_dtor_identifier;
      dtor = true;
      break;
    case CHARS2 ('D', '4'):
      identifier = dtor_identifier; // unified destructor
      dtor = true;
      break;

    default:
      gcc_unreachable ();
    }

  gcc_assert (!ctor != !dtor);
  gcc_assert (ctor
	      ? (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
		 && DECL_NAME (decl) == ctor_identifier)
	      : (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)
		 && DECL_NAME (decl) == dtor_identifier));

  while (decl && DECL_NAME (decl) != identifier)
    {
      decl = DECL_CHAIN (decl);
      if (decl && !DECL_CLONED_FUNCTION_P (decl))
	decl = NULL_TREE;
    }
  gcc_assert (decl);

  record_decl_address (ctx, build_decl_addr_value (decl, address));

  return convert_out (decl);
}

int
plugin_add_friend (cc1_plugin::connection * /* self */,
		   gcc_decl decl_in,
		   gcc_type type_in)
{
  tree decl = convert_in (decl_in);
  tree type = convert_in (type_in);

  gcc_assert (type || at_class_scope_p ());

  if (!type)
    type = current_class_type;
  else
    gcc_assert (TREE_CODE (type) == RECORD_TYPE);

  if (TYPE_P (decl))
    make_friend_class (type, TREE_TYPE (decl), true);
  else
    {
      DECL_UNIQUE_FRIEND_P (decl) = true;
      add_friend (type, decl, true);
    }

  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)));
}

gcc_type
plugin_build_reference_type (cc1_plugin::connection *,
			     gcc_type base_type_in,
			     enum gcc_cp_ref_qualifiers rquals)
{
  bool rval;

  switch (rquals)
    {
    case GCC_CP_REF_QUAL_LVALUE:
      rval = false;
      break;
    case GCC_CP_REF_QUAL_RVALUE:
      rval = true;
      break;
    case GCC_CP_REF_QUAL_NONE:
    default:
      gcc_unreachable ();
    }

  tree rtype = cp_build_reference_type (convert_in (base_type_in), rval);

  return convert_out (rtype);
}

static tree
start_class_def (tree type,
		 const gcc_vbase_array *base_classes)
{
  tree bases = NULL;
  if (base_classes)
    {
      for (int i = 0; i < base_classes->n_elements; i++)
	{
	  tree access;

	  gcc_assert ((base_classes->flags[i] & GCC_CP_SYMBOL_MASK)
		      == GCC_CP_SYMBOL_BASECLASS);

	  switch (base_classes->flags[i] & GCC_CP_ACCESS_MASK)
	    {
	    case GCC_CP_ACCESS_PRIVATE:
	      access = ridpointers[(int)RID_PRIVATE];
	      break;

	    case GCC_CP_ACCESS_PROTECTED:
	      access = ridpointers[(int)RID_PROTECTED];
	      break;

	    case GCC_CP_ACCESS_PUBLIC:
	      access = ridpointers[(int)RID_PUBLIC];
	      break;

	    default:
	      gcc_unreachable ();
	    }

	  tree base = finish_base_specifier
	    (convert_in (base_classes->elements[i]), access,
	     (base_classes->flags[i] & GCC_CP_FLAG_BASECLASS_VIRTUAL) != 0);
	  TREE_CHAIN (base) = bases;
	  bases = base;
	}
      bases = nreverse (bases);
    }
  xref_basetypes (type, bases);
  begin_class_definition (type);
  return type;
}

gcc_type
plugin_start_class_type (cc1_plugin::connection *self,
			 gcc_decl typedecl_in,
			 const gcc_vbase_array *base_classes,
			 const char *filename,
			 unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  location_t loc = ctx->get_location_t (filename, line_number);
  tree typedecl = convert_in (typedecl_in);
  tree type = TREE_TYPE (typedecl);

  gcc_assert (RECORD_OR_UNION_CODE_P (TREE_CODE (type)));
  gcc_assert (!COMPLETE_TYPE_P (type));

  DECL_SOURCE_LOCATION (typedecl) = loc;

  tree result = start_class_def (type, base_classes);

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

gcc_type
plugin_start_closure_class_type (cc1_plugin::connection *self,
				 int discriminator,
				 gcc_decl extra_scope_in,
				 enum gcc_cp_symbol_kind flags,
				 const char *filename,
				 unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree extra_scope = convert_in (extra_scope_in);

  gcc_assert ((flags & GCC_CP_SYMBOL_MASK) == GCC_CP_SYMBOL_LAMBDA_CLOSURE);
  gcc_assert ((flags & (~(GCC_CP_SYMBOL_MASK | GCC_CP_ACCESS_MASK))) == 0);

  gcc_assert (!(flags & GCC_CP_ACCESS_MASK) == !at_class_scope_p ());

  /* See at_fake_function_scope_p.  */
  gcc_assert (!at_function_scope_p ());

  if (extra_scope)
    {
      if (TREE_CODE (extra_scope) == PARM_DECL)
	{
	  gcc_assert (at_fake_function_scope_p ());
	  /* Check that the given extra_scope is one of the parameters of
	     the current function.  */
	  for (tree parm = DECL_ARGUMENTS (current_function_decl);
	       ; parm = DECL_CHAIN (parm))
	    {
	      gcc_assert (parm);
	      if (parm == extra_scope)
		break;
	    }
	}
      else if (TREE_CODE (extra_scope) == FIELD_DECL)
	{
	  gcc_assert (at_class_scope_p ());
	  gcc_assert (DECL_CONTEXT (extra_scope) == current_class_type);
	}
      else
	/* FIXME: does this ever really occur?  */
	gcc_assert (TREE_CODE (extra_scope) == VAR_DECL);
    }

  tree lambda_expr = build_lambda_expr ();

  LAMBDA_EXPR_LOCATION (lambda_expr) = ctx->get_location_t (filename,
							    line_number);

  tree type = begin_lambda_type (lambda_expr);

  /* Instead of calling record_lambda_scope, do this:  */
  LAMBDA_EXPR_EXTRA_SCOPE (lambda_expr) = extra_scope;
  LAMBDA_EXPR_DISCRIMINATOR (lambda_expr) = discriminator;

  tree decl = TYPE_NAME (type);
  determine_visibility (decl);
  set_access_flags (decl, flags);

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

gcc_expr
plugin_build_lambda_expr (cc1_plugin::connection *self,
			  gcc_type closure_type_in)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree closure_type = convert_in (closure_type_in);

  gcc_assert (LAMBDA_TYPE_P (closure_type));

  tree lambda_expr = CLASSTYPE_LAMBDA_EXPR (closure_type);

  tree lambda_object = build_lambda_object (lambda_expr);

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

gcc_decl
plugin_build_field (cc1_plugin::connection *,
		    const char *field_name,
		    gcc_type field_type_in,
		    enum gcc_cp_symbol_kind flags,
		    unsigned long bitsize,
		    unsigned long bitpos)
{
  tree record_or_union_type = current_class_type;
  tree field_type = convert_in (field_type_in);

  gcc_assert (at_class_scope_p ());
  gcc_assert (RECORD_OR_UNION_CODE_P (TREE_CODE (record_or_union_type)));
  gcc_assert ((flags & GCC_CP_SYMBOL_MASK) == GCC_CP_SYMBOL_FIELD);
  gcc_assert ((flags & (~(GCC_CP_SYMBOL_MASK | GCC_CP_ACCESS_MASK
			  | GCC_CP_FLAG_MASK_FIELD))) == 0);
  gcc_assert ((flags & GCC_CP_ACCESS_MASK));

  /* 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;

  set_access_flags (decl, flags);

  if ((flags & GCC_CP_FLAG_FIELD_MUTABLE) != 0)
    DECL_MUTABLE_P (decl) = 1;

  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 convert_out (decl);
}

int
plugin_finish_class_type (cc1_plugin::connection *,
			  unsigned long size_in_bytes)
{
  tree record_or_union_type = current_class_type;

  gcc_assert (RECORD_OR_UNION_CODE_P (TREE_CODE (record_or_union_type)));

  finish_struct (record_or_union_type, NULL);

  gcc_assert (compare_tree_int (TYPE_SIZE_UNIT (record_or_union_type),
				size_in_bytes) == 0);

  return 1;
}

gcc_type
plugin_start_enum_type (cc1_plugin::connection *self,
			const char *name,
			gcc_type underlying_int_type_in,
			enum gcc_cp_symbol_kind flags,
			const char *filename,
			unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree underlying_int_type = convert_in (underlying_int_type_in);

  gcc_assert ((flags & GCC_CP_SYMBOL_MASK) == GCC_CP_SYMBOL_ENUM);
  gcc_assert ((flags & (~(GCC_CP_SYMBOL_MASK | GCC_CP_ACCESS_MASK
			  | GCC_CP_FLAG_MASK_ENUM))) == 0);
  gcc_assert (!(flags & GCC_CP_ACCESS_MASK) == !at_class_scope_p ());

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

  bool is_new_type = false;

  tree id = name ? get_identifier (name) : make_anon_name ();

  tree type = start_enum (id, NULL_TREE,
			  underlying_int_type,
			  /* attributes = */ NULL_TREE,
			  !!(flags & GCC_CP_FLAG_ENUM_SCOPED), &is_new_type);

  gcc_assert (is_new_type);

  location_t loc = ctx->get_location_t (filename, line_number);
  tree type_decl = TYPE_NAME (type);
  DECL_SOURCE_LOCATION (type_decl) = loc;
  SET_OPAQUE_ENUM_P (type, false);

  set_access_flags (type_decl, flags);

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

gcc_decl
plugin_build_enum_constant (cc1_plugin::connection *,
			    gcc_type enum_type_in,
			    const char *name,
			    unsigned long value)
{
  tree enum_type = convert_in (enum_type_in);

  gcc_assert (TREE_CODE (enum_type) == ENUMERAL_TYPE);

  build_enumerator (get_identifier (name), build_int_cst (enum_type, value),
		    enum_type, NULL_TREE, BUILTINS_LOCATION);

  return convert_out (TREE_VALUE (TYPE_VALUES (enum_type)));
}

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

  finish_enum_value_list (enum_type);
  finish_enum (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));
}

#if 0

gcc_type
plugin_add_function_default_args (cc1_plugin::connection *self,
				  gcc_type function_type_in,
				  const struct gcc_cp_function_args *defaults)
{
  tree function_type = convert_in (function_type_in);

  gcc_assert (TREE_CODE (function_type) == FUNCTION_TYPE);

  if (!defaults || !defaults->n_elements)
    return function_type_in;

  tree pargs = TYPE_ARG_TYPES (function_type);
  tree nargs = NULL_TREE;

  /* Build a reversed copy of the list of default-less arguments in
     NARGS.  At the end of the loop, PARGS will point to the end of
     the argument list, or to the first argument that had a default
     value.  */
  while (pargs && TREE_VALUE (pargs) != void_list_node
	 && !TREE_PURPOSE (pargs))
    {
      nargs = tree_cons (NULL_TREE, TREE_VALUE (pargs), nargs);
      pargs = TREE_CHAIN (pargs);
    }

  /* Set the defaults in the now-leading NARGS, taking into account
     that NARGS is reversed but DEFAULTS->elements isn't.  */
  tree ndargs = nargs;
  int i = defaults->n_elements;
  while (i--)
    {
      gcc_assert (ndargs);
      tree deflt = convert_in (defaults->elements[i]);
      if (!deflt)
	deflt = error_mark_node;
      TREE_PURPOSE (ndargs) = deflt;
      ndargs = TREE_CHAIN (ndargs);
    }

  /* Finally, reverse NARGS, and append the remaining PARGS that
     already had defaults.  */
  nargs = nreverse (nargs);
  nargs = chainon (nargs, pargs);

  tree result = build_function_type (TREE_TYPE (function_type), nargs);

  /* Copy exceptions, attributes and whatnot.  */
  result = build_exception_variant (result,
				    TYPE_RAISES_EXCEPTIONS (function_type));
  result = cp_build_type_attribute_variant (result,
					    TYPE_ATTRIBUTES (function_type));

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

int
plugin_set_deferred_function_default_args (cc1_plugin::connection *,
					   gcc_decl function_in,
					   const struct gcc_cp_function_args
					   *defaults)
{
  tree function = convert_in (function_in);

  gcc_assert (TREE_CODE (function) == FUNCTION_DECL);

  if (!defaults || !defaults->n_elements)
    return 1;

  tree arg = FUNCTION_FIRST_USER_PARMTYPE (function);

  for (int i = 0; i < defaults->n_elements; i++)
    {
      while (arg && TREE_PURPOSE (arg) != error_mark_node)
	arg = TREE_CHAIN (arg);

      if (!arg)
	return 0;

      TREE_PURPOSE (arg) = convert_in (defaults->elements[i]);
      arg = TREE_CHAIN (arg);
    }

  return 1;
}

#endif

gcc_decl
plugin_get_function_parameter_decl (cc1_plugin::connection *,
				    gcc_decl function_in,
				    int index)
{
  tree function = convert_in (function_in);

  gcc_assert (TREE_CODE (function) == FUNCTION_DECL);

  if (index == -1)
    {
      gcc_assert (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE);

      return convert_out (DECL_ARGUMENTS (function));
    }

  gcc_assert (index >= 0);

  tree args = FUNCTION_FIRST_USER_PARM (function);

  for (int i = 0; args && i < index; i++)
    args = DECL_CHAIN (args);

  return convert_out (args);
}

gcc_type
plugin_build_exception_spec_variant (cc1_plugin::connection *self,
				     gcc_type function_type_in,
				     const struct gcc_type_array *except_types_in)
{
  tree function_type = convert_in (function_type_in);
  tree except_types = NULL_TREE;

  if (!except_types_in)
    except_types = noexcept_false_spec;
  else if (!except_types_in->n_elements)
    except_types = empty_except_spec;
  else
    for (int i = 0; i < except_types_in->n_elements; i++)
      except_types = add_exception_specifier (except_types,
					      convert_in
					      (except_types_in->elements[i]),
					      0);

  function_type = build_exception_variant (function_type,
					   except_types);

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

gcc_type
plugin_build_method_type (cc1_plugin::connection *self,
			  gcc_type class_type_in,
			  gcc_type func_type_in,
			  enum gcc_cp_qualifiers quals_in,
			  enum gcc_cp_ref_qualifiers rquals_in)
{
  tree class_type = convert_in (class_type_in);
  tree func_type = convert_in (func_type_in);
  cp_cv_quals quals = 0;
  cp_ref_qualifier rquals;

  if ((quals_in & GCC_CP_QUALIFIER_CONST) != 0)
    quals |= TYPE_QUAL_CONST;
  if ((quals_in & GCC_CP_QUALIFIER_VOLATILE) != 0)
    quals |= TYPE_QUAL_VOLATILE;
  gcc_assert ((quals_in & GCC_CP_QUALIFIER_RESTRICT) == 0);

  switch (rquals_in)
    {
    case GCC_CP_REF_QUAL_NONE:
      rquals = REF_QUAL_NONE;
      break;
    case GCC_CP_REF_QUAL_LVALUE:
      rquals = REF_QUAL_LVALUE;
      break;
    case GCC_CP_REF_QUAL_RVALUE:
      rquals = REF_QUAL_RVALUE;
      break;
    default:
      gcc_unreachable ();
    }

  tree method_type = class_type
    ? build_memfn_type (func_type, class_type, quals, rquals)
    : apply_memfn_quals (func_type, quals, rquals);

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

gcc_type
plugin_build_pointer_to_member_type (cc1_plugin::connection *self,
				     gcc_type class_type_in,
				     gcc_type member_type_in)
{
  tree class_type = convert_in (class_type_in);
  tree member_type = convert_in (member_type_in);

  tree memptr_type = build_ptrmem_type (class_type, member_type);

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

int
plugin_start_template_decl (cc1_plugin::connection *)
{
  begin_template_parm_list ();

  TP_PARM_LIST = NULL_TREE;

  return 1;
}

gcc_decl
plugin_get_type_decl (cc1_plugin::connection *,
		      gcc_type type_in)
{
  tree type = convert_in (type_in);

  tree name = TYPE_NAME (type);
  gcc_assert (name);

  return convert_out (name);
}

gcc_type
plugin_get_decl_type (cc1_plugin::connection *,
		      gcc_decl decl_in)
{
  tree decl = convert_in (decl_in);

  tree type = TREE_TYPE (decl);
  gcc_assert (type);

  return convert_out (type);
}

gcc_type
plugin_build_type_template_parameter (cc1_plugin::connection *self,
				      const char *id,
				      int /* bool */ pack_p,
				      gcc_type default_type,
				      const char *filename,
				      unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  location_t loc = ctx->get_location_t (filename, line_number);

  gcc_assert (template_parm_scope_p ());

  tree parm = finish_template_type_parm (class_type_node, get_identifier (id));
  parm = build_tree_list (convert_in (default_type), parm);

  gcc_assert (!(pack_p && default_type));

  /* Create a type and a decl for the type parm, and add the decl to
     TP_PARM_LIST.  */
  TP_PARM_LIST = process_template_parm (TP_PARM_LIST, loc, parm,
					/* is_non_type = */ false, pack_p);

  /* Locate the decl of the newly-added, processed template parm.  */
  parm = TREE_VALUE (tree_last (TP_PARM_LIST));

  /* Return its type.  */
  return convert_out (ctx->preserve (TREE_TYPE (parm)));
}

gcc_utempl
plugin_build_template_template_parameter (cc1_plugin::connection *self,
					  const char *id,
					  int /* bool */ pack_p,
					  gcc_utempl default_templ,
					  const char *filename,
					  unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  location_t loc = ctx->get_location_t (filename, line_number);

  gcc_assert (template_parm_scope_p ());

  /* Finish the template parm list that started this template parm.  */
  end_template_parm_list (TP_PARM_LIST);

  gcc_assert (template_parm_scope_p ());

  tree parm = finish_template_template_parm (class_type_node,
					     get_identifier (id));
  parm = build_tree_list (convert_in (default_templ), parm);

  gcc_assert (!(pack_p && default_templ));

  /* Create a type and a decl for the template parm, and add the decl
     to TP_PARM_LIST.  */
  TP_PARM_LIST = process_template_parm (TP_PARM_LIST, loc, parm,
					/* is_non_type = */ false, pack_p);

  /* Locate the decl of the newly-added, processed template parm.  */
  parm = TREE_VALUE (tree_last (TP_PARM_LIST));

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

gcc_decl
plugin_build_value_template_parameter (cc1_plugin::connection *self,
				       gcc_type type,
				       const char *id,
				       gcc_expr default_value,
				       const char *filename,
				       unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  location_t loc = ctx->get_location_t (filename, line_number);

  gcc_assert (template_parm_scope_p ());

  cp_declarator declarator;
  memset (&declarator, 0, sizeof (declarator));
  // &declarator = make_id_declarator (NULL, get_identifier (id), sfk_none):
  declarator.kind = cdk_id;
  declarator.u.id.qualifying_scope = NULL;
  declarator.u.id.unqualified_name = get_identifier (id);
  declarator.u.id.sfk = sfk_none;

  cp_decl_specifier_seq declspec;
  memset (&declspec, 0, sizeof (declspec));
  // cp_parser_set_decl_spec_type (&declspec, convert_in (type), -token-, false):
  declspec.any_specifiers_p = declspec.any_type_specifiers_p = true;
  declspec.type = convert_in (type);
  declspec.locations[ds_type_spec] = loc;

  tree parm = grokdeclarator (&declarator, &declspec, TPARM, 0, 0);
  parm = build_tree_list (convert_in (default_value), parm);

  /* Create a type and a decl for the template parm, and add the decl
     to TP_PARM_LIST.  */
  TP_PARM_LIST = process_template_parm (TP_PARM_LIST, loc, parm,
					/* is_non_type = */ true, false);

  /* Locate the decl of the newly-added, processed template parm.  */
  parm = TREE_VALUE (tree_last (TP_PARM_LIST));

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

static tree
targlist (const gcc_cp_template_args *targs)
{
  int n = targs->n_elements;
  tree vec = make_tree_vec (n);
  while (n--)
    {
      switch (targs->kinds[n])
	{
	case GCC_CP_TPARG_VALUE:
	  TREE_VEC_ELT (vec, n) = convert_in (targs->elements[n].value);
	  break;
	case GCC_CP_TPARG_CLASS:
	  TREE_VEC_ELT (vec, n) = convert_in (targs->elements[n].type);
	  break;
	case GCC_CP_TPARG_TEMPL:
	  TREE_VEC_ELT (vec, n) = convert_in (targs->elements[n].templ);
	  break;
	case GCC_CP_TPARG_PACK:
	  TREE_VEC_ELT (vec, n) = convert_in (targs->elements[n].pack);
	  break;
	default:
	  gcc_unreachable ();
	}
    }
  return vec;
}

gcc_type
plugin_build_dependent_typename (cc1_plugin::connection *self,
				 gcc_type enclosing_type,
				 const char *id,
				 const gcc_cp_template_args *targs)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree type = convert_in (enclosing_type);
  tree name = get_identifier (id);
  if (targs)
    name = build_min_nt_loc (/*loc=*/0, TEMPLATE_ID_EXPR,
			     name, targlist (targs));
  tree res = make_typename_type (type, name, typename_type,
				 /*complain=*/tf_error);
  return convert_out (ctx->preserve (res));
}

gcc_utempl
plugin_build_dependent_class_template (cc1_plugin::connection *self,
				       gcc_type enclosing_type,
				       const char *id)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree type = convert_in (enclosing_type);
  tree name = get_identifier (id);
  tree res = make_unbound_class_template (type, name, NULL_TREE,
					  /*complain=*/tf_error);
  return convert_out (ctx->preserve (res));
}

gcc_type
plugin_build_dependent_type_template_id (cc1_plugin::connection *self,
					 gcc_utempl template_decl,
					 const gcc_cp_template_args *targs)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree type = convert_in (template_decl);
  tree decl = finish_template_type (type, targlist (targs),
				    /*entering_scope=*/false);
  return convert_out (ctx->preserve (TREE_TYPE (decl)));
}

gcc_expr
plugin_build_dependent_expr (cc1_plugin::connection *self,
			     gcc_decl enclosing_scope,
			     enum gcc_cp_symbol_kind flags,
			     const char *name,
			     gcc_type conv_type_in,
			     const gcc_cp_template_args *targs)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree scope = convert_in (enclosing_scope);
  tree conv_type = convert_in (conv_type_in);
  tree identifier;

  if (TREE_CODE (scope) != NAMESPACE_DECL)
    {
      tree type = TREE_TYPE (scope);
      gcc_assert (TYPE_NAME (type) == scope);
      scope = type;
    }

  if (flags == (GCC_CP_SYMBOL_FUNCTION | GCC_CP_FLAG_SPECIAL_FUNCTION))
    {
      bool assop = false, convop = false;
      tree_code opcode = ERROR_MARK;

      switch (CHARS2 (name[0], name[1]))
	{
	case CHARS2 ('C', 0x0): // ctor base declaration
	case CHARS2 ('C', ' '):
	case CHARS2 ('C', '1'):
	case CHARS2 ('C', '2'):
	case CHARS2 ('C', '4'):
	  identifier = ctor_identifier;
	  break;
	case CHARS2 ('D', 0x0): // dtor base declaration
	case CHARS2 ('D', ' '):
	case CHARS2 ('D', '0'):
	case CHARS2 ('D', '1'):
	case CHARS2 ('D', '2'):
	case CHARS2 ('D', '4'):
	  gcc_assert (!targs);
	  identifier = dtor_identifier;
	  break;
	case CHARS2 ('n', 'w'): // operator new
	  opcode = NEW_EXPR;
	  break;
	case CHARS2 ('n', 'a'): // operator new[]
	  opcode = VEC_NEW_EXPR;
	  break;
	case CHARS2 ('d', 'l'): // operator delete
	  opcode = DELETE_EXPR;
	  break;
	case CHARS2 ('d', 'a'): // operator delete[]
	  opcode = VEC_DELETE_EXPR;
	  break;
	case CHARS2 ('p', 's'): // operator + (unary)
	  opcode = PLUS_EXPR;
	  break;
	case CHARS2 ('n', 'g'): // operator - (unary)
	  opcode = MINUS_EXPR;
	  break;
	case CHARS2 ('a', 'd'): // operator & (unary)
	  opcode = BIT_AND_EXPR;
	  break;
	case CHARS2 ('d', 'e'): // operator * (unary)
	  opcode = MULT_EXPR;
	  break;
	case CHARS2 ('c', 'o'): // operator ~
	  opcode = BIT_NOT_EXPR;
	  break;
	case CHARS2 ('p', 'l'): // operator +
	  opcode = PLUS_EXPR;
	  break;
	case CHARS2 ('m', 'i'): // operator -
	  opcode = MINUS_EXPR;
	  break;
	case CHARS2 ('m', 'l'): // operator *
	  opcode = MULT_EXPR;
	  break;
	case CHARS2 ('d', 'v'): // operator /
	  opcode = TRUNC_DIV_EXPR;
	  break;
	case CHARS2 ('r', 'm'): // operator %
	  opcode = TRUNC_MOD_EXPR;
	  break;
	case CHARS2 ('a', 'n'): // operator &
	  opcode = BIT_AND_EXPR;
	  break;
	case CHARS2 ('o', 'r'): // operator |
	  opcode = BIT_IOR_EXPR;
	  break;
	case CHARS2 ('e', 'o'): // operator ^
	  opcode = BIT_XOR_EXPR;
	  break;
	case CHARS2 ('a', 'S'): // operator =
	  opcode = NOP_EXPR;
	  assop = true;
	  break;
	case CHARS2 ('p', 'L'): // operator +=
	  opcode = PLUS_EXPR;
	  assop = true;
	  break;
	case CHARS2 ('m', 'I'): // operator -=
	  opcode = MINUS_EXPR;
	  assop = true;
	  break;
	case CHARS2 ('m', 'L'): // operator *=
	  opcode = MULT_EXPR;
	  assop = true;
	  break;
	case CHARS2 ('d', 'V'): // operator /=
	  opcode = TRUNC_DIV_EXPR;
	  assop = true;
	  break;
	case CHARS2 ('r', 'M'): // operator %=
	  opcode = TRUNC_MOD_EXPR;
	  assop = true;
	  break;
	case CHARS2 ('a', 'N'): // operator &=
	  opcode = BIT_AND_EXPR;
	  assop = true;
	  break;
	case CHARS2 ('o', 'R'): // operator |=
	  opcode = BIT_IOR_EXPR;
	  assop = true;
	  break;
	case CHARS2 ('e', 'O'): // operator ^=
	  opcode = BIT_XOR_EXPR;
	  assop = true;
	  break;
	case CHARS2 ('l', 's'): // operator <<
	  opcode = LSHIFT_EXPR;
	  break;
	case CHARS2 ('r', 's'): // operator >>
	  opcode = RSHIFT_EXPR;
	  break;
	case CHARS2 ('l', 'S'): // operator <<=
	  opcode = LSHIFT_EXPR;
	  assop = true;
	  break;
	case CHARS2 ('r', 'S'): // operator >>=
	  opcode = RSHIFT_EXPR;
	  assop = true;
	  break;
	case CHARS2 ('e', 'q'): // operator ==
	  opcode = EQ_EXPR;
	  break;
	case CHARS2 ('n', 'e'): // operator !=
	  opcode = NE_EXPR;
	  break;
	case CHARS2 ('l', 't'): // operator <
	  opcode = LT_EXPR;
	  break;
	case CHARS2 ('g', 't'): // operator >
	  opcode = GT_EXPR;
	  break;
	case CHARS2 ('l', 'e'): // operator <=
	  opcode = LE_EXPR;
	  break;
	case CHARS2 ('g', 'e'): // operator >=
	  opcode = GE_EXPR;
	  break;
	case CHARS2 ('n', 't'): // operator !
	  opcode = TRUTH_NOT_EXPR;
	  break;
	case CHARS2 ('a', 'a'): // operator &&
	  opcode = TRUTH_ANDIF_EXPR;
	  break;
	case CHARS2 ('o', 'o'): // operator ||
	  opcode = TRUTH_ORIF_EXPR;
	  break;
	case CHARS2 ('p', 'p'): // operator ++
	  opcode = POSTINCREMENT_EXPR;
	  break;
	case CHARS2 ('m', 'm'): // operator --
	  opcode = PREDECREMENT_EXPR;
	  break;
	case CHARS2 ('c', 'm'): // operator ,
	  opcode = COMPOUND_EXPR;
	  break;
	case CHARS2 ('p', 'm'): // operator ->*
	  opcode = MEMBER_REF;
	  break;
	case CHARS2 ('p', 't'): // operator ->
	  opcode = COMPONENT_REF;
	  break;
	case CHARS2 ('c', 'l'): // operator ()
	  opcode = CALL_EXPR;
	  break;
	case CHARS2 ('i', 'x'): // operator []
	  opcode = ARRAY_REF;
	  break;
	case CHARS2 ('c', 'v'): // operator <T> (conversion operator)
	  convop = true;
	  identifier = make_conv_op_name (conv_type);
	  break;
	  // C++11-only:
	case CHARS2 ('l', 'i'): // operator "" <id>
	  {
	    char *id = (char *)name + 2;
	    bool freeid = false;
	    if (*id >= '0' && *id <= '9')
	      {
		unsigned len = 0;
		do
		  {
		    len *= 10;
		    len += id[0] - '0';
		    id++;
		  }
		while (*id && *id >= '0' && *id <= '9');
		id = xstrndup (id, len);
		freeid = true;
	      }
	    identifier = cp_literal_operator_id (id);
	    if (freeid)
	      free (id);
	  }
	  break;
	case CHARS2 ('q', 'u'): // ternary operator, not overloadable.
	default:
	  gcc_unreachable ();
	}

      gcc_assert (convop || !conv_type);

      if (opcode != ERROR_MARK)
	identifier = ovl_op_identifier (assop, opcode);

      gcc_assert (identifier);
    }
  else
    {
      gcc_assert (flags == GCC_CP_SYMBOL_MASK);
      gcc_assert (!conv_type);
      identifier = get_identifier (name);
    }
  tree res = identifier;
  if (!scope)
    res = lookup_name (res, LOOK_where::BLOCK_NAMESPACE);
  else if (!TYPE_P (scope) || !dependent_scope_p (scope))
    {
      res = lookup_qualified_name (scope, res, LOOK_want::NORMAL, true);
      /* We've already resolved the name in the scope, so skip the
	 build_qualified_name call below.  */
      scope = NULL;
    }
  if (targs)
    res = lookup_template_function (res, targlist (targs));
  if (scope)
    res = build_qualified_name (NULL_TREE, scope, res, !!targs);
  return convert_out (ctx->preserve (res));
}

gcc_expr
plugin_build_literal_expr (cc1_plugin::connection *self,
			   gcc_type type, unsigned long value)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree t = convert_in (type);
  tree val = build_int_cst_type (t, (unsigned HOST_WIDE_INT) value);
  return convert_out (ctx->preserve (val));
}

gcc_expr
plugin_build_decl_expr (cc1_plugin::connection *self,
			gcc_decl decl_in,
			int qualified_p)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree decl = convert_in (decl_in);
  gcc_assert (DECL_P (decl));
  tree result = decl;
  if (qualified_p)
    {
      gcc_assert (DECL_CLASS_SCOPE_P (decl));
      result = build_offset_ref (DECL_CONTEXT (decl), decl,
				 /*address_p=*/true, tf_error);
    }
  return convert_out (ctx->preserve (result));
}

gcc_expr
plugin_build_unary_expr (cc1_plugin::connection *self,
			 const char *unary_op,
			 gcc_expr operand)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree op0 = convert_in (operand);
  tree_code opcode = ERROR_MARK;
  bool global_scope_p = false;

 once_more:
  switch (CHARS2 (unary_op[0], unary_op[1]))
    {
    case CHARS2 ('p', 's'): // operator + (unary)
      opcode = UNARY_PLUS_EXPR;
      break;
    case CHARS2 ('n', 'g'): // operator - (unary)
      opcode = NEGATE_EXPR;
      break;
    case CHARS2 ('a', 'd'): // operator & (unary)
      opcode = ADDR_EXPR;
      break;
    case CHARS2 ('d', 'e'): // operator * (unary)
      opcode = INDIRECT_REF;
      break;
    case CHARS2 ('c', 'o'): // operator ~
      opcode = BIT_NOT_EXPR;
      break;
    case CHARS2 ('n', 't'): // operator !
      opcode = TRUTH_NOT_EXPR;
      break;
    case CHARS2 ('p', 'p'): // operator ++
      opcode = unary_op[2] == '_' ? PREINCREMENT_EXPR : POSTINCREMENT_EXPR;
      break;
    case CHARS2 ('m', 'm'): // operator --
      opcode = unary_op[2] == '_' ? PREDECREMENT_EXPR : POSTDECREMENT_EXPR;
      break;
    case CHARS2 ('n', 'x'): // noexcept
      opcode = NOEXCEPT_EXPR;
      break;
    case CHARS2 ('t', 'w'): // throw
      gcc_assert (op0);
      opcode = THROW_EXPR;
      break;
    case CHARS2 ('t', 'r'): // rethrow
      gcc_assert (!op0);
      opcode = THROW_EXPR;
      break;
    case CHARS2 ('t', 'e'): // typeid (value)
      opcode = TYPEID_EXPR;
      break;
    case CHARS2 ('s', 'z'): // sizeof (value)
      opcode = SIZEOF_EXPR;
      break;
    case CHARS2 ('a', 'z'): // alignof (value)
      opcode = ALIGNOF_EXPR;
      break;
    case CHARS2 ('g', 's'): // global scope (for delete, delete[])
      gcc_assert (!global_scope_p);
      global_scope_p = true;
      unary_op += 2;
      goto once_more;
    case CHARS2 ('d', 'l'): // delete
      opcode = DELETE_EXPR;
      break;
    case CHARS2 ('d', 'a'): // delete[]
      opcode = VEC_DELETE_EXPR;
      break;
    case CHARS2 ('s', 'p'): // pack...
      opcode = EXPR_PACK_EXPANSION;
      break;
    case CHARS2 ('s', 'Z'): // sizeof...(pack)
      opcode = TYPE_PACK_EXPANSION; // Not really, but let's use its code.
      break;

      /* FIXME: __real__, __imag__?  */

    default:
      gcc_unreachable ();
    }

  gcc_assert (!global_scope_p
	      || opcode == DELETE_EXPR || opcode == VEC_DELETE_EXPR);

  processing_template_decl++;
  bool template_dependent_p = op0
    && (type_dependent_expression_p (op0)
	|| value_dependent_expression_p (op0));
  if (!template_dependent_p)
    processing_template_decl--;

  tree result;

  gcc_assert (op0 || opcode == THROW_EXPR);

  switch (opcode)
    {
    case NOEXCEPT_EXPR:
      result = finish_noexcept_expr (op0, tf_error);
      break;

    case THROW_EXPR:
      result = build_throw (input_location, op0);
      break;

    case TYPEID_EXPR:
      result = build_typeid (op0, tf_error);
      break;

    case SIZEOF_EXPR:
    case ALIGNOF_EXPR:
      result = cxx_sizeof_or_alignof_expr (input_location,
					   op0, opcode, true, true);
      break;

    case DELETE_EXPR:
    case VEC_DELETE_EXPR:
      result = delete_sanity (input_location, op0, NULL_TREE,
			      opcode == VEC_DELETE_EXPR,
			      global_scope_p, tf_error);
      break;

    case EXPR_PACK_EXPANSION:
      result = make_pack_expansion (op0);
      break;

      // We're using this for sizeof...(pack).  */
    case TYPE_PACK_EXPANSION:
      result = make_pack_expansion (op0);
      PACK_EXPANSION_SIZEOF_P (result) = true;
      break;

    default:
      result = build_x_unary_op (/*loc=*/0, opcode, op0, tf_error);
      break;
    }

  if (template_dependent_p)
    processing_template_decl--;

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

gcc_expr
plugin_build_binary_expr (cc1_plugin::connection *self,
			  const char *binary_op,
			  gcc_expr operand1,
			  gcc_expr operand2)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree op0 = convert_in (operand1);
  tree op1 = convert_in (operand2);
  tree_code opcode = ERROR_MARK;

  switch (CHARS2 (binary_op[0], binary_op[1]))
    {
    case CHARS2 ('p', 'l'): // operator +
      opcode = PLUS_EXPR;
      break;
    case CHARS2 ('m', 'i'): // operator -
      opcode = MINUS_EXPR;
      break;
    case CHARS2 ('m', 'l'): // operator *
      opcode = MULT_EXPR;
      break;
    case CHARS2 ('d', 'v'): // operator /
      opcode = TRUNC_DIV_EXPR;
      break;
    case CHARS2 ('r', 'm'): // operator %
      opcode = TRUNC_MOD_EXPR;
      break;
    case CHARS2 ('a', 'n'): // operator &
      opcode = BIT_AND_EXPR;
      break;
    case CHARS2 ('o', 'r'): // operator |
      opcode = BIT_IOR_EXPR;
      break;
    case CHARS2 ('e', 'o'): // operator ^
      opcode = BIT_XOR_EXPR;
      break;
    case CHARS2 ('l', 's'): // operator <<
      opcode = LSHIFT_EXPR;
      break;
    case CHARS2 ('r', 's'): // operator >>
      opcode = RSHIFT_EXPR;
      break;
    case CHARS2 ('e', 'q'): // operator ==
      opcode = EQ_EXPR;
      break;
    case CHARS2 ('n', 'e'): // operator !=
      opcode = NE_EXPR;
      break;
    case CHARS2 ('l', 't'): // operator <
      opcode = LT_EXPR;
      break;
    case CHARS2 ('g', 't'): // operator >
      opcode = GT_EXPR;
      break;
    case CHARS2 ('l', 'e'): // operator <=
      opcode = LE_EXPR;
      break;
    case CHARS2 ('g', 'e'): // operator >=
      opcode = GE_EXPR;
      break;
    case CHARS2 ('a', 'a'): // operator &&
      opcode = TRUTH_ANDIF_EXPR;
      break;
    case CHARS2 ('o', 'o'): // operator ||
      opcode = TRUTH_ORIF_EXPR;
      break;
    case CHARS2 ('c', 'm'): // operator ,
      opcode = COMPOUND_EXPR;
      break;
    case CHARS2 ('p', 'm'): // operator ->*
      opcode = MEMBER_REF;
      break;
    case CHARS2 ('p', 't'): // operator ->
      opcode = INDIRECT_REF; // Not really!  This will stand for
			     // INDIRECT_REF followed by COMPONENT_REF
			     // later on.
      break;
    case CHARS2 ('i', 'x'): // operator []
      opcode = ARRAY_REF;
      break;
    case CHARS2 ('d', 's'): // operator .*
      opcode = DOTSTAR_EXPR;
      break;
    case CHARS2 ('d', 't'): // operator .
      opcode = COMPONENT_REF;
      break;

    default:
      gcc_unreachable ();
    }

  processing_template_decl++;
  bool template_dependent_p = type_dependent_expression_p (op0)
    || value_dependent_expression_p (op0)
    || type_dependent_expression_p (op1)
    || value_dependent_expression_p (op1);
  if (!template_dependent_p)
    processing_template_decl--;

  tree result;

  switch (opcode)
    {
    case INDIRECT_REF: // This is actually a "->".
      op0 = build_x_arrow (/*loc=*/0, op0, tf_error);
      /* Fall through.  */
    case COMPONENT_REF:
      result = finish_class_member_access_expr (op0, op1,
						/*template_p=*/false,
						tf_error);
      break;

    default:
      result = build_x_binary_op (/*loc=*/0, opcode, op0, ERROR_MARK,
				  op1, ERROR_MARK, NULL, tf_error);
      break;
    }

  if (template_dependent_p)
    processing_template_decl--;

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

gcc_expr
plugin_build_ternary_expr (cc1_plugin::connection *self,
			   const char *ternary_op,
			   gcc_expr operand1,
			   gcc_expr operand2,
			   gcc_expr operand3)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree op0 = convert_in (operand1);
  tree op1 = convert_in (operand2);
  tree op2 = convert_in (operand3);
  gcc_assert (CHARS2 (ternary_op[0], ternary_op[1])
	      == CHARS2 ('q', 'u')); // ternary operator

  processing_template_decl++;
  bool template_dependent_p = type_dependent_expression_p (op0)
    || value_dependent_expression_p (op0)
    || type_dependent_expression_p (op1)
    || value_dependent_expression_p (op1)
    || type_dependent_expression_p (op2)
    || value_dependent_expression_p (op2);
  if (!template_dependent_p)
    processing_template_decl--;

  tree val = build_x_conditional_expr (/*loc=*/0, op0, op1, op2, tf_error);

  if (template_dependent_p)
    processing_template_decl--;

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

gcc_expr
plugin_build_unary_type_expr (cc1_plugin::connection *self,
			      const char *unary_op,
			      gcc_type operand)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree type = convert_in (operand);
  tree_code opcode = ERROR_MARK;

  switch (CHARS2 (unary_op[0], unary_op[1]))
    {
    case CHARS2 ('t', 'i'): // typeid (type)
      opcode = TYPEID_EXPR;
      break;

    case CHARS2 ('s', 't'): // sizeof (type)
      opcode = SIZEOF_EXPR;
      break;
    case CHARS2 ('a', 't'): // alignof (type)
      opcode = ALIGNOF_EXPR;
      break;

    case CHARS2 ('s', 'Z'): // sizeof...(pack)
      opcode = TYPE_PACK_EXPANSION; // Not really, but let's use its code.
      break;

      // FIXME: do we have to handle "sp", for the size of a captured
      // template parameter pack from an alias template, taking
      // multiple template arguments?

    default:
      gcc_unreachable ();
    }

  processing_template_decl++;
  bool template_dependent_p = dependent_type_p (type);
  if (!template_dependent_p)
    processing_template_decl--;

  tree result;

  switch (opcode)
    {
    case TYPEID_EXPR:
      result = get_typeid (type, tf_error);
      break;

      // We're using this for sizeof...(pack).  */
    case TYPE_PACK_EXPANSION:
      result = make_pack_expansion (type);
      PACK_EXPANSION_SIZEOF_P (result) = true;
      break;

    default:
      /* Use the C++11 alignof semantics.  */
      result = cxx_sizeof_or_alignof_type (input_location, type,
					   opcode, true, true);
    }

  if (template_dependent_p)
    processing_template_decl--;

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

gcc_expr
plugin_build_cast_expr (cc1_plugin::connection *self,
			const char *binary_op,
			gcc_type operand1,
			gcc_expr operand2)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree (*build_cast)(location_t loc, tree type, tree expr,
		     tsubst_flags_t complain) = NULL;
  tree type = convert_in (operand1);
  tree expr = convert_in (operand2);

  switch (CHARS2 (binary_op[0], binary_op[1]))
    {
    case CHARS2 ('d', 'c'): // dynamic_cast
      build_cast = build_dynamic_cast;
      break;

    case CHARS2 ('s', 'c'): // static_cast
      build_cast = build_static_cast;
      break;

    case CHARS2 ('c', 'c'): // const_cast
      build_cast = build_const_cast;
      break;

    case CHARS2 ('r', 'c'): // reinterpret_cast
      build_cast = build_reinterpret_cast;
      break;

    case CHARS2 ('c', 'v'): // C cast, conversion with one argument
      build_cast = cp_build_c_cast;
      break;

    default:
      gcc_unreachable ();
    }

  processing_template_decl++;
  bool template_dependent_p = dependent_type_p (type)
    || type_dependent_expression_p (expr)
    || value_dependent_expression_p (expr);
  if (!template_dependent_p)
    processing_template_decl--;

  tree val = build_cast (input_location, type, expr, tf_error);

  if (template_dependent_p)
    processing_template_decl--;

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

static inline vec<tree, va_gc> *
args_to_tree_vec (const struct gcc_cp_function_args *args_in)
{
  vec<tree, va_gc> *args = make_tree_vector ();
  for (int i = 0; i < args_in->n_elements; i++)
    vec_safe_push (args, convert_in (args_in->elements[i]));
  return args;
}

static inline tree
args_to_tree_list (const struct gcc_cp_function_args *args_in)
{
  tree args, *tail = &args;
  for (int i = 0; i < args_in->n_elements; i++)
    {
      *tail = build_tree_list (NULL, convert_in (args_in->elements[i]));
      tail = &TREE_CHAIN (*tail);
    }
  return args;
}

static inline vec<constructor_elt, va_gc> *
args_to_ctor_elts (const struct gcc_cp_function_args *args_in)
{
  vec<constructor_elt, va_gc> *args = NULL;
  for (int i = 0; i < args_in->n_elements; i++)
    CONSTRUCTOR_APPEND_ELT (args, NULL_TREE, convert_in (args_in->elements[i]));
  return args;
}

gcc_expr
plugin_build_expression_list_expr (cc1_plugin::connection *self,
				   const char *conv_op,
				   gcc_type type_in,
				   const struct gcc_cp_function_args *values_in)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree type = convert_in (type_in);
  tree args;
  tree result;

  switch (CHARS2 (conv_op[0], conv_op[1]))
    {
    case CHARS2 ('c', 'v'): // conversion with parenthesized expression list
      gcc_assert (TYPE_P (type));
      args = args_to_tree_list (values_in);
      result = build_functional_cast (input_location, type, args, tf_error);
      break;

    case CHARS2 ('t', 'l'): // conversion with braced expression list
      gcc_assert (type);
      gcc_assert (TYPE_P (type));
      args = make_node (CONSTRUCTOR);
      CONSTRUCTOR_ELTS (args) = args_to_ctor_elts (values_in);
      CONSTRUCTOR_IS_DIRECT_INIT (args) = 1;
      result = finish_compound_literal (type, args, tf_error);
      break;

    case CHARS2 ('i', 'l'): // untyped braced expression list
      gcc_assert (!type);
      result = make_node (CONSTRUCTOR);
      CONSTRUCTOR_ELTS (result) = args_to_ctor_elts (values_in);
      break;

    default:
      gcc_unreachable ();
    }

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

gcc_expr
plugin_build_new_expr (cc1_plugin::connection *self,
		       const char *new_op,
		       const struct gcc_cp_function_args *placement_in,
		       gcc_type type_in,
		       const struct gcc_cp_function_args *initializer_in)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree type = convert_in (type_in);
  vec<tree, va_gc> *placement = NULL, *initializer = NULL;
  bool global_scope_p = false;
  tree nelts = NULL;

  if (placement_in)
    placement = args_to_tree_vec (placement_in);
  if (initializer_in)
    initializer = args_to_tree_vec (initializer_in);

  gcc_assert (TYPE_P (type));

 once_more:
  switch (CHARS2 (new_op[0], new_op[1]))
    {
    case CHARS2 ('g', 's'):
      gcc_assert (!global_scope_p);
      global_scope_p = true;
      new_op += 2;
      goto once_more;

    case CHARS2 ('n', 'w'): // non-array new
      gcc_assert (TREE_CODE (type) != ARRAY_TYPE);
      break;

    case CHARS2 ('n', 'a'): // array new
      gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
      gcc_assert (TYPE_DOMAIN (type));
      {
	// Compute the length of the outermost array type, then discard it.
	tree maxelt = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
	tree eltype = TREE_TYPE (maxelt);
	tree onecst = integer_one_node;

	processing_template_decl++;
	bool template_dependent_p = value_dependent_expression_p (maxelt)
	  || type_dependent_expression_p (maxelt);
	if (!template_dependent_p)
	  {
	    processing_template_decl--;
	    onecst = fold_convert (eltype, onecst);
	  }

	nelts = fold_build2 (PLUS_EXPR, eltype, nelts, onecst);

	if (template_dependent_p)
	  processing_template_decl--;

	type = TREE_TYPE (type);
      }
      break;

    default:
      gcc_unreachable ();
    }

  processing_template_decl++;
  bool template_dependent_p = dependent_type_p (type)
    || value_dependent_expression_p (nelts)
    || (placement
	&& any_type_dependent_arguments_p (placement))
    || (initializer
	&& any_type_dependent_arguments_p (initializer));
  if (!template_dependent_p)
    processing_template_decl--;

  tree result = build_new (input_location, &placement, type, nelts,
			   &initializer, global_scope_p, tf_error);

  if (template_dependent_p)
    processing_template_decl--;

  if (placement != NULL)
    release_tree_vector (placement);
  if (initializer != NULL)
    release_tree_vector (initializer);

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

gcc_expr
plugin_build_call_expr (cc1_plugin::connection *self,
			gcc_expr callable_in, int qualified_p,
			const struct gcc_cp_function_args *args_in)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree callable = convert_in (callable_in);
  tree call_expr;

  vec<tree, va_gc> *args = args_to_tree_vec (args_in);

  bool koenig_p = false;
  if (!qualified_p && !args->is_empty ())
    {
      if (identifier_p (callable))
	koenig_p = true;
      else if (is_overloaded_fn (callable))
	{
	  tree fn = get_first_fn (callable);
	  fn = STRIP_TEMPLATE (fn);

	  if (!DECL_FUNCTION_MEMBER_P (fn)
	      && !DECL_LOCAL_DECL_P (fn))
	    koenig_p = true;
	}
    }

  if (koenig_p && !any_type_dependent_arguments_p (args))
    callable = perform_koenig_lookup (callable, args, tf_none);

  if (TREE_CODE (callable) == COMPONENT_REF)
    {
      tree object = TREE_OPERAND (callable, 0);
      tree memfn = TREE_OPERAND (callable, 1);

      if (type_dependent_expression_p (object)
	  || (!BASELINK_P (memfn) && TREE_CODE (memfn) != FIELD_DECL)
	  || type_dependent_expression_p (memfn)
	  || any_type_dependent_arguments_p (args))
	call_expr = build_nt_call_vec (callable, args);
      else if (BASELINK_P (memfn))
	call_expr = build_new_method_call (object, memfn, &args, NULL_TREE,
					   qualified_p
					   ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
					   : LOOKUP_NORMAL,
					   NULL, tf_none);
      else
	call_expr = finish_call_expr (callable, &args, false, false, tf_none);
    }
  else if (TREE_CODE (callable) == OFFSET_REF
	   || TREE_CODE (callable) == MEMBER_REF
	   || TREE_CODE (callable) == DOTSTAR_EXPR)
    call_expr = build_offset_ref_call_from_tree (callable, &args, tf_none);
  else
    call_expr = finish_call_expr (callable, &args,
				  !!qualified_p, koenig_p, tf_none);

  release_tree_vector (args);
  return convert_out (ctx->preserve (call_expr));
}

gcc_type
plugin_get_expr_type (cc1_plugin::connection *self,
		      gcc_expr operand)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree op0 = convert_in (operand);
  tree type;
  if (op0)
    type = TREE_TYPE (op0);
  else
    type = make_decltype_auto ();
  return convert_out (ctx->preserve (type));
}

gcc_decl
plugin_build_function_template_specialization (cc1_plugin::connection *self,
					       gcc_decl template_decl,
					       const gcc_cp_template_args *targs,
					       gcc_address address,
					       const char *filename,
					       unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  location_t loc = ctx->get_location_t (filename, line_number);
  tree name = convert_in (template_decl);
  tree targsl = targlist (targs);

  tree decl = tsubst (name, targsl, tf_error, NULL_TREE);
  DECL_SOURCE_LOCATION (decl) = loc;

  record_decl_address (ctx, build_decl_addr_value (decl, address));

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

gcc_decl
plugin_build_class_template_specialization (cc1_plugin::connection *self,
					    gcc_decl template_decl,
					    const gcc_cp_template_args *args,
					    const char *filename,
					    unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  location_t loc = ctx->get_location_t (filename, line_number);
  tree name = convert_in (template_decl);

  tree tdecl = finish_template_type (name, targlist (args), false);;
  DECL_SOURCE_LOCATION (tdecl) = loc;

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

/* 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;
}

gcc_type
plugin_get_int_type (cc1_plugin::connection *self,
		     int is_unsigned, unsigned long size_in_bytes,
		     const char *builtin_name)
{
  tree result;

  if (builtin_name)
    {
      result = safe_lookup_builtin_type (builtin_name);
      gcc_assert (!result || TREE_CODE (result) == INTEGER_TYPE);
    }
  else
    result = c_common_type_for_size (BITS_PER_UNIT * size_in_bytes,
				     is_unsigned);

  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_get_char_type (cc1_plugin::connection *)
{
  return convert_out (char_type_node);
}

gcc_type
plugin_get_float_type (cc1_plugin::connection *,
		       unsigned long size_in_bytes,
		       const char *builtin_name)
{
  if (builtin_name)
    {
      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);
    }

  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_get_void_type (cc1_plugin::connection *)
{
  return convert_out (void_type_node);
}

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

gcc_type
plugin_get_nullptr_type (cc1_plugin::connection *)
{
  return convert_out (nullptr_type_node);
}

gcc_expr
plugin_get_nullptr_constant (cc1_plugin::connection *)
{
  return convert_out (nullptr_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_dependent_array_type (cc1_plugin::connection *self,
				   gcc_type element_type_in,
				   gcc_expr num_elements_in)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree element_type = convert_in (element_type_in);
  tree size = convert_in (num_elements_in);
  tree name = get_identifier ("dependent array type");

  processing_template_decl++;
  bool template_dependent_p = dependent_type_p (element_type)
    || type_dependent_expression_p (size)
    || value_dependent_expression_p (size);
  if (!template_dependent_p)
    processing_template_decl--;

  tree itype = compute_array_index_type (name, size, tf_error);
  tree type = build_cplus_array_type (element_type, itype);

  if (template_dependent_p)
    processing_template_decl--;

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

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 size = fold_build2 (PLUS_EXPR, TREE_TYPE (upper_bound), upper_bound,
			   build_one_cst (TREE_TYPE (upper_bound)));
  tree range = compute_array_index_type (NULL_TREE, size,
					 tf_error);

  tree result = build_cplus_array_type (element_type, range);

  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_cp_qualifiers qualifiers)
{
  tree unqualified_type = convert_in (unqualified_type_in);
  cp_cv_quals quals = 0;

  if ((qualifiers & GCC_CP_QUALIFIER_CONST) != 0)
    quals |= TYPE_QUAL_CONST;
  if ((qualifiers & GCC_CP_QUALIFIER_VOLATILE) != 0)
    quals |= TYPE_QUAL_VOLATILE;
  if ((qualifiers & GCC_CP_QUALIFIER_RESTRICT) != 0)
    quals |= TYPE_QUAL_RESTRICT;

  gcc_assert ((TREE_CODE (unqualified_type) != METHOD_TYPE
	       && TREE_CODE (unqualified_type) != REFERENCE_TYPE)
	      || quals == 0);

  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);
  if (!TYPE_READONLY (type))
    type = build_qualified_type (type, TYPE_QUAL_CONST);
  decl = build_decl (ctx->get_location_t (filename, line_number),
		     VAR_DECL, get_identifier (name), type);
  TREE_STATIC (decl) = 1;
  TREE_READONLY (decl) = 1;
  cp_finish_decl (decl, cst, true, NULL, LOOKUP_ONLYCONVERTING);
  safe_pushdecl (decl);

  return 1;
}

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

int
plugin_add_static_assert (cc1_plugin::connection *self,
			  gcc_expr condition_in,
			  const char *errormsg,
			  const char *filename,
			  unsigned int line_number)
{
  plugin_context *ctx = static_cast<plugin_context *> (self);
  tree condition = convert_in (condition_in);

  if (!errormsg)
    errormsg = "";

  tree message = build_string (strlen (errormsg) + 1, errormsg);

  TREE_TYPE (message) = char_array_type_node;
  fix_string_type (message);

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

  bool member_p = at_class_scope_p ();

  finish_static_assert (condition, message, loc, member_p, false);

  return 1;
}



#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_CP_FE_VERSION_0);

  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-cp-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;
}
