/* 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)
	{
	  /* Make sure it fits in lang_decl_fn::operator_code. */
	  gcc_checking_assert (op_ptr->ovl_op_code < (1 << 6));
	  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"
