/* Language-independent node constructors for parse phase of GNU compiler.
   Copyright (C) 1987-2019 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)
{
  gcc_assert (CONSTANT_CLASS_P (real));
  gcc_assert (CONSTANT_CLASS_P (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, or a location wrapper for such a constant.  */

bool
integer_zerop (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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, or a location wrapper for such a constant.  */

bool
integer_onep (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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.
   Also return 1 for location wrappers for such a constant.  */

bool
integer_each_onep (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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,
   or a location wrapper for such a constant.  */

bool
integer_all_onesp (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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, or a location wrapper
   for such a constant.  */

bool
integer_minus_onep (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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), or a location wrapper for such a constant.  */

bool
integer_pow2p (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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, or a location wrapper for such a
   constant.  */

bool
integer_nonzerop (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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).
   Also return 1 for location wrappers for such a constant.  */

bool
integer_truep (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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, or a location wrapper
   for such a constant.  */

bool
fixed_zerop (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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.
   Also return 1 for location wrappers around such a constant.  */

bool
real_zerop (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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.
   Also return 1 for location wrappers around such a constant.  */

bool
real_onep (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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.
   Also return 1 for location wrappers around such a constant.  */

bool
real_minus_onep (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (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)
      || (!DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (type))
	  && (TREE_CODE (type) != RECORD_TYPE
	      || !TYPE_BINFO (type)
	      || !BINFO_VTABLE (TYPE_BINFO (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);
  /* FIXME: This triggers verification error, see PR88140.  */
  if (TREE_CODE (t) == ARRAY_TYPE && 0)
    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 cannot 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))
    {
      /* Rebuild type inheritance graph even when not doing LTO to get
	 consistent profile data.  */
      rebuild_type_inheritance_graph ();
      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;

  STRIP_ANY_LOCATION_WRAPPER (t1);
  STRIP_ANY_LOCATION_WRAPPER (t2);

  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;

  /* For location wrappers to be the same, they must be at the same
     source location (and wrap the same thing).  */
  if (location_wrapper_p (t1) && location_wrapper_p (t2))
    {
      if (EXPR_LOCATION (t1) != EXPR_LOCATION (t2))
	return 0;
      return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 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).
   When PERR is non-null, set *PERR on failure to the description of
   why SIZE is not valid.  */

bool
valid_constant_size_p (const_tree size, cst_size_error *perr /* = NULL */)
{
  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;
    }

  cst_size_error error;
  if (!perr)
    perr = &error;

  if (TREE_OVERFLOW (size))
    {
      *perr = cst_size_overflow;
      return false;
    }

  tree type = TREE_TYPE (size);
  if (TYPE_UNSIGNED (type))
    {
      if (!tree_fits_uhwi_p (size)
	  || tree_int_cst_sign_bit (size))
	{
	  *perr = cst_size_too_big;
	  return false;
	}
    }
  else if (tree_int_cst_sign_bit (size))
    {
      *perr = cst_size_negative;
      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;

  gcc_assert (arg_types != error_mark_node);

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

/* Return true if EXPR is an initializer expression in which every element
   is a constant that is numerically equal to 0 or 1.  The elements do not
   need to be equal to each other.  */

bool
initializer_each_zero_or_onep (const_tree expr)
{
  STRIP_ANY_LOCATION_WRAPPER (expr);

  switch (TREE_CODE (expr))
    {
    case INTEGER_CST:
      return integer_zerop (expr) || integer_onep (expr);

    case REAL_CST:
      return real_zerop (expr) || real_onep (expr);

    case VECTOR_CST:
      {
	unsigned HOST_WIDE_INT nelts = vector_cst_encoded_nelts (expr);
	if (VECTOR_CST_STEPPED_P (expr)
	    && !TYPE_VECTOR_SUBPARTS (TREE_TYPE (expr)).is_constant (&nelts))
	  return false;

	for (unsigned int i = 0; i < nelts; ++i)
	  {
	    tree elt = vector_cst_elt (expr, i);
	    if (!initializer_each_zero_or_onep (elt))
	      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.
   Look through location wrappers. */

tree
uniform_integer_cst_p (tree t)
{
  STRIP_ANY_LOCATION_WRAPPER (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;
}

/* If VECTOR_CST T has a single nonzero element, return the index of that
   element, otherwise return -1.  */

int
single_nonzero_element (const_tree t)
{
  unsigned HOST_WIDE_INT nelts;
  unsigned int repeat_nelts;
  if (VECTOR_CST_NELTS (t).is_constant (&nelts))
    repeat_nelts = nelts;
  else if (VECTOR_CST_NELTS_PER_PATTERN (t) == 2)
    {
      nelts = vector_cst_encoded_nelts (t);
      repeat_nelts = VECTOR_CST_NPATTERNS (t);
    }
  else
    return -1;

  int res = -1;
  for (unsigned int i = 0; i < nelts; ++i)
    {
      tree elt = vector_cst_elt (t, i);
      if (!integer_zerop (elt) && !real_zerop (elt))
	{
	  if (res >= 0 || i >= repeat_nelts)
	    return -1;
	  res = i;
	}
    }
  return res;
}

/* 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.
   If TYPE is a floating-point type, return an integer type with the same
   bitsize and with the signedness given by UNSIGNEDP; this is useful
   when doing bit-level operations on a floating-point value.  */

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

  unsigned int bits;
  if (INTEGRAL_TYPE_P (type)
      || POINTER_TYPE_P (type)
      || TREE_CODE (type) == OFFSET_TYPE)
    bits = TYPE_PRECISION (type);
  else if (TREE_CODE (type) == REAL_TYPE)
    bits = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (type));
  else
    return NULL_TREE;

  return build_nonstandard_integer_type (bits, 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.  If TYPE is a floating-point type, return an
   unsigned integer type with the same bitsize as 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.  If TYPE is a floating-point type, return a
   signed integer type with the same bitsize as 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;
}

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

  /* If any auto_suppress_location_wrappers are active, don't create
     wrappers.  */
  if (suppress_location_wrappers > 0)
    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;
}

int suppress_location_wrappers;

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

/* Return the maximum object size.  */

tree
max_object_size (void)
{
  /* To do: Make this a configurable parameter.  */
  return TYPE_MAX_VALUE (ptrdiff_type_node);
}

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

/* Test various tree predicates.  Verify that location wrappers don't
   affect the results.  */

static void
test_predicates ()
{
  /* Build various constants and wrappers around them.  */

  location_t loc = BUILTINS_LOCATION;

  tree i_0 = build_int_cst (integer_type_node, 0);
  tree wr_i_0 = maybe_wrap_with_location (i_0, loc);

  tree i_1 = build_int_cst (integer_type_node, 1);
  tree wr_i_1 = maybe_wrap_with_location (i_1, loc);

  tree i_m1 = build_int_cst (integer_type_node, -1);
  tree wr_i_m1 = maybe_wrap_with_location (i_m1, loc);

  tree f_0 = build_real_from_int_cst (float_type_node, i_0);
  tree wr_f_0 = maybe_wrap_with_location (f_0, loc);
  tree f_1 = build_real_from_int_cst (float_type_node, i_1);
  tree wr_f_1 = maybe_wrap_with_location (f_1, loc);
  tree f_m1 = build_real_from_int_cst (float_type_node, i_m1);
  tree wr_f_m1 = maybe_wrap_with_location (f_m1, loc);

  tree c_i_0 = build_complex (NULL_TREE, i_0, i_0);
  tree c_i_1 = build_complex (NULL_TREE, i_1, i_0);
  tree c_i_m1 = build_complex (NULL_TREE, i_m1, i_0);

  tree c_f_0 = build_complex (NULL_TREE, f_0, f_0);
  tree c_f_1 = build_complex (NULL_TREE, f_1, f_0);
  tree c_f_m1 = build_complex (NULL_TREE, f_m1, f_0);

  /* TODO: vector constants.  */

  /* Test integer_onep.  */
  ASSERT_FALSE (integer_onep (i_0));
  ASSERT_FALSE (integer_onep (wr_i_0));
  ASSERT_TRUE (integer_onep (i_1));
  ASSERT_TRUE (integer_onep (wr_i_1));
  ASSERT_FALSE (integer_onep (i_m1));
  ASSERT_FALSE (integer_onep (wr_i_m1));
  ASSERT_FALSE (integer_onep (f_0));
  ASSERT_FALSE (integer_onep (wr_f_0));
  ASSERT_FALSE (integer_onep (f_1));
  ASSERT_FALSE (integer_onep (wr_f_1));
  ASSERT_FALSE (integer_onep (f_m1));
  ASSERT_FALSE (integer_onep (wr_f_m1));
  ASSERT_FALSE (integer_onep (c_i_0));
  ASSERT_TRUE (integer_onep (c_i_1));
  ASSERT_FALSE (integer_onep (c_i_m1));
  ASSERT_FALSE (integer_onep (c_f_0));
  ASSERT_FALSE (integer_onep (c_f_1));
  ASSERT_FALSE (integer_onep (c_f_m1));

  /* Test integer_zerop.  */
  ASSERT_TRUE (integer_zerop (i_0));
  ASSERT_TRUE (integer_zerop (wr_i_0));
  ASSERT_FALSE (integer_zerop (i_1));
  ASSERT_FALSE (integer_zerop (wr_i_1));
  ASSERT_FALSE (integer_zerop (i_m1));
  ASSERT_FALSE (integer_zerop (wr_i_m1));
  ASSERT_FALSE (integer_zerop (f_0));
  ASSERT_FALSE (integer_zerop (wr_f_0));
  ASSERT_FALSE (integer_zerop (f_1));
  ASSERT_FALSE (integer_zerop (wr_f_1));
  ASSERT_FALSE (integer_zerop (f_m1));
  ASSERT_FALSE (integer_zerop (wr_f_m1));
  ASSERT_TRUE (integer_zerop (c_i_0));
  ASSERT_FALSE (integer_zerop (c_i_1));
  ASSERT_FALSE (integer_zerop (c_i_m1));
  ASSERT_FALSE (integer_zerop (c_f_0));
  ASSERT_FALSE (integer_zerop (c_f_1));
  ASSERT_FALSE (integer_zerop (c_f_m1));

  /* Test integer_all_onesp.  */
  ASSERT_FALSE (integer_all_onesp (i_0));
  ASSERT_FALSE (integer_all_onesp (wr_i_0));
  ASSERT_FALSE (integer_all_onesp (i_1));
  ASSERT_FALSE (integer_all_onesp (wr_i_1));
  ASSERT_TRUE (integer_all_onesp (i_m1));
  ASSERT_TRUE (integer_all_onesp (wr_i_m1));
  ASSERT_FALSE (integer_all_onesp (f_0));
  ASSERT_FALSE (integer_all_onesp (wr_f_0));
  ASSERT_FALSE (integer_all_onesp (f_1));
  ASSERT_FALSE (integer_all_onesp (wr_f_1));
  ASSERT_FALSE (integer_all_onesp (f_m1));
  ASSERT_FALSE (integer_all_onesp (wr_f_m1));
  ASSERT_FALSE (integer_all_onesp (c_i_0));
  ASSERT_FALSE (integer_all_onesp (c_i_1));
  ASSERT_FALSE (integer_all_onesp (c_i_m1));
  ASSERT_FALSE (integer_all_onesp (c_f_0));
  ASSERT_FALSE (integer_all_onesp (c_f_1));
  ASSERT_FALSE (integer_all_onesp (c_f_m1));

  /* Test integer_minus_onep.  */
  ASSERT_FALSE (integer_minus_onep (i_0));
  ASSERT_FALSE (integer_minus_onep (wr_i_0));
  ASSERT_FALSE (integer_minus_onep (i_1));
  ASSERT_FALSE (integer_minus_onep (wr_i_1));
  ASSERT_TRUE (integer_minus_onep (i_m1));
  ASSERT_TRUE (integer_minus_onep (wr_i_m1));
  ASSERT_FALSE (integer_minus_onep (f_0));
  ASSERT_FALSE (integer_minus_onep (wr_f_0));
  ASSERT_FALSE (integer_minus_onep (f_1));
  ASSERT_FALSE (integer_minus_onep (wr_f_1));
  ASSERT_FALSE (integer_minus_onep (f_m1));
  ASSERT_FALSE (integer_minus_onep (wr_f_m1));
  ASSERT_FALSE (integer_minus_onep (c_i_0));
  ASSERT_FALSE (integer_minus_onep (c_i_1));
  ASSERT_TRUE (integer_minus_onep (c_i_m1));
  ASSERT_FALSE (integer_minus_onep (c_f_0));
  ASSERT_FALSE (integer_minus_onep (c_f_1));
  ASSERT_FALSE (integer_minus_onep (c_f_m1));

  /* Test integer_each_onep.  */
  ASSERT_FALSE (integer_each_onep (i_0));
  ASSERT_FALSE (integer_each_onep (wr_i_0));
  ASSERT_TRUE (integer_each_onep (i_1));
  ASSERT_TRUE (integer_each_onep (wr_i_1));
  ASSERT_FALSE (integer_each_onep (i_m1));
  ASSERT_FALSE (integer_each_onep (wr_i_m1));
  ASSERT_FALSE (integer_each_onep (f_0));
  ASSERT_FALSE (integer_each_onep (wr_f_0));
  ASSERT_FALSE (integer_each_onep (f_1));
  ASSERT_FALSE (integer_each_onep (wr_f_1));
  ASSERT_FALSE (integer_each_onep (f_m1));
  ASSERT_FALSE (integer_each_onep (wr_f_m1));
  ASSERT_FALSE (integer_each_onep (c_i_0));
  ASSERT_FALSE (integer_each_onep (c_i_1));
  ASSERT_FALSE (integer_each_onep (c_i_m1));
  ASSERT_FALSE (integer_each_onep (c_f_0));
  ASSERT_FALSE (integer_each_onep (c_f_1));
  ASSERT_FALSE (integer_each_onep (c_f_m1));

  /* Test integer_truep.  */
  ASSERT_FALSE (integer_truep (i_0));
  ASSERT_FALSE (integer_truep (wr_i_0));
  ASSERT_TRUE (integer_truep (i_1));
  ASSERT_TRUE (integer_truep (wr_i_1));
  ASSERT_FALSE (integer_truep (i_m1));
  ASSERT_FALSE (integer_truep (wr_i_m1));
  ASSERT_FALSE (integer_truep (f_0));
  ASSERT_FALSE (integer_truep (wr_f_0));
  ASSERT_FALSE (integer_truep (f_1));
  ASSERT_FALSE (integer_truep (wr_f_1));
  ASSERT_FALSE (integer_truep (f_m1));
  ASSERT_FALSE (integer_truep (wr_f_m1));
  ASSERT_FALSE (integer_truep (c_i_0));
  ASSERT_TRUE (integer_truep (c_i_1));
  ASSERT_FALSE (integer_truep (c_i_m1));
  ASSERT_FALSE (integer_truep (c_f_0));
  ASSERT_FALSE (integer_truep (c_f_1));
  ASSERT_FALSE (integer_truep (c_f_m1));

  /* Test integer_nonzerop.  */
  ASSERT_FALSE (integer_nonzerop (i_0));
  ASSERT_FALSE (integer_nonzerop (wr_i_0));
  ASSERT_TRUE (integer_nonzerop (i_1));
  ASSERT_TRUE (integer_nonzerop (wr_i_1));
  ASSERT_TRUE (integer_nonzerop (i_m1));
  ASSERT_TRUE (integer_nonzerop (wr_i_m1));
  ASSERT_FALSE (integer_nonzerop (f_0));
  ASSERT_FALSE (integer_nonzerop (wr_f_0));
  ASSERT_FALSE (integer_nonzerop (f_1));
  ASSERT_FALSE (integer_nonzerop (wr_f_1));
  ASSERT_FALSE (integer_nonzerop (f_m1));
  ASSERT_FALSE (integer_nonzerop (wr_f_m1));
  ASSERT_FALSE (integer_nonzerop (c_i_0));
  ASSERT_TRUE (integer_nonzerop (c_i_1));
  ASSERT_TRUE (integer_nonzerop (c_i_m1));
  ASSERT_FALSE (integer_nonzerop (c_f_0));
  ASSERT_FALSE (integer_nonzerop (c_f_1));
  ASSERT_FALSE (integer_nonzerop (c_f_m1));

  /* Test real_zerop.  */
  ASSERT_FALSE (real_zerop (i_0));
  ASSERT_FALSE (real_zerop (wr_i_0));
  ASSERT_FALSE (real_zerop (i_1));
  ASSERT_FALSE (real_zerop (wr_i_1));
  ASSERT_FALSE (real_zerop (i_m1));
  ASSERT_FALSE (real_zerop (wr_i_m1));
  ASSERT_TRUE (real_zerop (f_0));
  ASSERT_TRUE (real_zerop (wr_f_0));
  ASSERT_FALSE (real_zerop (f_1));
  ASSERT_FALSE (real_zerop (wr_f_1));
  ASSERT_FALSE (real_zerop (f_m1));
  ASSERT_FALSE (real_zerop (wr_f_m1));
  ASSERT_FALSE (real_zerop (c_i_0));
  ASSERT_FALSE (real_zerop (c_i_1));
  ASSERT_FALSE (real_zerop (c_i_m1));
  ASSERT_TRUE (real_zerop (c_f_0));
  ASSERT_FALSE (real_zerop (c_f_1));
  ASSERT_FALSE (real_zerop (c_f_m1));

  /* Test real_onep.  */
  ASSERT_FALSE (real_onep (i_0));
  ASSERT_FALSE (real_onep (wr_i_0));
  ASSERT_FALSE (real_onep (i_1));
  ASSERT_FALSE (real_onep (wr_i_1));
  ASSERT_FALSE (real_onep (i_m1));
  ASSERT_FALSE (real_onep (wr_i_m1));
  ASSERT_FALSE (real_onep (f_0));
  ASSERT_FALSE (real_onep (wr_f_0));
  ASSERT_TRUE (real_onep (f_1));
  ASSERT_TRUE (real_onep (wr_f_1));
  ASSERT_FALSE (real_onep (f_m1));
  ASSERT_FALSE (real_onep (wr_f_m1));
  ASSERT_FALSE (real_onep (c_i_0));
  ASSERT_FALSE (real_onep (c_i_1));
  ASSERT_FALSE (real_onep (c_i_m1));
  ASSERT_FALSE (real_onep (c_f_0));
  ASSERT_TRUE (real_onep (c_f_1));
  ASSERT_FALSE (real_onep (c_f_m1));

  /* Test real_minus_onep.  */
  ASSERT_FALSE (real_minus_onep (i_0));
  ASSERT_FALSE (real_minus_onep (wr_i_0));
  ASSERT_FALSE (real_minus_onep (i_1));
  ASSERT_FALSE (real_minus_onep (wr_i_1));
  ASSERT_FALSE (real_minus_onep (i_m1));
  ASSERT_FALSE (real_minus_onep (wr_i_m1));
  ASSERT_FALSE (real_minus_onep (f_0));
  ASSERT_FALSE (real_minus_onep (wr_f_0));
  ASSERT_FALSE (real_minus_onep (f_1));
  ASSERT_FALSE (real_minus_onep (wr_f_1));
  ASSERT_TRUE (real_minus_onep (f_m1));
  ASSERT_TRUE (real_minus_onep (wr_f_m1));
  ASSERT_FALSE (real_minus_onep (c_i_0));
  ASSERT_FALSE (real_minus_onep (c_i_1));
  ASSERT_FALSE (real_minus_onep (c_i_m1));
  ASSERT_FALSE (real_minus_onep (c_f_0));
  ASSERT_FALSE (real_minus_onep (c_f_1));
  ASSERT_TRUE (real_minus_onep (c_f_m1));

  /* Test zerop.  */
  ASSERT_TRUE (zerop (i_0));
  ASSERT_TRUE (zerop (wr_i_0));
  ASSERT_FALSE (zerop (i_1));
  ASSERT_FALSE (zerop (wr_i_1));
  ASSERT_FALSE (zerop (i_m1));
  ASSERT_FALSE (zerop (wr_i_m1));
  ASSERT_TRUE (zerop (f_0));
  ASSERT_TRUE (zerop (wr_f_0));
  ASSERT_FALSE (zerop (f_1));
  ASSERT_FALSE (zerop (wr_f_1));
  ASSERT_FALSE (zerop (f_m1));
  ASSERT_FALSE (zerop (wr_f_m1));
  ASSERT_TRUE (zerop (c_i_0));
  ASSERT_FALSE (zerop (c_i_1));
  ASSERT_FALSE (zerop (c_i_m1));
  ASSERT_TRUE (zerop (c_f_0));
  ASSERT_FALSE (zerop (c_f_1));
  ASSERT_FALSE (zerop (c_f_m1));

  /* Test tree_expr_nonnegative_p.  */
  ASSERT_TRUE (tree_expr_nonnegative_p (i_0));
  ASSERT_TRUE (tree_expr_nonnegative_p (wr_i_0));
  ASSERT_TRUE (tree_expr_nonnegative_p (i_1));
  ASSERT_TRUE (tree_expr_nonnegative_p (wr_i_1));
  ASSERT_FALSE (tree_expr_nonnegative_p (i_m1));
  ASSERT_FALSE (tree_expr_nonnegative_p (wr_i_m1));
  ASSERT_TRUE (tree_expr_nonnegative_p (f_0));
  ASSERT_TRUE (tree_expr_nonnegative_p (wr_f_0));
  ASSERT_TRUE (tree_expr_nonnegative_p (f_1));
  ASSERT_TRUE (tree_expr_nonnegative_p (wr_f_1));
  ASSERT_FALSE (tree_expr_nonnegative_p (f_m1));
  ASSERT_FALSE (tree_expr_nonnegative_p (wr_f_m1));
  ASSERT_FALSE (tree_expr_nonnegative_p (c_i_0));
  ASSERT_FALSE (tree_expr_nonnegative_p (c_i_1));
  ASSERT_FALSE (tree_expr_nonnegative_p (c_i_m1));
  ASSERT_FALSE (tree_expr_nonnegative_p (c_f_0));
  ASSERT_FALSE (tree_expr_nonnegative_p (c_f_1));
  ASSERT_FALSE (tree_expr_nonnegative_p (c_f_m1));

  /* Test tree_expr_nonzero_p.  */
  ASSERT_FALSE (tree_expr_nonzero_p (i_0));
  ASSERT_FALSE (tree_expr_nonzero_p (wr_i_0));
  ASSERT_TRUE (tree_expr_nonzero_p (i_1));
  ASSERT_TRUE (tree_expr_nonzero_p (wr_i_1));
  ASSERT_TRUE (tree_expr_nonzero_p (i_m1));
  ASSERT_TRUE (tree_expr_nonzero_p (wr_i_m1));

  /* Test integer_valued_real_p.  */
  ASSERT_FALSE (integer_valued_real_p (i_0));
  ASSERT_TRUE (integer_valued_real_p (f_0));
  ASSERT_TRUE (integer_valued_real_p (wr_f_0));
  ASSERT_TRUE (integer_valued_real_p (f_1));
  ASSERT_TRUE (integer_valued_real_p (wr_f_1));

  /* Test integer_pow2p.  */
  ASSERT_FALSE (integer_pow2p (i_0));
  ASSERT_TRUE (integer_pow2p (i_1));
  ASSERT_TRUE (integer_pow2p (wr_i_1));

  /* Test uniform_integer_cst_p.  */
  ASSERT_TRUE (uniform_integer_cst_p (i_0));
  ASSERT_TRUE (uniform_integer_cst_p (wr_i_0));
  ASSERT_TRUE (uniform_integer_cst_p (i_1));
  ASSERT_TRUE (uniform_integer_cst_p (wr_i_1));
  ASSERT_TRUE (uniform_integer_cst_p (i_m1));
  ASSERT_TRUE (uniform_integer_cst_p (wr_i_m1));
  ASSERT_FALSE (uniform_integer_cst_p (f_0));
  ASSERT_FALSE (uniform_integer_cst_p (wr_f_0));
  ASSERT_FALSE (uniform_integer_cst_p (f_1));
  ASSERT_FALSE (uniform_integer_cst_p (wr_f_1));
  ASSERT_FALSE (uniform_integer_cst_p (f_m1));
  ASSERT_FALSE (uniform_integer_cst_p (wr_f_m1));
  ASSERT_FALSE (uniform_integer_cst_p (c_i_0));
  ASSERT_FALSE (uniform_integer_cst_p (c_i_1));
  ASSERT_FALSE (uniform_integer_cst_p (c_i_m1));
  ASSERT_FALSE (uniform_integer_cst_p (c_f_0));
  ASSERT_FALSE (uniform_integer_cst_p (c_f_1));
  ASSERT_FALSE (uniform_integer_cst_p (c_f_m1));
}

/* 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_predicates ();
  test_escaped_strings ();
}

} // namespace selftest

#endif /* CHECKING_P */

#include "gt-tree.h"
