/* Language-independent node constructors for parse phase of GNU compiler.
   Copyright (C) 1987-2018 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

/* This file contains the low level primitives for operating on tree nodes,
   including allocation, list operations, interning of identifiers,
   construction of data type nodes and statement nodes,
   and construction of type conversion nodes.  It also contains
   tables index by tree code that describe how to take apart
   nodes of that code.

   It is intended to be language-independent but can occasionally
   calls language-dependent routines.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "diagnostic.h"
#include "flags.h"
#include "alias.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "calls.h"
#include "attribs.h"
#include "toplev.h" /* get_random_seed */
#include "output.h"
#include "common/common-target.h"
#include "langhooks.h"
#include "tree-inline.h"
#include "tree-iterator.h"
#include "internal-fn.h"
#include "gimple-iterator.h"
#include "gimplify.h"
#include "tree-dfa.h"
#include "params.h"
#include "langhooks-def.h"
#include "tree-diagnostic.h"
#include "except.h"
#include "builtins.h"
#include "print-tree.h"
#include "ipa-utils.h"
#include "selftest.h"
#include "stringpool.h"
#include "attribs.h"
#include "rtl.h"
#include "regs.h"
#include "tree-vector-builder.h"

/* Tree code classes.  */

#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
#define END_OF_BASE_TREE_CODES tcc_exceptional,

const enum tree_code_class tree_code_type[] = {
#include "all-tree.def"
};

#undef DEFTREECODE
#undef END_OF_BASE_TREE_CODES

/* Table indexed by tree code giving number of expression
   operands beyond the fixed part of the node structure.
   Not used for types or decls.  */

#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
#define END_OF_BASE_TREE_CODES 0,

const unsigned char tree_code_length[] = {
#include "all-tree.def"
};

#undef DEFTREECODE
#undef END_OF_BASE_TREE_CODES

/* Names of tree components.
   Used for printing out the tree and error messages.  */
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
#define END_OF_BASE_TREE_CODES "@dummy",

static const char *const tree_code_name[] = {
#include "all-tree.def"
};

#undef DEFTREECODE
#undef END_OF_BASE_TREE_CODES

/* Each tree code class has an associated string representation.
   These must correspond to the tree_code_class entries.  */

const char *const tree_code_class_strings[] =
{
  "exceptional",
  "constant",
  "type",
  "declaration",
  "reference",
  "comparison",
  "unary",
  "binary",
  "statement",
  "vl_exp",
  "expression"
};

/* obstack.[ch] explicitly declined to prototype this.  */
extern int _obstack_allocated_p (struct obstack *h, void *obj);

/* Statistics-gathering stuff.  */

static uint64_t tree_code_counts[MAX_TREE_CODES];
uint64_t tree_node_counts[(int) all_kinds];
uint64_t tree_node_sizes[(int) all_kinds];

/* Keep in sync with tree.h:enum tree_node_kind.  */
static const char * const tree_node_kind_names[] = {
  "decls",
  "types",
  "blocks",
  "stmts",
  "refs",
  "exprs",
  "constants",
  "identifiers",
  "vecs",
  "binfos",
  "ssa names",
  "constructors",
  "random kinds",
  "lang_decl kinds",
  "lang_type kinds",
  "omp clauses",
};

/* Unique id for next decl created.  */
static GTY(()) int next_decl_uid;
/* Unique id for next type created.  */
static GTY(()) unsigned next_type_uid = 1;
/* Unique id for next debug decl created.  Use negative numbers,
   to catch erroneous uses.  */
static GTY(()) int next_debug_decl_uid;

/* Since we cannot rehash a type after it is in the table, we have to
   keep the hash code.  */

struct GTY((for_user)) type_hash {
  unsigned long hash;
  tree type;
};

/* Initial size of the hash table (rounded to next prime).  */
#define TYPE_HASH_INITIAL_SIZE 1000

struct type_cache_hasher : ggc_cache_ptr_hash<type_hash>
{
  static hashval_t hash (type_hash *t) { return t->hash; }
  static bool equal (type_hash *a, type_hash *b);

  static int
  keep_cache_entry (type_hash *&t)
  {
    return ggc_marked_p (t->type);
  }
};

/* Now here is the hash table.  When recording a type, it is added to
   the slot whose index is the hash code.  Note that the hash table is
   used for several kinds of types (function types, array types and
   array index range types, for now).  While all these live in the
   same table, they are completely independent, and the hash code is
   computed differently for each of these.  */

static GTY ((cache)) hash_table<type_cache_hasher> *type_hash_table;

/* Hash table and temporary node for larger integer const values.  */
static GTY (()) tree int_cst_node;

struct int_cst_hasher : ggc_cache_ptr_hash<tree_node>
{
  static hashval_t hash (tree t);
  static bool equal (tree x, tree y);
};

static GTY ((cache)) hash_table<int_cst_hasher> *int_cst_hash_table;

/* Class and variable for making sure that there is a single POLY_INT_CST
   for a given value.  */
struct poly_int_cst_hasher : ggc_cache_ptr_hash<tree_node>
{
  typedef std::pair<tree, const poly_wide_int *> compare_type;
  static hashval_t hash (tree t);
  static bool equal (tree x, const compare_type &y);
};

static GTY ((cache)) hash_table<poly_int_cst_hasher> *poly_int_cst_hash_table;

/* Hash table for optimization flags and target option flags.  Use the same
   hash table for both sets of options.  Nodes for building the current
   optimization and target option nodes.  The assumption is most of the time
   the options created will already be in the hash table, so we avoid
   allocating and freeing up a node repeatably.  */
static GTY (()) tree cl_optimization_node;
static GTY (()) tree cl_target_option_node;

struct cl_option_hasher : ggc_cache_ptr_hash<tree_node>
{
  static hashval_t hash (tree t);
  static bool equal (tree x, tree y);
};

static GTY ((cache)) hash_table<cl_option_hasher> *cl_option_hash_table;

/* General tree->tree mapping  structure for use in hash tables.  */


static GTY ((cache))
     hash_table<tree_decl_map_cache_hasher> *debug_expr_for_decl;

static GTY ((cache))
     hash_table<tree_decl_map_cache_hasher> *value_expr_for_decl;

struct tree_vec_map_cache_hasher : ggc_cache_ptr_hash<tree_vec_map>
{
  static hashval_t hash (tree_vec_map *m) { return DECL_UID (m->base.from); }

  static bool
  equal (tree_vec_map *a, tree_vec_map *b)
  {
    return a->base.from == b->base.from;
  }

  static int
  keep_cache_entry (tree_vec_map *&m)
  {
    return ggc_marked_p (m->base.from);
  }
};

static GTY ((cache))
     hash_table<tree_vec_map_cache_hasher> *debug_args_for_decl;

static void set_type_quals (tree, int);
static void print_type_hash_statistics (void);
static void print_debug_expr_statistics (void);
static void print_value_expr_statistics (void);

static tree build_array_type_1 (tree, tree, bool, bool);

tree global_trees[TI_MAX];
tree integer_types[itk_none];

bool int_n_enabled_p[NUM_INT_N_ENTS];
struct int_n_trees_t int_n_trees [NUM_INT_N_ENTS];

bool tree_contains_struct[MAX_TREE_CODES][64];

/* Number of operands for each OpenMP clause.  */
unsigned const char omp_clause_num_ops[] =
{
  0, /* OMP_CLAUSE_ERROR  */
  1, /* OMP_CLAUSE_PRIVATE  */
  1, /* OMP_CLAUSE_SHARED  */
  1, /* OMP_CLAUSE_FIRSTPRIVATE  */
  2, /* OMP_CLAUSE_LASTPRIVATE  */
  5, /* OMP_CLAUSE_REDUCTION  */
  5, /* OMP_CLAUSE_TASK_REDUCTION  */
  5, /* OMP_CLAUSE_IN_REDUCTION  */
  1, /* OMP_CLAUSE_COPYIN  */
  1, /* OMP_CLAUSE_COPYPRIVATE  */
  3, /* OMP_CLAUSE_LINEAR  */
  2, /* OMP_CLAUSE_ALIGNED  */
  1, /* OMP_CLAUSE_DEPEND  */
  1, /* OMP_CLAUSE_NONTEMPORAL  */
  1, /* OMP_CLAUSE_UNIFORM  */
  1, /* OMP_CLAUSE_TO_DECLARE  */
  1, /* OMP_CLAUSE_LINK  */
  2, /* OMP_CLAUSE_FROM  */
  2, /* OMP_CLAUSE_TO  */
  2, /* OMP_CLAUSE_MAP  */
  1, /* OMP_CLAUSE_USE_DEVICE_PTR  */
  1, /* OMP_CLAUSE_IS_DEVICE_PTR  */
  2, /* OMP_CLAUSE__CACHE_  */
  2, /* OMP_CLAUSE_GANG  */
  1, /* OMP_CLAUSE_ASYNC  */
  1, /* OMP_CLAUSE_WAIT  */
  0, /* OMP_CLAUSE_AUTO  */
  0, /* OMP_CLAUSE_SEQ  */
  1, /* OMP_CLAUSE__LOOPTEMP_  */
  1, /* OMP_CLAUSE__REDUCTEMP_  */
  1, /* OMP_CLAUSE_IF  */
  1, /* OMP_CLAUSE_NUM_THREADS  */
  1, /* OMP_CLAUSE_SCHEDULE  */
  0, /* OMP_CLAUSE_NOWAIT  */
  1, /* OMP_CLAUSE_ORDERED  */
  0, /* OMP_CLAUSE_DEFAULT  */
  3, /* OMP_CLAUSE_COLLAPSE  */
  0, /* OMP_CLAUSE_UNTIED   */
  1, /* OMP_CLAUSE_FINAL  */
  0, /* OMP_CLAUSE_MERGEABLE  */
  1, /* OMP_CLAUSE_DEVICE  */
  1, /* OMP_CLAUSE_DIST_SCHEDULE  */
  0, /* OMP_CLAUSE_INBRANCH  */
  0, /* OMP_CLAUSE_NOTINBRANCH  */
  1, /* OMP_CLAUSE_NUM_TEAMS  */
  1, /* OMP_CLAUSE_THREAD_LIMIT  */
  0, /* OMP_CLAUSE_PROC_BIND  */
  1, /* OMP_CLAUSE_SAFELEN  */
  1, /* OMP_CLAUSE_SIMDLEN  */
  0, /* OMP_CLAUSE_FOR  */
  0, /* OMP_CLAUSE_PARALLEL  */
  0, /* OMP_CLAUSE_SECTIONS  */
  0, /* OMP_CLAUSE_TASKGROUP  */
  1, /* OMP_CLAUSE_PRIORITY  */
  1, /* OMP_CLAUSE_GRAINSIZE  */
  1, /* OMP_CLAUSE_NUM_TASKS  */
  0, /* OMP_CLAUSE_NOGROUP  */
  0, /* OMP_CLAUSE_THREADS  */
  0, /* OMP_CLAUSE_SIMD  */
  1, /* OMP_CLAUSE_HINT  */
  0, /* OMP_CLAUSE_DEFALTMAP  */
  1, /* OMP_CLAUSE__SIMDUID_  */
  0, /* OMP_CLAUSE__SIMT_  */
  0, /* OMP_CLAUSE_INDEPENDENT  */
  1, /* OMP_CLAUSE_WORKER  */
  1, /* OMP_CLAUSE_VECTOR  */
  1, /* OMP_CLAUSE_NUM_GANGS  */
  1, /* OMP_CLAUSE_NUM_WORKERS  */
  1, /* OMP_CLAUSE_VECTOR_LENGTH  */
  3, /* OMP_CLAUSE_TILE  */
  2, /* OMP_CLAUSE__GRIDDIM_  */
  0, /* OMP_CLAUSE_IF_PRESENT */
  0, /* OMP_CLAUSE_FINALIZE */
};

const char * const omp_clause_code_name[] =
{
  "error_clause",
  "private",
  "shared",
  "firstprivate",
  "lastprivate",
  "reduction",
  "task_reduction",
  "in_reduction",
  "copyin",
  "copyprivate",
  "linear",
  "aligned",
  "depend",
  "nontemporal",
  "uniform",
  "to",
  "link",
  "from",
  "to",
  "map",
  "use_device_ptr",
  "is_device_ptr",
  "_cache_",
  "gang",
  "async",
  "wait",
  "auto",
  "seq",
  "_looptemp_",
  "_reductemp_",
  "if",
  "num_threads",
  "schedule",
  "nowait",
  "ordered",
  "default",
  "collapse",
  "untied",
  "final",
  "mergeable",
  "device",
  "dist_schedule",
  "inbranch",
  "notinbranch",
  "num_teams",
  "thread_limit",
  "proc_bind",
  "safelen",
  "simdlen",
  "for",
  "parallel",
  "sections",
  "taskgroup",
  "priority",
  "grainsize",
  "num_tasks",
  "nogroup",
  "threads",
  "simd",
  "hint",
  "defaultmap",
  "_simduid_",
  "_simt_",
  "independent",
  "worker",
  "vector",
  "num_gangs",
  "num_workers",
  "vector_length",
  "tile",
  "_griddim_",
  "if_present",
  "finalize",
};


/* Return the tree node structure used by tree code CODE.  */

static inline enum tree_node_structure_enum
tree_node_structure_for_code (enum tree_code code)
{
  switch (TREE_CODE_CLASS (code))
    {
    case tcc_declaration:
      {
	switch (code)
	  {
	  case FIELD_DECL:
	    return TS_FIELD_DECL;
	  case PARM_DECL:
	    return TS_PARM_DECL;
	  case VAR_DECL:
	    return TS_VAR_DECL;
	  case LABEL_DECL:
	    return TS_LABEL_DECL;
	  case RESULT_DECL:
	    return TS_RESULT_DECL;
	  case DEBUG_EXPR_DECL:
	    return TS_DECL_WRTL;
	  case CONST_DECL:
	    return TS_CONST_DECL;
	  case TYPE_DECL:
	    return TS_TYPE_DECL;
	  case FUNCTION_DECL:
	    return TS_FUNCTION_DECL;
	  case TRANSLATION_UNIT_DECL:
	    return TS_TRANSLATION_UNIT_DECL;
	  default:
	    return TS_DECL_NON_COMMON;
	  }
      }
    case tcc_type:
      return TS_TYPE_NON_COMMON;
    case tcc_reference:
    case tcc_comparison:
    case tcc_unary:
    case tcc_binary:
    case tcc_expression:
    case tcc_statement:
    case tcc_vl_exp:
      return TS_EXP;
    default:  /* tcc_constant and tcc_exceptional */
      break;
    }
  switch (code)
    {
      /* tcc_constant cases.  */
    case VOID_CST:		return TS_TYPED;
    case INTEGER_CST:		return TS_INT_CST;
    case POLY_INT_CST:		return TS_POLY_INT_CST;
    case REAL_CST:		return TS_REAL_CST;
    case FIXED_CST:		return TS_FIXED_CST;
    case COMPLEX_CST:		return TS_COMPLEX;
    case VECTOR_CST:		return TS_VECTOR;
    case STRING_CST:		return TS_STRING;
      /* tcc_exceptional cases.  */
    case ERROR_MARK:		return TS_COMMON;
    case IDENTIFIER_NODE:	return TS_IDENTIFIER;
    case TREE_LIST:		return TS_LIST;
    case TREE_VEC:		return TS_VEC;
    case SSA_NAME:		return TS_SSA_NAME;
    case PLACEHOLDER_EXPR:	return TS_COMMON;
    case STATEMENT_LIST:	return TS_STATEMENT_LIST;
    case BLOCK:			return TS_BLOCK;
    case CONSTRUCTOR:		return TS_CONSTRUCTOR;
    case TREE_BINFO:		return TS_BINFO;
    case OMP_CLAUSE:		return TS_OMP_CLAUSE;
    case OPTIMIZATION_NODE:	return TS_OPTIMIZATION;
    case TARGET_OPTION_NODE:	return TS_TARGET_OPTION;

    default:
      gcc_unreachable ();
    }
}


/* Initialize tree_contains_struct to describe the hierarchy of tree
   nodes.  */

static void
initialize_tree_contains_struct (void)
{
  unsigned i;

  for (i = ERROR_MARK; i < LAST_AND_UNUSED_TREE_CODE; i++)
    {
      enum tree_code code;
      enum tree_node_structure_enum ts_code;

      code = (enum tree_code) i;
      ts_code = tree_node_structure_for_code (code);

      /* Mark the TS structure itself.  */
      tree_contains_struct[code][ts_code] = 1;

      /* Mark all the structures that TS is derived from.  */
      switch (ts_code)
	{
	case TS_TYPED:
	case TS_BLOCK:
	case TS_OPTIMIZATION:
	case TS_TARGET_OPTION:
	  MARK_TS_BASE (code);
	  break;

	case TS_COMMON:
	case TS_INT_CST:
	case TS_POLY_INT_CST:
	case TS_REAL_CST:
	case TS_FIXED_CST:
	case TS_VECTOR:
	case TS_STRING:
	case TS_COMPLEX:
	case TS_SSA_NAME:
	case TS_CONSTRUCTOR:
	case TS_EXP:
	case TS_STATEMENT_LIST:
	  MARK_TS_TYPED (code);
	  break;

	case TS_IDENTIFIER:
	case TS_DECL_MINIMAL:
	case TS_TYPE_COMMON:
	case TS_LIST:
	case TS_VEC:
	case TS_BINFO:
	case TS_OMP_CLAUSE:
	  MARK_TS_COMMON (code);
	  break;

	case TS_TYPE_WITH_LANG_SPECIFIC:
	  MARK_TS_TYPE_COMMON (code);
	  break;

	case TS_TYPE_NON_COMMON:
	  MARK_TS_TYPE_WITH_LANG_SPECIFIC (code);
	  break;

	case TS_DECL_COMMON:
	  MARK_TS_DECL_MINIMAL (code);
	  break;

	case TS_DECL_WRTL:
	case TS_CONST_DECL:
	  MARK_TS_DECL_COMMON (code);
	  break;

	case TS_DECL_NON_COMMON:
	  MARK_TS_DECL_WITH_VIS (code);
	  break;

	case TS_DECL_WITH_VIS:
	case TS_PARM_DECL:
	case TS_LABEL_DECL:
	case TS_RESULT_DECL:
	  MARK_TS_DECL_WRTL (code);
	  break;

	case TS_FIELD_DECL:
	  MARK_TS_DECL_COMMON (code);
	  break;

	case TS_VAR_DECL:
	  MARK_TS_DECL_WITH_VIS (code);
	  break;

	case TS_TYPE_DECL:
	case TS_FUNCTION_DECL:
	  MARK_TS_DECL_NON_COMMON (code);
	  break;

	case TS_TRANSLATION_UNIT_DECL:
	  MARK_TS_DECL_COMMON (code);
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  /* Basic consistency checks for attributes used in fold.  */
  gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_NON_COMMON]);
  gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_NON_COMMON]);
  gcc_assert (tree_contains_struct[CONST_DECL][TS_DECL_COMMON]);
  gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_COMMON]);
  gcc_assert (tree_contains_struct[PARM_DECL][TS_DECL_COMMON]);
  gcc_assert (tree_contains_struct[RESULT_DECL][TS_DECL_COMMON]);
  gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_COMMON]);
  gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_COMMON]);
  gcc_assert (tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_COMMON]);
  gcc_assert (tree_contains_struct[LABEL_DECL][TS_DECL_COMMON]);
  gcc_assert (tree_contains_struct[FIELD_DECL][TS_DECL_COMMON]);
  gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_WRTL]);
  gcc_assert (tree_contains_struct[PARM_DECL][TS_DECL_WRTL]);
  gcc_assert (tree_contains_struct[RESULT_DECL][TS_DECL_WRTL]);
  gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_WRTL]);
  gcc_assert (tree_contains_struct[LABEL_DECL][TS_DECL_WRTL]);
  gcc_assert (tree_contains_struct[CONST_DECL][TS_DECL_MINIMAL]);
  gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_MINIMAL]);
  gcc_assert (tree_contains_struct[PARM_DECL][TS_DECL_MINIMAL]);
  gcc_assert (tree_contains_struct[RESULT_DECL][TS_DECL_MINIMAL]);
  gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_MINIMAL]);
  gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_MINIMAL]);
  gcc_assert (tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_MINIMAL]);
  gcc_assert (tree_contains_struct[LABEL_DECL][TS_DECL_MINIMAL]);
  gcc_assert (tree_contains_struct[FIELD_DECL][TS_DECL_MINIMAL]);
  gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_WITH_VIS]);
  gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_WITH_VIS]);
  gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_WITH_VIS]);
  gcc_assert (tree_contains_struct[VAR_DECL][TS_VAR_DECL]);
  gcc_assert (tree_contains_struct[FIELD_DECL][TS_FIELD_DECL]);
  gcc_assert (tree_contains_struct[PARM_DECL][TS_PARM_DECL]);
  gcc_assert (tree_contains_struct[LABEL_DECL][TS_LABEL_DECL]);
  gcc_assert (tree_contains_struct[RESULT_DECL][TS_RESULT_DECL]);
  gcc_assert (tree_contains_struct[CONST_DECL][TS_CONST_DECL]);
  gcc_assert (tree_contains_struct[TYPE_DECL][TS_TYPE_DECL]);
  gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL]);
  gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL]);
  gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON]);
  gcc_assert (tree_contains_struct[NAMELIST_DECL][TS_DECL_MINIMAL]);
  gcc_assert (tree_contains_struct[NAMELIST_DECL][TS_DECL_COMMON]);
}


/* Init tree.c.  */

void
init_ttree (void)
{
  /* Initialize the hash table of types.  */
  type_hash_table
    = hash_table<type_cache_hasher>::create_ggc (TYPE_HASH_INITIAL_SIZE);

  debug_expr_for_decl
    = hash_table<tree_decl_map_cache_hasher>::create_ggc (512);

  value_expr_for_decl
    = hash_table<tree_decl_map_cache_hasher>::create_ggc (512);

  int_cst_hash_table = hash_table<int_cst_hasher>::create_ggc (1024);

  poly_int_cst_hash_table = hash_table<poly_int_cst_hasher>::create_ggc (64);

  int_cst_node = make_int_cst (1, 1);

  cl_option_hash_table = hash_table<cl_option_hasher>::create_ggc (64);

  cl_optimization_node = make_node (OPTIMIZATION_NODE);
  cl_target_option_node = make_node (TARGET_OPTION_NODE);

  /* Initialize the tree_contains_struct array.  */
  initialize_tree_contains_struct ();
  lang_hooks.init_ts ();
}


/* The name of the object as the assembler will see it (but before any
   translations made by ASM_OUTPUT_LABELREF).  Often this is the same
   as DECL_NAME.  It is an IDENTIFIER_NODE.  */
tree
decl_assembler_name (tree decl)
{
  if (!DECL_ASSEMBLER_NAME_SET_P (decl))
    lang_hooks.set_decl_assembler_name (decl);
  return DECL_ASSEMBLER_NAME_RAW (decl);
}

/* The DECL_ASSEMBLER_NAME_RAW of DECL is being explicitly set to NAME
   (either of which may be NULL).  Inform the FE, if this changes the
   name.  */

void
overwrite_decl_assembler_name (tree decl, tree name)
{
  if (DECL_ASSEMBLER_NAME_RAW (decl) != name)
    lang_hooks.overwrite_decl_assembler_name (decl, name);
}

/* When the target supports COMDAT groups, this indicates which group the
   DECL is associated with.  This can be either an IDENTIFIER_NODE or a
   decl, in which case its DECL_ASSEMBLER_NAME identifies the group.  */
tree
decl_comdat_group (const_tree node)
{
  struct symtab_node *snode = symtab_node::get (node);
  if (!snode)
    return NULL;
  return snode->get_comdat_group ();
}

/* Likewise, but make sure it's been reduced to an IDENTIFIER_NODE.  */
tree
decl_comdat_group_id (const_tree node)
{
  struct symtab_node *snode = symtab_node::get (node);
  if (!snode)
    return NULL;
  return snode->get_comdat_group_id ();
}

/* When the target supports named section, return its name as IDENTIFIER_NODE
   or NULL if it is in no section.  */
const char *
decl_section_name (const_tree node)
{
  struct symtab_node *snode = symtab_node::get (node);
  if (!snode)
    return NULL;
  return snode->get_section ();
}

/* Set section name of NODE to VALUE (that is expected to be
   identifier node) */
void
set_decl_section_name (tree node, const char *value)
{
  struct symtab_node *snode;

  if (value == NULL)
    {
      snode = symtab_node::get (node);
      if (!snode)
	return;
    }
  else if (VAR_P (node))
    snode = varpool_node::get_create (node);
  else
    snode = cgraph_node::get_create (node);
  snode->set_section (value);
}

/* Return TLS model of a variable NODE.  */
enum tls_model
decl_tls_model (const_tree node)
{
  struct varpool_node *snode = varpool_node::get (node);
  if (!snode)
    return TLS_MODEL_NONE;
  return snode->tls_model;
}

/* Set TLS model of variable NODE to MODEL.  */
void
set_decl_tls_model (tree node, enum tls_model model)
{
  struct varpool_node *vnode;

  if (model == TLS_MODEL_NONE)
    {
      vnode = varpool_node::get (node);
      if (!vnode)
	return;
    }
  else
    vnode = varpool_node::get_create (node);
  vnode->tls_model = model;
}

/* Compute the number of bytes occupied by a tree with code CODE.
   This function cannot be used for nodes that have variable sizes,
   including TREE_VEC, INTEGER_CST, STRING_CST, and CALL_EXPR.  */
size_t
tree_code_size (enum tree_code code)
{
  switch (TREE_CODE_CLASS (code))
    {
    case tcc_declaration:  /* A decl node */
      switch (code)
	{
	case FIELD_DECL:	return sizeof (tree_field_decl);
	case PARM_DECL:		return sizeof (tree_parm_decl);
	case VAR_DECL:		return sizeof (tree_var_decl);
	case LABEL_DECL:	return sizeof (tree_label_decl);
	case RESULT_DECL:	return sizeof (tree_result_decl);
	case CONST_DECL:	return sizeof (tree_const_decl);
	case TYPE_DECL:		return sizeof (tree_type_decl);
	case FUNCTION_DECL:	return sizeof (tree_function_decl);
	case DEBUG_EXPR_DECL:	return sizeof (tree_decl_with_rtl);
	case TRANSLATION_UNIT_DECL: return sizeof (tree_translation_unit_decl);
	case NAMESPACE_DECL:
	case IMPORTED_DECL:
	case NAMELIST_DECL:	return sizeof (tree_decl_non_common);
	default:
	  gcc_checking_assert (code >= NUM_TREE_CODES);
	  return lang_hooks.tree_size (code);
	}

    case tcc_type:  /* a type node */
      switch (code)
	{
	case OFFSET_TYPE:
	case ENUMERAL_TYPE:
	case BOOLEAN_TYPE:
	case INTEGER_TYPE:
	case REAL_TYPE:
	case POINTER_TYPE:
	case REFERENCE_TYPE:
	case NULLPTR_TYPE:
	case FIXED_POINT_TYPE:
	case COMPLEX_TYPE:
	case VECTOR_TYPE:
	case ARRAY_TYPE:
	case RECORD_TYPE:
	case UNION_TYPE:
	case QUAL_UNION_TYPE:
	case VOID_TYPE:
	case FUNCTION_TYPE:
	case METHOD_TYPE:
	case LANG_TYPE:		return sizeof (tree_type_non_common);
	default:
	  gcc_checking_assert (code >= NUM_TREE_CODES);
	  return lang_hooks.tree_size (code);
	}

    case tcc_reference:   /* a reference */
    case tcc_expression:  /* an expression */
    case tcc_statement:   /* an expression with side effects */
    case tcc_comparison:  /* a comparison expression */
    case tcc_unary:       /* a unary arithmetic expression */
    case tcc_binary:      /* a binary arithmetic expression */
      return (sizeof (struct tree_exp)
	      + (TREE_CODE_LENGTH (code) - 1) * sizeof (tree));

    case tcc_constant:  /* a constant */
      switch (code)
	{
	case VOID_CST:		return sizeof (tree_typed);
	case INTEGER_CST:	gcc_unreachable ();
	case POLY_INT_CST:	return sizeof (tree_poly_int_cst);
	case REAL_CST:		return sizeof (tree_real_cst);
	case FIXED_CST:		return sizeof (tree_fixed_cst);
	case COMPLEX_CST:	return sizeof (tree_complex);
	case VECTOR_CST:	gcc_unreachable ();
	case STRING_CST:	gcc_unreachable ();
	default:
	  gcc_checking_assert (code >= NUM_TREE_CODES);
	  return lang_hooks.tree_size (code);
	}

    case tcc_exceptional:  /* something random, like an identifier.  */
      switch (code)
	{
	case IDENTIFIER_NODE:	return lang_hooks.identifier_size;
	case TREE_LIST:		return sizeof (tree_list);

	case ERROR_MARK:
	case PLACEHOLDER_EXPR:	return sizeof (tree_common);

	case TREE_VEC:		gcc_unreachable ();
	case OMP_CLAUSE:	gcc_unreachable ();

	case SSA_NAME:		return sizeof (tree_ssa_name);

	case STATEMENT_LIST:	return sizeof (tree_statement_list);
	case BLOCK:		return sizeof (struct tree_block);
	case CONSTRUCTOR:	return sizeof (tree_constructor);
	case OPTIMIZATION_NODE: return sizeof (tree_optimization_option);
	case TARGET_OPTION_NODE: return sizeof (tree_target_option);

	default:
	  gcc_checking_assert (code >= NUM_TREE_CODES);
	  return lang_hooks.tree_size (code);
	}

    default:
      gcc_unreachable ();
    }
}

/* Compute the number of bytes occupied by NODE.  This routine only
   looks at TREE_CODE, except for those nodes that have variable sizes.  */
size_t
tree_size (const_tree node)
{
  const enum tree_code code = TREE_CODE (node);
  switch (code)
    {
    case INTEGER_CST:
      return (sizeof (struct tree_int_cst)
	      + (TREE_INT_CST_EXT_NUNITS (node) - 1) * sizeof (HOST_WIDE_INT));

    case TREE_BINFO:
      return (offsetof (struct tree_binfo, base_binfos)
	      + vec<tree, va_gc>
		  ::embedded_size (BINFO_N_BASE_BINFOS (node)));

    case TREE_VEC:
      return (sizeof (struct tree_vec)
	      + (TREE_VEC_LENGTH (node) - 1) * sizeof (tree));

    case VECTOR_CST:
      return (sizeof (struct tree_vector)
	      + (vector_cst_encoded_nelts (node) - 1) * sizeof (tree));

    case STRING_CST:
      return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 1;

    case OMP_CLAUSE:
      return (sizeof (struct tree_omp_clause)
	      + (omp_clause_num_ops[OMP_CLAUSE_CODE (node)] - 1)
	        * sizeof (tree));

    default:
      if (TREE_CODE_CLASS (code) == tcc_vl_exp)
	return (sizeof (struct tree_exp)
		+ (VL_EXP_OPERAND_LENGTH (node) - 1) * sizeof (tree));
      else
	return tree_code_size (code);
    }
}

/* Return tree node kind based on tree CODE.  */

static tree_node_kind
get_stats_node_kind (enum tree_code code)
{
  enum tree_code_class type = TREE_CODE_CLASS (code);

  switch (type)
    {
    case tcc_declaration:  /* A decl node */
      return d_kind;
    case tcc_type:  /* a type node */
      return t_kind;
    case tcc_statement:  /* an expression with side effects */
      return s_kind;
    case tcc_reference:  /* a reference */
      return r_kind;
    case tcc_expression:  /* an expression */
    case tcc_comparison:  /* a comparison expression */
    case tcc_unary:  /* a unary arithmetic expression */
    case tcc_binary:  /* a binary arithmetic expression */
      return e_kind;
    case tcc_constant:  /* a constant */
      return c_kind;
    case tcc_exceptional:  /* something random, like an identifier.  */
      switch (code)
	{
	case IDENTIFIER_NODE:
	  return id_kind;
	case TREE_VEC:
	  return vec_kind;
	case TREE_BINFO:
	  return binfo_kind;
	case SSA_NAME:
	  return ssa_name_kind;
	case BLOCK:
	  return b_kind;
	case CONSTRUCTOR:
	  return constr_kind;
	case OMP_CLAUSE:
	  return omp_clause_kind;
	default:
	  return x_kind;
	}
      break;
    case tcc_vl_exp:
      return e_kind;
    default:
      gcc_unreachable ();
    }
}

/* Record interesting allocation statistics for a tree node with CODE
   and LENGTH.  */

static void
record_node_allocation_statistics (enum tree_code code, size_t length)
{
  if (!GATHER_STATISTICS)
    return;

  tree_node_kind kind = get_stats_node_kind (code);

  tree_code_counts[(int) code]++;
  tree_node_counts[(int) kind]++;
  tree_node_sizes[(int) kind] += length;
}

/* Allocate and return a new UID from the DECL_UID namespace.  */

int
allocate_decl_uid (void)
{
  return next_decl_uid++;
}

/* Return a newly allocated node of code CODE.  For decl and type
   nodes, some other fields are initialized.  The rest of the node is
   initialized to zero.  This function cannot be used for TREE_VEC,
   INTEGER_CST or OMP_CLAUSE nodes, which is enforced by asserts in
   tree_code_size.

   Achoo!  I got a code in the node.  */

tree
make_node (enum tree_code code MEM_STAT_DECL)
{
  tree t;
  enum tree_code_class type = TREE_CODE_CLASS (code);
  size_t length = tree_code_size (code);

  record_node_allocation_statistics (code, length);

  t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);
  TREE_SET_CODE (t, code);

  switch (type)
    {
    case tcc_statement:
      if (code != DEBUG_BEGIN_STMT)
	TREE_SIDE_EFFECTS (t) = 1;
      break;

    case tcc_declaration:
      if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
	{
	  if (code == FUNCTION_DECL)
	    {
	      SET_DECL_ALIGN (t, FUNCTION_ALIGNMENT (FUNCTION_BOUNDARY));
	      SET_DECL_MODE (t, FUNCTION_MODE);
	    }
	  else
	    SET_DECL_ALIGN (t, 1);
	}
      DECL_SOURCE_LOCATION (t) = input_location;
      if (TREE_CODE (t) == DEBUG_EXPR_DECL)
	DECL_UID (t) = --next_debug_decl_uid;
      else
	{
	  DECL_UID (t) = allocate_decl_uid ();
	  SET_DECL_PT_UID (t, -1);
	}
      if (TREE_CODE (t) == LABEL_DECL)
	LABEL_DECL_UID (t) = -1;

      break;

    case tcc_type:
      TYPE_UID (t) = next_type_uid++;
      SET_TYPE_ALIGN (t, BITS_PER_UNIT);
      TYPE_USER_ALIGN (t) = 0;
      TYPE_MAIN_VARIANT (t) = t;
      TYPE_CANONICAL (t) = t;

      /* Default to no attributes for type, but let target change that.  */
      TYPE_ATTRIBUTES (t) = NULL_TREE;
      targetm.set_default_type_attributes (t);

      /* We have not yet computed the alias set for this type.  */
      TYPE_ALIAS_SET (t) = -1;
      break;

    case tcc_constant:
      TREE_CONSTANT (t) = 1;
      break;

    case tcc_expression:
      switch (code)
	{
	case INIT_EXPR:
	case MODIFY_EXPR:
	case VA_ARG_EXPR:
	case PREDECREMENT_EXPR:
	case PREINCREMENT_EXPR:
	case POSTDECREMENT_EXPR:
	case POSTINCREMENT_EXPR:
	  /* All of these have side-effects, no matter what their
	     operands are.  */
	  TREE_SIDE_EFFECTS (t) = 1;
	  break;

	default:
	  break;
	}
      break;

    case tcc_exceptional:
      switch (code)
        {
	case TARGET_OPTION_NODE:
	  TREE_TARGET_OPTION(t)
			    = ggc_cleared_alloc<struct cl_target_option> ();
	  break;

	case OPTIMIZATION_NODE:
	  TREE_OPTIMIZATION (t)
			    = ggc_cleared_alloc<struct cl_optimization> ();
	  break;

	default:
	  break;
	}
      break;

    default:
      /* Other classes need no special treatment.  */
      break;
    }

  return t;
}

/* Free tree node.  */

void
free_node (tree node)
{
  enum tree_code code = TREE_CODE (node);
  if (GATHER_STATISTICS)
    {
      enum tree_node_kind kind = get_stats_node_kind (code);

      gcc_checking_assert (tree_code_counts[(int) TREE_CODE (node)] != 0);
      gcc_checking_assert (tree_node_counts[(int) kind] != 0);
      gcc_checking_assert (tree_node_sizes[(int) kind] >= tree_size (node));

      tree_code_counts[(int) TREE_CODE (node)]--;
      tree_node_counts[(int) kind]--;
      tree_node_sizes[(int) kind] -= tree_size (node);
    }
  if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
    vec_free (CONSTRUCTOR_ELTS (node));
  else if (code == BLOCK)
    vec_free (BLOCK_NONLOCALIZED_VARS (node));
  else if (code == TREE_BINFO)
    vec_free (BINFO_BASE_ACCESSES (node));
  ggc_free (node);
}

/* Return a new node with the same contents as NODE except that its
   TREE_CHAIN, if it has one, is zero and it has a fresh uid.  */

tree
copy_node (tree node MEM_STAT_DECL)
{
  tree t;
  enum tree_code code = TREE_CODE (node);
  size_t length;

  gcc_assert (code != STATEMENT_LIST);

  length = tree_size (node);
  record_node_allocation_statistics (code, length);
  t = ggc_alloc_tree_node_stat (length PASS_MEM_STAT);
  memcpy (t, node, length);

  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
    TREE_CHAIN (t) = 0;
  TREE_ASM_WRITTEN (t) = 0;
  TREE_VISITED (t) = 0;

  if (TREE_CODE_CLASS (code) == tcc_declaration)
    {
      if (code == DEBUG_EXPR_DECL)
	DECL_UID (t) = --next_debug_decl_uid;
      else
	{
	  DECL_UID (t) = allocate_decl_uid ();
	  if (DECL_PT_UID_SET_P (node))
	    SET_DECL_PT_UID (t, DECL_PT_UID (node));
	}
      if ((TREE_CODE (node) == PARM_DECL || VAR_P (node))
	  && DECL_HAS_VALUE_EXPR_P (node))
	{
	  SET_DECL_VALUE_EXPR (t, DECL_VALUE_EXPR (node));
	  DECL_HAS_VALUE_EXPR_P (t) = 1;
	}
      /* DECL_DEBUG_EXPR is copied explicitely by callers.  */
      if (VAR_P (node))
	{
	  DECL_HAS_DEBUG_EXPR_P (t) = 0;
	  t->decl_with_vis.symtab_node = NULL;
	}
      if (VAR_P (node) && DECL_HAS_INIT_PRIORITY_P (node))
	{
	  SET_DECL_INIT_PRIORITY (t, DECL_INIT_PRIORITY (node));
	  DECL_HAS_INIT_PRIORITY_P (t) = 1;
	}
      if (TREE_CODE (node) == FUNCTION_DECL)
	{
	  DECL_STRUCT_FUNCTION (t) = NULL;
	  t->decl_with_vis.symtab_node = NULL;
	}
    }
  else if (TREE_CODE_CLASS (code) == tcc_type)
    {
      TYPE_UID (t) = next_type_uid++;
      /* The following is so that the debug code for
	 the copy is different from the original type.
	 The two statements usually duplicate each other
	 (because they clear fields of the same union),
	 but the optimizer should catch that.  */
      TYPE_SYMTAB_ADDRESS (t) = 0;
      TYPE_SYMTAB_DIE (t) = 0;

      /* Do not copy the values cache.  */
      if (TYPE_CACHED_VALUES_P (t))
	{
	  TYPE_CACHED_VALUES_P (t) = 0;
	  TYPE_CACHED_VALUES (t) = NULL_TREE;
	}
    }
    else if (code == TARGET_OPTION_NODE)
      {
	TREE_TARGET_OPTION (t) = ggc_alloc<struct cl_target_option>();
	memcpy (TREE_TARGET_OPTION (t), TREE_TARGET_OPTION (node),
		sizeof (struct cl_target_option));
      }
    else if (code == OPTIMIZATION_NODE)
      {
	TREE_OPTIMIZATION (t) = ggc_alloc<struct cl_optimization>();
	memcpy (TREE_OPTIMIZATION (t), TREE_OPTIMIZATION (node),
		sizeof (struct cl_optimization));
      }

  return t;
}

/* Return a copy of a chain of nodes, chained through the TREE_CHAIN field.
   For example, this can copy a list made of TREE_LIST nodes.  */

tree
copy_list (tree list)
{
  tree head;
  tree prev, next;

  if (list == 0)
    return 0;

  head = prev = copy_node (list);
  next = TREE_CHAIN (list);
  while (next)
    {
      TREE_CHAIN (prev) = copy_node (next);
      prev = TREE_CHAIN (prev);
      next = TREE_CHAIN (next);
    }
  return head;
}


/* Return the value that TREE_INT_CST_EXT_NUNITS should have for an
   INTEGER_CST with value CST and type TYPE.   */

static unsigned int
get_int_cst_ext_nunits (tree type, const wide_int &cst)
{
  gcc_checking_assert (cst.get_precision () == TYPE_PRECISION (type));
  /* We need extra HWIs if CST is an unsigned integer with its
     upper bit set.  */
  if (TYPE_UNSIGNED (type) && wi::neg_p (cst))
    return cst.get_precision () / HOST_BITS_PER_WIDE_INT + 1;
  return cst.get_len ();
}

/* Return a new INTEGER_CST with value CST and type TYPE.  */

static tree
build_new_int_cst (tree type, const wide_int &cst)
{
  unsigned int len = cst.get_len ();
  unsigned int ext_len = get_int_cst_ext_nunits (type, cst);
  tree nt = make_int_cst (len, ext_len);

  if (len < ext_len)
    {
      --ext_len;
      TREE_INT_CST_ELT (nt, ext_len)
	= zext_hwi (-1, cst.get_precision () % HOST_BITS_PER_WIDE_INT);
      for (unsigned int i = len; i < ext_len; ++i)
	TREE_INT_CST_ELT (nt, i) = -1;
    }
  else if (TYPE_UNSIGNED (type)
	   && cst.get_precision () < len * HOST_BITS_PER_WIDE_INT)
    {
      len--;
      TREE_INT_CST_ELT (nt, len)
	= zext_hwi (cst.elt (len),
		    cst.get_precision () % HOST_BITS_PER_WIDE_INT);
    }

  for (unsigned int i = 0; i < len; i++)
    TREE_INT_CST_ELT (nt, i) = cst.elt (i);
  TREE_TYPE (nt) = type;
  return nt;
}

/* Return a new POLY_INT_CST with coefficients COEFFS and type TYPE.  */

static tree
build_new_poly_int_cst (tree type, tree (&coeffs)[NUM_POLY_INT_COEFFS]
			CXX_MEM_STAT_INFO)
{
  size_t length = sizeof (struct tree_poly_int_cst);
  record_node_allocation_statistics (POLY_INT_CST, length);

  tree t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);

  TREE_SET_CODE (t, POLY_INT_CST);
  TREE_CONSTANT (t) = 1;
  TREE_TYPE (t) = type;
  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    POLY_INT_CST_COEFF (t, i) = coeffs[i];
  return t;
}

/* Create a constant tree that contains CST sign-extended to TYPE.  */

tree
build_int_cst (tree type, poly_int64 cst)
{
  /* Support legacy code.  */
  if (!type)
    type = integer_type_node;

  return wide_int_to_tree (type, wi::shwi (cst, TYPE_PRECISION (type)));
}

/* Create a constant tree that contains CST zero-extended to TYPE.  */

tree
build_int_cstu (tree type, poly_uint64 cst)
{
  return wide_int_to_tree (type, wi::uhwi (cst, TYPE_PRECISION (type)));
}

/* Create a constant tree that contains CST sign-extended to TYPE.  */

tree
build_int_cst_type (tree type, poly_int64 cst)
{
  gcc_assert (type);
  return wide_int_to_tree (type, wi::shwi (cst, TYPE_PRECISION (type)));
}

/* Constructs tree in type TYPE from with value given by CST.  Signedness
   of CST is assumed to be the same as the signedness of TYPE.  */

tree
double_int_to_tree (tree type, double_int cst)
{
  return wide_int_to_tree (type, widest_int::from (cst, TYPE_SIGN (type)));
}

/* We force the wide_int CST to the range of the type TYPE by sign or
   zero extending it.  OVERFLOWABLE indicates if we are interested in
   overflow of the value, when >0 we are only interested in signed
   overflow, for <0 we are interested in any overflow.  OVERFLOWED
   indicates whether overflow has already occurred.  CONST_OVERFLOWED
   indicates whether constant overflow has already occurred.  We force
   T's value to be within range of T's type (by setting to 0 or 1 all
   the bits outside the type's range).  We set TREE_OVERFLOWED if,
        OVERFLOWED is nonzero,
        or OVERFLOWABLE is >0 and signed overflow occurs
        or OVERFLOWABLE is <0 and any overflow occurs
   We return a new tree node for the extended wide_int.  The node
   is shared if no overflow flags are set.  */


tree
force_fit_type (tree type, const poly_wide_int_ref &cst,
		int overflowable, bool overflowed)
{
  signop sign = TYPE_SIGN (type);

  /* If we need to set overflow flags, return a new unshared node.  */
  if (overflowed || !wi::fits_to_tree_p (cst, type))
    {
      if (overflowed
	  || overflowable < 0
	  || (overflowable > 0 && sign == SIGNED))
	{
	  poly_wide_int tmp = poly_wide_int::from (cst, TYPE_PRECISION (type),
						   sign);
	  tree t;
	  if (tmp.is_constant ())
	    t = build_new_int_cst (type, tmp.coeffs[0]);
	  else
	    {
	      tree coeffs[NUM_POLY_INT_COEFFS];
	      for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
		{
		  coeffs[i] = build_new_int_cst (type, tmp.coeffs[i]);
		  TREE_OVERFLOW (coeffs[i]) = 1;
		}
	      t = build_new_poly_int_cst (type, coeffs);
	    }
	  TREE_OVERFLOW (t) = 1;
	  return t;
	}
    }

  /* Else build a shared node.  */
  return wide_int_to_tree (type, cst);
}

/* These are the hash table functions for the hash table of INTEGER_CST
   nodes of a sizetype.  */

/* Return the hash code X, an INTEGER_CST.  */

hashval_t
int_cst_hasher::hash (tree x)
{
  const_tree const t = x;
  hashval_t code = TYPE_UID (TREE_TYPE (t));
  int i;

  for (i = 0; i < TREE_INT_CST_NUNITS (t); i++)
    code = iterative_hash_host_wide_int (TREE_INT_CST_ELT(t, i), code);

  return code;
}

/* Return nonzero if the value represented by *X (an INTEGER_CST tree node)
   is the same as that given by *Y, which is the same.  */

bool
int_cst_hasher::equal (tree x, tree y)
{
  const_tree const xt = x;
  const_tree const yt = y;

  if (TREE_TYPE (xt) != TREE_TYPE (yt)
      || TREE_INT_CST_NUNITS (xt) != TREE_INT_CST_NUNITS (yt)
      || TREE_INT_CST_EXT_NUNITS (xt) != TREE_INT_CST_EXT_NUNITS (yt))
    return false;

  for (int i = 0; i < TREE_INT_CST_NUNITS (xt); i++)
    if (TREE_INT_CST_ELT (xt, i) != TREE_INT_CST_ELT (yt, i))
      return false;

  return true;
}

/* Create an INT_CST node of TYPE and value CST.
   The returned node is always shared.  For small integers we use a
   per-type vector cache, for larger ones we use a single hash table.
   The value is extended from its precision according to the sign of
   the type to be a multiple of HOST_BITS_PER_WIDE_INT.  This defines
   the upper bits and ensures that hashing and value equality based
   upon the underlying HOST_WIDE_INTs works without masking.  */

static tree
wide_int_to_tree_1 (tree type, const wide_int_ref &pcst)
{
  tree t;
  int ix = -1;
  int limit = 0;

  gcc_assert (type);
  unsigned int prec = TYPE_PRECISION (type);
  signop sgn = TYPE_SIGN (type);

  /* Verify that everything is canonical.  */
  int l = pcst.get_len ();
  if (l > 1)
    {
      if (pcst.elt (l - 1) == 0)
	gcc_checking_assert (pcst.elt (l - 2) < 0);
      if (pcst.elt (l - 1) == HOST_WIDE_INT_M1)
	gcc_checking_assert (pcst.elt (l - 2) >= 0);
    }

  wide_int cst = wide_int::from (pcst, prec, sgn);
  unsigned int ext_len = get_int_cst_ext_nunits (type, cst);

  if (ext_len == 1)
    {
      /* We just need to store a single HOST_WIDE_INT.  */
      HOST_WIDE_INT hwi;
      if (TYPE_UNSIGNED (type))
	hwi = cst.to_uhwi ();
      else
	hwi = cst.to_shwi ();

      switch (TREE_CODE (type))
	{
	case NULLPTR_TYPE:
	  gcc_assert (hwi == 0);
	  /* Fallthru.  */

	case POINTER_TYPE:
	case REFERENCE_TYPE:
	  /* Cache NULL pointer and zero bounds.  */
	  if (hwi == 0)
	    {
	      limit = 1;
	      ix = 0;
	    }
	  break;

	case BOOLEAN_TYPE:
	  /* Cache false or true.  */
	  limit = 2;
	  if (IN_RANGE (hwi, 0, 1))
	    ix = hwi;
	  break;

	case INTEGER_TYPE:
	case OFFSET_TYPE:
	  if (TYPE_SIGN (type) == UNSIGNED)
	    {
	      /* Cache [0, N).  */
	      limit = INTEGER_SHARE_LIMIT;
	      if (IN_RANGE (hwi, 0, INTEGER_SHARE_LIMIT - 1))
		ix = hwi;
	    }
	  else
	    {
	      /* Cache [-1, N).  */
	      limit = INTEGER_SHARE_LIMIT + 1;
	      if (IN_RANGE (hwi, -1, INTEGER_SHARE_LIMIT - 1))
		ix = hwi + 1;
	    }
	  break;

	case ENUMERAL_TYPE:
	  break;

	default:
	  gcc_unreachable ();
	}

      if (ix >= 0)
	{
	  /* Look for it in the type's vector of small shared ints.  */
	  if (!TYPE_CACHED_VALUES_P (type))
	    {
	      TYPE_CACHED_VALUES_P (type) = 1;
	      TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
	    }

	  t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix);
	  if (t)
	    /* Make sure no one is clobbering the shared constant.  */
	    gcc_checking_assert (TREE_TYPE (t) == type
				 && TREE_INT_CST_NUNITS (t) == 1
				 && TREE_INT_CST_OFFSET_NUNITS (t) == 1
				 && TREE_INT_CST_EXT_NUNITS (t) == 1
				 && TREE_INT_CST_ELT (t, 0) == hwi);
	  else
	    {
	      /* Create a new shared int.  */
	      t = build_new_int_cst (type, cst);
	      TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
	    }
	}
      else
	{
	  /* Use the cache of larger shared ints, using int_cst_node as
	     a temporary.  */

	  TREE_INT_CST_ELT (int_cst_node, 0) = hwi;
	  TREE_TYPE (int_cst_node) = type;

	  tree *slot = int_cst_hash_table->find_slot (int_cst_node, INSERT);
	  t = *slot;
	  if (!t)
	    {
	      /* Insert this one into the hash table.  */
	      t = int_cst_node;
	      *slot = t;
	      /* Make a new node for next time round.  */
	      int_cst_node = make_int_cst (1, 1);
	    }
	}
    }
  else
    {
      /* The value either hashes properly or we drop it on the floor
	 for the gc to take care of.  There will not be enough of them
	 to worry about.  */

      tree nt = build_new_int_cst (type, cst);
      tree *slot = int_cst_hash_table->find_slot (nt, INSERT);
      t = *slot;
      if (!t)
	{
	  /* Insert this one into the hash table.  */
	  t = nt;
	  *slot = t;
	}
      else
	ggc_free (nt);
    }

  return t;
}

hashval_t
poly_int_cst_hasher::hash (tree t)
{
  inchash::hash hstate;

  hstate.add_int (TYPE_UID (TREE_TYPE (t)));
  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    hstate.add_wide_int (wi::to_wide (POLY_INT_CST_COEFF (t, i)));

  return hstate.end ();
}

bool
poly_int_cst_hasher::equal (tree x, const compare_type &y)
{
  if (TREE_TYPE (x) != y.first)
    return false;
  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    if (wi::to_wide (POLY_INT_CST_COEFF (x, i)) != y.second->coeffs[i])
      return false;
  return true;
}

/* Build a POLY_INT_CST node with type TYPE and with the elements in VALUES.
   The elements must also have type TYPE.  */

tree
build_poly_int_cst (tree type, const poly_wide_int_ref &values)
{
  unsigned int prec = TYPE_PRECISION (type);
  gcc_assert (prec <= values.coeffs[0].get_precision ());
  poly_wide_int c = poly_wide_int::from (values, prec, SIGNED);

  inchash::hash h;
  h.add_int (TYPE_UID (type));
  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    h.add_wide_int (c.coeffs[i]);
  poly_int_cst_hasher::compare_type comp (type, &c);
  tree *slot = poly_int_cst_hash_table->find_slot_with_hash (comp, h.end (),
							     INSERT);
  if (*slot == NULL_TREE)
    {
      tree coeffs[NUM_POLY_INT_COEFFS];
      for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
	coeffs[i] = wide_int_to_tree_1 (type, c.coeffs[i]);
      *slot = build_new_poly_int_cst (type, coeffs);
    }
  return *slot;
}

/* Create a constant tree with value VALUE in type TYPE.  */

tree
wide_int_to_tree (tree type, const poly_wide_int_ref &value)
{
  if (value.is_constant ())
    return wide_int_to_tree_1 (type, value.coeffs[0]);
  return build_poly_int_cst (type, value);
}

void
cache_integer_cst (tree t)
{
  tree type = TREE_TYPE (t);
  int ix = -1;
  int limit = 0;
  int prec = TYPE_PRECISION (type);

  gcc_assert (!TREE_OVERFLOW (t));

  switch (TREE_CODE (type))
    {
    case NULLPTR_TYPE:
      gcc_assert (integer_zerop (t));
      /* Fallthru.  */

    case POINTER_TYPE:
    case REFERENCE_TYPE:
      /* Cache NULL pointer.  */
      if (integer_zerop (t))
	{
	  limit = 1;
	  ix = 0;
	}
      break;

    case BOOLEAN_TYPE:
      /* Cache false or true.  */
      limit = 2;
      if (wi::ltu_p (wi::to_wide (t), 2))
	ix = TREE_INT_CST_ELT (t, 0);
      break;

    case INTEGER_TYPE:
    case OFFSET_TYPE:
      if (TYPE_UNSIGNED (type))
	{
	  /* Cache 0..N */
	  limit = INTEGER_SHARE_LIMIT;

	  /* This is a little hokie, but if the prec is smaller than
	     what is necessary to hold INTEGER_SHARE_LIMIT, then the
	     obvious test will not get the correct answer.  */
	  if (prec < HOST_BITS_PER_WIDE_INT)
	    {
	      if (tree_to_uhwi (t) < (unsigned HOST_WIDE_INT) INTEGER_SHARE_LIMIT)
		ix = tree_to_uhwi (t);
	    }
	  else if (wi::ltu_p (wi::to_wide (t), INTEGER_SHARE_LIMIT))
	    ix = tree_to_uhwi (t);
	}
      else
	{
	  /* Cache -1..N */
	  limit = INTEGER_SHARE_LIMIT + 1;

	  if (integer_minus_onep (t))
	    ix = 0;
	  else if (!wi::neg_p (wi::to_wide (t)))
	    {
	      if (prec < HOST_BITS_PER_WIDE_INT)
		{
		  if (tree_to_shwi (t) < INTEGER_SHARE_LIMIT)
		    ix = tree_to_shwi (t) + 1;
		}
	      else if (wi::ltu_p (wi::to_wide (t), INTEGER_SHARE_LIMIT))
		ix = tree_to_shwi (t) + 1;
	    }
	}
      break;

    case ENUMERAL_TYPE:
      break;

    default:
      gcc_unreachable ();
    }

  if (ix >= 0)
    {
      /* Look for it in the type's vector of small shared ints.  */
      if (!TYPE_CACHED_VALUES_P (type))
	{
	  TYPE_CACHED_VALUES_P (type) = 1;
	  TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
	}

      gcc_assert (TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) == NULL_TREE);
      TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
    }
  else
    {
      /* Use the cache of larger shared ints.  */
      tree *slot = int_cst_hash_table->find_slot (t, INSERT);
      /* If there is already an entry for the number verify it's the
         same.  */
      if (*slot)
	gcc_assert (wi::to_wide (tree (*slot)) == wi::to_wide (t));
      else
	/* Otherwise insert this one into the hash table.  */
	*slot = t;
    }
}


/* Builds an integer constant in TYPE such that lowest BITS bits are ones
   and the rest are zeros.  */

tree
build_low_bits_mask (tree type, unsigned bits)
{
  gcc_assert (bits <= TYPE_PRECISION (type));

  return wide_int_to_tree (type, wi::mask (bits, false,
					   TYPE_PRECISION (type)));
}

/* Checks that X is integer constant that can be expressed in (unsigned)
   HOST_WIDE_INT without loss of precision.  */

bool
cst_and_fits_in_hwi (const_tree x)
{
  return (TREE_CODE (x) == INTEGER_CST
	  && (tree_fits_shwi_p (x) || tree_fits_uhwi_p (x)));
}

/* Build a newly constructed VECTOR_CST with the given values of
   (VECTOR_CST_)LOG2_NPATTERNS and (VECTOR_CST_)NELTS_PER_PATTERN.  */

tree
make_vector (unsigned log2_npatterns,
	     unsigned int nelts_per_pattern MEM_STAT_DECL)
{
  gcc_assert (IN_RANGE (nelts_per_pattern, 1, 3));
  tree t;
  unsigned npatterns = 1 << log2_npatterns;
  unsigned encoded_nelts = npatterns * nelts_per_pattern;
  unsigned length = (sizeof (struct tree_vector)
		     + (encoded_nelts - 1) * sizeof (tree));

  record_node_allocation_statistics (VECTOR_CST, length);

  t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);

  TREE_SET_CODE (t, VECTOR_CST);
  TREE_CONSTANT (t) = 1;
  VECTOR_CST_LOG2_NPATTERNS (t) = log2_npatterns;
  VECTOR_CST_NELTS_PER_PATTERN (t) = nelts_per_pattern;

  return t;
}

/* Return a new VECTOR_CST node whose type is TYPE and whose values
   are extracted from V, a vector of CONSTRUCTOR_ELT.  */

tree
build_vector_from_ctor (tree type, vec<constructor_elt, va_gc> *v)
{
  unsigned HOST_WIDE_INT idx, nelts;
  tree value;

  /* We can't construct a VECTOR_CST for a variable number of elements.  */
  nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
  tree_vector_builder vec (type, nelts, 1);
  FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
    {
      if (TREE_CODE (value) == VECTOR_CST)
	{
	  /* If NELTS is constant then this must be too.  */
	  unsigned int sub_nelts = VECTOR_CST_NELTS (value).to_constant ();
	  for (unsigned i = 0; i < sub_nelts; ++i)
	    vec.quick_push (VECTOR_CST_ELT (value, i));
	}
      else
	vec.quick_push (value);
    }
  while (vec.length () < nelts)
    vec.quick_push (build_zero_cst (TREE_TYPE (type)));

  return vec.build ();
}

/* Build a vector of type VECTYPE where all the elements are SCs.  */
tree
build_vector_from_val (tree vectype, tree sc)
{
  unsigned HOST_WIDE_INT i, nunits;

  if (sc == error_mark_node)
    return sc;

  /* Verify that the vector type is suitable for SC.  Note that there
     is some inconsistency in the type-system with respect to restrict
     qualifications of pointers.  Vector types always have a main-variant
     element type and the qualification is applied to the vector-type.
     So TREE_TYPE (vector-type) does not return a properly qualified
     vector element-type.  */
  gcc_checking_assert (types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (sc)),
					   TREE_TYPE (vectype)));

  if (CONSTANT_CLASS_P (sc))
    {
      tree_vector_builder v (vectype, 1, 1);
      v.quick_push (sc);
      return v.build ();
    }
  else if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant (&nunits))
    return fold_build1 (VEC_DUPLICATE_EXPR, vectype, sc);
  else
    {
      vec<constructor_elt, va_gc> *v;
      vec_alloc (v, nunits);
      for (i = 0; i < nunits; ++i)
	CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, sc);
      return build_constructor (vectype, v);
    }
}

/* If TYPE is not a vector type, just return SC, otherwise return
   build_vector_from_val (TYPE, SC).  */

tree
build_uniform_cst (tree type, tree sc)
{
  if (!VECTOR_TYPE_P (type))
    return sc;

  return build_vector_from_val (type, sc);
}

/* Build a vector series of type TYPE in which element I has the value
   BASE + I * STEP.  The result is a constant if BASE and STEP are constant
   and a VEC_SERIES_EXPR otherwise.  */

tree
build_vec_series (tree type, tree base, tree step)
{
  if (integer_zerop (step))
    return build_vector_from_val (type, base);
  if (TREE_CODE (base) == INTEGER_CST && TREE_CODE (step) == INTEGER_CST)
    {
      tree_vector_builder builder (type, 1, 3);
      tree elt1 = wide_int_to_tree (TREE_TYPE (base),
				    wi::to_wide (base) + wi::to_wide (step));
      tree elt2 = wide_int_to_tree (TREE_TYPE (base),
				    wi::to_wide (elt1) + wi::to_wide (step));
      builder.quick_push (base);
      builder.quick_push (elt1);
      builder.quick_push (elt2);
      return builder.build ();
    }
  return build2 (VEC_SERIES_EXPR, type, base, step);
}

/* Return a vector with the same number of units and number of bits
   as VEC_TYPE, but in which the elements are a linear series of unsigned
   integers { BASE, BASE + STEP, BASE + STEP * 2, ... }.  */

tree
build_index_vector (tree vec_type, poly_uint64 base, poly_uint64 step)
{
  tree index_vec_type = vec_type;
  tree index_elt_type = TREE_TYPE (vec_type);
  poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vec_type);
  if (!INTEGRAL_TYPE_P (index_elt_type) || !TYPE_UNSIGNED (index_elt_type))
    {
      index_elt_type = build_nonstandard_integer_type
	(GET_MODE_BITSIZE (SCALAR_TYPE_MODE (index_elt_type)), true);
      index_vec_type = build_vector_type (index_elt_type, nunits);
    }

  tree_vector_builder v (index_vec_type, 1, 3);
  for (unsigned int i = 0; i < 3; ++i)
    v.quick_push (build_int_cstu (index_elt_type, base + i * step));
  return v.build ();
}

/* Something has messed with the elements of CONSTRUCTOR C after it was built;
   calculate TREE_CONSTANT and TREE_SIDE_EFFECTS.  */

void
recompute_constructor_flags (tree c)
{
  unsigned int i;
  tree val;
  bool constant_p = true;
  bool side_effects_p = false;
  vec<constructor_elt, va_gc> *vals = CONSTRUCTOR_ELTS (c);

  FOR_EACH_CONSTRUCTOR_VALUE (vals, i, val)
    {
      /* Mostly ctors will have elts that don't have side-effects, so
	 the usual case is to scan all the elements.  Hence a single
	 loop for both const and side effects, rather than one loop
	 each (with early outs).  */
      if (!TREE_CONSTANT (val))
	constant_p = false;
      if (TREE_SIDE_EFFECTS (val))
	side_effects_p = true;
    }

  TREE_SIDE_EFFECTS (c) = side_effects_p;
  TREE_CONSTANT (c) = constant_p;
}

/* Make sure that TREE_CONSTANT and TREE_SIDE_EFFECTS are correct for
   CONSTRUCTOR C.  */

void
verify_constructor_flags (tree c)
{
  unsigned int i;
  tree val;
  bool constant_p = TREE_CONSTANT (c);
  bool side_effects_p = TREE_SIDE_EFFECTS (c);
  vec<constructor_elt, va_gc> *vals = CONSTRUCTOR_ELTS (c);

  FOR_EACH_CONSTRUCTOR_VALUE (vals, i, val)
    {
      if (constant_p && !TREE_CONSTANT (val))
	internal_error ("non-constant element in constant CONSTRUCTOR");
      if (!side_effects_p && TREE_SIDE_EFFECTS (val))
	internal_error ("side-effects element in no-side-effects CONSTRUCTOR");
    }
}

/* Return a new CONSTRUCTOR node whose type is TYPE and whose values
   are in the vec pointed to by VALS.  */
tree
build_constructor (tree type, vec<constructor_elt, va_gc> *vals)
{
  tree c = make_node (CONSTRUCTOR);

  TREE_TYPE (c) = type;
  CONSTRUCTOR_ELTS (c) = vals;

  recompute_constructor_flags (c);

  return c;
}

/* Build a CONSTRUCTOR node made of a single initializer, with the specified
   INDEX and VALUE.  */
tree
build_constructor_single (tree type, tree index, tree value)
{
  vec<constructor_elt, va_gc> *v;
  constructor_elt elt = {index, value};

  vec_alloc (v, 1);
  v->quick_push (elt);

  return build_constructor (type, v);
}


/* Return a new CONSTRUCTOR node whose type is TYPE and whose values
   are in a list pointed to by VALS.  */
tree
build_constructor_from_list (tree type, tree vals)
{
  tree t;
  vec<constructor_elt, va_gc> *v = NULL;

  if (vals)
    {
      vec_alloc (v, list_length (vals));
      for (t = vals; t; t = TREE_CHAIN (t))
	CONSTRUCTOR_APPEND_ELT (v, TREE_PURPOSE (t), TREE_VALUE (t));
    }

  return build_constructor (type, v);
}

/* Return a new CONSTRUCTOR node whose type is TYPE.  NELTS is the number
   of elements, provided as index/value pairs.  */

tree
build_constructor_va (tree type, int nelts, ...)
{
  vec<constructor_elt, va_gc> *v = NULL;
  va_list p;

  va_start (p, nelts);
  vec_alloc (v, nelts);
  while (nelts--)
    {
      tree index = va_arg (p, tree);
      tree value = va_arg (p, tree);
      CONSTRUCTOR_APPEND_ELT (v, index, value);
    }
  va_end (p);
  return build_constructor (type, v);
}

/* Return a node of type TYPE for which TREE_CLOBBER_P is true.  */

tree
build_clobber (tree type)
{
  tree clobber = build_constructor (type, NULL);
  TREE_THIS_VOLATILE (clobber) = true;
  return clobber;
}

/* Return a new FIXED_CST node whose type is TYPE and value is F.  */

tree
build_fixed (tree type, FIXED_VALUE_TYPE f)
{
  tree v;
  FIXED_VALUE_TYPE *fp;

  v = make_node (FIXED_CST);
  fp = ggc_alloc<fixed_value> ();
  memcpy (fp, &f, sizeof (FIXED_VALUE_TYPE));

  TREE_TYPE (v) = type;
  TREE_FIXED_CST_PTR (v) = fp;
  return v;
}

/* Return a new REAL_CST node whose type is TYPE and value is D.  */

tree
build_real (tree type, REAL_VALUE_TYPE d)
{
  tree v;
  REAL_VALUE_TYPE *dp;
  int overflow = 0;

  /* ??? Used to check for overflow here via CHECK_FLOAT_TYPE.
     Consider doing it via real_convert now.  */

  v = make_node (REAL_CST);
  dp = ggc_alloc<real_value> ();
  memcpy (dp, &d, sizeof (REAL_VALUE_TYPE));

  TREE_TYPE (v) = type;
  TREE_REAL_CST_PTR (v) = dp;
  TREE_OVERFLOW (v) = overflow;
  return v;
}

/* Like build_real, but first truncate D to the type.  */

tree
build_real_truncate (tree type, REAL_VALUE_TYPE d)
{
  return build_real (type, real_value_truncate (TYPE_MODE (type), d));
}

/* Return a new REAL_CST node whose type is TYPE
   and whose value is the integer value of the INTEGER_CST node I.  */

REAL_VALUE_TYPE
real_value_from_int_cst (const_tree type, const_tree i)
{
  REAL_VALUE_TYPE d;

  /* Clear all bits of the real value type so that we can later do
     bitwise comparisons to see if two values are the same.  */
  memset (&d, 0, sizeof d);

  real_from_integer (&d, type ? TYPE_MODE (type) : VOIDmode, wi::to_wide (i),
		     TYPE_SIGN (TREE_TYPE (i)));
  return d;
}

/* Given a tree representing an integer constant I, return a tree
   representing the same value as a floating-point constant of type TYPE.  */

tree
build_real_from_int_cst (tree type, const_tree i)
{
  tree v;
  int overflow = TREE_OVERFLOW (i);

  v = build_real (type, real_value_from_int_cst (type, i));

  TREE_OVERFLOW (v) |= overflow;
  return v;
}

/* Return a newly constructed STRING_CST node whose value is
   the LEN characters at STR.
   Note that for a C string literal, LEN should include the trailing NUL.
   The TREE_TYPE is not initialized.  */

tree
build_string (int len, const char *str)
{
  tree s;
  size_t length;

  /* Do not waste bytes provided by padding of struct tree_string.  */
  length = len + offsetof (struct tree_string, str) + 1;

  record_node_allocation_statistics (STRING_CST, length);

  s = (tree) ggc_internal_alloc (length);

  memset (s, 0, sizeof (struct tree_typed));
  TREE_SET_CODE (s, STRING_CST);
  TREE_CONSTANT (s) = 1;
  TREE_STRING_LENGTH (s) = len;
  memcpy (s->string.str, str, len);
  s->string.str[len] = '\0';

  return s;
}

/* Return a newly constructed COMPLEX_CST node whose value is
   specified by the real and imaginary parts REAL and IMAG.
   Both REAL and IMAG should be constant nodes.  TYPE, if specified,
   will be the type of the COMPLEX_CST; otherwise a new type will be made.  */

tree
build_complex (tree type, tree real, tree imag)
{
  tree t = make_node (COMPLEX_CST);

  TREE_REALPART (t) = real;
  TREE_IMAGPART (t) = imag;
  TREE_TYPE (t) = type ? type : build_complex_type (TREE_TYPE (real));
  TREE_OVERFLOW (t) = TREE_OVERFLOW (real) | TREE_OVERFLOW (imag);
  return t;
}

/* Build a complex (inf +- 0i), such as for the result of cproj.
   TYPE is the complex tree type of the result.  If NEG is true, the
   imaginary zero is negative.  */

tree
build_complex_inf (tree type, bool neg)
{
  REAL_VALUE_TYPE rinf, rzero = dconst0;

  real_inf (&rinf);
  rzero.sign = neg;
  return build_complex (type, build_real (TREE_TYPE (type), rinf),
			build_real (TREE_TYPE (type), rzero));
}

/* Return the constant 1 in type TYPE.  If TYPE has several elements, each
   element is set to 1.  In particular, this is 1 + i for complex types.  */

tree
build_each_one_cst (tree type)
{
  if (TREE_CODE (type) == COMPLEX_TYPE)
    {
      tree scalar = build_one_cst (TREE_TYPE (type));
      return build_complex (type, scalar, scalar);
    }
  else
    return build_one_cst (type);
}

/* Return a constant of arithmetic type TYPE which is the
   multiplicative identity of the set TYPE.  */

tree
build_one_cst (tree type)
{
  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
    case POINTER_TYPE: case REFERENCE_TYPE:
    case OFFSET_TYPE:
      return build_int_cst (type, 1);

    case REAL_TYPE:
      return build_real (type, dconst1);

    case FIXED_POINT_TYPE:
      /* We can only generate 1 for accum types.  */
      gcc_assert (ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type)));
      return build_fixed (type, FCONST1 (TYPE_MODE (type)));

    case VECTOR_TYPE:
      {
	tree scalar = build_one_cst (TREE_TYPE (type));

	return build_vector_from_val (type, scalar);
      }

    case COMPLEX_TYPE:
      return build_complex (type,
			    build_one_cst (TREE_TYPE (type)),
			    build_zero_cst (TREE_TYPE (type)));

    default:
      gcc_unreachable ();
    }
}

/* Return an integer of type TYPE containing all 1's in as much precision as
   it contains, or a complex or vector whose subparts are such integers.  */

tree
build_all_ones_cst (tree type)
{
  if (TREE_CODE (type) == COMPLEX_TYPE)
    {
      tree scalar = build_all_ones_cst (TREE_TYPE (type));
      return build_complex (type, scalar, scalar);
    }
  else
    return build_minus_one_cst (type);
}

/* Return a constant of arithmetic type TYPE which is the
   opposite of the multiplicative identity of the set TYPE.  */

tree
build_minus_one_cst (tree type)
{
  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
    case POINTER_TYPE: case REFERENCE_TYPE:
    case OFFSET_TYPE:
      return build_int_cst (type, -1);

    case REAL_TYPE:
      return build_real (type, dconstm1);

    case FIXED_POINT_TYPE:
      /* We can only generate 1 for accum types.  */
      gcc_assert (ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type)));
      return build_fixed (type,
			  fixed_from_double_int (double_int_minus_one,
						 SCALAR_TYPE_MODE (type)));

    case VECTOR_TYPE:
      {
	tree scalar = build_minus_one_cst (TREE_TYPE (type));

	return build_vector_from_val (type, scalar);
      }

    case COMPLEX_TYPE:
      return build_complex (type,
			    build_minus_one_cst (TREE_TYPE (type)),
			    build_zero_cst (TREE_TYPE (type)));

    default:
      gcc_unreachable ();
    }
}

/* Build 0 constant of type TYPE.  This is used by constructor folding
   and thus the constant should be represented in memory by
   zero(es).  */

tree
build_zero_cst (tree type)
{
  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
    case POINTER_TYPE: case REFERENCE_TYPE:
    case OFFSET_TYPE: case NULLPTR_TYPE:
      return build_int_cst (type, 0);

    case REAL_TYPE:
      return build_real (type, dconst0);

    case FIXED_POINT_TYPE:
      return build_fixed (type, FCONST0 (TYPE_MODE (type)));

    case VECTOR_TYPE:
      {
	tree scalar = build_zero_cst (TREE_TYPE (type));

	return build_vector_from_val (type, scalar);
      }

    case COMPLEX_TYPE:
      {
	tree zero = build_zero_cst (TREE_TYPE (type));

	return build_complex (type, zero, zero);
      }

    default:
      if (!AGGREGATE_TYPE_P (type))
	return fold_convert (type, integer_zero_node);
      return build_constructor (type, NULL);
    }
}


/* Build a BINFO with LEN language slots.  */

tree
make_tree_binfo (unsigned base_binfos MEM_STAT_DECL)
{
  tree t;
  size_t length = (offsetof (struct tree_binfo, base_binfos)
		   + vec<tree, va_gc>::embedded_size (base_binfos));

  record_node_allocation_statistics (TREE_BINFO, length);

  t = ggc_alloc_tree_node_stat (length PASS_MEM_STAT);

  memset (t, 0, offsetof (struct tree_binfo, base_binfos));

  TREE_SET_CODE (t, TREE_BINFO);

  BINFO_BASE_BINFOS (t)->embedded_init (base_binfos);

  return t;
}

/* Create a CASE_LABEL_EXPR tree node and return it.  */

tree
build_case_label (tree low_value, tree high_value, tree label_decl)
{
  tree t = make_node (CASE_LABEL_EXPR);

  TREE_TYPE (t) = void_type_node;
  SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (label_decl));

  CASE_LOW (t) = low_value;
  CASE_HIGH (t) = high_value;
  CASE_LABEL (t) = label_decl;
  CASE_CHAIN (t) = NULL_TREE;

  return t;
}

/* Build a newly constructed INTEGER_CST node.  LEN and EXT_LEN are the
   values of TREE_INT_CST_NUNITS and TREE_INT_CST_EXT_NUNITS respectively.
   The latter determines the length of the HOST_WIDE_INT vector.  */

tree
make_int_cst (int len, int ext_len MEM_STAT_DECL)
{
  tree t;
  int length = ((ext_len - 1) * sizeof (HOST_WIDE_INT)
		+ sizeof (struct tree_int_cst));

  gcc_assert (len);
  record_node_allocation_statistics (INTEGER_CST, length);

  t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);

  TREE_SET_CODE (t, INTEGER_CST);
  TREE_INT_CST_NUNITS (t) = len;
  TREE_INT_CST_EXT_NUNITS (t) = ext_len;
  /* to_offset can only be applied to trees that are offset_int-sized
     or smaller.  EXT_LEN is correct if it fits, otherwise the constant
     must be exactly the precision of offset_int and so LEN is correct.  */
  if (ext_len <= OFFSET_INT_ELTS)
    TREE_INT_CST_OFFSET_NUNITS (t) = ext_len;
  else
    TREE_INT_CST_OFFSET_NUNITS (t) = len;

  TREE_CONSTANT (t) = 1;

  return t;
}

/* Build a newly constructed TREE_VEC node of length LEN.  */

tree
make_tree_vec (int len MEM_STAT_DECL)
{
  tree t;
  size_t length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);

  record_node_allocation_statistics (TREE_VEC, length);

  t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);

  TREE_SET_CODE (t, TREE_VEC);
  TREE_VEC_LENGTH (t) = len;

  return t;
}

/* Grow a TREE_VEC node to new length LEN.  */

tree
grow_tree_vec (tree v, int len MEM_STAT_DECL)
{
  gcc_assert (TREE_CODE (v) == TREE_VEC);

  int oldlen = TREE_VEC_LENGTH (v);
  gcc_assert (len > oldlen);

  size_t oldlength = (oldlen - 1) * sizeof (tree) + sizeof (struct tree_vec);
  size_t length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);

  record_node_allocation_statistics (TREE_VEC, length - oldlength);

  v = (tree) ggc_realloc (v, length PASS_MEM_STAT);

  TREE_VEC_LENGTH (v) = len;

  return v;
}

/* Return 1 if EXPR is the constant zero, whether it is integral, float or
   fixed, and scalar, complex or vector.  */

bool
zerop (const_tree expr)
{
  return (integer_zerop (expr)
	  || real_zerop (expr)
	  || fixed_zerop (expr));
}

/* Return 1 if EXPR is the integer constant zero or a complex constant
   of zero.  */

bool
integer_zerop (const_tree expr)
{
  switch (TREE_CODE (expr))
    {
    case INTEGER_CST:
      return wi::to_wide (expr) == 0;
    case COMPLEX_CST:
      return (integer_zerop (TREE_REALPART (expr))
	      && integer_zerop (TREE_IMAGPART (expr)));
    case VECTOR_CST:
      return (VECTOR_CST_NPATTERNS (expr) == 1
	      && VECTOR_CST_DUPLICATE_P (expr)
	      && integer_zerop (VECTOR_CST_ENCODED_ELT (expr, 0)));
    default:
      return false;
    }
}

/* Return 1 if EXPR is the integer constant one or the corresponding
   complex constant.  */

bool
integer_onep (const_tree expr)
{
  switch (TREE_CODE (expr))
    {
    case INTEGER_CST:
      return wi::eq_p (wi::to_widest (expr), 1);
    case COMPLEX_CST:
      return (integer_onep (TREE_REALPART (expr))
	      && integer_zerop (TREE_IMAGPART (expr)));
    case VECTOR_CST:
      return (VECTOR_CST_NPATTERNS (expr) == 1
	      && VECTOR_CST_DUPLICATE_P (expr)
	      && integer_onep (VECTOR_CST_ENCODED_ELT (expr, 0)));
    default:
      return false;
    }
}

/* Return 1 if EXPR is the integer constant one.  For complex and vector,
   return 1 if every piece is the integer constant one.  */

bool
integer_each_onep (const_tree expr)
{
  if (TREE_CODE (expr) == COMPLEX_CST)
    return (integer_onep (TREE_REALPART (expr))
	    && integer_onep (TREE_IMAGPART (expr)));
  else
    return integer_onep (expr);
}

/* Return 1 if EXPR is an integer containing all 1's in as much precision as
   it contains, or a complex or vector whose subparts are such integers.  */

bool
integer_all_onesp (const_tree expr)
{
  if (TREE_CODE (expr) == COMPLEX_CST
      && integer_all_onesp (TREE_REALPART (expr))
      && integer_all_onesp (TREE_IMAGPART (expr)))
    return true;

  else if (TREE_CODE (expr) == VECTOR_CST)
    return (VECTOR_CST_NPATTERNS (expr) == 1
	    && VECTOR_CST_DUPLICATE_P (expr)
	    && integer_all_onesp (VECTOR_CST_ENCODED_ELT (expr, 0)));

  else if (TREE_CODE (expr) != INTEGER_CST)
    return false;

  return (wi::max_value (TYPE_PRECISION (TREE_TYPE (expr)), UNSIGNED)
	  == wi::to_wide (expr));
}

/* Return 1 if EXPR is the integer constant minus one.  */

bool
integer_minus_onep (const_tree expr)
{
  if (TREE_CODE (expr) == COMPLEX_CST)
    return (integer_all_onesp (TREE_REALPART (expr))
	    && integer_zerop (TREE_IMAGPART (expr)));
  else
    return integer_all_onesp (expr);
}

/* Return 1 if EXPR is an integer constant that is a power of 2 (i.e., has only
   one bit on).  */

bool
integer_pow2p (const_tree expr)
{
  if (TREE_CODE (expr) == COMPLEX_CST
      && integer_pow2p (TREE_REALPART (expr))
      && integer_zerop (TREE_IMAGPART (expr)))
    return true;

  if (TREE_CODE (expr) != INTEGER_CST)
    return false;

  return wi::popcount (wi::to_wide (expr)) == 1;
}

/* Return 1 if EXPR is an integer constant other than zero or a
   complex constant other than zero.  */

bool
integer_nonzerop (const_tree expr)
{
  return ((TREE_CODE (expr) == INTEGER_CST
	   && wi::to_wide (expr) != 0)
	  || (TREE_CODE (expr) == COMPLEX_CST
	      && (integer_nonzerop (TREE_REALPART (expr))
		  || integer_nonzerop (TREE_IMAGPART (expr)))));
}

/* Return 1 if EXPR is the integer constant one.  For vector,
   return 1 if every piece is the integer constant minus one
   (representing the value TRUE).  */

bool
integer_truep (const_tree expr)
{
  if (TREE_CODE (expr) == VECTOR_CST)
    return integer_all_onesp (expr);
  return integer_onep (expr);
}

/* Return 1 if EXPR is the fixed-point constant zero.  */

bool
fixed_zerop (const_tree expr)
{
  return (TREE_CODE (expr) == FIXED_CST
	  && TREE_FIXED_CST (expr).data.is_zero ());
}

/* Return the power of two represented by a tree node known to be a
   power of two.  */

int
tree_log2 (const_tree expr)
{
  if (TREE_CODE (expr) == COMPLEX_CST)
    return tree_log2 (TREE_REALPART (expr));

  return wi::exact_log2 (wi::to_wide (expr));
}

/* Similar, but return the largest integer Y such that 2 ** Y is less
   than or equal to EXPR.  */

int
tree_floor_log2 (const_tree expr)
{
  if (TREE_CODE (expr) == COMPLEX_CST)
    return tree_log2 (TREE_REALPART (expr));

  return wi::floor_log2 (wi::to_wide (expr));
}

/* Return number of known trailing zero bits in EXPR, or, if the value of
   EXPR is known to be zero, the precision of it's type.  */

unsigned int
tree_ctz (const_tree expr)
{
  if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
      && !POINTER_TYPE_P (TREE_TYPE (expr)))
    return 0;

  unsigned int ret1, ret2, prec = TYPE_PRECISION (TREE_TYPE (expr));
  switch (TREE_CODE (expr))
    {
    case INTEGER_CST:
      ret1 = wi::ctz (wi::to_wide (expr));
      return MIN (ret1, prec);
    case SSA_NAME:
      ret1 = wi::ctz (get_nonzero_bits (expr));
      return MIN (ret1, prec);
    case PLUS_EXPR:
    case MINUS_EXPR:
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
    case MIN_EXPR:
    case MAX_EXPR:
      ret1 = tree_ctz (TREE_OPERAND (expr, 0));
      if (ret1 == 0)
	return ret1;
      ret2 = tree_ctz (TREE_OPERAND (expr, 1));
      return MIN (ret1, ret2);
    case POINTER_PLUS_EXPR:
      ret1 = tree_ctz (TREE_OPERAND (expr, 0));
      ret2 = tree_ctz (TREE_OPERAND (expr, 1));
      /* Second operand is sizetype, which could be in theory
	 wider than pointer's precision.  Make sure we never
	 return more than prec.  */
      ret2 = MIN (ret2, prec);
      return MIN (ret1, ret2);
    case BIT_AND_EXPR:
      ret1 = tree_ctz (TREE_OPERAND (expr, 0));
      ret2 = tree_ctz (TREE_OPERAND (expr, 1));
      return MAX (ret1, ret2);
    case MULT_EXPR:
      ret1 = tree_ctz (TREE_OPERAND (expr, 0));
      ret2 = tree_ctz (TREE_OPERAND (expr, 1));
      return MIN (ret1 + ret2, prec);
    case LSHIFT_EXPR:
      ret1 = tree_ctz (TREE_OPERAND (expr, 0));
      if (tree_fits_uhwi_p (TREE_OPERAND (expr, 1))
	  && (tree_to_uhwi (TREE_OPERAND (expr, 1)) < prec))
	{
	  ret2 = tree_to_uhwi (TREE_OPERAND (expr, 1));
	  return MIN (ret1 + ret2, prec);
	}
      return ret1;
    case RSHIFT_EXPR:
      if (tree_fits_uhwi_p (TREE_OPERAND (expr, 1))
	  && (tree_to_uhwi (TREE_OPERAND (expr, 1)) < prec))
	{
	  ret1 = tree_ctz (TREE_OPERAND (expr, 0));
	  ret2 = tree_to_uhwi (TREE_OPERAND (expr, 1));
	  if (ret1 > ret2)
	    return ret1 - ret2;
	}
      return 0;
    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case EXACT_DIV_EXPR:
      if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
	  && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) == 1)
	{
	  int l = tree_log2 (TREE_OPERAND (expr, 1));
	  if (l >= 0)
	    {
	      ret1 = tree_ctz (TREE_OPERAND (expr, 0));
	      ret2 = l;
	      if (ret1 > ret2)
		return ret1 - ret2;
	    }
	}
      return 0;
    CASE_CONVERT:
      ret1 = tree_ctz (TREE_OPERAND (expr, 0));
      if (ret1 && ret1 == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
	ret1 = prec;
      return MIN (ret1, prec);
    case SAVE_EXPR:
      return tree_ctz (TREE_OPERAND (expr, 0));
    case COND_EXPR:
      ret1 = tree_ctz (TREE_OPERAND (expr, 1));
      if (ret1 == 0)
	return 0;
      ret2 = tree_ctz (TREE_OPERAND (expr, 2));
      return MIN (ret1, ret2);
    case COMPOUND_EXPR:
      return tree_ctz (TREE_OPERAND (expr, 1));
    case ADDR_EXPR:
      ret1 = get_pointer_alignment (CONST_CAST_TREE (expr));
      if (ret1 > BITS_PER_UNIT)
	{
	  ret1 = ctz_hwi (ret1 / BITS_PER_UNIT);
	  return MIN (ret1, prec);
	}
      return 0;
    default:
      return 0;
    }
}

/* Return 1 if EXPR is the real constant zero.  Trailing zeroes matter for
   decimal float constants, so don't return 1 for them.  */

bool
real_zerop (const_tree expr)
{
  switch (TREE_CODE (expr))
    {
    case REAL_CST:
      return real_equal (&TREE_REAL_CST (expr), &dconst0)
	     && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
    case COMPLEX_CST:
      return real_zerop (TREE_REALPART (expr))
	     && real_zerop (TREE_IMAGPART (expr));
    case VECTOR_CST:
      {
	/* Don't simply check for a duplicate because the predicate
	   accepts both +0.0 and -0.0.  */
	unsigned count = vector_cst_encoded_nelts (expr);
	for (unsigned int i = 0; i < count; ++i)
	  if (!real_zerop (VECTOR_CST_ENCODED_ELT (expr, i)))
	    return false;
	return true;
      }
    default:
      return false;
    }
}

/* Return 1 if EXPR is the real constant one in real or complex form.
   Trailing zeroes matter for decimal float constants, so don't return
   1 for them.  */

bool
real_onep (const_tree expr)
{
  switch (TREE_CODE (expr))
    {
    case REAL_CST:
      return real_equal (&TREE_REAL_CST (expr), &dconst1)
	     && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
    case COMPLEX_CST:
      return real_onep (TREE_REALPART (expr))
	     && real_zerop (TREE_IMAGPART (expr));
    case VECTOR_CST:
      return (VECTOR_CST_NPATTERNS (expr) == 1
	      && VECTOR_CST_DUPLICATE_P (expr)
	      && real_onep (VECTOR_CST_ENCODED_ELT (expr, 0)));
    default:
      return false;
    }
}

/* Return 1 if EXPR is the real constant minus one.  Trailing zeroes
   matter for decimal float constants, so don't return 1 for them.  */

bool
real_minus_onep (const_tree expr)
{
  switch (TREE_CODE (expr))
    {
    case REAL_CST:
      return real_equal (&TREE_REAL_CST (expr), &dconstm1)
	     && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
    case COMPLEX_CST:
      return real_minus_onep (TREE_REALPART (expr))
	     && real_zerop (TREE_IMAGPART (expr));
    case VECTOR_CST:
      return (VECTOR_CST_NPATTERNS (expr) == 1
	      && VECTOR_CST_DUPLICATE_P (expr)
	      && real_minus_onep (VECTOR_CST_ENCODED_ELT (expr, 0)));
    default:
      return false;
    }
}

/* Nonzero if EXP is a constant or a cast of a constant.  */

bool
really_constant_p (const_tree exp)
{
  /* This is not quite the same as STRIP_NOPS.  It does more.  */
  while (CONVERT_EXPR_P (exp)
	 || TREE_CODE (exp) == NON_LVALUE_EXPR)
    exp = TREE_OPERAND (exp, 0);
  return TREE_CONSTANT (exp);
}

/* Return true if T holds a polynomial pointer difference, storing it in
   *VALUE if so.  A true return means that T's precision is no greater
   than 64 bits, which is the largest address space we support, so *VALUE
   never loses precision.  However, the signedness of the result does
   not necessarily match the signedness of T: sometimes an unsigned type
   like sizetype is used to encode a value that is actually negative.  */

bool
ptrdiff_tree_p (const_tree t, poly_int64_pod *value)
{
  if (!t)
    return false;
  if (TREE_CODE (t) == INTEGER_CST)
    {
      if (!cst_and_fits_in_hwi (t))
	return false;
      *value = int_cst_value (t);
      return true;
    }
  if (POLY_INT_CST_P (t))
    {
      for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
	if (!cst_and_fits_in_hwi (POLY_INT_CST_COEFF (t, i)))
	  return false;
      for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
	value->coeffs[i] = int_cst_value (POLY_INT_CST_COEFF (t, i));
      return true;
    }
  return false;
}

poly_int64
tree_to_poly_int64 (const_tree t)
{
  gcc_assert (tree_fits_poly_int64_p (t));
  if (POLY_INT_CST_P (t))
    return poly_int_cst_value (t).force_shwi ();
  return TREE_INT_CST_LOW (t);
}

poly_uint64
tree_to_poly_uint64 (const_tree t)
{
  gcc_assert (tree_fits_poly_uint64_p (t));
  if (POLY_INT_CST_P (t))
    return poly_int_cst_value (t).force_uhwi ();
  return TREE_INT_CST_LOW (t);
}

/* Return first list element whose TREE_VALUE is ELEM.
   Return 0 if ELEM is not in LIST.  */

tree
value_member (tree elem, tree list)
{
  while (list)
    {
      if (elem == TREE_VALUE (list))
	return list;
      list = TREE_CHAIN (list);
    }
  return NULL_TREE;
}

/* Return first list element whose TREE_PURPOSE is ELEM.
   Return 0 if ELEM is not in LIST.  */

tree
purpose_member (const_tree elem, tree list)
{
  while (list)
    {
      if (elem == TREE_PURPOSE (list))
	return list;
      list = TREE_CHAIN (list);
    }
  return NULL_TREE;
}

/* Return true if ELEM is in V.  */

bool
vec_member (const_tree elem, vec<tree, va_gc> *v)
{
  unsigned ix;
  tree t;
  FOR_EACH_VEC_SAFE_ELT (v, ix, t)
    if (elem == t)
      return true;
  return false;
}

/* Returns element number IDX (zero-origin) of chain CHAIN, or
   NULL_TREE.  */

tree
chain_index (int idx, tree chain)
{
  for (; chain && idx > 0; --idx)
    chain = TREE_CHAIN (chain);
  return chain;
}

/* Return nonzero if ELEM is part of the chain CHAIN.  */

bool
chain_member (const_tree elem, const_tree chain)
{
  while (chain)
    {
      if (elem == chain)
	return true;
      chain = DECL_CHAIN (chain);
    }

  return false;
}

/* Return the length of a chain of nodes chained through TREE_CHAIN.
   We expect a null pointer to mark the end of the chain.
   This is the Lisp primitive `length'.  */

int
list_length (const_tree t)
{
  const_tree p = t;
#ifdef ENABLE_TREE_CHECKING
  const_tree q = t;
#endif
  int len = 0;

  while (p)
    {
      p = TREE_CHAIN (p);
#ifdef ENABLE_TREE_CHECKING
      if (len % 2)
	q = TREE_CHAIN (q);
      gcc_assert (p != q);
#endif
      len++;
    }

  return len;
}

/* Returns the first FIELD_DECL in the TYPE_FIELDS of the RECORD_TYPE or
   UNION_TYPE TYPE, or NULL_TREE if none.  */

tree
first_field (const_tree type)
{
  tree t = TYPE_FIELDS (type);
  while (t && TREE_CODE (t) != FIELD_DECL)
    t = TREE_CHAIN (t);
  return t;
}

/* Concatenate two chains of nodes (chained through TREE_CHAIN)
   by modifying the last node in chain 1 to point to chain 2.
   This is the Lisp primitive `nconc'.  */

tree
chainon (tree op1, tree op2)
{
  tree t1;

  if (!op1)
    return op2;
  if (!op2)
    return op1;

  for (t1 = op1; TREE_CHAIN (t1); t1 = TREE_CHAIN (t1))
    continue;
  TREE_CHAIN (t1) = op2;

#ifdef ENABLE_TREE_CHECKING
  {
    tree t2;
    for (t2 = op2; t2; t2 = TREE_CHAIN (t2))
      gcc_assert (t2 != t1);
  }
#endif

  return op1;
}

/* Return the last node in a chain of nodes (chained through TREE_CHAIN).  */

tree
tree_last (tree chain)
{
  tree next;
  if (chain)
    while ((next = TREE_CHAIN (chain)))
      chain = next;
  return chain;
}

/* Reverse the order of elements in the chain T,
   and return the new head of the chain (old last element).  */

tree
nreverse (tree t)
{
  tree prev = 0, decl, next;
  for (decl = t; decl; decl = next)
    {
      /* We shouldn't be using this function to reverse BLOCK chains; we
	 have blocks_nreverse for that.  */
      gcc_checking_assert (TREE_CODE (decl) != BLOCK);
      next = TREE_CHAIN (decl);
      TREE_CHAIN (decl) = prev;
      prev = decl;
    }
  return prev;
}

/* Return a newly created TREE_LIST node whose
   purpose and value fields are PARM and VALUE.  */

tree
build_tree_list (tree parm, tree value MEM_STAT_DECL)
{
  tree t = make_node (TREE_LIST PASS_MEM_STAT);
  TREE_PURPOSE (t) = parm;
  TREE_VALUE (t) = value;
  return t;
}

/* Build a chain of TREE_LIST nodes from a vector.  */

tree
build_tree_list_vec (const vec<tree, va_gc> *vec MEM_STAT_DECL)
{
  tree ret = NULL_TREE;
  tree *pp = &ret;
  unsigned int i;
  tree t;
  FOR_EACH_VEC_SAFE_ELT (vec, i, t)
    {
      *pp = build_tree_list (NULL, t PASS_MEM_STAT);
      pp = &TREE_CHAIN (*pp);
    }
  return ret;
}

/* Return a newly created TREE_LIST node whose
   purpose and value fields are PURPOSE and VALUE
   and whose TREE_CHAIN is CHAIN.  */

tree 
tree_cons (tree purpose, tree value, tree chain MEM_STAT_DECL)
{
  tree node;

  node = ggc_alloc_tree_node_stat (sizeof (struct tree_list) PASS_MEM_STAT);
  memset (node, 0, sizeof (struct tree_common));

  record_node_allocation_statistics (TREE_LIST, sizeof (struct tree_list));

  TREE_SET_CODE (node, TREE_LIST);
  TREE_CHAIN (node) = chain;
  TREE_PURPOSE (node) = purpose;
  TREE_VALUE (node) = value;
  return node;
}

/* Return the values of the elements of a CONSTRUCTOR as a vector of
   trees.  */

vec<tree, va_gc> *
ctor_to_vec (tree ctor)
{
  vec<tree, va_gc> *vec;
  vec_alloc (vec, CONSTRUCTOR_NELTS (ctor));
  unsigned int ix;
  tree val;

  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), ix, val)
    vec->quick_push (val);

  return vec;
}

/* Return the size nominally occupied by an object of type TYPE
   when it resides in memory.  The value is measured in units of bytes,
   and its data type is that normally used for type sizes
   (which is the first type created by make_signed_type or
   make_unsigned_type).  */

tree
size_in_bytes_loc (location_t loc, const_tree type)
{
  tree t;

  if (type == error_mark_node)
    return integer_zero_node;

  type = TYPE_MAIN_VARIANT (type);
  t = TYPE_SIZE_UNIT (type);

  if (t == 0)
    {
      lang_hooks.types.incomplete_type_error (loc, NULL_TREE, type);
      return size_zero_node;
    }

  return t;
}

/* Return the size of TYPE (in bytes) as a wide integer
   or return -1 if the size can vary or is larger than an integer.  */

HOST_WIDE_INT
int_size_in_bytes (const_tree type)
{
  tree t;

  if (type == error_mark_node)
    return 0;

  type = TYPE_MAIN_VARIANT (type);
  t = TYPE_SIZE_UNIT (type);

  if (t && tree_fits_uhwi_p (t))
    return TREE_INT_CST_LOW (t);
  else
    return -1;
}

/* Return the maximum size of TYPE (in bytes) as a wide integer
   or return -1 if the size can vary or is larger than an integer.  */

HOST_WIDE_INT
max_int_size_in_bytes (const_tree type)
{
  HOST_WIDE_INT size = -1;
  tree size_tree;

  /* If this is an array type, check for a possible MAX_SIZE attached.  */

  if (TREE_CODE (type) == ARRAY_TYPE)
    {
      size_tree = TYPE_ARRAY_MAX_SIZE (type);

      if (size_tree && tree_fits_uhwi_p (size_tree))
	size = tree_to_uhwi (size_tree);
    }

  /* If we still haven't been able to get a size, see if the language
     can compute a maximum size.  */

  if (size == -1)
    {
      size_tree = lang_hooks.types.max_size (type);

      if (size_tree && tree_fits_uhwi_p (size_tree))
	size = tree_to_uhwi (size_tree);
    }

  return size;
}

/* Return the bit position of FIELD, in bits from the start of the record.
   This is a tree of type bitsizetype.  */

tree
bit_position (const_tree field)
{
  return bit_from_pos (DECL_FIELD_OFFSET (field),
		       DECL_FIELD_BIT_OFFSET (field));
}

/* Return the byte position of FIELD, in bytes from the start of the record.
   This is a tree of type sizetype.  */

tree
byte_position (const_tree field)
{
  return byte_from_pos (DECL_FIELD_OFFSET (field),
			DECL_FIELD_BIT_OFFSET (field));
}

/* Likewise, but return as an integer.  It must be representable in
   that way (since it could be a signed value, we don't have the
   option of returning -1 like int_size_in_byte can.  */

HOST_WIDE_INT
int_byte_position (const_tree field)
{
  return tree_to_shwi (byte_position (field));
}

/* Return the strictest alignment, in bits, that T is known to have.  */

unsigned int
expr_align (const_tree t)
{
  unsigned int align0, align1;

  switch (TREE_CODE (t))
    {
    CASE_CONVERT:  case NON_LVALUE_EXPR:
      /* If we have conversions, we know that the alignment of the
	 object must meet each of the alignments of the types.  */
      align0 = expr_align (TREE_OPERAND (t, 0));
      align1 = TYPE_ALIGN (TREE_TYPE (t));
      return MAX (align0, align1);

    case SAVE_EXPR:         case COMPOUND_EXPR:       case MODIFY_EXPR:
    case INIT_EXPR:         case TARGET_EXPR:         case WITH_CLEANUP_EXPR:
    case CLEANUP_POINT_EXPR:
      /* These don't change the alignment of an object.  */
      return expr_align (TREE_OPERAND (t, 0));

    case COND_EXPR:
      /* The best we can do is say that the alignment is the least aligned
	 of the two arms.  */
      align0 = expr_align (TREE_OPERAND (t, 1));
      align1 = expr_align (TREE_OPERAND (t, 2));
      return MIN (align0, align1);

      /* FIXME: LABEL_DECL and CONST_DECL never have DECL_ALIGN set
	 meaningfully, it's always 1.  */
    case LABEL_DECL:     case CONST_DECL:
    case VAR_DECL:       case PARM_DECL:   case RESULT_DECL:
    case FUNCTION_DECL:
      gcc_assert (DECL_ALIGN (t) != 0);
      return DECL_ALIGN (t);

    default:
      break;
    }

  /* Otherwise take the alignment from that of the type.  */
  return TYPE_ALIGN (TREE_TYPE (t));
}

/* Return, as a tree node, the number of elements for TYPE (which is an
   ARRAY_TYPE) minus one. This counts only elements of the top array.  */

tree
array_type_nelts (const_tree type)
{
  tree index_type, min, max;

  /* If they did it with unspecified bounds, then we should have already
     given an error about it before we got here.  */
  if (! TYPE_DOMAIN (type))
    return error_mark_node;

  index_type = TYPE_DOMAIN (type);
  min = TYPE_MIN_VALUE (index_type);
  max = TYPE_MAX_VALUE (index_type);

  /* TYPE_MAX_VALUE may not be set if the array has unknown length.  */
  if (!max)
    return error_mark_node;

  return (integer_zerop (min)
	  ? max
	  : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
}

/* If arg is static -- a reference to an object in static storage -- then
   return the object.  This is not the same as the C meaning of `static'.
   If arg isn't static, return NULL.  */

tree
staticp (tree arg)
{
  switch (TREE_CODE (arg))
    {
    case FUNCTION_DECL:
      /* Nested functions are static, even though taking their address will
	 involve a trampoline as we unnest the nested function and create
	 the trampoline on the tree level.  */
      return arg;

    case VAR_DECL:
      return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
	      && ! DECL_THREAD_LOCAL_P (arg)
	      && ! DECL_DLLIMPORT_P (arg)
	      ? arg : NULL);

    case CONST_DECL:
      return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
	      ? arg : NULL);

    case CONSTRUCTOR:
      return TREE_STATIC (arg) ? arg : NULL;

    case LABEL_DECL:
    case STRING_CST:
      return arg;

    case COMPONENT_REF:
      /* If the thing being referenced is not a field, then it is
	 something language specific.  */
      gcc_assert (TREE_CODE (TREE_OPERAND (arg, 1)) == FIELD_DECL);

      /* If we are referencing a bitfield, we can't evaluate an
	 ADDR_EXPR at compile time and so it isn't a constant.  */
      if (DECL_BIT_FIELD (TREE_OPERAND (arg, 1)))
	return NULL;

      return staticp (TREE_OPERAND (arg, 0));

    case BIT_FIELD_REF:
      return NULL;

    case INDIRECT_REF:
      return TREE_CONSTANT (TREE_OPERAND (arg, 0)) ? arg : NULL;

    case ARRAY_REF:
    case ARRAY_RANGE_REF:
      if (TREE_CODE (TYPE_SIZE (TREE_TYPE (arg))) == INTEGER_CST
	  && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST)
	return staticp (TREE_OPERAND (arg, 0));
      else
	return NULL;

    case COMPOUND_LITERAL_EXPR:
      return TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (arg)) ? arg : NULL;

    default:
      return NULL;
    }
}




/* Return whether OP is a DECL whose address is function-invariant.  */

bool
decl_address_invariant_p (const_tree op)
{
  /* The conditions below are slightly less strict than the one in
     staticp.  */

  switch (TREE_CODE (op))
    {
    case PARM_DECL:
    case RESULT_DECL:
    case LABEL_DECL:
    case FUNCTION_DECL:
      return true;

    case VAR_DECL:
      if ((TREE_STATIC (op) || DECL_EXTERNAL (op))
          || DECL_THREAD_LOCAL_P (op)
          || DECL_CONTEXT (op) == current_function_decl
          || decl_function_context (op) == current_function_decl)
        return true;
      break;

    case CONST_DECL:
      if ((TREE_STATIC (op) || DECL_EXTERNAL (op))
          || decl_function_context (op) == current_function_decl)
        return true;
      break;

    default:
      break;
    }

  return false;
}

/* Return whether OP is a DECL whose address is interprocedural-invariant.  */

bool
decl_address_ip_invariant_p (const_tree op)
{
  /* The conditions below are slightly less strict than the one in
     staticp.  */

  switch (TREE_CODE (op))
    {
    case LABEL_DECL:
    case FUNCTION_DECL:
    case STRING_CST:
      return true;

    case VAR_DECL:
      if (((TREE_STATIC (op) || DECL_EXTERNAL (op))
           && !DECL_DLLIMPORT_P (op))
          || DECL_THREAD_LOCAL_P (op))
        return true;
      break;

    case CONST_DECL:
      if ((TREE_STATIC (op) || DECL_EXTERNAL (op)))
        return true;
      break;

    default:
      break;
    }

  return false;
}


/* Return true if T is function-invariant (internal function, does
   not handle arithmetic; that's handled in skip_simple_arithmetic and
   tree_invariant_p).  */

static bool
tree_invariant_p_1 (tree t)
{
  tree op;

  if (TREE_CONSTANT (t)
      || (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t)))
    return true;

  switch (TREE_CODE (t))
    {
    case SAVE_EXPR:
      return true;

    case ADDR_EXPR:
      op = TREE_OPERAND (t, 0);
      while (handled_component_p (op))
	{
	  switch (TREE_CODE (op))
	    {
	    case ARRAY_REF:
	    case ARRAY_RANGE_REF:
	      if (!tree_invariant_p (TREE_OPERAND (op, 1))
		  || TREE_OPERAND (op, 2) != NULL_TREE
		  || TREE_OPERAND (op, 3) != NULL_TREE)
		return false;
	      break;

	    case COMPONENT_REF:
	      if (TREE_OPERAND (op, 2) != NULL_TREE)
		return false;
	      break;

	    default:;
	    }
	  op = TREE_OPERAND (op, 0);
	}

      return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op);

    default:
      break;
    }

  return false;
}

/* Return true if T is function-invariant.  */

bool
tree_invariant_p (tree t)
{
  tree inner = skip_simple_arithmetic (t);
  return tree_invariant_p_1 (inner);
}

/* Wrap a SAVE_EXPR around EXPR, if appropriate.
   Do this to any expression which may be used in more than one place,
   but must be evaluated only once.

   Normally, expand_expr would reevaluate the expression each time.
   Calling save_expr produces something that is evaluated and recorded
   the first time expand_expr is called on it.  Subsequent calls to
   expand_expr just reuse the recorded value.

   The call to expand_expr that generates code that actually computes
   the value is the first call *at compile time*.  Subsequent calls
   *at compile time* generate code to use the saved value.
   This produces correct result provided that *at run time* control
   always flows through the insns made by the first expand_expr
   before reaching the other places where the save_expr was evaluated.
   You, the caller of save_expr, must make sure this is so.

   Constants, and certain read-only nodes, are returned with no
   SAVE_EXPR because that is safe.  Expressions containing placeholders
   are not touched; see tree.def for an explanation of what these
   are used for.  */

tree
save_expr (tree expr)
{
  tree inner;

  /* If the tree evaluates to a constant, then we don't want to hide that
     fact (i.e. this allows further folding, and direct checks for constants).
     However, a read-only object that has side effects cannot be bypassed.
     Since it is no problem to reevaluate literals, we just return the
     literal node.  */
  inner = skip_simple_arithmetic (expr);
  if (TREE_CODE (inner) == ERROR_MARK)
    return inner;

  if (tree_invariant_p_1 (inner))
    return expr;

  /* If INNER contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
     it means that the size or offset of some field of an object depends on
     the value within another field.

     Note that it must not be the case that EXPR contains both a PLACEHOLDER_EXPR
     and some variable since it would then need to be both evaluated once and
     evaluated more than once.  Front-ends must assure this case cannot
     happen by surrounding any such subexpressions in their own SAVE_EXPR
     and forcing evaluation at the proper time.  */
  if (contains_placeholder_p (inner))
    return expr;

  expr = build1_loc (EXPR_LOCATION (expr), SAVE_EXPR, TREE_TYPE (expr), expr);

  /* This expression might be placed ahead of a jump to ensure that the
     value was computed on both sides of the jump.  So make sure it isn't
     eliminated as dead.  */
  TREE_SIDE_EFFECTS (expr) = 1;
  return expr;
}

/* Look inside EXPR into any simple arithmetic operations.  Return the
   outermost non-arithmetic or non-invariant node.  */

tree
skip_simple_arithmetic (tree expr)
{
  /* We don't care about whether this can be used as an lvalue in this
     context.  */
  while (TREE_CODE (expr) == NON_LVALUE_EXPR)
    expr = TREE_OPERAND (expr, 0);

  /* If we have simple operations applied to a SAVE_EXPR or to a SAVE_EXPR and
     a constant, it will be more efficient to not make another SAVE_EXPR since
     it will allow better simplification and GCSE will be able to merge the
     computations if they actually occur.  */
  while (true)
    {
      if (UNARY_CLASS_P (expr))
	expr = TREE_OPERAND (expr, 0);
      else if (BINARY_CLASS_P (expr))
	{
	  if (tree_invariant_p (TREE_OPERAND (expr, 1)))
	    expr = TREE_OPERAND (expr, 0);
	  else if (tree_invariant_p (TREE_OPERAND (expr, 0)))
	    expr = TREE_OPERAND (expr, 1);
	  else
	    break;
	}
      else
	break;
    }

  return expr;
}

/* Look inside EXPR into simple arithmetic operations involving constants.
   Return the outermost non-arithmetic or non-constant node.  */

tree
skip_simple_constant_arithmetic (tree expr)
{
  while (TREE_CODE (expr) == NON_LVALUE_EXPR)
    expr = TREE_OPERAND (expr, 0);

  while (true)
    {
      if (UNARY_CLASS_P (expr))
	expr = TREE_OPERAND (expr, 0);
      else if (BINARY_CLASS_P (expr))
	{
	  if (TREE_CONSTANT (TREE_OPERAND (expr, 1)))
	    expr = TREE_OPERAND (expr, 0);
	  else if (TREE_CONSTANT (TREE_OPERAND (expr, 0)))
	    expr = TREE_OPERAND (expr, 1);
	  else
	    break;
	}
      else
	break;
    }

  return expr;
}

/* Return which tree structure is used by T.  */

enum tree_node_structure_enum
tree_node_structure (const_tree t)
{
  const enum tree_code code = TREE_CODE (t);
  return tree_node_structure_for_code (code);
}

/* Set various status flags when building a CALL_EXPR object T.  */

static void
process_call_operands (tree t)
{
  bool side_effects = TREE_SIDE_EFFECTS (t);
  bool read_only = false;
  int i = call_expr_flags (t);

  /* Calls have side-effects, except those to const or pure functions.  */
  if ((i & ECF_LOOPING_CONST_OR_PURE) || !(i & (ECF_CONST | ECF_PURE)))
    side_effects = true;
  /* Propagate TREE_READONLY of arguments for const functions.  */
  if (i & ECF_CONST)
    read_only = true;

  if (!side_effects || read_only)
    for (i = 1; i < TREE_OPERAND_LENGTH (t); i++)
      {
	tree op = TREE_OPERAND (t, i);
	if (op && TREE_SIDE_EFFECTS (op))
	  side_effects = true;
	if (op && !TREE_READONLY (op) && !CONSTANT_CLASS_P (op))
	  read_only = false;
      }

  TREE_SIDE_EFFECTS (t) = side_effects;
  TREE_READONLY (t) = read_only;
}

/* Return true if EXP contains a PLACEHOLDER_EXPR, i.e. if it represents a
   size or offset that depends on a field within a record.  */

bool
contains_placeholder_p (const_tree exp)
{
  enum tree_code code;

  if (!exp)
    return 0;

  code = TREE_CODE (exp);
  if (code == PLACEHOLDER_EXPR)
    return 1;

  switch (TREE_CODE_CLASS (code))
    {
    case tcc_reference:
      /* Don't look at any PLACEHOLDER_EXPRs that might be in index or bit
	 position computations since they will be converted into a
	 WITH_RECORD_EXPR involving the reference, which will assume
	 here will be valid.  */
      return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));

    case tcc_exceptional:
      if (code == TREE_LIST)
	return (CONTAINS_PLACEHOLDER_P (TREE_VALUE (exp))
		|| CONTAINS_PLACEHOLDER_P (TREE_CHAIN (exp)));
      break;

    case tcc_unary:
    case tcc_binary:
    case tcc_comparison:
    case tcc_expression:
      switch (code)
	{
	case COMPOUND_EXPR:
	  /* Ignoring the first operand isn't quite right, but works best.  */
	  return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));

	case COND_EXPR:
	  return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
		  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1))
		  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2)));

	case SAVE_EXPR:
	  /* The save_expr function never wraps anything containing
	     a PLACEHOLDER_EXPR. */
	  return 0;

	default:
	  break;
	}

      switch (TREE_CODE_LENGTH (code))
	{
	case 1:
	  return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
	case 2:
	  return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
		  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1)));
	default:
	  return 0;
	}

    case tcc_vl_exp:
      switch (code)
	{
	case CALL_EXPR:
	  {
	    const_tree arg;
	    const_call_expr_arg_iterator iter;
	    FOR_EACH_CONST_CALL_EXPR_ARG (arg, iter, exp)
	      if (CONTAINS_PLACEHOLDER_P (arg))
		return 1;
	    return 0;
	  }
	default:
	  return 0;
	}

    default:
      return 0;
    }
  return 0;
}

/* Return true if any part of the structure of TYPE involves a PLACEHOLDER_EXPR
   directly.  This includes size, bounds, qualifiers (for QUAL_UNION_TYPE) and
   field positions.  */

static bool
type_contains_placeholder_1 (const_tree type)
{
  /* If the size contains a placeholder or the parent type (component type in
     the case of arrays) type involves a placeholder, this type does.  */
  if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type))
      || CONTAINS_PLACEHOLDER_P (TYPE_SIZE_UNIT (type))
      || (!POINTER_TYPE_P (type)
	  && TREE_TYPE (type)
	  && type_contains_placeholder_p (TREE_TYPE (type))))
    return true;

  /* Now do type-specific checks.  Note that the last part of the check above
     greatly limits what we have to do below.  */
  switch (TREE_CODE (type))
    {
    case VOID_TYPE:
    case COMPLEX_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
    case POINTER_TYPE:
    case OFFSET_TYPE:
    case REFERENCE_TYPE:
    case METHOD_TYPE:
    case FUNCTION_TYPE:
    case VECTOR_TYPE:
    case NULLPTR_TYPE:
      return false;

    case INTEGER_TYPE:
    case REAL_TYPE:
    case FIXED_POINT_TYPE:
      /* Here we just check the bounds.  */
      return (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (type))
	      || CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (type)));

    case ARRAY_TYPE:
      /* We have already checked the component type above, so just check
	 the domain type.  Flexible array members have a null domain.  */
      return TYPE_DOMAIN (type) ?
	type_contains_placeholder_p (TYPE_DOMAIN (type)) : false;

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      {
	tree field;

	for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	  if (TREE_CODE (field) == FIELD_DECL
	      && (CONTAINS_PLACEHOLDER_P (DECL_FIELD_OFFSET (field))
		  || (TREE_CODE (type) == QUAL_UNION_TYPE
		      && CONTAINS_PLACEHOLDER_P (DECL_QUALIFIER (field)))
		  || type_contains_placeholder_p (TREE_TYPE (field))))
	    return true;

	return false;
      }

    default:
      gcc_unreachable ();
    }
}

/* Wrapper around above function used to cache its result.  */

bool
type_contains_placeholder_p (tree type)
{
  bool result;

  /* If the contains_placeholder_bits field has been initialized,
     then we know the answer.  */
  if (TYPE_CONTAINS_PLACEHOLDER_INTERNAL (type) > 0)
    return TYPE_CONTAINS_PLACEHOLDER_INTERNAL (type) - 1;

  /* Indicate that we've seen this type node, and the answer is false.
     This is what we want to return if we run into recursion via fields.  */
  TYPE_CONTAINS_PLACEHOLDER_INTERNAL (type) = 1;

  /* Compute the real value.  */
  result = type_contains_placeholder_1 (type);

  /* Store the real value.  */
  TYPE_CONTAINS_PLACEHOLDER_INTERNAL (type) = result + 1;

  return result;
}

/* Push tree EXP onto vector QUEUE if it is not already present.  */

static void
push_without_duplicates (tree exp, vec<tree> *queue)
{
  unsigned int i;
  tree iter;

  FOR_EACH_VEC_ELT (*queue, i, iter)
    if (simple_cst_equal (iter, exp) == 1)
      break;

  if (!iter)
    queue->safe_push (exp);
}

/* Given a tree EXP, find all occurrences of references to fields
   in a PLACEHOLDER_EXPR and place them in vector REFS without
   duplicates.  Also record VAR_DECLs and CONST_DECLs.  Note that
   we assume here that EXP contains only arithmetic expressions
   or CALL_EXPRs with PLACEHOLDER_EXPRs occurring only in their
   argument list.  */

void
find_placeholder_in_expr (tree exp, vec<tree> *refs)
{
  enum tree_code code = TREE_CODE (exp);
  tree inner;
  int i;

  /* We handle TREE_LIST and COMPONENT_REF separately.  */
  if (code == TREE_LIST)
    {
      FIND_PLACEHOLDER_IN_EXPR (TREE_CHAIN (exp), refs);
      FIND_PLACEHOLDER_IN_EXPR (TREE_VALUE (exp), refs);
    }
  else if (code == COMPONENT_REF)
    {
      for (inner = TREE_OPERAND (exp, 0);
	   REFERENCE_CLASS_P (inner);
	   inner = TREE_OPERAND (inner, 0))
	;

      if (TREE_CODE (inner) == PLACEHOLDER_EXPR)
	push_without_duplicates (exp, refs);
      else
	FIND_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), refs);
   }
  else
    switch (TREE_CODE_CLASS (code))
      {
      case tcc_constant:
	break;

      case tcc_declaration:
	/* Variables allocated to static storage can stay.  */
        if (!TREE_STATIC (exp))
	  push_without_duplicates (exp, refs);
	break;

      case tcc_expression:
	/* This is the pattern built in ada/make_aligning_type.  */
	if (code == ADDR_EXPR
	    && TREE_CODE (TREE_OPERAND (exp, 0)) == PLACEHOLDER_EXPR)
	  {
	    push_without_duplicates (exp, refs);
	    break;
	  }

        /* Fall through.  */

      case tcc_exceptional:
      case tcc_unary:
      case tcc_binary:
      case tcc_comparison:
      case tcc_reference:
	for (i = 0; i < TREE_CODE_LENGTH (code); i++)
	  FIND_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, i), refs);
	break;

      case tcc_vl_exp:
	for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
	  FIND_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, i), refs);
	break;

      default:
	gcc_unreachable ();
      }
}

/* Given a tree EXP, a FIELD_DECL F, and a replacement value R,
   return a tree with all occurrences of references to F in a
   PLACEHOLDER_EXPR replaced by R.  Also handle VAR_DECLs and
   CONST_DECLs.  Note that we assume here that EXP contains only
   arithmetic expressions or CALL_EXPRs with PLACEHOLDER_EXPRs
   occurring only in their argument list.  */

tree
substitute_in_expr (tree exp, tree f, tree r)
{
  enum tree_code code = TREE_CODE (exp);
  tree op0, op1, op2, op3;
  tree new_tree;

  /* We handle TREE_LIST and COMPONENT_REF separately.  */
  if (code == TREE_LIST)
    {
      op0 = SUBSTITUTE_IN_EXPR (TREE_CHAIN (exp), f, r);
      op1 = SUBSTITUTE_IN_EXPR (TREE_VALUE (exp), f, r);
      if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
	return exp;

      return tree_cons (TREE_PURPOSE (exp), op1, op0);
    }
  else if (code == COMPONENT_REF)
    {
      tree inner;

      /* If this expression is getting a value from a PLACEHOLDER_EXPR
	 and it is the right field, replace it with R.  */
      for (inner = TREE_OPERAND (exp, 0);
	   REFERENCE_CLASS_P (inner);
	   inner = TREE_OPERAND (inner, 0))
	;

      /* The field.  */
      op1 = TREE_OPERAND (exp, 1);

      if (TREE_CODE (inner) == PLACEHOLDER_EXPR && op1 == f)
	return r;

      /* If this expression hasn't been completed let, leave it alone.  */
      if (TREE_CODE (inner) == PLACEHOLDER_EXPR && !TREE_TYPE (inner))
	return exp;

      op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
      if (op0 == TREE_OPERAND (exp, 0))
	return exp;

      new_tree
	= fold_build3 (COMPONENT_REF, TREE_TYPE (exp), op0, op1, NULL_TREE);
   }
  else
    switch (TREE_CODE_CLASS (code))
      {
      case tcc_constant:
	return exp;

      case tcc_declaration:
	if (exp == f)
	  return r;
	else
	  return exp;

      case tcc_expression:
	if (exp == f)
	  return r;

        /* Fall through.  */

      case tcc_exceptional:
      case tcc_unary:
      case tcc_binary:
      case tcc_comparison:
      case tcc_reference:
	switch (TREE_CODE_LENGTH (code))
	  {
	  case 0:
	    return exp;

	  case 1:
	    op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
	    if (op0 == TREE_OPERAND (exp, 0))
	      return exp;

	    new_tree = fold_build1 (code, TREE_TYPE (exp), op0);
	    break;

	  case 2:
	    op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
	    op1 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 1), f, r);

	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
	      return exp;

	    new_tree = fold_build2 (code, TREE_TYPE (exp), op0, op1);
	    break;

	  case 3:
	    op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
	    op1 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 1), f, r);
	    op2 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 2), f, r);

	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
		&& op2 == TREE_OPERAND (exp, 2))
	      return exp;

	    new_tree = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
	    break;

	  case 4:
	    op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
	    op1 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 1), f, r);
	    op2 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 2), f, r);
	    op3 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 3), f, r);

	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
		&& op2 == TREE_OPERAND (exp, 2)
		&& op3 == TREE_OPERAND (exp, 3))
	      return exp;

	    new_tree
	      = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
	    break;

	  default:
	    gcc_unreachable ();
	  }
	break;

      case tcc_vl_exp:
	{
	  int i;

	  new_tree = NULL_TREE;

	  /* If we are trying to replace F with a constant or with another
	     instance of one of the arguments of the call, inline back
	     functions which do nothing else than computing a value from
	     the arguments they are passed.  This makes it possible to
	     fold partially or entirely the replacement expression.  */
	  if (code == CALL_EXPR)
	    {
	      bool maybe_inline = false;
	      if (CONSTANT_CLASS_P (r))
		maybe_inline = true;
	      else
		for (i = 3; i < TREE_OPERAND_LENGTH (exp); i++)
		  if (operand_equal_p (TREE_OPERAND (exp, i), r, 0))
		    {
		      maybe_inline = true;
		      break;
		    }
	      if (maybe_inline)
		{
		  tree t = maybe_inline_call_in_expr (exp);
		  if (t)
		    return SUBSTITUTE_IN_EXPR (t, f, r);
		}
	    }

	  for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
	    {
	      tree op = TREE_OPERAND (exp, i);
	      tree new_op = SUBSTITUTE_IN_EXPR (op, f, r);
	      if (new_op != op)
		{
		  if (!new_tree)
		    new_tree = copy_node (exp);
		  TREE_OPERAND (new_tree, i) = new_op;
		}
	    }

	  if (new_tree)
	    {
	      new_tree = fold (new_tree);
	      if (TREE_CODE (new_tree) == CALL_EXPR)
		process_call_operands (new_tree);
	    }
	  else
	    return exp;
	}
	break;

      default:
	gcc_unreachable ();
      }

  TREE_READONLY (new_tree) |= TREE_READONLY (exp);

  if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
    TREE_THIS_NOTRAP (new_tree) |= TREE_THIS_NOTRAP (exp);

  return new_tree;
}

/* Similar, but look for a PLACEHOLDER_EXPR in EXP and find a replacement
   for it within OBJ, a tree that is an object or a chain of references.  */

tree
substitute_placeholder_in_expr (tree exp, tree obj)
{
  enum tree_code code = TREE_CODE (exp);
  tree op0, op1, op2, op3;
  tree new_tree;

  /* If this is a PLACEHOLDER_EXPR, see if we find a corresponding type
     in the chain of OBJ.  */
  if (code == PLACEHOLDER_EXPR)
    {
      tree need_type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
      tree elt;

      for (elt = obj; elt != 0;
	   elt = ((TREE_CODE (elt) == COMPOUND_EXPR
		   || TREE_CODE (elt) == COND_EXPR)
		  ? TREE_OPERAND (elt, 1)
		  : (REFERENCE_CLASS_P (elt)
		     || UNARY_CLASS_P (elt)
		     || BINARY_CLASS_P (elt)
		     || VL_EXP_CLASS_P (elt)
		     || EXPRESSION_CLASS_P (elt))
		  ? TREE_OPERAND (elt, 0) : 0))
	if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
	  return elt;

      for (elt = obj; elt != 0;
	   elt = ((TREE_CODE (elt) == COMPOUND_EXPR
		   || TREE_CODE (elt) == COND_EXPR)
		  ? TREE_OPERAND (elt, 1)
		  : (REFERENCE_CLASS_P (elt)
		     || UNARY_CLASS_P (elt)
		     || BINARY_CLASS_P (elt)
		     || VL_EXP_CLASS_P (elt)
		     || EXPRESSION_CLASS_P (elt))
		  ? TREE_OPERAND (elt, 0) : 0))
	if (POINTER_TYPE_P (TREE_TYPE (elt))
	    && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
		== need_type))
	  return fold_build1 (INDIRECT_REF, need_type, elt);

      /* If we didn't find it, return the original PLACEHOLDER_EXPR.  If it
	 survives until RTL generation, there will be an error.  */
      return exp;
    }

  /* TREE_LIST is special because we need to look at TREE_VALUE
     and TREE_CHAIN, not TREE_OPERANDS.  */
  else if (code == TREE_LIST)
    {
      op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_CHAIN (exp), obj);
      op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_VALUE (exp), obj);
      if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
	return exp;

      return tree_cons (TREE_PURPOSE (exp), op1, op0);
    }
  else
    switch (TREE_CODE_CLASS (code))
      {
      case tcc_constant:
      case tcc_declaration:
	return exp;

      case tcc_exceptional:
      case tcc_unary:
      case tcc_binary:
      case tcc_comparison:
      case tcc_expression:
      case tcc_reference:
      case tcc_statement:
	switch (TREE_CODE_LENGTH (code))
	  {
	  case 0:
	    return exp;

	  case 1:
	    op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
	    if (op0 == TREE_OPERAND (exp, 0))
	      return exp;

	    new_tree = fold_build1 (code, TREE_TYPE (exp), op0);
	    break;

	  case 2:
	    op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
	    op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 1), obj);

	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
	      return exp;

	    new_tree = fold_build2 (code, TREE_TYPE (exp), op0, op1);
	    break;

	  case 3:
	    op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
	    op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 1), obj);
	    op2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 2), obj);

	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
		&& op2 == TREE_OPERAND (exp, 2))
	      return exp;

	    new_tree = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
	    break;

	  case 4:
	    op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
	    op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 1), obj);
	    op2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 2), obj);
	    op3 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 3), obj);

	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
		&& op2 == TREE_OPERAND (exp, 2)
		&& op3 == TREE_OPERAND (exp, 3))
	      return exp;

	    new_tree
	      = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
	    break;

	  default:
	    gcc_unreachable ();
	  }
	break;

      case tcc_vl_exp:
	{
	  int i;

	  new_tree = NULL_TREE;

	  for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
	    {
	      tree op = TREE_OPERAND (exp, i);
	      tree new_op = SUBSTITUTE_PLACEHOLDER_IN_EXPR (op, obj);
	      if (new_op != op)
		{
		  if (!new_tree)
		    new_tree = copy_node (exp);
		  TREE_OPERAND (new_tree, i) = new_op;
		}
	    }

	  if (new_tree)
	    {
	      new_tree = fold (new_tree);
	      if (TREE_CODE (new_tree) == CALL_EXPR)
		process_call_operands (new_tree);
	    }
	  else
	    return exp;
	}
	break;

      default:
	gcc_unreachable ();
      }

  TREE_READONLY (new_tree) |= TREE_READONLY (exp);

  if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
    TREE_THIS_NOTRAP (new_tree) |= TREE_THIS_NOTRAP (exp);

  return new_tree;
}


/* Subroutine of stabilize_reference; this is called for subtrees of
   references.  Any expression with side-effects must be put in a SAVE_EXPR
   to ensure that it is only evaluated once.

   We don't put SAVE_EXPR nodes around everything, because assigning very
   simple expressions to temporaries causes us to miss good opportunities
   for optimizations.  Among other things, the opportunity to fold in the
   addition of a constant into an addressing mode often gets lost, e.g.
   "y[i+1] += x;".  In general, we take the approach that we should not make
   an assignment unless we are forced into it - i.e., that any non-side effect
   operator should be allowed, and that cse should take care of coalescing
   multiple utterances of the same expression should that prove fruitful.  */

static tree
stabilize_reference_1 (tree e)
{
  tree result;
  enum tree_code code = TREE_CODE (e);

  /* We cannot ignore const expressions because it might be a reference
     to a const array but whose index contains side-effects.  But we can
     ignore things that are actual constant or that already have been
     handled by this function.  */

  if (tree_invariant_p (e))
    return e;

  switch (TREE_CODE_CLASS (code))
    {
    case tcc_exceptional:
      /* Always wrap STATEMENT_LIST into SAVE_EXPR, even if it doesn't
	 have side-effects.  */
      if (code == STATEMENT_LIST)
	return save_expr (e);
      /* FALLTHRU */
    case tcc_type:
    case tcc_declaration:
    case tcc_comparison:
    case tcc_statement:
    case tcc_expression:
    case tcc_reference:
    case tcc_vl_exp:
      /* If the expression has side-effects, then encase it in a SAVE_EXPR
	 so that it will only be evaluated once.  */
      /* The reference (r) and comparison (<) classes could be handled as
	 below, but it is generally faster to only evaluate them once.  */
      if (TREE_SIDE_EFFECTS (e))
	return save_expr (e);
      return e;

    case tcc_constant:
      /* Constants need no processing.  In fact, we should never reach
	 here.  */
      return e;

    case tcc_binary:
      /* Division is slow and tends to be compiled with jumps,
	 especially the division by powers of 2 that is often
	 found inside of an array reference.  So do it just once.  */
      if (code == TRUNC_DIV_EXPR || code == TRUNC_MOD_EXPR
	  || code == FLOOR_DIV_EXPR || code == FLOOR_MOD_EXPR
	  || code == CEIL_DIV_EXPR || code == CEIL_MOD_EXPR
	  || code == ROUND_DIV_EXPR || code == ROUND_MOD_EXPR)
	return save_expr (e);
      /* Recursively stabilize each operand.  */
      result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)),
			 stabilize_reference_1 (TREE_OPERAND (e, 1)));
      break;

    case tcc_unary:
      /* Recursively stabilize each operand.  */
      result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)));
      break;

    default:
      gcc_unreachable ();
    }

  TREE_TYPE (result) = TREE_TYPE (e);
  TREE_READONLY (result) = TREE_READONLY (e);
  TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
  TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);

  return result;
}

/* Stabilize a reference so that we can use it any number of times
   without causing its operands to be evaluated more than once.
   Returns the stabilized reference.  This works by means of save_expr,
   so see the caveats in the comments about save_expr.

   Also allows conversion expressions whose operands are references.
   Any other kind of expression is returned unchanged.  */

tree
stabilize_reference (tree ref)
{
  tree result;
  enum tree_code code = TREE_CODE (ref);

  switch (code)
    {
    case VAR_DECL:
    case PARM_DECL:
    case RESULT_DECL:
      /* No action is needed in this case.  */
      return ref;

    CASE_CONVERT:
    case FLOAT_EXPR:
    case FIX_TRUNC_EXPR:
      result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
      break;

    case INDIRECT_REF:
      result = build_nt (INDIRECT_REF,
			 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
      break;

    case COMPONENT_REF:
      result = build_nt (COMPONENT_REF,
			 stabilize_reference (TREE_OPERAND (ref, 0)),
			 TREE_OPERAND (ref, 1), NULL_TREE);
      break;

    case BIT_FIELD_REF:
      result = build_nt (BIT_FIELD_REF,
			 stabilize_reference (TREE_OPERAND (ref, 0)),
			 TREE_OPERAND (ref, 1), TREE_OPERAND (ref, 2));
      REF_REVERSE_STORAGE_ORDER (result) = REF_REVERSE_STORAGE_ORDER (ref);
      break;

    case ARRAY_REF:
      result = build_nt (ARRAY_REF,
			 stabilize_reference (TREE_OPERAND (ref, 0)),
			 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
			 TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
      break;

    case ARRAY_RANGE_REF:
      result = build_nt (ARRAY_RANGE_REF,
			 stabilize_reference (TREE_OPERAND (ref, 0)),
			 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
			 TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
      break;

    case COMPOUND_EXPR:
      /* We cannot wrap the first expression in a SAVE_EXPR, as then
	 it wouldn't be ignored.  This matters when dealing with
	 volatiles.  */
      return stabilize_reference_1 (ref);

      /* If arg isn't a kind of lvalue we recognize, make no change.
	 Caller should recognize the error for an invalid lvalue.  */
    default:
      return ref;

    case ERROR_MARK:
      return error_mark_node;
    }

  TREE_TYPE (result) = TREE_TYPE (ref);
  TREE_READONLY (result) = TREE_READONLY (ref);
  TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
  TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);

  return result;
}

/* Low-level constructors for expressions.  */

/* A helper function for build1 and constant folders.  Set TREE_CONSTANT,
   and TREE_SIDE_EFFECTS for an ADDR_EXPR.  */

void
recompute_tree_invariant_for_addr_expr (tree t)
{
  tree node;
  bool tc = true, se = false;

  gcc_assert (TREE_CODE (t) == ADDR_EXPR);

  /* We started out assuming this address is both invariant and constant, but
     does not have side effects.  Now go down any handled components and see if
     any of them involve offsets that are either non-constant or non-invariant.
     Also check for side-effects.

     ??? Note that this code makes no attempt to deal with the case where
     taking the address of something causes a copy due to misalignment.  */

#define UPDATE_FLAGS(NODE)  \
do { tree _node = (NODE); \
     if (_node && !TREE_CONSTANT (_node)) tc = false; \
     if (_node && TREE_SIDE_EFFECTS (_node)) se = true; } while (0)

  for (node = TREE_OPERAND (t, 0); handled_component_p (node);
       node = TREE_OPERAND (node, 0))
    {
      /* If the first operand doesn't have an ARRAY_TYPE, this is a bogus
	 array reference (probably made temporarily by the G++ front end),
	 so ignore all the operands.  */
      if ((TREE_CODE (node) == ARRAY_REF
	   || TREE_CODE (node) == ARRAY_RANGE_REF)
	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (node, 0))) == ARRAY_TYPE)
	{
	  UPDATE_FLAGS (TREE_OPERAND (node, 1));
	  if (TREE_OPERAND (node, 2))
	    UPDATE_FLAGS (TREE_OPERAND (node, 2));
	  if (TREE_OPERAND (node, 3))
	    UPDATE_FLAGS (TREE_OPERAND (node, 3));
	}
      /* Likewise, just because this is a COMPONENT_REF doesn't mean we have a
	 FIELD_DECL, apparently.  The G++ front end can put something else
	 there, at least temporarily.  */
      else if (TREE_CODE (node) == COMPONENT_REF
	       && TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL)
	{
	  if (TREE_OPERAND (node, 2))
	    UPDATE_FLAGS (TREE_OPERAND (node, 2));
	}
    }

  node = lang_hooks.expr_to_decl (node, &tc, &se);

  /* Now see what's inside.  If it's an INDIRECT_REF, copy our properties from
     the address, since &(*a)->b is a form of addition.  If it's a constant, the
     address is constant too.  If it's a decl, its address is constant if the
     decl is static.  Everything else is not constant and, furthermore,
     taking the address of a volatile variable is not volatile.  */
  if (TREE_CODE (node) == INDIRECT_REF
      || TREE_CODE (node) == MEM_REF)
    UPDATE_FLAGS (TREE_OPERAND (node, 0));
  else if (CONSTANT_CLASS_P (node))
    ;
  else if (DECL_P (node))
    tc &= (staticp (node) != NULL_TREE);
  else
    {
      tc = false;
      se |= TREE_SIDE_EFFECTS (node);
    }


  TREE_CONSTANT (t) = tc;
  TREE_SIDE_EFFECTS (t) = se;
#undef UPDATE_FLAGS
}

/* Build an expression of code CODE, data type TYPE, and operands as
   specified.  Expressions and reference nodes can be created this way.
   Constants, decls, types and misc nodes cannot be.

   We define 5 non-variadic functions, from 0 to 4 arguments.  This is
   enough for all extant tree codes.  */

tree
build0 (enum tree_code code, tree tt MEM_STAT_DECL)
{
  tree t;

  gcc_assert (TREE_CODE_LENGTH (code) == 0);

  t = make_node (code PASS_MEM_STAT);
  TREE_TYPE (t) = tt;

  return t;
}

tree
build1 (enum tree_code code, tree type, tree node MEM_STAT_DECL)
{
  int length = sizeof (struct tree_exp);
  tree t;

  record_node_allocation_statistics (code, length);

  gcc_assert (TREE_CODE_LENGTH (code) == 1);

  t = ggc_alloc_tree_node_stat (length PASS_MEM_STAT);

  memset (t, 0, sizeof (struct tree_common));

  TREE_SET_CODE (t, code);

  TREE_TYPE (t) = type;
  SET_EXPR_LOCATION (t, UNKNOWN_LOCATION);
  TREE_OPERAND (t, 0) = node;
  if (node && !TYPE_P (node))
    {
      TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
      TREE_READONLY (t) = TREE_READONLY (node);
    }

  if (TREE_CODE_CLASS (code) == tcc_statement)
    {
      if (code != DEBUG_BEGIN_STMT)
	TREE_SIDE_EFFECTS (t) = 1;
    }
  else switch (code)
    {
    case VA_ARG_EXPR:
      /* All of these have side-effects, no matter what their
	 operands are.  */
      TREE_SIDE_EFFECTS (t) = 1;
      TREE_READONLY (t) = 0;
      break;

    case INDIRECT_REF:
      /* Whether a dereference is readonly has nothing to do with whether
	 its operand is readonly.  */
      TREE_READONLY (t) = 0;
      break;

    case ADDR_EXPR:
      if (node)
	recompute_tree_invariant_for_addr_expr (t);
      break;

    default:
      if ((TREE_CODE_CLASS (code) == tcc_unary || code == VIEW_CONVERT_EXPR)
	  && node && !TYPE_P (node)
	  && TREE_CONSTANT (node))
	TREE_CONSTANT (t) = 1;
      if (TREE_CODE_CLASS (code) == tcc_reference
	  && node && TREE_THIS_VOLATILE (node))
	TREE_THIS_VOLATILE (t) = 1;
      break;
    }

  return t;
}

#define PROCESS_ARG(N)				\
  do {						\
    TREE_OPERAND (t, N) = arg##N;		\
    if (arg##N &&!TYPE_P (arg##N))		\
      {						\
        if (TREE_SIDE_EFFECTS (arg##N))		\
	  side_effects = 1;			\
        if (!TREE_READONLY (arg##N)		\
	    && !CONSTANT_CLASS_P (arg##N))	\
	  (void) (read_only = 0);		\
        if (!TREE_CONSTANT (arg##N))		\
	  (void) (constant = 0);		\
      }						\
  } while (0)

tree
build2 (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
{
  bool constant, read_only, side_effects, div_by_zero;
  tree t;

  gcc_assert (TREE_CODE_LENGTH (code) == 2);

  if ((code == MINUS_EXPR || code == PLUS_EXPR || code == MULT_EXPR)
      && arg0 && arg1 && tt && POINTER_TYPE_P (tt)
      /* When sizetype precision doesn't match that of pointers
         we need to be able to build explicit extensions or truncations
	 of the offset argument.  */
      && TYPE_PRECISION (sizetype) == TYPE_PRECISION (tt))
    gcc_assert (TREE_CODE (arg0) == INTEGER_CST
		&& TREE_CODE (arg1) == INTEGER_CST);

  if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt)
    gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0))
		&& ptrofftype_p (TREE_TYPE (arg1)));

  t = make_node (code PASS_MEM_STAT);
  TREE_TYPE (t) = tt;

  /* Below, we automatically set TREE_SIDE_EFFECTS and TREE_READONLY for the
     result based on those same flags for the arguments.  But if the
     arguments aren't really even `tree' expressions, we shouldn't be trying
     to do this.  */

  /* Expressions without side effects may be constant if their
     arguments are as well.  */
  constant = (TREE_CODE_CLASS (code) == tcc_comparison
	      || TREE_CODE_CLASS (code) == tcc_binary);
  read_only = 1;
  side_effects = TREE_SIDE_EFFECTS (t);

  switch (code)
    {
    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case EXACT_DIV_EXPR:
    case CEIL_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case TRUNC_MOD_EXPR:
      div_by_zero = integer_zerop (arg1);
      break;
    default:
      div_by_zero = false;
    }

  PROCESS_ARG (0);
  PROCESS_ARG (1);

  TREE_SIDE_EFFECTS (t) = side_effects;
  if (code == MEM_REF)
    {
      if (arg0 && TREE_CODE (arg0) == ADDR_EXPR)
	{
	  tree o = TREE_OPERAND (arg0, 0);
	  TREE_READONLY (t) = TREE_READONLY (o);
	  TREE_THIS_VOLATILE (t) = TREE_THIS_VOLATILE (o);
	}
    }
  else
    {
      TREE_READONLY (t) = read_only;
      /* Don't mark X / 0 as constant.  */
      TREE_CONSTANT (t) = constant && !div_by_zero;
      TREE_THIS_VOLATILE (t)
	= (TREE_CODE_CLASS (code) == tcc_reference
	   && arg0 && TREE_THIS_VOLATILE (arg0));
    }

  return t;
}


tree
build3 (enum tree_code code, tree tt, tree arg0, tree arg1,
	tree arg2 MEM_STAT_DECL)
{
  bool constant, read_only, side_effects;
  tree t;

  gcc_assert (TREE_CODE_LENGTH (code) == 3);
  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);

  t = make_node (code PASS_MEM_STAT);
  TREE_TYPE (t) = tt;

  read_only = 1;

  /* As a special exception, if COND_EXPR has NULL branches, we
     assume that it is a gimple statement and always consider
     it to have side effects.  */
  if (code == COND_EXPR
      && tt == void_type_node
      && arg1 == NULL_TREE
      && arg2 == NULL_TREE)
    side_effects = true;
  else
    side_effects = TREE_SIDE_EFFECTS (t);

  PROCESS_ARG (0);
  PROCESS_ARG (1);
  PROCESS_ARG (2);

  if (code == COND_EXPR)
    TREE_READONLY (t) = read_only;

  TREE_SIDE_EFFECTS (t) = side_effects;
  TREE_THIS_VOLATILE (t)
    = (TREE_CODE_CLASS (code) == tcc_reference
       && arg0 && TREE_THIS_VOLATILE (arg0));

  return t;
}

tree
build4 (enum tree_code code, tree tt, tree arg0, tree arg1,
	tree arg2, tree arg3 MEM_STAT_DECL)
{
  bool constant, read_only, side_effects;
  tree t;

  gcc_assert (TREE_CODE_LENGTH (code) == 4);

  t = make_node (code PASS_MEM_STAT);
  TREE_TYPE (t) = tt;

  side_effects = TREE_SIDE_EFFECTS (t);

  PROCESS_ARG (0);
  PROCESS_ARG (1);
  PROCESS_ARG (2);
  PROCESS_ARG (3);

  TREE_SIDE_EFFECTS (t) = side_effects;
  TREE_THIS_VOLATILE (t)
    = (TREE_CODE_CLASS (code) == tcc_reference
       && arg0 && TREE_THIS_VOLATILE (arg0));

  return t;
}

tree
build5 (enum tree_code code, tree tt, tree arg0, tree arg1,
	tree arg2, tree arg3, tree arg4 MEM_STAT_DECL)
{
  bool constant, read_only, side_effects;
  tree t;

  gcc_assert (TREE_CODE_LENGTH (code) == 5);

  t = make_node (code PASS_MEM_STAT);
  TREE_TYPE (t) = tt;

  side_effects = TREE_SIDE_EFFECTS (t);

  PROCESS_ARG (0);
  PROCESS_ARG (1);
  PROCESS_ARG (2);
  PROCESS_ARG (3);
  PROCESS_ARG (4);

  TREE_SIDE_EFFECTS (t) = side_effects;
  if (code == TARGET_MEM_REF)
    {
      if (arg0 && TREE_CODE (arg0) == ADDR_EXPR)
	{
	  tree o = TREE_OPERAND (arg0, 0);
	  TREE_READONLY (t) = TREE_READONLY (o);
	  TREE_THIS_VOLATILE (t) = TREE_THIS_VOLATILE (o);
	}
    }
  else
    TREE_THIS_VOLATILE (t)
      = (TREE_CODE_CLASS (code) == tcc_reference
	 && arg0 && TREE_THIS_VOLATILE (arg0));

  return t;
}

/* Build a simple MEM_REF tree with the sematics of a plain INDIRECT_REF
   on the pointer PTR.  */

tree
build_simple_mem_ref_loc (location_t loc, tree ptr)
{
  poly_int64 offset = 0;
  tree ptype = TREE_TYPE (ptr);
  tree tem;
  /* For convenience allow addresses that collapse to a simple base
     and offset.  */
  if (TREE_CODE (ptr) == ADDR_EXPR
      && (handled_component_p (TREE_OPERAND (ptr, 0))
	  || TREE_CODE (TREE_OPERAND (ptr, 0)) == MEM_REF))
    {
      ptr = get_addr_base_and_unit_offset (TREE_OPERAND (ptr, 0), &offset);
      gcc_assert (ptr);
      if (TREE_CODE (ptr) == MEM_REF)
	{
	  offset += mem_ref_offset (ptr).force_shwi ();
	  ptr = TREE_OPERAND (ptr, 0);
	}
      else
	ptr = build_fold_addr_expr (ptr);
      gcc_assert (is_gimple_reg (ptr) || is_gimple_min_invariant (ptr));
    }
  tem = build2 (MEM_REF, TREE_TYPE (ptype),
		ptr, build_int_cst (ptype, offset));
  SET_EXPR_LOCATION (tem, loc);
  return tem;
}

/* Return the constant offset of a MEM_REF or TARGET_MEM_REF tree T.  */

poly_offset_int
mem_ref_offset (const_tree t)
{
  return poly_offset_int::from (wi::to_poly_wide (TREE_OPERAND (t, 1)),
				SIGNED);
}

/* Return an invariant ADDR_EXPR of type TYPE taking the address of BASE
   offsetted by OFFSET units.  */

tree
build_invariant_address (tree type, tree base, poly_int64 offset)
{
  tree ref = fold_build2 (MEM_REF, TREE_TYPE (type),
			  build_fold_addr_expr (base),
			  build_int_cst (ptr_type_node, offset));
  tree addr = build1 (ADDR_EXPR, type, ref);
  recompute_tree_invariant_for_addr_expr (addr);
  return addr;
}

/* Similar except don't specify the TREE_TYPE
   and leave the TREE_SIDE_EFFECTS as 0.
   It is permissible for arguments to be null,
   or even garbage if their values do not matter.  */

tree
build_nt (enum tree_code code, ...)
{
  tree t;
  int length;
  int i;
  va_list p;

  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);

  va_start (p, code);

  t = make_node (code);
  length = TREE_CODE_LENGTH (code);

  for (i = 0; i < length; i++)
    TREE_OPERAND (t, i) = va_arg (p, tree);

  va_end (p);
  return t;
}

/* Similar to build_nt, but for creating a CALL_EXPR object with a
   tree vec.  */

tree
build_nt_call_vec (tree fn, vec<tree, va_gc> *args)
{
  tree ret, t;
  unsigned int ix;

  ret = build_vl_exp (CALL_EXPR, vec_safe_length (args) + 3);
  CALL_EXPR_FN (ret) = fn;
  CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE;
  FOR_EACH_VEC_SAFE_ELT (args, ix, t)
    CALL_EXPR_ARG (ret, ix) = t;
  return ret;
}

/* Create a DECL_... node of code CODE, name NAME  (if non-null)
   and data type TYPE.
   We do NOT enter this node in any sort of symbol table.

   LOC is the location of the decl.

   layout_decl is used to set up the decl's storage layout.
   Other slots are initialized to 0 or null pointers.  */

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

  t = make_node (code PASS_MEM_STAT);
  DECL_SOURCE_LOCATION (t) = loc;

/*  if (type == error_mark_node)
    type = integer_type_node; */
/* That is not done, deliberately, so that having error_mark_node
   as the type can suppress useless errors in the use of this variable.  */

  DECL_NAME (t) = name;
  TREE_TYPE (t) = type;

  if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
    layout_decl (t, 0);

  return t;
}

/* Builds and returns function declaration with NAME and TYPE.  */

tree
build_fn_decl (const char *name, tree type)
{
  tree id = get_identifier (name);
  tree decl = build_decl (input_location, FUNCTION_DECL, id, type);

  DECL_EXTERNAL (decl) = 1;
  TREE_PUBLIC (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  TREE_NOTHROW (decl) = 1;

  return decl;
}

vec<tree, va_gc> *all_translation_units;

/* Builds a new translation-unit decl with name NAME, queues it in the
   global list of translation-unit decls and returns it.   */

tree
build_translation_unit_decl (tree name)
{
  tree tu = build_decl (UNKNOWN_LOCATION, TRANSLATION_UNIT_DECL,
			name, NULL_TREE);
  TRANSLATION_UNIT_LANGUAGE (tu) = lang_hooks.name;
  vec_safe_push (all_translation_units, tu);
  return tu;
}


/* BLOCK nodes are used to represent the structure of binding contours
   and declarations, once those contours have been exited and their contents
   compiled.  This information is used for outputting debugging info.  */

tree
build_block (tree vars, tree subblocks, tree supercontext, tree chain)
{
  tree block = make_node (BLOCK);

  BLOCK_VARS (block) = vars;
  BLOCK_SUBBLOCKS (block) = subblocks;
  BLOCK_SUPERCONTEXT (block) = supercontext;
  BLOCK_CHAIN (block) = chain;
  return block;
}


/* Like SET_EXPR_LOCATION, but make sure the tree can have a location.

   LOC is the location to use in tree T.  */

void
protected_set_expr_location (tree t, location_t loc)
{
  if (CAN_HAVE_LOCATION_P (t))
    SET_EXPR_LOCATION (t, loc);
}

/* Data used when collecting DECLs and TYPEs for language data removal.  */

struct free_lang_data_d
{
  free_lang_data_d () : decls (100), types (100) {}

  /* Worklist to avoid excessive recursion.  */
  auto_vec<tree> worklist;

  /* Set of traversed objects.  Used to avoid duplicate visits.  */
  hash_set<tree> pset;

  /* Array of symbols to process with free_lang_data_in_decl.  */
  auto_vec<tree> decls;

  /* Array of types to process with free_lang_data_in_type.  */
  auto_vec<tree> types;
};


/* Add type or decl T to one of the list of tree nodes that need their
   language data removed.  The lists are held inside FLD.  */

static void
add_tree_to_fld_list (tree t, struct free_lang_data_d *fld)
{
  if (DECL_P (t))
    fld->decls.safe_push (t);
  else if (TYPE_P (t))
    fld->types.safe_push (t);
  else
    gcc_unreachable ();
}

/* Push tree node T into FLD->WORKLIST.  */

static inline void
fld_worklist_push (tree t, struct free_lang_data_d *fld)
{
  if (t && !is_lang_specific (t) && !fld->pset.contains (t))
    fld->worklist.safe_push ((t));
}



/* Return simplified TYPE_NAME of TYPE.  */

static tree
fld_simplified_type_name (tree type)
{
  if (!TYPE_NAME (type) || TREE_CODE (TYPE_NAME (type)) != TYPE_DECL)
    return TYPE_NAME (type);
  /* Drop TYPE_DECLs in TYPE_NAME in favor of the identifier in the
     TYPE_DECL if the type doesn't have linkage.
     this must match fld_  */
  if (type != TYPE_MAIN_VARIANT (type) || ! type_with_linkage_p (type))
    return DECL_NAME (TYPE_NAME (type));
  return TYPE_NAME (type);
}

/* Do same comparsion as check_qualified_type skipping lang part of type
   and be more permissive about type names: we only care that names are
   same (for diagnostics) and that ODR names are the same.
   If INNER_TYPE is non-NULL, be sure that TREE_TYPE match it.  */

static bool
fld_type_variant_equal_p (tree t, tree v, tree inner_type)
{
  if (TYPE_QUALS (t) != TYPE_QUALS (v)
      /* We want to match incomplete variants with complete types.
	 In this case we need to ignore alignment.   */
      || ((!RECORD_OR_UNION_TYPE_P (t) || COMPLETE_TYPE_P (v))
	  && (TYPE_ALIGN (t) != TYPE_ALIGN (v)
	      || TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (v)))
      || fld_simplified_type_name (t) != fld_simplified_type_name (v)
      || !attribute_list_equal (TYPE_ATTRIBUTES (t),
			        TYPE_ATTRIBUTES (v))
      || (inner_type && TREE_TYPE (v) != inner_type))
    return false;

  return true;
}

/* Find variant of FIRST that match T and create new one if necessary.
   Set TREE_TYPE to INNER_TYPE if non-NULL.  */

static tree
fld_type_variant (tree first, tree t, struct free_lang_data_d *fld,
		  tree inner_type = NULL)
{
  if (first == TYPE_MAIN_VARIANT (t))
    return t;
  for (tree v = first; v; v = TYPE_NEXT_VARIANT (v))
    if (fld_type_variant_equal_p (t, v, inner_type))
      return v;
  tree v = build_variant_type_copy (first);
  TYPE_READONLY (v) = TYPE_READONLY (t);
  TYPE_VOLATILE (v) = TYPE_VOLATILE (t);
  TYPE_ATOMIC (v) = TYPE_ATOMIC (t);
  TYPE_RESTRICT (v) = TYPE_RESTRICT (t);
  TYPE_ADDR_SPACE (v) = TYPE_ADDR_SPACE (t);
  TYPE_NAME (v) = TYPE_NAME (t);
  TYPE_ATTRIBUTES (v) = TYPE_ATTRIBUTES (t);
  TYPE_CANONICAL (v) = TYPE_CANONICAL (t);
  /* Variants of incomplete types should have alignment 
     set to BITS_PER_UNIT.  Do not copy the actual alignment.  */
  if (!RECORD_OR_UNION_TYPE_P (v) || COMPLETE_TYPE_P (v))
    {
      SET_TYPE_ALIGN (v, TYPE_ALIGN (t));
      TYPE_USER_ALIGN (v) = TYPE_USER_ALIGN (t);
    }
  if (inner_type)
    TREE_TYPE (v) = inner_type;
  gcc_checking_assert (fld_type_variant_equal_p (t,v, inner_type));
  add_tree_to_fld_list (v, fld);
  return v;
}

/* Map complete types to incomplete types.  */

static hash_map<tree, tree> *fld_incomplete_types;

/* Map types to simplified types.  */

static hash_map<tree, tree> *fld_simplified_types;

/* Produce variant of T whose TREE_TYPE is T2. If it is main variant,
   use MAP to prevent duplicates.  */

static tree
fld_process_array_type (tree t, tree t2, hash_map<tree, tree> *map,
			struct free_lang_data_d *fld)
{
  if (TREE_TYPE (t) == t2)
    return t;

  if (TYPE_MAIN_VARIANT (t) != t)
    {
      return fld_type_variant
	       (fld_process_array_type (TYPE_MAIN_VARIANT (t),
					TYPE_MAIN_VARIANT (t2), map, fld),
		t, fld, t2);
    }

  bool existed;
  tree &array
     = map->get_or_insert (t, &existed);
  if (!existed)
    {
      array = build_array_type_1 (t2, TYPE_DOMAIN (t),
				  TYPE_TYPELESS_STORAGE (t), false);
      TYPE_CANONICAL (array) = TYPE_CANONICAL (t);
      add_tree_to_fld_list (array, fld);
    }
  return array;
}

/* Return CTX after removal of contexts that are not relevant  */

static tree
fld_decl_context (tree ctx)
{
  /* Variably modified types are needed for tree_is_indexable to decide
     whether the type needs to go to local or global section.
     This code is semi-broken but for now it is easiest to keep contexts
     as expected.  */
  if (ctx && TYPE_P (ctx)
      && !variably_modified_type_p (ctx, NULL_TREE))
     {
       while (ctx && TYPE_P (ctx))
	 ctx = TYPE_CONTEXT (ctx);
     }
  return ctx;
}

/* For T being aggregate type try to turn it into a incomplete variant.
   Return T if no simplification is possible.  */

static tree
fld_incomplete_type_of (tree t, struct free_lang_data_d *fld)
{
  if (!t)
    return NULL;
  if (POINTER_TYPE_P (t))
    {
      tree t2 = fld_incomplete_type_of (TREE_TYPE (t), fld);
      if (t2 != TREE_TYPE (t))
	{
	  tree first;
	  if (TREE_CODE (t) == POINTER_TYPE)
	    first = build_pointer_type_for_mode (t2, TYPE_MODE (t),
						TYPE_REF_CAN_ALIAS_ALL (t));
	  else
	    first = build_reference_type_for_mode (t2, TYPE_MODE (t),
						TYPE_REF_CAN_ALIAS_ALL (t));
	  gcc_assert (TYPE_CANONICAL (t2) != t2
		      && TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t)));
	  add_tree_to_fld_list (first, fld);
	  return fld_type_variant (first, t, fld);
	}
      return t;
    }
  if (TREE_CODE (t) == ARRAY_TYPE)
    return fld_process_array_type (t,
				   fld_incomplete_type_of (TREE_TYPE (t), fld),
				   fld_incomplete_types, fld);
  if ((!RECORD_OR_UNION_TYPE_P (t) && TREE_CODE (t) != ENUMERAL_TYPE)
      || !COMPLETE_TYPE_P (t))
    return t;
  if (TYPE_MAIN_VARIANT (t) == t)
    {
      bool existed;
      tree &copy
	 = fld_incomplete_types->get_or_insert (t, &existed);

      if (!existed)
	{
	  copy = build_distinct_type_copy (t);

	  /* It is possible that type was not seen by free_lang_data yet.  */
	  add_tree_to_fld_list (copy, fld);
	  TYPE_SIZE (copy) = NULL;
	  TYPE_USER_ALIGN (copy) = 0;
	  TYPE_SIZE_UNIT (copy) = NULL;
	  TYPE_CANONICAL (copy) = TYPE_CANONICAL (t);
	  TREE_ADDRESSABLE (copy) = 0;
	  if (AGGREGATE_TYPE_P (t))
	    {
	      SET_TYPE_MODE (copy, VOIDmode);
	      SET_TYPE_ALIGN (copy, BITS_PER_UNIT);
	      TYPE_TYPELESS_STORAGE (copy) = 0;
	      TYPE_FIELDS (copy) = NULL;
	      TYPE_BINFO (copy) = NULL;
	    }
	  else
	    TYPE_VALUES (copy) = NULL;

	  /* Build copy of TYPE_DECL in TYPE_NAME if necessary.
	     This is needed for ODR violation warnings to come out right (we
	     want duplicate TYPE_DECLs whenever the type is duplicated because
	     of ODR violation.  Because lang data in the TYPE_DECL may not
	     have been freed yet, rebuild it from scratch and copy relevant
	     fields.  */
	  TYPE_NAME (copy) = fld_simplified_type_name (copy);
	  tree name = TYPE_NAME (copy);

	  if (name && TREE_CODE (name) == TYPE_DECL)
	    {
	      gcc_checking_assert (TREE_TYPE (name) == t);
	      tree name2 = build_decl (DECL_SOURCE_LOCATION (name), TYPE_DECL,
				       DECL_NAME (name), copy);
	      if (DECL_ASSEMBLER_NAME_SET_P (name))
	        SET_DECL_ASSEMBLER_NAME (name2, DECL_ASSEMBLER_NAME (name));
	      SET_DECL_ALIGN (name2, 0);
	      DECL_CONTEXT (name2) = fld_decl_context
					 (DECL_CONTEXT (name));
	      TYPE_NAME (copy) = name2;
	    }
	}
      return copy;
   }
  return (fld_type_variant
	    (fld_incomplete_type_of (TYPE_MAIN_VARIANT (t), fld), t, fld));
}

/* Simplify type T for scenarios where we do not need complete pointer
   types.  */

static tree
fld_simplified_type (tree t, struct free_lang_data_d *fld)
{
  if (!t)
    return t;
  if (POINTER_TYPE_P (t))
    return fld_incomplete_type_of (t, fld);
  if (TREE_CODE (t) == ARRAY_TYPE)
    return fld_process_array_type (t, fld_simplified_type (TREE_TYPE (t), fld),
				   fld_simplified_types, fld);
  return t;
}

/* Reset the expression *EXPR_P, a size or position.

   ??? We could reset all non-constant sizes or positions.  But it's cheap
   enough to not do so and refrain from adding workarounds to dwarf2out.c.

   We need to reset self-referential sizes or positions because they cannot
   be gimplified and thus can contain a CALL_EXPR after the gimplification
   is finished, which will run afoul of LTO streaming.  And they need to be
   reset to something essentially dummy but not constant, so as to preserve
   the properties of the object they are attached to.  */

static inline void
free_lang_data_in_one_sizepos (tree *expr_p)
{
  tree expr = *expr_p;
  if (CONTAINS_PLACEHOLDER_P (expr))
    *expr_p = build0 (PLACEHOLDER_EXPR, TREE_TYPE (expr));
}


/* Reset all the fields in a binfo node BINFO.  We only keep
   BINFO_VTABLE, which is used by gimple_fold_obj_type_ref.  */

static void
free_lang_data_in_binfo (tree binfo)
{
  unsigned i;
  tree t;

  gcc_assert (TREE_CODE (binfo) == TREE_BINFO);

  BINFO_VIRTUALS (binfo) = NULL_TREE;
  BINFO_BASE_ACCESSES (binfo) = NULL;
  BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE;
  BINFO_SUBVTT_INDEX (binfo) = NULL_TREE;
  BINFO_VPTR_FIELD (binfo) = NULL_TREE;

  FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (binfo), i, t)
    free_lang_data_in_binfo (t);
}


/* Reset all language specific information still present in TYPE.  */

static void
free_lang_data_in_type (tree type, struct free_lang_data_d *fld)
{
  gcc_assert (TYPE_P (type));

  /* Give the FE a chance to remove its own data first.  */
  lang_hooks.free_lang_data (type);

  TREE_LANG_FLAG_0 (type) = 0;
  TREE_LANG_FLAG_1 (type) = 0;
  TREE_LANG_FLAG_2 (type) = 0;
  TREE_LANG_FLAG_3 (type) = 0;
  TREE_LANG_FLAG_4 (type) = 0;
  TREE_LANG_FLAG_5 (type) = 0;
  TREE_LANG_FLAG_6 (type) = 0;

  TYPE_NEEDS_CONSTRUCTING (type) = 0;

  if (TREE_CODE (type) == FUNCTION_TYPE)
    {
      TREE_TYPE (type) = fld_simplified_type (TREE_TYPE (type), fld);
      /* Remove the const and volatile qualifiers from arguments.  The
	 C++ front end removes them, but the C front end does not,
	 leading to false ODR violation errors when merging two
	 instances of the same function signature compiled by
	 different front ends.  */
      for (tree p = TYPE_ARG_TYPES (type); p; p = TREE_CHAIN (p))
	{
          TREE_VALUE (p) = fld_simplified_type (TREE_VALUE (p), fld);
	  tree arg_type = TREE_VALUE (p);

	  if (TYPE_READONLY (arg_type) || TYPE_VOLATILE (arg_type))
	    {
	      int quals = TYPE_QUALS (arg_type)
			  & ~TYPE_QUAL_CONST
			  & ~TYPE_QUAL_VOLATILE;
	      TREE_VALUE (p) = build_qualified_type (arg_type, quals);
	      free_lang_data_in_type (TREE_VALUE (p), fld);
	    }
	  /* C++ FE uses TREE_PURPOSE to store initial values.  */
	  TREE_PURPOSE (p) = NULL;
	}
    }
  else if (TREE_CODE (type) == METHOD_TYPE)
    {
      TREE_TYPE (type) = fld_simplified_type (TREE_TYPE (type), fld);
      for (tree p = TYPE_ARG_TYPES (type); p; p = TREE_CHAIN (p))
	{
	  /* C++ FE uses TREE_PURPOSE to store initial values.  */
	  TREE_VALUE (p) = fld_simplified_type (TREE_VALUE (p), fld);
	  TREE_PURPOSE (p) = NULL;
	}
    }
  else if (RECORD_OR_UNION_TYPE_P (type))
    {
      /* Remove members that are not FIELD_DECLs from the field list
	 of an aggregate.  These occur in C++.  */
      for (tree *prev = &TYPE_FIELDS (type), member; (member = *prev);)
	if (TREE_CODE (member) == FIELD_DECL)
	  prev = &DECL_CHAIN (member);
	else
	  *prev = DECL_CHAIN (member);

      TYPE_VFIELD (type) = NULL_TREE;

      if (TYPE_BINFO (type))
	{
	  free_lang_data_in_binfo (TYPE_BINFO (type));
	  /* We need to preserve link to bases and virtual table for all
	     polymorphic types to make devirtualization machinery working.  */
	  if (!BINFO_VTABLE (TYPE_BINFO (type))
	      || !flag_devirtualize)
	    TYPE_BINFO (type) = NULL;
	}
    }
  else if (INTEGRAL_TYPE_P (type)
	   || SCALAR_FLOAT_TYPE_P (type)
	   || FIXED_POINT_TYPE_P (type))
    {
      if (TREE_CODE (type) == ENUMERAL_TYPE)
	{
	  /* Type values are used only for C++ ODR checking.  Drop them
	     for all type variants and non-ODR types.
	     For ODR types the data is freed in free_odr_warning_data.  */
	  if (TYPE_MAIN_VARIANT (type) != type
	      || !type_with_linkage_p (type))
	    TYPE_VALUES (type) = NULL;
	  else
	  /* Simplify representation by recording only values rather
	     than const decls.  */
	    for (tree e = TYPE_VALUES (type); e; e = TREE_CHAIN (e))
	      if (TREE_CODE (TREE_VALUE (e)) == CONST_DECL)
		TREE_VALUE (e) = DECL_INITIAL (TREE_VALUE (e));
	}
      free_lang_data_in_one_sizepos (&TYPE_MIN_VALUE (type));
      free_lang_data_in_one_sizepos (&TYPE_MAX_VALUE (type));
    }

  TYPE_LANG_SLOT_1 (type) = NULL_TREE;

  free_lang_data_in_one_sizepos (&TYPE_SIZE (type));
  free_lang_data_in_one_sizepos (&TYPE_SIZE_UNIT (type));

  if (TYPE_CONTEXT (type)
      && TREE_CODE (TYPE_CONTEXT (type)) == BLOCK)
    {
      tree ctx = TYPE_CONTEXT (type);
      do
	{
	  ctx = BLOCK_SUPERCONTEXT (ctx);
	}
      while (ctx && TREE_CODE (ctx) == BLOCK);
      TYPE_CONTEXT (type) = ctx;
    }

  TYPE_STUB_DECL (type) = NULL;
  TYPE_NAME (type) = fld_simplified_type_name (type);
}


/* Return true if DECL may need an assembler name to be set.  */

static inline bool
need_assembler_name_p (tree decl)
{
  /* We use DECL_ASSEMBLER_NAME to hold mangled type names for One Definition
     Rule merging.  This makes type_odr_p to return true on those types during
     LTO and by comparing the mangled name, we can say what types are intended
     to be equivalent across compilation unit.

     We do not store names of type_in_anonymous_namespace_p.

     Record, union and enumeration type have linkage that allows use
     to check type_in_anonymous_namespace_p. We do not mangle compound types
     that always can be compared structurally.

     Similarly for builtin types, we compare properties of their main variant.
     A special case are integer types where mangling do make differences
     between char/signed char/unsigned char etc.  Storing name for these makes
     e.g.  -fno-signed-char/-fsigned-char mismatches to be handled well.
     See cp/mangle.c:write_builtin_type for details.  */

  if (TREE_CODE (decl) == TYPE_DECL)
    {
      if (flag_lto_odr_type_mering
	  && DECL_NAME (decl)
	  && decl == TYPE_NAME (TREE_TYPE (decl))
	  && TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TREE_TYPE (decl)
	  && !TYPE_ARTIFICIAL (TREE_TYPE (decl))
	  && (type_with_linkage_p (TREE_TYPE (decl))
	      || TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE)
	  && !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
	return !DECL_ASSEMBLER_NAME_SET_P (decl);
      return false;
    }
  /* Only FUNCTION_DECLs and VAR_DECLs are considered.  */
  if (!VAR_OR_FUNCTION_DECL_P (decl))
    return false;

  /* If DECL already has its assembler name set, it does not need a
     new one.  */
  if (!HAS_DECL_ASSEMBLER_NAME_P (decl)
      || DECL_ASSEMBLER_NAME_SET_P (decl))
    return false;

  /* Abstract decls do not need an assembler name.  */
  if (DECL_ABSTRACT_P (decl))
    return false;

  /* For VAR_DECLs, only static, public and external symbols need an
     assembler name.  */
  if (VAR_P (decl)
      && !TREE_STATIC (decl)
      && !TREE_PUBLIC (decl)
      && !DECL_EXTERNAL (decl))
    return false;

  if (TREE_CODE (decl) == FUNCTION_DECL)
    {
      /* Do not set assembler name on builtins.  Allow RTL expansion to
	 decide whether to expand inline or via a regular call.  */
      if (fndecl_built_in_p (decl)
	  && DECL_BUILT_IN_CLASS (decl) != BUILT_IN_FRONTEND)
	return false;

      /* Functions represented in the callgraph need an assembler name.  */
      if (cgraph_node::get (decl) != NULL)
	return true;

      /* Unused and not public functions don't need an assembler name.  */
      if (!TREE_USED (decl) && !TREE_PUBLIC (decl))
	return false;
    }

  return true;
}


/* Reset all language specific information still present in symbol
   DECL.  */

static void
free_lang_data_in_decl (tree decl, struct free_lang_data_d *fld)
{
  gcc_assert (DECL_P (decl));

  /* Give the FE a chance to remove its own data first.  */
  lang_hooks.free_lang_data (decl);

  TREE_LANG_FLAG_0 (decl) = 0;
  TREE_LANG_FLAG_1 (decl) = 0;
  TREE_LANG_FLAG_2 (decl) = 0;
  TREE_LANG_FLAG_3 (decl) = 0;
  TREE_LANG_FLAG_4 (decl) = 0;
  TREE_LANG_FLAG_5 (decl) = 0;
  TREE_LANG_FLAG_6 (decl) = 0;

  free_lang_data_in_one_sizepos (&DECL_SIZE (decl));
  free_lang_data_in_one_sizepos (&DECL_SIZE_UNIT (decl));
  if (TREE_CODE (decl) == FIELD_DECL)
    {
      DECL_FCONTEXT (decl) = NULL;
      free_lang_data_in_one_sizepos (&DECL_FIELD_OFFSET (decl));
      if (TREE_CODE (DECL_CONTEXT (decl)) == QUAL_UNION_TYPE)
	DECL_QUALIFIER (decl) = NULL_TREE;
    }

 if (TREE_CODE (decl) == FUNCTION_DECL)
    {
      struct cgraph_node *node;
      /* Frontends do not set TREE_ADDRESSABLE on public variables even though
	 the address may be taken in other unit, so this flag has no practical
	 use for middle-end.

	 It would make more sense if frontends set TREE_ADDRESSABLE to 0 only
	 for public objects that indeed can not be adressed, but it is not
	 the case.  Set the flag to true so we do not get merge failures for
	 i.e. virtual tables between units that take address of it and
	 units that don't.  */
      if (TREE_PUBLIC (decl))
	TREE_ADDRESSABLE (decl) = true;
      TREE_TYPE (decl) = fld_simplified_type (TREE_TYPE (decl), fld);
      if (!(node = cgraph_node::get (decl))
	  || (!node->definition && !node->clones))
	{
	  if (node)
	    node->release_body ();
	  else
	    {
	      release_function_body (decl);
	      DECL_ARGUMENTS (decl) = NULL;
	      DECL_RESULT (decl) = NULL;
	      DECL_INITIAL (decl) = error_mark_node;
	    }
	}
      if (gimple_has_body_p (decl) || (node && node->thunk.thunk_p))
	{
	  tree t;

	  /* If DECL has a gimple body, then the context for its
	     arguments must be DECL.  Otherwise, it doesn't really
	     matter, as we will not be emitting any code for DECL.  In
	     general, there may be other instances of DECL created by
	     the front end and since PARM_DECLs are generally shared,
	     their DECL_CONTEXT changes as the replicas of DECL are
	     created.  The only time where DECL_CONTEXT is important
	     is for the FUNCTION_DECLs that have a gimple body (since
	     the PARM_DECL will be used in the function's body).  */
	  for (t = DECL_ARGUMENTS (decl); t; t = TREE_CHAIN (t))
	    DECL_CONTEXT (t) = decl;
	  if (!DECL_FUNCTION_SPECIFIC_TARGET (decl))
	    DECL_FUNCTION_SPECIFIC_TARGET (decl)
	      = target_option_default_node;
	  if (!DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))
	    DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)
	      = optimization_default_node;
	}

      /* DECL_SAVED_TREE holds the GENERIC representation for DECL.
	 At this point, it is not needed anymore.  */
      DECL_SAVED_TREE (decl) = NULL_TREE;

      /* Clear the abstract origin if it refers to a method.
         Otherwise dwarf2out.c will ICE as we splice functions out of
         TYPE_FIELDS and thus the origin will not be output
         correctly.  */
      if (DECL_ABSTRACT_ORIGIN (decl)
	  && DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))
	  && RECORD_OR_UNION_TYPE_P
	       (DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))))
	DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;

      DECL_VINDEX (decl) = NULL_TREE;
    }
  else if (VAR_P (decl))
    {
      /* See comment above why we set the flag for functoins.  */
      if (TREE_PUBLIC (decl))
	TREE_ADDRESSABLE (decl) = true;
      if ((DECL_EXTERNAL (decl)
	   && (!TREE_STATIC (decl) || !TREE_READONLY (decl)))
	  || (decl_function_context (decl) && !TREE_STATIC (decl)))
	DECL_INITIAL (decl) = NULL_TREE;
    }
  else if (TREE_CODE (decl) == TYPE_DECL)
    {
      DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
      DECL_VISIBILITY_SPECIFIED (decl) = 0;
      TREE_PUBLIC (decl) = 0;
      TREE_PRIVATE (decl) = 0;
      DECL_ARTIFICIAL (decl) = 0;
      TYPE_DECL_SUPPRESS_DEBUG (decl) = 0;
      DECL_INITIAL (decl) = NULL_TREE;
      DECL_ORIGINAL_TYPE (decl) = NULL_TREE;
      DECL_MODE (decl) = VOIDmode;
      SET_DECL_ALIGN (decl, 0);
      /* TREE_TYPE is cleared at WPA time in free_odr_warning_data.  */
    }
  else if (TREE_CODE (decl) == FIELD_DECL)
    {
      TREE_TYPE (decl) = fld_simplified_type (TREE_TYPE (decl), fld);
      DECL_INITIAL (decl) = NULL_TREE;
    }
  else if (TREE_CODE (decl) == TRANSLATION_UNIT_DECL
           && DECL_INITIAL (decl)
           && TREE_CODE (DECL_INITIAL (decl)) == BLOCK)
    {
      /* Strip builtins from the translation-unit BLOCK.  We still have targets
	 without builtin_decl_explicit support and also builtins are shared
	 nodes and thus we can't use TREE_CHAIN in multiple lists.  */
      tree *nextp = &BLOCK_VARS (DECL_INITIAL (decl));
      while (*nextp)
	{
	  tree var = *nextp;
	  if (fndecl_built_in_p (var))
	    *nextp = TREE_CHAIN (var);
	  else
	    nextp = &TREE_CHAIN (var);
        }
    }
  /* We need to keep field decls associated with their trees. Otherwise tree
     merging may merge some fileds and keep others disjoint wich in turn will
     not do well with TREE_CHAIN pointers linking them.

     Also do not drop containing types for virtual methods and tables because
     these are needed by devirtualization.  */
  if (TREE_CODE (decl) != FIELD_DECL
      && ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
          || !DECL_VIRTUAL_P (decl)))
    DECL_CONTEXT (decl) = fld_decl_context (DECL_CONTEXT (decl));
}


/* Operand callback helper for free_lang_data_in_node.  *TP is the
   subtree operand being considered.  */

static tree
find_decls_types_r (tree *tp, int *ws, void *data)
{
  tree t = *tp;
  struct free_lang_data_d *fld = (struct free_lang_data_d *) data;

  if (TREE_CODE (t) == TREE_LIST)
    return NULL_TREE;

  /* Language specific nodes will be removed, so there is no need
     to gather anything under them.  */
  if (is_lang_specific (t))
    {
      *ws = 0;
      return NULL_TREE;
    }

  if (DECL_P (t))
    {
      /* Note that walk_tree does not traverse every possible field in
	 decls, so we have to do our own traversals here.  */
      add_tree_to_fld_list (t, fld);

      fld_worklist_push (DECL_NAME (t), fld);
      fld_worklist_push (DECL_CONTEXT (t), fld);
      fld_worklist_push (DECL_SIZE (t), fld);
      fld_worklist_push (DECL_SIZE_UNIT (t), fld);

      /* We are going to remove everything under DECL_INITIAL for
	 TYPE_DECLs.  No point walking them.  */
      if (TREE_CODE (t) != TYPE_DECL)
	fld_worklist_push (DECL_INITIAL (t), fld);

      fld_worklist_push (DECL_ATTRIBUTES (t), fld);
      fld_worklist_push (DECL_ABSTRACT_ORIGIN (t), fld);

      if (TREE_CODE (t) == FUNCTION_DECL)
	{
	  fld_worklist_push (DECL_ARGUMENTS (t), fld);
	  fld_worklist_push (DECL_RESULT (t), fld);
	}
      else if (TREE_CODE (t) == FIELD_DECL)
	{
	  fld_worklist_push (DECL_FIELD_OFFSET (t), fld);
	  fld_worklist_push (DECL_BIT_FIELD_TYPE (t), fld);
	  fld_worklist_push (DECL_FIELD_BIT_OFFSET (t), fld);
	  fld_worklist_push (DECL_FCONTEXT (t), fld);
	}

      if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL)
	  && DECL_HAS_VALUE_EXPR_P (t))
	fld_worklist_push (DECL_VALUE_EXPR (t), fld);

      if (TREE_CODE (t) != FIELD_DECL
	  && TREE_CODE (t) != TYPE_DECL)
	fld_worklist_push (TREE_CHAIN (t), fld);
      *ws = 0;
    }
  else if (TYPE_P (t))
    {
      /* Note that walk_tree does not traverse every possible field in
	 types, so we have to do our own traversals here.  */
      add_tree_to_fld_list (t, fld);

      if (!RECORD_OR_UNION_TYPE_P (t))
	fld_worklist_push (TYPE_CACHED_VALUES (t), fld);
      fld_worklist_push (TYPE_SIZE (t), fld);
      fld_worklist_push (TYPE_SIZE_UNIT (t), fld);
      fld_worklist_push (TYPE_ATTRIBUTES (t), fld);
      fld_worklist_push (TYPE_POINTER_TO (t), fld);
      fld_worklist_push (TYPE_REFERENCE_TO (t), fld);
      fld_worklist_push (TYPE_NAME (t), fld);
      /* While we do not stream TYPE_POINTER_TO and TYPE_REFERENCE_TO
	 lists, we may look types up in these lists and use them while
	 optimizing the function body.  Thus we need to free lang data
	 in them.  */
      if (TREE_CODE (t) == POINTER_TYPE)
        fld_worklist_push (TYPE_NEXT_PTR_TO (t), fld);
      if (TREE_CODE (t) == REFERENCE_TYPE)
        fld_worklist_push (TYPE_NEXT_REF_TO (t), fld);
      if (!POINTER_TYPE_P (t))
	fld_worklist_push (TYPE_MIN_VALUE_RAW (t), fld);
      /* TYPE_MAX_VALUE_RAW is TYPE_BINFO for record types.  */
      if (!RECORD_OR_UNION_TYPE_P (t))
	fld_worklist_push (TYPE_MAX_VALUE_RAW (t), fld);
      fld_worklist_push (TYPE_MAIN_VARIANT (t), fld);
      /* Do not walk TYPE_NEXT_VARIANT.  We do not stream it and thus
         do not and want not to reach unused variants this way.  */
      if (TYPE_CONTEXT (t))
	{
	  tree ctx = TYPE_CONTEXT (t);
	  /* We adjust BLOCK TYPE_CONTEXTs to the innermost non-BLOCK one.
	     So push that instead.  */
	  while (ctx && TREE_CODE (ctx) == BLOCK)
	    ctx = BLOCK_SUPERCONTEXT (ctx);
	  fld_worklist_push (ctx, fld);
	}
      /* Do not walk TYPE_CANONICAL.  We do not stream it and thus do not
	 and want not to reach unused types this way.  */

      if (RECORD_OR_UNION_TYPE_P (t) && TYPE_BINFO (t))
	{
	  unsigned i;
	  tree tem;
	  FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (TYPE_BINFO (t)), i, tem)
	    fld_worklist_push (TREE_TYPE (tem), fld);
	  fld_worklist_push (BINFO_TYPE (TYPE_BINFO (t)), fld);
	  fld_worklist_push (BINFO_VTABLE (TYPE_BINFO (t)), fld);
	}
      if (RECORD_OR_UNION_TYPE_P (t))
	{
	  tree tem;
	  /* Push all TYPE_FIELDS - there can be interleaving interesting
	     and non-interesting things.  */
	  tem = TYPE_FIELDS (t);
	  while (tem)
	    {
	      if (TREE_CODE (tem) == FIELD_DECL)
		fld_worklist_push (tem, fld);
	      tem = TREE_CHAIN (tem);
	    }
	}
      if (FUNC_OR_METHOD_TYPE_P (t))
	fld_worklist_push (TYPE_METHOD_BASETYPE (t), fld);

      fld_worklist_push (TYPE_STUB_DECL (t), fld);
      *ws = 0;
    }
  else if (TREE_CODE (t) == BLOCK)
    {
      for (tree *tem = &BLOCK_VARS (t); *tem; )
	{
	  if (TREE_CODE (*tem) != VAR_DECL
	      || !auto_var_in_fn_p (*tem, DECL_CONTEXT (*tem)))
	    {
	      gcc_assert (TREE_CODE (*tem) != RESULT_DECL
			  && TREE_CODE (*tem) != PARM_DECL);
	      *tem = TREE_CHAIN (*tem);
	    }
	  else 
	    {
	      fld_worklist_push (*tem, fld);
	      tem = &TREE_CHAIN (*tem);
	    }
	}
      for (tree tem = BLOCK_SUBBLOCKS (t); tem; tem = BLOCK_CHAIN (tem))
	fld_worklist_push (tem, fld);
      fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
    }

  if (TREE_CODE (t) != IDENTIFIER_NODE
      && CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
    fld_worklist_push (TREE_TYPE (t), fld);

  return NULL_TREE;
}


/* Find decls and types in T.  */

static void
find_decls_types (tree t, struct free_lang_data_d *fld)
{
  while (1)
    {
      if (!fld->pset.contains (t))
	walk_tree (&t, find_decls_types_r, fld, &fld->pset);
      if (fld->worklist.is_empty ())
	break;
      t = fld->worklist.pop ();
    }
}

/* Translate all the types in LIST with the corresponding runtime
   types.  */

static tree
get_eh_types_for_runtime (tree list)
{
  tree head, prev;

  if (list == NULL_TREE)
    return NULL_TREE;

  head = build_tree_list (0, lookup_type_for_runtime (TREE_VALUE (list)));
  prev = head;
  list = TREE_CHAIN (list);
  while (list)
    {
      tree n = build_tree_list (0, lookup_type_for_runtime (TREE_VALUE (list)));
      TREE_CHAIN (prev) = n;
      prev = TREE_CHAIN (prev);
      list = TREE_CHAIN (list);
    }

  return head;
}


/* Find decls and types referenced in EH region R and store them in
   FLD->DECLS and FLD->TYPES.  */

static void
find_decls_types_in_eh_region (eh_region r, struct free_lang_data_d *fld)
{
  switch (r->type)
    {
    case ERT_CLEANUP:
      break;

    case ERT_TRY:
      {
	eh_catch c;

	/* The types referenced in each catch must first be changed to the
	   EH types used at runtime.  This removes references to FE types
	   in the region.  */
	for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
	  {
	    c->type_list = get_eh_types_for_runtime (c->type_list);
	    walk_tree (&c->type_list, find_decls_types_r, fld, &fld->pset);
	  }
      }
      break;

    case ERT_ALLOWED_EXCEPTIONS:
      r->u.allowed.type_list
	= get_eh_types_for_runtime (r->u.allowed.type_list);
      walk_tree (&r->u.allowed.type_list, find_decls_types_r, fld, &fld->pset);
      break;

    case ERT_MUST_NOT_THROW:
      walk_tree (&r->u.must_not_throw.failure_decl,
		 find_decls_types_r, fld, &fld->pset);
      break;
    }
}


/* Find decls and types referenced in cgraph node N and store them in
   FLD->DECLS and FLD->TYPES.  Unlike pass_referenced_vars, this will
   look for *every* kind of DECL and TYPE node reachable from N,
   including those embedded inside types and decls (i.e,, TYPE_DECLs,
   NAMESPACE_DECLs, etc).  */

static void
find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld)
{
  basic_block bb;
  struct function *fn;
  unsigned ix;
  tree t;

  find_decls_types (n->decl, fld);

  if (!gimple_has_body_p (n->decl))
    return;

  gcc_assert (current_function_decl == NULL_TREE && cfun == NULL);

  fn = DECL_STRUCT_FUNCTION (n->decl);

  /* Traverse locals. */
  FOR_EACH_LOCAL_DECL (fn, ix, t)
    find_decls_types (t, fld);

  /* Traverse EH regions in FN.  */
  {
    eh_region r;
    FOR_ALL_EH_REGION_FN (r, fn)
      find_decls_types_in_eh_region (r, fld);
  }

  /* Traverse every statement in FN.  */
  FOR_EACH_BB_FN (bb, fn)
    {
      gphi_iterator psi;
      gimple_stmt_iterator si;
      unsigned i;

      for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
	{
	  gphi *phi = psi.phi ();

	  for (i = 0; i < gimple_phi_num_args (phi); i++)
	    {
	      tree *arg_p = gimple_phi_arg_def_ptr (phi, i);
	      find_decls_types (*arg_p, fld);
	    }
	}

      for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
	{
	  gimple *stmt = gsi_stmt (si);

	  if (is_gimple_call (stmt))
	    find_decls_types (gimple_call_fntype (stmt), fld);

	  for (i = 0; i < gimple_num_ops (stmt); i++)
	    {
	      tree arg = gimple_op (stmt, i);
	      find_decls_types (arg, fld);
	    }
	}
    }
}


/* Find decls and types referenced in varpool node N and store them in
   FLD->DECLS and FLD->TYPES.  Unlike pass_referenced_vars, this will
   look for *every* kind of DECL and TYPE node reachable from N,
   including those embedded inside types and decls (i.e,, TYPE_DECLs,
   NAMESPACE_DECLs, etc).  */

static void
find_decls_types_in_var (varpool_node *v, struct free_lang_data_d *fld)
{
  find_decls_types (v->decl, fld);
}

/* If T needs an assembler name, have one created for it.  */

void
assign_assembler_name_if_needed (tree t)
{
  if (need_assembler_name_p (t))
    {
      /* When setting DECL_ASSEMBLER_NAME, the C++ mangler may emit
	 diagnostics that use input_location to show locus
	 information.  The problem here is that, at this point,
	 input_location is generally anchored to the end of the file
	 (since the parser is long gone), so we don't have a good
	 position to pin it to.

	 To alleviate this problem, this uses the location of T's
	 declaration.  Examples of this are
	 testsuite/g++.dg/template/cond2.C and
	 testsuite/g++.dg/template/pr35240.C.  */
      location_t saved_location = input_location;
      input_location = DECL_SOURCE_LOCATION (t);

      decl_assembler_name (t);

      input_location = saved_location;
    }
}


/* Free language specific information for every operand and expression
   in every node of the call graph.  This process operates in three stages:

   1- Every callgraph node and varpool node is traversed looking for
      decls and types embedded in them.  This is a more exhaustive
      search than that done by find_referenced_vars, because it will
      also collect individual fields, decls embedded in types, etc.

   2- All the decls found are sent to free_lang_data_in_decl.

   3- All the types found are sent to free_lang_data_in_type.

   The ordering between decls and types is important because
   free_lang_data_in_decl sets assembler names, which includes
   mangling.  So types cannot be freed up until assembler names have
   been set up.  */

static void
free_lang_data_in_cgraph (struct free_lang_data_d *fld)
{
  struct cgraph_node *n;
  varpool_node *v;
  tree t;
  unsigned i;
  alias_pair *p;

  /* Find decls and types in the body of every function in the callgraph.  */
  FOR_EACH_FUNCTION (n)
    find_decls_types_in_node (n, fld);

  FOR_EACH_VEC_SAFE_ELT (alias_pairs, i, p)
    find_decls_types (p->decl, fld);

  /* Find decls and types in every varpool symbol.  */
  FOR_EACH_VARIABLE (v)
    find_decls_types_in_var (v, fld);

  /* Set the assembler name on every decl found.  We need to do this
     now because free_lang_data_in_decl will invalidate data needed
     for mangling.  This breaks mangling on interdependent decls.  */
  FOR_EACH_VEC_ELT (fld->decls, i, t)
    assign_assembler_name_if_needed (t);

  /* Traverse every decl found freeing its language data.  */
  FOR_EACH_VEC_ELT (fld->decls, i, t)
    free_lang_data_in_decl (t, fld);

  /* Traverse every type found freeing its language data.  */
  FOR_EACH_VEC_ELT (fld->types, i, t)
    free_lang_data_in_type (t, fld);
}


/* Free resources that are used by FE but are not needed once they are done. */

static unsigned
free_lang_data (void)
{
  unsigned i;
  struct free_lang_data_d fld;

  /* If we are the LTO frontend we have freed lang-specific data already.  */
  if (in_lto_p
      || (!flag_generate_lto && !flag_generate_offload))
    return 0;

  fld_incomplete_types = new hash_map<tree, tree>;
  fld_simplified_types = new hash_map<tree, tree>;

  /* Provide a dummy TRANSLATION_UNIT_DECL if the FE failed to provide one.  */
  if (vec_safe_is_empty (all_translation_units))
    build_translation_unit_decl (NULL_TREE);

  /* Allocate and assign alias sets to the standard integer types
     while the slots are still in the way the frontends generated them.  */
  for (i = 0; i < itk_none; ++i)
    if (integer_types[i])
      TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i]);

  /* Traverse the IL resetting language specific information for
     operands, expressions, etc.  */
  free_lang_data_in_cgraph (&fld);

  /* Create gimple variants for common types.  */
  for (unsigned i = 0;
       i < sizeof (builtin_structptr_types) / sizeof (builtin_structptr_type);
       ++i)
    builtin_structptr_types[i].node = builtin_structptr_types[i].base;

  /* Reset some langhooks.  Do not reset types_compatible_p, it may
     still be used indirectly via the get_alias_set langhook.  */
  lang_hooks.dwarf_name = lhd_dwarf_name;
  lang_hooks.decl_printable_name = gimple_decl_printable_name;
  lang_hooks.gimplify_expr = lhd_gimplify_expr;
  lang_hooks.overwrite_decl_assembler_name = lhd_overwrite_decl_assembler_name;
  lang_hooks.print_xnode = lhd_print_tree_nothing;
  lang_hooks.print_decl = lhd_print_tree_nothing;
  lang_hooks.print_type = lhd_print_tree_nothing;
  lang_hooks.print_identifier = lhd_print_tree_nothing;

  lang_hooks.tree_inlining.var_mod_type_p = hook_bool_tree_tree_false;

  if (flag_checking)
    {
      int i;
      tree t;

      FOR_EACH_VEC_ELT (fld.types, i, t)
	verify_type (t);
    }

  /* We do not want the default decl_assembler_name implementation,
     rather if we have fixed everything we want a wrapper around it
     asserting that all non-local symbols already got their assembler
     name and only produce assembler names for local symbols.  Or rather
     make sure we never call decl_assembler_name on local symbols and
     devise a separate, middle-end private scheme for it.  */

  /* Reset diagnostic machinery.  */
  tree_diagnostics_defaults (global_dc);

  rebuild_type_inheritance_graph ();

  delete fld_incomplete_types;
  delete fld_simplified_types;

  return 0;
}


namespace {

const pass_data pass_data_ipa_free_lang_data =
{
  SIMPLE_IPA_PASS, /* type */
  "*free_lang_data", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_IPA_FREE_LANG_DATA, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_ipa_free_lang_data : public simple_ipa_opt_pass
{
public:
  pass_ipa_free_lang_data (gcc::context *ctxt)
    : simple_ipa_opt_pass (pass_data_ipa_free_lang_data, ctxt)
  {}

  /* opt_pass methods: */
  virtual unsigned int execute (function *) { return free_lang_data (); }

}; // class pass_ipa_free_lang_data

} // anon namespace

simple_ipa_opt_pass *
make_pass_ipa_free_lang_data (gcc::context *ctxt)
{
  return new pass_ipa_free_lang_data (ctxt);
}

/* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask
   of the various TYPE_QUAL values.  */

static void
set_type_quals (tree type, int type_quals)
{
  TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0;
  TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
  TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
  TYPE_ATOMIC (type) = (type_quals & TYPE_QUAL_ATOMIC) != 0;
  TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals);
}

/* Returns true iff CAND and BASE have equivalent language-specific
   qualifiers.  */

bool
check_lang_type (const_tree cand, const_tree base)
{
  if (lang_hooks.types.type_hash_eq == NULL)
    return true;
  /* type_hash_eq currently only applies to these types.  */
  if (TREE_CODE (cand) != FUNCTION_TYPE
      && TREE_CODE (cand) != METHOD_TYPE)
    return true;
  return lang_hooks.types.type_hash_eq (cand, base);
}

/* Returns true iff unqualified CAND and BASE are equivalent.  */

bool
check_base_type (const_tree cand, const_tree base)
{
  return (TYPE_NAME (cand) == TYPE_NAME (base)
	  /* Apparently this is needed for Objective-C.  */
	  && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base)
	  /* Check alignment.  */
	  && TYPE_ALIGN (cand) == TYPE_ALIGN (base)
	  && attribute_list_equal (TYPE_ATTRIBUTES (cand),
				   TYPE_ATTRIBUTES (base)));
}

/* Returns true iff CAND is equivalent to BASE with TYPE_QUALS.  */

bool
check_qualified_type (const_tree cand, const_tree base, int type_quals)
{
  return (TYPE_QUALS (cand) == type_quals
	  && check_base_type (cand, base)
	  && check_lang_type (cand, base));
}

/* Returns true iff CAND is equivalent to BASE with ALIGN.  */

static bool
check_aligned_type (const_tree cand, const_tree base, unsigned int align)
{
  return (TYPE_QUALS (cand) == TYPE_QUALS (base)
	  && TYPE_NAME (cand) == TYPE_NAME (base)
	  /* Apparently this is needed for Objective-C.  */
	  && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base)
	  /* Check alignment.  */
	  && TYPE_ALIGN (cand) == align
	  && attribute_list_equal (TYPE_ATTRIBUTES (cand),
				   TYPE_ATTRIBUTES (base))
	  && check_lang_type (cand, base));
}

/* This function checks to see if TYPE matches the size one of the built-in 
   atomic types, and returns that core atomic type.  */

static tree
find_atomic_core_type (tree type)
{
  tree base_atomic_type;

  /* Only handle complete types.  */
  if (!tree_fits_uhwi_p (TYPE_SIZE (type)))
    return NULL_TREE;

  switch (tree_to_uhwi (TYPE_SIZE (type)))
    {
    case 8:
      base_atomic_type = atomicQI_type_node;
      break;

    case 16:
      base_atomic_type = atomicHI_type_node;
      break;

    case 32:
      base_atomic_type = atomicSI_type_node;
      break;

    case 64:
      base_atomic_type = atomicDI_type_node;
      break;

    case 128:
      base_atomic_type = atomicTI_type_node;
      break;

    default:
      base_atomic_type = NULL_TREE;
    }

  return base_atomic_type;
}

/* Return a version of the TYPE, qualified as indicated by the
   TYPE_QUALS, if one exists.  If no qualified version exists yet,
   return NULL_TREE.  */

tree
get_qualified_type (tree type, int type_quals)
{
  tree t;

  if (TYPE_QUALS (type) == type_quals)
    return type;

  /* Search the chain of variants to see if there is already one there just
     like the one we need to have.  If so, use that existing one.  We must
     preserve the TYPE_NAME, since there is code that depends on this.  */
  for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
    if (check_qualified_type (t, type, type_quals))
      return t;

  return NULL_TREE;
}

/* Like get_qualified_type, but creates the type if it does not
   exist.  This function never returns NULL_TREE.  */

tree
build_qualified_type (tree type, int type_quals MEM_STAT_DECL)
{
  tree t;

  /* See if we already have the appropriate qualified variant.  */
  t = get_qualified_type (type, type_quals);

  /* If not, build it.  */
  if (!t)
    {
      t = build_variant_type_copy (type PASS_MEM_STAT);
      set_type_quals (t, type_quals);

      if (((type_quals & TYPE_QUAL_ATOMIC) == TYPE_QUAL_ATOMIC))
	{
	  /* See if this object can map to a basic atomic type.  */
	  tree atomic_type = find_atomic_core_type (type);
	  if (atomic_type)
	    {
	      /* Ensure the alignment of this type is compatible with
		 the required alignment of the atomic type.  */
	      if (TYPE_ALIGN (atomic_type) > TYPE_ALIGN (t))
		SET_TYPE_ALIGN (t, TYPE_ALIGN (atomic_type));
	    }
	}

      if (TYPE_STRUCTURAL_EQUALITY_P (type))
	/* Propagate structural equality. */
	SET_TYPE_STRUCTURAL_EQUALITY (t);
      else if (TYPE_CANONICAL (type) != type)
	/* Build the underlying canonical type, since it is different
	   from TYPE. */
	{
	  tree c = build_qualified_type (TYPE_CANONICAL (type), type_quals);
	  TYPE_CANONICAL (t) = TYPE_CANONICAL (c);
	}
      else
	/* T is its own canonical type. */
	TYPE_CANONICAL (t) = t;

    }

  return t;
}

/* Create a variant of type T with alignment ALIGN.  */

tree
build_aligned_type (tree type, unsigned int align)
{
  tree t;

  if (TYPE_PACKED (type)
      || TYPE_ALIGN (type) == align)
    return type;

  for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
    if (check_aligned_type (t, type, align))
      return t;

  t = build_variant_type_copy (type);
  SET_TYPE_ALIGN (t, align);
  TYPE_USER_ALIGN (t) = 1;

  return t;
}

/* Create a new distinct copy of TYPE.  The new type is made its own
   MAIN_VARIANT. If TYPE requires structural equality checks, the
   resulting type requires structural equality checks; otherwise, its
   TYPE_CANONICAL points to itself. */

tree
build_distinct_type_copy (tree type MEM_STAT_DECL)
{
  tree t = copy_node (type PASS_MEM_STAT);

  TYPE_POINTER_TO (t) = 0;
  TYPE_REFERENCE_TO (t) = 0;

  /* Set the canonical type either to a new equivalence class, or
     propagate the need for structural equality checks. */
  if (TYPE_STRUCTURAL_EQUALITY_P (type))
    SET_TYPE_STRUCTURAL_EQUALITY (t);
  else
    TYPE_CANONICAL (t) = t;

  /* Make it its own variant.  */
  TYPE_MAIN_VARIANT (t) = t;
  TYPE_NEXT_VARIANT (t) = 0;

  /* Note that it is now possible for TYPE_MIN_VALUE to be a value
     whose TREE_TYPE is not t.  This can also happen in the Ada
     frontend when using subtypes.  */

  return t;
}

/* Create a new variant of TYPE, equivalent but distinct.  This is so
   the caller can modify it. TYPE_CANONICAL for the return type will
   be equivalent to TYPE_CANONICAL of TYPE, indicating that the types
   are considered equal by the language itself (or that both types
   require structural equality checks). */

tree
build_variant_type_copy (tree type MEM_STAT_DECL)
{
  tree t, m = TYPE_MAIN_VARIANT (type);

  t = build_distinct_type_copy (type PASS_MEM_STAT);

  /* Since we're building a variant, assume that it is a non-semantic
     variant. This also propagates TYPE_STRUCTURAL_EQUALITY_P. */
  TYPE_CANONICAL (t) = TYPE_CANONICAL (type);
  /* Type variants have no alias set defined.  */
  TYPE_ALIAS_SET (t) = -1;

  /* Add the new type to the chain of variants of TYPE.  */
  TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
  TYPE_NEXT_VARIANT (m) = t;
  TYPE_MAIN_VARIANT (t) = m;

  return t;
}

/* Return true if the from tree in both tree maps are equal.  */

int
tree_map_base_eq (const void *va, const void *vb)
{
  const struct tree_map_base  *const a = (const struct tree_map_base *) va,
    *const b = (const struct tree_map_base *) vb;
  return (a->from == b->from);
}

/* Hash a from tree in a tree_base_map.  */

unsigned int
tree_map_base_hash (const void *item)
{
  return htab_hash_pointer (((const struct tree_map_base *)item)->from);
}

/* Return true if this tree map structure is marked for garbage collection
   purposes.  We simply return true if the from tree is marked, so that this
   structure goes away when the from tree goes away.  */

int
tree_map_base_marked_p (const void *p)
{
  return ggc_marked_p (((const struct tree_map_base *) p)->from);
}

/* Hash a from tree in a tree_map.  */

unsigned int
tree_map_hash (const void *item)
{
  return (((const struct tree_map *) item)->hash);
}

/* Hash a from tree in a tree_decl_map.  */

unsigned int
tree_decl_map_hash (const void *item)
{
  return DECL_UID (((const struct tree_decl_map *) item)->base.from);
}

/* Return the initialization priority for DECL.  */

priority_type
decl_init_priority_lookup (tree decl)
{
  symtab_node *snode = symtab_node::get (decl);

  if (!snode)
    return DEFAULT_INIT_PRIORITY;
  return
    snode->get_init_priority ();
}

/* Return the finalization priority for DECL.  */

priority_type
decl_fini_priority_lookup (tree decl)
{
  cgraph_node *node = cgraph_node::get (decl);

  if (!node)
    return DEFAULT_INIT_PRIORITY;
  return
    node->get_fini_priority ();
}

/* Set the initialization priority for DECL to PRIORITY.  */

void
decl_init_priority_insert (tree decl, priority_type priority)
{
  struct symtab_node *snode;

  if (priority == DEFAULT_INIT_PRIORITY)
    {
      snode = symtab_node::get (decl);
      if (!snode)
	return;
    }
  else if (VAR_P (decl))
    snode = varpool_node::get_create (decl);
  else
    snode = cgraph_node::get_create (decl);
  snode->set_init_priority (priority);
}

/* Set the finalization priority for DECL to PRIORITY.  */

void
decl_fini_priority_insert (tree decl, priority_type priority)
{
  struct cgraph_node *node;

  if (priority == DEFAULT_INIT_PRIORITY)
    {
      node = cgraph_node::get (decl);
      if (!node)
	return;
    }
  else
    node = cgraph_node::get_create (decl);
  node->set_fini_priority (priority);
}

/* Print out the statistics for the DECL_DEBUG_EXPR hash table.  */

static void
print_debug_expr_statistics (void)
{
  fprintf (stderr, "DECL_DEBUG_EXPR  hash: size %ld, %ld elements, %f collisions\n",
	   (long) debug_expr_for_decl->size (),
	   (long) debug_expr_for_decl->elements (),
	   debug_expr_for_decl->collisions ());
}

/* Print out the statistics for the DECL_VALUE_EXPR hash table.  */

static void
print_value_expr_statistics (void)
{
  fprintf (stderr, "DECL_VALUE_EXPR  hash: size %ld, %ld elements, %f collisions\n",
	   (long) value_expr_for_decl->size (),
	   (long) value_expr_for_decl->elements (),
	   value_expr_for_decl->collisions ());
}

/* Lookup a debug expression for FROM, and return it if we find one.  */

tree
decl_debug_expr_lookup (tree from)
{
  struct tree_decl_map *h, in;
  in.base.from = from;

  h = debug_expr_for_decl->find_with_hash (&in, DECL_UID (from));
  if (h)
    return h->to;
  return NULL_TREE;
}

/* Insert a mapping FROM->TO in the debug expression hashtable.  */

void
decl_debug_expr_insert (tree from, tree to)
{
  struct tree_decl_map *h;

  h = ggc_alloc<tree_decl_map> ();
  h->base.from = from;
  h->to = to;
  *debug_expr_for_decl->find_slot_with_hash (h, DECL_UID (from), INSERT) = h;
}

/* Lookup a value expression for FROM, and return it if we find one.  */

tree
decl_value_expr_lookup (tree from)
{
  struct tree_decl_map *h, in;
  in.base.from = from;

  h = value_expr_for_decl->find_with_hash (&in, DECL_UID (from));
  if (h)
    return h->to;
  return NULL_TREE;
}

/* Insert a mapping FROM->TO in the value expression hashtable.  */

void
decl_value_expr_insert (tree from, tree to)
{
  struct tree_decl_map *h;

  h = ggc_alloc<tree_decl_map> ();
  h->base.from = from;
  h->to = to;
  *value_expr_for_decl->find_slot_with_hash (h, DECL_UID (from), INSERT) = h;
}

/* Lookup a vector of debug arguments for FROM, and return it if we
   find one.  */

vec<tree, va_gc> **
decl_debug_args_lookup (tree from)
{
  struct tree_vec_map *h, in;

  if (!DECL_HAS_DEBUG_ARGS_P (from))
    return NULL;
  gcc_checking_assert (debug_args_for_decl != NULL);
  in.base.from = from;
  h = debug_args_for_decl->find_with_hash (&in, DECL_UID (from));
  if (h)
    return &h->to;
  return NULL;
}

/* Insert a mapping FROM->empty vector of debug arguments in the value
   expression hashtable.  */

vec<tree, va_gc> **
decl_debug_args_insert (tree from)
{
  struct tree_vec_map *h;
  tree_vec_map **loc;

  if (DECL_HAS_DEBUG_ARGS_P (from))
    return decl_debug_args_lookup (from);
  if (debug_args_for_decl == NULL)
    debug_args_for_decl = hash_table<tree_vec_map_cache_hasher>::create_ggc (64);
  h = ggc_alloc<tree_vec_map> ();
  h->base.from = from;
  h->to = NULL;
  loc = debug_args_for_decl->find_slot_with_hash (h, DECL_UID (from), INSERT);
  *loc = h;
  DECL_HAS_DEBUG_ARGS_P (from) = 1;
  return &h->to;
}

/* Hashing of types so that we don't make duplicates.
   The entry point is `type_hash_canon'.  */

/* Generate the default hash code for TYPE.  This is designed for
   speed, rather than maximum entropy.  */

hashval_t
type_hash_canon_hash (tree type)
{
  inchash::hash hstate;

  hstate.add_int (TREE_CODE (type));

  if (TREE_TYPE (type))
    hstate.add_object (TYPE_HASH (TREE_TYPE (type)));

  for (tree t = TYPE_ATTRIBUTES (type); t; t = TREE_CHAIN (t))
    /* Just the identifier is adequate to distinguish.  */
    hstate.add_object (IDENTIFIER_HASH_VALUE (get_attribute_name (t)));

  switch (TREE_CODE (type))
    {
    case METHOD_TYPE:
      hstate.add_object (TYPE_HASH (TYPE_METHOD_BASETYPE (type)));
      /* FALLTHROUGH. */
    case FUNCTION_TYPE:
      for (tree t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
	if (TREE_VALUE (t) != error_mark_node)
	  hstate.add_object (TYPE_HASH (TREE_VALUE (t)));
      break;

    case OFFSET_TYPE:
      hstate.add_object (TYPE_HASH (TYPE_OFFSET_BASETYPE (type)));
      break;

    case ARRAY_TYPE:
      {
	if (TYPE_DOMAIN (type))
	  hstate.add_object (TYPE_HASH (TYPE_DOMAIN (type)));
	if (!AGGREGATE_TYPE_P (TREE_TYPE (type)))
	  {
	    unsigned typeless = TYPE_TYPELESS_STORAGE (type);
	    hstate.add_object (typeless);
	  }
      }
      break;

    case INTEGER_TYPE:
      {
	tree t = TYPE_MAX_VALUE (type);
	if (!t)
	  t = TYPE_MIN_VALUE (type);
	for (int i = 0; i < TREE_INT_CST_NUNITS (t); i++)
	  hstate.add_object (TREE_INT_CST_ELT (t, i));
	break;
      }
      
    case REAL_TYPE:
    case FIXED_POINT_TYPE:
      {
	unsigned prec = TYPE_PRECISION (type);
	hstate.add_object (prec);
	break;
      }

    case VECTOR_TYPE:
      hstate.add_poly_int (TYPE_VECTOR_SUBPARTS (type));
      break;

    default:
      break;
    }

  return hstate.end ();
}

/* These are the Hashtable callback functions.  */

/* Returns true iff the types are equivalent.  */

bool
type_cache_hasher::equal (type_hash *a, type_hash *b)
{
  /* First test the things that are the same for all types.  */
  if (a->hash != b->hash
      || TREE_CODE (a->type) != TREE_CODE (b->type)
      || TREE_TYPE (a->type) != TREE_TYPE (b->type)
      || !attribute_list_equal (TYPE_ATTRIBUTES (a->type),
				 TYPE_ATTRIBUTES (b->type))
      || (TREE_CODE (a->type) != COMPLEX_TYPE
          && TYPE_NAME (a->type) != TYPE_NAME (b->type)))
    return 0;

  /* Be careful about comparing arrays before and after the element type
     has been completed; don't compare TYPE_ALIGN unless both types are
     complete.  */
  if (COMPLETE_TYPE_P (a->type) && COMPLETE_TYPE_P (b->type)
      && (TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type)
	  || TYPE_MODE (a->type) != TYPE_MODE (b->type)))
    return 0;

  switch (TREE_CODE (a->type))
    {
    case VOID_TYPE:
    case COMPLEX_TYPE:
    case POINTER_TYPE:
    case REFERENCE_TYPE:
    case NULLPTR_TYPE:
      return 1;

    case VECTOR_TYPE:
      return known_eq (TYPE_VECTOR_SUBPARTS (a->type),
		       TYPE_VECTOR_SUBPARTS (b->type));

    case ENUMERAL_TYPE:
      if (TYPE_VALUES (a->type) != TYPE_VALUES (b->type)
	  && !(TYPE_VALUES (a->type)
	       && TREE_CODE (TYPE_VALUES (a->type)) == TREE_LIST
	       && TYPE_VALUES (b->type)
	       && TREE_CODE (TYPE_VALUES (b->type)) == TREE_LIST
	       && type_list_equal (TYPE_VALUES (a->type),
				   TYPE_VALUES (b->type))))
	return 0;

      /* fall through */

    case INTEGER_TYPE:
    case REAL_TYPE:
    case BOOLEAN_TYPE:
      if (TYPE_PRECISION (a->type) != TYPE_PRECISION (b->type))
	return false;
      return ((TYPE_MAX_VALUE (a->type) == TYPE_MAX_VALUE (b->type)
	       || tree_int_cst_equal (TYPE_MAX_VALUE (a->type),
				      TYPE_MAX_VALUE (b->type)))
	      && (TYPE_MIN_VALUE (a->type) == TYPE_MIN_VALUE (b->type)
		  || tree_int_cst_equal (TYPE_MIN_VALUE (a->type),
					 TYPE_MIN_VALUE (b->type))));

    case FIXED_POINT_TYPE:
      return TYPE_SATURATING (a->type) == TYPE_SATURATING (b->type);

    case OFFSET_TYPE:
      return TYPE_OFFSET_BASETYPE (a->type) == TYPE_OFFSET_BASETYPE (b->type);

    case METHOD_TYPE:
      if (TYPE_METHOD_BASETYPE (a->type) == TYPE_METHOD_BASETYPE (b->type)
	  && (TYPE_ARG_TYPES (a->type) == TYPE_ARG_TYPES (b->type)
	      || (TYPE_ARG_TYPES (a->type)
		  && TREE_CODE (TYPE_ARG_TYPES (a->type)) == TREE_LIST
		  && TYPE_ARG_TYPES (b->type)
		  && TREE_CODE (TYPE_ARG_TYPES (b->type)) == TREE_LIST
		  && type_list_equal (TYPE_ARG_TYPES (a->type),
				      TYPE_ARG_TYPES (b->type)))))
        break;
      return 0;
    case ARRAY_TYPE:
      /* Don't compare TYPE_TYPELESS_STORAGE flag on aggregates,
	 where the flag should be inherited from the element type
	 and can change after ARRAY_TYPEs are created; on non-aggregates
	 compare it and hash it, scalars will never have that flag set
	 and we need to differentiate between arrays created by different
	 front-ends or middle-end created arrays.  */
      return (TYPE_DOMAIN (a->type) == TYPE_DOMAIN (b->type)
	      && (AGGREGATE_TYPE_P (TREE_TYPE (a->type))
		  || (TYPE_TYPELESS_STORAGE (a->type)
		      == TYPE_TYPELESS_STORAGE (b->type))));

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      return (TYPE_FIELDS (a->type) == TYPE_FIELDS (b->type)
	      || (TYPE_FIELDS (a->type)
		  && TREE_CODE (TYPE_FIELDS (a->type)) == TREE_LIST
		  && TYPE_FIELDS (b->type)
		  && TREE_CODE (TYPE_FIELDS (b->type)) == TREE_LIST
		  && type_list_equal (TYPE_FIELDS (a->type),
				      TYPE_FIELDS (b->type))));

    case FUNCTION_TYPE:
      if (TYPE_ARG_TYPES (a->type) == TYPE_ARG_TYPES (b->type)
	  || (TYPE_ARG_TYPES (a->type)
	      && TREE_CODE (TYPE_ARG_TYPES (a->type)) == TREE_LIST
	      && TYPE_ARG_TYPES (b->type)
	      && TREE_CODE (TYPE_ARG_TYPES (b->type)) == TREE_LIST
	      && type_list_equal (TYPE_ARG_TYPES (a->type),
				  TYPE_ARG_TYPES (b->type))))
	break;
      return 0;

    default:
      return 0;
    }

  if (lang_hooks.types.type_hash_eq != NULL)
    return lang_hooks.types.type_hash_eq (a->type, b->type);

  return 1;
}

/* Given TYPE, and HASHCODE its hash code, return the canonical
   object for an identical type if one already exists.
   Otherwise, return TYPE, and record it as the canonical object.

   To use this function, first create a type of the sort you want.
   Then compute its hash code from the fields of the type that
   make it different from other similar types.
   Then call this function and use the value.  */

tree
type_hash_canon (unsigned int hashcode, tree type)
{
  type_hash in;
  type_hash **loc;

  /* The hash table only contains main variants, so ensure that's what we're
     being passed.  */
  gcc_assert (TYPE_MAIN_VARIANT (type) == type);

  /* The TYPE_ALIGN field of a type is set by layout_type(), so we
     must call that routine before comparing TYPE_ALIGNs.  */
  layout_type (type);

  in.hash = hashcode;
  in.type = type;

  loc = type_hash_table->find_slot_with_hash (&in, hashcode, INSERT);
  if (*loc)
    {
      tree t1 = ((type_hash *) *loc)->type;
      gcc_assert (TYPE_MAIN_VARIANT (t1) == t1
		  && t1 != type);
      if (TYPE_UID (type) + 1 == next_type_uid)
	--next_type_uid;
      /* Free also min/max values and the cache for integer
	 types.  This can't be done in free_node, as LTO frees
	 those on its own.  */
      if (TREE_CODE (type) == INTEGER_TYPE)
	{
	  if (TYPE_MIN_VALUE (type)
	      && TREE_TYPE (TYPE_MIN_VALUE (type)) == type)
	    {
	      /* Zero is always in TYPE_CACHED_VALUES.  */
	      if (! TYPE_UNSIGNED (type))
		int_cst_hash_table->remove_elt (TYPE_MIN_VALUE (type));
	      ggc_free (TYPE_MIN_VALUE (type));
	    }
	  if (TYPE_MAX_VALUE (type)
	      && TREE_TYPE (TYPE_MAX_VALUE (type)) == type)
	    {
	      int_cst_hash_table->remove_elt (TYPE_MAX_VALUE (type));
	      ggc_free (TYPE_MAX_VALUE (type));
	    }
	  if (TYPE_CACHED_VALUES_P (type))
	    ggc_free (TYPE_CACHED_VALUES (type));
	}
      free_node (type);
      return t1;
    }
  else
    {
      struct type_hash *h;

      h = ggc_alloc<type_hash> ();
      h->hash = hashcode;
      h->type = type;
      *loc = h;

      return type;
    }
}

static void
print_type_hash_statistics (void)
{
  fprintf (stderr, "Type hash: size %ld, %ld elements, %f collisions\n",
	   (long) type_hash_table->size (),
	   (long) type_hash_table->elements (),
	   type_hash_table->collisions ());
}

/* Given two lists of types
   (chains of TREE_LIST nodes with types in the TREE_VALUE slots)
   return 1 if the lists contain the same types in the same order.
   Also, the TREE_PURPOSEs must match.  */

bool
type_list_equal (const_tree l1, const_tree l2)
{
  const_tree t1, t2;

  for (t1 = l1, t2 = l2; t1 && t2; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
    if (TREE_VALUE (t1) != TREE_VALUE (t2)
	|| (TREE_PURPOSE (t1) != TREE_PURPOSE (t2)
	    && ! (1 == simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))
		  && (TREE_TYPE (TREE_PURPOSE (t1))
		      == TREE_TYPE (TREE_PURPOSE (t2))))))
      return false;

  return t1 == t2;
}

/* Returns the number of arguments to the FUNCTION_TYPE or METHOD_TYPE
   given by TYPE.  If the argument list accepts variable arguments,
   then this function counts only the ordinary arguments.  */

int
type_num_arguments (const_tree fntype)
{
  int i = 0;

  for (tree t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
    /* If the function does not take a variable number of arguments,
       the last element in the list will have type `void'.  */
    if (VOID_TYPE_P (TREE_VALUE (t)))
      break;
    else
      ++i;

  return i;
}

/* Return the type of the function TYPE's argument ARGNO if known.
   For vararg function's where ARGNO refers to one of the variadic
   arguments return null.  Otherwise, return a void_type_node for
   out-of-bounds ARGNO.  */

tree
type_argument_type (const_tree fntype, unsigned argno)
{
  /* Treat zero the same as an out-of-bounds argument number.  */
  if (!argno)
    return void_type_node;

  function_args_iterator iter;

  tree argtype;
  unsigned i = 1;
  FOREACH_FUNCTION_ARGS (fntype, argtype, iter)
    {
      /* A vararg function's argument list ends in a null.  Otherwise,
	 an ordinary function's argument list ends with void.  Return
	 null if ARGNO refers to a vararg argument, void_type_node if
	 it's out of bounds, and the formal argument type otherwise.  */
      if (!argtype)
	break;

      if (i == argno || VOID_TYPE_P (argtype))
	return argtype;

      ++i;
    }

  return NULL_TREE;
}

/* Nonzero if integer constants T1 and T2
   represent the same constant value.  */

int
tree_int_cst_equal (const_tree t1, const_tree t2)
{
  if (t1 == t2)
    return 1;

  if (t1 == 0 || t2 == 0)
    return 0;

  if (TREE_CODE (t1) == INTEGER_CST
      && TREE_CODE (t2) == INTEGER_CST
      && wi::to_widest (t1) == wi::to_widest (t2))
    return 1;

  return 0;
}

/* Return true if T is an INTEGER_CST whose numerical value (extended
   according to TYPE_UNSIGNED) fits in a signed HOST_WIDE_INT.  */

bool
tree_fits_shwi_p (const_tree t)
{
  return (t != NULL_TREE
	  && TREE_CODE (t) == INTEGER_CST
	  && wi::fits_shwi_p (wi::to_widest (t)));
}

/* Return true if T is an INTEGER_CST or POLY_INT_CST whose numerical
   value (extended according to TYPE_UNSIGNED) fits in a poly_int64.  */

bool
tree_fits_poly_int64_p (const_tree t)
{
  if (t == NULL_TREE)
    return false;
  if (POLY_INT_CST_P (t))
    {
      for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; i++)
	if (!wi::fits_shwi_p (wi::to_wide (POLY_INT_CST_COEFF (t, i))))
	  return false;
      return true;
    }
  return (TREE_CODE (t) == INTEGER_CST
	  && wi::fits_shwi_p (wi::to_widest (t)));
}

/* Return true if T is an INTEGER_CST whose numerical value (extended
   according to TYPE_UNSIGNED) fits in an unsigned HOST_WIDE_INT.  */

bool
tree_fits_uhwi_p (const_tree t)
{
  return (t != NULL_TREE
	  && TREE_CODE (t) == INTEGER_CST
	  && wi::fits_uhwi_p (wi::to_widest (t)));
}

/* Return true if T is an INTEGER_CST or POLY_INT_CST whose numerical
   value (extended according to TYPE_UNSIGNED) fits in a poly_uint64.  */

bool
tree_fits_poly_uint64_p (const_tree t)
{
  if (t == NULL_TREE)
    return false;
  if (POLY_INT_CST_P (t))
    {
      for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; i++)
	if (!wi::fits_uhwi_p (wi::to_widest (POLY_INT_CST_COEFF (t, i))))
	  return false;
      return true;
    }
  return (TREE_CODE (t) == INTEGER_CST
	  && wi::fits_uhwi_p (wi::to_widest (t)));
}

/* T is an INTEGER_CST whose numerical value (extended according to
   TYPE_UNSIGNED) fits in a signed HOST_WIDE_INT.  Return that
   HOST_WIDE_INT.  */

HOST_WIDE_INT
tree_to_shwi (const_tree t)
{
  gcc_assert (tree_fits_shwi_p (t));
  return TREE_INT_CST_LOW (t);
}

/* T is an INTEGER_CST whose numerical value (extended according to
   TYPE_UNSIGNED) fits in an unsigned HOST_WIDE_INT.  Return that
   HOST_WIDE_INT.  */

unsigned HOST_WIDE_INT
tree_to_uhwi (const_tree t)
{
  gcc_assert (tree_fits_uhwi_p (t));
  return TREE_INT_CST_LOW (t);
}

/* Return the most significant (sign) bit of T.  */

int
tree_int_cst_sign_bit (const_tree t)
{
  unsigned bitno = TYPE_PRECISION (TREE_TYPE (t)) - 1;

  return wi::extract_uhwi (wi::to_wide (t), bitno, 1);
}

/* Return an indication of the sign of the integer constant T.
   The return value is -1 if T < 0, 0 if T == 0, and 1 if T > 0.
   Note that -1 will never be returned if T's type is unsigned.  */

int
tree_int_cst_sgn (const_tree t)
{
  if (wi::to_wide (t) == 0)
    return 0;
  else if (TYPE_UNSIGNED (TREE_TYPE (t)))
    return 1;
  else if (wi::neg_p (wi::to_wide (t)))
    return -1;
  else
    return 1;
}

/* Return the minimum number of bits needed to represent VALUE in a
   signed or unsigned type, UNSIGNEDP says which.  */

unsigned int
tree_int_cst_min_precision (tree value, signop sgn)
{
  /* If the value is negative, compute its negative minus 1.  The latter
     adjustment is because the absolute value of the largest negative value
     is one larger than the largest positive value.  This is equivalent to
     a bit-wise negation, so use that operation instead.  */

  if (tree_int_cst_sgn (value) < 0)
    value = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (value), value);

  /* Return the number of bits needed, taking into account the fact
     that we need one more bit for a signed than unsigned type.
     If value is 0 or -1, the minimum precision is 1 no matter
     whether unsignedp is true or false.  */

  if (integer_zerop (value))
    return 1;
  else
    return tree_floor_log2 (value) + 1 + (sgn == SIGNED ? 1 : 0) ;
}

/* Return truthvalue of whether T1 is the same tree structure as T2.
   Return 1 if they are the same.
   Return 0 if they are understandably different.
   Return -1 if either contains tree structure not understood by
   this function.  */

int
simple_cst_equal (const_tree t1, const_tree t2)
{
  enum tree_code code1, code2;
  int cmp;
  int i;

  if (t1 == t2)
    return 1;
  if (t1 == 0 || t2 == 0)
    return 0;

  code1 = TREE_CODE (t1);
  code2 = TREE_CODE (t2);

  if (CONVERT_EXPR_CODE_P (code1) || code1 == NON_LVALUE_EXPR)
    {
      if (CONVERT_EXPR_CODE_P (code2)
	  || code2 == NON_LVALUE_EXPR)
	return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
      else
	return simple_cst_equal (TREE_OPERAND (t1, 0), t2);
    }

  else if (CONVERT_EXPR_CODE_P (code2)
	   || code2 == NON_LVALUE_EXPR)
    return simple_cst_equal (t1, TREE_OPERAND (t2, 0));

  if (code1 != code2)
    return 0;

  switch (code1)
    {
    case INTEGER_CST:
      return wi::to_widest (t1) == wi::to_widest (t2);

    case REAL_CST:
      return real_identical (&TREE_REAL_CST (t1), &TREE_REAL_CST (t2));

    case FIXED_CST:
      return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1), TREE_FIXED_CST (t2));

    case STRING_CST:
      return (TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
	      && ! memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
			 TREE_STRING_LENGTH (t1)));

    case CONSTRUCTOR:
      {
	unsigned HOST_WIDE_INT idx;
	vec<constructor_elt, va_gc> *v1 = CONSTRUCTOR_ELTS (t1);
	vec<constructor_elt, va_gc> *v2 = CONSTRUCTOR_ELTS (t2);

	if (vec_safe_length (v1) != vec_safe_length (v2))
	  return false;

        for (idx = 0; idx < vec_safe_length (v1); ++idx)
	  /* ??? Should we handle also fields here? */
	  if (!simple_cst_equal ((*v1)[idx].value, (*v2)[idx].value))
	    return false;
	return true;
      }

    case SAVE_EXPR:
      return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));

    case CALL_EXPR:
      cmp = simple_cst_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2));
      if (cmp <= 0)
	return cmp;
      if (call_expr_nargs (t1) != call_expr_nargs (t2))
	return 0;
      {
	const_tree arg1, arg2;
	const_call_expr_arg_iterator iter1, iter2;
	for (arg1 = first_const_call_expr_arg (t1, &iter1),
	       arg2 = first_const_call_expr_arg (t2, &iter2);
	     arg1 && arg2;
	     arg1 = next_const_call_expr_arg (&iter1),
	       arg2 = next_const_call_expr_arg (&iter2))
	  {
	    cmp = simple_cst_equal (arg1, arg2);
	    if (cmp <= 0)
	      return cmp;
	  }
	return arg1 == arg2;
      }

    case TARGET_EXPR:
      /* Special case: if either target is an unallocated VAR_DECL,
	 it means that it's going to be unified with whatever the
	 TARGET_EXPR is really supposed to initialize, so treat it
	 as being equivalent to anything.  */
      if ((TREE_CODE (TREE_OPERAND (t1, 0)) == VAR_DECL
	   && DECL_NAME (TREE_OPERAND (t1, 0)) == NULL_TREE
	   && !DECL_RTL_SET_P (TREE_OPERAND (t1, 0)))
	  || (TREE_CODE (TREE_OPERAND (t2, 0)) == VAR_DECL
	      && DECL_NAME (TREE_OPERAND (t2, 0)) == NULL_TREE
	      && !DECL_RTL_SET_P (TREE_OPERAND (t2, 0))))
	cmp = 1;
      else
	cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));

      if (cmp <= 0)
	return cmp;

      return simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));

    case WITH_CLEANUP_EXPR:
      cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
      if (cmp <= 0)
	return cmp;

      return simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t1, 1));

    case COMPONENT_REF:
      if (TREE_OPERAND (t1, 1) == TREE_OPERAND (t2, 1))
	return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));

      return 0;

    case VAR_DECL:
    case PARM_DECL:
    case CONST_DECL:
    case FUNCTION_DECL:
      return 0;

    default:
      if (POLY_INT_CST_P (t1))
	/* A false return means maybe_ne rather than known_ne.  */
	return known_eq (poly_widest_int::from (poly_int_cst_value (t1),
						TYPE_SIGN (TREE_TYPE (t1))),
			 poly_widest_int::from (poly_int_cst_value (t2),
						TYPE_SIGN (TREE_TYPE (t2))));
      break;
    }

  /* This general rule works for most tree codes.  All exceptions should be
     handled above.  If this is a language-specific tree code, we can't
     trust what might be in the operand, so say we don't know
     the situation.  */
  if ((int) code1 >= (int) LAST_AND_UNUSED_TREE_CODE)
    return -1;

  switch (TREE_CODE_CLASS (code1))
    {
    case tcc_unary:
    case tcc_binary:
    case tcc_comparison:
    case tcc_expression:
    case tcc_reference:
    case tcc_statement:
      cmp = 1;
      for (i = 0; i < TREE_CODE_LENGTH (code1); i++)
	{
	  cmp = simple_cst_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i));
	  if (cmp <= 0)
	    return cmp;
	}

      return cmp;

    default:
      return -1;
    }
}

/* Compare the value of T, an INTEGER_CST, with U, an unsigned integer value.
   Return -1, 0, or 1 if the value of T is less than, equal to, or greater
   than U, respectively.  */

int
compare_tree_int (const_tree t, unsigned HOST_WIDE_INT u)
{
  if (tree_int_cst_sgn (t) < 0)
    return -1;
  else if (!tree_fits_uhwi_p (t))
    return 1;
  else if (TREE_INT_CST_LOW (t) == u)
    return 0;
  else if (TREE_INT_CST_LOW (t) < u)
    return -1;
  else
    return 1;
}

/* Return true if SIZE represents a constant size that is in bounds of
   what the middle-end and the backend accepts (covering not more than
   half of the address-space).  */

bool
valid_constant_size_p (const_tree size)
{
  if (POLY_INT_CST_P (size))
    {
      if (TREE_OVERFLOW (size))
	return false;
      for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
	if (!valid_constant_size_p (POLY_INT_CST_COEFF (size, i)))
	  return false;
      return true;
    }
  if (! tree_fits_uhwi_p (size)
      || TREE_OVERFLOW (size)
      || tree_int_cst_sign_bit (size) != 0)
    return false;
  return true;
}

/* Return the precision of the type, or for a complex or vector type the
   precision of the type of its elements.  */

unsigned int
element_precision (const_tree type)
{
  if (!TYPE_P (type))
    type = TREE_TYPE (type);
  enum tree_code code = TREE_CODE (type);
  if (code == COMPLEX_TYPE || code == VECTOR_TYPE)
    type = TREE_TYPE (type);

  return TYPE_PRECISION (type);
}

/* Return true if CODE represents an associative tree code.  Otherwise
   return false.  */
bool
associative_tree_code (enum tree_code code)
{
  switch (code)
    {
    case BIT_IOR_EXPR:
    case BIT_AND_EXPR:
    case BIT_XOR_EXPR:
    case PLUS_EXPR:
    case MULT_EXPR:
    case MIN_EXPR:
    case MAX_EXPR:
      return true;

    default:
      break;
    }
  return false;
}

/* Return true if CODE represents a commutative tree code.  Otherwise
   return false.  */
bool
commutative_tree_code (enum tree_code code)
{
  switch (code)
    {
    case PLUS_EXPR:
    case MULT_EXPR:
    case MULT_HIGHPART_EXPR:
    case MIN_EXPR:
    case MAX_EXPR:
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
    case BIT_AND_EXPR:
    case NE_EXPR:
    case EQ_EXPR:
    case UNORDERED_EXPR:
    case ORDERED_EXPR:
    case UNEQ_EXPR:
    case LTGT_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_XOR_EXPR:
    case TRUTH_OR_EXPR:
    case WIDEN_MULT_EXPR:
    case VEC_WIDEN_MULT_HI_EXPR:
    case VEC_WIDEN_MULT_LO_EXPR:
    case VEC_WIDEN_MULT_EVEN_EXPR:
    case VEC_WIDEN_MULT_ODD_EXPR:
      return true;

    default:
      break;
    }
  return false;
}

/* Return true if CODE represents a ternary tree code for which the
   first two operands are commutative.  Otherwise return false.  */
bool
commutative_ternary_tree_code (enum tree_code code)
{
  switch (code)
    {
    case WIDEN_MULT_PLUS_EXPR:
    case WIDEN_MULT_MINUS_EXPR:
    case DOT_PROD_EXPR:
      return true;

    default:
      break;
    }
  return false;
}

/* Returns true if CODE can overflow.  */

bool
operation_can_overflow (enum tree_code code)
{
  switch (code)
    {
    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
    case LSHIFT_EXPR:
      /* Can overflow in various ways.  */
      return true;
    case TRUNC_DIV_EXPR:
    case EXACT_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case CEIL_DIV_EXPR:
      /* For INT_MIN / -1.  */
      return true;
    case NEGATE_EXPR:
    case ABS_EXPR:
      /* For -INT_MIN.  */
      return true;
    default:
      /* These operators cannot overflow.  */
      return false;
    }
}

/* Returns true if CODE operating on operands of type TYPE doesn't overflow, or
   ftrapv doesn't generate trapping insns for CODE.  */

bool
operation_no_trapping_overflow (tree type, enum tree_code code)
{
  gcc_checking_assert (ANY_INTEGRAL_TYPE_P (type));

  /* We don't generate instructions that trap on overflow for complex or vector
     types.  */
  if (!INTEGRAL_TYPE_P (type))
    return true;

  if (!TYPE_OVERFLOW_TRAPS (type))
    return true;

  switch (code)
    {
    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
    case NEGATE_EXPR:
    case ABS_EXPR:
      /* These operators can overflow, and -ftrapv generates trapping code for
	 these.  */
      return false;
    case TRUNC_DIV_EXPR:
    case EXACT_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case LSHIFT_EXPR:
      /* These operators can overflow, but -ftrapv does not generate trapping
	 code for these.  */
      return true;
    default:
      /* These operators cannot overflow.  */
      return true;
    }
}

namespace inchash
{

/* Generate a hash value for an expression.  This can be used iteratively
   by passing a previous result as the HSTATE argument.

   This function is intended to produce the same hash for expressions which
   would compare equal using operand_equal_p.  */
void
add_expr (const_tree t, inchash::hash &hstate, unsigned int flags)
{
  int i;
  enum tree_code code;
  enum tree_code_class tclass;

  if (t == NULL_TREE || t == error_mark_node)
    {
      hstate.merge_hash (0);
      return;
    }

  if (!(flags & OEP_ADDRESS_OF))
    STRIP_NOPS (t);

  code = TREE_CODE (t);

  switch (code)
    {
    /* Alas, constants aren't shared, so we can't rely on pointer
       identity.  */
    case VOID_CST:
      hstate.merge_hash (0);
      return;
    case INTEGER_CST:
      gcc_checking_assert (!(flags & OEP_ADDRESS_OF));
      for (i = 0; i < TREE_INT_CST_EXT_NUNITS (t); i++)
	hstate.add_hwi (TREE_INT_CST_ELT (t, i));
      return;
    case REAL_CST:
      {
	unsigned int val2;
	if (!HONOR_SIGNED_ZEROS (t) && real_zerop (t))
	  val2 = rvc_zero;
	else
	  val2 = real_hash (TREE_REAL_CST_PTR (t));
	hstate.merge_hash (val2);
	return;
      }
    case FIXED_CST:
      {
	unsigned int val2 = fixed_hash (TREE_FIXED_CST_PTR (t));
	hstate.merge_hash (val2);
	return;
      }
    case STRING_CST:
      hstate.add ((const void *) TREE_STRING_POINTER (t),
		  TREE_STRING_LENGTH (t));
      return;
    case COMPLEX_CST:
      inchash::add_expr (TREE_REALPART (t), hstate, flags);
      inchash::add_expr (TREE_IMAGPART (t), hstate, flags);
      return;
    case VECTOR_CST:
      {
	hstate.add_int (VECTOR_CST_NPATTERNS (t));
	hstate.add_int (VECTOR_CST_NELTS_PER_PATTERN (t));
	unsigned int count = vector_cst_encoded_nelts (t);
	for (unsigned int i = 0; i < count; ++i)
	  inchash::add_expr (VECTOR_CST_ENCODED_ELT (t, i), hstate, flags);
	return;
      }
    case SSA_NAME:
      /* We can just compare by pointer.  */
      hstate.add_hwi (SSA_NAME_VERSION (t));
      return;
    case PLACEHOLDER_EXPR:
      /* The node itself doesn't matter.  */
      return;
    case BLOCK:
    case OMP_CLAUSE:
      /* Ignore.  */
      return;
    case TREE_LIST:
      /* A list of expressions, for a CALL_EXPR or as the elements of a
	 VECTOR_CST.  */
      for (; t; t = TREE_CHAIN (t))
	inchash::add_expr (TREE_VALUE (t), hstate, flags);
      return;
    case CONSTRUCTOR:
      {
	unsigned HOST_WIDE_INT idx;
	tree field, value;
	flags &= ~OEP_ADDRESS_OF;
	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), idx, field, value)
	  {
	    inchash::add_expr (field, hstate, flags);
	    inchash::add_expr (value, hstate, flags);
	  }
	return;
      }
    case STATEMENT_LIST:
      {
	tree_stmt_iterator i;
	for (i = tsi_start (CONST_CAST_TREE (t));
	     !tsi_end_p (i); tsi_next (&i))
	  inchash::add_expr (tsi_stmt (i), hstate, flags);
	return;
      }
    case TREE_VEC:
      for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
	inchash::add_expr (TREE_VEC_ELT (t, i), hstate, flags);
      return;
    case IDENTIFIER_NODE:
      hstate.add_object (IDENTIFIER_HASH_VALUE (t));
      return;
    case FUNCTION_DECL:
      /* When referring to a built-in FUNCTION_DECL, use the __builtin__ form.
	 Otherwise nodes that compare equal according to operand_equal_p might
	 get different hash codes.  However, don't do this for machine specific
	 or front end builtins, since the function code is overloaded in those
	 cases.  */
      if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
	  && builtin_decl_explicit_p (DECL_FUNCTION_CODE (t)))
	{
	  t = builtin_decl_explicit (DECL_FUNCTION_CODE (t));
	  code = TREE_CODE (t);
	}
      /* FALL THROUGH */
    default:
      if (POLY_INT_CST_P (t))
	{
	  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
	    hstate.add_wide_int (wi::to_wide (POLY_INT_CST_COEFF (t, i)));
	  return;
	}
      tclass = TREE_CODE_CLASS (code);

      if (tclass == tcc_declaration)
	{
	  /* DECL's have a unique ID */
	  hstate.add_hwi (DECL_UID (t));
	}
      else if (tclass == tcc_comparison && !commutative_tree_code (code))
	{
	  /* For comparisons that can be swapped, use the lower
	     tree code.  */
	  enum tree_code ccode = swap_tree_comparison (code);
	  if (code < ccode)
	    ccode = code;
	  hstate.add_object (ccode);
	  inchash::add_expr (TREE_OPERAND (t, ccode != code), hstate, flags);
	  inchash::add_expr (TREE_OPERAND (t, ccode == code), hstate, flags);
	}
      else if (CONVERT_EXPR_CODE_P (code))
	{
	  /* NOP_EXPR and CONVERT_EXPR are considered equal by
	     operand_equal_p.  */
	  enum tree_code ccode = NOP_EXPR;
	  hstate.add_object (ccode);

	  /* Don't hash the type, that can lead to having nodes which
	     compare equal according to operand_equal_p, but which
	     have different hash codes.  Make sure to include signedness
	     in the hash computation.  */
	  hstate.add_int (TYPE_UNSIGNED (TREE_TYPE (t)));
	  inchash::add_expr (TREE_OPERAND (t, 0), hstate, flags);
	}
      /* For OEP_ADDRESS_OF, hash MEM_EXPR[&decl, 0] the same as decl.  */
      else if (code == MEM_REF
	       && (flags & OEP_ADDRESS_OF) != 0
	       && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
	       && DECL_P (TREE_OPERAND (TREE_OPERAND (t, 0), 0))
	       && integer_zerop (TREE_OPERAND (t, 1)))
	inchash::add_expr (TREE_OPERAND (TREE_OPERAND (t, 0), 0),
			   hstate, flags);
      /* Don't ICE on FE specific trees, or their arguments etc.
	 during operand_equal_p hash verification.  */
      else if (!IS_EXPR_CODE_CLASS (tclass))
	gcc_assert (flags & OEP_HASH_CHECK);
      else
	{
	  unsigned int sflags = flags;

	  hstate.add_object (code);

	  switch (code)
	    {
	    case ADDR_EXPR:
	      gcc_checking_assert (!(flags & OEP_ADDRESS_OF));
	      flags |= OEP_ADDRESS_OF;
	      sflags = flags;
	      break;

	    case INDIRECT_REF:
	    case MEM_REF:
	    case TARGET_MEM_REF:
	      flags &= ~OEP_ADDRESS_OF;
	      sflags = flags;
	      break;

	    case ARRAY_REF:
	    case ARRAY_RANGE_REF:
	    case COMPONENT_REF:
	    case BIT_FIELD_REF:
	      sflags &= ~OEP_ADDRESS_OF;
	      break;

	    case COND_EXPR:
	      flags &= ~OEP_ADDRESS_OF;
	      break;

	    case WIDEN_MULT_PLUS_EXPR:
	    case WIDEN_MULT_MINUS_EXPR:
	      {
		/* The multiplication operands are commutative.  */
		inchash::hash one, two;
		inchash::add_expr (TREE_OPERAND (t, 0), one, flags);
		inchash::add_expr (TREE_OPERAND (t, 1), two, flags);
		hstate.add_commutative (one, two);
		inchash::add_expr (TREE_OPERAND (t, 2), two, flags);
		return;
	      }

	    case CALL_EXPR:
	      if (CALL_EXPR_FN (t) == NULL_TREE)
		hstate.add_int (CALL_EXPR_IFN (t));
	      break;

	    case TARGET_EXPR:
	      /* For TARGET_EXPR, just hash on the TARGET_EXPR_SLOT.
		 Usually different TARGET_EXPRs just should use
		 different temporaries in their slots.  */
	      inchash::add_expr (TARGET_EXPR_SLOT (t), hstate, flags);
	      return;

	    default:
	      break;
	    }

	  /* Don't hash the type, that can lead to having nodes which
	     compare equal according to operand_equal_p, but which
	     have different hash codes.  */
	  if (code == NON_LVALUE_EXPR)
	    {
	      /* Make sure to include signness in the hash computation.  */
	      hstate.add_int (TYPE_UNSIGNED (TREE_TYPE (t)));
	      inchash::add_expr (TREE_OPERAND (t, 0), hstate, flags);
	    }

	  else if (commutative_tree_code (code))
	    {
	      /* It's a commutative expression.  We want to hash it the same
		 however it appears.  We do this by first hashing both operands
		 and then rehashing based on the order of their independent
		 hashes.  */
	      inchash::hash one, two;
	      inchash::add_expr (TREE_OPERAND (t, 0), one, flags);
	      inchash::add_expr (TREE_OPERAND (t, 1), two, flags);
	      hstate.add_commutative (one, two);
	    }
	  else
	    for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
	      inchash::add_expr (TREE_OPERAND (t, i), hstate,
				 i == 0 ? flags : sflags);
	}
      return;
    }
}

}

/* Constructors for pointer, array and function types.
   (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are
   constructed by language-dependent code, not here.)  */

/* Construct, lay out and return the type of pointers to TO_TYPE with
   mode MODE.  If CAN_ALIAS_ALL is TRUE, indicate this type can
   reference all of memory. If such a type has already been
   constructed, reuse it.  */

tree
build_pointer_type_for_mode (tree to_type, machine_mode mode,
			     bool can_alias_all)
{
  tree t;
  bool could_alias = can_alias_all;

  if (to_type == error_mark_node)
    return error_mark_node;

  /* If the pointed-to type has the may_alias attribute set, force
     a TYPE_REF_CAN_ALIAS_ALL pointer to be generated.  */
  if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type)))
    can_alias_all = true;

  /* In some cases, languages will have things that aren't a POINTER_TYPE
     (such as a RECORD_TYPE for fat pointers in Ada) as TYPE_POINTER_TO.
     In that case, return that type without regard to the rest of our
     operands.

     ??? This is a kludge, but consistent with the way this function has
     always operated and there doesn't seem to be a good way to avoid this
     at the moment.  */
  if (TYPE_POINTER_TO (to_type) != 0
      && TREE_CODE (TYPE_POINTER_TO (to_type)) != POINTER_TYPE)
    return TYPE_POINTER_TO (to_type);

  /* First, if we already have a type for pointers to TO_TYPE and it's
     the proper mode, use it.  */
  for (t = TYPE_POINTER_TO (to_type); t; t = TYPE_NEXT_PTR_TO (t))
    if (TYPE_MODE (t) == mode && TYPE_REF_CAN_ALIAS_ALL (t) == can_alias_all)
      return t;

  t = make_node (POINTER_TYPE);

  TREE_TYPE (t) = to_type;
  SET_TYPE_MODE (t, mode);
  TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
  TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (to_type);
  TYPE_POINTER_TO (to_type) = t;

  /* During LTO we do not set TYPE_CANONICAL of pointers and references.  */
  if (TYPE_STRUCTURAL_EQUALITY_P (to_type) || in_lto_p)
    SET_TYPE_STRUCTURAL_EQUALITY (t);
  else if (TYPE_CANONICAL (to_type) != to_type || could_alias)
    TYPE_CANONICAL (t)
      = build_pointer_type_for_mode (TYPE_CANONICAL (to_type),
				     mode, false);

  /* Lay out the type.  This function has many callers that are concerned
     with expression-construction, and this simplifies them all.  */
  layout_type (t);

  return t;
}

/* By default build pointers in ptr_mode.  */

tree
build_pointer_type (tree to_type)
{
  addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
					      : TYPE_ADDR_SPACE (to_type);
  machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
  return build_pointer_type_for_mode (to_type, pointer_mode, false);
}

/* Same as build_pointer_type_for_mode, but for REFERENCE_TYPE.  */

tree
build_reference_type_for_mode (tree to_type, machine_mode mode,
			       bool can_alias_all)
{
  tree t;
  bool could_alias = can_alias_all;

  if (to_type == error_mark_node)
    return error_mark_node;

  /* If the pointed-to type has the may_alias attribute set, force
     a TYPE_REF_CAN_ALIAS_ALL pointer to be generated.  */
  if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type)))
    can_alias_all = true;

  /* In some cases, languages will have things that aren't a REFERENCE_TYPE
     (such as a RECORD_TYPE for fat pointers in Ada) as TYPE_REFERENCE_TO.
     In that case, return that type without regard to the rest of our
     operands.

     ??? This is a kludge, but consistent with the way this function has
     always operated and there doesn't seem to be a good way to avoid this
     at the moment.  */
  if (TYPE_REFERENCE_TO (to_type) != 0
      && TREE_CODE (TYPE_REFERENCE_TO (to_type)) != REFERENCE_TYPE)
    return TYPE_REFERENCE_TO (to_type);

  /* First, if we already have a type for pointers to TO_TYPE and it's
     the proper mode, use it.  */
  for (t = TYPE_REFERENCE_TO (to_type); t; t = TYPE_NEXT_REF_TO (t))
    if (TYPE_MODE (t) == mode && TYPE_REF_CAN_ALIAS_ALL (t) == can_alias_all)
      return t;

  t = make_node (REFERENCE_TYPE);

  TREE_TYPE (t) = to_type;
  SET_TYPE_MODE (t, mode);
  TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
  TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (to_type);
  TYPE_REFERENCE_TO (to_type) = t;

  /* During LTO we do not set TYPE_CANONICAL of pointers and references.  */
  if (TYPE_STRUCTURAL_EQUALITY_P (to_type) || in_lto_p)
    SET_TYPE_STRUCTURAL_EQUALITY (t);
  else if (TYPE_CANONICAL (to_type) != to_type || could_alias)
    TYPE_CANONICAL (t)
      = build_reference_type_for_mode (TYPE_CANONICAL (to_type),
				       mode, false);

  layout_type (t);

  return t;
}


/* Build the node for the type of references-to-TO_TYPE by default
   in ptr_mode.  */

tree
build_reference_type (tree to_type)
{
  addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
					      : TYPE_ADDR_SPACE (to_type);
  machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
  return build_reference_type_for_mode (to_type, pointer_mode, false);
}

#define MAX_INT_CACHED_PREC \
  (HOST_BITS_PER_WIDE_INT > 64 ? HOST_BITS_PER_WIDE_INT : 64)
static GTY(()) tree nonstandard_integer_type_cache[2 * MAX_INT_CACHED_PREC + 2];

/* Builds a signed or unsigned integer type of precision PRECISION.
   Used for C bitfields whose precision does not match that of
   built-in target types.  */
tree
build_nonstandard_integer_type (unsigned HOST_WIDE_INT precision,
				int unsignedp)
{
  tree itype, ret;

  if (unsignedp)
    unsignedp = MAX_INT_CACHED_PREC + 1;
    
  if (precision <= MAX_INT_CACHED_PREC)
    {
      itype = nonstandard_integer_type_cache[precision + unsignedp];
      if (itype)
	return itype;
    }

  itype = make_node (INTEGER_TYPE);
  TYPE_PRECISION (itype) = precision;

  if (unsignedp)
    fixup_unsigned_type (itype);
  else
    fixup_signed_type (itype);

  ret = itype;

  inchash::hash hstate;
  inchash::add_expr (TYPE_MAX_VALUE (itype), hstate);
  ret = type_hash_canon (hstate.end (), itype);
  if (precision <= MAX_INT_CACHED_PREC)
    nonstandard_integer_type_cache[precision + unsignedp] = ret;

  return ret;
}

#define MAX_BOOL_CACHED_PREC \
  (HOST_BITS_PER_WIDE_INT > 64 ? HOST_BITS_PER_WIDE_INT : 64)
static GTY(()) tree nonstandard_boolean_type_cache[MAX_BOOL_CACHED_PREC + 1];

/* Builds a boolean type of precision PRECISION.
   Used for boolean vectors to choose proper vector element size.  */
tree
build_nonstandard_boolean_type (unsigned HOST_WIDE_INT precision)
{
  tree type;

  if (precision <= MAX_BOOL_CACHED_PREC)
    {
      type = nonstandard_boolean_type_cache[precision];
      if (type)
	return type;
    }

  type = make_node (BOOLEAN_TYPE);
  TYPE_PRECISION (type) = precision;
  fixup_signed_type (type);

  if (precision <= MAX_INT_CACHED_PREC)
    nonstandard_boolean_type_cache[precision] = type;

  return type;
}

/* Create a range of some discrete type TYPE (an INTEGER_TYPE, ENUMERAL_TYPE
   or BOOLEAN_TYPE) with low bound LOWVAL and high bound HIGHVAL.  If SHARED
   is true, reuse such a type that has already been constructed.  */

static tree
build_range_type_1 (tree type, tree lowval, tree highval, bool shared)
{
  tree itype = make_node (INTEGER_TYPE);

  TREE_TYPE (itype) = type;

  TYPE_MIN_VALUE (itype) = fold_convert (type, lowval);
  TYPE_MAX_VALUE (itype) = highval ? fold_convert (type, highval) : NULL;

  TYPE_PRECISION (itype) = TYPE_PRECISION (type);
  SET_TYPE_MODE (itype, TYPE_MODE (type));
  TYPE_SIZE (itype) = TYPE_SIZE (type);
  TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (type);
  SET_TYPE_ALIGN (itype, TYPE_ALIGN (type));
  TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (type);
  SET_TYPE_WARN_IF_NOT_ALIGN (itype, TYPE_WARN_IF_NOT_ALIGN (type));

  if (!shared)
    return itype;

  if ((TYPE_MIN_VALUE (itype)
       && TREE_CODE (TYPE_MIN_VALUE (itype)) != INTEGER_CST)
      || (TYPE_MAX_VALUE (itype)
	  && TREE_CODE (TYPE_MAX_VALUE (itype)) != INTEGER_CST))
    {
      /* Since we cannot reliably merge this type, we need to compare it using
	 structural equality checks.  */
      SET_TYPE_STRUCTURAL_EQUALITY (itype);
      return itype;
    }

  hashval_t hash = type_hash_canon_hash (itype);
  itype = type_hash_canon (hash, itype);

  return itype;
}

/* Wrapper around build_range_type_1 with SHARED set to true.  */

tree
build_range_type (tree type, tree lowval, tree highval)
{
  return build_range_type_1 (type, lowval, highval, true);
}

/* Wrapper around build_range_type_1 with SHARED set to false.  */

tree
build_nonshared_range_type (tree type, tree lowval, tree highval)
{
  return build_range_type_1 (type, lowval, highval, false);
}

/* Create a type of integers to be the TYPE_DOMAIN of an ARRAY_TYPE.
   MAXVAL should be the maximum value in the domain
   (one less than the length of the array).

   The maximum value that MAXVAL can have is INT_MAX for a HOST_WIDE_INT.
   We don't enforce this limit, that is up to caller (e.g. language front end).
   The limit exists because the result is a signed type and we don't handle
   sizes that use more than one HOST_WIDE_INT.  */

tree
build_index_type (tree maxval)
{
  return build_range_type (sizetype, size_zero_node, maxval);
}

/* Return true if the debug information for TYPE, a subtype, should be emitted
   as a subrange type.  If so, set LOWVAL to the low bound and HIGHVAL to the
   high bound, respectively.  Sometimes doing so unnecessarily obfuscates the
   debug info and doesn't reflect the source code.  */

bool
subrange_type_for_debug_p (const_tree type, tree *lowval, tree *highval)
{
  tree base_type = TREE_TYPE (type), low, high;

  /* Subrange types have a base type which is an integral type.  */
  if (!INTEGRAL_TYPE_P (base_type))
    return false;

  /* Get the real bounds of the subtype.  */
  if (lang_hooks.types.get_subrange_bounds)
    lang_hooks.types.get_subrange_bounds (type, &low, &high);
  else
    {
      low = TYPE_MIN_VALUE (type);
      high = TYPE_MAX_VALUE (type);
    }

  /* If the type and its base type have the same representation and the same
     name, then the type is not a subrange but a copy of the base type.  */
  if ((TREE_CODE (base_type) == INTEGER_TYPE
       || TREE_CODE (base_type) == BOOLEAN_TYPE)
      && int_size_in_bytes (type) == int_size_in_bytes (base_type)
      && tree_int_cst_equal (low, TYPE_MIN_VALUE (base_type))
      && tree_int_cst_equal (high, TYPE_MAX_VALUE (base_type))
      && TYPE_IDENTIFIER (type) == TYPE_IDENTIFIER (base_type))
    return false;

  if (lowval)
    *lowval = low;
  if (highval)
    *highval = high;
  return true;
}

/* Construct, lay out and return the type of arrays of elements with ELT_TYPE
   and number of elements specified by the range of values of INDEX_TYPE.
   If TYPELESS_STORAGE is true, TYPE_TYPELESS_STORAGE flag is set on the type.
   If SHARED is true, reuse such a type that has already been constructed.  */

static tree
build_array_type_1 (tree elt_type, tree index_type, bool typeless_storage,
		    bool shared)
{
  tree t;

  if (TREE_CODE (elt_type) == FUNCTION_TYPE)
    {
      error ("arrays of functions are not meaningful");
      elt_type = integer_type_node;
    }

  t = make_node (ARRAY_TYPE);
  TREE_TYPE (t) = elt_type;
  TYPE_DOMAIN (t) = index_type;
  TYPE_ADDR_SPACE (t) = TYPE_ADDR_SPACE (elt_type);
  TYPE_TYPELESS_STORAGE (t) = typeless_storage;
  layout_type (t);

  /* If the element type is incomplete at this point we get marked for
     structural equality.  Do not record these types in the canonical
     type hashtable.  */
  if (TYPE_STRUCTURAL_EQUALITY_P (t))
    return t;

  if (shared)
    {
      hashval_t hash = type_hash_canon_hash (t);
      t = type_hash_canon (hash, t);
    }

  if (TYPE_CANONICAL (t) == t)
    {
      if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
	  || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))
	  || in_lto_p)
	SET_TYPE_STRUCTURAL_EQUALITY (t);
      else if (TYPE_CANONICAL (elt_type) != elt_type
	       || (index_type && TYPE_CANONICAL (index_type) != index_type))
	TYPE_CANONICAL (t)
	  = build_array_type_1 (TYPE_CANONICAL (elt_type),
				index_type
				? TYPE_CANONICAL (index_type) : NULL_TREE,
				typeless_storage, shared);
    }

  return t;
}

/* Wrapper around build_array_type_1 with SHARED set to true.  */

tree
build_array_type (tree elt_type, tree index_type, bool typeless_storage)
{
  return build_array_type_1 (elt_type, index_type, typeless_storage, true);
}

/* Wrapper around build_array_type_1 with SHARED set to false.  */

tree
build_nonshared_array_type (tree elt_type, tree index_type)
{
  return build_array_type_1 (elt_type, index_type, false, false);
}

/* Return a representation of ELT_TYPE[NELTS], using indices of type
   sizetype.  */

tree
build_array_type_nelts (tree elt_type, poly_uint64 nelts)
{
  return build_array_type (elt_type, build_index_type (size_int (nelts - 1)));
}

/* Recursively examines the array elements of TYPE, until a non-array
   element type is found.  */

tree
strip_array_types (tree type)
{
  while (TREE_CODE (type) == ARRAY_TYPE)
    type = TREE_TYPE (type);

  return type;
}

/* Computes the canonical argument types from the argument type list
   ARGTYPES.

   Upon return, *ANY_STRUCTURAL_P will be true iff either it was true
   on entry to this function, or if any of the ARGTYPES are
   structural.

   Upon return, *ANY_NONCANONICAL_P will be true iff either it was
   true on entry to this function, or if any of the ARGTYPES are
   non-canonical.

   Returns a canonical argument list, which may be ARGTYPES when the
   canonical argument list is unneeded (i.e., *ANY_STRUCTURAL_P is
   true) or would not differ from ARGTYPES.  */

static tree
maybe_canonicalize_argtypes (tree argtypes,
			     bool *any_structural_p,
			     bool *any_noncanonical_p)
{
  tree arg;
  bool any_noncanonical_argtypes_p = false;

  for (arg = argtypes; arg && !(*any_structural_p); arg = TREE_CHAIN (arg))
    {
      if (!TREE_VALUE (arg) || TREE_VALUE (arg) == error_mark_node)
	/* Fail gracefully by stating that the type is structural.  */
	*any_structural_p = true;
      else if (TYPE_STRUCTURAL_EQUALITY_P (TREE_VALUE (arg)))
	*any_structural_p = true;
      else if (TYPE_CANONICAL (TREE_VALUE (arg)) != TREE_VALUE (arg)
	       || TREE_PURPOSE (arg))
	/* If the argument has a default argument, we consider it
	   non-canonical even though the type itself is canonical.
	   That way, different variants of function and method types
	   with default arguments will all point to the variant with
	   no defaults as their canonical type.  */
        any_noncanonical_argtypes_p = true;
    }

  if (*any_structural_p)
    return argtypes;

  if (any_noncanonical_argtypes_p)
    {
      /* Build the canonical list of argument types.  */
      tree canon_argtypes = NULL_TREE;
      bool is_void = false;

      for (arg = argtypes; arg; arg = TREE_CHAIN (arg))
        {
          if (arg == void_list_node)
            is_void = true;
          else
            canon_argtypes = tree_cons (NULL_TREE,
                                        TYPE_CANONICAL (TREE_VALUE (arg)),
                                        canon_argtypes);
        }

      canon_argtypes = nreverse (canon_argtypes);
      if (is_void)
        canon_argtypes = chainon (canon_argtypes, void_list_node);

      /* There is a non-canonical type.  */
      *any_noncanonical_p = true;
      return canon_argtypes;
    }

  /* The canonical argument types are the same as ARGTYPES.  */
  return argtypes;
}

/* Construct, lay out and return
   the type of functions returning type VALUE_TYPE
   given arguments of types ARG_TYPES.
   ARG_TYPES is a chain of TREE_LIST nodes whose TREE_VALUEs
   are data type nodes for the arguments of the function.
   If such a type has already been constructed, reuse it.  */

tree
build_function_type (tree value_type, tree arg_types)
{
  tree t;
  inchash::hash hstate;
  bool any_structural_p, any_noncanonical_p;
  tree canon_argtypes;

  if (TREE_CODE (value_type) == FUNCTION_TYPE)
    {
      error ("function return type cannot be function");
      value_type = integer_type_node;
    }

  /* Make a node of the sort we want.  */
  t = make_node (FUNCTION_TYPE);
  TREE_TYPE (t) = value_type;
  TYPE_ARG_TYPES (t) = arg_types;

  /* If we already have such a type, use the old one.  */
  hashval_t hash = type_hash_canon_hash (t);
  t = type_hash_canon (hash, t);

  /* Set up the canonical type. */
  any_structural_p   = TYPE_STRUCTURAL_EQUALITY_P (value_type);
  any_noncanonical_p = TYPE_CANONICAL (value_type) != value_type;
  canon_argtypes = maybe_canonicalize_argtypes (arg_types,
						&any_structural_p,
						&any_noncanonical_p);
  if (any_structural_p)
    SET_TYPE_STRUCTURAL_EQUALITY (t);
  else if (any_noncanonical_p)
    TYPE_CANONICAL (t) = build_function_type (TYPE_CANONICAL (value_type),
					      canon_argtypes);

  if (!COMPLETE_TYPE_P (t))
    layout_type (t);
  return t;
}

/* Build a function type.  The RETURN_TYPE is the type returned by the
   function.  If VAARGS is set, no void_type_node is appended to the
   list.  ARGP must be always be terminated be a NULL_TREE.  */

static tree
build_function_type_list_1 (bool vaargs, tree return_type, va_list argp)
{
  tree t, args, last;

  t = va_arg (argp, tree);
  for (args = NULL_TREE; t != NULL_TREE; t = va_arg (argp, tree))
    args = tree_cons (NULL_TREE, t, args);

  if (vaargs)
    {
      last = args;
      if (args != NULL_TREE)
	args = nreverse (args);
      gcc_assert (last != void_list_node);
    }
  else if (args == NULL_TREE)
    args = void_list_node;
  else
    {
      last = args;
      args = nreverse (args);
      TREE_CHAIN (last) = void_list_node;
    }
  args = build_function_type (return_type, args);

  return args;
}

/* Build a function type.  The RETURN_TYPE is the type returned by the
   function.  If additional arguments are provided, they are
   additional argument types.  The list of argument types must always
   be terminated by NULL_TREE.  */

tree
build_function_type_list (tree return_type, ...)
{
  tree args;
  va_list p;

  va_start (p, return_type);
  args = build_function_type_list_1 (false, return_type, p);
  va_end (p);
  return args;
}

/* Build a variable argument function type.  The RETURN_TYPE is the
   type returned by the function.  If additional arguments are provided,
   they are additional argument types.  The list of argument types must
   always be terminated by NULL_TREE.  */

tree
build_varargs_function_type_list (tree return_type, ...)
{
  tree args;
  va_list p;

  va_start (p, return_type);
  args = build_function_type_list_1 (true, return_type, p);
  va_end (p);

  return args;
}

/* Build a function type.  RETURN_TYPE is the type returned by the
   function; VAARGS indicates whether the function takes varargs.  The
   function takes N named arguments, the types of which are provided in
   ARG_TYPES.  */

static tree
build_function_type_array_1 (bool vaargs, tree return_type, int n,
			     tree *arg_types)
{
  int i;
  tree t = vaargs ? NULL_TREE : void_list_node;

  for (i = n - 1; i >= 0; i--)
    t = tree_cons (NULL_TREE, arg_types[i], t);

  return build_function_type (return_type, t);
}

/* Build a function type.  RETURN_TYPE is the type returned by the
   function.  The function takes N named arguments, the types of which
   are provided in ARG_TYPES.  */

tree
build_function_type_array (tree return_type, int n, tree *arg_types)
{
  return build_function_type_array_1 (false, return_type, n, arg_types);
}

/* Build a variable argument function type.  RETURN_TYPE is the type
   returned by the function.  The function takes N named arguments, the
   types of which are provided in ARG_TYPES.  */

tree
build_varargs_function_type_array (tree return_type, int n, tree *arg_types)
{
  return build_function_type_array_1 (true, return_type, n, arg_types);
}

/* Build a METHOD_TYPE for a member of BASETYPE.  The RETTYPE (a TYPE)
   and ARGTYPES (a TREE_LIST) are the return type and arguments types
   for the method.  An implicit additional parameter (of type
   pointer-to-BASETYPE) is added to the ARGTYPES.  */

tree
build_method_type_directly (tree basetype,
			    tree rettype,
			    tree argtypes)
{
  tree t;
  tree ptype;
  bool any_structural_p, any_noncanonical_p;
  tree canon_argtypes;

  /* Make a node of the sort we want.  */
  t = make_node (METHOD_TYPE);

  TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
  TREE_TYPE (t) = rettype;
  ptype = build_pointer_type (basetype);

  /* The actual arglist for this function includes a "hidden" argument
     which is "this".  Put it into the list of argument types.  */
  argtypes = tree_cons (NULL_TREE, ptype, argtypes);
  TYPE_ARG_TYPES (t) = argtypes;

  /* If we already have such a type, use the old one.  */
  hashval_t hash = type_hash_canon_hash (t);
  t = type_hash_canon (hash, t);

  /* Set up the canonical type. */
  any_structural_p
    = (TYPE_STRUCTURAL_EQUALITY_P (basetype)
       || TYPE_STRUCTURAL_EQUALITY_P (rettype));
  any_noncanonical_p
    = (TYPE_CANONICAL (basetype) != basetype
       || TYPE_CANONICAL (rettype) != rettype);
  canon_argtypes = maybe_canonicalize_argtypes (TREE_CHAIN (argtypes),
						&any_structural_p,
						&any_noncanonical_p);
  if (any_structural_p)
    SET_TYPE_STRUCTURAL_EQUALITY (t);
  else if (any_noncanonical_p)
    TYPE_CANONICAL (t)
      = build_method_type_directly (TYPE_CANONICAL (basetype),
				    TYPE_CANONICAL (rettype),
				    canon_argtypes);
  if (!COMPLETE_TYPE_P (t))
    layout_type (t);

  return t;
}

/* Construct, lay out and return the type of methods belonging to class
   BASETYPE and whose arguments and values are described by TYPE.
   If that type exists already, reuse it.
   TYPE must be a FUNCTION_TYPE node.  */

tree
build_method_type (tree basetype, tree type)
{
  gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);

  return build_method_type_directly (basetype,
				     TREE_TYPE (type),
				     TYPE_ARG_TYPES (type));
}

/* Construct, lay out and return the type of offsets to a value
   of type TYPE, within an object of type BASETYPE.
   If a suitable offset type exists already, reuse it.  */

tree
build_offset_type (tree basetype, tree type)
{
  tree t;

  /* Make a node of the sort we want.  */
  t = make_node (OFFSET_TYPE);

  TYPE_OFFSET_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
  TREE_TYPE (t) = type;

  /* If we already have such a type, use the old one.  */
  hashval_t hash = type_hash_canon_hash (t);
  t = type_hash_canon (hash, t);

  if (!COMPLETE_TYPE_P (t))
    layout_type (t);

  if (TYPE_CANONICAL (t) == t)
    {
      if (TYPE_STRUCTURAL_EQUALITY_P (basetype)
	  || TYPE_STRUCTURAL_EQUALITY_P (type))
	SET_TYPE_STRUCTURAL_EQUALITY (t);
      else if (TYPE_CANONICAL (TYPE_MAIN_VARIANT (basetype)) != basetype
	       || TYPE_CANONICAL (type) != type)
	TYPE_CANONICAL (t)
	  = build_offset_type (TYPE_CANONICAL (TYPE_MAIN_VARIANT (basetype)),
			       TYPE_CANONICAL (type));
    }

  return t;
}

/* Create a complex type whose components are COMPONENT_TYPE.

   If NAMED is true, the type is given a TYPE_NAME.  We do not always
   do so because this creates a DECL node and thus make the DECL_UIDs
   dependent on the type canonicalization hashtable, which is GC-ed,
   so the DECL_UIDs would not be stable wrt garbage collection.  */

tree
build_complex_type (tree component_type, bool named)
{
  gcc_assert (INTEGRAL_TYPE_P (component_type)
	      || SCALAR_FLOAT_TYPE_P (component_type)
	      || FIXED_POINT_TYPE_P (component_type));

  /* Make a node of the sort we want.  */
  tree probe = make_node (COMPLEX_TYPE);

  TREE_TYPE (probe) = TYPE_MAIN_VARIANT (component_type);

  /* If we already have such a type, use the old one.  */
  hashval_t hash = type_hash_canon_hash (probe);
  tree t = type_hash_canon (hash, probe);

  if (t == probe)
    {
      /* We created a new type.  The hash insertion will have laid
	 out the type.  We need to check the canonicalization and
	 maybe set the name.  */
      gcc_checking_assert (COMPLETE_TYPE_P (t)
			   && !TYPE_NAME (t)
			   && TYPE_CANONICAL (t) == t);

      if (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (t)))
	SET_TYPE_STRUCTURAL_EQUALITY (t);
      else if (TYPE_CANONICAL (TREE_TYPE (t)) != TREE_TYPE (t))
	TYPE_CANONICAL (t)
	  = build_complex_type (TYPE_CANONICAL (TREE_TYPE (t)), named);

      /* We need to create a name, since complex is a fundamental type.  */
      if (named)
	{
	  const char *name = NULL;

	  if (TREE_TYPE (t) == char_type_node)
	    name = "complex char";
	  else if (TREE_TYPE (t) == signed_char_type_node)
	    name = "complex signed char";
	  else if (TREE_TYPE (t) == unsigned_char_type_node)
	    name = "complex unsigned char";
	  else if (TREE_TYPE (t) == short_integer_type_node)
	    name = "complex short int";
	  else if (TREE_TYPE (t) == short_unsigned_type_node)
	    name = "complex short unsigned int";
	  else if (TREE_TYPE (t) == integer_type_node)
	    name = "complex int";
	  else if (TREE_TYPE (t) == unsigned_type_node)
	    name = "complex unsigned int";
	  else if (TREE_TYPE (t) == long_integer_type_node)
	    name = "complex long int";
	  else if (TREE_TYPE (t) == long_unsigned_type_node)
	    name = "complex long unsigned int";
	  else if (TREE_TYPE (t) == long_long_integer_type_node)
	    name = "complex long long int";
	  else if (TREE_TYPE (t) == long_long_unsigned_type_node)
	    name = "complex long long unsigned int";

	  if (name != NULL)
	    TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
					get_identifier (name), t);
	}
    }

  return build_qualified_type (t, TYPE_QUALS (component_type));
}

/* If TYPE is a real or complex floating-point type and the target
   does not directly support arithmetic on TYPE then return the wider
   type to be used for arithmetic on TYPE.  Otherwise, return
   NULL_TREE.  */

tree
excess_precision_type (tree type)
{
  /* The target can give two different responses to the question of
     which excess precision mode it would like depending on whether we
     are in -fexcess-precision=standard or -fexcess-precision=fast.  */

  enum excess_precision_type requested_type
    = (flag_excess_precision == EXCESS_PRECISION_FAST
       ? EXCESS_PRECISION_TYPE_FAST
       : EXCESS_PRECISION_TYPE_STANDARD);

  enum flt_eval_method target_flt_eval_method
    = targetm.c.excess_precision (requested_type);

  /* The target should not ask for unpredictable float evaluation (though
     it might advertise that implicitly the evaluation is unpredictable,
     but we don't care about that here, it will have been reported
     elsewhere).  If it does ask for unpredictable evaluation, we have
     nothing to do here.  */
  gcc_assert (target_flt_eval_method != FLT_EVAL_METHOD_UNPREDICTABLE);

  /* Nothing to do.  The target has asked for all types we know about
     to be computed with their native precision and range.  */
  if (target_flt_eval_method == FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16)
    return NULL_TREE;

  /* The target will promote this type in a target-dependent way, so excess
     precision ought to leave it alone.  */
  if (targetm.promoted_type (type) != NULL_TREE)
    return NULL_TREE;

  machine_mode float16_type_mode = (float16_type_node
				    ? TYPE_MODE (float16_type_node)
				    : VOIDmode);
  machine_mode float_type_mode = TYPE_MODE (float_type_node);
  machine_mode double_type_mode = TYPE_MODE (double_type_node);

  switch (TREE_CODE (type))
    {
    case REAL_TYPE:
      {
	machine_mode type_mode = TYPE_MODE (type);
	switch (target_flt_eval_method)
	  {
	  case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT:
	    if (type_mode == float16_type_mode)
	      return float_type_node;
	    break;
	  case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE:
	    if (type_mode == float16_type_mode
		|| type_mode == float_type_mode)
	      return double_type_node;
	    break;
	  case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE:
	    if (type_mode == float16_type_mode
		|| type_mode == float_type_mode
		|| type_mode == double_type_mode)
	      return long_double_type_node;
	    break;
	  default:
	    gcc_unreachable ();
	  }
	break;
      }
    case COMPLEX_TYPE:
      {
	if (TREE_CODE (TREE_TYPE (type)) != REAL_TYPE)
	  return NULL_TREE;
	machine_mode type_mode = TYPE_MODE (TREE_TYPE (type));
	switch (target_flt_eval_method)
	  {
	  case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT:
	    if (type_mode == float16_type_mode)
	      return complex_float_type_node;
	    break;
	  case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE:
	    if (type_mode == float16_type_mode
		|| type_mode == float_type_mode)
	      return complex_double_type_node;
	    break;
	  case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE:
	    if (type_mode == float16_type_mode
		|| type_mode == float_type_mode
		|| type_mode == double_type_mode)
	      return complex_long_double_type_node;
	    break;
	  default:
	    gcc_unreachable ();
	  }
	break;
      }
    default:
      break;
    }

  return NULL_TREE;
}

/* Return OP, stripped of any conversions to wider types as much as is safe.
   Converting the value back to OP's type makes a value equivalent to OP.

   If FOR_TYPE is nonzero, we return a value which, if converted to
   type FOR_TYPE, would be equivalent to converting OP to type FOR_TYPE.

   OP must have integer, real or enumeral type.  Pointers are not allowed!

   There are some cases where the obvious value we could return
   would regenerate to OP if converted to OP's type,
   but would not extend like OP to wider types.
   If FOR_TYPE indicates such extension is contemplated, we eschew such values.
   For example, if OP is (unsigned short)(signed char)-1,
   we avoid returning (signed char)-1 if FOR_TYPE is int,
   even though extending that to an unsigned short would regenerate OP,
   since the result of extending (signed char)-1 to (int)
   is different from (int) OP.  */

tree
get_unwidened (tree op, tree for_type)
{
  /* Set UNS initially if converting OP to FOR_TYPE is a zero-extension.  */
  tree type = TREE_TYPE (op);
  unsigned final_prec
    = TYPE_PRECISION (for_type != 0 ? for_type : type);
  int uns
    = (for_type != 0 && for_type != type
       && final_prec > TYPE_PRECISION (type)
       && TYPE_UNSIGNED (type));
  tree win = op;

  while (CONVERT_EXPR_P (op))
    {
      int bitschange;

      /* TYPE_PRECISION on vector types has different meaning
	 (TYPE_VECTOR_SUBPARTS) and casts from vectors are view conversions,
	 so avoid them here.  */
      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == VECTOR_TYPE)
	break;

      bitschange = TYPE_PRECISION (TREE_TYPE (op))
		   - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0)));

      /* Truncations are many-one so cannot be removed.
	 Unless we are later going to truncate down even farther.  */
      if (bitschange < 0
	  && final_prec > TYPE_PRECISION (TREE_TYPE (op)))
	break;

      /* See what's inside this conversion.  If we decide to strip it,
	 we will set WIN.  */
      op = TREE_OPERAND (op, 0);

      /* If we have not stripped any zero-extensions (uns is 0),
	 we can strip any kind of extension.
	 If we have previously stripped a zero-extension,
	 only zero-extensions can safely be stripped.
	 Any extension can be stripped if the bits it would produce
	 are all going to be discarded later by truncating to FOR_TYPE.  */

      if (bitschange > 0)
	{
	  if (! uns || final_prec <= TYPE_PRECISION (TREE_TYPE (op)))
	    win = op;
	  /* TYPE_UNSIGNED says whether this is a zero-extension.
	     Let's avoid computing it if it does not affect WIN
	     and if UNS will not be needed again.  */
	  if ((uns
	       || CONVERT_EXPR_P (op))
	      && TYPE_UNSIGNED (TREE_TYPE (op)))
	    {
	      uns = 1;
	      win = op;
	    }
	}
    }

  /* If we finally reach a constant see if it fits in sth smaller and
     in that case convert it.  */
  if (TREE_CODE (win) == INTEGER_CST)
    {
      tree wtype = TREE_TYPE (win);
      unsigned prec = wi::min_precision (wi::to_wide (win), TYPE_SIGN (wtype));
      if (for_type)
	prec = MAX (prec, final_prec);
      if (prec < TYPE_PRECISION (wtype))
	{
	  tree t = lang_hooks.types.type_for_size (prec, TYPE_UNSIGNED (wtype));
	  if (t && TYPE_PRECISION (t) < TYPE_PRECISION (wtype))
	    win = fold_convert (t, win);
	}
    }

  return win;
}

/* Return OP or a simpler expression for a narrower value
   which can be sign-extended or zero-extended to give back OP.
   Store in *UNSIGNEDP_PTR either 1 if the value should be zero-extended
   or 0 if the value should be sign-extended.  */

tree
get_narrower (tree op, int *unsignedp_ptr)
{
  int uns = 0;
  int first = 1;
  tree win = op;
  bool integral_p = INTEGRAL_TYPE_P (TREE_TYPE (op));

  while (TREE_CODE (op) == NOP_EXPR)
    {
      int bitschange
	= (TYPE_PRECISION (TREE_TYPE (op))
	   - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0))));

      /* Truncations are many-one so cannot be removed.  */
      if (bitschange < 0)
	break;

      /* See what's inside this conversion.  If we decide to strip it,
	 we will set WIN.  */

      if (bitschange > 0)
	{
	  op = TREE_OPERAND (op, 0);
	  /* An extension: the outermost one can be stripped,
	     but remember whether it is zero or sign extension.  */
	  if (first)
	    uns = TYPE_UNSIGNED (TREE_TYPE (op));
	  /* Otherwise, if a sign extension has been stripped,
	     only sign extensions can now be stripped;
	     if a zero extension has been stripped, only zero-extensions.  */
	  else if (uns != TYPE_UNSIGNED (TREE_TYPE (op)))
	    break;
	  first = 0;
	}
      else /* bitschange == 0 */
	{
	  /* A change in nominal type can always be stripped, but we must
	     preserve the unsignedness.  */
	  if (first)
	    uns = TYPE_UNSIGNED (TREE_TYPE (op));
	  first = 0;
	  op = TREE_OPERAND (op, 0);
	  /* Keep trying to narrow, but don't assign op to win if it
	     would turn an integral type into something else.  */
	  if (INTEGRAL_TYPE_P (TREE_TYPE (op)) != integral_p)
	    continue;
	}

      win = op;
    }

  if (TREE_CODE (op) == COMPONENT_REF
      /* Since type_for_size always gives an integer type.  */
      && TREE_CODE (TREE_TYPE (op)) != REAL_TYPE
      && TREE_CODE (TREE_TYPE (op)) != FIXED_POINT_TYPE
      /* Ensure field is laid out already.  */
      && DECL_SIZE (TREE_OPERAND (op, 1)) != 0
      && tree_fits_uhwi_p (DECL_SIZE (TREE_OPERAND (op, 1))))
    {
      unsigned HOST_WIDE_INT innerprec
	= tree_to_uhwi (DECL_SIZE (TREE_OPERAND (op, 1)));
      int unsignedp = (DECL_UNSIGNED (TREE_OPERAND (op, 1))
		       || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 1))));
      tree type = lang_hooks.types.type_for_size (innerprec, unsignedp);

      /* We can get this structure field in a narrower type that fits it,
	 but the resulting extension to its nominal type (a fullword type)
	 must satisfy the same conditions as for other extensions.

	 Do this only for fields that are aligned (not bit-fields),
	 because when bit-field insns will be used there is no
	 advantage in doing this.  */

      if (innerprec < TYPE_PRECISION (TREE_TYPE (op))
	  && ! DECL_BIT_FIELD (TREE_OPERAND (op, 1))
	  && (first || uns == DECL_UNSIGNED (TREE_OPERAND (op, 1)))
	  && type != 0)
	{
	  if (first)
	    uns = DECL_UNSIGNED (TREE_OPERAND (op, 1));
	  win = fold_convert (type, op);
	}
    }

  *unsignedp_ptr = uns;
  return win;
}

/* Return true if integer constant C has a value that is permissible
   for TYPE, an integral type.  */

bool
int_fits_type_p (const_tree c, const_tree type)
{
  tree type_low_bound, type_high_bound;
  bool ok_for_low_bound, ok_for_high_bound;
  signop sgn_c = TYPE_SIGN (TREE_TYPE (c));

  /* Non-standard boolean types can have arbitrary precision but various
     transformations assume that they can only take values 0 and +/-1.  */
  if (TREE_CODE (type) == BOOLEAN_TYPE)
    return wi::fits_to_boolean_p (wi::to_wide (c), type);

retry:
  type_low_bound = TYPE_MIN_VALUE (type);
  type_high_bound = TYPE_MAX_VALUE (type);

  /* If at least one bound of the type is a constant integer, we can check
     ourselves and maybe make a decision. If no such decision is possible, but
     this type is a subtype, try checking against that.  Otherwise, use
     fits_to_tree_p, which checks against the precision.

     Compute the status for each possibly constant bound, and return if we see
     one does not match. Use ok_for_xxx_bound for this purpose, assigning -1
     for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
     for "constant known to fit".  */

  /* Check if c >= type_low_bound.  */
  if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
    {
      if (tree_int_cst_lt (c, type_low_bound))
	return false;
      ok_for_low_bound = true;
    }
  else
    ok_for_low_bound = false;

  /* Check if c <= type_high_bound.  */
  if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
    {
      if (tree_int_cst_lt (type_high_bound, c))
	return false;
      ok_for_high_bound = true;
    }
  else
    ok_for_high_bound = false;

  /* If the constant fits both bounds, the result is known.  */
  if (ok_for_low_bound && ok_for_high_bound)
    return true;

  /* Perform some generic filtering which may allow making a decision
     even if the bounds are not constant.  First, negative integers
     never fit in unsigned types, */
  if (TYPE_UNSIGNED (type) && sgn_c == SIGNED && wi::neg_p (wi::to_wide (c)))
    return false;

  /* Second, narrower types always fit in wider ones.  */
  if (TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (c)))
    return true;

  /* Third, unsigned integers with top bit set never fit signed types.  */
  if (!TYPE_UNSIGNED (type) && sgn_c == UNSIGNED)
    {
      int prec = GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (TREE_TYPE (c))) - 1;
      if (prec < TYPE_PRECISION (TREE_TYPE (c)))
	{
	  /* When a tree_cst is converted to a wide-int, the precision
	     is taken from the type.  However, if the precision of the
	     mode underneath the type is smaller than that, it is
	     possible that the value will not fit.  The test below
	     fails if any bit is set between the sign bit of the
	     underlying mode and the top bit of the type.  */
	  if (wi::zext (wi::to_wide (c), prec - 1) != wi::to_wide (c))
	    return false;
	}
      else if (wi::neg_p (wi::to_wide (c)))
	return false;
    }

  /* If we haven't been able to decide at this point, there nothing more we
     can check ourselves here.  Look at the base type if we have one and it
     has the same precision.  */
  if (TREE_CODE (type) == INTEGER_TYPE
      && TREE_TYPE (type) != 0
      && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (type)))
    {
      type = TREE_TYPE (type);
      goto retry;
    }

  /* Or to fits_to_tree_p, if nothing else.  */
  return wi::fits_to_tree_p (wi::to_wide (c), type);
}

/* Stores bounds of an integer TYPE in MIN and MAX.  If TYPE has non-constant
   bounds or is a POINTER_TYPE, the maximum and/or minimum values that can be
   represented (assuming two's-complement arithmetic) within the bit
   precision of the type are returned instead.  */

void
get_type_static_bounds (const_tree type, mpz_t min, mpz_t max)
{
  if (!POINTER_TYPE_P (type) && TYPE_MIN_VALUE (type)
      && TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST)
    wi::to_mpz (wi::to_wide (TYPE_MIN_VALUE (type)), min, TYPE_SIGN (type));
  else
    {
      if (TYPE_UNSIGNED (type))
	mpz_set_ui (min, 0);
      else
	{
	  wide_int mn = wi::min_value (TYPE_PRECISION (type), SIGNED);
	  wi::to_mpz (mn, min, SIGNED);
	}
    }

  if (!POINTER_TYPE_P (type) && TYPE_MAX_VALUE (type)
      && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST)
    wi::to_mpz (wi::to_wide (TYPE_MAX_VALUE (type)), max, TYPE_SIGN (type));
  else
    {
      wide_int mn = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
      wi::to_mpz (mn, max, TYPE_SIGN (type));
    }
}

/* Return true if VAR is an automatic variable defined in function FN.  */

bool
auto_var_in_fn_p (const_tree var, const_tree fn)
{
  return (DECL_P (var) && DECL_CONTEXT (var) == fn
	  && ((((VAR_P (var) && ! DECL_EXTERNAL (var))
		|| TREE_CODE (var) == PARM_DECL)
	       && ! TREE_STATIC (var))
	      || TREE_CODE (var) == LABEL_DECL
	      || TREE_CODE (var) == RESULT_DECL));
}

/* Subprogram of following function.  Called by walk_tree.

   Return *TP if it is an automatic variable or parameter of the
   function passed in as DATA.  */

static tree
find_var_from_fn (tree *tp, int *walk_subtrees, void *data)
{
  tree fn = (tree) data;

  if (TYPE_P (*tp))
    *walk_subtrees = 0;

  else if (DECL_P (*tp)
	   && auto_var_in_fn_p (*tp, fn))
    return *tp;

  return NULL_TREE;
}

/* Returns true if T is, contains, or refers to a type with variable
   size.  For METHOD_TYPEs and FUNCTION_TYPEs we exclude the
   arguments, but not the return type.  If FN is nonzero, only return
   true if a modifier of the type or position of FN is a variable or
   parameter inside FN.

   This concept is more general than that of C99 'variably modified types':
   in C99, a struct type is never variably modified because a VLA may not
   appear as a structure member.  However, in GNU C code like:

     struct S { int i[f()]; };

   is valid, and other languages may define similar constructs.  */

bool
variably_modified_type_p (tree type, tree fn)
{
  tree t;

/* Test if T is either variable (if FN is zero) or an expression containing
   a variable in FN.  If TYPE isn't gimplified, return true also if
   gimplify_one_sizepos would gimplify the expression into a local
   variable.  */
#define RETURN_TRUE_IF_VAR(T)						\
  do { tree _t = (T);							\
    if (_t != NULL_TREE							\
	&& _t != error_mark_node					\
	&& !CONSTANT_CLASS_P (_t)					\
	&& TREE_CODE (_t) != PLACEHOLDER_EXPR				\
	&& (!fn								\
	    || (!TYPE_SIZES_GIMPLIFIED (type)				\
		&& (TREE_CODE (_t) != VAR_DECL				\
		    && !CONTAINS_PLACEHOLDER_P (_t)))			\
	    || walk_tree (&_t, find_var_from_fn, fn, NULL)))		\
      return true;  } while (0)

  if (type == error_mark_node)
    return false;

  /* If TYPE itself has variable size, it is variably modified.  */
  RETURN_TRUE_IF_VAR (TYPE_SIZE (type));
  RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT (type));

  switch (TREE_CODE (type))
    {
    case POINTER_TYPE:
    case REFERENCE_TYPE:
    case VECTOR_TYPE:
      /* Ada can have pointer types refering to themselves indirectly.  */
      if (TREE_VISITED (type))
	return false;
      TREE_VISITED (type) = true;
      if (variably_modified_type_p (TREE_TYPE (type), fn))
	{
	  TREE_VISITED (type) = false;
	  return true;
	}
      TREE_VISITED (type) = false;
      break;

    case FUNCTION_TYPE:
    case METHOD_TYPE:
      /* If TYPE is a function type, it is variably modified if the
	 return type is variably modified.  */
      if (variably_modified_type_p (TREE_TYPE (type), fn))
	  return true;
      break;

    case INTEGER_TYPE:
    case REAL_TYPE:
    case FIXED_POINT_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
      /* Scalar types are variably modified if their end points
	 aren't constant.  */
      RETURN_TRUE_IF_VAR (TYPE_MIN_VALUE (type));
      RETURN_TRUE_IF_VAR (TYPE_MAX_VALUE (type));
      break;

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      /* We can't see if any of the fields are variably-modified by the
	 definition we normally use, since that would produce infinite
	 recursion via pointers.  */
      /* This is variably modified if some field's type is.  */
      for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
	if (TREE_CODE (t) == FIELD_DECL)
	  {
	    RETURN_TRUE_IF_VAR (DECL_FIELD_OFFSET (t));
	    RETURN_TRUE_IF_VAR (DECL_SIZE (t));
	    RETURN_TRUE_IF_VAR (DECL_SIZE_UNIT (t));

	    if (TREE_CODE (type) == QUAL_UNION_TYPE)
	      RETURN_TRUE_IF_VAR (DECL_QUALIFIER (t));
	  }
      break;

    case ARRAY_TYPE:
      /* Do not call ourselves to avoid infinite recursion.  This is
	 variably modified if the element type is.  */
      RETURN_TRUE_IF_VAR (TYPE_SIZE (TREE_TYPE (type)));
      RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT (TREE_TYPE (type)));
      break;

    default:
      break;
    }

  /* The current language may have other cases to check, but in general,
     all other types are not variably modified.  */
  return lang_hooks.tree_inlining.var_mod_type_p (type, fn);

#undef RETURN_TRUE_IF_VAR
}

/* Given a DECL or TYPE, return the scope in which it was declared, or
   NULL_TREE if there is no containing scope.  */

tree
get_containing_scope (const_tree t)
{
  return (TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t));
}

/* Returns the ultimate TRANSLATION_UNIT_DECL context of DECL or NULL.  */

const_tree
get_ultimate_context (const_tree decl)
{
  while (decl && TREE_CODE (decl) != TRANSLATION_UNIT_DECL)
    {
      if (TREE_CODE (decl) == BLOCK)
	decl = BLOCK_SUPERCONTEXT (decl);
      else
	decl = get_containing_scope (decl);
    }
  return decl;
}

/* Return the innermost context enclosing DECL that is
   a FUNCTION_DECL, or zero if none.  */

tree
decl_function_context (const_tree decl)
{
  tree context;

  if (TREE_CODE (decl) == ERROR_MARK)
    return 0;

  /* C++ virtual functions use DECL_CONTEXT for the class of the vtable
     where we look up the function at runtime.  Such functions always take
     a first argument of type 'pointer to real context'.

     C++ should really be fixed to use DECL_CONTEXT for the real context,
     and use something else for the "virtual context".  */
  else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))
    context
      = TYPE_MAIN_VARIANT
	(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));
  else
    context = DECL_CONTEXT (decl);

  while (context && TREE_CODE (context) != FUNCTION_DECL)
    {
      if (TREE_CODE (context) == BLOCK)
	context = BLOCK_SUPERCONTEXT (context);
      else
	context = get_containing_scope (context);
    }

  return context;
}

/* Return the innermost context enclosing DECL that is
   a RECORD_TYPE, UNION_TYPE or QUAL_UNION_TYPE, or zero if none.
   TYPE_DECLs and FUNCTION_DECLs are transparent to this function.  */

tree
decl_type_context (const_tree decl)
{
  tree context = DECL_CONTEXT (decl);

  while (context)
    switch (TREE_CODE (context))
      {
      case NAMESPACE_DECL:
      case TRANSLATION_UNIT_DECL:
	return NULL_TREE;

      case RECORD_TYPE:
      case UNION_TYPE:
      case QUAL_UNION_TYPE:
	return context;

      case TYPE_DECL:
      case FUNCTION_DECL:
	context = DECL_CONTEXT (context);
	break;

      case BLOCK:
	context = BLOCK_SUPERCONTEXT (context);
	break;

      default:
	gcc_unreachable ();
      }

  return NULL_TREE;
}

/* CALL is a CALL_EXPR.  Return the declaration for the function
   called, or NULL_TREE if the called function cannot be
   determined.  */

tree
get_callee_fndecl (const_tree call)
{
  tree addr;

  if (call == error_mark_node)
    return error_mark_node;

  /* It's invalid to call this function with anything but a
     CALL_EXPR.  */
  gcc_assert (TREE_CODE (call) == CALL_EXPR);

  /* The first operand to the CALL is the address of the function
     called.  */
  addr = CALL_EXPR_FN (call);

  /* If there is no function, return early.  */
  if (addr == NULL_TREE)
    return NULL_TREE;

  STRIP_NOPS (addr);

  /* If this is a readonly function pointer, extract its initial value.  */
  if (DECL_P (addr) && TREE_CODE (addr) != FUNCTION_DECL
      && TREE_READONLY (addr) && ! TREE_THIS_VOLATILE (addr)
      && DECL_INITIAL (addr))
    addr = DECL_INITIAL (addr);

  /* If the address is just `&f' for some function `f', then we know
     that `f' is being called.  */
  if (TREE_CODE (addr) == ADDR_EXPR
      && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
    return TREE_OPERAND (addr, 0);

  /* We couldn't figure out what was being called.  */
  return NULL_TREE;
}

/* If CALL_EXPR CALL calls a normal built-in function or an internal function,
   return the associated function code, otherwise return CFN_LAST.  */

combined_fn
get_call_combined_fn (const_tree call)
{
  /* It's invalid to call this function with anything but a CALL_EXPR.  */
  gcc_assert (TREE_CODE (call) == CALL_EXPR);

  if (!CALL_EXPR_FN (call))
    return as_combined_fn (CALL_EXPR_IFN (call));

  tree fndecl = get_callee_fndecl (call);
  if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    return as_combined_fn (DECL_FUNCTION_CODE (fndecl));

  return CFN_LAST;
}

/* Comparator of indices based on tree_node_counts.  */

static int
tree_nodes_cmp (const void *p1, const void *p2)
{
  const unsigned *n1 = (const unsigned *)p1;
  const unsigned *n2 = (const unsigned *)p2;

  return tree_node_counts[*n1] - tree_node_counts[*n2];
}

/* Comparator of indices based on tree_code_counts.  */

static int
tree_codes_cmp (const void *p1, const void *p2)
{
  const unsigned *n1 = (const unsigned *)p1;
  const unsigned *n2 = (const unsigned *)p2;

  return tree_code_counts[*n1] - tree_code_counts[*n2];
}

#define TREE_MEM_USAGE_SPACES 40

/* Print debugging information about tree nodes generated during the compile,
   and any language-specific information.  */

void
dump_tree_statistics (void)
{
  if (GATHER_STATISTICS)
    {
      uint64_t total_nodes, total_bytes;
      fprintf (stderr, "\nKind                   Nodes      Bytes\n");
      mem_usage::print_dash_line (TREE_MEM_USAGE_SPACES);
      total_nodes = total_bytes = 0;

      {
	auto_vec<unsigned> indices (all_kinds);
	for (unsigned i = 0; i < all_kinds; i++)
	  indices.quick_push (i);
	indices.qsort (tree_nodes_cmp);

	for (unsigned i = 0; i < (int) all_kinds; i++)
	  {
	    unsigned j = indices[i];
	    fprintf (stderr, "%-20s %6" PRIu64 "%c %9" PRIu64 "%c\n",
		     tree_node_kind_names[i], SIZE_AMOUNT (tree_node_counts[j]),
		     SIZE_AMOUNT (tree_node_sizes[j]));
	    total_nodes += tree_node_counts[j];
	    total_bytes += tree_node_sizes[j];
	  }
	mem_usage::print_dash_line (TREE_MEM_USAGE_SPACES);
	fprintf (stderr, "%-20s %6" PRIu64 "%c %9" PRIu64 "%c\n", "Total",
		 SIZE_AMOUNT (total_nodes), SIZE_AMOUNT (total_bytes));
	mem_usage::print_dash_line (TREE_MEM_USAGE_SPACES);
      }

      {
	fprintf (stderr, "Code                              Nodes\n");
	mem_usage::print_dash_line (TREE_MEM_USAGE_SPACES);

	auto_vec<unsigned> indices (MAX_TREE_CODES);
	for (unsigned i = 0; i < MAX_TREE_CODES; i++)
	  indices.quick_push (i);
	indices.qsort (tree_codes_cmp);

	for (unsigned i = 0; i < MAX_TREE_CODES; i++)
	  {
	    unsigned j = indices[i];
	    fprintf (stderr, "%-32s %6" PRIu64 "%c\n",
		     get_tree_code_name ((enum tree_code) j),
		     SIZE_AMOUNT (tree_code_counts[j]));
	  }
	mem_usage::print_dash_line (TREE_MEM_USAGE_SPACES);
	fprintf (stderr, "\n");
	ssanames_print_statistics ();
	fprintf (stderr, "\n");
	phinodes_print_statistics ();
	fprintf (stderr, "\n");
      }
    }
  else
    fprintf (stderr, "(No per-node statistics)\n");

  print_type_hash_statistics ();
  print_debug_expr_statistics ();
  print_value_expr_statistics ();
  lang_hooks.print_statistics ();
}

#define FILE_FUNCTION_FORMAT "_GLOBAL__%s_%s"

/* Generate a crc32 of the low BYTES bytes of VALUE.  */

unsigned
crc32_unsigned_n (unsigned chksum, unsigned value, unsigned bytes)
{
  /* This relies on the raw feedback's top 4 bits being zero.  */
#define FEEDBACK(X) ((X) * 0x04c11db7)
#define SYNDROME(X) (FEEDBACK ((X) & 1) ^ FEEDBACK ((X) & 2) \
		     ^ FEEDBACK ((X) & 4) ^ FEEDBACK ((X) & 8))
  static const unsigned syndromes[16] =
    {
      SYNDROME(0x0), SYNDROME(0x1), SYNDROME(0x2), SYNDROME(0x3),
      SYNDROME(0x4), SYNDROME(0x5), SYNDROME(0x6), SYNDROME(0x7),
      SYNDROME(0x8), SYNDROME(0x9), SYNDROME(0xa), SYNDROME(0xb),
      SYNDROME(0xc), SYNDROME(0xd), SYNDROME(0xe), SYNDROME(0xf),
    };
#undef FEEDBACK
#undef SYNDROME

  value <<= (32 - bytes * 8);
  for (unsigned ix = bytes * 2; ix--; value <<= 4)
    {
      unsigned feedback = syndromes[((value ^ chksum) >> 28) & 0xf];

      chksum = (chksum << 4) ^ feedback;
    }

  return chksum;
}

/* Generate a crc32 of a string.  */

unsigned
crc32_string (unsigned chksum, const char *string)
{
  do
    chksum = crc32_byte (chksum, *string);
  while (*string++);
  return chksum;
}

/* P is a string that will be used in a symbol.  Mask out any characters
   that are not valid in that context.  */

void
clean_symbol_name (char *p)
{
  for (; *p; p++)
    if (! (ISALNUM (*p)
#ifndef NO_DOLLAR_IN_LABEL	/* this for `$'; unlikely, but... -- kr */
	    || *p == '$'
#endif
#ifndef NO_DOT_IN_LABEL		/* this for `.'; unlikely, but...  */
	    || *p == '.'
#endif
	   ))
      *p = '_';
}

/* For anonymous aggregate types, we need some sort of name to
   hold on to.  In practice, this should not appear, but it should
   not be harmful if it does.  */
bool 
anon_aggrname_p(const_tree id_node)
{
#ifndef NO_DOT_IN_LABEL
 return (IDENTIFIER_POINTER (id_node)[0] == '.'
	 && IDENTIFIER_POINTER (id_node)[1] == '_');
#else /* NO_DOT_IN_LABEL */
#ifndef NO_DOLLAR_IN_LABEL
  return (IDENTIFIER_POINTER (id_node)[0] == '$' \
	  && IDENTIFIER_POINTER (id_node)[1] == '_');
#else /* NO_DOLLAR_IN_LABEL */
#define ANON_AGGRNAME_PREFIX "__anon_"
  return (!strncmp (IDENTIFIER_POINTER (id_node), ANON_AGGRNAME_PREFIX, 
		    sizeof (ANON_AGGRNAME_PREFIX) - 1));
#endif	/* NO_DOLLAR_IN_LABEL */
#endif	/* NO_DOT_IN_LABEL */
}

/* Return a format for an anonymous aggregate name.  */
const char *
anon_aggrname_format()
{
#ifndef NO_DOT_IN_LABEL
 return "._%d";
#else /* NO_DOT_IN_LABEL */
#ifndef NO_DOLLAR_IN_LABEL
  return "$_%d";
#else /* NO_DOLLAR_IN_LABEL */
  return "__anon_%d";
#endif	/* NO_DOLLAR_IN_LABEL */
#endif	/* NO_DOT_IN_LABEL */
}

/* Generate a name for a special-purpose function.
   The generated name may need to be unique across the whole link.
   Changes to this function may also require corresponding changes to
   xstrdup_mask_random.
   TYPE is some string to identify the purpose of this function to the
   linker or collect2; it must start with an uppercase letter,
   one of:
   I - for constructors
   D - for destructors
   N - for C++ anonymous namespaces
   F - for DWARF unwind frame information.  */

tree
get_file_function_name (const char *type)
{
  char *buf;
  const char *p;
  char *q;

  /* If we already have a name we know to be unique, just use that.  */
  if (first_global_object_name)
    p = q = ASTRDUP (first_global_object_name);
  /* If the target is handling the constructors/destructors, they
     will be local to this file and the name is only necessary for
     debugging purposes. 
     We also assign sub_I and sub_D sufixes to constructors called from
     the global static constructors.  These are always local.  */
  else if (((type[0] == 'I' || type[0] == 'D') && targetm.have_ctors_dtors)
	   || (strncmp (type, "sub_", 4) == 0
	       && (type[4] == 'I' || type[4] == 'D')))
    {
      const char *file = main_input_filename;
      if (! file)
	file = LOCATION_FILE (input_location);
      /* Just use the file's basename, because the full pathname
	 might be quite long.  */
      p = q = ASTRDUP (lbasename (file));
    }
  else
    {
      /* Otherwise, the name must be unique across the entire link.
	 We don't have anything that we know to be unique to this translation
	 unit, so use what we do have and throw in some randomness.  */
      unsigned len;
      const char *name = weak_global_object_name;
      const char *file = main_input_filename;

      if (! name)
	name = "";
      if (! file)
	file = LOCATION_FILE (input_location);

      len = strlen (file);
      q = (char *) alloca (9 + 19 + len + 1);
      memcpy (q, file, len + 1);

      snprintf (q + len, 9 + 19 + 1, "_%08X_" HOST_WIDE_INT_PRINT_HEX,
		crc32_string (0, name), get_random_seed (false));

      p = q;
    }

  clean_symbol_name (q);
  buf = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) + strlen (p)
			 + strlen (type));

  /* Set up the name of the file-level functions we may need.
     Use a global object (which is already required to be unique over
     the program) rather than the file name (which imposes extra
     constraints).  */
  sprintf (buf, FILE_FUNCTION_FORMAT, type, p);

  return get_identifier (buf);
}

#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)

/* Complain that the tree code of NODE does not match the expected 0
   terminated list of trailing codes. The trailing code list can be
   empty, for a more vague error message.  FILE, LINE, and FUNCTION
   are of the caller.  */

void
tree_check_failed (const_tree node, const char *file,
		   int line, const char *function, ...)
{
  va_list args;
  const char *buffer;
  unsigned length = 0;
  enum tree_code code;

  va_start (args, function);
  while ((code = (enum tree_code) va_arg (args, int)))
    length += 4 + strlen (get_tree_code_name (code));
  va_end (args);
  if (length)
    {
      char *tmp;
      va_start (args, function);
      length += strlen ("expected ");
      buffer = tmp = (char *) alloca (length);
      length = 0;
      while ((code = (enum tree_code) va_arg (args, int)))
	{
	  const char *prefix = length ? " or " : "expected ";

	  strcpy (tmp + length, prefix);
	  length += strlen (prefix);
	  strcpy (tmp + length, get_tree_code_name (code));
	  length += strlen (get_tree_code_name (code));
	}
      va_end (args);
    }
  else
    buffer = "unexpected node";

  internal_error ("tree check: %s, have %s in %s, at %s:%d",
		  buffer, get_tree_code_name (TREE_CODE (node)),
		  function, trim_filename (file), line);
}

/* Complain that the tree code of NODE does match the expected 0
   terminated list of trailing codes. FILE, LINE, and FUNCTION are of
   the caller.  */

void
tree_not_check_failed (const_tree node, const char *file,
		       int line, const char *function, ...)
{
  va_list args;
  char *buffer;
  unsigned length = 0;
  enum tree_code code;

  va_start (args, function);
  while ((code = (enum tree_code) va_arg (args, int)))
    length += 4 + strlen (get_tree_code_name (code));
  va_end (args);
  va_start (args, function);
  buffer = (char *) alloca (length);
  length = 0;
  while ((code = (enum tree_code) va_arg (args, int)))
    {
      if (length)
	{
	  strcpy (buffer + length, " or ");
	  length += 4;
	}
      strcpy (buffer + length, get_tree_code_name (code));
      length += strlen (get_tree_code_name (code));
    }
  va_end (args);

  internal_error ("tree check: expected none of %s, have %s in %s, at %s:%d",
		  buffer, get_tree_code_name (TREE_CODE (node)),
		  function, trim_filename (file), line);
}

/* Similar to tree_check_failed, except that we check for a class of tree
   code, given in CL.  */

void
tree_class_check_failed (const_tree node, const enum tree_code_class cl,
			 const char *file, int line, const char *function)
{
  internal_error
    ("tree check: expected class %qs, have %qs (%s) in %s, at %s:%d",
     TREE_CODE_CLASS_STRING (cl),
     TREE_CODE_CLASS_STRING (TREE_CODE_CLASS (TREE_CODE (node))),
     get_tree_code_name (TREE_CODE (node)), function, trim_filename (file), line);
}

/* Similar to tree_check_failed, except that instead of specifying a
   dozen codes, use the knowledge that they're all sequential.  */

void
tree_range_check_failed (const_tree node, const char *file, int line,
			 const char *function, enum tree_code c1,
			 enum tree_code c2)
{
  char *buffer;
  unsigned length = 0;
  unsigned int c;

  for (c = c1; c <= c2; ++c)
    length += 4 + strlen (get_tree_code_name ((enum tree_code) c));

  length += strlen ("expected ");
  buffer = (char *) alloca (length);
  length = 0;

  for (c = c1; c <= c2; ++c)
    {
      const char *prefix = length ? " or " : "expected ";

      strcpy (buffer + length, prefix);
      length += strlen (prefix);
      strcpy (buffer + length, get_tree_code_name ((enum tree_code) c));
      length += strlen (get_tree_code_name ((enum tree_code) c));
    }

  internal_error ("tree check: %s, have %s in %s, at %s:%d",
		  buffer, get_tree_code_name (TREE_CODE (node)),
		  function, trim_filename (file), line);
}


/* Similar to tree_check_failed, except that we check that a tree does
   not have the specified code, given in CL.  */

void
tree_not_class_check_failed (const_tree node, const enum tree_code_class cl,
			     const char *file, int line, const char *function)
{
  internal_error
    ("tree check: did not expect class %qs, have %qs (%s) in %s, at %s:%d",
     TREE_CODE_CLASS_STRING (cl),
     TREE_CODE_CLASS_STRING (TREE_CODE_CLASS (TREE_CODE (node))),
     get_tree_code_name (TREE_CODE (node)), function, trim_filename (file), line);
}


/* Similar to tree_check_failed but applied to OMP_CLAUSE codes.  */

void
omp_clause_check_failed (const_tree node, const char *file, int line,
                         const char *function, enum omp_clause_code code)
{
  internal_error ("tree check: expected omp_clause %s, have %s in %s, at %s:%d",
		  omp_clause_code_name[code], get_tree_code_name (TREE_CODE (node)),
		  function, trim_filename (file), line);
}


/* Similar to tree_range_check_failed but applied to OMP_CLAUSE codes.  */

void
omp_clause_range_check_failed (const_tree node, const char *file, int line,
			       const char *function, enum omp_clause_code c1,
			       enum omp_clause_code c2)
{
  char *buffer;
  unsigned length = 0;
  unsigned int c;

  for (c = c1; c <= c2; ++c)
    length += 4 + strlen (omp_clause_code_name[c]);

  length += strlen ("expected ");
  buffer = (char *) alloca (length);
  length = 0;

  for (c = c1; c <= c2; ++c)
    {
      const char *prefix = length ? " or " : "expected ";

      strcpy (buffer + length, prefix);
      length += strlen (prefix);
      strcpy (buffer + length, omp_clause_code_name[c]);
      length += strlen (omp_clause_code_name[c]);
    }

  internal_error ("tree check: %s, have %s in %s, at %s:%d",
		  buffer, omp_clause_code_name[TREE_CODE (node)],
		  function, trim_filename (file), line);
}


#undef DEFTREESTRUCT
#define DEFTREESTRUCT(VAL, NAME) NAME,

static const char *ts_enum_names[] = {
#include "treestruct.def"
};
#undef DEFTREESTRUCT

#define TS_ENUM_NAME(EN) (ts_enum_names[(EN)])

/* Similar to tree_class_check_failed, except that we check for
   whether CODE contains the tree structure identified by EN.  */

void
tree_contains_struct_check_failed (const_tree node,
				   const enum tree_node_structure_enum en,
				   const char *file, int line,
				   const char *function)
{
  internal_error
    ("tree check: expected tree that contains %qs structure, have %qs in %s, at %s:%d",
     TS_ENUM_NAME (en),
     get_tree_code_name (TREE_CODE (node)), function, trim_filename (file), line);
}


/* Similar to above, except that the check is for the bounds of a TREE_VEC's
   (dynamically sized) vector.  */

void
tree_int_cst_elt_check_failed (int idx, int len, const char *file, int line,
			       const char *function)
{
  internal_error
    ("tree check: accessed elt %d of tree_int_cst with %d elts in %s, at %s:%d",
     idx + 1, len, function, trim_filename (file), line);
}

/* Similar to above, except that the check is for the bounds of a TREE_VEC's
   (dynamically sized) vector.  */

void
tree_vec_elt_check_failed (int idx, int len, const char *file, int line,
			   const char *function)
{
  internal_error
    ("tree check: accessed elt %d of tree_vec with %d elts in %s, at %s:%d",
     idx + 1, len, function, trim_filename (file), line);
}

/* Similar to above, except that the check is for the bounds of the operand
   vector of an expression node EXP.  */

void
tree_operand_check_failed (int idx, const_tree exp, const char *file,
			   int line, const char *function)
{
  enum tree_code code = TREE_CODE (exp);
  internal_error
    ("tree check: accessed operand %d of %s with %d operands in %s, at %s:%d",
     idx + 1, get_tree_code_name (code), TREE_OPERAND_LENGTH (exp),
     function, trim_filename (file), line);
}

/* Similar to above, except that the check is for the number of
   operands of an OMP_CLAUSE node.  */

void
omp_clause_operand_check_failed (int idx, const_tree t, const char *file,
			         int line, const char *function)
{
  internal_error
    ("tree check: accessed operand %d of omp_clause %s with %d operands "
     "in %s, at %s:%d", idx + 1, omp_clause_code_name[OMP_CLAUSE_CODE (t)],
     omp_clause_num_ops [OMP_CLAUSE_CODE (t)], function,
     trim_filename (file), line);
}
#endif /* ENABLE_TREE_CHECKING */

/* Create a new vector type node holding NUNITS units of type INNERTYPE,
   and mapped to the machine mode MODE.  Initialize its fields and build
   the information necessary for debugging output.  */

static tree
make_vector_type (tree innertype, poly_int64 nunits, machine_mode mode)
{
  tree t;
  tree mv_innertype = TYPE_MAIN_VARIANT (innertype);

  t = make_node (VECTOR_TYPE);
  TREE_TYPE (t) = mv_innertype;
  SET_TYPE_VECTOR_SUBPARTS (t, nunits);
  SET_TYPE_MODE (t, mode);

  if (TYPE_STRUCTURAL_EQUALITY_P (mv_innertype) || in_lto_p)
    SET_TYPE_STRUCTURAL_EQUALITY (t);
  else if ((TYPE_CANONICAL (mv_innertype) != innertype
	    || mode != VOIDmode)
	   && !VECTOR_BOOLEAN_TYPE_P (t))
    TYPE_CANONICAL (t)
      = make_vector_type (TYPE_CANONICAL (mv_innertype), nunits, VOIDmode);

  layout_type (t);

  hashval_t hash = type_hash_canon_hash (t);
  t = type_hash_canon (hash, t);

  /* We have built a main variant, based on the main variant of the
     inner type. Use it to build the variant we return.  */
  if ((TYPE_ATTRIBUTES (innertype) || TYPE_QUALS (innertype))
      && TREE_TYPE (t) != innertype)
    return build_type_attribute_qual_variant (t,
					      TYPE_ATTRIBUTES (innertype),
					      TYPE_QUALS (innertype));

  return t;
}

static tree
make_or_reuse_type (unsigned size, int unsignedp)
{
  int i;

  if (size == INT_TYPE_SIZE)
    return unsignedp ? unsigned_type_node : integer_type_node;
  if (size == CHAR_TYPE_SIZE)
    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
  if (size == SHORT_TYPE_SIZE)
    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
  if (size == LONG_TYPE_SIZE)
    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
  if (size == LONG_LONG_TYPE_SIZE)
    return (unsignedp ? long_long_unsigned_type_node
            : long_long_integer_type_node);

  for (i = 0; i < NUM_INT_N_ENTS; i ++)
    if (size == int_n_data[i].bitsize
	&& int_n_enabled_p[i])
      return (unsignedp ? int_n_trees[i].unsigned_type
	      : int_n_trees[i].signed_type);

  if (unsignedp)
    return make_unsigned_type (size);
  else
    return make_signed_type (size);
}

/* Create or reuse a fract type by SIZE, UNSIGNEDP, and SATP.  */

static tree
make_or_reuse_fract_type (unsigned size, int unsignedp, int satp)
{
  if (satp)
    {
      if (size == SHORT_FRACT_TYPE_SIZE)
	return unsignedp ? sat_unsigned_short_fract_type_node
			 : sat_short_fract_type_node;
      if (size == FRACT_TYPE_SIZE)
	return unsignedp ? sat_unsigned_fract_type_node : sat_fract_type_node;
      if (size == LONG_FRACT_TYPE_SIZE)
	return unsignedp ? sat_unsigned_long_fract_type_node
			 : sat_long_fract_type_node;
      if (size == LONG_LONG_FRACT_TYPE_SIZE)
	return unsignedp ? sat_unsigned_long_long_fract_type_node
			 : sat_long_long_fract_type_node;
    }
  else
    {
      if (size == SHORT_FRACT_TYPE_SIZE)
	return unsignedp ? unsigned_short_fract_type_node
			 : short_fract_type_node;
      if (size == FRACT_TYPE_SIZE)
	return unsignedp ? unsigned_fract_type_node : fract_type_node;
      if (size == LONG_FRACT_TYPE_SIZE)
	return unsignedp ? unsigned_long_fract_type_node
			 : long_fract_type_node;
      if (size == LONG_LONG_FRACT_TYPE_SIZE)
	return unsignedp ? unsigned_long_long_fract_type_node
			 : long_long_fract_type_node;
    }

  return make_fract_type (size, unsignedp, satp);
}

/* Create or reuse an accum type by SIZE, UNSIGNEDP, and SATP.  */

static tree
make_or_reuse_accum_type (unsigned size, int unsignedp, int satp)
{
  if (satp)
    {
      if (size == SHORT_ACCUM_TYPE_SIZE)
	return unsignedp ? sat_unsigned_short_accum_type_node
			 : sat_short_accum_type_node;
      if (size == ACCUM_TYPE_SIZE)
	return unsignedp ? sat_unsigned_accum_type_node : sat_accum_type_node;
      if (size == LONG_ACCUM_TYPE_SIZE)
	return unsignedp ? sat_unsigned_long_accum_type_node
			 : sat_long_accum_type_node;
      if (size == LONG_LONG_ACCUM_TYPE_SIZE)
	return unsignedp ? sat_unsigned_long_long_accum_type_node
			 : sat_long_long_accum_type_node;
    }
  else
    {
      if (size == SHORT_ACCUM_TYPE_SIZE)
	return unsignedp ? unsigned_short_accum_type_node
			 : short_accum_type_node;
      if (size == ACCUM_TYPE_SIZE)
	return unsignedp ? unsigned_accum_type_node : accum_type_node;
      if (size == LONG_ACCUM_TYPE_SIZE)
	return unsignedp ? unsigned_long_accum_type_node
			 : long_accum_type_node;
      if (size == LONG_LONG_ACCUM_TYPE_SIZE)
	return unsignedp ? unsigned_long_long_accum_type_node
			 : long_long_accum_type_node;
    }

  return make_accum_type (size, unsignedp, satp);
}


/* Create an atomic variant node for TYPE.  This routine is called
   during initialization of data types to create the 5 basic atomic
   types. The generic build_variant_type function requires these to
   already be set up in order to function properly, so cannot be
   called from there.  If ALIGN is non-zero, then ensure alignment is
   overridden to this value.  */

static tree
build_atomic_base (tree type, unsigned int align)
{
  tree t;

  /* Make sure its not already registered.  */
  if ((t = get_qualified_type (type, TYPE_QUAL_ATOMIC)))
    return t;
  
  t = build_variant_type_copy (type);
  set_type_quals (t, TYPE_QUAL_ATOMIC);

  if (align)
    SET_TYPE_ALIGN (t, align);

  return t;
}

/* Information about the _FloatN and _FloatNx types.  This must be in
   the same order as the corresponding TI_* enum values.  */
const floatn_type_info floatn_nx_types[NUM_FLOATN_NX_TYPES] =
  {
    { 16, false },
    { 32, false },
    { 64, false },
    { 128, false },
    { 32, true },
    { 64, true },
    { 128, true },
  };


/* Create nodes for all integer types (and error_mark_node) using the sizes
   of C datatypes.  SIGNED_CHAR specifies whether char is signed.  */

void
build_common_tree_nodes (bool signed_char)
{
  int i;

  error_mark_node = make_node (ERROR_MARK);
  TREE_TYPE (error_mark_node) = error_mark_node;

  initialize_sizetypes ();

  /* Define both `signed char' and `unsigned char'.  */
  signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
  TYPE_STRING_FLAG (signed_char_type_node) = 1;
  unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
  TYPE_STRING_FLAG (unsigned_char_type_node) = 1;

  /* Define `char', which is like either `signed char' or `unsigned char'
     but not the same as either.  */
  char_type_node
    = (signed_char
       ? make_signed_type (CHAR_TYPE_SIZE)
       : make_unsigned_type (CHAR_TYPE_SIZE));
  TYPE_STRING_FLAG (char_type_node) = 1;

  short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
  short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
  integer_type_node = make_signed_type (INT_TYPE_SIZE);
  unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE);
  long_integer_type_node = make_signed_type (LONG_TYPE_SIZE);
  long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE);
  long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE);
  long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE);

  for (i = 0; i < NUM_INT_N_ENTS; i ++)
    {
      int_n_trees[i].signed_type = make_signed_type (int_n_data[i].bitsize);
      int_n_trees[i].unsigned_type = make_unsigned_type (int_n_data[i].bitsize);

      if (int_n_enabled_p[i])
	{
	  integer_types[itk_intN_0 + i * 2] = int_n_trees[i].signed_type;
	  integer_types[itk_unsigned_intN_0 + i * 2] = int_n_trees[i].unsigned_type;
	}
    }

  /* Define a boolean type.  This type only represents boolean values but
     may be larger than char depending on the value of BOOL_TYPE_SIZE.  */
  boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
  TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
  TYPE_PRECISION (boolean_type_node) = 1;
  TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1);

  /* Define what type to use for size_t.  */
  if (strcmp (SIZE_TYPE, "unsigned int") == 0)
    size_type_node = unsigned_type_node;
  else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
    size_type_node = long_unsigned_type_node;
  else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
    size_type_node = long_long_unsigned_type_node;
  else if (strcmp (SIZE_TYPE, "short unsigned int") == 0)
    size_type_node = short_unsigned_type_node;
  else
    {
      int i;

      size_type_node = NULL_TREE;
      for (i = 0; i < NUM_INT_N_ENTS; i++)
	if (int_n_enabled_p[i])
	  {
	    char name[50];
	    sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);

	    if (strcmp (name, SIZE_TYPE) == 0)
	      {
		size_type_node = int_n_trees[i].unsigned_type;
	      }
	  }
      if (size_type_node == NULL_TREE)
	gcc_unreachable ();
    }

  /* Define what type to use for ptrdiff_t.  */
  if (strcmp (PTRDIFF_TYPE, "int") == 0)
    ptrdiff_type_node = integer_type_node;
  else if (strcmp (PTRDIFF_TYPE, "long int") == 0)
    ptrdiff_type_node = long_integer_type_node;
  else if (strcmp (PTRDIFF_TYPE, "long long int") == 0)
    ptrdiff_type_node = long_long_integer_type_node;
  else if (strcmp (PTRDIFF_TYPE, "short int") == 0)
    ptrdiff_type_node = short_integer_type_node;
  else
    {
      ptrdiff_type_node = NULL_TREE;
      for (int i = 0; i < NUM_INT_N_ENTS; i++)
	if (int_n_enabled_p[i])
	  {
	    char name[50];
	    sprintf (name, "__int%d", int_n_data[i].bitsize);
	    if (strcmp (name, PTRDIFF_TYPE) == 0)
	      ptrdiff_type_node = int_n_trees[i].signed_type;
	  }
      if (ptrdiff_type_node == NULL_TREE)
	gcc_unreachable ();
    }

  /* Fill in the rest of the sized types.  Reuse existing type nodes
     when possible.  */
  intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 0);
  intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 0);
  intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 0);
  intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 0);
  intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 0);

  unsigned_intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 1);
  unsigned_intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 1);
  unsigned_intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 1);
  unsigned_intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 1);
  unsigned_intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 1);

  /* Don't call build_qualified type for atomics.  That routine does
     special processing for atomics, and until they are initialized
     it's better not to make that call.
     
     Check to see if there is a target override for atomic types.  */

  atomicQI_type_node = build_atomic_base (unsigned_intQI_type_node,
					targetm.atomic_align_for_mode (QImode));
  atomicHI_type_node = build_atomic_base (unsigned_intHI_type_node,
					targetm.atomic_align_for_mode (HImode));
  atomicSI_type_node = build_atomic_base (unsigned_intSI_type_node,
					targetm.atomic_align_for_mode (SImode));
  atomicDI_type_node = build_atomic_base (unsigned_intDI_type_node,
					targetm.atomic_align_for_mode (DImode));
  atomicTI_type_node = build_atomic_base (unsigned_intTI_type_node,
					targetm.atomic_align_for_mode (TImode));
  	
  access_public_node = get_identifier ("public");
  access_protected_node = get_identifier ("protected");
  access_private_node = get_identifier ("private");

  /* Define these next since types below may used them.  */
  integer_zero_node = build_int_cst (integer_type_node, 0);
  integer_one_node = build_int_cst (integer_type_node, 1);
  integer_three_node = build_int_cst (integer_type_node, 3);
  integer_minus_one_node = build_int_cst (integer_type_node, -1);

  size_zero_node = size_int (0);
  size_one_node = size_int (1);
  bitsize_zero_node = bitsize_int (0);
  bitsize_one_node = bitsize_int (1);
  bitsize_unit_node = bitsize_int (BITS_PER_UNIT);

  boolean_false_node = TYPE_MIN_VALUE (boolean_type_node);
  boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);

  void_type_node = make_node (VOID_TYPE);
  layout_type (void_type_node);

  /* We are not going to have real types in C with less than byte alignment,
     so we might as well not have any types that claim to have it.  */
  SET_TYPE_ALIGN (void_type_node, BITS_PER_UNIT);
  TYPE_USER_ALIGN (void_type_node) = 0;

  void_node = make_node (VOID_CST);
  TREE_TYPE (void_node) = void_type_node;

  null_pointer_node = build_int_cst (build_pointer_type (void_type_node), 0);
  layout_type (TREE_TYPE (null_pointer_node));

  ptr_type_node = build_pointer_type (void_type_node);
  const_ptr_type_node
    = build_pointer_type (build_type_variant (void_type_node, 1, 0));
  for (unsigned i = 0;
       i < sizeof (builtin_structptr_types) / sizeof (builtin_structptr_type);
       ++i)
    builtin_structptr_types[i].node = builtin_structptr_types[i].base;

  pointer_sized_int_node = build_nonstandard_integer_type (POINTER_SIZE, 1);

  float_type_node = make_node (REAL_TYPE);
  TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
  layout_type (float_type_node);

  double_type_node = make_node (REAL_TYPE);
  TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE;
  layout_type (double_type_node);

  long_double_type_node = make_node (REAL_TYPE);
  TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
  layout_type (long_double_type_node);

  for (i = 0; i < NUM_FLOATN_NX_TYPES; i++)
    {
      int n = floatn_nx_types[i].n;
      bool extended = floatn_nx_types[i].extended;
      scalar_float_mode mode;
      if (!targetm.floatn_mode (n, extended).exists (&mode))
	continue;
      int precision = GET_MODE_PRECISION (mode);
      /* Work around the rs6000 KFmode having precision 113 not
	 128.  */
      const struct real_format *fmt = REAL_MODE_FORMAT (mode);
      gcc_assert (fmt->b == 2 && fmt->emin + fmt->emax == 3);
      int min_precision = fmt->p + ceil_log2 (fmt->emax - fmt->emin);
      if (!extended)
	gcc_assert (min_precision == n);
      if (precision < min_precision)
	precision = min_precision;
      FLOATN_NX_TYPE_NODE (i) = make_node (REAL_TYPE);
      TYPE_PRECISION (FLOATN_NX_TYPE_NODE (i)) = precision;
      layout_type (FLOATN_NX_TYPE_NODE (i));
      SET_TYPE_MODE (FLOATN_NX_TYPE_NODE (i), mode);
    }

  float_ptr_type_node = build_pointer_type (float_type_node);
  double_ptr_type_node = build_pointer_type (double_type_node);
  long_double_ptr_type_node = build_pointer_type (long_double_type_node);
  integer_ptr_type_node = build_pointer_type (integer_type_node);

  /* Fixed size integer types.  */
  uint16_type_node = make_or_reuse_type (16, 1);
  uint32_type_node = make_or_reuse_type (32, 1);
  uint64_type_node = make_or_reuse_type (64, 1);

  /* Decimal float types. */
  dfloat32_type_node = make_node (REAL_TYPE);
  TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE;
  SET_TYPE_MODE (dfloat32_type_node, SDmode);
  layout_type (dfloat32_type_node);
  dfloat32_ptr_type_node = build_pointer_type (dfloat32_type_node);

  dfloat64_type_node = make_node (REAL_TYPE);
  TYPE_PRECISION (dfloat64_type_node) = DECIMAL64_TYPE_SIZE;
  SET_TYPE_MODE (dfloat64_type_node, DDmode);
  layout_type (dfloat64_type_node);
  dfloat64_ptr_type_node = build_pointer_type (dfloat64_type_node);

  dfloat128_type_node = make_node (REAL_TYPE);
  TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE;
  SET_TYPE_MODE (dfloat128_type_node, TDmode);
  layout_type (dfloat128_type_node);
  dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);

  complex_integer_type_node = build_complex_type (integer_type_node, true);
  complex_float_type_node = build_complex_type (float_type_node, true);
  complex_double_type_node = build_complex_type (double_type_node, true);
  complex_long_double_type_node = build_complex_type (long_double_type_node,
						      true);

  for (i = 0; i < NUM_FLOATN_NX_TYPES; i++)
    {
      if (FLOATN_NX_TYPE_NODE (i) != NULL_TREE)
	COMPLEX_FLOATN_NX_TYPE_NODE (i)
	  = build_complex_type (FLOATN_NX_TYPE_NODE (i));
    }

/* Make fixed-point nodes based on sat/non-sat and signed/unsigned.  */
#define MAKE_FIXED_TYPE_NODE(KIND,SIZE) \
  sat_ ## KIND ## _type_node = \
    make_sat_signed_ ## KIND ## _type (SIZE); \
  sat_unsigned_ ## KIND ## _type_node = \
    make_sat_unsigned_ ## KIND ## _type (SIZE); \
  KIND ## _type_node = make_signed_ ## KIND ## _type (SIZE); \
  unsigned_ ## KIND ## _type_node = \
    make_unsigned_ ## KIND ## _type (SIZE);

#define MAKE_FIXED_TYPE_NODE_WIDTH(KIND,WIDTH,SIZE) \
  sat_ ## WIDTH ## KIND ## _type_node = \
    make_sat_signed_ ## KIND ## _type (SIZE); \
  sat_unsigned_ ## WIDTH ## KIND ## _type_node = \
    make_sat_unsigned_ ## KIND ## _type (SIZE); \
  WIDTH ## KIND ## _type_node = make_signed_ ## KIND ## _type (SIZE); \
  unsigned_ ## WIDTH ## KIND ## _type_node = \
    make_unsigned_ ## KIND ## _type (SIZE);

/* Make fixed-point type nodes based on four different widths.  */
#define MAKE_FIXED_TYPE_NODE_FAMILY(N1,N2) \
  MAKE_FIXED_TYPE_NODE_WIDTH (N1, short_, SHORT_ ## N2 ## _TYPE_SIZE) \
  MAKE_FIXED_TYPE_NODE (N1, N2 ## _TYPE_SIZE) \
  MAKE_FIXED_TYPE_NODE_WIDTH (N1, long_, LONG_ ## N2 ## _TYPE_SIZE) \
  MAKE_FIXED_TYPE_NODE_WIDTH (N1, long_long_, LONG_LONG_ ## N2 ## _TYPE_SIZE)

/* Make fixed-point mode nodes based on sat/non-sat and signed/unsigned.  */
#define MAKE_FIXED_MODE_NODE(KIND,NAME,MODE) \
  NAME ## _type_node = \
    make_or_reuse_signed_ ## KIND ## _type (GET_MODE_BITSIZE (MODE ## mode)); \
  u ## NAME ## _type_node = \
    make_or_reuse_unsigned_ ## KIND ## _type \
      (GET_MODE_BITSIZE (U ## MODE ## mode)); \
  sat_ ## NAME ## _type_node = \
    make_or_reuse_sat_signed_ ## KIND ## _type \
      (GET_MODE_BITSIZE (MODE ## mode)); \
  sat_u ## NAME ## _type_node = \
    make_or_reuse_sat_unsigned_ ## KIND ## _type \
      (GET_MODE_BITSIZE (U ## MODE ## mode));

  /* Fixed-point type and mode nodes.  */
  MAKE_FIXED_TYPE_NODE_FAMILY (fract, FRACT)
  MAKE_FIXED_TYPE_NODE_FAMILY (accum, ACCUM)
  MAKE_FIXED_MODE_NODE (fract, qq, QQ)
  MAKE_FIXED_MODE_NODE (fract, hq, HQ)
  MAKE_FIXED_MODE_NODE (fract, sq, SQ)
  MAKE_FIXED_MODE_NODE (fract, dq, DQ)
  MAKE_FIXED_MODE_NODE (fract, tq, TQ)
  MAKE_FIXED_MODE_NODE (accum, ha, HA)
  MAKE_FIXED_MODE_NODE (accum, sa, SA)
  MAKE_FIXED_MODE_NODE (accum, da, DA)
  MAKE_FIXED_MODE_NODE (accum, ta, TA)

  {
    tree t = targetm.build_builtin_va_list ();

    /* Many back-ends define record types without setting TYPE_NAME.
       If we copied the record type here, we'd keep the original
       record type without a name.  This breaks name mangling.  So,
       don't copy record types and let c_common_nodes_and_builtins()
       declare the type to be __builtin_va_list.  */
    if (TREE_CODE (t) != RECORD_TYPE)
      t = build_variant_type_copy (t);

    va_list_type_node = t;
  }
}

/* Modify DECL for given flags.
   TM_PURE attribute is set only on types, so the function will modify
   DECL's type when ECF_TM_PURE is used.  */

void
set_call_expr_flags (tree decl, int flags)
{
  if (flags & ECF_NOTHROW)
    TREE_NOTHROW (decl) = 1;
  if (flags & ECF_CONST)
    TREE_READONLY (decl) = 1;
  if (flags & ECF_PURE)
    DECL_PURE_P (decl) = 1;
  if (flags & ECF_LOOPING_CONST_OR_PURE)
    DECL_LOOPING_CONST_OR_PURE_P (decl) = 1;
  if (flags & ECF_NOVOPS)
    DECL_IS_NOVOPS (decl) = 1;
  if (flags & ECF_NORETURN)
    TREE_THIS_VOLATILE (decl) = 1;
  if (flags & ECF_MALLOC)
    DECL_IS_MALLOC (decl) = 1;
  if (flags & ECF_RETURNS_TWICE)
    DECL_IS_RETURNS_TWICE (decl) = 1;
  if (flags & ECF_LEAF)
    DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
					NULL, DECL_ATTRIBUTES (decl));
  if (flags & ECF_COLD)
    DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("cold"),
					NULL, DECL_ATTRIBUTES (decl));
  if (flags & ECF_RET1)
    DECL_ATTRIBUTES (decl)
      = tree_cons (get_identifier ("fn spec"),
		   build_tree_list (NULL_TREE, build_string (1, "1")),
		   DECL_ATTRIBUTES (decl));
  if ((flags & ECF_TM_PURE) && flag_tm)
    apply_tm_attr (decl, get_identifier ("transaction_pure"));
  /* Looping const or pure is implied by noreturn.
     There is currently no way to declare looping const or looping pure alone.  */
  gcc_assert (!(flags & ECF_LOOPING_CONST_OR_PURE)
	      || ((flags & ECF_NORETURN) && (flags & (ECF_CONST | ECF_PURE))));
}


/* A subroutine of build_common_builtin_nodes.  Define a builtin function.  */

static void
local_define_builtin (const char *name, tree type, enum built_in_function code,
                      const char *library_name, int ecf_flags)
{
  tree decl;

  decl = add_builtin_function (name, type, code, BUILT_IN_NORMAL,
			       library_name, NULL_TREE);
  set_call_expr_flags (decl, ecf_flags);

  set_builtin_decl (code, decl, true);
}

/* Call this function after instantiating all builtins that the language
   front end cares about.  This will build the rest of the builtins
   and internal functions that are relied upon by the tree optimizers and
   the middle-end.  */

void
build_common_builtin_nodes (void)
{
  tree tmp, ftype;
  int ecf_flags;

  if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE)
      || !builtin_decl_explicit_p (BUILT_IN_ABORT))
    {
      ftype = build_function_type (void_type_node, void_list_node);
      if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE))
	local_define_builtin ("__builtin_unreachable", ftype,
			      BUILT_IN_UNREACHABLE,
			      "__builtin_unreachable",
			      ECF_NOTHROW | ECF_LEAF | ECF_NORETURN
			      | ECF_CONST | ECF_COLD);
      if (!builtin_decl_explicit_p (BUILT_IN_ABORT))
	local_define_builtin ("__builtin_abort", ftype, BUILT_IN_ABORT,
			      "abort",
			      ECF_LEAF | ECF_NORETURN | ECF_CONST | ECF_COLD);
    }

  if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY)
      || !builtin_decl_explicit_p (BUILT_IN_MEMMOVE))
    {
      ftype = build_function_type_list (ptr_type_node,
					ptr_type_node, const_ptr_type_node,
					size_type_node, NULL_TREE);

      if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY))
	local_define_builtin ("__builtin_memcpy", ftype, BUILT_IN_MEMCPY,
			      "memcpy", ECF_NOTHROW | ECF_LEAF | ECF_RET1);
      if (!builtin_decl_explicit_p (BUILT_IN_MEMMOVE))
	local_define_builtin ("__builtin_memmove", ftype, BUILT_IN_MEMMOVE,
			      "memmove", ECF_NOTHROW | ECF_LEAF | ECF_RET1);
    }

  if (!builtin_decl_explicit_p (BUILT_IN_MEMCMP))
    {
      ftype = build_function_type_list (integer_type_node, const_ptr_type_node,
					const_ptr_type_node, size_type_node,
					NULL_TREE);
      local_define_builtin ("__builtin_memcmp", ftype, BUILT_IN_MEMCMP,
			    "memcmp", ECF_PURE | ECF_NOTHROW | ECF_LEAF);
    }

  if (!builtin_decl_explicit_p (BUILT_IN_MEMSET))
    {
      ftype = build_function_type_list (ptr_type_node,
					ptr_type_node, integer_type_node,
					size_type_node, NULL_TREE);
      local_define_builtin ("__builtin_memset", ftype, BUILT_IN_MEMSET,
			    "memset", ECF_NOTHROW | ECF_LEAF | ECF_RET1);
    }

  /* If we're checking the stack, `alloca' can throw.  */
  const int alloca_flags
    = ECF_MALLOC | ECF_LEAF | (flag_stack_check ? 0 : ECF_NOTHROW);

  if (!builtin_decl_explicit_p (BUILT_IN_ALLOCA))
    {
      ftype = build_function_type_list (ptr_type_node,
					size_type_node, NULL_TREE);
      local_define_builtin ("__builtin_alloca", ftype, BUILT_IN_ALLOCA,
			    "alloca", alloca_flags);
    }

  ftype = build_function_type_list (ptr_type_node, size_type_node,
				    size_type_node, NULL_TREE);
  local_define_builtin ("__builtin_alloca_with_align", ftype,
			BUILT_IN_ALLOCA_WITH_ALIGN,
			"__builtin_alloca_with_align",
			alloca_flags);

  ftype = build_function_type_list (ptr_type_node, size_type_node,
				    size_type_node, size_type_node, NULL_TREE);
  local_define_builtin ("__builtin_alloca_with_align_and_max", ftype,
			BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX,
			"__builtin_alloca_with_align_and_max",
			alloca_flags);

  ftype = build_function_type_list (void_type_node,
				    ptr_type_node, ptr_type_node,
				    ptr_type_node, NULL_TREE);
  local_define_builtin ("__builtin_init_trampoline", ftype,
			BUILT_IN_INIT_TRAMPOLINE,
			"__builtin_init_trampoline", ECF_NOTHROW | ECF_LEAF);
  local_define_builtin ("__builtin_init_heap_trampoline", ftype,
			BUILT_IN_INIT_HEAP_TRAMPOLINE,
			"__builtin_init_heap_trampoline",
			ECF_NOTHROW | ECF_LEAF);
  local_define_builtin ("__builtin_init_descriptor", ftype,
			BUILT_IN_INIT_DESCRIPTOR,
			"__builtin_init_descriptor", ECF_NOTHROW | ECF_LEAF);

  ftype = build_function_type_list (ptr_type_node, ptr_type_node, NULL_TREE);
  local_define_builtin ("__builtin_adjust_trampoline", ftype,
			BUILT_IN_ADJUST_TRAMPOLINE,
			"__builtin_adjust_trampoline",
			ECF_CONST | ECF_NOTHROW);
  local_define_builtin ("__builtin_adjust_descriptor", ftype,
			BUILT_IN_ADJUST_DESCRIPTOR,
			"__builtin_adjust_descriptor",
			ECF_CONST | ECF_NOTHROW);

  ftype = build_function_type_list (void_type_node,
				    ptr_type_node, ptr_type_node, NULL_TREE);
  local_define_builtin ("__builtin_nonlocal_goto", ftype,
			BUILT_IN_NONLOCAL_GOTO,
			"__builtin_nonlocal_goto",
			ECF_NORETURN | ECF_NOTHROW);

  ftype = build_function_type_list (void_type_node,
				    ptr_type_node, ptr_type_node, NULL_TREE);
  local_define_builtin ("__builtin_setjmp_setup", ftype,
			BUILT_IN_SETJMP_SETUP,
			"__builtin_setjmp_setup", ECF_NOTHROW);

  ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
  local_define_builtin ("__builtin_setjmp_receiver", ftype,
			BUILT_IN_SETJMP_RECEIVER,
			"__builtin_setjmp_receiver", ECF_NOTHROW | ECF_LEAF);

  ftype = build_function_type_list (ptr_type_node, NULL_TREE);
  local_define_builtin ("__builtin_stack_save", ftype, BUILT_IN_STACK_SAVE,
			"__builtin_stack_save", ECF_NOTHROW | ECF_LEAF);

  ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
  local_define_builtin ("__builtin_stack_restore", ftype,
			BUILT_IN_STACK_RESTORE,
			"__builtin_stack_restore", ECF_NOTHROW | ECF_LEAF);

  ftype = build_function_type_list (integer_type_node, const_ptr_type_node,
				    const_ptr_type_node, size_type_node,
				    NULL_TREE);
  local_define_builtin ("__builtin_memcmp_eq", ftype, BUILT_IN_MEMCMP_EQ,
			"__builtin_memcmp_eq",
			ECF_PURE | ECF_NOTHROW | ECF_LEAF);

  local_define_builtin ("__builtin_strncmp_eq", ftype, BUILT_IN_STRNCMP_EQ,
			"__builtin_strncmp_eq",
			ECF_PURE | ECF_NOTHROW | ECF_LEAF);

  local_define_builtin ("__builtin_strcmp_eq", ftype, BUILT_IN_STRCMP_EQ,
			"__builtin_strcmp_eq",
			ECF_PURE | ECF_NOTHROW | ECF_LEAF);

  /* If there's a possibility that we might use the ARM EABI, build the
    alternate __cxa_end_cleanup node used to resume from C++.  */
  if (targetm.arm_eabi_unwinder)
    {
      ftype = build_function_type_list (void_type_node, NULL_TREE);
      local_define_builtin ("__builtin_cxa_end_cleanup", ftype,
			    BUILT_IN_CXA_END_CLEANUP,
			    "__cxa_end_cleanup", ECF_NORETURN | ECF_LEAF);
    }

  ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
  local_define_builtin ("__builtin_unwind_resume", ftype,
			BUILT_IN_UNWIND_RESUME,
			((targetm_common.except_unwind_info (&global_options)
			  == UI_SJLJ)
			 ? "_Unwind_SjLj_Resume" : "_Unwind_Resume"),
			ECF_NORETURN);

  if (builtin_decl_explicit (BUILT_IN_RETURN_ADDRESS) == NULL_TREE)
    {
      ftype = build_function_type_list (ptr_type_node, integer_type_node,
					NULL_TREE);
      local_define_builtin ("__builtin_return_address", ftype,
			    BUILT_IN_RETURN_ADDRESS,
			    "__builtin_return_address",
			    ECF_NOTHROW);
    }

  if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_ENTER)
      || !builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_EXIT))
    {
      ftype = build_function_type_list (void_type_node, ptr_type_node,
					ptr_type_node, NULL_TREE);
      if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_ENTER))
	local_define_builtin ("__cyg_profile_func_enter", ftype,
			      BUILT_IN_PROFILE_FUNC_ENTER,
			      "__cyg_profile_func_enter", 0);
      if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_EXIT))
	local_define_builtin ("__cyg_profile_func_exit", ftype,
			      BUILT_IN_PROFILE_FUNC_EXIT,
			      "__cyg_profile_func_exit", 0);
    }

  /* The exception object and filter values from the runtime.  The argument
     must be zero before exception lowering, i.e. from the front end.  After
     exception lowering, it will be the region number for the exception
     landing pad.  These functions are PURE instead of CONST to prevent
     them from being hoisted past the exception edge that will initialize
     its value in the landing pad.  */
  ftype = build_function_type_list (ptr_type_node,
				    integer_type_node, NULL_TREE);
  ecf_flags = ECF_PURE | ECF_NOTHROW | ECF_LEAF;
  /* Only use TM_PURE if we have TM language support.  */
  if (builtin_decl_explicit_p (BUILT_IN_TM_LOAD_1))
    ecf_flags |= ECF_TM_PURE;
  local_define_builtin ("__builtin_eh_pointer", ftype, BUILT_IN_EH_POINTER,
			"__builtin_eh_pointer", ecf_flags);

  tmp = lang_hooks.types.type_for_mode (targetm.eh_return_filter_mode (), 0);
  ftype = build_function_type_list (tmp, integer_type_node, NULL_TREE);
  local_define_builtin ("__builtin_eh_filter", ftype, BUILT_IN_EH_FILTER,
			"__builtin_eh_filter", ECF_PURE | ECF_NOTHROW | ECF_LEAF);

  ftype = build_function_type_list (void_type_node,
				    integer_type_node, integer_type_node,
				    NULL_TREE);
  local_define_builtin ("__builtin_eh_copy_values", ftype,
			BUILT_IN_EH_COPY_VALUES,
			"__builtin_eh_copy_values", ECF_NOTHROW);

  /* Complex multiplication and division.  These are handled as builtins
     rather than optabs because emit_library_call_value doesn't support
     complex.  Further, we can do slightly better with folding these
     beasties if the real and complex parts of the arguments are separate.  */
  {
    int mode;

    for (mode = MIN_MODE_COMPLEX_FLOAT; mode <= MAX_MODE_COMPLEX_FLOAT; ++mode)
      {
	char mode_name_buf[4], *q;
	const char *p;
	enum built_in_function mcode, dcode;
	tree type, inner_type;
	const char *prefix = "__";

	if (targetm.libfunc_gnu_prefix)
	  prefix = "__gnu_";

	type = lang_hooks.types.type_for_mode ((machine_mode) mode, 0);
	if (type == NULL)
	  continue;
	inner_type = TREE_TYPE (type);

	ftype = build_function_type_list (type, inner_type, inner_type,
					  inner_type, inner_type, NULL_TREE);

        mcode = ((enum built_in_function)
		 (BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
        dcode = ((enum built_in_function)
		 (BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT));

        for (p = GET_MODE_NAME (mode), q = mode_name_buf; *p; p++, q++)
	  *q = TOLOWER (*p);
	*q = '\0';

	/* For -ftrapping-math these should throw from a former
	   -fnon-call-exception stmt.  */
	built_in_names[mcode] = concat (prefix, "mul", mode_name_buf, "3",
					NULL);
        local_define_builtin (built_in_names[mcode], ftype, mcode,
			      built_in_names[mcode],
			      ECF_CONST | ECF_LEAF);

	built_in_names[dcode] = concat (prefix, "div", mode_name_buf, "3",
					NULL);
        local_define_builtin (built_in_names[dcode], ftype, dcode,
			      built_in_names[dcode],
			      ECF_CONST | ECF_LEAF);
      }
  }

  init_internal_fns ();
}

/* HACK.  GROSS.  This is absolutely disgusting.  I wish there was a
   better way.

   If we requested a pointer to a vector, build up the pointers that
   we stripped off while looking for the inner type.  Similarly for
   return values from functions.

   The argument TYPE is the top of the chain, and BOTTOM is the
   new type which we will point to.  */

tree
reconstruct_complex_type (tree type, tree bottom)
{
  tree inner, outer;

  if (TREE_CODE (type) == POINTER_TYPE)
    {
      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
      outer = build_pointer_type_for_mode (inner, TYPE_MODE (type),
					   TYPE_REF_CAN_ALIAS_ALL (type));
    }
  else if (TREE_CODE (type) == REFERENCE_TYPE)
    {
      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
      outer = build_reference_type_for_mode (inner, TYPE_MODE (type),
					     TYPE_REF_CAN_ALIAS_ALL (type));
    }
  else if (TREE_CODE (type) == ARRAY_TYPE)
    {
      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
      outer = build_array_type (inner, TYPE_DOMAIN (type));
    }
  else if (TREE_CODE (type) == FUNCTION_TYPE)
    {
      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
      outer = build_function_type (inner, TYPE_ARG_TYPES (type));
    }
  else if (TREE_CODE (type) == METHOD_TYPE)
    {
      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
      /* The build_method_type_directly() routine prepends 'this' to argument list,
         so we must compensate by getting rid of it.  */
      outer
	= build_method_type_directly
	    (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))),
	     inner,
	     TREE_CHAIN (TYPE_ARG_TYPES (type)));
    }
  else if (TREE_CODE (type) == OFFSET_TYPE)
    {
      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
      outer = build_offset_type (TYPE_OFFSET_BASETYPE (type), inner);
    }
  else
    return bottom;

  return build_type_attribute_qual_variant (outer, TYPE_ATTRIBUTES (type),
					    TYPE_QUALS (type));
}

/* Returns a vector tree node given a mode (integer, vector, or BLKmode) and
   the inner type.  */
tree
build_vector_type_for_mode (tree innertype, machine_mode mode)
{
  poly_int64 nunits;
  unsigned int bitsize;

  switch (GET_MODE_CLASS (mode))
    {
    case MODE_VECTOR_BOOL:
    case MODE_VECTOR_INT:
    case MODE_VECTOR_FLOAT:
    case MODE_VECTOR_FRACT:
    case MODE_VECTOR_UFRACT:
    case MODE_VECTOR_ACCUM:
    case MODE_VECTOR_UACCUM:
      nunits = GET_MODE_NUNITS (mode);
      break;

    case MODE_INT:
      /* Check that there are no leftover bits.  */
      bitsize = GET_MODE_BITSIZE (as_a <scalar_int_mode> (mode));
      gcc_assert (bitsize % TREE_INT_CST_LOW (TYPE_SIZE (innertype)) == 0);
      nunits = bitsize / TREE_INT_CST_LOW (TYPE_SIZE (innertype));
      break;

    default:
      gcc_unreachable ();
    }

  return make_vector_type (innertype, nunits, mode);
}

/* Similarly, but takes the inner type and number of units, which must be
   a power of two.  */

tree
build_vector_type (tree innertype, poly_int64 nunits)
{
  return make_vector_type (innertype, nunits, VOIDmode);
}

/* Build truth vector with specified length and number of units.  */

tree
build_truth_vector_type (poly_uint64 nunits, poly_uint64 vector_size)
{
  machine_mode mask_mode
    = targetm.vectorize.get_mask_mode (nunits, vector_size).else_blk ();

  poly_uint64 vsize;
  if (mask_mode == BLKmode)
    vsize = vector_size * BITS_PER_UNIT;
  else
    vsize = GET_MODE_BITSIZE (mask_mode);

  unsigned HOST_WIDE_INT esize = vector_element_size (vsize, nunits);

  tree bool_type = build_nonstandard_boolean_type (esize);

  return make_vector_type (bool_type, nunits, mask_mode);
}

/* Returns a vector type corresponding to a comparison of VECTYPE.  */

tree
build_same_sized_truth_vector_type (tree vectype)
{
  if (VECTOR_BOOLEAN_TYPE_P (vectype))
    return vectype;

  poly_uint64 size = GET_MODE_SIZE (TYPE_MODE (vectype));

  if (known_eq (size, 0U))
    size = tree_to_uhwi (TYPE_SIZE_UNIT (vectype));

  return build_truth_vector_type (TYPE_VECTOR_SUBPARTS (vectype), size);
}

/* Similarly, but builds a variant type with TYPE_VECTOR_OPAQUE set.  */

tree
build_opaque_vector_type (tree innertype, poly_int64 nunits)
{
  tree t = make_vector_type (innertype, nunits, VOIDmode);
  tree cand;
  /* We always build the non-opaque variant before the opaque one,
     so if it already exists, it is TYPE_NEXT_VARIANT of this one.  */
  cand = TYPE_NEXT_VARIANT (t);
  if (cand
      && TYPE_VECTOR_OPAQUE (cand)
      && check_qualified_type (cand, t, TYPE_QUALS (t)))
    return cand;
  /* Othewise build a variant type and make sure to queue it after
     the non-opaque type.  */
  cand = build_distinct_type_copy (t);
  TYPE_VECTOR_OPAQUE (cand) = true;
  TYPE_CANONICAL (cand) = TYPE_CANONICAL (t);
  TYPE_NEXT_VARIANT (cand) = TYPE_NEXT_VARIANT (t);
  TYPE_NEXT_VARIANT (t) = cand;
  TYPE_MAIN_VARIANT (cand) = TYPE_MAIN_VARIANT (t);
  return cand;
}

/* Return the value of element I of VECTOR_CST T as a wide_int.  */

wide_int
vector_cst_int_elt (const_tree t, unsigned int i)
{
  /* First handle elements that are directly encoded.  */
  unsigned int encoded_nelts = vector_cst_encoded_nelts (t);
  if (i < encoded_nelts)
    return wi::to_wide (VECTOR_CST_ENCODED_ELT (t, i));

  /* Identify the pattern that contains element I and work out the index of
     the last encoded element for that pattern.  */
  unsigned int npatterns = VECTOR_CST_NPATTERNS (t);
  unsigned int pattern = i % npatterns;
  unsigned int count = i / npatterns;
  unsigned int final_i = encoded_nelts - npatterns + pattern;

  /* If there are no steps, the final encoded value is the right one.  */
  if (!VECTOR_CST_STEPPED_P (t))
    return wi::to_wide (VECTOR_CST_ENCODED_ELT (t, final_i));

  /* Otherwise work out the value from the last two encoded elements.  */
  tree v1 = VECTOR_CST_ENCODED_ELT (t, final_i - npatterns);
  tree v2 = VECTOR_CST_ENCODED_ELT (t, final_i);
  wide_int diff = wi::to_wide (v2) - wi::to_wide (v1);
  return wi::to_wide (v2) + (count - 2) * diff;
}

/* Return the value of element I of VECTOR_CST T.  */

tree
vector_cst_elt (const_tree t, unsigned int i)
{
  /* First handle elements that are directly encoded.  */
  unsigned int encoded_nelts = vector_cst_encoded_nelts (t);
  if (i < encoded_nelts)
    return VECTOR_CST_ENCODED_ELT (t, i);

  /* If there are no steps, the final encoded value is the right one.  */
  if (!VECTOR_CST_STEPPED_P (t))
    {
      /* Identify the pattern that contains element I and work out the index of
	 the last encoded element for that pattern.  */
      unsigned int npatterns = VECTOR_CST_NPATTERNS (t);
      unsigned int pattern = i % npatterns;
      unsigned int final_i = encoded_nelts - npatterns + pattern;
      return VECTOR_CST_ENCODED_ELT (t, final_i);
    }

  /* Otherwise work out the value from the last two encoded elements.  */
  return wide_int_to_tree (TREE_TYPE (TREE_TYPE (t)),
			   vector_cst_int_elt (t, i));
}

/* Given an initializer INIT, return TRUE if INIT is zero or some
   aggregate of zeros.  Otherwise return FALSE.  If NONZERO is not
   null, set *NONZERO if and only if INIT is known not to be all
   zeros.  The combination of return value of false and *NONZERO
   false implies that INIT may but need not be all zeros.  Other
   combinations indicate definitive answers.  */

bool
initializer_zerop (const_tree init, bool *nonzero /* = NULL */)
{
  bool dummy;
  if (!nonzero)
    nonzero = &dummy;

  /* Conservatively clear NONZERO and set it only if INIT is definitely
     not all zero.  */
  *nonzero = false;

  STRIP_NOPS (init);

  unsigned HOST_WIDE_INT off = 0;

  switch (TREE_CODE (init))
    {
    case INTEGER_CST:
      if (integer_zerop (init))
	return true;

      *nonzero = true;
      return false;

    case REAL_CST:
      /* ??? Note that this is not correct for C4X float formats.  There,
	 a bit pattern of all zeros is 1.0; 0.0 is encoded with the most
	 negative exponent.  */
      if (real_zerop (init)
	  && !REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (init)))
	return true;

      *nonzero = true;
      return false;

    case FIXED_CST:
      if (fixed_zerop (init))
	return true;

      *nonzero = true;
      return false;

    case COMPLEX_CST:
      if (integer_zerop (init)
	  || (real_zerop (init)
	      && !REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_REALPART (init)))
	      && !REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_IMAGPART (init)))))
	return true;

      *nonzero = true;
      return false;

    case VECTOR_CST:
      if (VECTOR_CST_NPATTERNS (init) == 1
	  && VECTOR_CST_DUPLICATE_P (init)
	  && initializer_zerop (VECTOR_CST_ENCODED_ELT (init, 0)))
	return true;

      *nonzero = true;
      return false;

    case CONSTRUCTOR:
      {
	if (TREE_CLOBBER_P (init))
	  return false;

	unsigned HOST_WIDE_INT idx;
	tree elt;

	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), idx, elt)
	  if (!initializer_zerop (elt, nonzero))
	    return false;

	return true;
      }

    case MEM_REF:
      {
	tree arg = TREE_OPERAND (init, 0);
	if (TREE_CODE (arg) != ADDR_EXPR)
	  return false;
	tree offset = TREE_OPERAND (init, 1);
	if (TREE_CODE (offset) != INTEGER_CST
	    || !tree_fits_uhwi_p (offset))
	  return false;
	off = tree_to_uhwi (offset);
	if (INT_MAX < off)
	  return false;
	arg = TREE_OPERAND (arg, 0);
	if (TREE_CODE (arg) != STRING_CST)
	  return false;
	init = arg;
      }
      /* Fall through.  */

    case STRING_CST:
      {
	gcc_assert (off <= INT_MAX);

	int i = off;
	int n = TREE_STRING_LENGTH (init);
	if (n <= i)
	  return false;

	/* We need to loop through all elements to handle cases like
	   "\0" and "\0foobar".  */
	for (i = 0; i < n; ++i)
	  if (TREE_STRING_POINTER (init)[i] != '\0')
	    {
	      *nonzero = true;
	      return false;
	    }

	return true;
      }

    default:
      return false;
    }
}

/* Check if vector VEC consists of all the equal elements and
   that the number of elements corresponds to the type of VEC.
   The function returns first element of the vector
   or NULL_TREE if the vector is not uniform.  */
tree
uniform_vector_p (const_tree vec)
{
  tree first, t;
  unsigned HOST_WIDE_INT i, nelts;

  if (vec == NULL_TREE)
    return NULL_TREE;

  gcc_assert (VECTOR_TYPE_P (TREE_TYPE (vec)));

  if (TREE_CODE (vec) == VEC_DUPLICATE_EXPR)
    return TREE_OPERAND (vec, 0);

  else if (TREE_CODE (vec) == VECTOR_CST)
    {
      if (VECTOR_CST_NPATTERNS (vec) == 1 && VECTOR_CST_DUPLICATE_P (vec))
	return VECTOR_CST_ENCODED_ELT (vec, 0);
      return NULL_TREE;
    }

  else if (TREE_CODE (vec) == CONSTRUCTOR
	   && TYPE_VECTOR_SUBPARTS (TREE_TYPE (vec)).is_constant (&nelts))
    {
      first = error_mark_node;

      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (vec), i, t)
        {
          if (i == 0)
            {
              first = t;
              continue;
            }
	  if (!operand_equal_p (first, t, 0))
	    return NULL_TREE;
        }
      if (i != nelts)
	return NULL_TREE;

      return first;
    }

  return NULL_TREE;
}

/* If the argument is INTEGER_CST, return it.  If the argument is vector
   with all elements the same INTEGER_CST, return that INTEGER_CST.  Otherwise
   return NULL_TREE.  */

tree
uniform_integer_cst_p (tree t)
{
  if (TREE_CODE (t) == INTEGER_CST)
    return t;

  if (VECTOR_TYPE_P (TREE_TYPE (t)))
    {
      t = uniform_vector_p (t);
      if (t && TREE_CODE (t) == INTEGER_CST)
	return t;
    }

  return NULL_TREE;
}

/* Build an empty statement at location LOC.  */

tree
build_empty_stmt (location_t loc)
{
  tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
  SET_EXPR_LOCATION (t, loc);
  return t;
}


/* Build an OpenMP clause with code CODE.  LOC is the location of the
   clause.  */

tree
build_omp_clause (location_t loc, enum omp_clause_code code)
{
  tree t;
  int size, length;

  length = omp_clause_num_ops[code];
  size = (sizeof (struct tree_omp_clause) + (length - 1) * sizeof (tree));

  record_node_allocation_statistics (OMP_CLAUSE, size);

  t = (tree) ggc_internal_alloc (size);
  memset (t, 0, size);
  TREE_SET_CODE (t, OMP_CLAUSE);
  OMP_CLAUSE_SET_CODE (t, code);
  OMP_CLAUSE_LOCATION (t) = loc;

  return t;
}

/* Build a tcc_vl_exp object with code CODE and room for LEN operands.  LEN
   includes the implicit operand count in TREE_OPERAND 0, and so must be >= 1.
   Except for the CODE and operand count field, other storage for the
   object is initialized to zeros.  */

tree
build_vl_exp (enum tree_code code, int len MEM_STAT_DECL)
{
  tree t;
  int length = (len - 1) * sizeof (tree) + sizeof (struct tree_exp);

  gcc_assert (TREE_CODE_CLASS (code) == tcc_vl_exp);
  gcc_assert (len >= 1);

  record_node_allocation_statistics (code, length);

  t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);

  TREE_SET_CODE (t, code);

  /* Can't use TREE_OPERAND to store the length because if checking is
     enabled, it will try to check the length before we store it.  :-P  */
  t->exp.operands[0] = build_int_cst (sizetype, len);

  return t;
}

/* Helper function for build_call_* functions; build a CALL_EXPR with
   indicated RETURN_TYPE, FN, and NARGS, but do not initialize any of
   the argument slots.  */

static tree
build_call_1 (tree return_type, tree fn, int nargs)
{
  tree t;

  t = build_vl_exp (CALL_EXPR, nargs + 3);
  TREE_TYPE (t) = return_type;
  CALL_EXPR_FN (t) = fn;
  CALL_EXPR_STATIC_CHAIN (t) = NULL;

  return t;
}

/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
   FN and a null static chain slot.  NARGS is the number of call arguments
   which are specified as "..." arguments.  */

tree
build_call_nary (tree return_type, tree fn, int nargs, ...)
{
  tree ret;
  va_list args;
  va_start (args, nargs);
  ret = build_call_valist (return_type, fn, nargs, args);
  va_end (args);
  return ret;
}

/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
   FN and a null static chain slot.  NARGS is the number of call arguments
   which are specified as a va_list ARGS.  */

tree
build_call_valist (tree return_type, tree fn, int nargs, va_list args)
{
  tree t;
  int i;

  t = build_call_1 (return_type, fn, nargs);
  for (i = 0; i < nargs; i++)
    CALL_EXPR_ARG (t, i) = va_arg (args, tree);
  process_call_operands (t);
  return t;
}

/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
   FN and a null static chain slot.  NARGS is the number of call arguments
   which are specified as a tree array ARGS.  */

tree
build_call_array_loc (location_t loc, tree return_type, tree fn,
		      int nargs, const tree *args)
{
  tree t;
  int i;

  t = build_call_1 (return_type, fn, nargs);
  for (i = 0; i < nargs; i++)
    CALL_EXPR_ARG (t, i) = args[i];
  process_call_operands (t);
  SET_EXPR_LOCATION (t, loc);
  return t;
}

/* Like build_call_array, but takes a vec.  */

tree
build_call_vec (tree return_type, tree fn, vec<tree, va_gc> *args)
{
  tree ret, t;
  unsigned int ix;

  ret = build_call_1 (return_type, fn, vec_safe_length (args));
  FOR_EACH_VEC_SAFE_ELT (args, ix, t)
    CALL_EXPR_ARG (ret, ix) = t;
  process_call_operands (ret);
  return ret;
}

/* Conveniently construct a function call expression.  FNDECL names the
   function to be called and N arguments are passed in the array
   ARGARRAY.  */

tree
build_call_expr_loc_array (location_t loc, tree fndecl, int n, tree *argarray)
{
  tree fntype = TREE_TYPE (fndecl);
  tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
 
  return fold_build_call_array_loc (loc, TREE_TYPE (fntype), fn, n, argarray);
}

/* Conveniently construct a function call expression.  FNDECL names the
   function to be called and the arguments are passed in the vector
   VEC.  */

tree
build_call_expr_loc_vec (location_t loc, tree fndecl, vec<tree, va_gc> *vec)
{
  return build_call_expr_loc_array (loc, fndecl, vec_safe_length (vec),
				    vec_safe_address (vec));
}


/* Conveniently construct a function call expression.  FNDECL names the
   function to be called, N is the number of arguments, and the "..."
   parameters are the argument expressions.  */

tree
build_call_expr_loc (location_t loc, tree fndecl, int n, ...)
{
  va_list ap;
  tree *argarray = XALLOCAVEC (tree, n);
  int i;

  va_start (ap, n);
  for (i = 0; i < n; i++)
    argarray[i] = va_arg (ap, tree);
  va_end (ap);
  return build_call_expr_loc_array (loc, fndecl, n, argarray);
}

/* Like build_call_expr_loc (UNKNOWN_LOCATION, ...).  Duplicated because
   varargs macros aren't supported by all bootstrap compilers.  */

tree
build_call_expr (tree fndecl, int n, ...)
{
  va_list ap;
  tree *argarray = XALLOCAVEC (tree, n);
  int i;

  va_start (ap, n);
  for (i = 0; i < n; i++)
    argarray[i] = va_arg (ap, tree);
  va_end (ap);
  return build_call_expr_loc_array (UNKNOWN_LOCATION, fndecl, n, argarray);
}

/* Build an internal call to IFN, with arguments ARGS[0:N-1] and with return
   type TYPE.  This is just like CALL_EXPR, except its CALL_EXPR_FN is NULL.
   It will get gimplified later into an ordinary internal function.  */

tree
build_call_expr_internal_loc_array (location_t loc, internal_fn ifn,
				    tree type, int n, const tree *args)
{
  tree t = build_call_1 (type, NULL_TREE, n);
  for (int i = 0; i < n; ++i)
    CALL_EXPR_ARG (t, i) = args[i];
  SET_EXPR_LOCATION (t, loc);
  CALL_EXPR_IFN (t) = ifn;
  return t;
}

/* Build internal call expression.  This is just like CALL_EXPR, except
   its CALL_EXPR_FN is NULL.  It will get gimplified later into ordinary
   internal function.  */

tree
build_call_expr_internal_loc (location_t loc, enum internal_fn ifn,
			      tree type, int n, ...)
{
  va_list ap;
  tree *argarray = XALLOCAVEC (tree, n);
  int i;

  va_start (ap, n);
  for (i = 0; i < n; i++)
    argarray[i] = va_arg (ap, tree);
  va_end (ap);
  return build_call_expr_internal_loc_array (loc, ifn, type, n, argarray);
}

/* Return a function call to FN, if the target is guaranteed to support it,
   or null otherwise.

   N is the number of arguments, passed in the "...", and TYPE is the
   type of the return value.  */

tree
maybe_build_call_expr_loc (location_t loc, combined_fn fn, tree type,
			   int n, ...)
{
  va_list ap;
  tree *argarray = XALLOCAVEC (tree, n);
  int i;

  va_start (ap, n);
  for (i = 0; i < n; i++)
    argarray[i] = va_arg (ap, tree);
  va_end (ap);
  if (internal_fn_p (fn))
    {
      internal_fn ifn = as_internal_fn (fn);
      if (direct_internal_fn_p (ifn))
	{
	  tree_pair types = direct_internal_fn_types (ifn, type, argarray);
	  if (!direct_internal_fn_supported_p (ifn, types,
					       OPTIMIZE_FOR_BOTH))
	    return NULL_TREE;
	}
      return build_call_expr_internal_loc_array (loc, ifn, type, n, argarray);
    }
  else
    {
      tree fndecl = builtin_decl_implicit (as_builtin_fn (fn));
      if (!fndecl)
	return NULL_TREE;
      return build_call_expr_loc_array (loc, fndecl, n, argarray);
    }
}

/* Return a function call to the appropriate builtin alloca variant.

   SIZE is the size to be allocated.  ALIGN, if non-zero, is the requested
   alignment of the allocated area.  MAX_SIZE, if non-negative, is an upper
   bound for SIZE in case it is not a fixed value.  */

tree
build_alloca_call_expr (tree size, unsigned int align, HOST_WIDE_INT max_size)
{
  if (max_size >= 0)
    {
      tree t = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX);
      return
	build_call_expr (t, 3, size, size_int (align), size_int (max_size));
    }
  else if (align > 0)
    {
      tree t = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
      return build_call_expr (t, 2, size, size_int (align));
    }
  else
    {
      tree t = builtin_decl_explicit (BUILT_IN_ALLOCA);
      return build_call_expr (t, 1, size);
    }
}

/* Create a new constant string literal consisting of elements of type
   ELTYPE and return a tree node representing char* pointer to it as
   an ADDR_EXPR (ARRAY_REF (ELTYPE, ...)).  The STRING_CST value is
   the LEN bytes at STR (the representation of the string, which may
   be wide).  */

tree
build_string_literal (int len, const char *str,
		      tree eltype /* = char_type_node */)
{
  tree t = build_string (len, str);
  tree index = build_index_type (size_int (len - 1));
  eltype = build_type_variant (eltype, 1, 0);
  tree type = build_array_type (eltype, index);
  TREE_TYPE (t) = type;
  TREE_CONSTANT (t) = 1;
  TREE_READONLY (t) = 1;
  TREE_STATIC (t) = 1;

  type = build_pointer_type (eltype);
  t = build1 (ADDR_EXPR, type,
	      build4 (ARRAY_REF, eltype,
		      t, integer_zero_node, NULL_TREE, NULL_TREE));
  return t;
}



/* Return true if T (assumed to be a DECL) must be assigned a memory
   location.  */

bool
needs_to_live_in_memory (const_tree t)
{
  return (TREE_ADDRESSABLE (t)
	  || is_global_var (t)
	  || (TREE_CODE (t) == RESULT_DECL
	      && !DECL_BY_REFERENCE (t)
	      && aggregate_value_p (t, current_function_decl)));
}

/* Return value of a constant X and sign-extend it.  */

HOST_WIDE_INT
int_cst_value (const_tree x)
{
  unsigned bits = TYPE_PRECISION (TREE_TYPE (x));
  unsigned HOST_WIDE_INT val = TREE_INT_CST_LOW (x);

  /* Make sure the sign-extended value will fit in a HOST_WIDE_INT.  */
  gcc_assert (cst_and_fits_in_hwi (x));

  if (bits < HOST_BITS_PER_WIDE_INT)
    {
      bool negative = ((val >> (bits - 1)) & 1) != 0;
      if (negative)
	val |= HOST_WIDE_INT_M1U << (bits - 1) << 1;
      else
	val &= ~(HOST_WIDE_INT_M1U << (bits - 1) << 1);
    }

  return val;
}

/* If TYPE is an integral or pointer type, return an integer type with
   the same precision which is unsigned iff UNSIGNEDP is true, or itself
   if TYPE is already an integer type of signedness UNSIGNEDP.  */

tree
signed_or_unsigned_type_for (int unsignedp, tree type)
{
  if (ANY_INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) == unsignedp)
    return type;

  if (TREE_CODE (type) == VECTOR_TYPE)
    {
      tree inner = TREE_TYPE (type);
      tree inner2 = signed_or_unsigned_type_for (unsignedp, inner);
      if (!inner2)
	return NULL_TREE;
      if (inner == inner2)
	return type;
      return build_vector_type (inner2, TYPE_VECTOR_SUBPARTS (type));
    }

  if (TREE_CODE (type) == COMPLEX_TYPE)
    {
      tree inner = TREE_TYPE (type);
      tree inner2 = signed_or_unsigned_type_for (unsignedp, inner);
      if (!inner2)
	return NULL_TREE;
      if (inner == inner2)
	return type;
      return build_complex_type (inner2);
    }

  if (!INTEGRAL_TYPE_P (type)
      && !POINTER_TYPE_P (type)
      && TREE_CODE (type) != OFFSET_TYPE)
    return NULL_TREE;

  return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp);
}

/* If TYPE is an integral or pointer type, return an integer type with
   the same precision which is unsigned, or itself if TYPE is already an
   unsigned integer type.  */

tree
unsigned_type_for (tree type)
{
  return signed_or_unsigned_type_for (1, type);
}

/* If TYPE is an integral or pointer type, return an integer type with
   the same precision which is signed, or itself if TYPE is already a
   signed integer type.  */

tree
signed_type_for (tree type)
{
  return signed_or_unsigned_type_for (0, type);
}

/* If TYPE is a vector type, return a signed integer vector type with the
   same width and number of subparts. Otherwise return boolean_type_node.  */

tree
truth_type_for (tree type)
{
  if (TREE_CODE (type) == VECTOR_TYPE)
    {
      if (VECTOR_BOOLEAN_TYPE_P (type))
	return type;
      return build_truth_vector_type (TYPE_VECTOR_SUBPARTS (type),
				      GET_MODE_SIZE (TYPE_MODE (type)));
    }
  else
    return boolean_type_node;
}

/* Returns the largest value obtainable by casting something in INNER type to
   OUTER type.  */

tree
upper_bound_in_type (tree outer, tree inner)
{
  unsigned int det = 0;
  unsigned oprec = TYPE_PRECISION (outer);
  unsigned iprec = TYPE_PRECISION (inner);
  unsigned prec;

  /* Compute a unique number for every combination.  */
  det |= (oprec > iprec) ? 4 : 0;
  det |= TYPE_UNSIGNED (outer) ? 2 : 0;
  det |= TYPE_UNSIGNED (inner) ? 1 : 0;

  /* Determine the exponent to use.  */
  switch (det)
    {
    case 0:
    case 1:
      /* oprec <= iprec, outer: signed, inner: don't care.  */
      prec = oprec - 1;
      break;
    case 2:
    case 3:
      /* oprec <= iprec, outer: unsigned, inner: don't care.  */
      prec = oprec;
      break;
    case 4:
      /* oprec > iprec, outer: signed, inner: signed.  */
      prec = iprec - 1;
      break;
    case 5:
      /* oprec > iprec, outer: signed, inner: unsigned.  */
      prec = iprec;
      break;
    case 6:
      /* oprec > iprec, outer: unsigned, inner: signed.  */
      prec = oprec;
      break;
    case 7:
      /* oprec > iprec, outer: unsigned, inner: unsigned.  */
      prec = iprec;
      break;
    default:
      gcc_unreachable ();
    }

  return wide_int_to_tree (outer,
			   wi::mask (prec, false, TYPE_PRECISION (outer)));
}

/* Returns the smallest value obtainable by casting something in INNER type to
   OUTER type.  */

tree
lower_bound_in_type (tree outer, tree inner)
{
  unsigned oprec = TYPE_PRECISION (outer);
  unsigned iprec = TYPE_PRECISION (inner);

  /* If OUTER type is unsigned, we can definitely cast 0 to OUTER type
     and obtain 0.  */
  if (TYPE_UNSIGNED (outer)
      /* If we are widening something of an unsigned type, OUTER type
	 contains all values of INNER type.  In particular, both INNER
	 and OUTER types have zero in common.  */
      || (oprec > iprec && TYPE_UNSIGNED (inner)))
    return build_int_cst (outer, 0);
  else
    {
      /* If we are widening a signed type to another signed type, we
	 want to obtain -2^^(iprec-1).  If we are keeping the
	 precision or narrowing to a signed type, we want to obtain
	 -2^(oprec-1).  */
      unsigned prec = oprec > iprec ? iprec : oprec;
      return wide_int_to_tree (outer,
			       wi::mask (prec - 1, true,
					 TYPE_PRECISION (outer)));
    }
}

/* Return nonzero if two operands that are suitable for PHI nodes are
   necessarily equal.  Specifically, both ARG0 and ARG1 must be either
   SSA_NAME or invariant.  Note that this is strictly an optimization.
   That is, callers of this function can directly call operand_equal_p
   and get the same result, only slower.  */

int
operand_equal_for_phi_arg_p (const_tree arg0, const_tree arg1)
{
  if (arg0 == arg1)
    return 1;
  if (TREE_CODE (arg0) == SSA_NAME || TREE_CODE (arg1) == SSA_NAME)
    return 0;
  return operand_equal_p (arg0, arg1, 0);
}

/* Returns number of zeros at the end of binary representation of X.  */

tree
num_ending_zeros (const_tree x)
{
  return build_int_cst (TREE_TYPE (x), wi::ctz (wi::to_wide (x)));
}


#define WALK_SUBTREE(NODE)				\
  do							\
    {							\
      result = walk_tree_1 (&(NODE), func, data, pset, lh);	\
      if (result)					\
	return result;					\
    }							\
  while (0)

/* This is a subroutine of walk_tree that walks field of TYPE that are to
   be walked whenever a type is seen in the tree.  Rest of operands and return
   value are as for walk_tree.  */

static tree
walk_type_fields (tree type, walk_tree_fn func, void *data,
		  hash_set<tree> *pset, walk_tree_lh lh)
{
  tree result = NULL_TREE;

  switch (TREE_CODE (type))
    {
    case POINTER_TYPE:
    case REFERENCE_TYPE:
    case VECTOR_TYPE:
      /* We have to worry about mutually recursive pointers.  These can't
	 be written in C.  They can in Ada.  It's pathological, but
	 there's an ACATS test (c38102a) that checks it.  Deal with this
	 by checking if we're pointing to another pointer, that one
	 points to another pointer, that one does too, and we have no htab.
	 If so, get a hash table.  We check three levels deep to avoid
	 the cost of the hash table if we don't need one.  */
      if (POINTER_TYPE_P (TREE_TYPE (type))
	  && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (type)))
	  && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_TYPE (type))))
	  && !pset)
	{
	  result = walk_tree_without_duplicates (&TREE_TYPE (type),
						 func, data);
	  if (result)
	    return result;

	  break;
	}

      /* fall through */

    case COMPLEX_TYPE:
      WALK_SUBTREE (TREE_TYPE (type));
      break;

    case METHOD_TYPE:
      WALK_SUBTREE (TYPE_METHOD_BASETYPE (type));

      /* Fall through.  */

    case FUNCTION_TYPE:
      WALK_SUBTREE (TREE_TYPE (type));
      {
	tree arg;

	/* We never want to walk into default arguments.  */
	for (arg = TYPE_ARG_TYPES (type); arg; arg = TREE_CHAIN (arg))
	  WALK_SUBTREE (TREE_VALUE (arg));
      }
      break;

    case ARRAY_TYPE:
      /* Don't follow this nodes's type if a pointer for fear that
	 we'll have infinite recursion.  If we have a PSET, then we
	 need not fear.  */
      if (pset
	  || (!POINTER_TYPE_P (TREE_TYPE (type))
	      && TREE_CODE (TREE_TYPE (type)) != OFFSET_TYPE))
	WALK_SUBTREE (TREE_TYPE (type));
      WALK_SUBTREE (TYPE_DOMAIN (type));
      break;

    case OFFSET_TYPE:
      WALK_SUBTREE (TREE_TYPE (type));
      WALK_SUBTREE (TYPE_OFFSET_BASETYPE (type));
      break;

    default:
      break;
    }

  return NULL_TREE;
}

/* Apply FUNC to all the sub-trees of TP in a pre-order traversal.  FUNC is
   called with the DATA and the address of each sub-tree.  If FUNC returns a
   non-NULL value, the traversal is stopped, and the value returned by FUNC
   is returned.  If PSET is non-NULL it is used to record the nodes visited,
   and to avoid visiting a node more than once.  */

tree
walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
	     hash_set<tree> *pset, walk_tree_lh lh)
{
  enum tree_code code;
  int walk_subtrees;
  tree result;

#define WALK_SUBTREE_TAIL(NODE)				\
  do							\
    {							\
       tp = & (NODE);					\
       goto tail_recurse;				\
    }							\
  while (0)

 tail_recurse:
  /* Skip empty subtrees.  */
  if (!*tp)
    return NULL_TREE;

  /* Don't walk the same tree twice, if the user has requested
     that we avoid doing so.  */
  if (pset && pset->add (*tp))
    return NULL_TREE;

  /* Call the function.  */
  walk_subtrees = 1;
  result = (*func) (tp, &walk_subtrees, data);

  /* If we found something, return it.  */
  if (result)
    return result;

  code = TREE_CODE (*tp);

  /* Even if we didn't, FUNC may have decided that there was nothing
     interesting below this point in the tree.  */
  if (!walk_subtrees)
    {
      /* But we still need to check our siblings.  */
      if (code == TREE_LIST)
	WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
      else if (code == OMP_CLAUSE)
	WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
      else
	return NULL_TREE;
    }

  if (lh)
    {
      result = (*lh) (tp, &walk_subtrees, func, data, pset);
      if (result || !walk_subtrees)
        return result;
    }

  switch (code)
    {
    case ERROR_MARK:
    case IDENTIFIER_NODE:
    case INTEGER_CST:
    case REAL_CST:
    case FIXED_CST:
    case VECTOR_CST:
    case STRING_CST:
    case BLOCK:
    case PLACEHOLDER_EXPR:
    case SSA_NAME:
    case FIELD_DECL:
    case RESULT_DECL:
      /* None of these have subtrees other than those already walked
	 above.  */
      break;

    case TREE_LIST:
      WALK_SUBTREE (TREE_VALUE (*tp));
      WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
      break;

    case TREE_VEC:
      {
	int len = TREE_VEC_LENGTH (*tp);

	if (len == 0)
	  break;

	/* Walk all elements but the first.  */
	while (--len)
	  WALK_SUBTREE (TREE_VEC_ELT (*tp, len));

	/* Now walk the first one as a tail call.  */
	WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
      }

    case COMPLEX_CST:
      WALK_SUBTREE (TREE_REALPART (*tp));
      WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));

    case CONSTRUCTOR:
      {
	unsigned HOST_WIDE_INT idx;
	constructor_elt *ce;

	for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (*tp), idx, &ce);
	     idx++)
	  WALK_SUBTREE (ce->value);
      }
      break;

    case SAVE_EXPR:
      WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));

    case BIND_EXPR:
      {
	tree decl;
	for (decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
	  {
	    /* Walk the DECL_INITIAL and DECL_SIZE.  We don't want to walk
	       into declarations that are just mentioned, rather than
	       declared; they don't really belong to this part of the tree.
	       And, we can see cycles: the initializer for a declaration
	       can refer to the declaration itself.  */
	    WALK_SUBTREE (DECL_INITIAL (decl));
	    WALK_SUBTREE (DECL_SIZE (decl));
	    WALK_SUBTREE (DECL_SIZE_UNIT (decl));
	  }
	WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
      }

    case STATEMENT_LIST:
      {
	tree_stmt_iterator i;
	for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
	  WALK_SUBTREE (*tsi_stmt_ptr (i));
      }
      break;

    case OMP_CLAUSE:
      switch (OMP_CLAUSE_CODE (*tp))
	{
	case OMP_CLAUSE_GANG:
	case OMP_CLAUSE__GRIDDIM_:
	  WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1));
	  /* FALLTHRU */

	case OMP_CLAUSE_ASYNC:
	case OMP_CLAUSE_WAIT:
	case OMP_CLAUSE_WORKER:
	case OMP_CLAUSE_VECTOR:
	case OMP_CLAUSE_NUM_GANGS:
	case OMP_CLAUSE_NUM_WORKERS:
	case OMP_CLAUSE_VECTOR_LENGTH:
	case OMP_CLAUSE_PRIVATE:
	case OMP_CLAUSE_SHARED:
	case OMP_CLAUSE_FIRSTPRIVATE:
	case OMP_CLAUSE_COPYIN:
	case OMP_CLAUSE_COPYPRIVATE:
	case OMP_CLAUSE_FINAL:
	case OMP_CLAUSE_IF:
	case OMP_CLAUSE_NUM_THREADS:
	case OMP_CLAUSE_SCHEDULE:
	case OMP_CLAUSE_UNIFORM:
	case OMP_CLAUSE_DEPEND:
	case OMP_CLAUSE_NONTEMPORAL:
	case OMP_CLAUSE_NUM_TEAMS:
	case OMP_CLAUSE_THREAD_LIMIT:
	case OMP_CLAUSE_DEVICE:
	case OMP_CLAUSE_DIST_SCHEDULE:
	case OMP_CLAUSE_SAFELEN:
	case OMP_CLAUSE_SIMDLEN:
	case OMP_CLAUSE_ORDERED:
	case OMP_CLAUSE_PRIORITY:
	case OMP_CLAUSE_GRAINSIZE:
	case OMP_CLAUSE_NUM_TASKS:
	case OMP_CLAUSE_HINT:
	case OMP_CLAUSE_TO_DECLARE:
	case OMP_CLAUSE_LINK:
	case OMP_CLAUSE_USE_DEVICE_PTR:
	case OMP_CLAUSE_IS_DEVICE_PTR:
	case OMP_CLAUSE__LOOPTEMP_:
	case OMP_CLAUSE__REDUCTEMP_:
	case OMP_CLAUSE__SIMDUID_:
	  WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0));
	  /* FALLTHRU */

	case OMP_CLAUSE_INDEPENDENT:
	case OMP_CLAUSE_NOWAIT:
	case OMP_CLAUSE_DEFAULT:
	case OMP_CLAUSE_UNTIED:
	case OMP_CLAUSE_MERGEABLE:
	case OMP_CLAUSE_PROC_BIND:
	case OMP_CLAUSE_INBRANCH:
	case OMP_CLAUSE_NOTINBRANCH:
	case OMP_CLAUSE_FOR:
	case OMP_CLAUSE_PARALLEL:
	case OMP_CLAUSE_SECTIONS:
	case OMP_CLAUSE_TASKGROUP:
	case OMP_CLAUSE_NOGROUP:
	case OMP_CLAUSE_THREADS:
	case OMP_CLAUSE_SIMD:
	case OMP_CLAUSE_DEFAULTMAP:
	case OMP_CLAUSE_AUTO:
	case OMP_CLAUSE_SEQ:
	case OMP_CLAUSE_TILE:
	case OMP_CLAUSE__SIMT_:
	case OMP_CLAUSE_IF_PRESENT:
	case OMP_CLAUSE_FINALIZE:
	  WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));

	case OMP_CLAUSE_LASTPRIVATE:
	  WALK_SUBTREE (OMP_CLAUSE_DECL (*tp));
	  WALK_SUBTREE (OMP_CLAUSE_LASTPRIVATE_STMT (*tp));
	  WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));

	case OMP_CLAUSE_COLLAPSE:
	  {
	    int i;
	    for (i = 0; i < 3; i++)
	      WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i));
	    WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
	  }

	case OMP_CLAUSE_LINEAR:
	  WALK_SUBTREE (OMP_CLAUSE_DECL (*tp));
	  WALK_SUBTREE (OMP_CLAUSE_LINEAR_STEP (*tp));
	  WALK_SUBTREE (OMP_CLAUSE_LINEAR_STMT (*tp));
	  WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));

	case OMP_CLAUSE_ALIGNED:
	case OMP_CLAUSE_FROM:
	case OMP_CLAUSE_TO:
	case OMP_CLAUSE_MAP:
	case OMP_CLAUSE__CACHE_:
	  WALK_SUBTREE (OMP_CLAUSE_DECL (*tp));
	  WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1));
	  WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));

	case OMP_CLAUSE_REDUCTION:
	case OMP_CLAUSE_TASK_REDUCTION:
	case OMP_CLAUSE_IN_REDUCTION:
	  {
	    int i;
	    for (i = 0; i < 5; i++)
	      WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i));
	    WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
	  }

	default:
	  gcc_unreachable ();
	}
      break;

    case TARGET_EXPR:
      {
	int i, len;

	/* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
	   But, we only want to walk once.  */
	len = (TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1)) ? 2 : 3;
	for (i = 0; i < len; ++i)
	  WALK_SUBTREE (TREE_OPERAND (*tp, i));
	WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len));
      }

    case DECL_EXPR:
      /* If this is a TYPE_DECL, walk into the fields of the type that it's
	 defining.  We only want to walk into these fields of a type in this
	 case and not in the general case of a mere reference to the type.

	 The criterion is as follows: if the field can be an expression, it
	 must be walked only here.  This should be in keeping with the fields
	 that are directly gimplified in gimplify_type_sizes in order for the
	 mark/copy-if-shared/unmark machinery of the gimplifier to work with
	 variable-sized types.

	 Note that DECLs get walked as part of processing the BIND_EXPR.  */
      if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL)
	{
	  tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
	  if (TREE_CODE (*type_p) == ERROR_MARK)
	    return NULL_TREE;

	  /* Call the function for the type.  See if it returns anything or
	     doesn't want us to continue.  If we are to continue, walk both
	     the normal fields and those for the declaration case.  */
	  result = (*func) (type_p, &walk_subtrees, data);
	  if (result || !walk_subtrees)
	    return result;

	  /* But do not walk a pointed-to type since it may itself need to
	     be walked in the declaration case if it isn't anonymous.  */
	  if (!POINTER_TYPE_P (*type_p))
	    {
	      result = walk_type_fields (*type_p, func, data, pset, lh);
	      if (result)
		return result;
	    }

	  /* If this is a record type, also walk the fields.  */
	  if (RECORD_OR_UNION_TYPE_P (*type_p))
	    {
	      tree field;

	      for (field = TYPE_FIELDS (*type_p); field;
		   field = DECL_CHAIN (field))
		{
		  /* We'd like to look at the type of the field, but we can
		     easily get infinite recursion.  So assume it's pointed
		     to elsewhere in the tree.  Also, ignore things that
		     aren't fields.  */
		  if (TREE_CODE (field) != FIELD_DECL)
		    continue;

		  WALK_SUBTREE (DECL_FIELD_OFFSET (field));
		  WALK_SUBTREE (DECL_SIZE (field));
		  WALK_SUBTREE (DECL_SIZE_UNIT (field));
		  if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
		    WALK_SUBTREE (DECL_QUALIFIER (field));
		}
	    }

	  /* Same for scalar types.  */
	  else if (TREE_CODE (*type_p) == BOOLEAN_TYPE
		   || TREE_CODE (*type_p) == ENUMERAL_TYPE
		   || TREE_CODE (*type_p) == INTEGER_TYPE
		   || TREE_CODE (*type_p) == FIXED_POINT_TYPE
		   || TREE_CODE (*type_p) == REAL_TYPE)
	    {
	      WALK_SUBTREE (TYPE_MIN_VALUE (*type_p));
	      WALK_SUBTREE (TYPE_MAX_VALUE (*type_p));
	    }

	  WALK_SUBTREE (TYPE_SIZE (*type_p));
	  WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (*type_p));
	}
      /* FALLTHRU */

    default:
      if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
	{
	  int i, len;

	  /* Walk over all the sub-trees of this operand.  */
	  len = TREE_OPERAND_LENGTH (*tp);

	  /* Go through the subtrees.  We need to do this in forward order so
	     that the scope of a FOR_EXPR is handled properly.  */
	  if (len)
	    {
	      for (i = 0; i < len - 1; ++i)
		WALK_SUBTREE (TREE_OPERAND (*tp, i));
	      WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
	    }
	}
      /* If this is a type, walk the needed fields in the type.  */
      else if (TYPE_P (*tp))
	return walk_type_fields (*tp, func, data, pset, lh);
      break;
    }

  /* We didn't find what we were looking for.  */
  return NULL_TREE;

#undef WALK_SUBTREE_TAIL
}
#undef WALK_SUBTREE

/* Like walk_tree, but does not walk duplicate nodes more than once.  */

tree
walk_tree_without_duplicates_1 (tree *tp, walk_tree_fn func, void *data,
				walk_tree_lh lh)
{
  tree result;

  hash_set<tree> pset;
  result = walk_tree_1 (tp, func, data, &pset, lh);
  return result;
}


tree
tree_block (tree t)
{
  const enum tree_code_class c = TREE_CODE_CLASS (TREE_CODE (t));

  if (IS_EXPR_CODE_CLASS (c))
    return LOCATION_BLOCK (t->exp.locus);
  gcc_unreachable ();
  return NULL;
}

void
tree_set_block (tree t, tree b)
{
  const enum tree_code_class c = TREE_CODE_CLASS (TREE_CODE (t));

  if (IS_EXPR_CODE_CLASS (c))
    {
      t->exp.locus = set_block (t->exp.locus, b);
    }
  else
    gcc_unreachable ();
}

/* Create a nameless artificial label and put it in the current
   function context.  The label has a location of LOC.  Returns the
   newly created label.  */

tree
create_artificial_label (location_t loc)
{
  tree lab = build_decl (loc,
      			 LABEL_DECL, NULL_TREE, void_type_node);

  DECL_ARTIFICIAL (lab) = 1;
  DECL_IGNORED_P (lab) = 1;
  DECL_CONTEXT (lab) = current_function_decl;
  return lab;
}

/*  Given a tree, try to return a useful variable name that we can use
    to prefix a temporary that is being assigned the value of the tree.
    I.E. given  <temp> = &A, return A.  */

const char *
get_name (tree t)
{
  tree stripped_decl;

  stripped_decl = t;
  STRIP_NOPS (stripped_decl);
  if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl))
    return IDENTIFIER_POINTER (DECL_NAME (stripped_decl));
  else if (TREE_CODE (stripped_decl) == SSA_NAME)
    {
      tree name = SSA_NAME_IDENTIFIER (stripped_decl);
      if (!name)
	return NULL;
      return IDENTIFIER_POINTER (name);
    }
  else
    {
      switch (TREE_CODE (stripped_decl))
	{
	case ADDR_EXPR:
	  return get_name (TREE_OPERAND (stripped_decl, 0));
	default:
	  return NULL;
	}
    }
}

/* Return true if TYPE has a variable argument list.  */

bool
stdarg_p (const_tree fntype)
{
  function_args_iterator args_iter;
  tree n = NULL_TREE, t;

  if (!fntype)
    return false;

  FOREACH_FUNCTION_ARGS (fntype, t, args_iter)
    {
      n = t;
    }

  return n != NULL_TREE && n != void_type_node;
}

/* Return true if TYPE has a prototype.  */

bool
prototype_p (const_tree fntype)
{
  tree t;

  gcc_assert (fntype != NULL_TREE);

  t = TYPE_ARG_TYPES (fntype);
  return (t != NULL_TREE);
}

/* If BLOCK is inlined from an __attribute__((__artificial__))
   routine, return pointer to location from where it has been
   called.  */
location_t *
block_nonartificial_location (tree block)
{
  location_t *ret = NULL;

  while (block && TREE_CODE (block) == BLOCK
	 && BLOCK_ABSTRACT_ORIGIN (block))
    {
      tree ao = BLOCK_ABSTRACT_ORIGIN (block);
      if (TREE_CODE (ao) == FUNCTION_DECL)
	{
	  /* If AO is an artificial inline, point RET to the
	     call site locus at which it has been inlined and continue
	     the loop, in case AO's caller is also an artificial
	     inline.  */
	  if (DECL_DECLARED_INLINE_P (ao)
	      && lookup_attribute ("artificial", DECL_ATTRIBUTES (ao)))
	    ret = &BLOCK_SOURCE_LOCATION (block);
	  else
	    break;
	}
      else if (TREE_CODE (ao) != BLOCK)
	break;

      block = BLOCK_SUPERCONTEXT (block);
    }
  return ret;
}


/* If EXP is inlined from an __attribute__((__artificial__))
   function, return the location of the original call expression.  */

location_t
tree_nonartificial_location (tree exp)
{
  location_t *loc = block_nonartificial_location (TREE_BLOCK (exp));

  if (loc)
    return *loc;
  else
    return EXPR_LOCATION (exp);
}


/* These are the hash table functions for the hash table of OPTIMIZATION_NODEq
   nodes.  */

/* Return the hash code X, an OPTIMIZATION_NODE or TARGET_OPTION code.  */

hashval_t
cl_option_hasher::hash (tree x)
{
  const_tree const t = x;
  const char *p;
  size_t i;
  size_t len = 0;
  hashval_t hash = 0;

  if (TREE_CODE (t) == OPTIMIZATION_NODE)
    {
      p = (const char *)TREE_OPTIMIZATION (t);
      len = sizeof (struct cl_optimization);
    }

  else if (TREE_CODE (t) == TARGET_OPTION_NODE)
    return cl_target_option_hash (TREE_TARGET_OPTION (t));

  else
    gcc_unreachable ();

  /* assume most opt flags are just 0/1, some are 2-3, and a few might be
     something else.  */
  for (i = 0; i < len; i++)
    if (p[i])
      hash = (hash << 4) ^ ((i << 2) | p[i]);

  return hash;
}

/* Return nonzero if the value represented by *X (an OPTIMIZATION or
   TARGET_OPTION tree node) is the same as that given by *Y, which is the
   same.  */

bool
cl_option_hasher::equal (tree x, tree y)
{
  const_tree const xt = x;
  const_tree const yt = y;

  if (TREE_CODE (xt) != TREE_CODE (yt))
    return 0;

  if (TREE_CODE (xt) == OPTIMIZATION_NODE)
    return cl_optimization_option_eq (TREE_OPTIMIZATION (xt),
				      TREE_OPTIMIZATION (yt));
  else if (TREE_CODE (xt) == TARGET_OPTION_NODE)
    return cl_target_option_eq (TREE_TARGET_OPTION (xt),
				TREE_TARGET_OPTION (yt));
  else
    gcc_unreachable ();
}

/* Build an OPTIMIZATION_NODE based on the options in OPTS.  */

tree
build_optimization_node (struct gcc_options *opts)
{
  tree t;

  /* Use the cache of optimization nodes.  */

  cl_optimization_save (TREE_OPTIMIZATION (cl_optimization_node),
			opts);

  tree *slot = cl_option_hash_table->find_slot (cl_optimization_node, INSERT);
  t = *slot;
  if (!t)
    {
      /* Insert this one into the hash table.  */
      t = cl_optimization_node;
      *slot = t;

      /* Make a new node for next time round.  */
      cl_optimization_node = make_node (OPTIMIZATION_NODE);
    }

  return t;
}

/* Build a TARGET_OPTION_NODE based on the options in OPTS.  */

tree
build_target_option_node (struct gcc_options *opts)
{
  tree t;

  /* Use the cache of optimization nodes.  */

  cl_target_option_save (TREE_TARGET_OPTION (cl_target_option_node),
			 opts);

  tree *slot = cl_option_hash_table->find_slot (cl_target_option_node, INSERT);
  t = *slot;
  if (!t)
    {
      /* Insert this one into the hash table.  */
      t = cl_target_option_node;
      *slot = t;

      /* Make a new node for next time round.  */
      cl_target_option_node = make_node (TARGET_OPTION_NODE);
    }

  return t;
}

/* Clear TREE_TARGET_GLOBALS of all TARGET_OPTION_NODE trees,
   so that they aren't saved during PCH writing.  */

void
prepare_target_option_nodes_for_pch (void)
{
  hash_table<cl_option_hasher>::iterator iter = cl_option_hash_table->begin ();
  for (; iter != cl_option_hash_table->end (); ++iter)
    if (TREE_CODE (*iter) == TARGET_OPTION_NODE)
      TREE_TARGET_GLOBALS (*iter) = NULL;
}

/* Determine the "ultimate origin" of a block.  */

tree
block_ultimate_origin (const_tree block)
{
  tree origin = BLOCK_ABSTRACT_ORIGIN (block);

  if (origin == NULL_TREE)
    return NULL_TREE;
  else
    {
      gcc_checking_assert ((DECL_P (origin)
			    && DECL_ORIGIN (origin) == origin)
			   || BLOCK_ORIGIN (origin) == origin);
      return origin;
    }
}

/* Return true iff conversion from INNER_TYPE to OUTER_TYPE generates
   no instruction.  */

bool
tree_nop_conversion_p (const_tree outer_type, const_tree inner_type)
{
  /* Do not strip casts into or out of differing address spaces.  */
  if (POINTER_TYPE_P (outer_type)
      && TYPE_ADDR_SPACE (TREE_TYPE (outer_type)) != ADDR_SPACE_GENERIC)
    {
      if (!POINTER_TYPE_P (inner_type)
	  || (TYPE_ADDR_SPACE (TREE_TYPE (outer_type))
	      != TYPE_ADDR_SPACE (TREE_TYPE (inner_type))))
	return false;
    }
  else if (POINTER_TYPE_P (inner_type)
	   && TYPE_ADDR_SPACE (TREE_TYPE (inner_type)) != ADDR_SPACE_GENERIC)
    {
      /* We already know that outer_type is not a pointer with
	 a non-generic address space.  */
      return false;
    }

  /* Use precision rather then machine mode when we can, which gives
     the correct answer even for submode (bit-field) types.  */
  if ((INTEGRAL_TYPE_P (outer_type)
       || POINTER_TYPE_P (outer_type)
       || TREE_CODE (outer_type) == OFFSET_TYPE)
      && (INTEGRAL_TYPE_P (inner_type)
	  || POINTER_TYPE_P (inner_type)
	  || TREE_CODE (inner_type) == OFFSET_TYPE))
    return TYPE_PRECISION (outer_type) == TYPE_PRECISION (inner_type);

  /* Otherwise fall back on comparing machine modes (e.g. for
     aggregate types, floats).  */
  return TYPE_MODE (outer_type) == TYPE_MODE (inner_type);
}

/* Return true iff conversion in EXP generates no instruction.  Mark
   it inline so that we fully inline into the stripping functions even
   though we have two uses of this function.  */

static inline bool
tree_nop_conversion (const_tree exp)
{
  tree outer_type, inner_type;

  if (location_wrapper_p (exp))
    return true;
  if (!CONVERT_EXPR_P (exp)
      && TREE_CODE (exp) != NON_LVALUE_EXPR)
    return false;
  if (TREE_OPERAND (exp, 0) == error_mark_node)
    return false;

  outer_type = TREE_TYPE (exp);
  inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));

  if (!inner_type)
    return false;

  return tree_nop_conversion_p (outer_type, inner_type);
}

/* Return true iff conversion in EXP generates no instruction.  Don't
   consider conversions changing the signedness.  */

static bool
tree_sign_nop_conversion (const_tree exp)
{
  tree outer_type, inner_type;

  if (!tree_nop_conversion (exp))
    return false;

  outer_type = TREE_TYPE (exp);
  inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));

  return (TYPE_UNSIGNED (outer_type) == TYPE_UNSIGNED (inner_type)
	  && POINTER_TYPE_P (outer_type) == POINTER_TYPE_P (inner_type));
}

/* Strip conversions from EXP according to tree_nop_conversion and
   return the resulting expression.  */

tree
tree_strip_nop_conversions (tree exp)
{
  while (tree_nop_conversion (exp))
    exp = TREE_OPERAND (exp, 0);
  return exp;
}

/* Strip conversions from EXP according to tree_sign_nop_conversion
   and return the resulting expression.  */

tree
tree_strip_sign_nop_conversions (tree exp)
{
  while (tree_sign_nop_conversion (exp))
    exp = TREE_OPERAND (exp, 0);
  return exp;
}

/* Avoid any floating point extensions from EXP.  */
tree
strip_float_extensions (tree exp)
{
  tree sub, expt, subt;

  /*  For floating point constant look up the narrowest type that can hold
      it properly and handle it like (type)(narrowest_type)constant.
      This way we can optimize for instance a=a*2.0 where "a" is float
      but 2.0 is double constant.  */
  if (TREE_CODE (exp) == REAL_CST && !DECIMAL_FLOAT_TYPE_P (TREE_TYPE (exp)))
    {
      REAL_VALUE_TYPE orig;
      tree type = NULL;

      orig = TREE_REAL_CST (exp);
      if (TYPE_PRECISION (TREE_TYPE (exp)) > TYPE_PRECISION (float_type_node)
	  && exact_real_truncate (TYPE_MODE (float_type_node), &orig))
	type = float_type_node;
      else if (TYPE_PRECISION (TREE_TYPE (exp))
	       > TYPE_PRECISION (double_type_node)
	       && exact_real_truncate (TYPE_MODE (double_type_node), &orig))
	type = double_type_node;
      if (type)
	return build_real_truncate (type, orig);
    }

  if (!CONVERT_EXPR_P (exp))
    return exp;

  sub = TREE_OPERAND (exp, 0);
  subt = TREE_TYPE (sub);
  expt = TREE_TYPE (exp);

  if (!FLOAT_TYPE_P (subt))
    return exp;

  if (DECIMAL_FLOAT_TYPE_P (expt) != DECIMAL_FLOAT_TYPE_P (subt))
    return exp;

  if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt))
    return exp;

  return strip_float_extensions (sub);
}

/* Strip out all handled components that produce invariant
   offsets.  */

const_tree
strip_invariant_refs (const_tree op)
{
  while (handled_component_p (op))
    {
      switch (TREE_CODE (op))
	{
	case ARRAY_REF:
	case ARRAY_RANGE_REF:
	  if (!is_gimple_constant (TREE_OPERAND (op, 1))
	      || TREE_OPERAND (op, 2) != NULL_TREE
	      || TREE_OPERAND (op, 3) != NULL_TREE)
	    return NULL;
	  break;

	case COMPONENT_REF:
	  if (TREE_OPERAND (op, 2) != NULL_TREE)
	    return NULL;
	  break;

	default:;
	}
      op = TREE_OPERAND (op, 0);
    }

  return op;
}

static GTY(()) tree gcc_eh_personality_decl;

/* Return the GCC personality function decl.  */

tree
lhd_gcc_personality (void)
{
  if (!gcc_eh_personality_decl)
    gcc_eh_personality_decl = build_personality_function ("gcc");
  return gcc_eh_personality_decl;
}

/* TARGET is a call target of GIMPLE call statement
   (obtained by gimple_call_fn).  Return true if it is
   OBJ_TYPE_REF representing an virtual call of C++ method.
   (As opposed to OBJ_TYPE_REF representing objc calls
   through a cast where middle-end devirtualization machinery
   can't apply.) */

bool
virtual_method_call_p (const_tree target)
{
  if (TREE_CODE (target) != OBJ_TYPE_REF)
    return false;
  tree t = TREE_TYPE (target);
  gcc_checking_assert (TREE_CODE (t) == POINTER_TYPE);
  t = TREE_TYPE (t);
  if (TREE_CODE (t) == FUNCTION_TYPE)
    return false;
  gcc_checking_assert (TREE_CODE (t) == METHOD_TYPE);
  /* If we do not have BINFO associated, it means that type was built
     without devirtualization enabled.  Do not consider this a virtual
     call.  */
  if (!TYPE_BINFO (obj_type_ref_class (target)))
    return false;
  return true;
}

/* REF is OBJ_TYPE_REF, return the class the ref corresponds to.  */

tree
obj_type_ref_class (const_tree ref)
{
  gcc_checking_assert (TREE_CODE (ref) == OBJ_TYPE_REF);
  ref = TREE_TYPE (ref);
  gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
  ref = TREE_TYPE (ref);
  /* We look for type THIS points to.  ObjC also builds
     OBJ_TYPE_REF with non-method calls, Their first parameter
     ID however also corresponds to class type. */
  gcc_checking_assert (TREE_CODE (ref) == METHOD_TYPE
		       || TREE_CODE (ref) == FUNCTION_TYPE);
  ref = TREE_VALUE (TYPE_ARG_TYPES (ref));
  gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
  return TREE_TYPE (ref);
}

/* Lookup sub-BINFO of BINFO of TYPE at offset POS.  */

static tree
lookup_binfo_at_offset (tree binfo, tree type, HOST_WIDE_INT pos)
{
  unsigned int i;
  tree base_binfo, b;

  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    if (pos == tree_to_shwi (BINFO_OFFSET (base_binfo))
	&& types_same_for_odr (TREE_TYPE (base_binfo), type))
      return base_binfo;
    else if ((b = lookup_binfo_at_offset (base_binfo, type, pos)) != NULL)
      return b;
  return NULL;
}

/* Try to find a base info of BINFO that would have its field decl at offset
   OFFSET within the BINFO type and which is of EXPECTED_TYPE.  If it can be
   found, return, otherwise return NULL_TREE.  */

tree
get_binfo_at_offset (tree binfo, poly_int64 offset, tree expected_type)
{
  tree type = BINFO_TYPE (binfo);

  while (true)
    {
      HOST_WIDE_INT pos, size;
      tree fld;
      int i;

      if (types_same_for_odr (type, expected_type))
	  return binfo;
      if (maybe_lt (offset, 0))
	return NULL_TREE;

      for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
	{
	  if (TREE_CODE (fld) != FIELD_DECL || !DECL_ARTIFICIAL (fld))
	    continue;

	  pos = int_bit_position (fld);
	  size = tree_to_uhwi (DECL_SIZE (fld));
	  if (known_in_range_p (offset, pos, size))
	    break;
	}
      if (!fld || TREE_CODE (TREE_TYPE (fld)) != RECORD_TYPE)
	return NULL_TREE;

      /* Offset 0 indicates the primary base, whose vtable contents are
	 represented in the binfo for the derived class.  */
      else if (maybe_ne (offset, 0))
	{
	  tree found_binfo = NULL, base_binfo;
	  /* Offsets in BINFO are in bytes relative to the whole structure
	     while POS is in bits relative to the containing field.  */
	  int binfo_offset = (tree_to_shwi (BINFO_OFFSET (binfo)) + pos
			     / BITS_PER_UNIT);

	  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
	    if (tree_to_shwi (BINFO_OFFSET (base_binfo)) == binfo_offset
		&& types_same_for_odr (TREE_TYPE (base_binfo), TREE_TYPE (fld)))
	      {
		found_binfo = base_binfo;
		break;
	      }
	  if (found_binfo)
	    binfo = found_binfo;
	  else
	    binfo = lookup_binfo_at_offset (binfo, TREE_TYPE (fld),
					    binfo_offset);
	 }

      type = TREE_TYPE (fld);
      offset -= pos;
    }
}

/* Returns true if X is a typedef decl.  */

bool
is_typedef_decl (const_tree x)
{
  return (x && TREE_CODE (x) == TYPE_DECL
          && DECL_ORIGINAL_TYPE (x) != NULL_TREE);
}

/* Returns true iff TYPE is a type variant created for a typedef. */

bool
typedef_variant_p (const_tree type)
{
  return is_typedef_decl (TYPE_NAME (type));
}

/* A class to handle converting a string that might contain
   control characters, (eg newline, form-feed, etc), into one
   in which contains escape sequences instead.  */

class escaped_string
{
 public:
  escaped_string () { m_owned = false; m_str = NULL; };
  ~escaped_string () { if (m_owned) free (m_str); }
  operator const char *() const { return (const char *) m_str; }
  void escape (const char *);
 private:
  char *m_str;
  bool  m_owned;
};

/* PR 84195: Replace control characters in "unescaped" with their
   escaped equivalents.  Allow newlines if -fmessage-length has
   been set to a non-zero value.  This is done here, rather than
   where the attribute is recorded as the message length can
   change between these two locations.  */

void
escaped_string::escape (const char *unescaped)
{
  char *escaped;
  size_t i, new_i, len;

  if (m_owned)
    free (m_str);

  m_str = const_cast<char *> (unescaped);
  m_owned = false;

  if (unescaped == NULL || *unescaped == 0)
    return;

  len = strlen (unescaped);
  escaped = NULL;
  new_i = 0;

  for (i = 0; i < len; i++)
    {
      char c = unescaped[i];

      if (!ISCNTRL (c))
	{
	  if (escaped)
	    escaped[new_i++] = c;
	  continue;
	}

      if (c != '\n' || !pp_is_wrapping_line (global_dc->printer))
	{
	  if (escaped == NULL)
	    {
	      /* We only allocate space for a new string if we
		 actually encounter a control character that
		 needs replacing.  */
	      escaped = (char *) xmalloc (len * 2 + 1);
	      strncpy (escaped, unescaped, i);
	      new_i = i;
	    }

	  escaped[new_i++] = '\\';

	  switch (c)
	    {
	    case '\a': escaped[new_i++] = 'a'; break;
	    case '\b': escaped[new_i++] = 'b'; break;
	    case '\f': escaped[new_i++] = 'f'; break;
	    case '\n': escaped[new_i++] = 'n'; break;
	    case '\r': escaped[new_i++] = 'r'; break;
	    case '\t': escaped[new_i++] = 't'; break;
	    case '\v': escaped[new_i++] = 'v'; break;
	    default:   escaped[new_i++] = '?'; break;
	    }
	}
      else if (escaped)
	escaped[new_i++] = c;
    }

  if (escaped)
    {
      escaped[new_i] = 0;
      m_str = escaped;
      m_owned = true;
    }
}

/* Warn about a use of an identifier which was marked deprecated.  Returns
   whether a warning was given.  */

bool
warn_deprecated_use (tree node, tree attr)
{
  escaped_string msg;

  if (node == 0 || !warn_deprecated_decl)
    return false;

  if (!attr)
    {
      if (DECL_P (node))
	attr = DECL_ATTRIBUTES (node);
      else if (TYPE_P (node))
	{
	  tree decl = TYPE_STUB_DECL (node);
	  if (decl)
	    attr = lookup_attribute ("deprecated",
				     TYPE_ATTRIBUTES (TREE_TYPE (decl)));
	}
    }

  if (attr)
    attr = lookup_attribute ("deprecated", attr);

  if (attr)
    msg.escape (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));

  bool w = false;
  if (DECL_P (node))
    {
      auto_diagnostic_group d;
      if (msg)
	w = warning (OPT_Wdeprecated_declarations,
		     "%qD is deprecated: %s", node, (const char *) msg);
      else
	w = warning (OPT_Wdeprecated_declarations,
		     "%qD is deprecated", node);
      if (w)
	inform (DECL_SOURCE_LOCATION (node), "declared here");
    }
  else if (TYPE_P (node))
    {
      tree what = NULL_TREE;
      tree decl = TYPE_STUB_DECL (node);

      if (TYPE_NAME (node))
	{
	  if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
	    what = TYPE_NAME (node);
	  else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
		   && DECL_NAME (TYPE_NAME (node)))
	    what = DECL_NAME (TYPE_NAME (node));
	}

      auto_diagnostic_group d;
      if (what)
	{
	  if (msg)
	    w = warning (OPT_Wdeprecated_declarations,
			 "%qE is deprecated: %s", what, (const char *) msg);
	  else
	    w = warning (OPT_Wdeprecated_declarations,
			 "%qE is deprecated", what);
	}
      else
	{
	  if (msg)
	    w = warning (OPT_Wdeprecated_declarations,
			 "type is deprecated: %s", (const char *) msg);
	  else
	    w = warning (OPT_Wdeprecated_declarations,
			 "type is deprecated");
	}

      if (w && decl)
	inform (DECL_SOURCE_LOCATION (decl), "declared here");
    }

  return w;
}

/* Return true if REF has a COMPONENT_REF with a bit-field field declaration
   somewhere in it.  */

bool
contains_bitfld_component_ref_p (const_tree ref)
{
  while (handled_component_p (ref))
    {
      if (TREE_CODE (ref) == COMPONENT_REF
          && DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))
        return true;
      ref = TREE_OPERAND (ref, 0);
    }

  return false;
}

/* Try to determine whether a TRY_CATCH expression can fall through.
   This is a subroutine of block_may_fallthru.  */

static bool
try_catch_may_fallthru (const_tree stmt)
{
  tree_stmt_iterator i;

  /* If the TRY block can fall through, the whole TRY_CATCH can
     fall through.  */
  if (block_may_fallthru (TREE_OPERAND (stmt, 0)))
    return true;

  i = tsi_start (TREE_OPERAND (stmt, 1));
  switch (TREE_CODE (tsi_stmt (i)))
    {
    case CATCH_EXPR:
      /* We expect to see a sequence of CATCH_EXPR trees, each with a
	 catch expression and a body.  The whole TRY_CATCH may fall
	 through iff any of the catch bodies falls through.  */
      for (; !tsi_end_p (i); tsi_next (&i))
	{
	  if (block_may_fallthru (CATCH_BODY (tsi_stmt (i))))
	    return true;
	}
      return false;

    case EH_FILTER_EXPR:
      /* The exception filter expression only matters if there is an
	 exception.  If the exception does not match EH_FILTER_TYPES,
	 we will execute EH_FILTER_FAILURE, and we will fall through
	 if that falls through.  If the exception does match
	 EH_FILTER_TYPES, the stack unwinder will continue up the
	 stack, so we will not fall through.  We don't know whether we
	 will throw an exception which matches EH_FILTER_TYPES or not,
	 so we just ignore EH_FILTER_TYPES and assume that we might
	 throw an exception which doesn't match.  */
      return block_may_fallthru (EH_FILTER_FAILURE (tsi_stmt (i)));

    default:
      /* This case represents statements to be executed when an
	 exception occurs.  Those statements are implicitly followed
	 by a RESX statement to resume execution after the exception.
	 So in this case the TRY_CATCH never falls through.  */
      return false;
    }
}

/* Try to determine if we can fall out of the bottom of BLOCK.  This guess
   need not be 100% accurate; simply be conservative and return true if we
   don't know.  This is used only to avoid stupidly generating extra code.
   If we're wrong, we'll just delete the extra code later.  */

bool
block_may_fallthru (const_tree block)
{
  /* This CONST_CAST is okay because expr_last returns its argument
     unmodified and we assign it to a const_tree.  */
  const_tree stmt = expr_last (CONST_CAST_TREE (block));

  switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
    {
    case GOTO_EXPR:
    case RETURN_EXPR:
      /* Easy cases.  If the last statement of the block implies
	 control transfer, then we can't fall through.  */
      return false;

    case SWITCH_EXPR:
      /* If there is a default: label or case labels cover all possible
	 SWITCH_COND values, then the SWITCH_EXPR will transfer control
	 to some case label in all cases and all we care is whether the
	 SWITCH_BODY falls through.  */
      if (SWITCH_ALL_CASES_P (stmt))
	return block_may_fallthru (SWITCH_BODY (stmt));
      return true;

    case COND_EXPR:
      if (block_may_fallthru (COND_EXPR_THEN (stmt)))
	return true;
      return block_may_fallthru (COND_EXPR_ELSE (stmt));

    case BIND_EXPR:
      return block_may_fallthru (BIND_EXPR_BODY (stmt));

    case TRY_CATCH_EXPR:
      return try_catch_may_fallthru (stmt);

    case TRY_FINALLY_EXPR:
      /* The finally clause is always executed after the try clause,
	 so if it does not fall through, then the try-finally will not
	 fall through.  Otherwise, if the try clause does not fall
	 through, then when the finally clause falls through it will
	 resume execution wherever the try clause was going.  So the
	 whole try-finally will only fall through if both the try
	 clause and the finally clause fall through.  */
      return (block_may_fallthru (TREE_OPERAND (stmt, 0))
	      && block_may_fallthru (TREE_OPERAND (stmt, 1)));

    case MODIFY_EXPR:
      if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
	stmt = TREE_OPERAND (stmt, 1);
      else
	return true;
      /* FALLTHRU */

    case CALL_EXPR:
      /* Functions that do not return do not fall through.  */
      return (call_expr_flags (stmt) & ECF_NORETURN) == 0;

    case CLEANUP_POINT_EXPR:
      return block_may_fallthru (TREE_OPERAND (stmt, 0));

    case TARGET_EXPR:
      return block_may_fallthru (TREE_OPERAND (stmt, 1));

    case ERROR_MARK:
      return true;

    default:
      return lang_hooks.block_may_fallthru (stmt);
    }
}

/* True if we are using EH to handle cleanups.  */
static bool using_eh_for_cleanups_flag = false;

/* This routine is called from front ends to indicate eh should be used for
   cleanups.  */
void
using_eh_for_cleanups (void)
{
  using_eh_for_cleanups_flag = true;
}

/* Query whether EH is used for cleanups.  */
bool
using_eh_for_cleanups_p (void)
{
  return using_eh_for_cleanups_flag;
}

/* Wrapper for tree_code_name to ensure that tree code is valid */
const char *
get_tree_code_name (enum tree_code code)
{
  const char *invalid = "<invalid tree code>";

  if (code >= MAX_TREE_CODES)
    return invalid;

  return tree_code_name[code];
}

/* Drops the TREE_OVERFLOW flag from T.  */

tree
drop_tree_overflow (tree t)
{
  gcc_checking_assert (TREE_OVERFLOW (t));

  /* For tree codes with a sharing machinery re-build the result.  */
  if (poly_int_tree_p (t))
    return wide_int_to_tree (TREE_TYPE (t), wi::to_poly_wide (t));

  /* For VECTOR_CST, remove the overflow bits from the encoded elements
     and canonicalize the result.  */
  if (TREE_CODE (t) == VECTOR_CST)
    {
      tree_vector_builder builder;
      builder.new_unary_operation (TREE_TYPE (t), t, true);
      unsigned int count = builder.encoded_nelts ();
      for (unsigned int i = 0; i < count; ++i)
	{
	  tree elt = VECTOR_CST_ELT (t, i);
	  if (TREE_OVERFLOW (elt))
	    elt = drop_tree_overflow (elt);
	  builder.quick_push (elt);
	}
      return builder.build ();
    }

  /* Otherwise, as all tcc_constants are possibly shared, copy the node
     and drop the flag.  */
  t = copy_node (t);
  TREE_OVERFLOW (t) = 0;

  /* For constants that contain nested constants, drop the flag
     from those as well.  */
  if (TREE_CODE (t) == COMPLEX_CST)
    {
      if (TREE_OVERFLOW (TREE_REALPART (t)))
	TREE_REALPART (t) = drop_tree_overflow (TREE_REALPART (t));
      if (TREE_OVERFLOW (TREE_IMAGPART (t)))
	TREE_IMAGPART (t) = drop_tree_overflow (TREE_IMAGPART (t));
    }

  return t;
}

/* Given a memory reference expression T, return its base address.
   The base address of a memory reference expression is the main
   object being referenced.  For instance, the base address for
   'array[i].fld[j]' is 'array'.  You can think of this as stripping
   away the offset part from a memory address.

   This function calls handled_component_p to strip away all the inner
   parts of the memory reference until it reaches the base object.  */

tree
get_base_address (tree t)
{
  while (handled_component_p (t))
    t = TREE_OPERAND (t, 0);

  if ((TREE_CODE (t) == MEM_REF
       || TREE_CODE (t) == TARGET_MEM_REF)
      && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
    t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);

  /* ???  Either the alias oracle or all callers need to properly deal
     with WITH_SIZE_EXPRs before we can look through those.  */
  if (TREE_CODE (t) == WITH_SIZE_EXPR)
    return NULL_TREE;

  return t;
}

/* Return a tree of sizetype representing the size, in bytes, of the element
   of EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */

tree
array_ref_element_size (tree exp)
{
  tree aligned_size = TREE_OPERAND (exp, 3);
  tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)));
  location_t loc = EXPR_LOCATION (exp);

  /* If a size was specified in the ARRAY_REF, it's the size measured
     in alignment units of the element type.  So multiply by that value.  */
  if (aligned_size)
    {
      /* ??? tree_ssa_useless_type_conversion will eliminate casts to
	 sizetype from another type of the same width and signedness.  */
      if (TREE_TYPE (aligned_size) != sizetype)
	aligned_size = fold_convert_loc (loc, sizetype, aligned_size);
      return size_binop_loc (loc, MULT_EXPR, aligned_size,
			     size_int (TYPE_ALIGN_UNIT (elmt_type)));
    }

  /* Otherwise, take the size from that of the element type.  Substitute
     any PLACEHOLDER_EXPR that we have.  */
  else
    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), exp);
}

/* Return a tree representing the lower bound of the array mentioned in
   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */

tree
array_ref_low_bound (tree exp)
{
  tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));

  /* If a lower bound is specified in EXP, use it.  */
  if (TREE_OPERAND (exp, 2))
    return TREE_OPERAND (exp, 2);

  /* Otherwise, if there is a domain type and it has a lower bound, use it,
     substituting for a PLACEHOLDER_EXPR as needed.  */
  if (domain_type && TYPE_MIN_VALUE (domain_type))
    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp);

  /* Otherwise, return a zero of the appropriate type.  */
  return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0);
}

/* Return a tree representing the upper bound of the array mentioned in
   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */

tree
array_ref_up_bound (tree exp)
{
  tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));

  /* If there is a domain type and it has an upper bound, use it, substituting
     for a PLACEHOLDER_EXPR as needed.  */
  if (domain_type && TYPE_MAX_VALUE (domain_type))
    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp);

  /* Otherwise fail.  */
  return NULL_TREE;
}

/* Returns true if REF is an array reference or a component reference
   to an array at the end of a structure.
   If this is the case, the array may be allocated larger
   than its upper bound implies.  */

bool
array_at_struct_end_p (tree ref)
{
  tree atype;

  if (TREE_CODE (ref) == ARRAY_REF
      || TREE_CODE (ref) == ARRAY_RANGE_REF)
    {
      atype = TREE_TYPE (TREE_OPERAND (ref, 0));
      ref = TREE_OPERAND (ref, 0);
    }
  else if (TREE_CODE (ref) == COMPONENT_REF
	   && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 1))) == ARRAY_TYPE)
    atype = TREE_TYPE (TREE_OPERAND (ref, 1));
  else
    return false;

  if (TREE_CODE (ref) == STRING_CST)
    return false;

  tree ref_to_array = ref;
  while (handled_component_p (ref))
    {
      /* If the reference chain contains a component reference to a
         non-union type and there follows another field the reference
	 is not at the end of a structure.  */
      if (TREE_CODE (ref) == COMPONENT_REF)
	{
	  if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
	    {
	      tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1));
	      while (nextf && TREE_CODE (nextf) != FIELD_DECL)
		nextf = DECL_CHAIN (nextf);
	      if (nextf)
		return false;
	    }
	}
      /* If we have a multi-dimensional array we do not consider
         a non-innermost dimension as flex array if the whole
	 multi-dimensional array is at struct end.
	 Same for an array of aggregates with a trailing array
	 member.  */
      else if (TREE_CODE (ref) == ARRAY_REF)
	return false;
      else if (TREE_CODE (ref) == ARRAY_RANGE_REF)
	;
      /* If we view an underlying object as sth else then what we
         gathered up to now is what we have to rely on.  */
      else if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
	break;
      else
	gcc_unreachable ();

      ref = TREE_OPERAND (ref, 0);
    }

  /* The array now is at struct end.  Treat flexible arrays as
     always subject to extend, even into just padding constrained by
     an underlying decl.  */
  if (! TYPE_SIZE (atype)
      || ! TYPE_DOMAIN (atype)
      || ! TYPE_MAX_VALUE (TYPE_DOMAIN (atype)))
    return true;

  if (TREE_CODE (ref) == MEM_REF
      && TREE_CODE (TREE_OPERAND (ref, 0)) == ADDR_EXPR)
    ref = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);

  /* If the reference is based on a declared entity, the size of the array
     is constrained by its given domain.  (Do not trust commons PR/69368).  */
  if (DECL_P (ref)
      && !(flag_unconstrained_commons
	   && VAR_P (ref) && DECL_COMMON (ref))
      && DECL_SIZE_UNIT (ref)
      && TREE_CODE (DECL_SIZE_UNIT (ref)) == INTEGER_CST)
    {
      /* Check whether the array domain covers all of the available
         padding.  */
      poly_int64 offset;
      if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (atype))) != INTEGER_CST
	  || TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (atype))) != INTEGER_CST
          || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (atype))) != INTEGER_CST)
	return true;
      if (! get_addr_base_and_unit_offset (ref_to_array, &offset))
	return true;

      /* If at least one extra element fits it is a flexarray.  */
      if (known_le ((wi::to_offset (TYPE_MAX_VALUE (TYPE_DOMAIN (atype)))
		     - wi::to_offset (TYPE_MIN_VALUE (TYPE_DOMAIN (atype)))
		     + 2)
		    * wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (atype))),
		    wi::to_offset (DECL_SIZE_UNIT (ref)) - offset))
	return true;

      return false;
    }

  return true;
}

/* Return a tree representing the offset, in bytes, of the field referenced
   by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */

tree
component_ref_field_offset (tree exp)
{
  tree aligned_offset = TREE_OPERAND (exp, 2);
  tree field = TREE_OPERAND (exp, 1);
  location_t loc = EXPR_LOCATION (exp);

  /* If an offset was specified in the COMPONENT_REF, it's the offset measured
     in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT.  So multiply by that
     value.  */
  if (aligned_offset)
    {
      /* ??? tree_ssa_useless_type_conversion will eliminate casts to
	 sizetype from another type of the same width and signedness.  */
      if (TREE_TYPE (aligned_offset) != sizetype)
	aligned_offset = fold_convert_loc (loc, sizetype, aligned_offset);
      return size_binop_loc (loc, MULT_EXPR, aligned_offset,
			     size_int (DECL_OFFSET_ALIGN (field)
				       / BITS_PER_UNIT));
    }

  /* Otherwise, take the offset from that of the field.  Substitute
     any PLACEHOLDER_EXPR that we have.  */
  else
    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp);
}

/* Return the machine mode of T.  For vectors, returns the mode of the
   inner type.  The main use case is to feed the result to HONOR_NANS,
   avoiding the BLKmode that a direct TYPE_MODE (T) might return.  */

machine_mode
element_mode (const_tree t)
{
  if (!TYPE_P (t))
    t = TREE_TYPE (t);
  if (VECTOR_TYPE_P (t) || TREE_CODE (t) == COMPLEX_TYPE)
    t = TREE_TYPE (t);
  return TYPE_MODE (t);
}

/* Vector types need to re-check the target flags each time we report
   the machine mode.  We need to do this because attribute target can
   change the result of vector_mode_supported_p and have_regs_of_mode
   on a per-function basis.  Thus the TYPE_MODE of a VECTOR_TYPE can
   change on a per-function basis.  */
/* ??? Possibly a better solution is to run through all the types
   referenced by a function and re-compute the TYPE_MODE once, rather
   than make the TYPE_MODE macro call a function.  */

machine_mode
vector_type_mode (const_tree t)
{
  machine_mode mode;

  gcc_assert (TREE_CODE (t) == VECTOR_TYPE);

  mode = t->type_common.mode;
  if (VECTOR_MODE_P (mode)
      && (!targetm.vector_mode_supported_p (mode)
	  || !have_regs_of_mode[mode]))
    {
      scalar_int_mode innermode;

      /* For integers, try mapping it to a same-sized scalar mode.  */
      if (is_int_mode (TREE_TYPE (t)->type_common.mode, &innermode))
	{
	  poly_int64 size = (TYPE_VECTOR_SUBPARTS (t)
			     * GET_MODE_BITSIZE (innermode));
	  scalar_int_mode mode;
	  if (int_mode_for_size (size, 0).exists (&mode)
	      && have_regs_of_mode[mode])
	    return mode;
	}

      return BLKmode;
    }

  return mode;
}

/* Verify that basic properties of T match TV and thus T can be a variant of
   TV.  TV should be the more specified variant (i.e. the main variant).  */

static bool
verify_type_variant (const_tree t, tree tv)
{
  /* Type variant can differ by:

     - TYPE_QUALS: TYPE_READONLY, TYPE_VOLATILE, TYPE_ATOMIC, TYPE_RESTRICT,
                   ENCODE_QUAL_ADDR_SPACE. 
     - main variant may be TYPE_COMPLETE_P and variant types !TYPE_COMPLETE_P
       in this case some values may not be set in the variant types
       (see TYPE_COMPLETE_P checks).
     - it is possible to have TYPE_ARTIFICIAL variant of non-artifical type
     - by TYPE_NAME and attributes (i.e. when variant originate by typedef)
     - TYPE_CANONICAL (TYPE_ALIAS_SET is the same among variants)
     - by the alignment: TYPE_ALIGN and TYPE_USER_ALIGN
     - during LTO by TYPE_CONTEXT if type is TYPE_FILE_SCOPE_P
       this is necessary to make it possible to merge types form different TUs
     - arrays, pointers and references may have TREE_TYPE that is a variant
       of TREE_TYPE of their main variants.
     - aggregates may have new TYPE_FIELDS list that list variants of
       the main variant TYPE_FIELDS.
     - vector types may differ by TYPE_VECTOR_OPAQUE
   */

  /* Convenience macro for matching individual fields.  */
#define verify_variant_match(flag)					    \
  do {									    \
    if (flag (tv) != flag (t))						    \
      {									    \
	error ("type variant differs by %s", #flag);			    \
	debug_tree (tv);						    \
	return false;							    \
      }									    \
  } while (false)

  /* tree_base checks.  */

  verify_variant_match (TREE_CODE);
  /* FIXME: Ada builds non-artificial variants of artificial types.  */
  if (TYPE_ARTIFICIAL (tv) && 0)
    verify_variant_match (TYPE_ARTIFICIAL);
  if (POINTER_TYPE_P (tv))
    verify_variant_match (TYPE_REF_CAN_ALIAS_ALL);
  /* FIXME: TYPE_SIZES_GIMPLIFIED may differs for Ada build.  */
  verify_variant_match (TYPE_UNSIGNED);
  verify_variant_match (TYPE_PACKED);
  if (TREE_CODE (t) == REFERENCE_TYPE)
    verify_variant_match (TYPE_REF_IS_RVALUE);
  if (AGGREGATE_TYPE_P (t))
    verify_variant_match (TYPE_REVERSE_STORAGE_ORDER);
  else
    verify_variant_match (TYPE_SATURATING);
  /* FIXME: This check trigger during libstdc++ build.  */
  if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t) && 0)
    verify_variant_match (TYPE_FINAL_P);

  /* tree_type_common checks.  */

  if (COMPLETE_TYPE_P (t))
    {
      verify_variant_match (TYPE_MODE);
      if (TREE_CODE (TYPE_SIZE (t)) != PLACEHOLDER_EXPR
	  && TREE_CODE (TYPE_SIZE (tv)) != PLACEHOLDER_EXPR)
	verify_variant_match (TYPE_SIZE);
      if (TREE_CODE (TYPE_SIZE_UNIT (t)) != PLACEHOLDER_EXPR
	  && TREE_CODE (TYPE_SIZE_UNIT (tv)) != PLACEHOLDER_EXPR
	  && TYPE_SIZE_UNIT (t) != TYPE_SIZE_UNIT (tv))
	{
	  gcc_assert (!operand_equal_p (TYPE_SIZE_UNIT (t),
					TYPE_SIZE_UNIT (tv), 0));
	  error ("type variant has different TYPE_SIZE_UNIT");
	  debug_tree (tv);
	  error ("type variant's TYPE_SIZE_UNIT");
	  debug_tree (TYPE_SIZE_UNIT (tv));
	  error ("type's TYPE_SIZE_UNIT");
	  debug_tree (TYPE_SIZE_UNIT (t));
	  return false;
	}
    }
  verify_variant_match (TYPE_PRECISION);
  verify_variant_match (TYPE_NEEDS_CONSTRUCTING);
  if (RECORD_OR_UNION_TYPE_P (t))
    verify_variant_match (TYPE_TRANSPARENT_AGGR);
  else if (TREE_CODE (t) == ARRAY_TYPE)
    verify_variant_match (TYPE_NONALIASED_COMPONENT);
  /* During LTO we merge variant lists from diferent translation units
     that may differ BY TYPE_CONTEXT that in turn may point 
     to TRANSLATION_UNIT_DECL.
     Ada also builds variants of types with different TYPE_CONTEXT.   */
  if ((!in_lto_p || !TYPE_FILE_SCOPE_P (t)) && 0)
    verify_variant_match (TYPE_CONTEXT);
  verify_variant_match (TYPE_STRING_FLAG);
  if (TYPE_ALIAS_SET_KNOWN_P (t))
    {
      error ("type variant with TYPE_ALIAS_SET_KNOWN_P");
      debug_tree (tv);
      return false;
    }

  /* tree_type_non_common checks.  */

  /* FIXME: C FE uses TYPE_VFIELD to record C_TYPE_INCOMPLETE_VARS
     and dangle the pointer from time to time.  */
  if (RECORD_OR_UNION_TYPE_P (t) && TYPE_VFIELD (t) != TYPE_VFIELD (tv)
      && (in_lto_p || !TYPE_VFIELD (tv)
	  || TREE_CODE (TYPE_VFIELD (tv)) != TREE_LIST))
    {
      error ("type variant has different TYPE_VFIELD");
      debug_tree (tv);
      return false;
    }
  if ((TREE_CODE (t) == ENUMERAL_TYPE && COMPLETE_TYPE_P (t))
       || TREE_CODE (t) == INTEGER_TYPE
       || TREE_CODE (t) == BOOLEAN_TYPE
       || TREE_CODE (t) == REAL_TYPE
       || TREE_CODE (t) == FIXED_POINT_TYPE)
    {
      verify_variant_match (TYPE_MAX_VALUE);
      verify_variant_match (TYPE_MIN_VALUE);
    }
  if (TREE_CODE (t) == METHOD_TYPE)
    verify_variant_match (TYPE_METHOD_BASETYPE);
  if (TREE_CODE (t) == OFFSET_TYPE)
    verify_variant_match (TYPE_OFFSET_BASETYPE);
  if (TREE_CODE (t) == ARRAY_TYPE)
    verify_variant_match (TYPE_ARRAY_MAX_SIZE);
  /* FIXME: Be lax and allow TYPE_BINFO to be missing in variant types
     or even type's main variant.  This is needed to make bootstrap pass
     and the bug seems new in GCC 5.
     C++ FE should be updated to make this consistent and we should check
     that TYPE_BINFO is always NULL for !COMPLETE_TYPE_P and otherwise there
     is a match with main variant.

     Also disable the check for Java for now because of parser hack that builds
     first an dummy BINFO and then sometimes replace it by real BINFO in some
     of the copies.  */
  if (RECORD_OR_UNION_TYPE_P (t) && TYPE_BINFO (t) && TYPE_BINFO (tv)
      && TYPE_BINFO (t) != TYPE_BINFO (tv)
      /* FIXME: Java sometimes keep dump TYPE_BINFOs on variant types.
	 Since there is no cheap way to tell C++/Java type w/o LTO, do checking
	 at LTO time only.  */
      && (in_lto_p && odr_type_p (t)))
    {
      error ("type variant has different TYPE_BINFO");
      debug_tree (tv);
      error ("type variant's TYPE_BINFO");
      debug_tree (TYPE_BINFO (tv));
      error ("type's TYPE_BINFO");
      debug_tree (TYPE_BINFO (t));
      return false;
    }

  /* Check various uses of TYPE_VALUES_RAW.  */
  if (TREE_CODE (t) == ENUMERAL_TYPE
      && TYPE_VALUES (t))
    verify_variant_match (TYPE_VALUES);
  else if (TREE_CODE (t) == ARRAY_TYPE)
    verify_variant_match (TYPE_DOMAIN);
  /* Permit incomplete variants of complete type.  While FEs may complete
     all variants, this does not happen for C++ templates in all cases.  */
  else if (RECORD_OR_UNION_TYPE_P (t)
	   && COMPLETE_TYPE_P (t)
	   && TYPE_FIELDS (t) != TYPE_FIELDS (tv))
    {
      tree f1, f2;

      /* Fortran builds qualified variants as new records with items of
	 qualified type. Verify that they looks same.  */
      for (f1 = TYPE_FIELDS (t), f2 = TYPE_FIELDS (tv);
	   f1 && f2;
	   f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
	if (TREE_CODE (f1) != FIELD_DECL || TREE_CODE (f2) != FIELD_DECL
	    || (TYPE_MAIN_VARIANT (TREE_TYPE (f1))
		 != TYPE_MAIN_VARIANT (TREE_TYPE (f2))
		/* FIXME: gfc_nonrestricted_type builds all types as variants
		   with exception of pointer types.  It deeply copies the type
		   which means that we may end up with a variant type
		   referring non-variant pointer.  We may change it to
		   produce types as variants, too, like
		   objc_get_protocol_qualified_type does.  */
		&& !POINTER_TYPE_P (TREE_TYPE (f1)))
	    || DECL_FIELD_OFFSET (f1) != DECL_FIELD_OFFSET (f2)
	    || DECL_FIELD_BIT_OFFSET (f1) != DECL_FIELD_BIT_OFFSET (f2))
	  break;
      if (f1 || f2)
	{
	  error ("type variant has different TYPE_FIELDS");
	  debug_tree (tv);
	  error ("first mismatch is field");
	  debug_tree (f1);
	  error ("and field");
	  debug_tree (f2);
          return false;
	}
    }
  else if ((TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE))
    verify_variant_match (TYPE_ARG_TYPES);
  /* For C++ the qualified variant of array type is really an array type
     of qualified TREE_TYPE.
     objc builds variants of pointer where pointer to type is a variant, too
     in objc_get_protocol_qualified_type.  */
  if (TREE_TYPE (t) != TREE_TYPE (tv)
      && ((TREE_CODE (t) != ARRAY_TYPE
	   && !POINTER_TYPE_P (t))
	  || TYPE_MAIN_VARIANT (TREE_TYPE (t))
	     != TYPE_MAIN_VARIANT (TREE_TYPE (tv))))
    {
      error ("type variant has different TREE_TYPE");
      debug_tree (tv);
      error ("type variant's TREE_TYPE");
      debug_tree (TREE_TYPE (tv));
      error ("type's TREE_TYPE");
      debug_tree (TREE_TYPE (t));
      return false;
    }
  if (type_with_alias_set_p (t)
      && !gimple_canonical_types_compatible_p (t, tv, false))
    {
      error ("type is not compatible with its variant");
      debug_tree (tv);
      error ("type variant's TREE_TYPE");
      debug_tree (TREE_TYPE (tv));
      error ("type's TREE_TYPE");
      debug_tree (TREE_TYPE (t));
      return false;
    }
  return true;
#undef verify_variant_match
}


/* The TYPE_CANONICAL merging machinery.  It should closely resemble
   the middle-end types_compatible_p function.  It needs to avoid
   claiming types are different for types that should be treated
   the same with respect to TBAA.  Canonical types are also used
   for IL consistency checks via the useless_type_conversion_p
   predicate which does not handle all type kinds itself but falls
   back to pointer-comparison of TYPE_CANONICAL for aggregates
   for example.  */

/* Return true if TYPE_UNSIGNED of TYPE should be ignored for canonical
   type calculation because we need to allow inter-operability between signed
   and unsigned variants.  */

bool
type_with_interoperable_signedness (const_tree type)
{
  /* Fortran standard require C_SIGNED_CHAR to be interoperable with both
     signed char and unsigned char.  Similarly fortran FE builds
     C_SIZE_T as signed type, while C defines it unsigned.  */

  return tree_code_for_canonical_type_merging (TREE_CODE (type))
	   == INTEGER_TYPE
         && (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)
	     || TYPE_PRECISION (type) == TYPE_PRECISION (size_type_node));
}

/* Return true iff T1 and T2 are structurally identical for what
   TBAA is concerned.  
   This function is used both by lto.c canonical type merging and by the
   verifier.  If TRUST_TYPE_CANONICAL we do not look into structure of types
   that have TYPE_CANONICAL defined and assume them equivalent.  This is useful
   only for LTO because only in these cases TYPE_CANONICAL equivalence
   correspond to one defined by gimple_canonical_types_compatible_p.  */

bool
gimple_canonical_types_compatible_p (const_tree t1, const_tree t2,
				     bool trust_type_canonical)
{
  /* Type variants should be same as the main variant.  When not doing sanity
     checking to verify this fact, go to main variants and save some work.  */
  if (trust_type_canonical)
    {
      t1 = TYPE_MAIN_VARIANT (t1);
      t2 = TYPE_MAIN_VARIANT (t2);
    }

  /* Check first for the obvious case of pointer identity.  */
  if (t1 == t2)
    return true;

  /* Check that we have two types to compare.  */
  if (t1 == NULL_TREE || t2 == NULL_TREE)
    return false;

  /* We consider complete types always compatible with incomplete type.
     This does not make sense for canonical type calculation and thus we
     need to ensure that we are never called on it.

     FIXME: For more correctness the function probably should have three modes
	1) mode assuming that types are complete mathcing their structure
	2) mode allowing incomplete types but producing equivalence classes
	   and thus ignoring all info from complete types
	3) mode allowing incomplete types to match complete but checking
	   compatibility between complete types.

     1 and 2 can be used for canonical type calculation. 3 is the real
     definition of type compatibility that can be used i.e. for warnings during
     declaration merging.  */

  gcc_assert (!trust_type_canonical
	      || (type_with_alias_set_p (t1) && type_with_alias_set_p (t2)));
  /* If the types have been previously registered and found equal
     they still are.  */

  if (TYPE_CANONICAL (t1) && TYPE_CANONICAL (t2)
      && trust_type_canonical)
    {
      /* Do not use TYPE_CANONICAL of pointer types.  For LTO streamed types
	 they are always NULL, but they are set to non-NULL for types
	 constructed by build_pointer_type and variants.  In this case the
	 TYPE_CANONICAL is more fine grained than the equivalnce we test (where
	 all pointers are considered equal.  Be sure to not return false
	 negatives.  */
      gcc_checking_assert (canonical_type_used_p (t1)
			   && canonical_type_used_p (t2));
      return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
    }

  /* Can't be the same type if the types don't have the same code.  */
  enum tree_code code = tree_code_for_canonical_type_merging (TREE_CODE (t1));
  if (code != tree_code_for_canonical_type_merging (TREE_CODE (t2)))
    return false;

  /* Qualifiers do not matter for canonical type comparison purposes.  */

  /* Void types and nullptr types are always the same.  */
  if (TREE_CODE (t1) == VOID_TYPE
      || TREE_CODE (t1) == NULLPTR_TYPE)
    return true;

  /* Can't be the same type if they have different mode.  */
  if (TYPE_MODE (t1) != TYPE_MODE (t2))
    return false;

  /* Non-aggregate types can be handled cheaply.  */
  if (INTEGRAL_TYPE_P (t1)
      || SCALAR_FLOAT_TYPE_P (t1)
      || FIXED_POINT_TYPE_P (t1)
      || TREE_CODE (t1) == VECTOR_TYPE
      || TREE_CODE (t1) == COMPLEX_TYPE
      || TREE_CODE (t1) == OFFSET_TYPE
      || POINTER_TYPE_P (t1))
    {
      /* Can't be the same type if they have different recision.  */
      if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2))
	return false;

      /* In some cases the signed and unsigned types are required to be
	 inter-operable.  */
      if (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)
	  && !type_with_interoperable_signedness (t1))
	return false;

      /* Fortran's C_SIGNED_CHAR is !TYPE_STRING_FLAG but needs to be
	 interoperable with "signed char".  Unless all frontends are revisited
	 to agree on these types, we must ignore the flag completely.  */

      /* Fortran standard define C_PTR type that is compatible with every
 	 C pointer.  For this reason we need to glob all pointers into one.
	 Still pointers in different address spaces are not compatible.  */
      if (POINTER_TYPE_P (t1))
	{
	  if (TYPE_ADDR_SPACE (TREE_TYPE (t1))
	      != TYPE_ADDR_SPACE (TREE_TYPE (t2)))
	    return false;
	}

      /* Tail-recurse to components.  */
      if (TREE_CODE (t1) == VECTOR_TYPE
	  || TREE_CODE (t1) == COMPLEX_TYPE)
	return gimple_canonical_types_compatible_p (TREE_TYPE (t1),
						    TREE_TYPE (t2),
						    trust_type_canonical);

      return true;
    }

  /* Do type-specific comparisons.  */
  switch (TREE_CODE (t1))
    {
    case ARRAY_TYPE:
      /* Array types are the same if the element types are the same and
	 the number of elements are the same.  */
      if (!gimple_canonical_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
						trust_type_canonical)
	  || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)
	  || TYPE_REVERSE_STORAGE_ORDER (t1) != TYPE_REVERSE_STORAGE_ORDER (t2)
	  || TYPE_NONALIASED_COMPONENT (t1) != TYPE_NONALIASED_COMPONENT (t2))
	return false;
      else
	{
	  tree i1 = TYPE_DOMAIN (t1);
	  tree i2 = TYPE_DOMAIN (t2);

	  /* For an incomplete external array, the type domain can be
 	     NULL_TREE.  Check this condition also.  */
	  if (i1 == NULL_TREE && i2 == NULL_TREE)
	    return true;
	  else if (i1 == NULL_TREE || i2 == NULL_TREE)
	    return false;
	  else
	    {
	      tree min1 = TYPE_MIN_VALUE (i1);
	      tree min2 = TYPE_MIN_VALUE (i2);
	      tree max1 = TYPE_MAX_VALUE (i1);
	      tree max2 = TYPE_MAX_VALUE (i2);

	      /* The minimum/maximum values have to be the same.  */
	      if ((min1 == min2
		   || (min1 && min2
		       && ((TREE_CODE (min1) == PLACEHOLDER_EXPR
			    && TREE_CODE (min2) == PLACEHOLDER_EXPR)
		           || operand_equal_p (min1, min2, 0))))
		  && (max1 == max2
		      || (max1 && max2
			  && ((TREE_CODE (max1) == PLACEHOLDER_EXPR
			       && TREE_CODE (max2) == PLACEHOLDER_EXPR)
			      || operand_equal_p (max1, max2, 0)))))
		return true;
	      else
		return false;
	    }
	}

    case METHOD_TYPE:
    case FUNCTION_TYPE:
      /* Function types are the same if the return type and arguments types
	 are the same.  */
      if (!gimple_canonical_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2),
						trust_type_canonical))
	return false;

      if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2))
	return true;
      else
	{
	  tree parms1, parms2;

	  for (parms1 = TYPE_ARG_TYPES (t1), parms2 = TYPE_ARG_TYPES (t2);
	       parms1 && parms2;
	       parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
	    {
	      if (!gimple_canonical_types_compatible_p
		     (TREE_VALUE (parms1), TREE_VALUE (parms2),
		      trust_type_canonical))
		return false;
	    }

	  if (parms1 || parms2)
	    return false;

	  return true;
	}

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      {
	tree f1, f2;

	/* Don't try to compare variants of an incomplete type, before
	   TYPE_FIELDS has been copied around.  */
	if (!COMPLETE_TYPE_P (t1) && !COMPLETE_TYPE_P (t2))
	  return true;


	if (TYPE_REVERSE_STORAGE_ORDER (t1) != TYPE_REVERSE_STORAGE_ORDER (t2))
	  return false;

	/* For aggregate types, all the fields must be the same.  */
	for (f1 = TYPE_FIELDS (t1), f2 = TYPE_FIELDS (t2);
	     f1 || f2;
	     f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
	  {
	    /* Skip non-fields and zero-sized fields.  */
	    while (f1 && (TREE_CODE (f1) != FIELD_DECL
			  || (DECL_SIZE (f1)
			      && integer_zerop (DECL_SIZE (f1)))))
	      f1 = TREE_CHAIN (f1);
	    while (f2 && (TREE_CODE (f2) != FIELD_DECL
			  || (DECL_SIZE (f2)
			      && integer_zerop (DECL_SIZE (f2)))))
	      f2 = TREE_CHAIN (f2);
	    if (!f1 || !f2)
	      break;
	    /* The fields must have the same name, offset and type.  */
	    if (DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2)
		|| !gimple_compare_field_offset (f1, f2)
		|| !gimple_canonical_types_compatible_p
		      (TREE_TYPE (f1), TREE_TYPE (f2),
		       trust_type_canonical))
	      return false;
	  }

	/* If one aggregate has more fields than the other, they
	   are not the same.  */
	if (f1 || f2)
	  return false;

	return true;
      }

    default:
      /* Consider all types with language specific trees in them mutually
	 compatible.  This is executed only from verify_type and false
         positives can be tolerated.  */
      gcc_assert (!in_lto_p);
      return true;
    }
}

/* Verify type T.  */

void
verify_type (const_tree t)
{
  bool error_found = false;
  tree mv = TYPE_MAIN_VARIANT (t);
  if (!mv)
    {
      error ("Main variant is not defined");
      error_found = true;
    }
  else if (mv != TYPE_MAIN_VARIANT (mv))
    {
      error ("TYPE_MAIN_VARIANT has different TYPE_MAIN_VARIANT");
      debug_tree (mv);
      error_found = true;
    }
  else if (t != mv && !verify_type_variant (t, mv))
    error_found = true;

  tree ct = TYPE_CANONICAL (t);
  if (!ct)
    ;
  else if (TYPE_CANONICAL (t) != ct)
    {
      error ("TYPE_CANONICAL has different TYPE_CANONICAL");
      debug_tree (ct);
      error_found = true;
    }
  /* Method and function types can not be used to address memory and thus
     TYPE_CANONICAL really matters only for determining useless conversions.

     FIXME: C++ FE produce declarations of builtin functions that are not
     compatible with main variants.  */
  else if (TREE_CODE (t) == FUNCTION_TYPE)
    ;
  else if (t != ct
	   /* FIXME: gimple_canonical_types_compatible_p can not compare types
	      with variably sized arrays because their sizes possibly
	      gimplified to different variables.  */
	   && !variably_modified_type_p (ct, NULL)
	   && !gimple_canonical_types_compatible_p (t, ct, false)
	   && COMPLETE_TYPE_P (t))
    {
      error ("TYPE_CANONICAL is not compatible");
      debug_tree (ct);
      error_found = true;
    }

  if (COMPLETE_TYPE_P (t) && TYPE_CANONICAL (t)
      && TYPE_MODE (t) != TYPE_MODE (TYPE_CANONICAL (t)))
    {
      error ("TYPE_MODE of TYPE_CANONICAL is not compatible");
      debug_tree (ct);
      error_found = true;
    }
  if (TYPE_MAIN_VARIANT (t) == t && ct && TYPE_MAIN_VARIANT (ct) != ct)
   {
      error ("TYPE_CANONICAL of main variant is not main variant");
      debug_tree (ct);
      debug_tree (TYPE_MAIN_VARIANT (ct));
      error_found = true;
   }


  /* Check various uses of TYPE_MIN_VALUE_RAW.  */
  if (RECORD_OR_UNION_TYPE_P (t))
    {
      /* FIXME: C FE uses TYPE_VFIELD to record C_TYPE_INCOMPLETE_VARS
	 and danagle the pointer from time to time.  */
      if (TYPE_VFIELD (t)
	  && TREE_CODE (TYPE_VFIELD (t)) != FIELD_DECL
	  && TREE_CODE (TYPE_VFIELD (t)) != TREE_LIST)
	{
	  error ("TYPE_VFIELD is not FIELD_DECL nor TREE_LIST");
	  debug_tree (TYPE_VFIELD (t));
	  error_found = true;
	}
    }
  else if (TREE_CODE (t) == POINTER_TYPE)
    {
      if (TYPE_NEXT_PTR_TO (t)
	  && TREE_CODE (TYPE_NEXT_PTR_TO (t)) != POINTER_TYPE)
	{
	  error ("TYPE_NEXT_PTR_TO is not POINTER_TYPE");
	  debug_tree (TYPE_NEXT_PTR_TO (t));
	  error_found = true;
	}
    }
  else if (TREE_CODE (t) == REFERENCE_TYPE)
    {
      if (TYPE_NEXT_REF_TO (t)
	  && TREE_CODE (TYPE_NEXT_REF_TO (t)) != REFERENCE_TYPE)
	{
	  error ("TYPE_NEXT_REF_TO is not REFERENCE_TYPE");
	  debug_tree (TYPE_NEXT_REF_TO (t));
	  error_found = true;
	}
    }
  else if (INTEGRAL_TYPE_P (t) || TREE_CODE (t) == REAL_TYPE
	   || TREE_CODE (t) == FIXED_POINT_TYPE)
    {
      /* FIXME: The following check should pass:
	  useless_type_conversion_p (const_cast <tree> (t),
				     TREE_TYPE (TYPE_MIN_VALUE (t))
	 but does not for C sizetypes in LTO.  */
    }

  /* Check various uses of TYPE_MAXVAL_RAW.  */
  if (RECORD_OR_UNION_TYPE_P (t))
    {
      if (!TYPE_BINFO (t))
	;
      else if (TREE_CODE (TYPE_BINFO (t)) != TREE_BINFO)
	{
	  error ("TYPE_BINFO is not TREE_BINFO");
	  debug_tree (TYPE_BINFO (t));
	  error_found = true;
	}
      else if (TREE_TYPE (TYPE_BINFO (t)) != TYPE_MAIN_VARIANT (t))
	{
	  error ("TYPE_BINFO type is not TYPE_MAIN_VARIANT");
	  debug_tree (TREE_TYPE (TYPE_BINFO (t)));
	  error_found = true;
	}
    }
  else if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE)
    {
      if (TYPE_METHOD_BASETYPE (t)
	  && TREE_CODE (TYPE_METHOD_BASETYPE (t)) != RECORD_TYPE
	  && TREE_CODE (TYPE_METHOD_BASETYPE (t)) != UNION_TYPE)
	{
	  error ("TYPE_METHOD_BASETYPE is not record nor union");
	  debug_tree (TYPE_METHOD_BASETYPE (t));
	  error_found = true;
	}
    }
  else if (TREE_CODE (t) == OFFSET_TYPE)
    {
      if (TYPE_OFFSET_BASETYPE (t)
	  && TREE_CODE (TYPE_OFFSET_BASETYPE (t)) != RECORD_TYPE
	  && TREE_CODE (TYPE_OFFSET_BASETYPE (t)) != UNION_TYPE)
	{
	  error ("TYPE_OFFSET_BASETYPE is not record nor union");
	  debug_tree (TYPE_OFFSET_BASETYPE (t));
	  error_found = true;
	}
    }
  else if (INTEGRAL_TYPE_P (t) || TREE_CODE (t) == REAL_TYPE
	   || TREE_CODE (t) == FIXED_POINT_TYPE)
    {
      /* FIXME: The following check should pass:
	  useless_type_conversion_p (const_cast <tree> (t),
				     TREE_TYPE (TYPE_MAX_VALUE (t))
	 but does not for C sizetypes in LTO.  */
    }
  else if (TREE_CODE (t) == ARRAY_TYPE)
    {
      if (TYPE_ARRAY_MAX_SIZE (t)
	  && TREE_CODE (TYPE_ARRAY_MAX_SIZE (t)) != INTEGER_CST)
        {
	  error ("TYPE_ARRAY_MAX_SIZE not INTEGER_CST");
	  debug_tree (TYPE_ARRAY_MAX_SIZE (t));
	  error_found = true;
        } 
    }
  else if (TYPE_MAX_VALUE_RAW (t))
    {
      error ("TYPE_MAX_VALUE_RAW non-NULL");
      debug_tree (TYPE_MAX_VALUE_RAW (t));
      error_found = true;
    }

  if (TYPE_LANG_SLOT_1 (t) && in_lto_p)
    {
      error ("TYPE_LANG_SLOT_1 (binfo) field is non-NULL");
      debug_tree (TYPE_LANG_SLOT_1 (t));
      error_found = true;
    }

  /* Check various uses of TYPE_VALUES_RAW.  */
  if (TREE_CODE (t) == ENUMERAL_TYPE)
    for (tree l = TYPE_VALUES (t); l; l = TREE_CHAIN (l))
      {
	tree value = TREE_VALUE (l);
	tree name = TREE_PURPOSE (l);

	/* C FE porduce INTEGER_CST of INTEGER_TYPE, while C++ FE uses
 	   CONST_DECL of ENUMERAL TYPE.  */
	if (TREE_CODE (value) != INTEGER_CST && TREE_CODE (value) != CONST_DECL)
	  {
	    error ("Enum value is not CONST_DECL or INTEGER_CST");
	    debug_tree (value);
	    debug_tree (name);
	    error_found = true;
	  }
	if (TREE_CODE (TREE_TYPE (value)) != INTEGER_TYPE
	    && !useless_type_conversion_p (const_cast <tree> (t), TREE_TYPE (value)))
	  {
	    error ("Enum value type is not INTEGER_TYPE nor convertible to the enum");
	    debug_tree (value);
	    debug_tree (name);
	    error_found = true;
	  }
	if (TREE_CODE (name) != IDENTIFIER_NODE)
	  {
	    error ("Enum value name is not IDENTIFIER_NODE");
	    debug_tree (value);
	    debug_tree (name);
	    error_found = true;
	  }
      }
  else if (TREE_CODE (t) == ARRAY_TYPE)
    {
      if (TYPE_DOMAIN (t) && TREE_CODE (TYPE_DOMAIN (t)) != INTEGER_TYPE)
	{
	  error ("Array TYPE_DOMAIN is not integer type");
	  debug_tree (TYPE_DOMAIN (t));
	  error_found = true;
	}
    }
  else if (RECORD_OR_UNION_TYPE_P (t))
    {
      if (TYPE_FIELDS (t) && !COMPLETE_TYPE_P (t) && in_lto_p)
	{
	  error ("TYPE_FIELDS defined in incomplete type");
	  error_found = true;
	}
      for (tree fld = TYPE_FIELDS (t); fld; fld = TREE_CHAIN (fld))
	{
	  /* TODO: verify properties of decls.  */
	  if (TREE_CODE (fld) == FIELD_DECL)
	    ;
	  else if (TREE_CODE (fld) == TYPE_DECL)
	    ;
	  else if (TREE_CODE (fld) == CONST_DECL)
	    ;
	  else if (VAR_P (fld))
	    ;
	  else if (TREE_CODE (fld) == TEMPLATE_DECL)
	    ;
	  else if (TREE_CODE (fld) == USING_DECL)
	    ;
	  else if (TREE_CODE (fld) == FUNCTION_DECL)
	    ;
	  else
	    {
	      error ("Wrong tree in TYPE_FIELDS list");
	      debug_tree (fld);
	      error_found = true;
	    }
	}
    }
  else if (TREE_CODE (t) == INTEGER_TYPE
	   || TREE_CODE (t) == BOOLEAN_TYPE
	   || TREE_CODE (t) == OFFSET_TYPE
	   || TREE_CODE (t) == REFERENCE_TYPE
	   || TREE_CODE (t) == NULLPTR_TYPE
	   || TREE_CODE (t) == POINTER_TYPE)
    {
      if (TYPE_CACHED_VALUES_P (t) != (TYPE_CACHED_VALUES (t) != NULL))
	{
	  error ("TYPE_CACHED_VALUES_P is %i while TYPE_CACHED_VALUES is %p",
		 TYPE_CACHED_VALUES_P (t), (void *)TYPE_CACHED_VALUES (t));
	  error_found = true;
	}
      else if (TYPE_CACHED_VALUES_P (t) && TREE_CODE (TYPE_CACHED_VALUES (t)) != TREE_VEC)
	{
	  error ("TYPE_CACHED_VALUES is not TREE_VEC");
	  debug_tree (TYPE_CACHED_VALUES (t));
	  error_found = true;
	}
      /* Verify just enough of cache to ensure that no one copied it to new type.
 	 All copying should go by copy_node that should clear it.  */
      else if (TYPE_CACHED_VALUES_P (t))
	{
	  int i;
	  for (i = 0; i < TREE_VEC_LENGTH (TYPE_CACHED_VALUES (t)); i++)
	    if (TREE_VEC_ELT (TYPE_CACHED_VALUES (t), i)
		&& TREE_TYPE (TREE_VEC_ELT (TYPE_CACHED_VALUES (t), i)) != t)
	      {
		error ("wrong TYPE_CACHED_VALUES entry");
		debug_tree (TREE_VEC_ELT (TYPE_CACHED_VALUES (t), i));
		error_found = true;
		break;
	      }
	}
    }
  else if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE)
    for (tree l = TYPE_ARG_TYPES (t); l; l = TREE_CHAIN (l))
      {
	/* C++ FE uses TREE_PURPOSE to store initial values.  */
	if (TREE_PURPOSE (l) && in_lto_p)
	  {
	    error ("TREE_PURPOSE is non-NULL in TYPE_ARG_TYPES list");
	    debug_tree (l);
	    error_found = true;
	  }
	if (!TYPE_P (TREE_VALUE (l)))
	  {
	    error ("Wrong entry in TYPE_ARG_TYPES list");
	    debug_tree (l);
	    error_found = true;
	  }
      }
  else if (!is_lang_specific (t) && TYPE_VALUES_RAW (t))
    {
      error ("TYPE_VALUES_RAW field is non-NULL");
      debug_tree (TYPE_VALUES_RAW (t));
      error_found = true;
    }
  if (TREE_CODE (t) != INTEGER_TYPE
      && TREE_CODE (t) != BOOLEAN_TYPE
      && TREE_CODE (t) != OFFSET_TYPE
      && TREE_CODE (t) != REFERENCE_TYPE
      && TREE_CODE (t) != NULLPTR_TYPE
      && TREE_CODE (t) != POINTER_TYPE
      && TYPE_CACHED_VALUES_P (t))
    {
      error ("TYPE_CACHED_VALUES_P is set while it should not");
      error_found = true;
    }
  if (TYPE_STRING_FLAG (t)
      && TREE_CODE (t) != ARRAY_TYPE && TREE_CODE (t) != INTEGER_TYPE)
    {
      error ("TYPE_STRING_FLAG is set on wrong type code");
      error_found = true;
    }
  
  /* ipa-devirt makes an assumption that TYPE_METHOD_BASETYPE is always
     TYPE_MAIN_VARIANT and it would be odd to add methods only to variatns
     of a type. */
  if (TREE_CODE (t) == METHOD_TYPE
      && TYPE_MAIN_VARIANT (TYPE_METHOD_BASETYPE (t)) != TYPE_METHOD_BASETYPE (t))
    {
	error ("TYPE_METHOD_BASETYPE is not main variant");
	error_found = true;
    }

  if (error_found)
    {
      debug_tree (const_cast <tree> (t));
      internal_error ("verify_type failed");
    }
}


/* Return 1 if ARG interpreted as signed in its precision is known to be
   always positive or 2 if ARG is known to be always negative, or 3 if
   ARG may be positive or negative.  */

int
get_range_pos_neg (tree arg)
{
  if (arg == error_mark_node)
    return 3;

  int prec = TYPE_PRECISION (TREE_TYPE (arg));
  int cnt = 0;
  if (TREE_CODE (arg) == INTEGER_CST)
    {
      wide_int w = wi::sext (wi::to_wide (arg), prec);
      if (wi::neg_p (w))
	return 2;
      else
	return 1;
    }
  while (CONVERT_EXPR_P (arg)
	 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
	 && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) <= prec)
    {
      arg = TREE_OPERAND (arg, 0);
      /* Narrower value zero extended into wider type
	 will always result in positive values.  */
      if (TYPE_UNSIGNED (TREE_TYPE (arg))
	  && TYPE_PRECISION (TREE_TYPE (arg)) < prec)
	return 1;
      prec = TYPE_PRECISION (TREE_TYPE (arg));
      if (++cnt > 30)
	return 3;
    }

  if (TREE_CODE (arg) != SSA_NAME)
    return 3;
  wide_int arg_min, arg_max;
  while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
    {
      gimple *g = SSA_NAME_DEF_STMT (arg);
      if (is_gimple_assign (g)
	  && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (g)))
	{
	  tree t = gimple_assign_rhs1 (g);
	  if (INTEGRAL_TYPE_P (TREE_TYPE (t))
	      && TYPE_PRECISION (TREE_TYPE (t)) <= prec)
	    {
	      if (TYPE_UNSIGNED (TREE_TYPE (t))
		  && TYPE_PRECISION (TREE_TYPE (t)) < prec)
		return 1;
	      prec = TYPE_PRECISION (TREE_TYPE (t));
	      arg = t;
	      if (++cnt > 30)
		return 3;
	      continue;
	    }
	}
      return 3;
    }
  if (TYPE_UNSIGNED (TREE_TYPE (arg)))
    {
      /* For unsigned values, the "positive" range comes
	 below the "negative" range.  */
      if (!wi::neg_p (wi::sext (arg_max, prec), SIGNED))
	return 1;
      if (wi::neg_p (wi::sext (arg_min, prec), SIGNED))
	return 2;
    }
  else
    {
      if (!wi::neg_p (wi::sext (arg_min, prec), SIGNED))
	return 1;
      if (wi::neg_p (wi::sext (arg_max, prec), SIGNED))
	return 2;
    }
  return 3;
}




/* Return true if ARG is marked with the nonnull attribute in the
   current function signature.  */

bool
nonnull_arg_p (const_tree arg)
{
  tree t, attrs, fntype;
  unsigned HOST_WIDE_INT arg_num;

  gcc_assert (TREE_CODE (arg) == PARM_DECL
	      && (POINTER_TYPE_P (TREE_TYPE (arg))
		  || TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE));

  /* The static chain decl is always non null.  */
  if (arg == cfun->static_chain_decl)
    return true;

  /* THIS argument of method is always non-NULL.  */
  if (TREE_CODE (TREE_TYPE (cfun->decl)) == METHOD_TYPE
      && arg == DECL_ARGUMENTS (cfun->decl)
      && flag_delete_null_pointer_checks)
    return true;

  /* Values passed by reference are always non-NULL.  */
  if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE
      && flag_delete_null_pointer_checks)
    return true;

  fntype = TREE_TYPE (cfun->decl);
  for (attrs = TYPE_ATTRIBUTES (fntype); attrs; attrs = TREE_CHAIN (attrs))
    {
      attrs = lookup_attribute ("nonnull", attrs);

      /* If "nonnull" wasn't specified, we know nothing about the argument.  */
      if (attrs == NULL_TREE)
	return false;

      /* If "nonnull" applies to all the arguments, then ARG is non-null.  */
      if (TREE_VALUE (attrs) == NULL_TREE)
	return true;

      /* Get the position number for ARG in the function signature.  */
      for (arg_num = 1, t = DECL_ARGUMENTS (cfun->decl);
	   t;
	   t = DECL_CHAIN (t), arg_num++)
	{
	  if (t == arg)
	    break;
	}

      gcc_assert (t == arg);

      /* Now see if ARG_NUM is mentioned in the nonnull list.  */
      for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
	{
	  if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
	    return true;
	}
    }

  return false;
}

/* Combine LOC and BLOCK to a combined adhoc loc, retaining any range
   information.  */

location_t
set_block (location_t loc, tree block)
{
  location_t pure_loc = get_pure_location (loc);
  source_range src_range = get_range_from_loc (line_table, loc);
  return COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, block);
}

location_t
set_source_range (tree expr, location_t start, location_t finish)
{
  source_range src_range;
  src_range.m_start = start;
  src_range.m_finish = finish;
  return set_source_range (expr, src_range);
}

location_t
set_source_range (tree expr, source_range src_range)
{
  if (!EXPR_P (expr))
    return UNKNOWN_LOCATION;

  location_t pure_loc = get_pure_location (EXPR_LOCATION (expr));
  location_t adhoc = COMBINE_LOCATION_DATA (line_table,
					    pure_loc,
					    src_range,
					    NULL);
  SET_EXPR_LOCATION (expr, adhoc);
  return adhoc;
}

/* Return EXPR, potentially wrapped with a node expression LOC,
   if !CAN_HAVE_LOCATION_P (expr).

   NON_LVALUE_EXPR is used for wrapping constants, apart from STRING_CST.
   VIEW_CONVERT_EXPR is used for wrapping non-constants and STRING_CST.

   Wrapper nodes can be identified using location_wrapper_p.  */

tree
maybe_wrap_with_location (tree expr, location_t loc)
{
  if (expr == NULL)
    return NULL;
  if (loc == UNKNOWN_LOCATION)
    return expr;
  if (CAN_HAVE_LOCATION_P (expr))
    return expr;
  /* We should only be adding wrappers for constants and for decls,
     or for some exceptional tree nodes (e.g. BASELINK in the C++ FE).  */
  gcc_assert (CONSTANT_CLASS_P (expr)
	      || DECL_P (expr)
	      || EXCEPTIONAL_CLASS_P (expr));

  /* For now, don't add wrappers to exceptional tree nodes, to minimize
     any impact of the wrapper nodes.  */
  if (EXCEPTIONAL_CLASS_P (expr))
    return expr;

  tree_code code
    = (((CONSTANT_CLASS_P (expr) && TREE_CODE (expr) != STRING_CST)
	|| (TREE_CODE (expr) == CONST_DECL && !TREE_STATIC (expr)))
       ? NON_LVALUE_EXPR : VIEW_CONVERT_EXPR);
  tree wrapper = build1_loc (loc, code, TREE_TYPE (expr), expr);
  /* Mark this node as being a wrapper.  */
  EXPR_LOCATION_WRAPPER_P (wrapper) = 1;
  return wrapper;
}

/* Return the name of combined function FN, for debugging purposes.  */

const char *
combined_fn_name (combined_fn fn)
{
  if (builtin_fn_p (fn))
    {
      tree fndecl = builtin_decl_explicit (as_builtin_fn (fn));
      return IDENTIFIER_POINTER (DECL_NAME (fndecl));
    }
  else
    return internal_fn_name (as_internal_fn (fn));
}

/* Return a bitmap with a bit set corresponding to each argument in
   a function call type FNTYPE declared with attribute nonnull,
   or null if none of the function's argument are nonnull.  The caller
   must free the bitmap.  */

bitmap
get_nonnull_args (const_tree fntype)
{
  if (fntype == NULL_TREE)
    return NULL;

  tree attrs = TYPE_ATTRIBUTES (fntype);
  if (!attrs)
    return NULL;

  bitmap argmap = NULL;

  /* A function declaration can specify multiple attribute nonnull,
     each with zero or more arguments.  The loop below creates a bitmap
     representing a union of all the arguments.  An empty (but non-null)
     bitmap means that all arguments have been declaraed nonnull.  */
  for ( ; attrs; attrs = TREE_CHAIN (attrs))
    {
      attrs = lookup_attribute ("nonnull", attrs);
      if (!attrs)
	break;

      if (!argmap)
	argmap = BITMAP_ALLOC (NULL);

      if (!TREE_VALUE (attrs))
	{
	  /* Clear the bitmap in case a previous attribute nonnull
	     set it and this one overrides it for all arguments.  */
	  bitmap_clear (argmap);
	  return argmap;
	}

      /* Iterate over the indices of the format arguments declared nonnull
	 and set a bit for each.  */
      for (tree idx = TREE_VALUE (attrs); idx; idx = TREE_CHAIN (idx))
	{
	  unsigned int val = TREE_INT_CST_LOW (TREE_VALUE (idx)) - 1;
	  bitmap_set_bit (argmap, val);
	}
    }

  return argmap;
}

/* Returns true if TYPE is a type where it and all of its subobjects
   (recursively) are of structure, union, or array type.  */

static bool
default_is_empty_type (tree type)
{
  if (RECORD_OR_UNION_TYPE_P (type))
    {
      for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	if (TREE_CODE (field) == FIELD_DECL
	    && !DECL_PADDING_P (field)
	    && !default_is_empty_type (TREE_TYPE (field)))
	  return false;
      return true;
    }
  else if (TREE_CODE (type) == ARRAY_TYPE)
    return (integer_minus_onep (array_type_nelts (type))
	    || TYPE_DOMAIN (type) == NULL_TREE
	    || default_is_empty_type (TREE_TYPE (type)));
  return false;
}

/* Implement TARGET_EMPTY_RECORD_P.  Return true if TYPE is an empty type
   that shouldn't be passed via stack.  */

bool
default_is_empty_record (const_tree type)
{
  if (!abi_version_at_least (12))
    return false;

  if (type == error_mark_node)
    return false;

  if (TREE_ADDRESSABLE (type))
    return false;

  return default_is_empty_type (TYPE_MAIN_VARIANT (type));
}

/* Like int_size_in_bytes, but handle empty records specially.  */

HOST_WIDE_INT
arg_int_size_in_bytes (const_tree type)
{
  return TYPE_EMPTY_P (type) ? 0 : int_size_in_bytes (type);
}

/* Like size_in_bytes, but handle empty records specially.  */

tree
arg_size_in_bytes (const_tree type)
{
  return TYPE_EMPTY_P (type) ? size_zero_node : size_in_bytes (type);
}

/* Return true if an expression with CODE has to have the same result type as
   its first operand.  */

bool
expr_type_first_operand_type_p (tree_code code)
{
  switch (code)
    {
    case NEGATE_EXPR:
    case ABS_EXPR:
    case BIT_NOT_EXPR:
    case PAREN_EXPR:
    case CONJ_EXPR:

    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case TRUNC_MOD_EXPR:
    case CEIL_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case RDIV_EXPR:
    case EXACT_DIV_EXPR:
    case MIN_EXPR:
    case MAX_EXPR:
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
    case BIT_AND_EXPR:

    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case LROTATE_EXPR:
    case RROTATE_EXPR:
      return true;

    default:
      return false;
    }
}

/* Return a typenode for the "standard" C type with a given name.  */
tree
get_typenode_from_name (const char *name)
{
  if (name == NULL || *name == '\0')
    return NULL_TREE;

  if (strcmp (name, "char") == 0)
    return char_type_node;
  if (strcmp (name, "unsigned char") == 0)
    return unsigned_char_type_node;
  if (strcmp (name, "signed char") == 0)
    return signed_char_type_node;

  if (strcmp (name, "short int") == 0)
    return short_integer_type_node;
  if (strcmp (name, "short unsigned int") == 0)
    return short_unsigned_type_node;

  if (strcmp (name, "int") == 0)
    return integer_type_node;
  if (strcmp (name, "unsigned int") == 0)
    return unsigned_type_node;

  if (strcmp (name, "long int") == 0)
    return long_integer_type_node;
  if (strcmp (name, "long unsigned int") == 0)
    return long_unsigned_type_node;

  if (strcmp (name, "long long int") == 0)
    return long_long_integer_type_node;
  if (strcmp (name, "long long unsigned int") == 0)
    return long_long_unsigned_type_node;

  gcc_unreachable ();
}

/* List of pointer types used to declare builtins before we have seen their
   real declaration.

   Keep the size up to date in tree.h !  */
const builtin_structptr_type builtin_structptr_types[6] = 
{
  { fileptr_type_node, ptr_type_node, "FILE" },
  { const_tm_ptr_type_node, const_ptr_type_node, "tm" },
  { fenv_t_ptr_type_node, ptr_type_node, "fenv_t" },
  { const_fenv_t_ptr_type_node, const_ptr_type_node, "fenv_t" },
  { fexcept_t_ptr_type_node, ptr_type_node, "fexcept_t" },
  { const_fexcept_t_ptr_type_node, const_ptr_type_node, "fexcept_t" }
};

#if CHECKING_P

namespace selftest {

/* Selftests for tree.  */

/* Verify that integer constants are sane.  */

static void
test_integer_constants ()
{
  ASSERT_TRUE (integer_type_node != NULL);
  ASSERT_TRUE (build_int_cst (integer_type_node, 0) != NULL);

  tree type = integer_type_node;

  tree zero = build_zero_cst (type);
  ASSERT_EQ (INTEGER_CST, TREE_CODE (zero));
  ASSERT_EQ (type, TREE_TYPE (zero));

  tree one = build_int_cst (type, 1);
  ASSERT_EQ (INTEGER_CST, TREE_CODE (one));
  ASSERT_EQ (type, TREE_TYPE (zero));
}

/* Verify identifiers.  */

static void
test_identifiers ()
{
  tree identifier = get_identifier ("foo");
  ASSERT_EQ (3, IDENTIFIER_LENGTH (identifier));
  ASSERT_STREQ ("foo", IDENTIFIER_POINTER (identifier));
}

/* Verify LABEL_DECL.  */

static void
test_labels ()
{
  tree identifier = get_identifier ("err");
  tree label_decl = build_decl (UNKNOWN_LOCATION, LABEL_DECL,
				identifier, void_type_node);
  ASSERT_EQ (-1, LABEL_DECL_UID (label_decl));
  ASSERT_FALSE (FORCED_LABEL (label_decl));
}

/* Return a new VECTOR_CST node whose type is TYPE and whose values
   are given by VALS.  */

static tree
build_vector (tree type, vec<tree> vals MEM_STAT_DECL)
{
  gcc_assert (known_eq (vals.length (), TYPE_VECTOR_SUBPARTS (type)));
  tree_vector_builder builder (type, vals.length (), 1);
  builder.splice (vals);
  return builder.build ();
}

/* Check that VECTOR_CST ACTUAL contains the elements in EXPECTED.  */

static void
check_vector_cst (vec<tree> expected, tree actual)
{
  ASSERT_KNOWN_EQ (expected.length (),
		   TYPE_VECTOR_SUBPARTS (TREE_TYPE (actual)));
  for (unsigned int i = 0; i < expected.length (); ++i)
    ASSERT_EQ (wi::to_wide (expected[i]),
	       wi::to_wide (vector_cst_elt (actual, i)));
}

/* Check that VECTOR_CST ACTUAL contains NPATTERNS duplicated elements,
   and that its elements match EXPECTED.  */

static void
check_vector_cst_duplicate (vec<tree> expected, tree actual,
			    unsigned int npatterns)
{
  ASSERT_EQ (npatterns, VECTOR_CST_NPATTERNS (actual));
  ASSERT_EQ (1, VECTOR_CST_NELTS_PER_PATTERN (actual));
  ASSERT_EQ (npatterns, vector_cst_encoded_nelts (actual));
  ASSERT_TRUE (VECTOR_CST_DUPLICATE_P (actual));
  ASSERT_FALSE (VECTOR_CST_STEPPED_P (actual));
  check_vector_cst (expected, actual);
}

/* Check that VECTOR_CST ACTUAL contains NPATTERNS foreground elements
   and NPATTERNS background elements, and that its elements match
   EXPECTED.  */

static void
check_vector_cst_fill (vec<tree> expected, tree actual,
		       unsigned int npatterns)
{
  ASSERT_EQ (npatterns, VECTOR_CST_NPATTERNS (actual));
  ASSERT_EQ (2, VECTOR_CST_NELTS_PER_PATTERN (actual));
  ASSERT_EQ (2 * npatterns, vector_cst_encoded_nelts (actual));
  ASSERT_FALSE (VECTOR_CST_DUPLICATE_P (actual));
  ASSERT_FALSE (VECTOR_CST_STEPPED_P (actual));
  check_vector_cst (expected, actual);
}

/* Check that VECTOR_CST ACTUAL contains NPATTERNS stepped patterns,
   and that its elements match EXPECTED.  */

static void
check_vector_cst_stepped (vec<tree> expected, tree actual,
			  unsigned int npatterns)
{
  ASSERT_EQ (npatterns, VECTOR_CST_NPATTERNS (actual));
  ASSERT_EQ (3, VECTOR_CST_NELTS_PER_PATTERN (actual));
  ASSERT_EQ (3 * npatterns, vector_cst_encoded_nelts (actual));
  ASSERT_FALSE (VECTOR_CST_DUPLICATE_P (actual));
  ASSERT_TRUE (VECTOR_CST_STEPPED_P (actual));
  check_vector_cst (expected, actual);
}

/* Test the creation of VECTOR_CSTs.  */

static void
test_vector_cst_patterns (ALONE_CXX_MEM_STAT_INFO)
{
  auto_vec<tree, 8> elements (8);
  elements.quick_grow (8);
  tree element_type = build_nonstandard_integer_type (16, true);
  tree vector_type = build_vector_type (element_type, 8);

  /* Test a simple linear series with a base of 0 and a step of 1:
     { 0, 1, 2, 3, 4, 5, 6, 7 }.  */
  for (unsigned int i = 0; i < 8; ++i)
    elements[i] = build_int_cst (element_type, i);
  tree vector = build_vector (vector_type, elements PASS_MEM_STAT);
  check_vector_cst_stepped (elements, vector, 1);

  /* Try the same with the first element replaced by 100:
     { 100, 1, 2, 3, 4, 5, 6, 7 }.  */
  elements[0] = build_int_cst (element_type, 100);
  vector = build_vector (vector_type, elements PASS_MEM_STAT);
  check_vector_cst_stepped (elements, vector, 1);

  /* Try a series that wraps around.
     { 100, 65531, 65532, 65533, 65534, 65535, 0, 1 }.  */
  for (unsigned int i = 1; i < 8; ++i)
    elements[i] = build_int_cst (element_type, (65530 + i) & 0xffff);
  vector = build_vector (vector_type, elements PASS_MEM_STAT);
  check_vector_cst_stepped (elements, vector, 1);

  /* Try a downward series:
     { 100, 79, 78, 77, 76, 75, 75, 73 }.  */
  for (unsigned int i = 1; i < 8; ++i)
    elements[i] = build_int_cst (element_type, 80 - i);
  vector = build_vector (vector_type, elements PASS_MEM_STAT);
  check_vector_cst_stepped (elements, vector, 1);

  /* Try two interleaved series with different bases and steps:
     { 100, 53, 66, 206, 62, 212, 58, 218 }.  */
  elements[1] = build_int_cst (element_type, 53);
  for (unsigned int i = 2; i < 8; i += 2)
    {
      elements[i] = build_int_cst (element_type, 70 - i * 2);
      elements[i + 1] = build_int_cst (element_type, 200 + i * 3);
    }
  vector = build_vector (vector_type, elements PASS_MEM_STAT);
  check_vector_cst_stepped (elements, vector, 2);

  /* Try a duplicated value:
     { 100, 100, 100, 100, 100, 100, 100, 100 }.  */
  for (unsigned int i = 1; i < 8; ++i)
    elements[i] = elements[0];
  vector = build_vector (vector_type, elements PASS_MEM_STAT);
  check_vector_cst_duplicate (elements, vector, 1);

  /* Try an interleaved duplicated value:
     { 100, 55, 100, 55, 100, 55, 100, 55 }.  */
  elements[1] = build_int_cst (element_type, 55);
  for (unsigned int i = 2; i < 8; ++i)
    elements[i] = elements[i - 2];
  vector = build_vector (vector_type, elements PASS_MEM_STAT);
  check_vector_cst_duplicate (elements, vector, 2);

  /* Try a duplicated value with 2 exceptions
     { 41, 97, 100, 55, 100, 55, 100, 55 }.  */
  elements[0] = build_int_cst (element_type, 41);
  elements[1] = build_int_cst (element_type, 97);
  vector = build_vector (vector_type, elements PASS_MEM_STAT);
  check_vector_cst_fill (elements, vector, 2);

  /* Try with and without a step
     { 41, 97, 100, 21, 100, 35, 100, 49 }.  */
  for (unsigned int i = 3; i < 8; i += 2)
    elements[i] = build_int_cst (element_type, i * 7);
  vector = build_vector (vector_type, elements PASS_MEM_STAT);
  check_vector_cst_stepped (elements, vector, 2);

  /* Try a fully-general constant:
     { 41, 97, 100, 21, 100, 9990, 100, 49 }.  */
  elements[5] = build_int_cst (element_type, 9990);
  vector = build_vector (vector_type, elements PASS_MEM_STAT);
  check_vector_cst_fill (elements, vector, 4);
}

/* Verify that STRIP_NOPS (NODE) is EXPECTED.
   Helper function for test_location_wrappers, to deal with STRIP_NOPS
   modifying its argument in-place.  */

static void
check_strip_nops (tree node, tree expected)
{
  STRIP_NOPS (node);
  ASSERT_EQ (expected, node);
}

/* Verify location wrappers.  */

static void
test_location_wrappers ()
{
  location_t loc = BUILTINS_LOCATION;

  ASSERT_EQ (NULL_TREE, maybe_wrap_with_location (NULL_TREE, loc));

  /* Wrapping a constant.  */
  tree int_cst = build_int_cst (integer_type_node, 42);
  ASSERT_FALSE (CAN_HAVE_LOCATION_P (int_cst));
  ASSERT_FALSE (location_wrapper_p (int_cst));

  tree wrapped_int_cst = maybe_wrap_with_location (int_cst, loc);
  ASSERT_TRUE (location_wrapper_p (wrapped_int_cst));
  ASSERT_EQ (loc, EXPR_LOCATION (wrapped_int_cst));
  ASSERT_EQ (int_cst, tree_strip_any_location_wrapper (wrapped_int_cst));

  /* We shouldn't add wrapper nodes for UNKNOWN_LOCATION.  */
  ASSERT_EQ (int_cst, maybe_wrap_with_location (int_cst, UNKNOWN_LOCATION));

  /* We shouldn't add wrapper nodes for nodes that CAN_HAVE_LOCATION_P.  */
  tree cast = build1 (NOP_EXPR, char_type_node, int_cst);
  ASSERT_TRUE (CAN_HAVE_LOCATION_P (cast));
  ASSERT_EQ (cast, maybe_wrap_with_location (cast, loc));

  /* Wrapping a STRING_CST.  */
  tree string_cst = build_string (4, "foo");
  ASSERT_FALSE (CAN_HAVE_LOCATION_P (string_cst));
  ASSERT_FALSE (location_wrapper_p (string_cst));

  tree wrapped_string_cst = maybe_wrap_with_location (string_cst, loc);
  ASSERT_TRUE (location_wrapper_p (wrapped_string_cst));
  ASSERT_EQ (VIEW_CONVERT_EXPR, TREE_CODE (wrapped_string_cst));
  ASSERT_EQ (loc, EXPR_LOCATION (wrapped_string_cst));
  ASSERT_EQ (string_cst, tree_strip_any_location_wrapper (wrapped_string_cst));


  /* Wrapping a variable.  */
  tree int_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
			     get_identifier ("some_int_var"),
			     integer_type_node);
  ASSERT_FALSE (CAN_HAVE_LOCATION_P (int_var));
  ASSERT_FALSE (location_wrapper_p (int_var));

  tree wrapped_int_var = maybe_wrap_with_location (int_var, loc);
  ASSERT_TRUE (location_wrapper_p (wrapped_int_var));
  ASSERT_EQ (loc, EXPR_LOCATION (wrapped_int_var));
  ASSERT_EQ (int_var, tree_strip_any_location_wrapper (wrapped_int_var));

  /* Verify that "reinterpret_cast<int>(some_int_var)" is not a location
     wrapper.  */
  tree r_cast = build1 (NON_LVALUE_EXPR, integer_type_node, int_var);
  ASSERT_FALSE (location_wrapper_p (r_cast));
  ASSERT_EQ (r_cast, tree_strip_any_location_wrapper (r_cast));

  /* Verify that STRIP_NOPS removes wrappers.  */
  check_strip_nops (wrapped_int_cst, int_cst);
  check_strip_nops (wrapped_string_cst, string_cst);
  check_strip_nops (wrapped_int_var, int_var);
}

/* Check that string escaping works correctly.  */

static void
test_escaped_strings (void)
{
  int saved_cutoff;
  escaped_string msg;

  msg.escape (NULL);
  /* ASSERT_STREQ does not accept NULL as a valid test
     result, so we have to use ASSERT_EQ instead.  */
  ASSERT_EQ (NULL, (const char *) msg);

  msg.escape ("");
  ASSERT_STREQ ("", (const char *) msg);

  msg.escape ("foobar");
  ASSERT_STREQ ("foobar", (const char *) msg);

  /* Ensure that we have -fmessage-length set to 0.  */
  saved_cutoff = pp_line_cutoff (global_dc->printer);
  pp_line_cutoff (global_dc->printer) = 0;

  msg.escape ("foo\nbar");
  ASSERT_STREQ ("foo\\nbar", (const char *) msg);

  msg.escape ("\a\b\f\n\r\t\v");
  ASSERT_STREQ ("\\a\\b\\f\\n\\r\\t\\v", (const char *) msg);

  /* Now repeat the tests with -fmessage-length set to 5.  */
  pp_line_cutoff (global_dc->printer) = 5;

  /* Note that the newline is not translated into an escape.  */
  msg.escape ("foo\nbar");
  ASSERT_STREQ ("foo\nbar", (const char *) msg);

  msg.escape ("\a\b\f\n\r\t\v");
  ASSERT_STREQ ("\\a\\b\\f\n\\r\\t\\v", (const char *) msg);

  /* Restore the original message length setting.  */
  pp_line_cutoff (global_dc->printer) = saved_cutoff;
}

/* Run all of the selftests within this file.  */

void
tree_c_tests ()
{
  test_integer_constants ();
  test_identifiers ();
  test_labels ();
  test_vector_cst_patterns ();
  test_location_wrappers ();
  test_escaped_strings ();
}

} // namespace selftest

#endif /* CHECKING_P */

#include "gt-tree.h"
