/* Separate lexical analyzer for GNU C++.
   Copyright (C) 1987-2021 Free Software Foundation, Inc.
   Hacked by Michael Tiemann (tiemann@cygnus.com)

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */


/* This file is the lexical analyzer for GNU C++.  */

#include "config.h"
/* For use with name_hint.  */
#define INCLUDE_UNIQUE_PTR
#include "system.h"
#include "coretypes.h"
#include "cp-tree.h"
#include "stringpool.h"
#include "c-family/c-pragma.h"
#include "c-family/c-objc.h"
#include "gcc-rich-location.h"
#include "cp-name-hint.h"
#include "langhooks.h"

static int interface_strcmp (const char *);
static void init_cp_pragma (void);

static tree parse_strconst_pragma (const char *, int);
static void handle_pragma_vtable (cpp_reader *);
static void handle_pragma_unit (cpp_reader *);
static void handle_pragma_interface (cpp_reader *);
static void handle_pragma_implementation (cpp_reader *);

static void init_operators (void);
static void copy_lang_type (tree);

/* A constraint that can be tested at compile time.  */
#define CONSTRAINT(name, expr) extern int constraint_##name [(expr) ? 1 : -1]

/* Functions and data structures for #pragma interface.

   `#pragma implementation' means that the main file being compiled
   is considered to implement (provide) the classes that appear in
   its main body.  I.e., if this is file "foo.cc", and class `bar'
   is defined in "foo.cc", then we say that "foo.cc implements bar".

   All main input files "implement" themselves automagically.

   `#pragma interface' means that unless this file (of the form "foo.h"
   is not presently being included by file "foo.cc", the
   CLASSTYPE_INTERFACE_ONLY bit gets set.  The effect is that none
   of the vtables nor any of the inline functions defined in foo.h
   will ever be output.

   There are cases when we want to link files such as "defs.h" and
   "main.cc".  In this case, we give "defs.h" a `#pragma interface',
   and "main.cc" has `#pragma implementation "defs.h"'.  */

struct impl_files
{
  const char *filename;
  struct impl_files *next;
};

static struct impl_files *impl_file_chain;

void
cxx_finish (void)
{
  c_common_finish ();
}

ovl_op_info_t ovl_op_info[2][OVL_OP_MAX] = 
  {
    {
      {NULL_TREE, NULL, NULL, ERROR_MARK, OVL_OP_ERROR_MARK, 0},
      {NULL_TREE, NULL, NULL, NOP_EXPR, OVL_OP_NOP_EXPR, 0},
#define DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS) \
      {NULL_TREE, NAME, MANGLING, CODE, OVL_OP_##CODE, FLAGS},
#define OPERATOR_TRANSITION }, {			\
      {NULL_TREE, NULL, NULL, ERROR_MARK, OVL_OP_ERROR_MARK, 0},
#include "operators.def"
    }
  };
unsigned char ovl_op_mapping[MAX_TREE_CODES];
unsigned char ovl_op_alternate[OVL_OP_MAX];

/* Get the name of the kind of identifier T.  */

const char *
get_identifier_kind_name (tree id)
{
  /* Keep in sync with cp_id_kind enumeration.  */
  static const char *const names[cik_max] = {
    "normal", "keyword", "constructor", "destructor",
    "simple-op", "assign-op", "conv-op", "<reserved>udlit-op"
  };

  unsigned kind = 0;
  kind |= IDENTIFIER_KIND_BIT_2 (id) << 2;
  kind |= IDENTIFIER_KIND_BIT_1 (id) << 1;
  kind |= IDENTIFIER_KIND_BIT_0 (id) << 0;

  return names[kind];
}

/* Set the identifier kind, which we expect to currently be zero.  */

void
set_identifier_kind (tree id, cp_identifier_kind kind)
{
  gcc_checking_assert (!IDENTIFIER_KIND_BIT_2 (id)
		       & !IDENTIFIER_KIND_BIT_1 (id)
		       & !IDENTIFIER_KIND_BIT_0 (id));
  IDENTIFIER_KIND_BIT_2 (id) |= (kind >> 2) & 1;
  IDENTIFIER_KIND_BIT_1 (id) |= (kind >> 1) & 1;
  IDENTIFIER_KIND_BIT_0 (id) |= (kind >> 0) & 1;
}

/* Create and tag the internal operator name for the overloaded
   operator PTR describes.  */

static tree
set_operator_ident (ovl_op_info_t *ptr)
{
  char buffer[32];
  size_t len = snprintf (buffer, sizeof (buffer), "operator%s%s",
			 &" "[ptr->name[0] && ptr->name[0] != '_'
			      && !ISALPHA (ptr->name[0])],
			 ptr->name);
  gcc_checking_assert (len < sizeof (buffer));

  tree ident = get_identifier_with_length (buffer, len);
  ptr->identifier = ident;

  return ident;
}

/* Initialize data structures that keep track of operator names.  */

static void
init_operators (void)
{
  /* We rely on both these being zero.  */
  gcc_checking_assert (!OVL_OP_ERROR_MARK && !ERROR_MARK);

  /* This loop iterates backwards because we need to move the
     assignment operators down to their correct slots.  I.e. morally
     equivalent to an overlapping memmove where dest > src.  Slot
     zero is for error_mark, so hae no operator. */
  for (unsigned ix = OVL_OP_MAX; --ix;)
    {
      ovl_op_info_t *op_ptr = &ovl_op_info[false][ix];

      if (op_ptr->name)
	{
	  tree ident = set_operator_ident (op_ptr);
	  if (unsigned index = IDENTIFIER_CP_INDEX (ident))
	    {
	      ovl_op_info_t *bin_ptr = &ovl_op_info[false][index];

	      /* They should only differ in unary/binary ness.  */
	      gcc_checking_assert ((op_ptr->flags ^ bin_ptr->flags)
				   == OVL_OP_FLAG_AMBIARY);
	      bin_ptr->flags |= op_ptr->flags;
	      ovl_op_alternate[index] = ix;
	    }
	  else
	    {
	      IDENTIFIER_CP_INDEX (ident) = ix;
	      set_identifier_kind (ident, cik_simple_op);
	    }
	}
      if (op_ptr->tree_code)
	{
	  gcc_checking_assert (op_ptr->ovl_op_code == ix
			       && !ovl_op_mapping[op_ptr->tree_code]);
	  ovl_op_mapping[op_ptr->tree_code] = op_ptr->ovl_op_code;
	}

      ovl_op_info_t *as_ptr = &ovl_op_info[true][ix];
      if (as_ptr->name)
	{
	  /* These will be placed at the start of the array, move to
	     the correct slot and initialize.  */
	  if (as_ptr->ovl_op_code != ix)
	    {
	      ovl_op_info_t *dst_ptr = &ovl_op_info[true][as_ptr->ovl_op_code];
	      gcc_assert (as_ptr->ovl_op_code > ix && !dst_ptr->tree_code);
	      memcpy (dst_ptr, as_ptr, sizeof (*dst_ptr));
	      memset (as_ptr, 0, sizeof (*as_ptr));
	      as_ptr = dst_ptr;
	    }

	  tree ident = set_operator_ident (as_ptr);
	  gcc_checking_assert (!IDENTIFIER_CP_INDEX (ident));
	  IDENTIFIER_CP_INDEX (ident) = as_ptr->ovl_op_code;
	  set_identifier_kind (ident, cik_assign_op);

	  gcc_checking_assert (!ovl_op_mapping[as_ptr->tree_code]
			       || (ovl_op_mapping[as_ptr->tree_code]
				   == as_ptr->ovl_op_code));
	  ovl_op_mapping[as_ptr->tree_code] = as_ptr->ovl_op_code;
	}
    }
}

/* Initialize the reserved words.  */

void
init_reswords (void)
{
  unsigned int i;
  tree id;
  int mask = 0;

  if (cxx_dialect < cxx11)
    mask |= D_CXX11;
  if (cxx_dialect < cxx20)
    mask |= D_CXX20;
  if (!flag_concepts)
    mask |= D_CXX_CONCEPTS;
  if (!flag_coroutines)
    mask |= D_CXX_COROUTINES;
  if (!flag_modules)
    mask |= D_CXX_MODULES;
  if (!flag_tm)
    mask |= D_TRANSMEM;
  if (!flag_char8_t)
    mask |= D_CXX_CHAR8_T;
  if (flag_no_asm)
    mask |= D_ASM | D_EXT;
  if (flag_no_gnu_keywords)
    mask |= D_EXT;

  /* The Objective-C keywords are all context-dependent.  */
  mask |= D_OBJC;

  ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
  for (i = 0; i < num_c_common_reswords; i++)
    {
      if (c_common_reswords[i].disable & D_CONLY)
	continue;
      id = get_identifier (c_common_reswords[i].word);
      C_SET_RID_CODE (id, c_common_reswords[i].rid);
      ridpointers [(int) c_common_reswords[i].rid] = id;
      if (! (c_common_reswords[i].disable & mask))
	set_identifier_kind (id, cik_keyword);
    }

  for (i = 0; i < NUM_INT_N_ENTS; i++)
    {
      char name[50];
      sprintf (name, "__int%d", int_n_data[i].bitsize);
      id = get_identifier (name);
      C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
      set_identifier_kind (id, cik_keyword);

      sprintf (name, "__int%d__", int_n_data[i].bitsize);
      id = get_identifier (name);
      C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
      set_identifier_kind (id, cik_keyword);
    }
}

static void
init_cp_pragma (void)
{
  c_register_pragma (0, "vtable", handle_pragma_vtable);
  c_register_pragma (0, "unit", handle_pragma_unit);
  c_register_pragma (0, "interface", handle_pragma_interface);
  c_register_pragma (0, "implementation", handle_pragma_implementation);
  c_register_pragma ("GCC", "interface", handle_pragma_interface);
  c_register_pragma ("GCC", "implementation", handle_pragma_implementation);
}

/* TRUE if a code represents a statement.  */

bool statement_code_p[MAX_TREE_CODES];

/* Initialize the C++ front end.  This function is very sensitive to
   the exact order that things are done here.  It would be nice if the
   initialization done by this routine were moved to its subroutines,
   and the ordering dependencies clarified and reduced.  */
bool
cxx_init (void)
{
  location_t saved_loc;
  unsigned int i;
  static const enum tree_code stmt_codes[] = {
   CTOR_INITIALIZER,	TRY_BLOCK,	HANDLER,
   EH_SPEC_BLOCK,	USING_STMT,	TAG_DEFN,
   IF_STMT,		CLEANUP_STMT,	FOR_STMT,
   RANGE_FOR_STMT,	WHILE_STMT,	DO_STMT,
   BREAK_STMT,		CONTINUE_STMT,	SWITCH_STMT,
   EXPR_STMT,		OMP_DEPOBJ
  };

  memset (&statement_code_p, 0, sizeof (statement_code_p));
  for (i = 0; i < ARRAY_SIZE (stmt_codes); i++)
    statement_code_p[stmt_codes[i]] = true;

  saved_loc = input_location;
  input_location = BUILTINS_LOCATION;

  init_reswords ();
  init_tree ();
  init_cp_semantics ();
  init_operators ();
  init_method ();

  current_function_decl = NULL;

  class_type_node = ridpointers[(int) RID_CLASS];

  cxx_init_decl_processing ();

  if (c_common_init () == false)
    {
      input_location = saved_loc;
      return false;
    }

  init_cp_pragma ();

  input_location = saved_loc;
  return true;
}

/* Return nonzero if S is not considered part of an
   INTERFACE/IMPLEMENTATION pair.  Otherwise, return 0.  */

static int
interface_strcmp (const char* s)
{
  /* Set the interface/implementation bits for this scope.  */
  struct impl_files *ifiles;
  const char *s1;

  for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
    {
      const char *t1 = ifiles->filename;
      s1 = s;

      if (*s1 == 0 || filename_ncmp (s1, t1, 1) != 0)
	continue;

      while (*s1 != 0 && filename_ncmp (s1, t1, 1) == 0)
	s1++, t1++;

      /* A match.  */
      if (*s1 == *t1)
	return 0;

      /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc.  */
      if (strchr (s1, '.') || strchr (t1, '.'))
	continue;

      if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
	continue;

      /* A match.  */
      return 0;
    }

  /* No matches.  */
  return 1;
}

/* We've just read a cpp-token, figure out our next state.  Hey, this
   is a hand-coded co-routine!  */

struct module_token_filter
{
  enum state
  {
   idle,
   module_first,
   module_cont,
   module_end,
  };

  enum state state : 8;
  bool is_import : 1;
  bool got_export : 1;
  bool got_colon : 1;
  bool want_dot : 1;

  location_t token_loc;
  cpp_reader *reader;
  module_state *module;
  module_state *import;

  module_token_filter (cpp_reader *reader)
    : state (idle), is_import (false),
    got_export (false), got_colon (false), want_dot (false),
    token_loc (UNKNOWN_LOCATION),
    reader (reader), module (NULL), import (NULL)
  {
  };

  /* Process the next token.  Note we cannot see CPP_EOF inside a
     pragma -- a CPP_PRAGMA_EOL always happens.  */
  uintptr_t resume (int type, int keyword, tree value, location_t loc)
  {
    unsigned res = 0;

    switch (state)
      {
      case idle:
	if (type == CPP_KEYWORD)
	  switch (keyword)
	    {
	    default:
	      break;

	    case RID__EXPORT:
	      got_export = true;
	      res = lang_hooks::PT_begin_pragma;
	      break;

	    case RID__IMPORT:
	      is_import = true;
	      /* FALLTHRU */
	    case RID__MODULE:
	      state = module_first;
	      want_dot = false;
	      got_colon = false;
	      token_loc = loc;
	      import = NULL;
	      if (!got_export)
		res = lang_hooks::PT_begin_pragma;
	      break;
	    }
	break;

      case module_first:
	if (is_import && type == CPP_HEADER_NAME)
	  {
	    /* A header name.  The preprocessor will have already
	       done include searching and canonicalization.  */
	    state = module_end;
	    goto header_unit;
	  }
	
	if (type == CPP_PADDING || type == CPP_COMMENT)
	  break;

	state = module_cont;
	if (type == CPP_COLON && module)
	  {
	    got_colon = true;
	    import = module;
	    break;
	  }
	/* FALLTHROUGH  */

      case module_cont:
	switch (type)
	  {
	  case CPP_PADDING:
	  case CPP_COMMENT:
	    break;

	  default:
	    /* If we ever need to pay attention to attributes for
	       header modules, more logic will be needed.  */
	    state = module_end;
	    break;

	  case CPP_COLON:
	    if (got_colon)
	      state = module_end;
	    got_colon = true;
	    /* FALLTHROUGH  */
	  case CPP_DOT:
	    if (!want_dot)
	      state = module_end;
	    want_dot = false;
	    break;

	  case CPP_PRAGMA_EOL:
	    goto module_end;

	  case CPP_NAME:
	    if (want_dot)
	      {
		/* Got name instead of [.:].  */
		state = module_end;
		break;
	      }
	  header_unit:
	    import = get_module (value, import, got_colon);
	    want_dot = true;
	    break;
	  }
	break;

      case module_end:
	if (type == CPP_PRAGMA_EOL)
	  {
	  module_end:;
	    /* End of the directive, handle the name.  */
	    if (import && (is_import || !flag_header_unit))
	      if (module_state *m
		  = preprocess_module (import, token_loc, module != NULL,
				       is_import, got_export, reader))
		if (!module)
		  module = m;

	    is_import = got_export = false;
	    state = idle;
	  }
	break;
      }

    return res;
  }
};

/* Initialize or teardown.  */

uintptr_t
module_token_cdtor (cpp_reader *pfile, uintptr_t data_)
{
  if (module_token_filter *filter = reinterpret_cast<module_token_filter *> (data_))
    {
      preprocessed_module (pfile);
      delete filter;
      data_ = 0;
    }
  else if (modules_p ())
    data_ = reinterpret_cast<uintptr_t > (new module_token_filter (pfile));

  return data_;
}

uintptr_t
module_token_lang (int type, int keyword, tree value, location_t loc,
		   uintptr_t data_)
{
  module_token_filter *filter = reinterpret_cast<module_token_filter *> (data_);
  return filter->resume (type, keyword, value, loc);
}

uintptr_t
module_token_pre (cpp_reader *pfile, const cpp_token *tok, uintptr_t data_)
{
  if (!tok)
    return module_token_cdtor (pfile, data_);

  int type = tok->type;
  int keyword = RID_MAX;
  tree value = NULL_TREE;

  if (tok->type == CPP_NAME)
    {
      value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node.node));
      if (IDENTIFIER_KEYWORD_P (value))
	{
	  keyword = C_RID_CODE (value);
	  type = CPP_KEYWORD;
	}
    }
  else if (tok->type == CPP_HEADER_NAME)
    value = build_string (tok->val.str.len, (const char *)tok->val.str.text);

  return module_token_lang (type, keyword, value, tok->src_loc, data_);
}

/* Parse a #pragma whose sole argument is a string constant.
   If OPT is true, the argument is optional.  */
static tree
parse_strconst_pragma (const char* name, int opt)
{
  tree result, x;
  enum cpp_ttype t;

  t = pragma_lex (&result);
  if (t == CPP_STRING)
    {
      if (pragma_lex (&x) != CPP_EOF)
	warning (0, "junk at end of %<#pragma %s%>", name);
      return result;
    }

  if (t == CPP_EOF && opt)
    return NULL_TREE;

  error ("invalid %<#pragma %s%>", name);
  return error_mark_node;
}

static void
handle_pragma_vtable (cpp_reader* /*dfile*/)
{
  parse_strconst_pragma ("vtable", 0);
  sorry ("%<#pragma vtable%> no longer supported");
}

static void
handle_pragma_unit (cpp_reader* /*dfile*/)
{
  /* Validate syntax, but don't do anything.  */
  parse_strconst_pragma ("unit", 0);
}

static void
handle_pragma_interface (cpp_reader* /*dfile*/)
{
  tree fname = parse_strconst_pragma ("interface", 1);
  struct c_fileinfo *finfo;
  const char *filename;

  if (fname == error_mark_node)
    return;
  else if (fname == 0)
    filename = lbasename (LOCATION_FILE (input_location));
  else
    filename = TREE_STRING_POINTER (fname);

  finfo = get_fileinfo (LOCATION_FILE (input_location));

  if (impl_file_chain == 0)
    {
      /* If this is zero at this point, then we are
	 auto-implementing.  */
      if (main_input_filename == 0)
	main_input_filename = LOCATION_FILE (input_location);
    }

  finfo->interface_only = interface_strcmp (filename);
  /* If MULTIPLE_SYMBOL_SPACES is set, we cannot assume that we can see
     a definition in another file.  */
  if (!MULTIPLE_SYMBOL_SPACES || !finfo->interface_only)
    finfo->interface_unknown = 0;
}

/* Note that we have seen a #pragma implementation for the key MAIN_FILENAME.
   We used to only allow this at toplevel, but that restriction was buggy
   in older compilers and it seems reasonable to allow it in the headers
   themselves, too.  It only needs to precede the matching #p interface.

   We don't touch finfo->interface_only or finfo->interface_unknown;
   the user must specify a matching #p interface for this to have
   any effect.  */

static void
handle_pragma_implementation (cpp_reader* /*dfile*/)
{
  tree fname = parse_strconst_pragma ("implementation", 1);
  const char *filename;
  struct impl_files *ifiles = impl_file_chain;

  if (fname == error_mark_node)
    return;

  if (fname == 0)
    {
      if (main_input_filename)
	filename = main_input_filename;
      else
	filename = LOCATION_FILE (input_location);
      filename = lbasename (filename);
    }
  else
    {
      filename = TREE_STRING_POINTER (fname);
      if (cpp_included_before (parse_in, filename, input_location))
	warning (0, "%<#pragma implementation%> for %qs appears after "
		 "file is included", filename);
    }

  for (; ifiles; ifiles = ifiles->next)
    {
      if (! filename_cmp (ifiles->filename, filename))
	break;
    }
  if (ifiles == 0)
    {
      ifiles = XNEW (struct impl_files);
      ifiles->filename = xstrdup (filename);
      ifiles->next = impl_file_chain;
      impl_file_chain = ifiles;
    }
}

/* Issue an error message indicating that the lookup of NAME (an
   IDENTIFIER_NODE) failed.  Returns the ERROR_MARK_NODE.  */

tree
unqualified_name_lookup_error (tree name, location_t loc)
{
  if (loc == UNKNOWN_LOCATION)
    loc = cp_expr_loc_or_input_loc (name);

  if (IDENTIFIER_ANY_OP_P (name))
    error_at (loc, "%qD not defined", name);
  else
    {
      if (!objc_diagnose_private_ivar (name))
	{
	  auto_diagnostic_group d;
	  name_hint hint = suggest_alternatives_for (loc, name, true);
	  if (const char *suggestion = hint.suggestion ())
	    {
	      gcc_rich_location richloc (loc);
	      richloc.add_fixit_replace (suggestion);
	      error_at (&richloc,
			"%qD was not declared in this scope; did you mean %qs?",
			name, suggestion);
	    }
	  else
	    error_at (loc, "%qD was not declared in this scope", name);
	}
      /* Prevent repeated error messages by creating a VAR_DECL with
	 this NAME in the innermost block scope.  */
      if (local_bindings_p ())
	{
	  tree decl = build_decl (loc, VAR_DECL, name, error_mark_node);
	  TREE_USED (decl) = true;
	  pushdecl (decl);
	}
    }

  return error_mark_node;
}

/* Like unqualified_name_lookup_error, but NAME_EXPR is an unqualified-id
   NAME, encapsulated with its location in a CP_EXPR, used as a function.
   Returns an appropriate expression for NAME.  */

tree
unqualified_fn_lookup_error (cp_expr name_expr)
{
  tree name = name_expr.get_value ();
  location_t loc = name_expr.get_location ();
  if (loc == UNKNOWN_LOCATION)
    loc = input_location;

  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
    name = TREE_OPERAND (name, 0);

  if (processing_template_decl)
    {
      /* In a template, it is invalid to write "f()" or "f(3)" if no
	 declaration of "f" is available.  Historically, G++ and most
	 other compilers accepted that usage since they deferred all name
	 lookup until instantiation time rather than doing unqualified
	 name lookup at template definition time; explain to the user what
	 is going wrong.

	 Note that we have the exact wording of the following message in
	 the manual (trouble.texi, node "Name lookup"), so they need to
	 be kept in synch.  */
      permerror (loc, "there are no arguments to %qD that depend on a template "
		 "parameter, so a declaration of %qD must be available",
		 name, name);

      if (!flag_permissive)
	{
	  static bool hint;
	  if (!hint)
	    {
	      inform (loc, "(if you use %<-fpermissive%>, G++ will accept your "
		      "code, but allowing the use of an undeclared name is "
		      "deprecated)");
	      hint = true;
	    }
	}
      return name;
    }

  return unqualified_name_lookup_error (name, loc);
}


/* Hasher for the conversion operator name hash table.  */
struct conv_type_hasher : ggc_ptr_hash<tree_node>
{
  /* Hash NODE, an identifier node in the table.  TYPE_UID is
     suitable, as we're not concerned about matching canonicalness
     here.  */
  static hashval_t hash (tree node)
  {
    return (hashval_t) TYPE_UID (TREE_TYPE (node));
  }

  /* Compare NODE, an identifier node in the table, against TYPE, an
     incoming TYPE being looked up.  */
  static bool equal (tree node, tree type)
  {
    return TREE_TYPE (node) == type;
  }
};

/* This hash table maps TYPEs to the IDENTIFIER for a conversion
   operator to TYPE.  The nodes are IDENTIFIERs whose TREE_TYPE is the
   TYPE.  */

static GTY (()) hash_table<conv_type_hasher> *conv_type_names;

/* Return an identifier for a conversion operator to TYPE.  We can get
   from the returned identifier to the type.  We store TYPE, which is
   not necessarily the canonical type,  which allows us to report the
   form the user used in error messages.  All these identifiers are
   not in the identifier hash table, and have the same string name.
   These IDENTIFIERS are not in the identifier hash table, and all
   have the same IDENTIFIER_STRING.  */

tree
make_conv_op_name (tree type)
{
  if (type == error_mark_node)
    return error_mark_node;

  if (conv_type_names == NULL)
    conv_type_names = hash_table<conv_type_hasher>::create_ggc (31);

  tree *slot = conv_type_names->find_slot_with_hash
    (type, (hashval_t) TYPE_UID (type), INSERT);
  tree identifier = *slot;
  if (!identifier)
    {
      /* Create a raw IDENTIFIER outside of the identifier hash
	 table.  */
      identifier = copy_node (conv_op_identifier);

      /* Just in case something managed to bind.  */
      IDENTIFIER_BINDING (identifier) = NULL;

      /* Hang TYPE off the identifier so it can be found easily later
	 when performing conversions.  */
      TREE_TYPE (identifier) = type;

      *slot = identifier;
    }

  return identifier;
}

/* Wrapper around build_lang_decl_loc(). Should gradually move to
   build_lang_decl_loc() and then rename build_lang_decl_loc() back to
   build_lang_decl().  */

tree
build_lang_decl (enum tree_code code, tree name, tree type)
{
  return build_lang_decl_loc (input_location, code, name, type);
}

/* Build a decl from CODE, NAME, TYPE declared at LOC, and then add
   DECL_LANG_SPECIFIC info to the result.  */

tree
build_lang_decl_loc (location_t loc, enum tree_code code, tree name, tree type)
{
  tree t;

  t = build_decl (loc, code, name, type);
  retrofit_lang_decl (t);

  return t;
}

/* Maybe add a raw lang_decl to T, a decl.  Return true if it needed
   one.  */

bool
maybe_add_lang_decl_raw (tree t, bool decomp_p)
{
  size_t size;
  lang_decl_selector sel;

  if (decomp_p)
    sel = lds_decomp, size = sizeof (struct lang_decl_decomp);
  else if (TREE_CODE (t) == FUNCTION_DECL)
    sel = lds_fn, size = sizeof (struct lang_decl_fn);
  else if (TREE_CODE (t) == NAMESPACE_DECL)
    sel = lds_ns, size = sizeof (struct lang_decl_ns);
  else if (TREE_CODE (t) == PARM_DECL)
    sel = lds_parm, size = sizeof (struct lang_decl_parm);
  else if (LANG_DECL_HAS_MIN (t))
    sel = lds_min, size = sizeof (struct lang_decl_min);
  else
    return false;

  struct lang_decl *ld
    = (struct lang_decl *) ggc_internal_cleared_alloc (size);

  ld->u.base.selector = sel;
  DECL_LANG_SPECIFIC (t) = ld;

  if (sel == lds_ns)
    /* Who'd create a namespace, only to put nothing in it?  */
    ld->u.ns.bindings = hash_table<named_decl_hash>::create_ggc (499);

  if (GATHER_STATISTICS)
    {
      tree_node_counts[(int)lang_decl] += 1;
      tree_node_sizes[(int)lang_decl] += size;
    }
  return true;
}

/* T has just had a decl_lang_specific added.  Initialize its
   linkage.  */

static void
set_decl_linkage (tree t)
{
  if (current_lang_name == lang_name_cplusplus
      || decl_linkage (t) == lk_none)
    SET_DECL_LANGUAGE (t, lang_cplusplus);
  else if (current_lang_name == lang_name_c)
    SET_DECL_LANGUAGE (t, lang_c);
  else
    gcc_unreachable ();
}

/* T is a VAR_DECL node that needs to be a decomposition of BASE.  */

void
fit_decomposition_lang_decl (tree t, tree base)
{
  if (struct lang_decl *orig_ld = DECL_LANG_SPECIFIC (t))
    {
      if (orig_ld->u.base.selector == lds_min)
	{
	  maybe_add_lang_decl_raw (t, true);
	  memcpy (DECL_LANG_SPECIFIC (t), orig_ld,
		  sizeof (struct lang_decl_min));
	  /* Reset selector, which will have been bashed by the
	     memcpy.  */
	  DECL_LANG_SPECIFIC (t)->u.base.selector = lds_decomp;
	}
      else
	gcc_checking_assert (orig_ld->u.base.selector == lds_decomp);
    }
  else
    {
      maybe_add_lang_decl_raw (t, true);
      set_decl_linkage (t);
    }

  DECL_DECOMP_BASE (t) = base;
}

/* Add DECL_LANG_SPECIFIC info to T, if it needs one.  Generally
   every C++ decl needs one, but C builtins etc do not.   */

void
retrofit_lang_decl (tree t)
{
  if (DECL_LANG_SPECIFIC (t))
    return;

  if (maybe_add_lang_decl_raw (t, false))
    set_decl_linkage (t);
}

void
cxx_dup_lang_specific_decl (tree node)
{
  int size;

  if (! DECL_LANG_SPECIFIC (node))
    return;

  switch (DECL_LANG_SPECIFIC (node)->u.base.selector)
    {
    case lds_min:
      size = sizeof (struct lang_decl_min);
      break;
    case lds_fn:
      size = sizeof (struct lang_decl_fn);
      break;
    case lds_ns:
      size = sizeof (struct lang_decl_ns);
      break;
    case lds_parm:
      size = sizeof (struct lang_decl_parm);
      break;
    case lds_decomp:
      size = sizeof (struct lang_decl_decomp);
      break;
    default:
      gcc_unreachable ();
    }

  struct lang_decl *ld = (struct lang_decl *) ggc_internal_alloc (size);
  memcpy (ld, DECL_LANG_SPECIFIC (node), size);
  DECL_LANG_SPECIFIC (node) = ld;

  /* Directly clear some flags that do not apply to the copy
     (module_purview_p still does).  */
  ld->u.base.module_entity_p = false;
  ld->u.base.module_import_p = false;
  ld->u.base.module_attached_p = false;
  
  if (GATHER_STATISTICS)
    {
      tree_node_counts[(int)lang_decl] += 1;
      tree_node_sizes[(int)lang_decl] += size;
    }
}

/* Copy DECL, including any language-specific parts.  */

tree
copy_decl (tree decl MEM_STAT_DECL)
{
  tree copy;

  copy = copy_node (decl PASS_MEM_STAT);
  cxx_dup_lang_specific_decl (copy);
  return copy;
}

/* Replace the shared language-specific parts of NODE with a new copy.  */

static void
copy_lang_type (tree node)
{
  if (! TYPE_LANG_SPECIFIC (node))
    return;

  auto *lt = (struct lang_type *) ggc_internal_alloc (sizeof (struct lang_type));

  memcpy (lt, TYPE_LANG_SPECIFIC (node), (sizeof (struct lang_type)));
  TYPE_LANG_SPECIFIC (node) = lt;

  if (GATHER_STATISTICS)
    {
      tree_node_counts[(int)lang_type] += 1;
      tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
    }
}

/* Copy TYPE, including any language-specific parts.  */

tree
copy_type (tree type MEM_STAT_DECL)
{
  tree copy;

  copy = copy_node (type PASS_MEM_STAT);
  copy_lang_type (copy);
  return copy;
}

/* Add a raw lang_type to T, a type, should it need one.  */

bool
maybe_add_lang_type_raw (tree t)
{
  if (!RECORD_OR_UNION_CODE_P (TREE_CODE (t)))
    return false;
  
  auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc
				   (sizeof (struct lang_type)));
  TYPE_LANG_SPECIFIC (t) = lt;

  if (GATHER_STATISTICS)
    {
      tree_node_counts[(int)lang_type] += 1;
      tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
    }

  return true;
}

tree
cxx_make_type (enum tree_code code MEM_STAT_DECL)
{
  tree t = make_node (code PASS_MEM_STAT);

  if (maybe_add_lang_type_raw (t))
    {
      /* Set up some flags that give proper default behavior.  */
      struct c_fileinfo *finfo =
	get_fileinfo (LOCATION_FILE (input_location));
      SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
      CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
    }

  if (code == RECORD_TYPE || code == UNION_TYPE)
    TYPE_CXX_ODR_P (t) = 1;

  return t;
}

/* A wrapper without the memory stats for LANG_HOOKS_MAKE_TYPE.  */

tree
cxx_make_type_hook (enum tree_code code)
{
  return cxx_make_type (code);
}

tree
make_class_type (enum tree_code code MEM_STAT_DECL)
{
  tree t = cxx_make_type (code PASS_MEM_STAT);
  SET_CLASS_TYPE_P (t, 1);
  return t;
}

/* Returns true if we are currently in the main source file, or in a
   template instantiation started from the main source file.  */

bool
in_main_input_context (void)
{
  struct tinst_level *tl = outermost_tinst_level();

  if (tl)
    return filename_cmp (main_input_filename,
			 LOCATION_FILE (tl->locus)) == 0;
  else
    return filename_cmp (main_input_filename, LOCATION_FILE (input_location)) == 0;
}

#include "gt-cp-lex.h"
