xref: /dflybsd-src/contrib/gcc-4.7/gcc/tree.c (revision 81fc95a5293ee307c688a350a3feb4734aaddbb4)
1e4b17023SJohn Marino /* Language-independent node constructors for parse phase of GNU compiler.
2e4b17023SJohn Marino    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3e4b17023SJohn Marino    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4e4b17023SJohn Marino    2011, 2012 Free Software Foundation, Inc.
5e4b17023SJohn Marino 
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino 
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11e4b17023SJohn Marino version.
12e4b17023SJohn Marino 
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16e4b17023SJohn Marino for more details.
17e4b17023SJohn Marino 
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21e4b17023SJohn Marino 
22e4b17023SJohn Marino /* This file contains the low level primitives for operating on tree nodes,
23e4b17023SJohn Marino    including allocation, list operations, interning of identifiers,
24e4b17023SJohn Marino    construction of data type nodes and statement nodes,
25e4b17023SJohn Marino    and construction of type conversion nodes.  It also contains
26e4b17023SJohn Marino    tables index by tree code that describe how to take apart
27e4b17023SJohn Marino    nodes of that code.
28e4b17023SJohn Marino 
29e4b17023SJohn Marino    It is intended to be language-independent, but occasionally
30e4b17023SJohn Marino    calls language-dependent routines defined (for C) in typecheck.c.  */
31e4b17023SJohn Marino 
32e4b17023SJohn Marino #include "config.h"
33e4b17023SJohn Marino #include "system.h"
34e4b17023SJohn Marino #include "coretypes.h"
35e4b17023SJohn Marino #include "tm.h"
36e4b17023SJohn Marino #include "flags.h"
37e4b17023SJohn Marino #include "tree.h"
38e4b17023SJohn Marino #include "tm_p.h"
39e4b17023SJohn Marino #include "function.h"
40e4b17023SJohn Marino #include "obstack.h"
41e4b17023SJohn Marino #include "toplev.h"
42e4b17023SJohn Marino #include "ggc.h"
43e4b17023SJohn Marino #include "hashtab.h"
44e4b17023SJohn Marino #include "filenames.h"
45e4b17023SJohn Marino #include "output.h"
46e4b17023SJohn Marino #include "target.h"
47e4b17023SJohn Marino #include "common/common-target.h"
48e4b17023SJohn Marino #include "langhooks.h"
49e4b17023SJohn Marino #include "tree-inline.h"
50e4b17023SJohn Marino #include "tree-iterator.h"
51e4b17023SJohn Marino #include "basic-block.h"
52e4b17023SJohn Marino #include "tree-flow.h"
53e4b17023SJohn Marino #include "params.h"
54e4b17023SJohn Marino #include "pointer-set.h"
55e4b17023SJohn Marino #include "tree-pass.h"
56e4b17023SJohn Marino #include "langhooks-def.h"
57e4b17023SJohn Marino #include "diagnostic.h"
58e4b17023SJohn Marino #include "tree-diagnostic.h"
59e4b17023SJohn Marino #include "tree-pretty-print.h"
60e4b17023SJohn Marino #include "cgraph.h"
61e4b17023SJohn Marino #include "timevar.h"
62e4b17023SJohn Marino #include "except.h"
63e4b17023SJohn Marino #include "debug.h"
64e4b17023SJohn Marino #include "intl.h"
65e4b17023SJohn Marino 
66e4b17023SJohn Marino /* Tree code classes.  */
67e4b17023SJohn Marino 
68e4b17023SJohn Marino #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
69e4b17023SJohn Marino #define END_OF_BASE_TREE_CODES tcc_exceptional,
70e4b17023SJohn Marino 
71e4b17023SJohn Marino const enum tree_code_class tree_code_type[] = {
72e4b17023SJohn Marino #include "all-tree.def"
73e4b17023SJohn Marino };
74e4b17023SJohn Marino 
75e4b17023SJohn Marino #undef DEFTREECODE
76e4b17023SJohn Marino #undef END_OF_BASE_TREE_CODES
77e4b17023SJohn Marino 
78e4b17023SJohn Marino /* Table indexed by tree code giving number of expression
79e4b17023SJohn Marino    operands beyond the fixed part of the node structure.
80e4b17023SJohn Marino    Not used for types or decls.  */
81e4b17023SJohn Marino 
82e4b17023SJohn Marino #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
83e4b17023SJohn Marino #define END_OF_BASE_TREE_CODES 0,
84e4b17023SJohn Marino 
85e4b17023SJohn Marino const unsigned char tree_code_length[] = {
86e4b17023SJohn Marino #include "all-tree.def"
87e4b17023SJohn Marino };
88e4b17023SJohn Marino 
89e4b17023SJohn Marino #undef DEFTREECODE
90e4b17023SJohn Marino #undef END_OF_BASE_TREE_CODES
91e4b17023SJohn Marino 
92e4b17023SJohn Marino /* Names of tree components.
93e4b17023SJohn Marino    Used for printing out the tree and error messages.  */
94e4b17023SJohn Marino #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
95e4b17023SJohn Marino #define END_OF_BASE_TREE_CODES "@dummy",
96e4b17023SJohn Marino 
97e4b17023SJohn Marino const char *const tree_code_name[] = {
98e4b17023SJohn Marino #include "all-tree.def"
99e4b17023SJohn Marino };
100e4b17023SJohn Marino 
101e4b17023SJohn Marino #undef DEFTREECODE
102e4b17023SJohn Marino #undef END_OF_BASE_TREE_CODES
103e4b17023SJohn Marino 
104e4b17023SJohn Marino /* Each tree code class has an associated string representation.
105e4b17023SJohn Marino    These must correspond to the tree_code_class entries.  */
106e4b17023SJohn Marino 
107e4b17023SJohn Marino const char *const tree_code_class_strings[] =
108e4b17023SJohn Marino {
109e4b17023SJohn Marino   "exceptional",
110e4b17023SJohn Marino   "constant",
111e4b17023SJohn Marino   "type",
112e4b17023SJohn Marino   "declaration",
113e4b17023SJohn Marino   "reference",
114e4b17023SJohn Marino   "comparison",
115e4b17023SJohn Marino   "unary",
116e4b17023SJohn Marino   "binary",
117e4b17023SJohn Marino   "statement",
118e4b17023SJohn Marino   "vl_exp",
119e4b17023SJohn Marino   "expression"
120e4b17023SJohn Marino };
121e4b17023SJohn Marino 
122e4b17023SJohn Marino /* obstack.[ch] explicitly declined to prototype this.  */
123e4b17023SJohn Marino extern int _obstack_allocated_p (struct obstack *h, void *obj);
124e4b17023SJohn Marino 
125e4b17023SJohn Marino #ifdef GATHER_STATISTICS
126e4b17023SJohn Marino /* Statistics-gathering stuff.  */
127e4b17023SJohn Marino 
128e4b17023SJohn Marino static int tree_code_counts[MAX_TREE_CODES];
129e4b17023SJohn Marino int tree_node_counts[(int) all_kinds];
130e4b17023SJohn Marino int tree_node_sizes[(int) all_kinds];
131e4b17023SJohn Marino 
132e4b17023SJohn Marino /* Keep in sync with tree.h:enum tree_node_kind.  */
133e4b17023SJohn Marino static const char * const tree_node_kind_names[] = {
134e4b17023SJohn Marino   "decls",
135e4b17023SJohn Marino   "types",
136e4b17023SJohn Marino   "blocks",
137e4b17023SJohn Marino   "stmts",
138e4b17023SJohn Marino   "refs",
139e4b17023SJohn Marino   "exprs",
140e4b17023SJohn Marino   "constants",
141e4b17023SJohn Marino   "identifiers",
142e4b17023SJohn Marino   "vecs",
143e4b17023SJohn Marino   "binfos",
144e4b17023SJohn Marino   "ssa names",
145e4b17023SJohn Marino   "constructors",
146e4b17023SJohn Marino   "random kinds",
147e4b17023SJohn Marino   "lang_decl kinds",
148e4b17023SJohn Marino   "lang_type kinds",
149e4b17023SJohn Marino   "omp clauses",
150e4b17023SJohn Marino };
151e4b17023SJohn Marino #endif /* GATHER_STATISTICS */
152e4b17023SJohn Marino 
153e4b17023SJohn Marino /* Unique id for next decl created.  */
154e4b17023SJohn Marino static GTY(()) int next_decl_uid;
155e4b17023SJohn Marino /* Unique id for next type created.  */
156e4b17023SJohn Marino static GTY(()) int next_type_uid = 1;
157e4b17023SJohn Marino /* Unique id for next debug decl created.  Use negative numbers,
158e4b17023SJohn Marino    to catch erroneous uses.  */
159e4b17023SJohn Marino static GTY(()) int next_debug_decl_uid;
160e4b17023SJohn Marino 
161e4b17023SJohn Marino /* Since we cannot rehash a type after it is in the table, we have to
162e4b17023SJohn Marino    keep the hash code.  */
163e4b17023SJohn Marino 
164e4b17023SJohn Marino struct GTY(()) type_hash {
165e4b17023SJohn Marino   unsigned long hash;
166e4b17023SJohn Marino   tree type;
167e4b17023SJohn Marino };
168e4b17023SJohn Marino 
169e4b17023SJohn Marino /* Initial size of the hash table (rounded to next prime).  */
170e4b17023SJohn Marino #define TYPE_HASH_INITIAL_SIZE 1000
171e4b17023SJohn Marino 
172e4b17023SJohn Marino /* Now here is the hash table.  When recording a type, it is added to
173e4b17023SJohn Marino    the slot whose index is the hash code.  Note that the hash table is
174e4b17023SJohn Marino    used for several kinds of types (function types, array types and
175e4b17023SJohn Marino    array index range types, for now).  While all these live in the
176e4b17023SJohn Marino    same table, they are completely independent, and the hash code is
177e4b17023SJohn Marino    computed differently for each of these.  */
178e4b17023SJohn Marino 
179e4b17023SJohn Marino static GTY ((if_marked ("type_hash_marked_p"), param_is (struct type_hash)))
180e4b17023SJohn Marino      htab_t type_hash_table;
181e4b17023SJohn Marino 
182e4b17023SJohn Marino /* Hash table and temporary node for larger integer const values.  */
183e4b17023SJohn Marino static GTY (()) tree int_cst_node;
184e4b17023SJohn Marino static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
185e4b17023SJohn Marino      htab_t int_cst_hash_table;
186e4b17023SJohn Marino 
187e4b17023SJohn Marino /* Hash table for optimization flags and target option flags.  Use the same
188e4b17023SJohn Marino    hash table for both sets of options.  Nodes for building the current
189e4b17023SJohn Marino    optimization and target option nodes.  The assumption is most of the time
190e4b17023SJohn Marino    the options created will already be in the hash table, so we avoid
191e4b17023SJohn Marino    allocating and freeing up a node repeatably.  */
192e4b17023SJohn Marino static GTY (()) tree cl_optimization_node;
193e4b17023SJohn Marino static GTY (()) tree cl_target_option_node;
194e4b17023SJohn Marino static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
195e4b17023SJohn Marino      htab_t cl_option_hash_table;
196e4b17023SJohn Marino 
197e4b17023SJohn Marino /* General tree->tree mapping  structure for use in hash tables.  */
198e4b17023SJohn Marino 
199e4b17023SJohn Marino 
200e4b17023SJohn Marino static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_map)))
201e4b17023SJohn Marino      htab_t debug_expr_for_decl;
202e4b17023SJohn Marino 
203e4b17023SJohn Marino static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_map)))
204e4b17023SJohn Marino      htab_t value_expr_for_decl;
205e4b17023SJohn Marino 
206e4b17023SJohn Marino static GTY ((if_marked ("tree_vec_map_marked_p"), param_is (struct tree_vec_map)))
207e4b17023SJohn Marino      htab_t debug_args_for_decl;
208e4b17023SJohn Marino 
209e4b17023SJohn Marino static GTY ((if_marked ("tree_priority_map_marked_p"),
210e4b17023SJohn Marino 	     param_is (struct tree_priority_map)))
211e4b17023SJohn Marino   htab_t init_priority_for_decl;
212e4b17023SJohn Marino 
213e4b17023SJohn Marino static void set_type_quals (tree, int);
214e4b17023SJohn Marino static int type_hash_eq (const void *, const void *);
215e4b17023SJohn Marino static hashval_t type_hash_hash (const void *);
216e4b17023SJohn Marino static hashval_t int_cst_hash_hash (const void *);
217e4b17023SJohn Marino static int int_cst_hash_eq (const void *, const void *);
218e4b17023SJohn Marino static hashval_t cl_option_hash_hash (const void *);
219e4b17023SJohn Marino static int cl_option_hash_eq (const void *, const void *);
220e4b17023SJohn Marino static void print_type_hash_statistics (void);
221e4b17023SJohn Marino static void print_debug_expr_statistics (void);
222e4b17023SJohn Marino static void print_value_expr_statistics (void);
223e4b17023SJohn Marino static int type_hash_marked_p (const void *);
224e4b17023SJohn Marino static unsigned int type_hash_list (const_tree, hashval_t);
225e4b17023SJohn Marino static unsigned int attribute_hash_list (const_tree, hashval_t);
226e4b17023SJohn Marino 
227e4b17023SJohn Marino tree global_trees[TI_MAX];
228e4b17023SJohn Marino tree integer_types[itk_none];
229e4b17023SJohn Marino 
230e4b17023SJohn Marino unsigned char tree_contains_struct[MAX_TREE_CODES][64];
231e4b17023SJohn Marino 
232e4b17023SJohn Marino /* Number of operands for each OpenMP clause.  */
233e4b17023SJohn Marino unsigned const char omp_clause_num_ops[] =
234e4b17023SJohn Marino {
235e4b17023SJohn Marino   0, /* OMP_CLAUSE_ERROR  */
236e4b17023SJohn Marino   1, /* OMP_CLAUSE_PRIVATE  */
237e4b17023SJohn Marino   1, /* OMP_CLAUSE_SHARED  */
238e4b17023SJohn Marino   1, /* OMP_CLAUSE_FIRSTPRIVATE  */
239e4b17023SJohn Marino   2, /* OMP_CLAUSE_LASTPRIVATE  */
240e4b17023SJohn Marino   4, /* OMP_CLAUSE_REDUCTION  */
241e4b17023SJohn Marino   1, /* OMP_CLAUSE_COPYIN  */
242e4b17023SJohn Marino   1, /* OMP_CLAUSE_COPYPRIVATE  */
243e4b17023SJohn Marino   1, /* OMP_CLAUSE_IF  */
244e4b17023SJohn Marino   1, /* OMP_CLAUSE_NUM_THREADS  */
245e4b17023SJohn Marino   1, /* OMP_CLAUSE_SCHEDULE  */
246e4b17023SJohn Marino   0, /* OMP_CLAUSE_NOWAIT  */
247e4b17023SJohn Marino   0, /* OMP_CLAUSE_ORDERED  */
248e4b17023SJohn Marino   0, /* OMP_CLAUSE_DEFAULT  */
249e4b17023SJohn Marino   3, /* OMP_CLAUSE_COLLAPSE  */
250e4b17023SJohn Marino   0, /* OMP_CLAUSE_UNTIED   */
251e4b17023SJohn Marino   1, /* OMP_CLAUSE_FINAL  */
252e4b17023SJohn Marino   0  /* OMP_CLAUSE_MERGEABLE  */
253e4b17023SJohn Marino };
254e4b17023SJohn Marino 
255e4b17023SJohn Marino const char * const omp_clause_code_name[] =
256e4b17023SJohn Marino {
257e4b17023SJohn Marino   "error_clause",
258e4b17023SJohn Marino   "private",
259e4b17023SJohn Marino   "shared",
260e4b17023SJohn Marino   "firstprivate",
261e4b17023SJohn Marino   "lastprivate",
262e4b17023SJohn Marino   "reduction",
263e4b17023SJohn Marino   "copyin",
264e4b17023SJohn Marino   "copyprivate",
265e4b17023SJohn Marino   "if",
266e4b17023SJohn Marino   "num_threads",
267e4b17023SJohn Marino   "schedule",
268e4b17023SJohn Marino   "nowait",
269e4b17023SJohn Marino   "ordered",
270e4b17023SJohn Marino   "default",
271e4b17023SJohn Marino   "collapse",
272e4b17023SJohn Marino   "untied",
273e4b17023SJohn Marino   "final",
274e4b17023SJohn Marino   "mergeable"
275e4b17023SJohn Marino };
276e4b17023SJohn Marino 
277e4b17023SJohn Marino 
278e4b17023SJohn Marino /* Return the tree node structure used by tree code CODE.  */
279e4b17023SJohn Marino 
280e4b17023SJohn Marino static inline enum tree_node_structure_enum
tree_node_structure_for_code(enum tree_code code)281e4b17023SJohn Marino tree_node_structure_for_code (enum tree_code code)
282e4b17023SJohn Marino {
283e4b17023SJohn Marino   switch (TREE_CODE_CLASS (code))
284e4b17023SJohn Marino     {
285e4b17023SJohn Marino     case tcc_declaration:
286e4b17023SJohn Marino       {
287e4b17023SJohn Marino 	switch (code)
288e4b17023SJohn Marino 	  {
289e4b17023SJohn Marino 	  case FIELD_DECL:
290e4b17023SJohn Marino 	    return TS_FIELD_DECL;
291e4b17023SJohn Marino 	  case PARM_DECL:
292e4b17023SJohn Marino 	    return TS_PARM_DECL;
293e4b17023SJohn Marino 	  case VAR_DECL:
294e4b17023SJohn Marino 	    return TS_VAR_DECL;
295e4b17023SJohn Marino 	  case LABEL_DECL:
296e4b17023SJohn Marino 	    return TS_LABEL_DECL;
297e4b17023SJohn Marino 	  case RESULT_DECL:
298e4b17023SJohn Marino 	    return TS_RESULT_DECL;
299e4b17023SJohn Marino 	  case DEBUG_EXPR_DECL:
300e4b17023SJohn Marino 	    return TS_DECL_WRTL;
301e4b17023SJohn Marino 	  case CONST_DECL:
302e4b17023SJohn Marino 	    return TS_CONST_DECL;
303e4b17023SJohn Marino 	  case TYPE_DECL:
304e4b17023SJohn Marino 	    return TS_TYPE_DECL;
305e4b17023SJohn Marino 	  case FUNCTION_DECL:
306e4b17023SJohn Marino 	    return TS_FUNCTION_DECL;
307e4b17023SJohn Marino 	  case TRANSLATION_UNIT_DECL:
308e4b17023SJohn Marino 	    return TS_TRANSLATION_UNIT_DECL;
309e4b17023SJohn Marino 	  default:
310e4b17023SJohn Marino 	    return TS_DECL_NON_COMMON;
311e4b17023SJohn Marino 	  }
312e4b17023SJohn Marino       }
313e4b17023SJohn Marino     case tcc_type:
314e4b17023SJohn Marino       return TS_TYPE_NON_COMMON;
315e4b17023SJohn Marino     case tcc_reference:
316e4b17023SJohn Marino     case tcc_comparison:
317e4b17023SJohn Marino     case tcc_unary:
318e4b17023SJohn Marino     case tcc_binary:
319e4b17023SJohn Marino     case tcc_expression:
320e4b17023SJohn Marino     case tcc_statement:
321e4b17023SJohn Marino     case tcc_vl_exp:
322e4b17023SJohn Marino       return TS_EXP;
323e4b17023SJohn Marino     default:  /* tcc_constant and tcc_exceptional */
324e4b17023SJohn Marino       break;
325e4b17023SJohn Marino     }
326e4b17023SJohn Marino   switch (code)
327e4b17023SJohn Marino     {
328e4b17023SJohn Marino       /* tcc_constant cases.  */
329e4b17023SJohn Marino     case INTEGER_CST:		return TS_INT_CST;
330e4b17023SJohn Marino     case REAL_CST:		return TS_REAL_CST;
331e4b17023SJohn Marino     case FIXED_CST:		return TS_FIXED_CST;
332e4b17023SJohn Marino     case COMPLEX_CST:		return TS_COMPLEX;
333e4b17023SJohn Marino     case VECTOR_CST:		return TS_VECTOR;
334e4b17023SJohn Marino     case STRING_CST:		return TS_STRING;
335e4b17023SJohn Marino       /* tcc_exceptional cases.  */
336e4b17023SJohn Marino     case ERROR_MARK:		return TS_COMMON;
337e4b17023SJohn Marino     case IDENTIFIER_NODE:	return TS_IDENTIFIER;
338e4b17023SJohn Marino     case TREE_LIST:		return TS_LIST;
339e4b17023SJohn Marino     case TREE_VEC:		return TS_VEC;
340e4b17023SJohn Marino     case SSA_NAME:		return TS_SSA_NAME;
341e4b17023SJohn Marino     case PLACEHOLDER_EXPR:	return TS_COMMON;
342e4b17023SJohn Marino     case STATEMENT_LIST:	return TS_STATEMENT_LIST;
343e4b17023SJohn Marino     case BLOCK:			return TS_BLOCK;
344e4b17023SJohn Marino     case CONSTRUCTOR:		return TS_CONSTRUCTOR;
345e4b17023SJohn Marino     case TREE_BINFO:		return TS_BINFO;
346e4b17023SJohn Marino     case OMP_CLAUSE:		return TS_OMP_CLAUSE;
347e4b17023SJohn Marino     case OPTIMIZATION_NODE:	return TS_OPTIMIZATION;
348e4b17023SJohn Marino     case TARGET_OPTION_NODE:	return TS_TARGET_OPTION;
349e4b17023SJohn Marino 
350e4b17023SJohn Marino     default:
351e4b17023SJohn Marino       gcc_unreachable ();
352e4b17023SJohn Marino     }
353e4b17023SJohn Marino }
354e4b17023SJohn Marino 
355e4b17023SJohn Marino 
356e4b17023SJohn Marino /* Initialize tree_contains_struct to describe the hierarchy of tree
357e4b17023SJohn Marino    nodes.  */
358e4b17023SJohn Marino 
359e4b17023SJohn Marino static void
initialize_tree_contains_struct(void)360e4b17023SJohn Marino initialize_tree_contains_struct (void)
361e4b17023SJohn Marino {
362e4b17023SJohn Marino   unsigned i;
363e4b17023SJohn Marino 
364e4b17023SJohn Marino   for (i = ERROR_MARK; i < LAST_AND_UNUSED_TREE_CODE; i++)
365e4b17023SJohn Marino     {
366e4b17023SJohn Marino       enum tree_code code;
367e4b17023SJohn Marino       enum tree_node_structure_enum ts_code;
368e4b17023SJohn Marino 
369e4b17023SJohn Marino       code = (enum tree_code) i;
370e4b17023SJohn Marino       ts_code = tree_node_structure_for_code (code);
371e4b17023SJohn Marino 
372e4b17023SJohn Marino       /* Mark the TS structure itself.  */
373e4b17023SJohn Marino       tree_contains_struct[code][ts_code] = 1;
374e4b17023SJohn Marino 
375e4b17023SJohn Marino       /* Mark all the structures that TS is derived from.  */
376e4b17023SJohn Marino       switch (ts_code)
377e4b17023SJohn Marino 	{
378e4b17023SJohn Marino 	case TS_TYPED:
379e4b17023SJohn Marino 	case TS_BLOCK:
380e4b17023SJohn Marino 	  MARK_TS_BASE (code);
381e4b17023SJohn Marino 	  break;
382e4b17023SJohn Marino 
383e4b17023SJohn Marino 	case TS_COMMON:
384e4b17023SJohn Marino 	case TS_INT_CST:
385e4b17023SJohn Marino 	case TS_REAL_CST:
386e4b17023SJohn Marino 	case TS_FIXED_CST:
387e4b17023SJohn Marino 	case TS_VECTOR:
388e4b17023SJohn Marino 	case TS_STRING:
389e4b17023SJohn Marino 	case TS_COMPLEX:
390e4b17023SJohn Marino 	case TS_SSA_NAME:
391e4b17023SJohn Marino 	case TS_CONSTRUCTOR:
392e4b17023SJohn Marino 	case TS_EXP:
393e4b17023SJohn Marino 	case TS_STATEMENT_LIST:
394e4b17023SJohn Marino 	  MARK_TS_TYPED (code);
395e4b17023SJohn Marino 	  break;
396e4b17023SJohn Marino 
397e4b17023SJohn Marino 	case TS_IDENTIFIER:
398e4b17023SJohn Marino 	case TS_DECL_MINIMAL:
399e4b17023SJohn Marino 	case TS_TYPE_COMMON:
400e4b17023SJohn Marino 	case TS_LIST:
401e4b17023SJohn Marino 	case TS_VEC:
402e4b17023SJohn Marino 	case TS_BINFO:
403e4b17023SJohn Marino 	case TS_OMP_CLAUSE:
404e4b17023SJohn Marino 	case TS_OPTIMIZATION:
405e4b17023SJohn Marino 	case TS_TARGET_OPTION:
406e4b17023SJohn Marino 	  MARK_TS_COMMON (code);
407e4b17023SJohn Marino 	  break;
408e4b17023SJohn Marino 
409e4b17023SJohn Marino 	case TS_TYPE_WITH_LANG_SPECIFIC:
410e4b17023SJohn Marino 	  MARK_TS_TYPE_COMMON (code);
411e4b17023SJohn Marino 	  break;
412e4b17023SJohn Marino 
413e4b17023SJohn Marino 	case TS_TYPE_NON_COMMON:
414e4b17023SJohn Marino 	  MARK_TS_TYPE_WITH_LANG_SPECIFIC (code);
415e4b17023SJohn Marino 	  break;
416e4b17023SJohn Marino 
417e4b17023SJohn Marino 	case TS_DECL_COMMON:
418e4b17023SJohn Marino 	  MARK_TS_DECL_MINIMAL (code);
419e4b17023SJohn Marino 	  break;
420e4b17023SJohn Marino 
421e4b17023SJohn Marino 	case TS_DECL_WRTL:
422e4b17023SJohn Marino 	case TS_CONST_DECL:
423e4b17023SJohn Marino 	  MARK_TS_DECL_COMMON (code);
424e4b17023SJohn Marino 	  break;
425e4b17023SJohn Marino 
426e4b17023SJohn Marino 	case TS_DECL_NON_COMMON:
427e4b17023SJohn Marino 	  MARK_TS_DECL_WITH_VIS (code);
428e4b17023SJohn Marino 	  break;
429e4b17023SJohn Marino 
430e4b17023SJohn Marino 	case TS_DECL_WITH_VIS:
431e4b17023SJohn Marino 	case TS_PARM_DECL:
432e4b17023SJohn Marino 	case TS_LABEL_DECL:
433e4b17023SJohn Marino 	case TS_RESULT_DECL:
434e4b17023SJohn Marino 	  MARK_TS_DECL_WRTL (code);
435e4b17023SJohn Marino 	  break;
436e4b17023SJohn Marino 
437e4b17023SJohn Marino 	case TS_FIELD_DECL:
438e4b17023SJohn Marino 	  MARK_TS_DECL_COMMON (code);
439e4b17023SJohn Marino 	  break;
440e4b17023SJohn Marino 
441e4b17023SJohn Marino 	case TS_VAR_DECL:
442e4b17023SJohn Marino 	  MARK_TS_DECL_WITH_VIS (code);
443e4b17023SJohn Marino 	  break;
444e4b17023SJohn Marino 
445e4b17023SJohn Marino 	case TS_TYPE_DECL:
446e4b17023SJohn Marino 	case TS_FUNCTION_DECL:
447e4b17023SJohn Marino 	  MARK_TS_DECL_NON_COMMON (code);
448e4b17023SJohn Marino 	  break;
449e4b17023SJohn Marino 
450e4b17023SJohn Marino 	case TS_TRANSLATION_UNIT_DECL:
451e4b17023SJohn Marino 	  MARK_TS_DECL_COMMON (code);
452e4b17023SJohn Marino 	  break;
453e4b17023SJohn Marino 
454e4b17023SJohn Marino 	default:
455e4b17023SJohn Marino 	  gcc_unreachable ();
456e4b17023SJohn Marino 	}
457e4b17023SJohn Marino     }
458e4b17023SJohn Marino 
459e4b17023SJohn Marino   /* Basic consistency checks for attributes used in fold.  */
460e4b17023SJohn Marino   gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_NON_COMMON]);
461e4b17023SJohn Marino   gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_NON_COMMON]);
462e4b17023SJohn Marino   gcc_assert (tree_contains_struct[CONST_DECL][TS_DECL_COMMON]);
463e4b17023SJohn Marino   gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_COMMON]);
464e4b17023SJohn Marino   gcc_assert (tree_contains_struct[PARM_DECL][TS_DECL_COMMON]);
465e4b17023SJohn Marino   gcc_assert (tree_contains_struct[RESULT_DECL][TS_DECL_COMMON]);
466e4b17023SJohn Marino   gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_COMMON]);
467e4b17023SJohn Marino   gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_COMMON]);
468e4b17023SJohn Marino   gcc_assert (tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_COMMON]);
469e4b17023SJohn Marino   gcc_assert (tree_contains_struct[LABEL_DECL][TS_DECL_COMMON]);
470e4b17023SJohn Marino   gcc_assert (tree_contains_struct[FIELD_DECL][TS_DECL_COMMON]);
471e4b17023SJohn Marino   gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_WRTL]);
472e4b17023SJohn Marino   gcc_assert (tree_contains_struct[PARM_DECL][TS_DECL_WRTL]);
473e4b17023SJohn Marino   gcc_assert (tree_contains_struct[RESULT_DECL][TS_DECL_WRTL]);
474e4b17023SJohn Marino   gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_WRTL]);
475e4b17023SJohn Marino   gcc_assert (tree_contains_struct[LABEL_DECL][TS_DECL_WRTL]);
476e4b17023SJohn Marino   gcc_assert (tree_contains_struct[CONST_DECL][TS_DECL_MINIMAL]);
477e4b17023SJohn Marino   gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_MINIMAL]);
478e4b17023SJohn Marino   gcc_assert (tree_contains_struct[PARM_DECL][TS_DECL_MINIMAL]);
479e4b17023SJohn Marino   gcc_assert (tree_contains_struct[RESULT_DECL][TS_DECL_MINIMAL]);
480e4b17023SJohn Marino   gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_MINIMAL]);
481e4b17023SJohn Marino   gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_MINIMAL]);
482e4b17023SJohn Marino   gcc_assert (tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_MINIMAL]);
483e4b17023SJohn Marino   gcc_assert (tree_contains_struct[LABEL_DECL][TS_DECL_MINIMAL]);
484e4b17023SJohn Marino   gcc_assert (tree_contains_struct[FIELD_DECL][TS_DECL_MINIMAL]);
485e4b17023SJohn Marino   gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_WITH_VIS]);
486e4b17023SJohn Marino   gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_DECL_WITH_VIS]);
487e4b17023SJohn Marino   gcc_assert (tree_contains_struct[TYPE_DECL][TS_DECL_WITH_VIS]);
488e4b17023SJohn Marino   gcc_assert (tree_contains_struct[VAR_DECL][TS_VAR_DECL]);
489e4b17023SJohn Marino   gcc_assert (tree_contains_struct[FIELD_DECL][TS_FIELD_DECL]);
490e4b17023SJohn Marino   gcc_assert (tree_contains_struct[PARM_DECL][TS_PARM_DECL]);
491e4b17023SJohn Marino   gcc_assert (tree_contains_struct[LABEL_DECL][TS_LABEL_DECL]);
492e4b17023SJohn Marino   gcc_assert (tree_contains_struct[RESULT_DECL][TS_RESULT_DECL]);
493e4b17023SJohn Marino   gcc_assert (tree_contains_struct[CONST_DECL][TS_CONST_DECL]);
494e4b17023SJohn Marino   gcc_assert (tree_contains_struct[TYPE_DECL][TS_TYPE_DECL]);
495e4b17023SJohn Marino   gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL]);
496e4b17023SJohn Marino   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL]);
497e4b17023SJohn Marino   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON]);
498e4b17023SJohn Marino }
499e4b17023SJohn Marino 
500e4b17023SJohn Marino 
501e4b17023SJohn Marino /* Init tree.c.  */
502e4b17023SJohn Marino 
503e4b17023SJohn Marino void
init_ttree(void)504e4b17023SJohn Marino init_ttree (void)
505e4b17023SJohn Marino {
506e4b17023SJohn Marino   /* Initialize the hash table of types.  */
507e4b17023SJohn Marino   type_hash_table = htab_create_ggc (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
508e4b17023SJohn Marino 				     type_hash_eq, 0);
509e4b17023SJohn Marino 
510e4b17023SJohn Marino   debug_expr_for_decl = htab_create_ggc (512, tree_decl_map_hash,
511e4b17023SJohn Marino 					 tree_decl_map_eq, 0);
512e4b17023SJohn Marino 
513e4b17023SJohn Marino   value_expr_for_decl = htab_create_ggc (512, tree_decl_map_hash,
514e4b17023SJohn Marino 					 tree_decl_map_eq, 0);
515e4b17023SJohn Marino   init_priority_for_decl = htab_create_ggc (512, tree_priority_map_hash,
516e4b17023SJohn Marino 					    tree_priority_map_eq, 0);
517e4b17023SJohn Marino 
518e4b17023SJohn Marino   int_cst_hash_table = htab_create_ggc (1024, int_cst_hash_hash,
519e4b17023SJohn Marino 					int_cst_hash_eq, NULL);
520e4b17023SJohn Marino 
521e4b17023SJohn Marino   int_cst_node = make_node (INTEGER_CST);
522e4b17023SJohn Marino 
523e4b17023SJohn Marino   cl_option_hash_table = htab_create_ggc (64, cl_option_hash_hash,
524e4b17023SJohn Marino 					  cl_option_hash_eq, NULL);
525e4b17023SJohn Marino 
526e4b17023SJohn Marino   cl_optimization_node = make_node (OPTIMIZATION_NODE);
527e4b17023SJohn Marino   cl_target_option_node = make_node (TARGET_OPTION_NODE);
528e4b17023SJohn Marino 
529e4b17023SJohn Marino   /* Initialize the tree_contains_struct array.  */
530e4b17023SJohn Marino   initialize_tree_contains_struct ();
531e4b17023SJohn Marino   lang_hooks.init_ts ();
532e4b17023SJohn Marino }
533e4b17023SJohn Marino 
534e4b17023SJohn Marino 
535e4b17023SJohn Marino /* The name of the object as the assembler will see it (but before any
536e4b17023SJohn Marino    translations made by ASM_OUTPUT_LABELREF).  Often this is the same
537e4b17023SJohn Marino    as DECL_NAME.  It is an IDENTIFIER_NODE.  */
538e4b17023SJohn Marino tree
decl_assembler_name(tree decl)539e4b17023SJohn Marino decl_assembler_name (tree decl)
540e4b17023SJohn Marino {
541e4b17023SJohn Marino   if (!DECL_ASSEMBLER_NAME_SET_P (decl))
542e4b17023SJohn Marino     lang_hooks.set_decl_assembler_name (decl);
543e4b17023SJohn Marino   return DECL_WITH_VIS_CHECK (decl)->decl_with_vis.assembler_name;
544e4b17023SJohn Marino }
545e4b17023SJohn Marino 
546e4b17023SJohn Marino /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL.  */
547e4b17023SJohn Marino 
548e4b17023SJohn Marino bool
decl_assembler_name_equal(tree decl,const_tree asmname)549e4b17023SJohn Marino decl_assembler_name_equal (tree decl, const_tree asmname)
550e4b17023SJohn Marino {
551e4b17023SJohn Marino   tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
552e4b17023SJohn Marino   const char *decl_str;
553e4b17023SJohn Marino   const char *asmname_str;
554e4b17023SJohn Marino   bool test = false;
555e4b17023SJohn Marino 
556e4b17023SJohn Marino   if (decl_asmname == asmname)
557e4b17023SJohn Marino     return true;
558e4b17023SJohn Marino 
559e4b17023SJohn Marino   decl_str = IDENTIFIER_POINTER (decl_asmname);
560e4b17023SJohn Marino   asmname_str = IDENTIFIER_POINTER (asmname);
561e4b17023SJohn Marino 
562e4b17023SJohn Marino 
563e4b17023SJohn Marino   /* If the target assembler name was set by the user, things are trickier.
564e4b17023SJohn Marino      We have a leading '*' to begin with.  After that, it's arguable what
565e4b17023SJohn Marino      is the correct thing to do with -fleading-underscore.  Arguably, we've
566e4b17023SJohn Marino      historically been doing the wrong thing in assemble_alias by always
567e4b17023SJohn Marino      printing the leading underscore.  Since we're not changing that, make
568e4b17023SJohn Marino      sure user_label_prefix follows the '*' before matching.  */
569e4b17023SJohn Marino   if (decl_str[0] == '*')
570e4b17023SJohn Marino     {
571e4b17023SJohn Marino       size_t ulp_len = strlen (user_label_prefix);
572e4b17023SJohn Marino 
573e4b17023SJohn Marino       decl_str ++;
574e4b17023SJohn Marino 
575e4b17023SJohn Marino       if (ulp_len == 0)
576e4b17023SJohn Marino 	test = true;
577e4b17023SJohn Marino       else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
578e4b17023SJohn Marino 	decl_str += ulp_len, test=true;
579e4b17023SJohn Marino       else
580e4b17023SJohn Marino 	decl_str --;
581e4b17023SJohn Marino     }
582e4b17023SJohn Marino   if (asmname_str[0] == '*')
583e4b17023SJohn Marino     {
584e4b17023SJohn Marino       size_t ulp_len = strlen (user_label_prefix);
585e4b17023SJohn Marino 
586e4b17023SJohn Marino       asmname_str ++;
587e4b17023SJohn Marino 
588e4b17023SJohn Marino       if (ulp_len == 0)
589e4b17023SJohn Marino 	test = true;
590e4b17023SJohn Marino       else if (strncmp (asmname_str, user_label_prefix, ulp_len) == 0)
591e4b17023SJohn Marino 	asmname_str += ulp_len, test=true;
592e4b17023SJohn Marino       else
593e4b17023SJohn Marino 	asmname_str --;
594e4b17023SJohn Marino     }
595e4b17023SJohn Marino 
596e4b17023SJohn Marino   if (!test)
597e4b17023SJohn Marino     return false;
598e4b17023SJohn Marino   return strcmp (decl_str, asmname_str) == 0;
599e4b17023SJohn Marino }
600e4b17023SJohn Marino 
601e4b17023SJohn Marino /* Hash asmnames ignoring the user specified marks.  */
602e4b17023SJohn Marino 
603e4b17023SJohn Marino hashval_t
decl_assembler_name_hash(const_tree asmname)604e4b17023SJohn Marino decl_assembler_name_hash (const_tree asmname)
605e4b17023SJohn Marino {
606e4b17023SJohn Marino   if (IDENTIFIER_POINTER (asmname)[0] == '*')
607e4b17023SJohn Marino     {
608e4b17023SJohn Marino       const char *decl_str = IDENTIFIER_POINTER (asmname) + 1;
609e4b17023SJohn Marino       size_t ulp_len = strlen (user_label_prefix);
610e4b17023SJohn Marino 
611e4b17023SJohn Marino       if (ulp_len == 0)
612e4b17023SJohn Marino 	;
613e4b17023SJohn Marino       else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
614e4b17023SJohn Marino 	decl_str += ulp_len;
615e4b17023SJohn Marino 
616e4b17023SJohn Marino       return htab_hash_string (decl_str);
617e4b17023SJohn Marino     }
618e4b17023SJohn Marino 
619e4b17023SJohn Marino   return htab_hash_string (IDENTIFIER_POINTER (asmname));
620e4b17023SJohn Marino }
621e4b17023SJohn Marino 
622e4b17023SJohn Marino /* Compute the number of bytes occupied by a tree with code CODE.
623e4b17023SJohn Marino    This function cannot be used for nodes that have variable sizes,
624e4b17023SJohn Marino    including TREE_VEC, STRING_CST, and CALL_EXPR.  */
625e4b17023SJohn Marino size_t
tree_code_size(enum tree_code code)626e4b17023SJohn Marino tree_code_size (enum tree_code code)
627e4b17023SJohn Marino {
628e4b17023SJohn Marino   switch (TREE_CODE_CLASS (code))
629e4b17023SJohn Marino     {
630e4b17023SJohn Marino     case tcc_declaration:  /* A decl node */
631e4b17023SJohn Marino       {
632e4b17023SJohn Marino 	switch (code)
633e4b17023SJohn Marino 	  {
634e4b17023SJohn Marino 	  case FIELD_DECL:
635e4b17023SJohn Marino 	    return sizeof (struct tree_field_decl);
636e4b17023SJohn Marino 	  case PARM_DECL:
637e4b17023SJohn Marino 	    return sizeof (struct tree_parm_decl);
638e4b17023SJohn Marino 	  case VAR_DECL:
639e4b17023SJohn Marino 	    return sizeof (struct tree_var_decl);
640e4b17023SJohn Marino 	  case LABEL_DECL:
641e4b17023SJohn Marino 	    return sizeof (struct tree_label_decl);
642e4b17023SJohn Marino 	  case RESULT_DECL:
643e4b17023SJohn Marino 	    return sizeof (struct tree_result_decl);
644e4b17023SJohn Marino 	  case CONST_DECL:
645e4b17023SJohn Marino 	    return sizeof (struct tree_const_decl);
646e4b17023SJohn Marino 	  case TYPE_DECL:
647e4b17023SJohn Marino 	    return sizeof (struct tree_type_decl);
648e4b17023SJohn Marino 	  case FUNCTION_DECL:
649e4b17023SJohn Marino 	    return sizeof (struct tree_function_decl);
650e4b17023SJohn Marino 	  case DEBUG_EXPR_DECL:
651e4b17023SJohn Marino 	    return sizeof (struct tree_decl_with_rtl);
652e4b17023SJohn Marino 	  default:
653e4b17023SJohn Marino 	    return sizeof (struct tree_decl_non_common);
654e4b17023SJohn Marino 	  }
655e4b17023SJohn Marino       }
656e4b17023SJohn Marino 
657e4b17023SJohn Marino     case tcc_type:  /* a type node */
658e4b17023SJohn Marino       return sizeof (struct tree_type_non_common);
659e4b17023SJohn Marino 
660e4b17023SJohn Marino     case tcc_reference:   /* a reference */
661e4b17023SJohn Marino     case tcc_expression:  /* an expression */
662e4b17023SJohn Marino     case tcc_statement:   /* an expression with side effects */
663e4b17023SJohn Marino     case tcc_comparison:  /* a comparison expression */
664e4b17023SJohn Marino     case tcc_unary:       /* a unary arithmetic expression */
665e4b17023SJohn Marino     case tcc_binary:      /* a binary arithmetic expression */
666e4b17023SJohn Marino       return (sizeof (struct tree_exp)
667e4b17023SJohn Marino 	      + (TREE_CODE_LENGTH (code) - 1) * sizeof (tree));
668e4b17023SJohn Marino 
669e4b17023SJohn Marino     case tcc_constant:  /* a constant */
670e4b17023SJohn Marino       switch (code)
671e4b17023SJohn Marino 	{
672e4b17023SJohn Marino 	case INTEGER_CST:	return sizeof (struct tree_int_cst);
673e4b17023SJohn Marino 	case REAL_CST:		return sizeof (struct tree_real_cst);
674e4b17023SJohn Marino 	case FIXED_CST:		return sizeof (struct tree_fixed_cst);
675e4b17023SJohn Marino 	case COMPLEX_CST:	return sizeof (struct tree_complex);
676e4b17023SJohn Marino 	case VECTOR_CST:	return sizeof (struct tree_vector);
677e4b17023SJohn Marino 	case STRING_CST:	gcc_unreachable ();
678e4b17023SJohn Marino 	default:
679e4b17023SJohn Marino 	  return lang_hooks.tree_size (code);
680e4b17023SJohn Marino 	}
681e4b17023SJohn Marino 
682e4b17023SJohn Marino     case tcc_exceptional:  /* something random, like an identifier.  */
683e4b17023SJohn Marino       switch (code)
684e4b17023SJohn Marino 	{
685e4b17023SJohn Marino 	case IDENTIFIER_NODE:	return lang_hooks.identifier_size;
686e4b17023SJohn Marino 	case TREE_LIST:		return sizeof (struct tree_list);
687e4b17023SJohn Marino 
688e4b17023SJohn Marino 	case ERROR_MARK:
689e4b17023SJohn Marino 	case PLACEHOLDER_EXPR:	return sizeof (struct tree_common);
690e4b17023SJohn Marino 
691e4b17023SJohn Marino 	case TREE_VEC:
692e4b17023SJohn Marino 	case OMP_CLAUSE:	gcc_unreachable ();
693e4b17023SJohn Marino 
694e4b17023SJohn Marino 	case SSA_NAME:		return sizeof (struct tree_ssa_name);
695e4b17023SJohn Marino 
696e4b17023SJohn Marino 	case STATEMENT_LIST:	return sizeof (struct tree_statement_list);
697e4b17023SJohn Marino 	case BLOCK:		return sizeof (struct tree_block);
698e4b17023SJohn Marino 	case CONSTRUCTOR:	return sizeof (struct tree_constructor);
699e4b17023SJohn Marino 	case OPTIMIZATION_NODE: return sizeof (struct tree_optimization_option);
700e4b17023SJohn Marino 	case TARGET_OPTION_NODE: return sizeof (struct tree_target_option);
701e4b17023SJohn Marino 
702e4b17023SJohn Marino 	default:
703e4b17023SJohn Marino 	  return lang_hooks.tree_size (code);
704e4b17023SJohn Marino 	}
705e4b17023SJohn Marino 
706e4b17023SJohn Marino     default:
707e4b17023SJohn Marino       gcc_unreachable ();
708e4b17023SJohn Marino     }
709e4b17023SJohn Marino }
710e4b17023SJohn Marino 
711e4b17023SJohn Marino /* Compute the number of bytes occupied by NODE.  This routine only
712e4b17023SJohn Marino    looks at TREE_CODE, except for those nodes that have variable sizes.  */
713e4b17023SJohn Marino size_t
tree_size(const_tree node)714e4b17023SJohn Marino tree_size (const_tree node)
715e4b17023SJohn Marino {
716e4b17023SJohn Marino   const enum tree_code code = TREE_CODE (node);
717e4b17023SJohn Marino   switch (code)
718e4b17023SJohn Marino     {
719e4b17023SJohn Marino     case TREE_BINFO:
720e4b17023SJohn Marino       return (offsetof (struct tree_binfo, base_binfos)
721e4b17023SJohn Marino 	      + VEC_embedded_size (tree, BINFO_N_BASE_BINFOS (node)));
722e4b17023SJohn Marino 
723e4b17023SJohn Marino     case TREE_VEC:
724e4b17023SJohn Marino       return (sizeof (struct tree_vec)
725e4b17023SJohn Marino 	      + (TREE_VEC_LENGTH (node) - 1) * sizeof (tree));
726e4b17023SJohn Marino 
727e4b17023SJohn Marino     case STRING_CST:
728e4b17023SJohn Marino       return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 1;
729e4b17023SJohn Marino 
730e4b17023SJohn Marino     case OMP_CLAUSE:
731e4b17023SJohn Marino       return (sizeof (struct tree_omp_clause)
732e4b17023SJohn Marino 	      + (omp_clause_num_ops[OMP_CLAUSE_CODE (node)] - 1)
733e4b17023SJohn Marino 	        * sizeof (tree));
734e4b17023SJohn Marino 
735e4b17023SJohn Marino     default:
736e4b17023SJohn Marino       if (TREE_CODE_CLASS (code) == tcc_vl_exp)
737e4b17023SJohn Marino 	return (sizeof (struct tree_exp)
738e4b17023SJohn Marino 		+ (VL_EXP_OPERAND_LENGTH (node) - 1) * sizeof (tree));
739e4b17023SJohn Marino       else
740e4b17023SJohn Marino 	return tree_code_size (code);
741e4b17023SJohn Marino     }
742e4b17023SJohn Marino }
743e4b17023SJohn Marino 
744e4b17023SJohn Marino /* Record interesting allocation statistics for a tree node with CODE
745e4b17023SJohn Marino    and LENGTH.  */
746e4b17023SJohn Marino 
747e4b17023SJohn Marino static void
record_node_allocation_statistics(enum tree_code code ATTRIBUTE_UNUSED,size_t length ATTRIBUTE_UNUSED)748e4b17023SJohn Marino record_node_allocation_statistics (enum tree_code code ATTRIBUTE_UNUSED,
749e4b17023SJohn Marino 				   size_t length ATTRIBUTE_UNUSED)
750e4b17023SJohn Marino {
751e4b17023SJohn Marino #ifdef GATHER_STATISTICS
752e4b17023SJohn Marino   enum tree_code_class type = TREE_CODE_CLASS (code);
753e4b17023SJohn Marino   tree_node_kind kind;
754e4b17023SJohn Marino 
755e4b17023SJohn Marino   switch (type)
756e4b17023SJohn Marino     {
757e4b17023SJohn Marino     case tcc_declaration:  /* A decl node */
758e4b17023SJohn Marino       kind = d_kind;
759e4b17023SJohn Marino       break;
760e4b17023SJohn Marino 
761e4b17023SJohn Marino     case tcc_type:  /* a type node */
762e4b17023SJohn Marino       kind = t_kind;
763e4b17023SJohn Marino       break;
764e4b17023SJohn Marino 
765e4b17023SJohn Marino     case tcc_statement:  /* an expression with side effects */
766e4b17023SJohn Marino       kind = s_kind;
767e4b17023SJohn Marino       break;
768e4b17023SJohn Marino 
769e4b17023SJohn Marino     case tcc_reference:  /* a reference */
770e4b17023SJohn Marino       kind = r_kind;
771e4b17023SJohn Marino       break;
772e4b17023SJohn Marino 
773e4b17023SJohn Marino     case tcc_expression:  /* an expression */
774e4b17023SJohn Marino     case tcc_comparison:  /* a comparison expression */
775e4b17023SJohn Marino     case tcc_unary:  /* a unary arithmetic expression */
776e4b17023SJohn Marino     case tcc_binary:  /* a binary arithmetic expression */
777e4b17023SJohn Marino       kind = e_kind;
778e4b17023SJohn Marino       break;
779e4b17023SJohn Marino 
780e4b17023SJohn Marino     case tcc_constant:  /* a constant */
781e4b17023SJohn Marino       kind = c_kind;
782e4b17023SJohn Marino       break;
783e4b17023SJohn Marino 
784e4b17023SJohn Marino     case tcc_exceptional:  /* something random, like an identifier.  */
785e4b17023SJohn Marino       switch (code)
786e4b17023SJohn Marino 	{
787e4b17023SJohn Marino 	case IDENTIFIER_NODE:
788e4b17023SJohn Marino 	  kind = id_kind;
789e4b17023SJohn Marino 	  break;
790e4b17023SJohn Marino 
791e4b17023SJohn Marino 	case TREE_VEC:
792e4b17023SJohn Marino 	  kind = vec_kind;
793e4b17023SJohn Marino 	  break;
794e4b17023SJohn Marino 
795e4b17023SJohn Marino 	case TREE_BINFO:
796e4b17023SJohn Marino 	  kind = binfo_kind;
797e4b17023SJohn Marino 	  break;
798e4b17023SJohn Marino 
799e4b17023SJohn Marino 	case SSA_NAME:
800e4b17023SJohn Marino 	  kind = ssa_name_kind;
801e4b17023SJohn Marino 	  break;
802e4b17023SJohn Marino 
803e4b17023SJohn Marino 	case BLOCK:
804e4b17023SJohn Marino 	  kind = b_kind;
805e4b17023SJohn Marino 	  break;
806e4b17023SJohn Marino 
807e4b17023SJohn Marino 	case CONSTRUCTOR:
808e4b17023SJohn Marino 	  kind = constr_kind;
809e4b17023SJohn Marino 	  break;
810e4b17023SJohn Marino 
811e4b17023SJohn Marino 	case OMP_CLAUSE:
812e4b17023SJohn Marino 	  kind = omp_clause_kind;
813e4b17023SJohn Marino 	  break;
814e4b17023SJohn Marino 
815e4b17023SJohn Marino 	default:
816e4b17023SJohn Marino 	  kind = x_kind;
817e4b17023SJohn Marino 	  break;
818e4b17023SJohn Marino 	}
819e4b17023SJohn Marino       break;
820e4b17023SJohn Marino 
821e4b17023SJohn Marino     case tcc_vl_exp:
822e4b17023SJohn Marino       kind = e_kind;
823e4b17023SJohn Marino       break;
824e4b17023SJohn Marino 
825e4b17023SJohn Marino     default:
826e4b17023SJohn Marino       gcc_unreachable ();
827e4b17023SJohn Marino     }
828e4b17023SJohn Marino 
829e4b17023SJohn Marino   tree_code_counts[(int) code]++;
830e4b17023SJohn Marino   tree_node_counts[(int) kind]++;
831e4b17023SJohn Marino   tree_node_sizes[(int) kind] += length;
832e4b17023SJohn Marino #endif
833e4b17023SJohn Marino }
834e4b17023SJohn Marino 
835e4b17023SJohn Marino /* Allocate and return a new UID from the DECL_UID namespace.  */
836e4b17023SJohn Marino 
837e4b17023SJohn Marino int
allocate_decl_uid(void)838e4b17023SJohn Marino allocate_decl_uid (void)
839e4b17023SJohn Marino {
840e4b17023SJohn Marino   return next_decl_uid++;
841e4b17023SJohn Marino }
842e4b17023SJohn Marino 
843e4b17023SJohn Marino /* Return a newly allocated node of code CODE.  For decl and type
844e4b17023SJohn Marino    nodes, some other fields are initialized.  The rest of the node is
845e4b17023SJohn Marino    initialized to zero.  This function cannot be used for TREE_VEC or
846e4b17023SJohn Marino    OMP_CLAUSE nodes, which is enforced by asserts in tree_code_size.
847e4b17023SJohn Marino 
848e4b17023SJohn Marino    Achoo!  I got a code in the node.  */
849e4b17023SJohn Marino 
850e4b17023SJohn Marino tree
make_node_stat(enum tree_code code MEM_STAT_DECL)851e4b17023SJohn Marino make_node_stat (enum tree_code code MEM_STAT_DECL)
852e4b17023SJohn Marino {
853e4b17023SJohn Marino   tree t;
854e4b17023SJohn Marino   enum tree_code_class type = TREE_CODE_CLASS (code);
855e4b17023SJohn Marino   size_t length = tree_code_size (code);
856e4b17023SJohn Marino 
857e4b17023SJohn Marino   record_node_allocation_statistics (code, length);
858e4b17023SJohn Marino 
859e4b17023SJohn Marino   t = ggc_alloc_zone_cleared_tree_node_stat (
860e4b17023SJohn Marino                (code == IDENTIFIER_NODE) ? &tree_id_zone : &tree_zone,
861e4b17023SJohn Marino                length PASS_MEM_STAT);
862e4b17023SJohn Marino   TREE_SET_CODE (t, code);
863e4b17023SJohn Marino 
864e4b17023SJohn Marino   switch (type)
865e4b17023SJohn Marino     {
866e4b17023SJohn Marino     case tcc_statement:
867e4b17023SJohn Marino       TREE_SIDE_EFFECTS (t) = 1;
868e4b17023SJohn Marino       break;
869e4b17023SJohn Marino 
870e4b17023SJohn Marino     case tcc_declaration:
871e4b17023SJohn Marino       if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
872e4b17023SJohn Marino 	{
873e4b17023SJohn Marino 	  if (code == FUNCTION_DECL)
874e4b17023SJohn Marino 	    {
875e4b17023SJohn Marino 	      DECL_ALIGN (t) = FUNCTION_BOUNDARY;
876e4b17023SJohn Marino 	      DECL_MODE (t) = FUNCTION_MODE;
877e4b17023SJohn Marino 	    }
878e4b17023SJohn Marino 	  else
879e4b17023SJohn Marino 	    DECL_ALIGN (t) = 1;
880e4b17023SJohn Marino 	}
881e4b17023SJohn Marino       DECL_SOURCE_LOCATION (t) = input_location;
882e4b17023SJohn Marino       if (TREE_CODE (t) == DEBUG_EXPR_DECL)
883e4b17023SJohn Marino 	DECL_UID (t) = --next_debug_decl_uid;
884e4b17023SJohn Marino       else
885e4b17023SJohn Marino 	{
886e4b17023SJohn Marino 	  DECL_UID (t) = allocate_decl_uid ();
887e4b17023SJohn Marino 	  SET_DECL_PT_UID (t, -1);
888e4b17023SJohn Marino 	}
889e4b17023SJohn Marino       if (TREE_CODE (t) == LABEL_DECL)
890e4b17023SJohn Marino 	LABEL_DECL_UID (t) = -1;
891e4b17023SJohn Marino 
892e4b17023SJohn Marino       break;
893e4b17023SJohn Marino 
894e4b17023SJohn Marino     case tcc_type:
895e4b17023SJohn Marino       TYPE_UID (t) = next_type_uid++;
896e4b17023SJohn Marino       TYPE_ALIGN (t) = BITS_PER_UNIT;
897e4b17023SJohn Marino       TYPE_USER_ALIGN (t) = 0;
898e4b17023SJohn Marino       TYPE_MAIN_VARIANT (t) = t;
899e4b17023SJohn Marino       TYPE_CANONICAL (t) = t;
900e4b17023SJohn Marino 
901e4b17023SJohn Marino       /* Default to no attributes for type, but let target change that.  */
902e4b17023SJohn Marino       TYPE_ATTRIBUTES (t) = NULL_TREE;
903e4b17023SJohn Marino       targetm.set_default_type_attributes (t);
904e4b17023SJohn Marino 
905e4b17023SJohn Marino       /* We have not yet computed the alias set for this type.  */
906e4b17023SJohn Marino       TYPE_ALIAS_SET (t) = -1;
907e4b17023SJohn Marino       break;
908e4b17023SJohn Marino 
909e4b17023SJohn Marino     case tcc_constant:
910e4b17023SJohn Marino       TREE_CONSTANT (t) = 1;
911e4b17023SJohn Marino       break;
912e4b17023SJohn Marino 
913e4b17023SJohn Marino     case tcc_expression:
914e4b17023SJohn Marino       switch (code)
915e4b17023SJohn Marino 	{
916e4b17023SJohn Marino 	case INIT_EXPR:
917e4b17023SJohn Marino 	case MODIFY_EXPR:
918e4b17023SJohn Marino 	case VA_ARG_EXPR:
919e4b17023SJohn Marino 	case PREDECREMENT_EXPR:
920e4b17023SJohn Marino 	case PREINCREMENT_EXPR:
921e4b17023SJohn Marino 	case POSTDECREMENT_EXPR:
922e4b17023SJohn Marino 	case POSTINCREMENT_EXPR:
923e4b17023SJohn Marino 	  /* All of these have side-effects, no matter what their
924e4b17023SJohn Marino 	     operands are.  */
925e4b17023SJohn Marino 	  TREE_SIDE_EFFECTS (t) = 1;
926e4b17023SJohn Marino 	  break;
927e4b17023SJohn Marino 
928e4b17023SJohn Marino 	default:
929e4b17023SJohn Marino 	  break;
930e4b17023SJohn Marino 	}
931e4b17023SJohn Marino       break;
932e4b17023SJohn Marino 
933e4b17023SJohn Marino     default:
934e4b17023SJohn Marino       /* Other classes need no special treatment.  */
935e4b17023SJohn Marino       break;
936e4b17023SJohn Marino     }
937e4b17023SJohn Marino 
938e4b17023SJohn Marino   return t;
939e4b17023SJohn Marino }
940e4b17023SJohn Marino 
941e4b17023SJohn Marino /* Return a new node with the same contents as NODE except that its
942e4b17023SJohn Marino    TREE_CHAIN, if it has one, is zero and it has a fresh uid.  */
943e4b17023SJohn Marino 
944e4b17023SJohn Marino tree
copy_node_stat(tree node MEM_STAT_DECL)945e4b17023SJohn Marino copy_node_stat (tree node MEM_STAT_DECL)
946e4b17023SJohn Marino {
947e4b17023SJohn Marino   tree t;
948e4b17023SJohn Marino   enum tree_code code = TREE_CODE (node);
949e4b17023SJohn Marino   size_t length;
950e4b17023SJohn Marino 
951e4b17023SJohn Marino   gcc_assert (code != STATEMENT_LIST);
952e4b17023SJohn Marino 
953e4b17023SJohn Marino   length = tree_size (node);
954e4b17023SJohn Marino   record_node_allocation_statistics (code, length);
955e4b17023SJohn Marino   t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
956e4b17023SJohn Marino   memcpy (t, node, length);
957e4b17023SJohn Marino 
958e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
959e4b17023SJohn Marino     TREE_CHAIN (t) = 0;
960e4b17023SJohn Marino   TREE_ASM_WRITTEN (t) = 0;
961e4b17023SJohn Marino   TREE_VISITED (t) = 0;
962e4b17023SJohn Marino   if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
963e4b17023SJohn Marino     *DECL_VAR_ANN_PTR (t) = 0;
964e4b17023SJohn Marino 
965e4b17023SJohn Marino   if (TREE_CODE_CLASS (code) == tcc_declaration)
966e4b17023SJohn Marino     {
967e4b17023SJohn Marino       if (code == DEBUG_EXPR_DECL)
968e4b17023SJohn Marino 	DECL_UID (t) = --next_debug_decl_uid;
969e4b17023SJohn Marino       else
970e4b17023SJohn Marino 	{
971e4b17023SJohn Marino 	  DECL_UID (t) = allocate_decl_uid ();
972e4b17023SJohn Marino 	  if (DECL_PT_UID_SET_P (node))
973e4b17023SJohn Marino 	    SET_DECL_PT_UID (t, DECL_PT_UID (node));
974e4b17023SJohn Marino 	}
975e4b17023SJohn Marino       if ((TREE_CODE (node) == PARM_DECL || TREE_CODE (node) == VAR_DECL)
976e4b17023SJohn Marino 	  && DECL_HAS_VALUE_EXPR_P (node))
977e4b17023SJohn Marino 	{
978e4b17023SJohn Marino 	  SET_DECL_VALUE_EXPR (t, DECL_VALUE_EXPR (node));
979e4b17023SJohn Marino 	  DECL_HAS_VALUE_EXPR_P (t) = 1;
980e4b17023SJohn Marino 	}
981e4b17023SJohn Marino       if (TREE_CODE (node) == VAR_DECL && DECL_HAS_INIT_PRIORITY_P (node))
982e4b17023SJohn Marino 	{
983e4b17023SJohn Marino 	  SET_DECL_INIT_PRIORITY (t, DECL_INIT_PRIORITY (node));
984e4b17023SJohn Marino 	  DECL_HAS_INIT_PRIORITY_P (t) = 1;
985e4b17023SJohn Marino 	}
986e4b17023SJohn Marino     }
987e4b17023SJohn Marino   else if (TREE_CODE_CLASS (code) == tcc_type)
988e4b17023SJohn Marino     {
989e4b17023SJohn Marino       TYPE_UID (t) = next_type_uid++;
990e4b17023SJohn Marino       /* The following is so that the debug code for
991e4b17023SJohn Marino 	 the copy is different from the original type.
992e4b17023SJohn Marino 	 The two statements usually duplicate each other
993e4b17023SJohn Marino 	 (because they clear fields of the same union),
994e4b17023SJohn Marino 	 but the optimizer should catch that.  */
995e4b17023SJohn Marino       TYPE_SYMTAB_POINTER (t) = 0;
996e4b17023SJohn Marino       TYPE_SYMTAB_ADDRESS (t) = 0;
997e4b17023SJohn Marino 
998e4b17023SJohn Marino       /* Do not copy the values cache.  */
999e4b17023SJohn Marino       if (TYPE_CACHED_VALUES_P(t))
1000e4b17023SJohn Marino 	{
1001e4b17023SJohn Marino 	  TYPE_CACHED_VALUES_P (t) = 0;
1002e4b17023SJohn Marino 	  TYPE_CACHED_VALUES (t) = NULL_TREE;
1003e4b17023SJohn Marino 	}
1004e4b17023SJohn Marino     }
1005e4b17023SJohn Marino 
1006e4b17023SJohn Marino   return t;
1007e4b17023SJohn Marino }
1008e4b17023SJohn Marino 
1009e4b17023SJohn Marino /* Return a copy of a chain of nodes, chained through the TREE_CHAIN field.
1010e4b17023SJohn Marino    For example, this can copy a list made of TREE_LIST nodes.  */
1011e4b17023SJohn Marino 
1012e4b17023SJohn Marino tree
copy_list(tree list)1013e4b17023SJohn Marino copy_list (tree list)
1014e4b17023SJohn Marino {
1015e4b17023SJohn Marino   tree head;
1016e4b17023SJohn Marino   tree prev, next;
1017e4b17023SJohn Marino 
1018e4b17023SJohn Marino   if (list == 0)
1019e4b17023SJohn Marino     return 0;
1020e4b17023SJohn Marino 
1021e4b17023SJohn Marino   head = prev = copy_node (list);
1022e4b17023SJohn Marino   next = TREE_CHAIN (list);
1023e4b17023SJohn Marino   while (next)
1024e4b17023SJohn Marino     {
1025e4b17023SJohn Marino       TREE_CHAIN (prev) = copy_node (next);
1026e4b17023SJohn Marino       prev = TREE_CHAIN (prev);
1027e4b17023SJohn Marino       next = TREE_CHAIN (next);
1028e4b17023SJohn Marino     }
1029e4b17023SJohn Marino   return head;
1030e4b17023SJohn Marino }
1031e4b17023SJohn Marino 
1032e4b17023SJohn Marino 
1033e4b17023SJohn Marino /* Create an INT_CST node with a LOW value sign extended to TYPE.  */
1034e4b17023SJohn Marino 
1035e4b17023SJohn Marino tree
build_int_cst(tree type,HOST_WIDE_INT low)1036e4b17023SJohn Marino build_int_cst (tree type, HOST_WIDE_INT low)
1037e4b17023SJohn Marino {
1038e4b17023SJohn Marino   /* Support legacy code.  */
1039e4b17023SJohn Marino   if (!type)
1040e4b17023SJohn Marino     type = integer_type_node;
1041e4b17023SJohn Marino 
1042e4b17023SJohn Marino   return double_int_to_tree (type, shwi_to_double_int (low));
1043e4b17023SJohn Marino }
1044e4b17023SJohn Marino 
1045e4b17023SJohn Marino /* Create an INT_CST node with a LOW value sign extended to TYPE.  */
1046e4b17023SJohn Marino 
1047e4b17023SJohn Marino tree
build_int_cst_type(tree type,HOST_WIDE_INT low)1048e4b17023SJohn Marino build_int_cst_type (tree type, HOST_WIDE_INT low)
1049e4b17023SJohn Marino {
1050e4b17023SJohn Marino   gcc_assert (type);
1051e4b17023SJohn Marino 
1052e4b17023SJohn Marino   return double_int_to_tree (type, shwi_to_double_int (low));
1053e4b17023SJohn Marino }
1054e4b17023SJohn Marino 
1055e4b17023SJohn Marino /* Constructs tree in type TYPE from with value given by CST.  Signedness
1056e4b17023SJohn Marino    of CST is assumed to be the same as the signedness of TYPE.  */
1057e4b17023SJohn Marino 
1058e4b17023SJohn Marino tree
double_int_to_tree(tree type,double_int cst)1059e4b17023SJohn Marino double_int_to_tree (tree type, double_int cst)
1060e4b17023SJohn Marino {
1061e4b17023SJohn Marino   /* Size types *are* sign extended.  */
1062e4b17023SJohn Marino   bool sign_extended_type = (!TYPE_UNSIGNED (type)
1063e4b17023SJohn Marino 			     || (TREE_CODE (type) == INTEGER_TYPE
1064e4b17023SJohn Marino 				 && TYPE_IS_SIZETYPE (type)));
1065e4b17023SJohn Marino 
1066e4b17023SJohn Marino   cst = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
1067e4b17023SJohn Marino 
1068e4b17023SJohn Marino   return build_int_cst_wide (type, cst.low, cst.high);
1069e4b17023SJohn Marino }
1070e4b17023SJohn Marino 
1071e4b17023SJohn Marino /* Returns true if CST fits into range of TYPE.  Signedness of CST is assumed
1072e4b17023SJohn Marino    to be the same as the signedness of TYPE.  */
1073e4b17023SJohn Marino 
1074e4b17023SJohn Marino bool
double_int_fits_to_tree_p(const_tree type,double_int cst)1075e4b17023SJohn Marino double_int_fits_to_tree_p (const_tree type, double_int cst)
1076e4b17023SJohn Marino {
1077e4b17023SJohn Marino   /* Size types *are* sign extended.  */
1078e4b17023SJohn Marino   bool sign_extended_type = (!TYPE_UNSIGNED (type)
1079e4b17023SJohn Marino 			     || (TREE_CODE (type) == INTEGER_TYPE
1080e4b17023SJohn Marino 				 && TYPE_IS_SIZETYPE (type)));
1081e4b17023SJohn Marino 
1082e4b17023SJohn Marino   double_int ext
1083e4b17023SJohn Marino     = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
1084e4b17023SJohn Marino 
1085e4b17023SJohn Marino   return double_int_equal_p (cst, ext);
1086e4b17023SJohn Marino }
1087e4b17023SJohn Marino 
1088e4b17023SJohn Marino /* We force the double_int CST to the range of the type TYPE by sign or
1089e4b17023SJohn Marino    zero extending it.  OVERFLOWABLE indicates if we are interested in
1090e4b17023SJohn Marino    overflow of the value, when >0 we are only interested in signed
1091e4b17023SJohn Marino    overflow, for <0 we are interested in any overflow.  OVERFLOWED
1092e4b17023SJohn Marino    indicates whether overflow has already occurred.  CONST_OVERFLOWED
1093e4b17023SJohn Marino    indicates whether constant overflow has already occurred.  We force
1094e4b17023SJohn Marino    T's value to be within range of T's type (by setting to 0 or 1 all
1095e4b17023SJohn Marino    the bits outside the type's range).  We set TREE_OVERFLOWED if,
1096e4b17023SJohn Marino         OVERFLOWED is nonzero,
1097e4b17023SJohn Marino         or OVERFLOWABLE is >0 and signed overflow occurs
1098e4b17023SJohn Marino         or OVERFLOWABLE is <0 and any overflow occurs
1099e4b17023SJohn Marino    We return a new tree node for the extended double_int.  The node
1100e4b17023SJohn Marino    is shared if no overflow flags are set.  */
1101e4b17023SJohn Marino 
1102e4b17023SJohn Marino 
1103e4b17023SJohn Marino tree
force_fit_type_double(tree type,double_int cst,int overflowable,bool overflowed)1104e4b17023SJohn Marino force_fit_type_double (tree type, double_int cst, int overflowable,
1105e4b17023SJohn Marino 		       bool overflowed)
1106e4b17023SJohn Marino {
1107e4b17023SJohn Marino   bool sign_extended_type;
1108e4b17023SJohn Marino 
1109e4b17023SJohn Marino   /* Size types *are* sign extended.  */
1110e4b17023SJohn Marino   sign_extended_type = (!TYPE_UNSIGNED (type)
1111e4b17023SJohn Marino                         || (TREE_CODE (type) == INTEGER_TYPE
1112e4b17023SJohn Marino                             && TYPE_IS_SIZETYPE (type)));
1113e4b17023SJohn Marino 
1114e4b17023SJohn Marino   /* If we need to set overflow flags, return a new unshared node.  */
1115e4b17023SJohn Marino   if (overflowed || !double_int_fits_to_tree_p(type, cst))
1116e4b17023SJohn Marino     {
1117e4b17023SJohn Marino       if (overflowed
1118e4b17023SJohn Marino 	  || overflowable < 0
1119e4b17023SJohn Marino 	  || (overflowable > 0 && sign_extended_type))
1120e4b17023SJohn Marino 	{
1121e4b17023SJohn Marino 	  tree t = make_node (INTEGER_CST);
1122e4b17023SJohn Marino 	  TREE_INT_CST (t) = double_int_ext (cst, TYPE_PRECISION (type),
1123e4b17023SJohn Marino 					     !sign_extended_type);
1124e4b17023SJohn Marino 	  TREE_TYPE (t) = type;
1125e4b17023SJohn Marino 	  TREE_OVERFLOW (t) = 1;
1126e4b17023SJohn Marino 	  return t;
1127e4b17023SJohn Marino 	}
1128e4b17023SJohn Marino     }
1129e4b17023SJohn Marino 
1130e4b17023SJohn Marino   /* Else build a shared node.  */
1131e4b17023SJohn Marino   return double_int_to_tree (type, cst);
1132e4b17023SJohn Marino }
1133e4b17023SJohn Marino 
1134e4b17023SJohn Marino /* These are the hash table functions for the hash table of INTEGER_CST
1135e4b17023SJohn Marino    nodes of a sizetype.  */
1136e4b17023SJohn Marino 
1137e4b17023SJohn Marino /* Return the hash code code X, an INTEGER_CST.  */
1138e4b17023SJohn Marino 
1139e4b17023SJohn Marino static hashval_t
int_cst_hash_hash(const void * x)1140e4b17023SJohn Marino int_cst_hash_hash (const void *x)
1141e4b17023SJohn Marino {
1142e4b17023SJohn Marino   const_tree const t = (const_tree) x;
1143e4b17023SJohn Marino 
1144e4b17023SJohn Marino   return (TREE_INT_CST_HIGH (t) ^ TREE_INT_CST_LOW (t)
1145e4b17023SJohn Marino 	  ^ htab_hash_pointer (TREE_TYPE (t)));
1146e4b17023SJohn Marino }
1147e4b17023SJohn Marino 
1148e4b17023SJohn Marino /* Return nonzero if the value represented by *X (an INTEGER_CST tree node)
1149e4b17023SJohn Marino    is the same as that given by *Y, which is the same.  */
1150e4b17023SJohn Marino 
1151e4b17023SJohn Marino static int
int_cst_hash_eq(const void * x,const void * y)1152e4b17023SJohn Marino int_cst_hash_eq (const void *x, const void *y)
1153e4b17023SJohn Marino {
1154e4b17023SJohn Marino   const_tree const xt = (const_tree) x;
1155e4b17023SJohn Marino   const_tree const yt = (const_tree) y;
1156e4b17023SJohn Marino 
1157e4b17023SJohn Marino   return (TREE_TYPE (xt) == TREE_TYPE (yt)
1158e4b17023SJohn Marino 	  && TREE_INT_CST_HIGH (xt) == TREE_INT_CST_HIGH (yt)
1159e4b17023SJohn Marino 	  && TREE_INT_CST_LOW (xt) == TREE_INT_CST_LOW (yt));
1160e4b17023SJohn Marino }
1161e4b17023SJohn Marino 
1162e4b17023SJohn Marino /* Create an INT_CST node of TYPE and value HI:LOW.
1163e4b17023SJohn Marino    The returned node is always shared.  For small integers we use a
1164e4b17023SJohn Marino    per-type vector cache, for larger ones we use a single hash table.  */
1165e4b17023SJohn Marino 
1166e4b17023SJohn Marino tree
build_int_cst_wide(tree type,unsigned HOST_WIDE_INT low,HOST_WIDE_INT hi)1167e4b17023SJohn Marino build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
1168e4b17023SJohn Marino {
1169e4b17023SJohn Marino   tree t;
1170e4b17023SJohn Marino   int ix = -1;
1171e4b17023SJohn Marino   int limit = 0;
1172e4b17023SJohn Marino 
1173e4b17023SJohn Marino   gcc_assert (type);
1174e4b17023SJohn Marino 
1175e4b17023SJohn Marino   switch (TREE_CODE (type))
1176e4b17023SJohn Marino     {
1177e4b17023SJohn Marino     case NULLPTR_TYPE:
1178e4b17023SJohn Marino       gcc_assert (hi == 0 && low == 0);
1179e4b17023SJohn Marino       /* Fallthru.  */
1180e4b17023SJohn Marino 
1181e4b17023SJohn Marino     case POINTER_TYPE:
1182e4b17023SJohn Marino     case REFERENCE_TYPE:
1183e4b17023SJohn Marino       /* Cache NULL pointer.  */
1184e4b17023SJohn Marino       if (!hi && !low)
1185e4b17023SJohn Marino 	{
1186e4b17023SJohn Marino 	  limit = 1;
1187e4b17023SJohn Marino 	  ix = 0;
1188e4b17023SJohn Marino 	}
1189e4b17023SJohn Marino       break;
1190e4b17023SJohn Marino 
1191e4b17023SJohn Marino     case BOOLEAN_TYPE:
1192e4b17023SJohn Marino       /* Cache false or true.  */
1193e4b17023SJohn Marino       limit = 2;
1194e4b17023SJohn Marino       if (!hi && low < 2)
1195e4b17023SJohn Marino 	ix = low;
1196e4b17023SJohn Marino       break;
1197e4b17023SJohn Marino 
1198e4b17023SJohn Marino     case INTEGER_TYPE:
1199e4b17023SJohn Marino     case OFFSET_TYPE:
1200e4b17023SJohn Marino       if (TYPE_UNSIGNED (type))
1201e4b17023SJohn Marino 	{
1202e4b17023SJohn Marino 	  /* Cache 0..N */
1203e4b17023SJohn Marino 	  limit = INTEGER_SHARE_LIMIT;
1204e4b17023SJohn Marino 	  if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT)
1205e4b17023SJohn Marino 	    ix = low;
1206e4b17023SJohn Marino 	}
1207e4b17023SJohn Marino       else
1208e4b17023SJohn Marino 	{
1209e4b17023SJohn Marino 	  /* Cache -1..N */
1210e4b17023SJohn Marino 	  limit = INTEGER_SHARE_LIMIT + 1;
1211e4b17023SJohn Marino 	  if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT)
1212e4b17023SJohn Marino 	    ix = low + 1;
1213e4b17023SJohn Marino 	  else if (hi == -1 && low == -(unsigned HOST_WIDE_INT)1)
1214e4b17023SJohn Marino 	    ix = 0;
1215e4b17023SJohn Marino 	}
1216e4b17023SJohn Marino       break;
1217e4b17023SJohn Marino 
1218e4b17023SJohn Marino     case ENUMERAL_TYPE:
1219e4b17023SJohn Marino       break;
1220e4b17023SJohn Marino 
1221e4b17023SJohn Marino     default:
1222e4b17023SJohn Marino       gcc_unreachable ();
1223e4b17023SJohn Marino     }
1224e4b17023SJohn Marino 
1225e4b17023SJohn Marino   if (ix >= 0)
1226e4b17023SJohn Marino     {
1227e4b17023SJohn Marino       /* Look for it in the type's vector of small shared ints.  */
1228e4b17023SJohn Marino       if (!TYPE_CACHED_VALUES_P (type))
1229e4b17023SJohn Marino 	{
1230e4b17023SJohn Marino 	  TYPE_CACHED_VALUES_P (type) = 1;
1231e4b17023SJohn Marino 	  TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
1232e4b17023SJohn Marino 	}
1233e4b17023SJohn Marino 
1234e4b17023SJohn Marino       t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix);
1235e4b17023SJohn Marino       if (t)
1236e4b17023SJohn Marino 	{
1237e4b17023SJohn Marino 	  /* Make sure no one is clobbering the shared constant.  */
1238e4b17023SJohn Marino 	  gcc_assert (TREE_TYPE (t) == type);
1239e4b17023SJohn Marino 	  gcc_assert (TREE_INT_CST_LOW (t) == low);
1240e4b17023SJohn Marino 	  gcc_assert (TREE_INT_CST_HIGH (t) == hi);
1241e4b17023SJohn Marino 	}
1242e4b17023SJohn Marino       else
1243e4b17023SJohn Marino 	{
1244e4b17023SJohn Marino 	  /* Create a new shared int.  */
1245e4b17023SJohn Marino 	  t = make_node (INTEGER_CST);
1246e4b17023SJohn Marino 
1247e4b17023SJohn Marino 	  TREE_INT_CST_LOW (t) = low;
1248e4b17023SJohn Marino 	  TREE_INT_CST_HIGH (t) = hi;
1249e4b17023SJohn Marino 	  TREE_TYPE (t) = type;
1250e4b17023SJohn Marino 
1251e4b17023SJohn Marino 	  TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
1252e4b17023SJohn Marino 	}
1253e4b17023SJohn Marino     }
1254e4b17023SJohn Marino   else
1255e4b17023SJohn Marino     {
1256e4b17023SJohn Marino       /* Use the cache of larger shared ints.  */
1257e4b17023SJohn Marino       void **slot;
1258e4b17023SJohn Marino 
1259e4b17023SJohn Marino       TREE_INT_CST_LOW (int_cst_node) = low;
1260e4b17023SJohn Marino       TREE_INT_CST_HIGH (int_cst_node) = hi;
1261e4b17023SJohn Marino       TREE_TYPE (int_cst_node) = type;
1262e4b17023SJohn Marino 
1263e4b17023SJohn Marino       slot = htab_find_slot (int_cst_hash_table, int_cst_node, INSERT);
1264e4b17023SJohn Marino       t = (tree) *slot;
1265e4b17023SJohn Marino       if (!t)
1266e4b17023SJohn Marino 	{
1267e4b17023SJohn Marino 	  /* Insert this one into the hash table.  */
1268e4b17023SJohn Marino 	  t = int_cst_node;
1269e4b17023SJohn Marino 	  *slot = t;
1270e4b17023SJohn Marino 	  /* Make a new node for next time round.  */
1271e4b17023SJohn Marino 	  int_cst_node = make_node (INTEGER_CST);
1272e4b17023SJohn Marino 	}
1273e4b17023SJohn Marino     }
1274e4b17023SJohn Marino 
1275e4b17023SJohn Marino   return t;
1276e4b17023SJohn Marino }
1277e4b17023SJohn Marino 
1278e4b17023SJohn Marino /* Builds an integer constant in TYPE such that lowest BITS bits are ones
1279e4b17023SJohn Marino    and the rest are zeros.  */
1280e4b17023SJohn Marino 
1281e4b17023SJohn Marino tree
build_low_bits_mask(tree type,unsigned bits)1282e4b17023SJohn Marino build_low_bits_mask (tree type, unsigned bits)
1283e4b17023SJohn Marino {
1284e4b17023SJohn Marino   double_int mask;
1285e4b17023SJohn Marino 
1286e4b17023SJohn Marino   gcc_assert (bits <= TYPE_PRECISION (type));
1287e4b17023SJohn Marino 
1288e4b17023SJohn Marino   if (bits == TYPE_PRECISION (type)
1289e4b17023SJohn Marino       && !TYPE_UNSIGNED (type))
1290e4b17023SJohn Marino     /* Sign extended all-ones mask.  */
1291e4b17023SJohn Marino     mask = double_int_minus_one;
1292e4b17023SJohn Marino   else
1293e4b17023SJohn Marino     mask = double_int_mask (bits);
1294e4b17023SJohn Marino 
1295e4b17023SJohn Marino   return build_int_cst_wide (type, mask.low, mask.high);
1296e4b17023SJohn Marino }
1297e4b17023SJohn Marino 
1298e4b17023SJohn Marino /* Checks that X is integer constant that can be expressed in (unsigned)
1299e4b17023SJohn Marino    HOST_WIDE_INT without loss of precision.  */
1300e4b17023SJohn Marino 
1301e4b17023SJohn Marino bool
cst_and_fits_in_hwi(const_tree x)1302e4b17023SJohn Marino cst_and_fits_in_hwi (const_tree x)
1303e4b17023SJohn Marino {
1304e4b17023SJohn Marino   if (TREE_CODE (x) != INTEGER_CST)
1305e4b17023SJohn Marino     return false;
1306e4b17023SJohn Marino 
1307e4b17023SJohn Marino   if (TYPE_PRECISION (TREE_TYPE (x)) > HOST_BITS_PER_WIDE_INT)
1308e4b17023SJohn Marino     return false;
1309e4b17023SJohn Marino 
1310e4b17023SJohn Marino   return (TREE_INT_CST_HIGH (x) == 0
1311e4b17023SJohn Marino 	  || TREE_INT_CST_HIGH (x) == -1);
1312e4b17023SJohn Marino }
1313e4b17023SJohn Marino 
1314e4b17023SJohn Marino /* Return a new VECTOR_CST node whose type is TYPE and whose values
1315e4b17023SJohn Marino    are in a list pointed to by VALS.  */
1316e4b17023SJohn Marino 
1317e4b17023SJohn Marino tree
build_vector(tree type,tree vals)1318e4b17023SJohn Marino build_vector (tree type, tree vals)
1319e4b17023SJohn Marino {
1320e4b17023SJohn Marino   tree v = make_node (VECTOR_CST);
1321e4b17023SJohn Marino   int over = 0;
1322e4b17023SJohn Marino   tree link;
1323e4b17023SJohn Marino   unsigned cnt = 0;
1324e4b17023SJohn Marino 
1325e4b17023SJohn Marino   TREE_VECTOR_CST_ELTS (v) = vals;
1326e4b17023SJohn Marino   TREE_TYPE (v) = type;
1327e4b17023SJohn Marino 
1328e4b17023SJohn Marino   /* Iterate through elements and check for overflow.  */
1329e4b17023SJohn Marino   for (link = vals; link; link = TREE_CHAIN (link))
1330e4b17023SJohn Marino     {
1331e4b17023SJohn Marino       tree value = TREE_VALUE (link);
1332e4b17023SJohn Marino       cnt++;
1333e4b17023SJohn Marino 
1334e4b17023SJohn Marino       /* Don't crash if we get an address constant.  */
1335e4b17023SJohn Marino       if (!CONSTANT_CLASS_P (value))
1336e4b17023SJohn Marino 	continue;
1337e4b17023SJohn Marino 
1338e4b17023SJohn Marino       over |= TREE_OVERFLOW (value);
1339e4b17023SJohn Marino     }
1340e4b17023SJohn Marino 
1341e4b17023SJohn Marino   gcc_assert (cnt == TYPE_VECTOR_SUBPARTS (type));
1342e4b17023SJohn Marino 
1343e4b17023SJohn Marino   TREE_OVERFLOW (v) = over;
1344e4b17023SJohn Marino   return v;
1345e4b17023SJohn Marino }
1346e4b17023SJohn Marino 
1347e4b17023SJohn Marino /* Return a new VECTOR_CST node whose type is TYPE and whose values
1348e4b17023SJohn Marino    are extracted from V, a vector of CONSTRUCTOR_ELT.  */
1349e4b17023SJohn Marino 
1350e4b17023SJohn Marino tree
build_vector_from_ctor(tree type,VEC (constructor_elt,gc)* v)1351e4b17023SJohn Marino build_vector_from_ctor (tree type, VEC(constructor_elt,gc) *v)
1352e4b17023SJohn Marino {
1353e4b17023SJohn Marino   tree list = NULL_TREE;
1354e4b17023SJohn Marino   unsigned HOST_WIDE_INT idx;
1355e4b17023SJohn Marino   tree value;
1356e4b17023SJohn Marino 
1357e4b17023SJohn Marino   FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
1358e4b17023SJohn Marino     list = tree_cons (NULL_TREE, value, list);
1359e4b17023SJohn Marino   for (; idx < TYPE_VECTOR_SUBPARTS (type); ++idx)
1360e4b17023SJohn Marino     list = tree_cons (NULL_TREE,
1361e4b17023SJohn Marino 		      build_zero_cst (TREE_TYPE (type)), list);
1362e4b17023SJohn Marino   return build_vector (type, nreverse (list));
1363e4b17023SJohn Marino }
1364e4b17023SJohn Marino 
1365e4b17023SJohn Marino /* Build a vector of type VECTYPE where all the elements are SCs.  */
1366e4b17023SJohn Marino tree
build_vector_from_val(tree vectype,tree sc)1367e4b17023SJohn Marino build_vector_from_val (tree vectype, tree sc)
1368e4b17023SJohn Marino {
1369e4b17023SJohn Marino   int i, nunits = TYPE_VECTOR_SUBPARTS (vectype);
1370e4b17023SJohn Marino   VEC(constructor_elt, gc) *v = NULL;
1371e4b17023SJohn Marino 
1372e4b17023SJohn Marino   if (sc == error_mark_node)
1373e4b17023SJohn Marino     return sc;
1374e4b17023SJohn Marino 
1375e4b17023SJohn Marino   /* Verify that the vector type is suitable for SC.  Note that there
1376e4b17023SJohn Marino      is some inconsistency in the type-system with respect to restrict
1377e4b17023SJohn Marino      qualifications of pointers.  Vector types always have a main-variant
1378e4b17023SJohn Marino      element type and the qualification is applied to the vector-type.
1379e4b17023SJohn Marino      So TREE_TYPE (vector-type) does not return a properly qualified
1380e4b17023SJohn Marino      vector element-type.  */
1381e4b17023SJohn Marino   gcc_checking_assert (types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (sc)),
1382e4b17023SJohn Marino 					   TREE_TYPE (vectype)));
1383e4b17023SJohn Marino 
1384e4b17023SJohn Marino   v = VEC_alloc (constructor_elt, gc, nunits);
1385e4b17023SJohn Marino   for (i = 0; i < nunits; ++i)
1386e4b17023SJohn Marino     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, sc);
1387e4b17023SJohn Marino 
1388e4b17023SJohn Marino   if (CONSTANT_CLASS_P (sc))
1389e4b17023SJohn Marino     return build_vector_from_ctor (vectype, v);
1390e4b17023SJohn Marino   else
1391e4b17023SJohn Marino     return build_constructor (vectype, v);
1392e4b17023SJohn Marino }
1393e4b17023SJohn Marino 
1394e4b17023SJohn Marino /* Return a new CONSTRUCTOR node whose type is TYPE and whose values
1395e4b17023SJohn Marino    are in the VEC pointed to by VALS.  */
1396e4b17023SJohn Marino tree
build_constructor(tree type,VEC (constructor_elt,gc)* vals)1397e4b17023SJohn Marino build_constructor (tree type, VEC(constructor_elt,gc) *vals)
1398e4b17023SJohn Marino {
1399e4b17023SJohn Marino   tree c = make_node (CONSTRUCTOR);
1400e4b17023SJohn Marino   unsigned int i;
1401e4b17023SJohn Marino   constructor_elt *elt;
1402e4b17023SJohn Marino   bool constant_p = true;
1403e4b17023SJohn Marino 
1404e4b17023SJohn Marino   TREE_TYPE (c) = type;
1405e4b17023SJohn Marino   CONSTRUCTOR_ELTS (c) = vals;
1406e4b17023SJohn Marino 
1407e4b17023SJohn Marino   FOR_EACH_VEC_ELT (constructor_elt, vals, i, elt)
1408e4b17023SJohn Marino     if (!TREE_CONSTANT (elt->value))
1409e4b17023SJohn Marino       {
1410e4b17023SJohn Marino 	constant_p = false;
1411e4b17023SJohn Marino 	break;
1412e4b17023SJohn Marino       }
1413e4b17023SJohn Marino 
1414e4b17023SJohn Marino   TREE_CONSTANT (c) = constant_p;
1415e4b17023SJohn Marino 
1416e4b17023SJohn Marino   return c;
1417e4b17023SJohn Marino }
1418e4b17023SJohn Marino 
1419e4b17023SJohn Marino /* Build a CONSTRUCTOR node made of a single initializer, with the specified
1420e4b17023SJohn Marino    INDEX and VALUE.  */
1421e4b17023SJohn Marino tree
build_constructor_single(tree type,tree index,tree value)1422e4b17023SJohn Marino build_constructor_single (tree type, tree index, tree value)
1423e4b17023SJohn Marino {
1424e4b17023SJohn Marino   VEC(constructor_elt,gc) *v;
1425e4b17023SJohn Marino   constructor_elt *elt;
1426e4b17023SJohn Marino 
1427e4b17023SJohn Marino   v = VEC_alloc (constructor_elt, gc, 1);
1428e4b17023SJohn Marino   elt = VEC_quick_push (constructor_elt, v, NULL);
1429e4b17023SJohn Marino   elt->index = index;
1430e4b17023SJohn Marino   elt->value = value;
1431e4b17023SJohn Marino 
1432e4b17023SJohn Marino   return build_constructor (type, v);
1433e4b17023SJohn Marino }
1434e4b17023SJohn Marino 
1435e4b17023SJohn Marino 
1436e4b17023SJohn Marino /* Return a new CONSTRUCTOR node whose type is TYPE and whose values
1437e4b17023SJohn Marino    are in a list pointed to by VALS.  */
1438e4b17023SJohn Marino tree
build_constructor_from_list(tree type,tree vals)1439e4b17023SJohn Marino build_constructor_from_list (tree type, tree vals)
1440e4b17023SJohn Marino {
1441e4b17023SJohn Marino   tree t;
1442e4b17023SJohn Marino   VEC(constructor_elt,gc) *v = NULL;
1443e4b17023SJohn Marino 
1444e4b17023SJohn Marino   if (vals)
1445e4b17023SJohn Marino     {
1446e4b17023SJohn Marino       v = VEC_alloc (constructor_elt, gc, list_length (vals));
1447e4b17023SJohn Marino       for (t = vals; t; t = TREE_CHAIN (t))
1448e4b17023SJohn Marino 	CONSTRUCTOR_APPEND_ELT (v, TREE_PURPOSE (t), TREE_VALUE (t));
1449e4b17023SJohn Marino     }
1450e4b17023SJohn Marino 
1451e4b17023SJohn Marino   return build_constructor (type, v);
1452e4b17023SJohn Marino }
1453e4b17023SJohn Marino 
1454e4b17023SJohn Marino /* Return a new FIXED_CST node whose type is TYPE and value is F.  */
1455e4b17023SJohn Marino 
1456e4b17023SJohn Marino tree
build_fixed(tree type,FIXED_VALUE_TYPE f)1457e4b17023SJohn Marino build_fixed (tree type, FIXED_VALUE_TYPE f)
1458e4b17023SJohn Marino {
1459e4b17023SJohn Marino   tree v;
1460e4b17023SJohn Marino   FIXED_VALUE_TYPE *fp;
1461e4b17023SJohn Marino 
1462e4b17023SJohn Marino   v = make_node (FIXED_CST);
1463e4b17023SJohn Marino   fp = ggc_alloc_fixed_value ();
1464e4b17023SJohn Marino   memcpy (fp, &f, sizeof (FIXED_VALUE_TYPE));
1465e4b17023SJohn Marino 
1466e4b17023SJohn Marino   TREE_TYPE (v) = type;
1467e4b17023SJohn Marino   TREE_FIXED_CST_PTR (v) = fp;
1468e4b17023SJohn Marino   return v;
1469e4b17023SJohn Marino }
1470e4b17023SJohn Marino 
1471e4b17023SJohn Marino /* Return a new REAL_CST node whose type is TYPE and value is D.  */
1472e4b17023SJohn Marino 
1473e4b17023SJohn Marino tree
build_real(tree type,REAL_VALUE_TYPE d)1474e4b17023SJohn Marino build_real (tree type, REAL_VALUE_TYPE d)
1475e4b17023SJohn Marino {
1476e4b17023SJohn Marino   tree v;
1477e4b17023SJohn Marino   REAL_VALUE_TYPE *dp;
1478e4b17023SJohn Marino   int overflow = 0;
1479e4b17023SJohn Marino 
1480e4b17023SJohn Marino   /* ??? Used to check for overflow here via CHECK_FLOAT_TYPE.
1481e4b17023SJohn Marino      Consider doing it via real_convert now.  */
1482e4b17023SJohn Marino 
1483e4b17023SJohn Marino   v = make_node (REAL_CST);
1484e4b17023SJohn Marino   dp = ggc_alloc_real_value ();
1485e4b17023SJohn Marino   memcpy (dp, &d, sizeof (REAL_VALUE_TYPE));
1486e4b17023SJohn Marino 
1487e4b17023SJohn Marino   TREE_TYPE (v) = type;
1488e4b17023SJohn Marino   TREE_REAL_CST_PTR (v) = dp;
1489e4b17023SJohn Marino   TREE_OVERFLOW (v) = overflow;
1490e4b17023SJohn Marino   return v;
1491e4b17023SJohn Marino }
1492e4b17023SJohn Marino 
1493e4b17023SJohn Marino /* Return a new REAL_CST node whose type is TYPE
1494e4b17023SJohn Marino    and whose value is the integer value of the INTEGER_CST node I.  */
1495e4b17023SJohn Marino 
1496e4b17023SJohn Marino REAL_VALUE_TYPE
real_value_from_int_cst(const_tree type,const_tree i)1497e4b17023SJohn Marino real_value_from_int_cst (const_tree type, const_tree i)
1498e4b17023SJohn Marino {
1499e4b17023SJohn Marino   REAL_VALUE_TYPE d;
1500e4b17023SJohn Marino 
1501e4b17023SJohn Marino   /* Clear all bits of the real value type so that we can later do
1502e4b17023SJohn Marino      bitwise comparisons to see if two values are the same.  */
1503e4b17023SJohn Marino   memset (&d, 0, sizeof d);
1504e4b17023SJohn Marino 
1505e4b17023SJohn Marino   real_from_integer (&d, type ? TYPE_MODE (type) : VOIDmode,
1506e4b17023SJohn Marino 		     TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i),
1507e4b17023SJohn Marino 		     TYPE_UNSIGNED (TREE_TYPE (i)));
1508e4b17023SJohn Marino   return d;
1509e4b17023SJohn Marino }
1510e4b17023SJohn Marino 
1511e4b17023SJohn Marino /* Given a tree representing an integer constant I, return a tree
1512e4b17023SJohn Marino    representing the same value as a floating-point constant of type TYPE.  */
1513e4b17023SJohn Marino 
1514e4b17023SJohn Marino tree
build_real_from_int_cst(tree type,const_tree i)1515e4b17023SJohn Marino build_real_from_int_cst (tree type, const_tree i)
1516e4b17023SJohn Marino {
1517e4b17023SJohn Marino   tree v;
1518e4b17023SJohn Marino   int overflow = TREE_OVERFLOW (i);
1519e4b17023SJohn Marino 
1520e4b17023SJohn Marino   v = build_real (type, real_value_from_int_cst (type, i));
1521e4b17023SJohn Marino 
1522e4b17023SJohn Marino   TREE_OVERFLOW (v) |= overflow;
1523e4b17023SJohn Marino   return v;
1524e4b17023SJohn Marino }
1525e4b17023SJohn Marino 
1526e4b17023SJohn Marino /* Return a newly constructed STRING_CST node whose value is
1527e4b17023SJohn Marino    the LEN characters at STR.
1528e4b17023SJohn Marino    Note that for a C string literal, LEN should include the trailing NUL.
1529e4b17023SJohn Marino    The TREE_TYPE is not initialized.  */
1530e4b17023SJohn Marino 
1531e4b17023SJohn Marino tree
build_string(int len,const char * str)1532e4b17023SJohn Marino build_string (int len, const char *str)
1533e4b17023SJohn Marino {
1534e4b17023SJohn Marino   tree s;
1535e4b17023SJohn Marino   size_t length;
1536e4b17023SJohn Marino 
1537e4b17023SJohn Marino   /* Do not waste bytes provided by padding of struct tree_string.  */
1538e4b17023SJohn Marino   length = len + offsetof (struct tree_string, str) + 1;
1539e4b17023SJohn Marino 
1540e4b17023SJohn Marino   record_node_allocation_statistics (STRING_CST, length);
1541e4b17023SJohn Marino 
1542e4b17023SJohn Marino   s = ggc_alloc_tree_node (length);
1543e4b17023SJohn Marino 
1544e4b17023SJohn Marino   memset (s, 0, sizeof (struct tree_typed));
1545e4b17023SJohn Marino   TREE_SET_CODE (s, STRING_CST);
1546e4b17023SJohn Marino   TREE_CONSTANT (s) = 1;
1547e4b17023SJohn Marino   TREE_STRING_LENGTH (s) = len;
1548e4b17023SJohn Marino   memcpy (s->string.str, str, len);
1549e4b17023SJohn Marino   s->string.str[len] = '\0';
1550e4b17023SJohn Marino 
1551e4b17023SJohn Marino   return s;
1552e4b17023SJohn Marino }
1553e4b17023SJohn Marino 
1554e4b17023SJohn Marino /* Return a newly constructed COMPLEX_CST node whose value is
1555e4b17023SJohn Marino    specified by the real and imaginary parts REAL and IMAG.
1556e4b17023SJohn Marino    Both REAL and IMAG should be constant nodes.  TYPE, if specified,
1557e4b17023SJohn Marino    will be the type of the COMPLEX_CST; otherwise a new type will be made.  */
1558e4b17023SJohn Marino 
1559e4b17023SJohn Marino tree
build_complex(tree type,tree real,tree imag)1560e4b17023SJohn Marino build_complex (tree type, tree real, tree imag)
1561e4b17023SJohn Marino {
1562e4b17023SJohn Marino   tree t = make_node (COMPLEX_CST);
1563e4b17023SJohn Marino 
1564e4b17023SJohn Marino   TREE_REALPART (t) = real;
1565e4b17023SJohn Marino   TREE_IMAGPART (t) = imag;
1566e4b17023SJohn Marino   TREE_TYPE (t) = type ? type : build_complex_type (TREE_TYPE (real));
1567e4b17023SJohn Marino   TREE_OVERFLOW (t) = TREE_OVERFLOW (real) | TREE_OVERFLOW (imag);
1568e4b17023SJohn Marino   return t;
1569e4b17023SJohn Marino }
1570e4b17023SJohn Marino 
1571e4b17023SJohn Marino /* Return a constant of arithmetic type TYPE which is the
1572e4b17023SJohn Marino    multiplicative identity of the set TYPE.  */
1573e4b17023SJohn Marino 
1574e4b17023SJohn Marino tree
build_one_cst(tree type)1575e4b17023SJohn Marino build_one_cst (tree type)
1576e4b17023SJohn Marino {
1577e4b17023SJohn Marino   switch (TREE_CODE (type))
1578e4b17023SJohn Marino     {
1579e4b17023SJohn Marino     case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
1580e4b17023SJohn Marino     case POINTER_TYPE: case REFERENCE_TYPE:
1581e4b17023SJohn Marino     case OFFSET_TYPE:
1582e4b17023SJohn Marino       return build_int_cst (type, 1);
1583e4b17023SJohn Marino 
1584e4b17023SJohn Marino     case REAL_TYPE:
1585e4b17023SJohn Marino       return build_real (type, dconst1);
1586e4b17023SJohn Marino 
1587e4b17023SJohn Marino     case FIXED_POINT_TYPE:
1588e4b17023SJohn Marino       /* We can only generate 1 for accum types.  */
1589e4b17023SJohn Marino       gcc_assert (ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type)));
1590e4b17023SJohn Marino       return build_fixed (type, FCONST1(TYPE_MODE (type)));
1591e4b17023SJohn Marino 
1592e4b17023SJohn Marino     case VECTOR_TYPE:
1593e4b17023SJohn Marino       {
1594e4b17023SJohn Marino 	tree scalar = build_one_cst (TREE_TYPE (type));
1595e4b17023SJohn Marino 
1596e4b17023SJohn Marino 	return build_vector_from_val (type, scalar);
1597e4b17023SJohn Marino       }
1598e4b17023SJohn Marino 
1599e4b17023SJohn Marino     case COMPLEX_TYPE:
1600e4b17023SJohn Marino       return build_complex (type,
1601e4b17023SJohn Marino 			    build_one_cst (TREE_TYPE (type)),
1602e4b17023SJohn Marino 			    build_zero_cst (TREE_TYPE (type)));
1603e4b17023SJohn Marino 
1604e4b17023SJohn Marino     default:
1605e4b17023SJohn Marino       gcc_unreachable ();
1606e4b17023SJohn Marino     }
1607e4b17023SJohn Marino }
1608e4b17023SJohn Marino 
1609e4b17023SJohn Marino /* Build 0 constant of type TYPE.  This is used by constructor folding
1610e4b17023SJohn Marino    and thus the constant should be represented in memory by
1611e4b17023SJohn Marino    zero(es).  */
1612e4b17023SJohn Marino 
1613e4b17023SJohn Marino tree
build_zero_cst(tree type)1614e4b17023SJohn Marino build_zero_cst (tree type)
1615e4b17023SJohn Marino {
1616e4b17023SJohn Marino   switch (TREE_CODE (type))
1617e4b17023SJohn Marino     {
1618e4b17023SJohn Marino     case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
1619e4b17023SJohn Marino     case POINTER_TYPE: case REFERENCE_TYPE:
1620e4b17023SJohn Marino     case OFFSET_TYPE: case NULLPTR_TYPE:
1621e4b17023SJohn Marino       return build_int_cst (type, 0);
1622e4b17023SJohn Marino 
1623e4b17023SJohn Marino     case REAL_TYPE:
1624e4b17023SJohn Marino       return build_real (type, dconst0);
1625e4b17023SJohn Marino 
1626e4b17023SJohn Marino     case FIXED_POINT_TYPE:
1627e4b17023SJohn Marino       return build_fixed (type, FCONST0 (TYPE_MODE (type)));
1628e4b17023SJohn Marino 
1629e4b17023SJohn Marino     case VECTOR_TYPE:
1630e4b17023SJohn Marino       {
1631e4b17023SJohn Marino 	tree scalar = build_zero_cst (TREE_TYPE (type));
1632e4b17023SJohn Marino 
1633e4b17023SJohn Marino 	return build_vector_from_val (type, scalar);
1634e4b17023SJohn Marino       }
1635e4b17023SJohn Marino 
1636e4b17023SJohn Marino     case COMPLEX_TYPE:
1637e4b17023SJohn Marino       {
1638e4b17023SJohn Marino 	tree zero = build_zero_cst (TREE_TYPE (type));
1639e4b17023SJohn Marino 
1640e4b17023SJohn Marino 	return build_complex (type, zero, zero);
1641e4b17023SJohn Marino       }
1642e4b17023SJohn Marino 
1643e4b17023SJohn Marino     default:
1644e4b17023SJohn Marino       if (!AGGREGATE_TYPE_P (type))
1645e4b17023SJohn Marino 	return fold_convert (type, integer_zero_node);
1646e4b17023SJohn Marino       return build_constructor (type, NULL);
1647e4b17023SJohn Marino     }
1648e4b17023SJohn Marino }
1649e4b17023SJohn Marino 
1650e4b17023SJohn Marino 
1651e4b17023SJohn Marino /* Build a BINFO with LEN language slots.  */
1652e4b17023SJohn Marino 
1653e4b17023SJohn Marino tree
make_tree_binfo_stat(unsigned base_binfos MEM_STAT_DECL)1654e4b17023SJohn Marino make_tree_binfo_stat (unsigned base_binfos MEM_STAT_DECL)
1655e4b17023SJohn Marino {
1656e4b17023SJohn Marino   tree t;
1657e4b17023SJohn Marino   size_t length = (offsetof (struct tree_binfo, base_binfos)
1658e4b17023SJohn Marino 		   + VEC_embedded_size (tree, base_binfos));
1659e4b17023SJohn Marino 
1660e4b17023SJohn Marino   record_node_allocation_statistics (TREE_BINFO, length);
1661e4b17023SJohn Marino 
1662e4b17023SJohn Marino   t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
1663e4b17023SJohn Marino 
1664e4b17023SJohn Marino   memset (t, 0, offsetof (struct tree_binfo, base_binfos));
1665e4b17023SJohn Marino 
1666e4b17023SJohn Marino   TREE_SET_CODE (t, TREE_BINFO);
1667e4b17023SJohn Marino 
1668e4b17023SJohn Marino   VEC_embedded_init (tree, BINFO_BASE_BINFOS (t), base_binfos);
1669e4b17023SJohn Marino 
1670e4b17023SJohn Marino   return t;
1671e4b17023SJohn Marino }
1672e4b17023SJohn Marino 
1673e4b17023SJohn Marino /* Create a CASE_LABEL_EXPR tree node and return it.  */
1674e4b17023SJohn Marino 
1675e4b17023SJohn Marino tree
build_case_label(tree low_value,tree high_value,tree label_decl)1676e4b17023SJohn Marino build_case_label (tree low_value, tree high_value, tree label_decl)
1677e4b17023SJohn Marino {
1678e4b17023SJohn Marino   tree t = make_node (CASE_LABEL_EXPR);
1679e4b17023SJohn Marino 
1680e4b17023SJohn Marino   TREE_TYPE (t) = void_type_node;
1681e4b17023SJohn Marino   SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (label_decl));
1682e4b17023SJohn Marino 
1683e4b17023SJohn Marino   CASE_LOW (t) = low_value;
1684e4b17023SJohn Marino   CASE_HIGH (t) = high_value;
1685e4b17023SJohn Marino   CASE_LABEL (t) = label_decl;
1686e4b17023SJohn Marino   CASE_CHAIN (t) = NULL_TREE;
1687e4b17023SJohn Marino 
1688e4b17023SJohn Marino   return t;
1689e4b17023SJohn Marino }
1690e4b17023SJohn Marino 
1691e4b17023SJohn Marino /* Build a newly constructed TREE_VEC node of length LEN.  */
1692e4b17023SJohn Marino 
1693e4b17023SJohn Marino tree
make_tree_vec_stat(int len MEM_STAT_DECL)1694e4b17023SJohn Marino make_tree_vec_stat (int len MEM_STAT_DECL)
1695e4b17023SJohn Marino {
1696e4b17023SJohn Marino   tree t;
1697e4b17023SJohn Marino   int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);
1698e4b17023SJohn Marino 
1699e4b17023SJohn Marino   record_node_allocation_statistics (TREE_VEC, length);
1700e4b17023SJohn Marino 
1701e4b17023SJohn Marino   t = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
1702e4b17023SJohn Marino 
1703e4b17023SJohn Marino   TREE_SET_CODE (t, TREE_VEC);
1704e4b17023SJohn Marino   TREE_VEC_LENGTH (t) = len;
1705e4b17023SJohn Marino 
1706e4b17023SJohn Marino   return t;
1707e4b17023SJohn Marino }
1708e4b17023SJohn Marino 
1709e4b17023SJohn Marino /* Return 1 if EXPR is the integer constant zero or a complex constant
1710e4b17023SJohn Marino    of zero.  */
1711e4b17023SJohn Marino 
1712e4b17023SJohn Marino int
integer_zerop(const_tree expr)1713e4b17023SJohn Marino integer_zerop (const_tree expr)
1714e4b17023SJohn Marino {
1715e4b17023SJohn Marino   STRIP_NOPS (expr);
1716e4b17023SJohn Marino 
1717e4b17023SJohn Marino   return ((TREE_CODE (expr) == INTEGER_CST
1718e4b17023SJohn Marino 	   && TREE_INT_CST_LOW (expr) == 0
1719e4b17023SJohn Marino 	   && TREE_INT_CST_HIGH (expr) == 0)
1720e4b17023SJohn Marino 	  || (TREE_CODE (expr) == COMPLEX_CST
1721e4b17023SJohn Marino 	      && integer_zerop (TREE_REALPART (expr))
1722e4b17023SJohn Marino 	      && integer_zerop (TREE_IMAGPART (expr))));
1723e4b17023SJohn Marino }
1724e4b17023SJohn Marino 
1725e4b17023SJohn Marino /* Return 1 if EXPR is the integer constant one or the corresponding
1726e4b17023SJohn Marino    complex constant.  */
1727e4b17023SJohn Marino 
1728e4b17023SJohn Marino int
integer_onep(const_tree expr)1729e4b17023SJohn Marino integer_onep (const_tree expr)
1730e4b17023SJohn Marino {
1731e4b17023SJohn Marino   STRIP_NOPS (expr);
1732e4b17023SJohn Marino 
1733e4b17023SJohn Marino   return ((TREE_CODE (expr) == INTEGER_CST
1734e4b17023SJohn Marino 	   && TREE_INT_CST_LOW (expr) == 1
1735e4b17023SJohn Marino 	   && TREE_INT_CST_HIGH (expr) == 0)
1736e4b17023SJohn Marino 	  || (TREE_CODE (expr) == COMPLEX_CST
1737e4b17023SJohn Marino 	      && integer_onep (TREE_REALPART (expr))
1738e4b17023SJohn Marino 	      && integer_zerop (TREE_IMAGPART (expr))));
1739e4b17023SJohn Marino }
1740e4b17023SJohn Marino 
1741e4b17023SJohn Marino /* Return 1 if EXPR is an integer containing all 1's in as much precision as
1742e4b17023SJohn Marino    it contains.  Likewise for the corresponding complex constant.  */
1743e4b17023SJohn Marino 
1744e4b17023SJohn Marino int
integer_all_onesp(const_tree expr)1745e4b17023SJohn Marino integer_all_onesp (const_tree expr)
1746e4b17023SJohn Marino {
1747e4b17023SJohn Marino   int prec;
1748e4b17023SJohn Marino   int uns;
1749e4b17023SJohn Marino 
1750e4b17023SJohn Marino   STRIP_NOPS (expr);
1751e4b17023SJohn Marino 
1752e4b17023SJohn Marino   if (TREE_CODE (expr) == COMPLEX_CST
1753e4b17023SJohn Marino       && integer_all_onesp (TREE_REALPART (expr))
1754e4b17023SJohn Marino       && integer_zerop (TREE_IMAGPART (expr)))
1755e4b17023SJohn Marino     return 1;
1756e4b17023SJohn Marino 
1757e4b17023SJohn Marino   else if (TREE_CODE (expr) != INTEGER_CST)
1758e4b17023SJohn Marino     return 0;
1759e4b17023SJohn Marino 
1760e4b17023SJohn Marino   uns = TYPE_UNSIGNED (TREE_TYPE (expr));
1761e4b17023SJohn Marino   if (TREE_INT_CST_LOW (expr) == ~(unsigned HOST_WIDE_INT) 0
1762e4b17023SJohn Marino       && TREE_INT_CST_HIGH (expr) == -1)
1763e4b17023SJohn Marino     return 1;
1764e4b17023SJohn Marino   if (!uns)
1765e4b17023SJohn Marino     return 0;
1766e4b17023SJohn Marino 
1767e4b17023SJohn Marino   prec = TYPE_PRECISION (TREE_TYPE (expr));
1768e4b17023SJohn Marino   if (prec >= HOST_BITS_PER_WIDE_INT)
1769e4b17023SJohn Marino     {
1770e4b17023SJohn Marino       HOST_WIDE_INT high_value;
1771e4b17023SJohn Marino       int shift_amount;
1772e4b17023SJohn Marino 
1773e4b17023SJohn Marino       shift_amount = prec - HOST_BITS_PER_WIDE_INT;
1774e4b17023SJohn Marino 
1775e4b17023SJohn Marino       /* Can not handle precisions greater than twice the host int size.  */
1776e4b17023SJohn Marino       gcc_assert (shift_amount <= HOST_BITS_PER_WIDE_INT);
1777e4b17023SJohn Marino       if (shift_amount == HOST_BITS_PER_WIDE_INT)
1778e4b17023SJohn Marino 	/* Shifting by the host word size is undefined according to the ANSI
1779e4b17023SJohn Marino 	   standard, so we must handle this as a special case.  */
1780e4b17023SJohn Marino 	high_value = -1;
1781e4b17023SJohn Marino       else
1782e4b17023SJohn Marino 	high_value = ((HOST_WIDE_INT) 1 << shift_amount) - 1;
1783e4b17023SJohn Marino 
1784e4b17023SJohn Marino       return (TREE_INT_CST_LOW (expr) == ~(unsigned HOST_WIDE_INT) 0
1785e4b17023SJohn Marino 	      && TREE_INT_CST_HIGH (expr) == high_value);
1786e4b17023SJohn Marino     }
1787e4b17023SJohn Marino   else
1788e4b17023SJohn Marino     return TREE_INT_CST_LOW (expr) == ((unsigned HOST_WIDE_INT) 1 << prec) - 1;
1789e4b17023SJohn Marino }
1790e4b17023SJohn Marino 
1791e4b17023SJohn Marino /* Return 1 if EXPR is an integer constant that is a power of 2 (i.e., has only
1792e4b17023SJohn Marino    one bit on).  */
1793e4b17023SJohn Marino 
1794e4b17023SJohn Marino int
integer_pow2p(const_tree expr)1795e4b17023SJohn Marino integer_pow2p (const_tree expr)
1796e4b17023SJohn Marino {
1797e4b17023SJohn Marino   int prec;
1798e4b17023SJohn Marino   HOST_WIDE_INT high, low;
1799e4b17023SJohn Marino 
1800e4b17023SJohn Marino   STRIP_NOPS (expr);
1801e4b17023SJohn Marino 
1802e4b17023SJohn Marino   if (TREE_CODE (expr) == COMPLEX_CST
1803e4b17023SJohn Marino       && integer_pow2p (TREE_REALPART (expr))
1804e4b17023SJohn Marino       && integer_zerop (TREE_IMAGPART (expr)))
1805e4b17023SJohn Marino     return 1;
1806e4b17023SJohn Marino 
1807e4b17023SJohn Marino   if (TREE_CODE (expr) != INTEGER_CST)
1808e4b17023SJohn Marino     return 0;
1809e4b17023SJohn Marino 
1810e4b17023SJohn Marino   prec = TYPE_PRECISION (TREE_TYPE (expr));
1811e4b17023SJohn Marino   high = TREE_INT_CST_HIGH (expr);
1812e4b17023SJohn Marino   low = TREE_INT_CST_LOW (expr);
1813e4b17023SJohn Marino 
1814e4b17023SJohn Marino   /* First clear all bits that are beyond the type's precision in case
1815e4b17023SJohn Marino      we've been sign extended.  */
1816e4b17023SJohn Marino 
1817e4b17023SJohn Marino   if (prec == 2 * HOST_BITS_PER_WIDE_INT)
1818e4b17023SJohn Marino     ;
1819e4b17023SJohn Marino   else if (prec > HOST_BITS_PER_WIDE_INT)
1820e4b17023SJohn Marino     high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
1821e4b17023SJohn Marino   else
1822e4b17023SJohn Marino     {
1823e4b17023SJohn Marino       high = 0;
1824e4b17023SJohn Marino       if (prec < HOST_BITS_PER_WIDE_INT)
1825e4b17023SJohn Marino 	low &= ~((HOST_WIDE_INT) (-1) << prec);
1826e4b17023SJohn Marino     }
1827e4b17023SJohn Marino 
1828e4b17023SJohn Marino   if (high == 0 && low == 0)
1829e4b17023SJohn Marino     return 0;
1830e4b17023SJohn Marino 
1831e4b17023SJohn Marino   return ((high == 0 && (low & (low - 1)) == 0)
1832e4b17023SJohn Marino 	  || (low == 0 && (high & (high - 1)) == 0));
1833e4b17023SJohn Marino }
1834e4b17023SJohn Marino 
1835e4b17023SJohn Marino /* Return 1 if EXPR is an integer constant other than zero or a
1836e4b17023SJohn Marino    complex constant other than zero.  */
1837e4b17023SJohn Marino 
1838e4b17023SJohn Marino int
integer_nonzerop(const_tree expr)1839e4b17023SJohn Marino integer_nonzerop (const_tree expr)
1840e4b17023SJohn Marino {
1841e4b17023SJohn Marino   STRIP_NOPS (expr);
1842e4b17023SJohn Marino 
1843e4b17023SJohn Marino   return ((TREE_CODE (expr) == INTEGER_CST
1844e4b17023SJohn Marino 	   && (TREE_INT_CST_LOW (expr) != 0
1845e4b17023SJohn Marino 	       || TREE_INT_CST_HIGH (expr) != 0))
1846e4b17023SJohn Marino 	  || (TREE_CODE (expr) == COMPLEX_CST
1847e4b17023SJohn Marino 	      && (integer_nonzerop (TREE_REALPART (expr))
1848e4b17023SJohn Marino 		  || integer_nonzerop (TREE_IMAGPART (expr)))));
1849e4b17023SJohn Marino }
1850e4b17023SJohn Marino 
1851e4b17023SJohn Marino /* Return 1 if EXPR is the fixed-point constant zero.  */
1852e4b17023SJohn Marino 
1853e4b17023SJohn Marino int
fixed_zerop(const_tree expr)1854e4b17023SJohn Marino fixed_zerop (const_tree expr)
1855e4b17023SJohn Marino {
1856e4b17023SJohn Marino   return (TREE_CODE (expr) == FIXED_CST
1857e4b17023SJohn Marino 	  && double_int_zero_p (TREE_FIXED_CST (expr).data));
1858e4b17023SJohn Marino }
1859e4b17023SJohn Marino 
1860e4b17023SJohn Marino /* Return the power of two represented by a tree node known to be a
1861e4b17023SJohn Marino    power of two.  */
1862e4b17023SJohn Marino 
1863e4b17023SJohn Marino int
tree_log2(const_tree expr)1864e4b17023SJohn Marino tree_log2 (const_tree expr)
1865e4b17023SJohn Marino {
1866e4b17023SJohn Marino   int prec;
1867e4b17023SJohn Marino   HOST_WIDE_INT high, low;
1868e4b17023SJohn Marino 
1869e4b17023SJohn Marino   STRIP_NOPS (expr);
1870e4b17023SJohn Marino 
1871e4b17023SJohn Marino   if (TREE_CODE (expr) == COMPLEX_CST)
1872e4b17023SJohn Marino     return tree_log2 (TREE_REALPART (expr));
1873e4b17023SJohn Marino 
1874e4b17023SJohn Marino   prec = TYPE_PRECISION (TREE_TYPE (expr));
1875e4b17023SJohn Marino   high = TREE_INT_CST_HIGH (expr);
1876e4b17023SJohn Marino   low = TREE_INT_CST_LOW (expr);
1877e4b17023SJohn Marino 
1878e4b17023SJohn Marino   /* First clear all bits that are beyond the type's precision in case
1879e4b17023SJohn Marino      we've been sign extended.  */
1880e4b17023SJohn Marino 
1881e4b17023SJohn Marino   if (prec == 2 * HOST_BITS_PER_WIDE_INT)
1882e4b17023SJohn Marino     ;
1883e4b17023SJohn Marino   else if (prec > HOST_BITS_PER_WIDE_INT)
1884e4b17023SJohn Marino     high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
1885e4b17023SJohn Marino   else
1886e4b17023SJohn Marino     {
1887e4b17023SJohn Marino       high = 0;
1888e4b17023SJohn Marino       if (prec < HOST_BITS_PER_WIDE_INT)
1889e4b17023SJohn Marino 	low &= ~((HOST_WIDE_INT) (-1) << prec);
1890e4b17023SJohn Marino     }
1891e4b17023SJohn Marino 
1892e4b17023SJohn Marino   return (high != 0 ? HOST_BITS_PER_WIDE_INT + exact_log2 (high)
1893e4b17023SJohn Marino 	  : exact_log2 (low));
1894e4b17023SJohn Marino }
1895e4b17023SJohn Marino 
1896e4b17023SJohn Marino /* Similar, but return the largest integer Y such that 2 ** Y is less
1897e4b17023SJohn Marino    than or equal to EXPR.  */
1898e4b17023SJohn Marino 
1899e4b17023SJohn Marino int
tree_floor_log2(const_tree expr)1900e4b17023SJohn Marino tree_floor_log2 (const_tree expr)
1901e4b17023SJohn Marino {
1902e4b17023SJohn Marino   int prec;
1903e4b17023SJohn Marino   HOST_WIDE_INT high, low;
1904e4b17023SJohn Marino 
1905e4b17023SJohn Marino   STRIP_NOPS (expr);
1906e4b17023SJohn Marino 
1907e4b17023SJohn Marino   if (TREE_CODE (expr) == COMPLEX_CST)
1908e4b17023SJohn Marino     return tree_log2 (TREE_REALPART (expr));
1909e4b17023SJohn Marino 
1910e4b17023SJohn Marino   prec = TYPE_PRECISION (TREE_TYPE (expr));
1911e4b17023SJohn Marino   high = TREE_INT_CST_HIGH (expr);
1912e4b17023SJohn Marino   low = TREE_INT_CST_LOW (expr);
1913e4b17023SJohn Marino 
1914e4b17023SJohn Marino   /* First clear all bits that are beyond the type's precision in case
1915e4b17023SJohn Marino      we've been sign extended.  Ignore if type's precision hasn't been set
1916e4b17023SJohn Marino      since what we are doing is setting it.  */
1917e4b17023SJohn Marino 
1918e4b17023SJohn Marino   if (prec == 2 * HOST_BITS_PER_WIDE_INT || prec == 0)
1919e4b17023SJohn Marino     ;
1920e4b17023SJohn Marino   else if (prec > HOST_BITS_PER_WIDE_INT)
1921e4b17023SJohn Marino     high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
1922e4b17023SJohn Marino   else
1923e4b17023SJohn Marino     {
1924e4b17023SJohn Marino       high = 0;
1925e4b17023SJohn Marino       if (prec < HOST_BITS_PER_WIDE_INT)
1926e4b17023SJohn Marino 	low &= ~((HOST_WIDE_INT) (-1) << prec);
1927e4b17023SJohn Marino     }
1928e4b17023SJohn Marino 
1929e4b17023SJohn Marino   return (high != 0 ? HOST_BITS_PER_WIDE_INT + floor_log2 (high)
1930e4b17023SJohn Marino 	  : floor_log2 (low));
1931e4b17023SJohn Marino }
1932e4b17023SJohn Marino 
1933e4b17023SJohn Marino /* Return 1 if EXPR is the real constant zero.  Trailing zeroes matter for
1934e4b17023SJohn Marino    decimal float constants, so don't return 1 for them.  */
1935e4b17023SJohn Marino 
1936e4b17023SJohn Marino int
real_zerop(const_tree expr)1937e4b17023SJohn Marino real_zerop (const_tree expr)
1938e4b17023SJohn Marino {
1939e4b17023SJohn Marino   STRIP_NOPS (expr);
1940e4b17023SJohn Marino 
1941e4b17023SJohn Marino   return ((TREE_CODE (expr) == REAL_CST
1942e4b17023SJohn Marino 	   && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0)
1943e4b17023SJohn Marino 	   && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
1944e4b17023SJohn Marino 	  || (TREE_CODE (expr) == COMPLEX_CST
1945e4b17023SJohn Marino 	      && real_zerop (TREE_REALPART (expr))
1946e4b17023SJohn Marino 	      && real_zerop (TREE_IMAGPART (expr))));
1947e4b17023SJohn Marino }
1948e4b17023SJohn Marino 
1949e4b17023SJohn Marino /* Return 1 if EXPR is the real constant one in real or complex form.
1950e4b17023SJohn Marino    Trailing zeroes matter for decimal float constants, so don't return
1951e4b17023SJohn Marino    1 for them.  */
1952e4b17023SJohn Marino 
1953e4b17023SJohn Marino int
real_onep(const_tree expr)1954e4b17023SJohn Marino real_onep (const_tree expr)
1955e4b17023SJohn Marino {
1956e4b17023SJohn Marino   STRIP_NOPS (expr);
1957e4b17023SJohn Marino 
1958e4b17023SJohn Marino   return ((TREE_CODE (expr) == REAL_CST
1959e4b17023SJohn Marino 	   && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1)
1960e4b17023SJohn Marino 	   && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
1961e4b17023SJohn Marino 	  || (TREE_CODE (expr) == COMPLEX_CST
1962e4b17023SJohn Marino 	      && real_onep (TREE_REALPART (expr))
1963e4b17023SJohn Marino 	      && real_zerop (TREE_IMAGPART (expr))));
1964e4b17023SJohn Marino }
1965e4b17023SJohn Marino 
1966e4b17023SJohn Marino /* Return 1 if EXPR is the real constant two.  Trailing zeroes matter
1967e4b17023SJohn Marino    for decimal float constants, so don't return 1 for them.  */
1968e4b17023SJohn Marino 
1969e4b17023SJohn Marino int
real_twop(const_tree expr)1970e4b17023SJohn Marino real_twop (const_tree expr)
1971e4b17023SJohn Marino {
1972e4b17023SJohn Marino   STRIP_NOPS (expr);
1973e4b17023SJohn Marino 
1974e4b17023SJohn Marino   return ((TREE_CODE (expr) == REAL_CST
1975e4b17023SJohn Marino 	   && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2)
1976e4b17023SJohn Marino 	   && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
1977e4b17023SJohn Marino 	  || (TREE_CODE (expr) == COMPLEX_CST
1978e4b17023SJohn Marino 	      && real_twop (TREE_REALPART (expr))
1979e4b17023SJohn Marino 	      && real_zerop (TREE_IMAGPART (expr))));
1980e4b17023SJohn Marino }
1981e4b17023SJohn Marino 
1982e4b17023SJohn Marino /* Return 1 if EXPR is the real constant minus one.  Trailing zeroes
1983e4b17023SJohn Marino    matter for decimal float constants, so don't return 1 for them.  */
1984e4b17023SJohn Marino 
1985e4b17023SJohn Marino int
real_minus_onep(const_tree expr)1986e4b17023SJohn Marino real_minus_onep (const_tree expr)
1987e4b17023SJohn Marino {
1988e4b17023SJohn Marino   STRIP_NOPS (expr);
1989e4b17023SJohn Marino 
1990e4b17023SJohn Marino   return ((TREE_CODE (expr) == REAL_CST
1991e4b17023SJohn Marino 	   && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1)
1992e4b17023SJohn Marino 	   && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr)))))
1993e4b17023SJohn Marino 	  || (TREE_CODE (expr) == COMPLEX_CST
1994e4b17023SJohn Marino 	      && real_minus_onep (TREE_REALPART (expr))
1995e4b17023SJohn Marino 	      && real_zerop (TREE_IMAGPART (expr))));
1996e4b17023SJohn Marino }
1997e4b17023SJohn Marino 
1998e4b17023SJohn Marino /* Nonzero if EXP is a constant or a cast of a constant.  */
1999e4b17023SJohn Marino 
2000e4b17023SJohn Marino int
really_constant_p(const_tree exp)2001e4b17023SJohn Marino really_constant_p (const_tree exp)
2002e4b17023SJohn Marino {
2003e4b17023SJohn Marino   /* This is not quite the same as STRIP_NOPS.  It does more.  */
2004e4b17023SJohn Marino   while (CONVERT_EXPR_P (exp)
2005e4b17023SJohn Marino 	 || TREE_CODE (exp) == NON_LVALUE_EXPR)
2006e4b17023SJohn Marino     exp = TREE_OPERAND (exp, 0);
2007e4b17023SJohn Marino   return TREE_CONSTANT (exp);
2008e4b17023SJohn Marino }
2009e4b17023SJohn Marino 
2010e4b17023SJohn Marino /* Return first list element whose TREE_VALUE is ELEM.
2011e4b17023SJohn Marino    Return 0 if ELEM is not in LIST.  */
2012e4b17023SJohn Marino 
2013e4b17023SJohn Marino tree
value_member(tree elem,tree list)2014e4b17023SJohn Marino value_member (tree elem, tree list)
2015e4b17023SJohn Marino {
2016e4b17023SJohn Marino   while (list)
2017e4b17023SJohn Marino     {
2018e4b17023SJohn Marino       if (elem == TREE_VALUE (list))
2019e4b17023SJohn Marino 	return list;
2020e4b17023SJohn Marino       list = TREE_CHAIN (list);
2021e4b17023SJohn Marino     }
2022e4b17023SJohn Marino   return NULL_TREE;
2023e4b17023SJohn Marino }
2024e4b17023SJohn Marino 
2025e4b17023SJohn Marino /* Return first list element whose TREE_PURPOSE is ELEM.
2026e4b17023SJohn Marino    Return 0 if ELEM is not in LIST.  */
2027e4b17023SJohn Marino 
2028e4b17023SJohn Marino tree
purpose_member(const_tree elem,tree list)2029e4b17023SJohn Marino purpose_member (const_tree elem, tree list)
2030e4b17023SJohn Marino {
2031e4b17023SJohn Marino   while (list)
2032e4b17023SJohn Marino     {
2033e4b17023SJohn Marino       if (elem == TREE_PURPOSE (list))
2034e4b17023SJohn Marino 	return list;
2035e4b17023SJohn Marino       list = TREE_CHAIN (list);
2036e4b17023SJohn Marino     }
2037e4b17023SJohn Marino   return NULL_TREE;
2038e4b17023SJohn Marino }
2039e4b17023SJohn Marino 
2040e4b17023SJohn Marino /* Return true if ELEM is in V.  */
2041e4b17023SJohn Marino 
2042e4b17023SJohn Marino bool
vec_member(const_tree elem,VEC (tree,gc)* v)2043e4b17023SJohn Marino vec_member (const_tree elem, VEC(tree,gc) *v)
2044e4b17023SJohn Marino {
2045e4b17023SJohn Marino   unsigned ix;
2046e4b17023SJohn Marino   tree t;
2047e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, v, ix, t)
2048e4b17023SJohn Marino     if (elem == t)
2049e4b17023SJohn Marino       return true;
2050e4b17023SJohn Marino   return false;
2051e4b17023SJohn Marino }
2052e4b17023SJohn Marino 
2053e4b17023SJohn Marino /* Returns element number IDX (zero-origin) of chain CHAIN, or
2054e4b17023SJohn Marino    NULL_TREE.  */
2055e4b17023SJohn Marino 
2056e4b17023SJohn Marino tree
chain_index(int idx,tree chain)2057e4b17023SJohn Marino chain_index (int idx, tree chain)
2058e4b17023SJohn Marino {
2059e4b17023SJohn Marino   for (; chain && idx > 0; --idx)
2060e4b17023SJohn Marino     chain = TREE_CHAIN (chain);
2061e4b17023SJohn Marino   return chain;
2062e4b17023SJohn Marino }
2063e4b17023SJohn Marino 
2064e4b17023SJohn Marino /* Return nonzero if ELEM is part of the chain CHAIN.  */
2065e4b17023SJohn Marino 
2066e4b17023SJohn Marino int
chain_member(const_tree elem,const_tree chain)2067e4b17023SJohn Marino chain_member (const_tree elem, const_tree chain)
2068e4b17023SJohn Marino {
2069e4b17023SJohn Marino   while (chain)
2070e4b17023SJohn Marino     {
2071e4b17023SJohn Marino       if (elem == chain)
2072e4b17023SJohn Marino 	return 1;
2073e4b17023SJohn Marino       chain = DECL_CHAIN (chain);
2074e4b17023SJohn Marino     }
2075e4b17023SJohn Marino 
2076e4b17023SJohn Marino   return 0;
2077e4b17023SJohn Marino }
2078e4b17023SJohn Marino 
2079e4b17023SJohn Marino /* Return the length of a chain of nodes chained through TREE_CHAIN.
2080e4b17023SJohn Marino    We expect a null pointer to mark the end of the chain.
2081e4b17023SJohn Marino    This is the Lisp primitive `length'.  */
2082e4b17023SJohn Marino 
2083e4b17023SJohn Marino int
list_length(const_tree t)2084e4b17023SJohn Marino list_length (const_tree t)
2085e4b17023SJohn Marino {
2086e4b17023SJohn Marino   const_tree p = t;
2087e4b17023SJohn Marino #ifdef ENABLE_TREE_CHECKING
2088e4b17023SJohn Marino   const_tree q = t;
2089e4b17023SJohn Marino #endif
2090e4b17023SJohn Marino   int len = 0;
2091e4b17023SJohn Marino 
2092e4b17023SJohn Marino   while (p)
2093e4b17023SJohn Marino     {
2094e4b17023SJohn Marino       p = TREE_CHAIN (p);
2095e4b17023SJohn Marino #ifdef ENABLE_TREE_CHECKING
2096e4b17023SJohn Marino       if (len % 2)
2097e4b17023SJohn Marino 	q = TREE_CHAIN (q);
2098e4b17023SJohn Marino       gcc_assert (p != q);
2099e4b17023SJohn Marino #endif
2100e4b17023SJohn Marino       len++;
2101e4b17023SJohn Marino     }
2102e4b17023SJohn Marino 
2103e4b17023SJohn Marino   return len;
2104e4b17023SJohn Marino }
2105e4b17023SJohn Marino 
2106e4b17023SJohn Marino /* Returns the number of FIELD_DECLs in TYPE.  */
2107e4b17023SJohn Marino 
2108e4b17023SJohn Marino int
fields_length(const_tree type)2109e4b17023SJohn Marino fields_length (const_tree type)
2110e4b17023SJohn Marino {
2111e4b17023SJohn Marino   tree t = TYPE_FIELDS (type);
2112e4b17023SJohn Marino   int count = 0;
2113e4b17023SJohn Marino 
2114e4b17023SJohn Marino   for (; t; t = DECL_CHAIN (t))
2115e4b17023SJohn Marino     if (TREE_CODE (t) == FIELD_DECL)
2116e4b17023SJohn Marino       ++count;
2117e4b17023SJohn Marino 
2118e4b17023SJohn Marino   return count;
2119e4b17023SJohn Marino }
2120e4b17023SJohn Marino 
2121e4b17023SJohn Marino /* Returns the first FIELD_DECL in the TYPE_FIELDS of the RECORD_TYPE or
2122e4b17023SJohn Marino    UNION_TYPE TYPE, or NULL_TREE if none.  */
2123e4b17023SJohn Marino 
2124e4b17023SJohn Marino tree
first_field(const_tree type)2125e4b17023SJohn Marino first_field (const_tree type)
2126e4b17023SJohn Marino {
2127e4b17023SJohn Marino   tree t = TYPE_FIELDS (type);
2128e4b17023SJohn Marino   while (t && TREE_CODE (t) != FIELD_DECL)
2129e4b17023SJohn Marino     t = TREE_CHAIN (t);
2130e4b17023SJohn Marino   return t;
2131e4b17023SJohn Marino }
2132e4b17023SJohn Marino 
2133e4b17023SJohn Marino /* Concatenate two chains of nodes (chained through TREE_CHAIN)
2134e4b17023SJohn Marino    by modifying the last node in chain 1 to point to chain 2.
2135e4b17023SJohn Marino    This is the Lisp primitive `nconc'.  */
2136e4b17023SJohn Marino 
2137e4b17023SJohn Marino tree
chainon(tree op1,tree op2)2138e4b17023SJohn Marino chainon (tree op1, tree op2)
2139e4b17023SJohn Marino {
2140e4b17023SJohn Marino   tree t1;
2141e4b17023SJohn Marino 
2142e4b17023SJohn Marino   if (!op1)
2143e4b17023SJohn Marino     return op2;
2144e4b17023SJohn Marino   if (!op2)
2145e4b17023SJohn Marino     return op1;
2146e4b17023SJohn Marino 
2147e4b17023SJohn Marino   for (t1 = op1; TREE_CHAIN (t1); t1 = TREE_CHAIN (t1))
2148e4b17023SJohn Marino     continue;
2149e4b17023SJohn Marino   TREE_CHAIN (t1) = op2;
2150e4b17023SJohn Marino 
2151e4b17023SJohn Marino #ifdef ENABLE_TREE_CHECKING
2152e4b17023SJohn Marino   {
2153e4b17023SJohn Marino     tree t2;
2154e4b17023SJohn Marino     for (t2 = op2; t2; t2 = TREE_CHAIN (t2))
2155e4b17023SJohn Marino       gcc_assert (t2 != t1);
2156e4b17023SJohn Marino   }
2157e4b17023SJohn Marino #endif
2158e4b17023SJohn Marino 
2159e4b17023SJohn Marino   return op1;
2160e4b17023SJohn Marino }
2161e4b17023SJohn Marino 
2162e4b17023SJohn Marino /* Return the last node in a chain of nodes (chained through TREE_CHAIN).  */
2163e4b17023SJohn Marino 
2164e4b17023SJohn Marino tree
tree_last(tree chain)2165e4b17023SJohn Marino tree_last (tree chain)
2166e4b17023SJohn Marino {
2167e4b17023SJohn Marino   tree next;
2168e4b17023SJohn Marino   if (chain)
2169e4b17023SJohn Marino     while ((next = TREE_CHAIN (chain)))
2170e4b17023SJohn Marino       chain = next;
2171e4b17023SJohn Marino   return chain;
2172e4b17023SJohn Marino }
2173e4b17023SJohn Marino 
2174e4b17023SJohn Marino /* Reverse the order of elements in the chain T,
2175e4b17023SJohn Marino    and return the new head of the chain (old last element).  */
2176e4b17023SJohn Marino 
2177e4b17023SJohn Marino tree
nreverse(tree t)2178e4b17023SJohn Marino nreverse (tree t)
2179e4b17023SJohn Marino {
2180e4b17023SJohn Marino   tree prev = 0, decl, next;
2181e4b17023SJohn Marino   for (decl = t; decl; decl = next)
2182e4b17023SJohn Marino     {
2183e4b17023SJohn Marino       /* We shouldn't be using this function to reverse BLOCK chains; we
2184e4b17023SJohn Marino 	 have blocks_nreverse for that.  */
2185e4b17023SJohn Marino       gcc_checking_assert (TREE_CODE (decl) != BLOCK);
2186e4b17023SJohn Marino       next = TREE_CHAIN (decl);
2187e4b17023SJohn Marino       TREE_CHAIN (decl) = prev;
2188e4b17023SJohn Marino       prev = decl;
2189e4b17023SJohn Marino     }
2190e4b17023SJohn Marino   return prev;
2191e4b17023SJohn Marino }
2192e4b17023SJohn Marino 
2193e4b17023SJohn Marino /* Return a newly created TREE_LIST node whose
2194e4b17023SJohn Marino    purpose and value fields are PARM and VALUE.  */
2195e4b17023SJohn Marino 
2196e4b17023SJohn Marino tree
build_tree_list_stat(tree parm,tree value MEM_STAT_DECL)2197e4b17023SJohn Marino build_tree_list_stat (tree parm, tree value MEM_STAT_DECL)
2198e4b17023SJohn Marino {
2199e4b17023SJohn Marino   tree t = make_node_stat (TREE_LIST PASS_MEM_STAT);
2200e4b17023SJohn Marino   TREE_PURPOSE (t) = parm;
2201e4b17023SJohn Marino   TREE_VALUE (t) = value;
2202e4b17023SJohn Marino   return t;
2203e4b17023SJohn Marino }
2204e4b17023SJohn Marino 
2205e4b17023SJohn Marino /* Build a chain of TREE_LIST nodes from a vector.  */
2206e4b17023SJohn Marino 
2207e4b17023SJohn Marino tree
build_tree_list_vec_stat(const VEC (tree,gc)* vec MEM_STAT_DECL)2208e4b17023SJohn Marino build_tree_list_vec_stat (const VEC(tree,gc) *vec MEM_STAT_DECL)
2209e4b17023SJohn Marino {
2210e4b17023SJohn Marino   tree ret = NULL_TREE;
2211e4b17023SJohn Marino   tree *pp = &ret;
2212e4b17023SJohn Marino   unsigned int i;
2213e4b17023SJohn Marino   tree t;
2214e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, vec, i, t)
2215e4b17023SJohn Marino     {
2216e4b17023SJohn Marino       *pp = build_tree_list_stat (NULL, t PASS_MEM_STAT);
2217e4b17023SJohn Marino       pp = &TREE_CHAIN (*pp);
2218e4b17023SJohn Marino     }
2219e4b17023SJohn Marino   return ret;
2220e4b17023SJohn Marino }
2221e4b17023SJohn Marino 
2222e4b17023SJohn Marino /* Return a newly created TREE_LIST node whose
2223e4b17023SJohn Marino    purpose and value fields are PURPOSE and VALUE
2224e4b17023SJohn Marino    and whose TREE_CHAIN is CHAIN.  */
2225e4b17023SJohn Marino 
2226e4b17023SJohn Marino tree
tree_cons_stat(tree purpose,tree value,tree chain MEM_STAT_DECL)2227e4b17023SJohn Marino tree_cons_stat (tree purpose, tree value, tree chain MEM_STAT_DECL)
2228e4b17023SJohn Marino {
2229e4b17023SJohn Marino   tree node;
2230e4b17023SJohn Marino 
2231e4b17023SJohn Marino   node = ggc_alloc_zone_tree_node_stat (&tree_zone, sizeof (struct tree_list)
2232e4b17023SJohn Marino                                         PASS_MEM_STAT);
2233e4b17023SJohn Marino   memset (node, 0, sizeof (struct tree_common));
2234e4b17023SJohn Marino 
2235e4b17023SJohn Marino   record_node_allocation_statistics (TREE_LIST, sizeof (struct tree_list));
2236e4b17023SJohn Marino 
2237e4b17023SJohn Marino   TREE_SET_CODE (node, TREE_LIST);
2238e4b17023SJohn Marino   TREE_CHAIN (node) = chain;
2239e4b17023SJohn Marino   TREE_PURPOSE (node) = purpose;
2240e4b17023SJohn Marino   TREE_VALUE (node) = value;
2241e4b17023SJohn Marino   return node;
2242e4b17023SJohn Marino }
2243e4b17023SJohn Marino 
2244e4b17023SJohn Marino /* Return the values of the elements of a CONSTRUCTOR as a vector of
2245e4b17023SJohn Marino    trees.  */
2246e4b17023SJohn Marino 
VEC(tree,gc)2247e4b17023SJohn Marino VEC(tree,gc) *
2248e4b17023SJohn Marino ctor_to_vec (tree ctor)
2249e4b17023SJohn Marino {
2250e4b17023SJohn Marino   VEC(tree, gc) *vec = VEC_alloc (tree, gc, CONSTRUCTOR_NELTS (ctor));
2251e4b17023SJohn Marino   unsigned int ix;
2252e4b17023SJohn Marino   tree val;
2253e4b17023SJohn Marino 
2254e4b17023SJohn Marino   FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), ix, val)
2255e4b17023SJohn Marino     VEC_quick_push (tree, vec, val);
2256e4b17023SJohn Marino 
2257e4b17023SJohn Marino   return vec;
2258e4b17023SJohn Marino }
2259e4b17023SJohn Marino 
2260e4b17023SJohn Marino /* Return the size nominally occupied by an object of type TYPE
2261e4b17023SJohn Marino    when it resides in memory.  The value is measured in units of bytes,
2262e4b17023SJohn Marino    and its data type is that normally used for type sizes
2263e4b17023SJohn Marino    (which is the first type created by make_signed_type or
2264e4b17023SJohn Marino    make_unsigned_type).  */
2265e4b17023SJohn Marino 
2266e4b17023SJohn Marino tree
size_in_bytes(const_tree type)2267e4b17023SJohn Marino size_in_bytes (const_tree type)
2268e4b17023SJohn Marino {
2269e4b17023SJohn Marino   tree t;
2270e4b17023SJohn Marino 
2271e4b17023SJohn Marino   if (type == error_mark_node)
2272e4b17023SJohn Marino     return integer_zero_node;
2273e4b17023SJohn Marino 
2274e4b17023SJohn Marino   type = TYPE_MAIN_VARIANT (type);
2275e4b17023SJohn Marino   t = TYPE_SIZE_UNIT (type);
2276e4b17023SJohn Marino 
2277e4b17023SJohn Marino   if (t == 0)
2278e4b17023SJohn Marino     {
2279e4b17023SJohn Marino       lang_hooks.types.incomplete_type_error (NULL_TREE, type);
2280e4b17023SJohn Marino       return size_zero_node;
2281e4b17023SJohn Marino     }
2282e4b17023SJohn Marino 
2283e4b17023SJohn Marino   return t;
2284e4b17023SJohn Marino }
2285e4b17023SJohn Marino 
2286e4b17023SJohn Marino /* Return the size of TYPE (in bytes) as a wide integer
2287e4b17023SJohn Marino    or return -1 if the size can vary or is larger than an integer.  */
2288e4b17023SJohn Marino 
2289e4b17023SJohn Marino HOST_WIDE_INT
int_size_in_bytes(const_tree type)2290e4b17023SJohn Marino int_size_in_bytes (const_tree type)
2291e4b17023SJohn Marino {
2292e4b17023SJohn Marino   tree t;
2293e4b17023SJohn Marino 
2294e4b17023SJohn Marino   if (type == error_mark_node)
2295e4b17023SJohn Marino     return 0;
2296e4b17023SJohn Marino 
2297e4b17023SJohn Marino   type = TYPE_MAIN_VARIANT (type);
2298e4b17023SJohn Marino   t = TYPE_SIZE_UNIT (type);
2299e4b17023SJohn Marino   if (t == 0
2300e4b17023SJohn Marino       || TREE_CODE (t) != INTEGER_CST
2301e4b17023SJohn Marino       || TREE_INT_CST_HIGH (t) != 0
2302e4b17023SJohn Marino       /* If the result would appear negative, it's too big to represent.  */
2303e4b17023SJohn Marino       || (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
2304e4b17023SJohn Marino     return -1;
2305e4b17023SJohn Marino 
2306e4b17023SJohn Marino   return TREE_INT_CST_LOW (t);
2307e4b17023SJohn Marino }
2308e4b17023SJohn Marino 
2309e4b17023SJohn Marino /* Return the maximum size of TYPE (in bytes) as a wide integer
2310e4b17023SJohn Marino    or return -1 if the size can vary or is larger than an integer.  */
2311e4b17023SJohn Marino 
2312e4b17023SJohn Marino HOST_WIDE_INT
max_int_size_in_bytes(const_tree type)2313e4b17023SJohn Marino max_int_size_in_bytes (const_tree type)
2314e4b17023SJohn Marino {
2315e4b17023SJohn Marino   HOST_WIDE_INT size = -1;
2316e4b17023SJohn Marino   tree size_tree;
2317e4b17023SJohn Marino 
2318e4b17023SJohn Marino   /* If this is an array type, check for a possible MAX_SIZE attached.  */
2319e4b17023SJohn Marino 
2320e4b17023SJohn Marino   if (TREE_CODE (type) == ARRAY_TYPE)
2321e4b17023SJohn Marino     {
2322e4b17023SJohn Marino       size_tree = TYPE_ARRAY_MAX_SIZE (type);
2323e4b17023SJohn Marino 
2324e4b17023SJohn Marino       if (size_tree && host_integerp (size_tree, 1))
2325e4b17023SJohn Marino 	size = tree_low_cst (size_tree, 1);
2326e4b17023SJohn Marino     }
2327e4b17023SJohn Marino 
2328e4b17023SJohn Marino   /* If we still haven't been able to get a size, see if the language
2329e4b17023SJohn Marino      can compute a maximum size.  */
2330e4b17023SJohn Marino 
2331e4b17023SJohn Marino   if (size == -1)
2332e4b17023SJohn Marino     {
2333e4b17023SJohn Marino       size_tree = lang_hooks.types.max_size (type);
2334e4b17023SJohn Marino 
2335e4b17023SJohn Marino       if (size_tree && host_integerp (size_tree, 1))
2336e4b17023SJohn Marino 	size = tree_low_cst (size_tree, 1);
2337e4b17023SJohn Marino     }
2338e4b17023SJohn Marino 
2339e4b17023SJohn Marino   return size;
2340e4b17023SJohn Marino }
2341e4b17023SJohn Marino 
2342e4b17023SJohn Marino /* Returns a tree for the size of EXP in bytes.  */
2343e4b17023SJohn Marino 
2344e4b17023SJohn Marino tree
tree_expr_size(const_tree exp)2345e4b17023SJohn Marino tree_expr_size (const_tree exp)
2346e4b17023SJohn Marino {
2347e4b17023SJohn Marino   if (DECL_P (exp)
2348e4b17023SJohn Marino       && DECL_SIZE_UNIT (exp) != 0)
2349e4b17023SJohn Marino     return DECL_SIZE_UNIT (exp);
2350e4b17023SJohn Marino   else
2351e4b17023SJohn Marino     return size_in_bytes (TREE_TYPE (exp));
2352e4b17023SJohn Marino }
2353e4b17023SJohn Marino 
2354e4b17023SJohn Marino /* Return the bit position of FIELD, in bits from the start of the record.
2355e4b17023SJohn Marino    This is a tree of type bitsizetype.  */
2356e4b17023SJohn Marino 
2357e4b17023SJohn Marino tree
bit_position(const_tree field)2358e4b17023SJohn Marino bit_position (const_tree field)
2359e4b17023SJohn Marino {
2360e4b17023SJohn Marino   return bit_from_pos (DECL_FIELD_OFFSET (field),
2361e4b17023SJohn Marino 		       DECL_FIELD_BIT_OFFSET (field));
2362e4b17023SJohn Marino }
2363e4b17023SJohn Marino 
2364e4b17023SJohn Marino /* Likewise, but return as an integer.  It must be representable in
2365e4b17023SJohn Marino    that way (since it could be a signed value, we don't have the
2366e4b17023SJohn Marino    option of returning -1 like int_size_in_byte can.  */
2367e4b17023SJohn Marino 
2368e4b17023SJohn Marino HOST_WIDE_INT
int_bit_position(const_tree field)2369e4b17023SJohn Marino int_bit_position (const_tree field)
2370e4b17023SJohn Marino {
2371e4b17023SJohn Marino   return tree_low_cst (bit_position (field), 0);
2372e4b17023SJohn Marino }
2373e4b17023SJohn Marino 
2374e4b17023SJohn Marino /* Return the byte position of FIELD, in bytes from the start of the record.
2375e4b17023SJohn Marino    This is a tree of type sizetype.  */
2376e4b17023SJohn Marino 
2377e4b17023SJohn Marino tree
byte_position(const_tree field)2378e4b17023SJohn Marino byte_position (const_tree field)
2379e4b17023SJohn Marino {
2380e4b17023SJohn Marino   return byte_from_pos (DECL_FIELD_OFFSET (field),
2381e4b17023SJohn Marino 			DECL_FIELD_BIT_OFFSET (field));
2382e4b17023SJohn Marino }
2383e4b17023SJohn Marino 
2384e4b17023SJohn Marino /* Likewise, but return as an integer.  It must be representable in
2385e4b17023SJohn Marino    that way (since it could be a signed value, we don't have the
2386e4b17023SJohn Marino    option of returning -1 like int_size_in_byte can.  */
2387e4b17023SJohn Marino 
2388e4b17023SJohn Marino HOST_WIDE_INT
int_byte_position(const_tree field)2389e4b17023SJohn Marino int_byte_position (const_tree field)
2390e4b17023SJohn Marino {
2391e4b17023SJohn Marino   return tree_low_cst (byte_position (field), 0);
2392e4b17023SJohn Marino }
2393e4b17023SJohn Marino 
2394e4b17023SJohn Marino /* Return the strictest alignment, in bits, that T is known to have.  */
2395e4b17023SJohn Marino 
2396e4b17023SJohn Marino unsigned int
expr_align(const_tree t)2397e4b17023SJohn Marino expr_align (const_tree t)
2398e4b17023SJohn Marino {
2399e4b17023SJohn Marino   unsigned int align0, align1;
2400e4b17023SJohn Marino 
2401e4b17023SJohn Marino   switch (TREE_CODE (t))
2402e4b17023SJohn Marino     {
2403e4b17023SJohn Marino     CASE_CONVERT:  case NON_LVALUE_EXPR:
2404e4b17023SJohn Marino       /* If we have conversions, we know that the alignment of the
2405e4b17023SJohn Marino 	 object must meet each of the alignments of the types.  */
2406e4b17023SJohn Marino       align0 = expr_align (TREE_OPERAND (t, 0));
2407e4b17023SJohn Marino       align1 = TYPE_ALIGN (TREE_TYPE (t));
2408e4b17023SJohn Marino       return MAX (align0, align1);
2409e4b17023SJohn Marino 
2410e4b17023SJohn Marino     case SAVE_EXPR:         case COMPOUND_EXPR:       case MODIFY_EXPR:
2411e4b17023SJohn Marino     case INIT_EXPR:         case TARGET_EXPR:         case WITH_CLEANUP_EXPR:
2412e4b17023SJohn Marino     case CLEANUP_POINT_EXPR:
2413e4b17023SJohn Marino       /* These don't change the alignment of an object.  */
2414e4b17023SJohn Marino       return expr_align (TREE_OPERAND (t, 0));
2415e4b17023SJohn Marino 
2416e4b17023SJohn Marino     case COND_EXPR:
2417e4b17023SJohn Marino       /* The best we can do is say that the alignment is the least aligned
2418e4b17023SJohn Marino 	 of the two arms.  */
2419e4b17023SJohn Marino       align0 = expr_align (TREE_OPERAND (t, 1));
2420e4b17023SJohn Marino       align1 = expr_align (TREE_OPERAND (t, 2));
2421e4b17023SJohn Marino       return MIN (align0, align1);
2422e4b17023SJohn Marino 
2423e4b17023SJohn Marino       /* FIXME: LABEL_DECL and CONST_DECL never have DECL_ALIGN set
2424e4b17023SJohn Marino 	 meaningfully, it's always 1.  */
2425e4b17023SJohn Marino     case LABEL_DECL:     case CONST_DECL:
2426e4b17023SJohn Marino     case VAR_DECL:       case PARM_DECL:   case RESULT_DECL:
2427e4b17023SJohn Marino     case FUNCTION_DECL:
2428e4b17023SJohn Marino       gcc_assert (DECL_ALIGN (t) != 0);
2429e4b17023SJohn Marino       return DECL_ALIGN (t);
2430e4b17023SJohn Marino 
2431e4b17023SJohn Marino     default:
2432e4b17023SJohn Marino       break;
2433e4b17023SJohn Marino     }
2434e4b17023SJohn Marino 
2435e4b17023SJohn Marino   /* Otherwise take the alignment from that of the type.  */
2436e4b17023SJohn Marino   return TYPE_ALIGN (TREE_TYPE (t));
2437e4b17023SJohn Marino }
2438e4b17023SJohn Marino 
2439e4b17023SJohn Marino /* Return, as a tree node, the number of elements for TYPE (which is an
2440e4b17023SJohn Marino    ARRAY_TYPE) minus one. This counts only elements of the top array.  */
2441e4b17023SJohn Marino 
2442e4b17023SJohn Marino tree
array_type_nelts(const_tree type)2443e4b17023SJohn Marino array_type_nelts (const_tree type)
2444e4b17023SJohn Marino {
2445e4b17023SJohn Marino   tree index_type, min, max;
2446e4b17023SJohn Marino 
2447e4b17023SJohn Marino   /* If they did it with unspecified bounds, then we should have already
2448e4b17023SJohn Marino      given an error about it before we got here.  */
2449e4b17023SJohn Marino   if (! TYPE_DOMAIN (type))
2450e4b17023SJohn Marino     return error_mark_node;
2451e4b17023SJohn Marino 
2452e4b17023SJohn Marino   index_type = TYPE_DOMAIN (type);
2453e4b17023SJohn Marino   min = TYPE_MIN_VALUE (index_type);
2454e4b17023SJohn Marino   max = TYPE_MAX_VALUE (index_type);
2455e4b17023SJohn Marino 
2456e4b17023SJohn Marino   /* TYPE_MAX_VALUE may not be set if the array has unknown length.  */
2457e4b17023SJohn Marino   if (!max)
2458e4b17023SJohn Marino     return error_mark_node;
2459e4b17023SJohn Marino 
2460e4b17023SJohn Marino   return (integer_zerop (min)
2461e4b17023SJohn Marino 	  ? max
2462e4b17023SJohn Marino 	  : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
2463e4b17023SJohn Marino }
2464e4b17023SJohn Marino 
2465e4b17023SJohn Marino /* If arg is static -- a reference to an object in static storage -- then
2466e4b17023SJohn Marino    return the object.  This is not the same as the C meaning of `static'.
2467e4b17023SJohn Marino    If arg isn't static, return NULL.  */
2468e4b17023SJohn Marino 
2469e4b17023SJohn Marino tree
staticp(tree arg)2470e4b17023SJohn Marino staticp (tree arg)
2471e4b17023SJohn Marino {
2472e4b17023SJohn Marino   switch (TREE_CODE (arg))
2473e4b17023SJohn Marino     {
2474e4b17023SJohn Marino     case FUNCTION_DECL:
2475e4b17023SJohn Marino       /* Nested functions are static, even though taking their address will
2476e4b17023SJohn Marino 	 involve a trampoline as we unnest the nested function and create
2477e4b17023SJohn Marino 	 the trampoline on the tree level.  */
2478e4b17023SJohn Marino       return arg;
2479e4b17023SJohn Marino 
2480e4b17023SJohn Marino     case VAR_DECL:
2481e4b17023SJohn Marino       return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
2482e4b17023SJohn Marino 	      && ! DECL_THREAD_LOCAL_P (arg)
2483e4b17023SJohn Marino 	      && ! DECL_DLLIMPORT_P (arg)
2484e4b17023SJohn Marino 	      ? arg : NULL);
2485e4b17023SJohn Marino 
2486e4b17023SJohn Marino     case CONST_DECL:
2487e4b17023SJohn Marino       return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
2488e4b17023SJohn Marino 	      ? arg : NULL);
2489e4b17023SJohn Marino 
2490e4b17023SJohn Marino     case CONSTRUCTOR:
2491e4b17023SJohn Marino       return TREE_STATIC (arg) ? arg : NULL;
2492e4b17023SJohn Marino 
2493e4b17023SJohn Marino     case LABEL_DECL:
2494e4b17023SJohn Marino     case STRING_CST:
2495e4b17023SJohn Marino       return arg;
2496e4b17023SJohn Marino 
2497e4b17023SJohn Marino     case COMPONENT_REF:
2498e4b17023SJohn Marino       /* If the thing being referenced is not a field, then it is
2499e4b17023SJohn Marino 	 something language specific.  */
2500e4b17023SJohn Marino       gcc_assert (TREE_CODE (TREE_OPERAND (arg, 1)) == FIELD_DECL);
2501e4b17023SJohn Marino 
2502e4b17023SJohn Marino       /* If we are referencing a bitfield, we can't evaluate an
2503e4b17023SJohn Marino 	 ADDR_EXPR at compile time and so it isn't a constant.  */
2504e4b17023SJohn Marino       if (DECL_BIT_FIELD (TREE_OPERAND (arg, 1)))
2505e4b17023SJohn Marino 	return NULL;
2506e4b17023SJohn Marino 
2507e4b17023SJohn Marino       return staticp (TREE_OPERAND (arg, 0));
2508e4b17023SJohn Marino 
2509e4b17023SJohn Marino     case BIT_FIELD_REF:
2510e4b17023SJohn Marino       return NULL;
2511e4b17023SJohn Marino 
2512e4b17023SJohn Marino     case INDIRECT_REF:
2513e4b17023SJohn Marino       return TREE_CONSTANT (TREE_OPERAND (arg, 0)) ? arg : NULL;
2514e4b17023SJohn Marino 
2515e4b17023SJohn Marino     case ARRAY_REF:
2516e4b17023SJohn Marino     case ARRAY_RANGE_REF:
2517e4b17023SJohn Marino       if (TREE_CODE (TYPE_SIZE (TREE_TYPE (arg))) == INTEGER_CST
2518e4b17023SJohn Marino 	  && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST)
2519e4b17023SJohn Marino 	return staticp (TREE_OPERAND (arg, 0));
2520e4b17023SJohn Marino       else
2521e4b17023SJohn Marino 	return NULL;
2522e4b17023SJohn Marino 
2523e4b17023SJohn Marino     case COMPOUND_LITERAL_EXPR:
2524e4b17023SJohn Marino       return TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (arg)) ? arg : NULL;
2525e4b17023SJohn Marino 
2526e4b17023SJohn Marino     default:
2527e4b17023SJohn Marino       return NULL;
2528e4b17023SJohn Marino     }
2529e4b17023SJohn Marino }
2530e4b17023SJohn Marino 
2531e4b17023SJohn Marino 
2532e4b17023SJohn Marino 
2533e4b17023SJohn Marino 
2534e4b17023SJohn Marino /* Return whether OP is a DECL whose address is function-invariant.  */
2535e4b17023SJohn Marino 
2536e4b17023SJohn Marino bool
decl_address_invariant_p(const_tree op)2537e4b17023SJohn Marino decl_address_invariant_p (const_tree op)
2538e4b17023SJohn Marino {
2539e4b17023SJohn Marino   /* The conditions below are slightly less strict than the one in
2540e4b17023SJohn Marino      staticp.  */
2541e4b17023SJohn Marino 
2542e4b17023SJohn Marino   switch (TREE_CODE (op))
2543e4b17023SJohn Marino     {
2544e4b17023SJohn Marino     case PARM_DECL:
2545e4b17023SJohn Marino     case RESULT_DECL:
2546e4b17023SJohn Marino     case LABEL_DECL:
2547e4b17023SJohn Marino     case FUNCTION_DECL:
2548e4b17023SJohn Marino       return true;
2549e4b17023SJohn Marino 
2550e4b17023SJohn Marino     case VAR_DECL:
2551e4b17023SJohn Marino       if ((TREE_STATIC (op) || DECL_EXTERNAL (op))
2552e4b17023SJohn Marino           || DECL_THREAD_LOCAL_P (op)
2553e4b17023SJohn Marino           || DECL_CONTEXT (op) == current_function_decl
2554e4b17023SJohn Marino           || decl_function_context (op) == current_function_decl)
2555e4b17023SJohn Marino         return true;
2556e4b17023SJohn Marino       break;
2557e4b17023SJohn Marino 
2558e4b17023SJohn Marino     case CONST_DECL:
2559e4b17023SJohn Marino       if ((TREE_STATIC (op) || DECL_EXTERNAL (op))
2560e4b17023SJohn Marino           || decl_function_context (op) == current_function_decl)
2561e4b17023SJohn Marino         return true;
2562e4b17023SJohn Marino       break;
2563e4b17023SJohn Marino 
2564e4b17023SJohn Marino     default:
2565e4b17023SJohn Marino       break;
2566e4b17023SJohn Marino     }
2567e4b17023SJohn Marino 
2568e4b17023SJohn Marino   return false;
2569e4b17023SJohn Marino }
2570e4b17023SJohn Marino 
2571e4b17023SJohn Marino /* Return whether OP is a DECL whose address is interprocedural-invariant.  */
2572e4b17023SJohn Marino 
2573e4b17023SJohn Marino bool
decl_address_ip_invariant_p(const_tree op)2574e4b17023SJohn Marino decl_address_ip_invariant_p (const_tree op)
2575e4b17023SJohn Marino {
2576e4b17023SJohn Marino   /* The conditions below are slightly less strict than the one in
2577e4b17023SJohn Marino      staticp.  */
2578e4b17023SJohn Marino 
2579e4b17023SJohn Marino   switch (TREE_CODE (op))
2580e4b17023SJohn Marino     {
2581e4b17023SJohn Marino     case LABEL_DECL:
2582e4b17023SJohn Marino     case FUNCTION_DECL:
2583e4b17023SJohn Marino     case STRING_CST:
2584e4b17023SJohn Marino       return true;
2585e4b17023SJohn Marino 
2586e4b17023SJohn Marino     case VAR_DECL:
2587e4b17023SJohn Marino       if (((TREE_STATIC (op) || DECL_EXTERNAL (op))
2588e4b17023SJohn Marino            && !DECL_DLLIMPORT_P (op))
2589e4b17023SJohn Marino           || DECL_THREAD_LOCAL_P (op))
2590e4b17023SJohn Marino         return true;
2591e4b17023SJohn Marino       break;
2592e4b17023SJohn Marino 
2593e4b17023SJohn Marino     case CONST_DECL:
2594e4b17023SJohn Marino       if ((TREE_STATIC (op) || DECL_EXTERNAL (op)))
2595e4b17023SJohn Marino         return true;
2596e4b17023SJohn Marino       break;
2597e4b17023SJohn Marino 
2598e4b17023SJohn Marino     default:
2599e4b17023SJohn Marino       break;
2600e4b17023SJohn Marino     }
2601e4b17023SJohn Marino 
2602e4b17023SJohn Marino   return false;
2603e4b17023SJohn Marino }
2604e4b17023SJohn Marino 
2605e4b17023SJohn Marino 
2606e4b17023SJohn Marino /* Return true if T is function-invariant (internal function, does
2607e4b17023SJohn Marino    not handle arithmetic; that's handled in skip_simple_arithmetic and
2608e4b17023SJohn Marino    tree_invariant_p).  */
2609e4b17023SJohn Marino 
2610e4b17023SJohn Marino static bool tree_invariant_p (tree t);
2611e4b17023SJohn Marino 
2612e4b17023SJohn Marino static bool
tree_invariant_p_1(tree t)2613e4b17023SJohn Marino tree_invariant_p_1 (tree t)
2614e4b17023SJohn Marino {
2615e4b17023SJohn Marino   tree op;
2616e4b17023SJohn Marino 
2617e4b17023SJohn Marino   if (TREE_CONSTANT (t)
2618e4b17023SJohn Marino       || (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t)))
2619e4b17023SJohn Marino     return true;
2620e4b17023SJohn Marino 
2621e4b17023SJohn Marino   switch (TREE_CODE (t))
2622e4b17023SJohn Marino     {
2623e4b17023SJohn Marino     case SAVE_EXPR:
2624e4b17023SJohn Marino       return true;
2625e4b17023SJohn Marino 
2626e4b17023SJohn Marino     case ADDR_EXPR:
2627e4b17023SJohn Marino       op = TREE_OPERAND (t, 0);
2628e4b17023SJohn Marino       while (handled_component_p (op))
2629e4b17023SJohn Marino 	{
2630e4b17023SJohn Marino 	  switch (TREE_CODE (op))
2631e4b17023SJohn Marino 	    {
2632e4b17023SJohn Marino 	    case ARRAY_REF:
2633e4b17023SJohn Marino 	    case ARRAY_RANGE_REF:
2634e4b17023SJohn Marino 	      if (!tree_invariant_p (TREE_OPERAND (op, 1))
2635e4b17023SJohn Marino 		  || TREE_OPERAND (op, 2) != NULL_TREE
2636e4b17023SJohn Marino 		  || TREE_OPERAND (op, 3) != NULL_TREE)
2637e4b17023SJohn Marino 		return false;
2638e4b17023SJohn Marino 	      break;
2639e4b17023SJohn Marino 
2640e4b17023SJohn Marino 	    case COMPONENT_REF:
2641e4b17023SJohn Marino 	      if (TREE_OPERAND (op, 2) != NULL_TREE)
2642e4b17023SJohn Marino 		return false;
2643e4b17023SJohn Marino 	      break;
2644e4b17023SJohn Marino 
2645e4b17023SJohn Marino 	    default:;
2646e4b17023SJohn Marino 	    }
2647e4b17023SJohn Marino 	  op = TREE_OPERAND (op, 0);
2648e4b17023SJohn Marino 	}
2649e4b17023SJohn Marino 
2650e4b17023SJohn Marino       return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op);
2651e4b17023SJohn Marino 
2652e4b17023SJohn Marino     default:
2653e4b17023SJohn Marino       break;
2654e4b17023SJohn Marino     }
2655e4b17023SJohn Marino 
2656e4b17023SJohn Marino   return false;
2657e4b17023SJohn Marino }
2658e4b17023SJohn Marino 
2659e4b17023SJohn Marino /* Return true if T is function-invariant.  */
2660e4b17023SJohn Marino 
2661e4b17023SJohn Marino static bool
tree_invariant_p(tree t)2662e4b17023SJohn Marino tree_invariant_p (tree t)
2663e4b17023SJohn Marino {
2664e4b17023SJohn Marino   tree inner = skip_simple_arithmetic (t);
2665e4b17023SJohn Marino   return tree_invariant_p_1 (inner);
2666e4b17023SJohn Marino }
2667e4b17023SJohn Marino 
2668e4b17023SJohn Marino /* Wrap a SAVE_EXPR around EXPR, if appropriate.
2669e4b17023SJohn Marino    Do this to any expression which may be used in more than one place,
2670e4b17023SJohn Marino    but must be evaluated only once.
2671e4b17023SJohn Marino 
2672e4b17023SJohn Marino    Normally, expand_expr would reevaluate the expression each time.
2673e4b17023SJohn Marino    Calling save_expr produces something that is evaluated and recorded
2674e4b17023SJohn Marino    the first time expand_expr is called on it.  Subsequent calls to
2675e4b17023SJohn Marino    expand_expr just reuse the recorded value.
2676e4b17023SJohn Marino 
2677e4b17023SJohn Marino    The call to expand_expr that generates code that actually computes
2678e4b17023SJohn Marino    the value is the first call *at compile time*.  Subsequent calls
2679e4b17023SJohn Marino    *at compile time* generate code to use the saved value.
2680e4b17023SJohn Marino    This produces correct result provided that *at run time* control
2681e4b17023SJohn Marino    always flows through the insns made by the first expand_expr
2682e4b17023SJohn Marino    before reaching the other places where the save_expr was evaluated.
2683e4b17023SJohn Marino    You, the caller of save_expr, must make sure this is so.
2684e4b17023SJohn Marino 
2685e4b17023SJohn Marino    Constants, and certain read-only nodes, are returned with no
2686e4b17023SJohn Marino    SAVE_EXPR because that is safe.  Expressions containing placeholders
2687e4b17023SJohn Marino    are not touched; see tree.def for an explanation of what these
2688e4b17023SJohn Marino    are used for.  */
2689e4b17023SJohn Marino 
2690e4b17023SJohn Marino tree
save_expr(tree expr)2691e4b17023SJohn Marino save_expr (tree expr)
2692e4b17023SJohn Marino {
2693e4b17023SJohn Marino   tree t = fold (expr);
2694e4b17023SJohn Marino   tree inner;
2695e4b17023SJohn Marino 
2696e4b17023SJohn Marino   /* If the tree evaluates to a constant, then we don't want to hide that
2697e4b17023SJohn Marino      fact (i.e. this allows further folding, and direct checks for constants).
2698e4b17023SJohn Marino      However, a read-only object that has side effects cannot be bypassed.
2699e4b17023SJohn Marino      Since it is no problem to reevaluate literals, we just return the
2700e4b17023SJohn Marino      literal node.  */
2701e4b17023SJohn Marino   inner = skip_simple_arithmetic (t);
2702e4b17023SJohn Marino   if (TREE_CODE (inner) == ERROR_MARK)
2703e4b17023SJohn Marino     return inner;
2704e4b17023SJohn Marino 
2705e4b17023SJohn Marino   if (tree_invariant_p_1 (inner))
2706e4b17023SJohn Marino     return t;
2707e4b17023SJohn Marino 
2708e4b17023SJohn Marino   /* If INNER contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
2709e4b17023SJohn Marino      it means that the size or offset of some field of an object depends on
2710e4b17023SJohn Marino      the value within another field.
2711e4b17023SJohn Marino 
2712e4b17023SJohn Marino      Note that it must not be the case that T contains both a PLACEHOLDER_EXPR
2713e4b17023SJohn Marino      and some variable since it would then need to be both evaluated once and
2714e4b17023SJohn Marino      evaluated more than once.  Front-ends must assure this case cannot
2715e4b17023SJohn Marino      happen by surrounding any such subexpressions in their own SAVE_EXPR
2716e4b17023SJohn Marino      and forcing evaluation at the proper time.  */
2717e4b17023SJohn Marino   if (contains_placeholder_p (inner))
2718e4b17023SJohn Marino     return t;
2719e4b17023SJohn Marino 
2720e4b17023SJohn Marino   t = build1 (SAVE_EXPR, TREE_TYPE (expr), t);
2721e4b17023SJohn Marino   SET_EXPR_LOCATION (t, EXPR_LOCATION (expr));
2722e4b17023SJohn Marino 
2723e4b17023SJohn Marino   /* This expression might be placed ahead of a jump to ensure that the
2724e4b17023SJohn Marino      value was computed on both sides of the jump.  So make sure it isn't
2725e4b17023SJohn Marino      eliminated as dead.  */
2726e4b17023SJohn Marino   TREE_SIDE_EFFECTS (t) = 1;
2727e4b17023SJohn Marino   return t;
2728e4b17023SJohn Marino }
2729e4b17023SJohn Marino 
2730e4b17023SJohn Marino /* Look inside EXPR and into any simple arithmetic operations.  Return
2731e4b17023SJohn Marino    the innermost non-arithmetic node.  */
2732e4b17023SJohn Marino 
2733e4b17023SJohn Marino tree
skip_simple_arithmetic(tree expr)2734e4b17023SJohn Marino skip_simple_arithmetic (tree expr)
2735e4b17023SJohn Marino {
2736e4b17023SJohn Marino   tree inner;
2737e4b17023SJohn Marino 
2738e4b17023SJohn Marino   /* We don't care about whether this can be used as an lvalue in this
2739e4b17023SJohn Marino      context.  */
2740e4b17023SJohn Marino   while (TREE_CODE (expr) == NON_LVALUE_EXPR)
2741e4b17023SJohn Marino     expr = TREE_OPERAND (expr, 0);
2742e4b17023SJohn Marino 
2743e4b17023SJohn Marino   /* If we have simple operations applied to a SAVE_EXPR or to a SAVE_EXPR and
2744e4b17023SJohn Marino      a constant, it will be more efficient to not make another SAVE_EXPR since
2745e4b17023SJohn Marino      it will allow better simplification and GCSE will be able to merge the
2746e4b17023SJohn Marino      computations if they actually occur.  */
2747e4b17023SJohn Marino   inner = expr;
2748e4b17023SJohn Marino   while (1)
2749e4b17023SJohn Marino     {
2750e4b17023SJohn Marino       if (UNARY_CLASS_P (inner))
2751e4b17023SJohn Marino 	inner = TREE_OPERAND (inner, 0);
2752e4b17023SJohn Marino       else if (BINARY_CLASS_P (inner))
2753e4b17023SJohn Marino 	{
2754e4b17023SJohn Marino 	  if (tree_invariant_p (TREE_OPERAND (inner, 1)))
2755e4b17023SJohn Marino 	    inner = TREE_OPERAND (inner, 0);
2756e4b17023SJohn Marino 	  else if (tree_invariant_p (TREE_OPERAND (inner, 0)))
2757e4b17023SJohn Marino 	    inner = TREE_OPERAND (inner, 1);
2758e4b17023SJohn Marino 	  else
2759e4b17023SJohn Marino 	    break;
2760e4b17023SJohn Marino 	}
2761e4b17023SJohn Marino       else
2762e4b17023SJohn Marino 	break;
2763e4b17023SJohn Marino     }
2764e4b17023SJohn Marino 
2765e4b17023SJohn Marino   return inner;
2766e4b17023SJohn Marino }
2767e4b17023SJohn Marino 
2768e4b17023SJohn Marino 
2769e4b17023SJohn Marino /* Return which tree structure is used by T.  */
2770e4b17023SJohn Marino 
2771e4b17023SJohn Marino enum tree_node_structure_enum
tree_node_structure(const_tree t)2772e4b17023SJohn Marino tree_node_structure (const_tree t)
2773e4b17023SJohn Marino {
2774e4b17023SJohn Marino   const enum tree_code code = TREE_CODE (t);
2775e4b17023SJohn Marino   return tree_node_structure_for_code (code);
2776e4b17023SJohn Marino }
2777e4b17023SJohn Marino 
2778e4b17023SJohn Marino /* Set various status flags when building a CALL_EXPR object T.  */
2779e4b17023SJohn Marino 
2780e4b17023SJohn Marino static void
process_call_operands(tree t)2781e4b17023SJohn Marino process_call_operands (tree t)
2782e4b17023SJohn Marino {
2783e4b17023SJohn Marino   bool side_effects = TREE_SIDE_EFFECTS (t);
2784e4b17023SJohn Marino   bool read_only = false;
2785e4b17023SJohn Marino   int i = call_expr_flags (t);
2786e4b17023SJohn Marino 
2787e4b17023SJohn Marino   /* Calls have side-effects, except those to const or pure functions.  */
2788e4b17023SJohn Marino   if ((i & ECF_LOOPING_CONST_OR_PURE) || !(i & (ECF_CONST | ECF_PURE)))
2789e4b17023SJohn Marino     side_effects = true;
2790e4b17023SJohn Marino   /* Propagate TREE_READONLY of arguments for const functions.  */
2791e4b17023SJohn Marino   if (i & ECF_CONST)
2792e4b17023SJohn Marino     read_only = true;
2793e4b17023SJohn Marino 
2794e4b17023SJohn Marino   if (!side_effects || read_only)
2795e4b17023SJohn Marino     for (i = 1; i < TREE_OPERAND_LENGTH (t); i++)
2796e4b17023SJohn Marino       {
2797e4b17023SJohn Marino 	tree op = TREE_OPERAND (t, i);
2798e4b17023SJohn Marino 	if (op && TREE_SIDE_EFFECTS (op))
2799e4b17023SJohn Marino 	  side_effects = true;
2800e4b17023SJohn Marino 	if (op && !TREE_READONLY (op) && !CONSTANT_CLASS_P (op))
2801e4b17023SJohn Marino 	  read_only = false;
2802e4b17023SJohn Marino       }
2803e4b17023SJohn Marino 
2804e4b17023SJohn Marino   TREE_SIDE_EFFECTS (t) = side_effects;
2805e4b17023SJohn Marino   TREE_READONLY (t) = read_only;
2806e4b17023SJohn Marino }
2807e4b17023SJohn Marino 
2808e4b17023SJohn Marino /* Return true if EXP contains a PLACEHOLDER_EXPR, i.e. if it represents a
2809e4b17023SJohn Marino    size or offset that depends on a field within a record.  */
2810e4b17023SJohn Marino 
2811e4b17023SJohn Marino bool
contains_placeholder_p(const_tree exp)2812e4b17023SJohn Marino contains_placeholder_p (const_tree exp)
2813e4b17023SJohn Marino {
2814e4b17023SJohn Marino   enum tree_code code;
2815e4b17023SJohn Marino 
2816e4b17023SJohn Marino   if (!exp)
2817e4b17023SJohn Marino     return 0;
2818e4b17023SJohn Marino 
2819e4b17023SJohn Marino   code = TREE_CODE (exp);
2820e4b17023SJohn Marino   if (code == PLACEHOLDER_EXPR)
2821e4b17023SJohn Marino     return 1;
2822e4b17023SJohn Marino 
2823e4b17023SJohn Marino   switch (TREE_CODE_CLASS (code))
2824e4b17023SJohn Marino     {
2825e4b17023SJohn Marino     case tcc_reference:
2826e4b17023SJohn Marino       /* Don't look at any PLACEHOLDER_EXPRs that might be in index or bit
2827e4b17023SJohn Marino 	 position computations since they will be converted into a
2828e4b17023SJohn Marino 	 WITH_RECORD_EXPR involving the reference, which will assume
2829e4b17023SJohn Marino 	 here will be valid.  */
2830e4b17023SJohn Marino       return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
2831e4b17023SJohn Marino 
2832e4b17023SJohn Marino     case tcc_exceptional:
2833e4b17023SJohn Marino       if (code == TREE_LIST)
2834e4b17023SJohn Marino 	return (CONTAINS_PLACEHOLDER_P (TREE_VALUE (exp))
2835e4b17023SJohn Marino 		|| CONTAINS_PLACEHOLDER_P (TREE_CHAIN (exp)));
2836e4b17023SJohn Marino       break;
2837e4b17023SJohn Marino 
2838e4b17023SJohn Marino     case tcc_unary:
2839e4b17023SJohn Marino     case tcc_binary:
2840e4b17023SJohn Marino     case tcc_comparison:
2841e4b17023SJohn Marino     case tcc_expression:
2842e4b17023SJohn Marino       switch (code)
2843e4b17023SJohn Marino 	{
2844e4b17023SJohn Marino 	case COMPOUND_EXPR:
2845e4b17023SJohn Marino 	  /* Ignoring the first operand isn't quite right, but works best.  */
2846e4b17023SJohn Marino 	  return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
2847e4b17023SJohn Marino 
2848e4b17023SJohn Marino 	case COND_EXPR:
2849e4b17023SJohn Marino 	  return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
2850e4b17023SJohn Marino 		  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1))
2851e4b17023SJohn Marino 		  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2)));
2852e4b17023SJohn Marino 
2853e4b17023SJohn Marino 	case SAVE_EXPR:
2854e4b17023SJohn Marino 	  /* The save_expr function never wraps anything containing
2855e4b17023SJohn Marino 	     a PLACEHOLDER_EXPR. */
2856e4b17023SJohn Marino 	  return 0;
2857e4b17023SJohn Marino 
2858e4b17023SJohn Marino 	default:
2859e4b17023SJohn Marino 	  break;
2860e4b17023SJohn Marino 	}
2861e4b17023SJohn Marino 
2862e4b17023SJohn Marino       switch (TREE_CODE_LENGTH (code))
2863e4b17023SJohn Marino 	{
2864e4b17023SJohn Marino 	case 1:
2865e4b17023SJohn Marino 	  return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
2866e4b17023SJohn Marino 	case 2:
2867e4b17023SJohn Marino 	  return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
2868e4b17023SJohn Marino 		  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1)));
2869e4b17023SJohn Marino 	default:
2870e4b17023SJohn Marino 	  return 0;
2871e4b17023SJohn Marino 	}
2872e4b17023SJohn Marino 
2873e4b17023SJohn Marino     case tcc_vl_exp:
2874e4b17023SJohn Marino       switch (code)
2875e4b17023SJohn Marino 	{
2876e4b17023SJohn Marino 	case CALL_EXPR:
2877e4b17023SJohn Marino 	  {
2878e4b17023SJohn Marino 	    const_tree arg;
2879e4b17023SJohn Marino 	    const_call_expr_arg_iterator iter;
2880e4b17023SJohn Marino 	    FOR_EACH_CONST_CALL_EXPR_ARG (arg, iter, exp)
2881e4b17023SJohn Marino 	      if (CONTAINS_PLACEHOLDER_P (arg))
2882e4b17023SJohn Marino 		return 1;
2883e4b17023SJohn Marino 	    return 0;
2884e4b17023SJohn Marino 	  }
2885e4b17023SJohn Marino 	default:
2886e4b17023SJohn Marino 	  return 0;
2887e4b17023SJohn Marino 	}
2888e4b17023SJohn Marino 
2889e4b17023SJohn Marino     default:
2890e4b17023SJohn Marino       return 0;
2891e4b17023SJohn Marino     }
2892e4b17023SJohn Marino   return 0;
2893e4b17023SJohn Marino }
2894e4b17023SJohn Marino 
2895e4b17023SJohn Marino /* Return true if any part of the structure of TYPE involves a PLACEHOLDER_EXPR
2896e4b17023SJohn Marino    directly.  This includes size, bounds, qualifiers (for QUAL_UNION_TYPE) and
2897e4b17023SJohn Marino    field positions.  */
2898e4b17023SJohn Marino 
2899e4b17023SJohn Marino static bool
type_contains_placeholder_1(const_tree type)2900e4b17023SJohn Marino type_contains_placeholder_1 (const_tree type)
2901e4b17023SJohn Marino {
2902e4b17023SJohn Marino   /* If the size contains a placeholder or the parent type (component type in
2903e4b17023SJohn Marino      the case of arrays) type involves a placeholder, this type does.  */
2904e4b17023SJohn Marino   if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type))
2905e4b17023SJohn Marino       || CONTAINS_PLACEHOLDER_P (TYPE_SIZE_UNIT (type))
2906e4b17023SJohn Marino       || (!POINTER_TYPE_P (type)
2907e4b17023SJohn Marino 	  && TREE_TYPE (type)
2908e4b17023SJohn Marino 	  && type_contains_placeholder_p (TREE_TYPE (type))))
2909e4b17023SJohn Marino     return true;
2910e4b17023SJohn Marino 
2911e4b17023SJohn Marino   /* Now do type-specific checks.  Note that the last part of the check above
2912e4b17023SJohn Marino      greatly limits what we have to do below.  */
2913e4b17023SJohn Marino   switch (TREE_CODE (type))
2914e4b17023SJohn Marino     {
2915e4b17023SJohn Marino     case VOID_TYPE:
2916e4b17023SJohn Marino     case COMPLEX_TYPE:
2917e4b17023SJohn Marino     case ENUMERAL_TYPE:
2918e4b17023SJohn Marino     case BOOLEAN_TYPE:
2919e4b17023SJohn Marino     case POINTER_TYPE:
2920e4b17023SJohn Marino     case OFFSET_TYPE:
2921e4b17023SJohn Marino     case REFERENCE_TYPE:
2922e4b17023SJohn Marino     case METHOD_TYPE:
2923e4b17023SJohn Marino     case FUNCTION_TYPE:
2924e4b17023SJohn Marino     case VECTOR_TYPE:
2925e4b17023SJohn Marino     case NULLPTR_TYPE:
2926e4b17023SJohn Marino       return false;
2927e4b17023SJohn Marino 
2928e4b17023SJohn Marino     case INTEGER_TYPE:
2929e4b17023SJohn Marino     case REAL_TYPE:
2930e4b17023SJohn Marino     case FIXED_POINT_TYPE:
2931e4b17023SJohn Marino       /* Here we just check the bounds.  */
2932e4b17023SJohn Marino       return (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (type))
2933e4b17023SJohn Marino 	      || CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (type)));
2934e4b17023SJohn Marino 
2935e4b17023SJohn Marino     case ARRAY_TYPE:
2936e4b17023SJohn Marino       /* We have already checked the component type above, so just check the
2937e4b17023SJohn Marino 	 domain type.  */
2938e4b17023SJohn Marino       return type_contains_placeholder_p (TYPE_DOMAIN (type));
2939e4b17023SJohn Marino 
2940e4b17023SJohn Marino     case RECORD_TYPE:
2941e4b17023SJohn Marino     case UNION_TYPE:
2942e4b17023SJohn Marino     case QUAL_UNION_TYPE:
2943e4b17023SJohn Marino       {
2944e4b17023SJohn Marino 	tree field;
2945e4b17023SJohn Marino 
2946e4b17023SJohn Marino 	for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2947e4b17023SJohn Marino 	  if (TREE_CODE (field) == FIELD_DECL
2948e4b17023SJohn Marino 	      && (CONTAINS_PLACEHOLDER_P (DECL_FIELD_OFFSET (field))
2949e4b17023SJohn Marino 		  || (TREE_CODE (type) == QUAL_UNION_TYPE
2950e4b17023SJohn Marino 		      && CONTAINS_PLACEHOLDER_P (DECL_QUALIFIER (field)))
2951e4b17023SJohn Marino 		  || type_contains_placeholder_p (TREE_TYPE (field))))
2952e4b17023SJohn Marino 	    return true;
2953e4b17023SJohn Marino 
2954e4b17023SJohn Marino 	return false;
2955e4b17023SJohn Marino       }
2956e4b17023SJohn Marino 
2957e4b17023SJohn Marino     default:
2958e4b17023SJohn Marino       gcc_unreachable ();
2959e4b17023SJohn Marino     }
2960e4b17023SJohn Marino }
2961e4b17023SJohn Marino 
2962e4b17023SJohn Marino /* Wrapper around above function used to cache its result.  */
2963e4b17023SJohn Marino 
2964e4b17023SJohn Marino bool
type_contains_placeholder_p(tree type)2965e4b17023SJohn Marino type_contains_placeholder_p (tree type)
2966e4b17023SJohn Marino {
2967e4b17023SJohn Marino   bool result;
2968e4b17023SJohn Marino 
2969e4b17023SJohn Marino   /* If the contains_placeholder_bits field has been initialized,
2970e4b17023SJohn Marino      then we know the answer.  */
2971e4b17023SJohn Marino   if (TYPE_CONTAINS_PLACEHOLDER_INTERNAL (type) > 0)
2972e4b17023SJohn Marino     return TYPE_CONTAINS_PLACEHOLDER_INTERNAL (type) - 1;
2973e4b17023SJohn Marino 
2974e4b17023SJohn Marino   /* Indicate that we've seen this type node, and the answer is false.
2975e4b17023SJohn Marino      This is what we want to return if we run into recursion via fields.  */
2976e4b17023SJohn Marino   TYPE_CONTAINS_PLACEHOLDER_INTERNAL (type) = 1;
2977e4b17023SJohn Marino 
2978e4b17023SJohn Marino   /* Compute the real value.  */
2979e4b17023SJohn Marino   result = type_contains_placeholder_1 (type);
2980e4b17023SJohn Marino 
2981e4b17023SJohn Marino   /* Store the real value.  */
2982e4b17023SJohn Marino   TYPE_CONTAINS_PLACEHOLDER_INTERNAL (type) = result + 1;
2983e4b17023SJohn Marino 
2984e4b17023SJohn Marino   return result;
2985e4b17023SJohn Marino }
2986e4b17023SJohn Marino 
2987e4b17023SJohn Marino /* Push tree EXP onto vector QUEUE if it is not already present.  */
2988e4b17023SJohn Marino 
2989e4b17023SJohn Marino static void
push_without_duplicates(tree exp,VEC (tree,heap)** queue)2990e4b17023SJohn Marino push_without_duplicates (tree exp, VEC (tree, heap) **queue)
2991e4b17023SJohn Marino {
2992e4b17023SJohn Marino   unsigned int i;
2993e4b17023SJohn Marino   tree iter;
2994e4b17023SJohn Marino 
2995e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, *queue, i, iter)
2996e4b17023SJohn Marino     if (simple_cst_equal (iter, exp) == 1)
2997e4b17023SJohn Marino       break;
2998e4b17023SJohn Marino 
2999e4b17023SJohn Marino   if (!iter)
3000e4b17023SJohn Marino     VEC_safe_push (tree, heap, *queue, exp);
3001e4b17023SJohn Marino }
3002e4b17023SJohn Marino 
3003e4b17023SJohn Marino /* Given a tree EXP, find all occurences of references to fields
3004e4b17023SJohn Marino    in a PLACEHOLDER_EXPR and place them in vector REFS without
3005e4b17023SJohn Marino    duplicates.  Also record VAR_DECLs and CONST_DECLs.  Note that
3006e4b17023SJohn Marino    we assume here that EXP contains only arithmetic expressions
3007e4b17023SJohn Marino    or CALL_EXPRs with PLACEHOLDER_EXPRs occurring only in their
3008e4b17023SJohn Marino    argument list.  */
3009e4b17023SJohn Marino 
3010e4b17023SJohn Marino void
find_placeholder_in_expr(tree exp,VEC (tree,heap)** refs)3011e4b17023SJohn Marino find_placeholder_in_expr (tree exp, VEC (tree, heap) **refs)
3012e4b17023SJohn Marino {
3013e4b17023SJohn Marino   enum tree_code code = TREE_CODE (exp);
3014e4b17023SJohn Marino   tree inner;
3015e4b17023SJohn Marino   int i;
3016e4b17023SJohn Marino 
3017e4b17023SJohn Marino   /* We handle TREE_LIST and COMPONENT_REF separately.  */
3018e4b17023SJohn Marino   if (code == TREE_LIST)
3019e4b17023SJohn Marino     {
3020e4b17023SJohn Marino       FIND_PLACEHOLDER_IN_EXPR (TREE_CHAIN (exp), refs);
3021e4b17023SJohn Marino       FIND_PLACEHOLDER_IN_EXPR (TREE_VALUE (exp), refs);
3022e4b17023SJohn Marino     }
3023e4b17023SJohn Marino   else if (code == COMPONENT_REF)
3024e4b17023SJohn Marino     {
3025e4b17023SJohn Marino       for (inner = TREE_OPERAND (exp, 0);
3026e4b17023SJohn Marino 	   REFERENCE_CLASS_P (inner);
3027e4b17023SJohn Marino 	   inner = TREE_OPERAND (inner, 0))
3028e4b17023SJohn Marino 	;
3029e4b17023SJohn Marino 
3030e4b17023SJohn Marino       if (TREE_CODE (inner) == PLACEHOLDER_EXPR)
3031e4b17023SJohn Marino 	push_without_duplicates (exp, refs);
3032e4b17023SJohn Marino       else
3033e4b17023SJohn Marino 	FIND_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), refs);
3034e4b17023SJohn Marino    }
3035e4b17023SJohn Marino   else
3036e4b17023SJohn Marino     switch (TREE_CODE_CLASS (code))
3037e4b17023SJohn Marino       {
3038e4b17023SJohn Marino       case tcc_constant:
3039e4b17023SJohn Marino 	break;
3040e4b17023SJohn Marino 
3041e4b17023SJohn Marino       case tcc_declaration:
3042e4b17023SJohn Marino 	/* Variables allocated to static storage can stay.  */
3043e4b17023SJohn Marino         if (!TREE_STATIC (exp))
3044e4b17023SJohn Marino 	  push_without_duplicates (exp, refs);
3045e4b17023SJohn Marino 	break;
3046e4b17023SJohn Marino 
3047e4b17023SJohn Marino       case tcc_expression:
3048e4b17023SJohn Marino 	/* This is the pattern built in ada/make_aligning_type.  */
3049e4b17023SJohn Marino 	if (code == ADDR_EXPR
3050e4b17023SJohn Marino 	    && TREE_CODE (TREE_OPERAND (exp, 0)) == PLACEHOLDER_EXPR)
3051e4b17023SJohn Marino 	  {
3052e4b17023SJohn Marino 	    push_without_duplicates (exp, refs);
3053e4b17023SJohn Marino 	    break;
3054e4b17023SJohn Marino 	  }
3055e4b17023SJohn Marino 
3056e4b17023SJohn Marino         /* Fall through...  */
3057e4b17023SJohn Marino 
3058e4b17023SJohn Marino       case tcc_exceptional:
3059e4b17023SJohn Marino       case tcc_unary:
3060e4b17023SJohn Marino       case tcc_binary:
3061e4b17023SJohn Marino       case tcc_comparison:
3062e4b17023SJohn Marino       case tcc_reference:
3063e4b17023SJohn Marino 	for (i = 0; i < TREE_CODE_LENGTH (code); i++)
3064e4b17023SJohn Marino 	  FIND_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, i), refs);
3065e4b17023SJohn Marino 	break;
3066e4b17023SJohn Marino 
3067e4b17023SJohn Marino       case tcc_vl_exp:
3068e4b17023SJohn Marino 	for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
3069e4b17023SJohn Marino 	  FIND_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, i), refs);
3070e4b17023SJohn Marino 	break;
3071e4b17023SJohn Marino 
3072e4b17023SJohn Marino       default:
3073e4b17023SJohn Marino 	gcc_unreachable ();
3074e4b17023SJohn Marino       }
3075e4b17023SJohn Marino }
3076e4b17023SJohn Marino 
3077e4b17023SJohn Marino /* Given a tree EXP, a FIELD_DECL F, and a replacement value R,
3078e4b17023SJohn Marino    return a tree with all occurrences of references to F in a
3079e4b17023SJohn Marino    PLACEHOLDER_EXPR replaced by R.  Also handle VAR_DECLs and
3080e4b17023SJohn Marino    CONST_DECLs.  Note that we assume here that EXP contains only
3081e4b17023SJohn Marino    arithmetic expressions or CALL_EXPRs with PLACEHOLDER_EXPRs
3082e4b17023SJohn Marino    occurring only in their argument list.  */
3083e4b17023SJohn Marino 
3084e4b17023SJohn Marino tree
substitute_in_expr(tree exp,tree f,tree r)3085e4b17023SJohn Marino substitute_in_expr (tree exp, tree f, tree r)
3086e4b17023SJohn Marino {
3087e4b17023SJohn Marino   enum tree_code code = TREE_CODE (exp);
3088e4b17023SJohn Marino   tree op0, op1, op2, op3;
3089e4b17023SJohn Marino   tree new_tree;
3090e4b17023SJohn Marino 
3091e4b17023SJohn Marino   /* We handle TREE_LIST and COMPONENT_REF separately.  */
3092e4b17023SJohn Marino   if (code == TREE_LIST)
3093e4b17023SJohn Marino     {
3094e4b17023SJohn Marino       op0 = SUBSTITUTE_IN_EXPR (TREE_CHAIN (exp), f, r);
3095e4b17023SJohn Marino       op1 = SUBSTITUTE_IN_EXPR (TREE_VALUE (exp), f, r);
3096e4b17023SJohn Marino       if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
3097e4b17023SJohn Marino 	return exp;
3098e4b17023SJohn Marino 
3099e4b17023SJohn Marino       return tree_cons (TREE_PURPOSE (exp), op1, op0);
3100e4b17023SJohn Marino     }
3101e4b17023SJohn Marino   else if (code == COMPONENT_REF)
3102e4b17023SJohn Marino     {
3103e4b17023SJohn Marino       tree inner;
3104e4b17023SJohn Marino 
3105e4b17023SJohn Marino       /* If this expression is getting a value from a PLACEHOLDER_EXPR
3106e4b17023SJohn Marino 	 and it is the right field, replace it with R.  */
3107e4b17023SJohn Marino       for (inner = TREE_OPERAND (exp, 0);
3108e4b17023SJohn Marino 	   REFERENCE_CLASS_P (inner);
3109e4b17023SJohn Marino 	   inner = TREE_OPERAND (inner, 0))
3110e4b17023SJohn Marino 	;
3111e4b17023SJohn Marino 
3112e4b17023SJohn Marino       /* The field.  */
3113e4b17023SJohn Marino       op1 = TREE_OPERAND (exp, 1);
3114e4b17023SJohn Marino 
3115e4b17023SJohn Marino       if (TREE_CODE (inner) == PLACEHOLDER_EXPR && op1 == f)
3116e4b17023SJohn Marino 	return r;
3117e4b17023SJohn Marino 
3118e4b17023SJohn Marino       /* If this expression hasn't been completed let, leave it alone.  */
3119e4b17023SJohn Marino       if (TREE_CODE (inner) == PLACEHOLDER_EXPR && !TREE_TYPE (inner))
3120e4b17023SJohn Marino 	return exp;
3121e4b17023SJohn Marino 
3122e4b17023SJohn Marino       op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
3123e4b17023SJohn Marino       if (op0 == TREE_OPERAND (exp, 0))
3124e4b17023SJohn Marino 	return exp;
3125e4b17023SJohn Marino 
3126e4b17023SJohn Marino       new_tree
3127e4b17023SJohn Marino 	= fold_build3 (COMPONENT_REF, TREE_TYPE (exp), op0, op1, NULL_TREE);
3128e4b17023SJohn Marino    }
3129e4b17023SJohn Marino   else
3130e4b17023SJohn Marino     switch (TREE_CODE_CLASS (code))
3131e4b17023SJohn Marino       {
3132e4b17023SJohn Marino       case tcc_constant:
3133e4b17023SJohn Marino 	return exp;
3134e4b17023SJohn Marino 
3135e4b17023SJohn Marino       case tcc_declaration:
3136e4b17023SJohn Marino 	if (exp == f)
3137e4b17023SJohn Marino 	  return r;
3138e4b17023SJohn Marino 	else
3139e4b17023SJohn Marino 	  return exp;
3140e4b17023SJohn Marino 
3141e4b17023SJohn Marino       case tcc_expression:
3142e4b17023SJohn Marino 	if (exp == f)
3143e4b17023SJohn Marino 	  return r;
3144e4b17023SJohn Marino 
3145e4b17023SJohn Marino         /* Fall through...  */
3146e4b17023SJohn Marino 
3147e4b17023SJohn Marino       case tcc_exceptional:
3148e4b17023SJohn Marino       case tcc_unary:
3149e4b17023SJohn Marino       case tcc_binary:
3150e4b17023SJohn Marino       case tcc_comparison:
3151e4b17023SJohn Marino       case tcc_reference:
3152e4b17023SJohn Marino 	switch (TREE_CODE_LENGTH (code))
3153e4b17023SJohn Marino 	  {
3154e4b17023SJohn Marino 	  case 0:
3155e4b17023SJohn Marino 	    return exp;
3156e4b17023SJohn Marino 
3157e4b17023SJohn Marino 	  case 1:
3158e4b17023SJohn Marino 	    op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
3159e4b17023SJohn Marino 	    if (op0 == TREE_OPERAND (exp, 0))
3160e4b17023SJohn Marino 	      return exp;
3161e4b17023SJohn Marino 
3162e4b17023SJohn Marino 	    new_tree = fold_build1 (code, TREE_TYPE (exp), op0);
3163e4b17023SJohn Marino 	    break;
3164e4b17023SJohn Marino 
3165e4b17023SJohn Marino 	  case 2:
3166e4b17023SJohn Marino 	    op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
3167e4b17023SJohn Marino 	    op1 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 1), f, r);
3168e4b17023SJohn Marino 
3169e4b17023SJohn Marino 	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
3170e4b17023SJohn Marino 	      return exp;
3171e4b17023SJohn Marino 
3172e4b17023SJohn Marino 	    new_tree = fold_build2 (code, TREE_TYPE (exp), op0, op1);
3173e4b17023SJohn Marino 	    break;
3174e4b17023SJohn Marino 
3175e4b17023SJohn Marino 	  case 3:
3176e4b17023SJohn Marino 	    op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
3177e4b17023SJohn Marino 	    op1 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 1), f, r);
3178e4b17023SJohn Marino 	    op2 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 2), f, r);
3179e4b17023SJohn Marino 
3180e4b17023SJohn Marino 	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
3181e4b17023SJohn Marino 		&& op2 == TREE_OPERAND (exp, 2))
3182e4b17023SJohn Marino 	      return exp;
3183e4b17023SJohn Marino 
3184e4b17023SJohn Marino 	    new_tree = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
3185e4b17023SJohn Marino 	    break;
3186e4b17023SJohn Marino 
3187e4b17023SJohn Marino 	  case 4:
3188e4b17023SJohn Marino 	    op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
3189e4b17023SJohn Marino 	    op1 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 1), f, r);
3190e4b17023SJohn Marino 	    op2 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 2), f, r);
3191e4b17023SJohn Marino 	    op3 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 3), f, r);
3192e4b17023SJohn Marino 
3193e4b17023SJohn Marino 	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
3194e4b17023SJohn Marino 		&& op2 == TREE_OPERAND (exp, 2)
3195e4b17023SJohn Marino 		&& op3 == TREE_OPERAND (exp, 3))
3196e4b17023SJohn Marino 	      return exp;
3197e4b17023SJohn Marino 
3198e4b17023SJohn Marino 	    new_tree
3199e4b17023SJohn Marino 	      = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
3200e4b17023SJohn Marino 	    break;
3201e4b17023SJohn Marino 
3202e4b17023SJohn Marino 	  default:
3203e4b17023SJohn Marino 	    gcc_unreachable ();
3204e4b17023SJohn Marino 	  }
3205e4b17023SJohn Marino 	break;
3206e4b17023SJohn Marino 
3207e4b17023SJohn Marino       case tcc_vl_exp:
3208e4b17023SJohn Marino 	{
3209e4b17023SJohn Marino 	  int i;
3210e4b17023SJohn Marino 
3211e4b17023SJohn Marino 	  new_tree = NULL_TREE;
3212e4b17023SJohn Marino 
3213e4b17023SJohn Marino 	  /* If we are trying to replace F with a constant, inline back
3214e4b17023SJohn Marino 	     functions which do nothing else than computing a value from
3215e4b17023SJohn Marino 	     the arguments they are passed.  This makes it possible to
3216e4b17023SJohn Marino 	     fold partially or entirely the replacement expression.  */
3217e4b17023SJohn Marino 	  if (CONSTANT_CLASS_P (r) && code == CALL_EXPR)
3218e4b17023SJohn Marino 	    {
3219e4b17023SJohn Marino 	      tree t = maybe_inline_call_in_expr (exp);
3220e4b17023SJohn Marino 	      if (t)
3221e4b17023SJohn Marino 		return SUBSTITUTE_IN_EXPR (t, f, r);
3222e4b17023SJohn Marino 	    }
3223e4b17023SJohn Marino 
3224e4b17023SJohn Marino 	  for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
3225e4b17023SJohn Marino 	    {
3226e4b17023SJohn Marino 	      tree op = TREE_OPERAND (exp, i);
3227e4b17023SJohn Marino 	      tree new_op = SUBSTITUTE_IN_EXPR (op, f, r);
3228e4b17023SJohn Marino 	      if (new_op != op)
3229e4b17023SJohn Marino 		{
3230e4b17023SJohn Marino 		  if (!new_tree)
3231e4b17023SJohn Marino 		    new_tree = copy_node (exp);
3232e4b17023SJohn Marino 		  TREE_OPERAND (new_tree, i) = new_op;
3233e4b17023SJohn Marino 		}
3234e4b17023SJohn Marino 	    }
3235e4b17023SJohn Marino 
3236e4b17023SJohn Marino 	  if (new_tree)
3237e4b17023SJohn Marino 	    {
3238e4b17023SJohn Marino 	      new_tree = fold (new_tree);
3239e4b17023SJohn Marino 	      if (TREE_CODE (new_tree) == CALL_EXPR)
3240e4b17023SJohn Marino 		process_call_operands (new_tree);
3241e4b17023SJohn Marino 	    }
3242e4b17023SJohn Marino 	  else
3243e4b17023SJohn Marino 	    return exp;
3244e4b17023SJohn Marino 	}
3245e4b17023SJohn Marino 	break;
3246e4b17023SJohn Marino 
3247e4b17023SJohn Marino       default:
3248e4b17023SJohn Marino 	gcc_unreachable ();
3249e4b17023SJohn Marino       }
3250e4b17023SJohn Marino 
3251e4b17023SJohn Marino   TREE_READONLY (new_tree) |= TREE_READONLY (exp);
3252e4b17023SJohn Marino 
3253e4b17023SJohn Marino   if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
3254e4b17023SJohn Marino     TREE_THIS_NOTRAP (new_tree) |= TREE_THIS_NOTRAP (exp);
3255e4b17023SJohn Marino 
3256e4b17023SJohn Marino   return new_tree;
3257e4b17023SJohn Marino }
3258e4b17023SJohn Marino 
3259e4b17023SJohn Marino /* Similar, but look for a PLACEHOLDER_EXPR in EXP and find a replacement
3260e4b17023SJohn Marino    for it within OBJ, a tree that is an object or a chain of references.  */
3261e4b17023SJohn Marino 
3262e4b17023SJohn Marino tree
substitute_placeholder_in_expr(tree exp,tree obj)3263e4b17023SJohn Marino substitute_placeholder_in_expr (tree exp, tree obj)
3264e4b17023SJohn Marino {
3265e4b17023SJohn Marino   enum tree_code code = TREE_CODE (exp);
3266e4b17023SJohn Marino   tree op0, op1, op2, op3;
3267e4b17023SJohn Marino   tree new_tree;
3268e4b17023SJohn Marino 
3269e4b17023SJohn Marino   /* If this is a PLACEHOLDER_EXPR, see if we find a corresponding type
3270e4b17023SJohn Marino      in the chain of OBJ.  */
3271e4b17023SJohn Marino   if (code == PLACEHOLDER_EXPR)
3272e4b17023SJohn Marino     {
3273e4b17023SJohn Marino       tree need_type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
3274e4b17023SJohn Marino       tree elt;
3275e4b17023SJohn Marino 
3276e4b17023SJohn Marino       for (elt = obj; elt != 0;
3277e4b17023SJohn Marino 	   elt = ((TREE_CODE (elt) == COMPOUND_EXPR
3278e4b17023SJohn Marino 		   || TREE_CODE (elt) == COND_EXPR)
3279e4b17023SJohn Marino 		  ? TREE_OPERAND (elt, 1)
3280e4b17023SJohn Marino 		  : (REFERENCE_CLASS_P (elt)
3281e4b17023SJohn Marino 		     || UNARY_CLASS_P (elt)
3282e4b17023SJohn Marino 		     || BINARY_CLASS_P (elt)
3283e4b17023SJohn Marino 		     || VL_EXP_CLASS_P (elt)
3284e4b17023SJohn Marino 		     || EXPRESSION_CLASS_P (elt))
3285e4b17023SJohn Marino 		  ? TREE_OPERAND (elt, 0) : 0))
3286e4b17023SJohn Marino 	if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
3287e4b17023SJohn Marino 	  return elt;
3288e4b17023SJohn Marino 
3289e4b17023SJohn Marino       for (elt = obj; elt != 0;
3290e4b17023SJohn Marino 	   elt = ((TREE_CODE (elt) == COMPOUND_EXPR
3291e4b17023SJohn Marino 		   || TREE_CODE (elt) == COND_EXPR)
3292e4b17023SJohn Marino 		  ? TREE_OPERAND (elt, 1)
3293e4b17023SJohn Marino 		  : (REFERENCE_CLASS_P (elt)
3294e4b17023SJohn Marino 		     || UNARY_CLASS_P (elt)
3295e4b17023SJohn Marino 		     || BINARY_CLASS_P (elt)
3296e4b17023SJohn Marino 		     || VL_EXP_CLASS_P (elt)
3297e4b17023SJohn Marino 		     || EXPRESSION_CLASS_P (elt))
3298e4b17023SJohn Marino 		  ? TREE_OPERAND (elt, 0) : 0))
3299e4b17023SJohn Marino 	if (POINTER_TYPE_P (TREE_TYPE (elt))
3300e4b17023SJohn Marino 	    && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
3301e4b17023SJohn Marino 		== need_type))
3302e4b17023SJohn Marino 	  return fold_build1 (INDIRECT_REF, need_type, elt);
3303e4b17023SJohn Marino 
3304e4b17023SJohn Marino       /* If we didn't find it, return the original PLACEHOLDER_EXPR.  If it
3305e4b17023SJohn Marino 	 survives until RTL generation, there will be an error.  */
3306e4b17023SJohn Marino       return exp;
3307e4b17023SJohn Marino     }
3308e4b17023SJohn Marino 
3309e4b17023SJohn Marino   /* TREE_LIST is special because we need to look at TREE_VALUE
3310e4b17023SJohn Marino      and TREE_CHAIN, not TREE_OPERANDS.  */
3311e4b17023SJohn Marino   else if (code == TREE_LIST)
3312e4b17023SJohn Marino     {
3313e4b17023SJohn Marino       op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_CHAIN (exp), obj);
3314e4b17023SJohn Marino       op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_VALUE (exp), obj);
3315e4b17023SJohn Marino       if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
3316e4b17023SJohn Marino 	return exp;
3317e4b17023SJohn Marino 
3318e4b17023SJohn Marino       return tree_cons (TREE_PURPOSE (exp), op1, op0);
3319e4b17023SJohn Marino     }
3320e4b17023SJohn Marino   else
3321e4b17023SJohn Marino     switch (TREE_CODE_CLASS (code))
3322e4b17023SJohn Marino       {
3323e4b17023SJohn Marino       case tcc_constant:
3324e4b17023SJohn Marino       case tcc_declaration:
3325e4b17023SJohn Marino 	return exp;
3326e4b17023SJohn Marino 
3327e4b17023SJohn Marino       case tcc_exceptional:
3328e4b17023SJohn Marino       case tcc_unary:
3329e4b17023SJohn Marino       case tcc_binary:
3330e4b17023SJohn Marino       case tcc_comparison:
3331e4b17023SJohn Marino       case tcc_expression:
3332e4b17023SJohn Marino       case tcc_reference:
3333e4b17023SJohn Marino       case tcc_statement:
3334e4b17023SJohn Marino 	switch (TREE_CODE_LENGTH (code))
3335e4b17023SJohn Marino 	  {
3336e4b17023SJohn Marino 	  case 0:
3337e4b17023SJohn Marino 	    return exp;
3338e4b17023SJohn Marino 
3339e4b17023SJohn Marino 	  case 1:
3340e4b17023SJohn Marino 	    op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
3341e4b17023SJohn Marino 	    if (op0 == TREE_OPERAND (exp, 0))
3342e4b17023SJohn Marino 	      return exp;
3343e4b17023SJohn Marino 
3344e4b17023SJohn Marino 	    new_tree = fold_build1 (code, TREE_TYPE (exp), op0);
3345e4b17023SJohn Marino 	    break;
3346e4b17023SJohn Marino 
3347e4b17023SJohn Marino 	  case 2:
3348e4b17023SJohn Marino 	    op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
3349e4b17023SJohn Marino 	    op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 1), obj);
3350e4b17023SJohn Marino 
3351e4b17023SJohn Marino 	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
3352e4b17023SJohn Marino 	      return exp;
3353e4b17023SJohn Marino 
3354e4b17023SJohn Marino 	    new_tree = fold_build2 (code, TREE_TYPE (exp), op0, op1);
3355e4b17023SJohn Marino 	    break;
3356e4b17023SJohn Marino 
3357e4b17023SJohn Marino 	  case 3:
3358e4b17023SJohn Marino 	    op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
3359e4b17023SJohn Marino 	    op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 1), obj);
3360e4b17023SJohn Marino 	    op2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 2), obj);
3361e4b17023SJohn Marino 
3362e4b17023SJohn Marino 	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
3363e4b17023SJohn Marino 		&& op2 == TREE_OPERAND (exp, 2))
3364e4b17023SJohn Marino 	      return exp;
3365e4b17023SJohn Marino 
3366e4b17023SJohn Marino 	    new_tree = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
3367e4b17023SJohn Marino 	    break;
3368e4b17023SJohn Marino 
3369e4b17023SJohn Marino 	  case 4:
3370e4b17023SJohn Marino 	    op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
3371e4b17023SJohn Marino 	    op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 1), obj);
3372e4b17023SJohn Marino 	    op2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 2), obj);
3373e4b17023SJohn Marino 	    op3 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 3), obj);
3374e4b17023SJohn Marino 
3375e4b17023SJohn Marino 	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
3376e4b17023SJohn Marino 		&& op2 == TREE_OPERAND (exp, 2)
3377e4b17023SJohn Marino 		&& op3 == TREE_OPERAND (exp, 3))
3378e4b17023SJohn Marino 	      return exp;
3379e4b17023SJohn Marino 
3380e4b17023SJohn Marino 	    new_tree
3381e4b17023SJohn Marino 	      = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
3382e4b17023SJohn Marino 	    break;
3383e4b17023SJohn Marino 
3384e4b17023SJohn Marino 	  default:
3385e4b17023SJohn Marino 	    gcc_unreachable ();
3386e4b17023SJohn Marino 	  }
3387e4b17023SJohn Marino 	break;
3388e4b17023SJohn Marino 
3389e4b17023SJohn Marino       case tcc_vl_exp:
3390e4b17023SJohn Marino 	{
3391e4b17023SJohn Marino 	  int i;
3392e4b17023SJohn Marino 
3393e4b17023SJohn Marino 	  new_tree = NULL_TREE;
3394e4b17023SJohn Marino 
3395e4b17023SJohn Marino 	  for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
3396e4b17023SJohn Marino 	    {
3397e4b17023SJohn Marino 	      tree op = TREE_OPERAND (exp, i);
3398e4b17023SJohn Marino 	      tree new_op = SUBSTITUTE_PLACEHOLDER_IN_EXPR (op, obj);
3399e4b17023SJohn Marino 	      if (new_op != op)
3400e4b17023SJohn Marino 		{
3401e4b17023SJohn Marino 		  if (!new_tree)
3402e4b17023SJohn Marino 		    new_tree = copy_node (exp);
3403e4b17023SJohn Marino 		  TREE_OPERAND (new_tree, i) = new_op;
3404e4b17023SJohn Marino 		}
3405e4b17023SJohn Marino 	    }
3406e4b17023SJohn Marino 
3407e4b17023SJohn Marino 	  if (new_tree)
3408e4b17023SJohn Marino 	    {
3409e4b17023SJohn Marino 	      new_tree = fold (new_tree);
3410e4b17023SJohn Marino 	      if (TREE_CODE (new_tree) == CALL_EXPR)
3411e4b17023SJohn Marino 		process_call_operands (new_tree);
3412e4b17023SJohn Marino 	    }
3413e4b17023SJohn Marino 	  else
3414e4b17023SJohn Marino 	    return exp;
3415e4b17023SJohn Marino 	}
3416e4b17023SJohn Marino 	break;
3417e4b17023SJohn Marino 
3418e4b17023SJohn Marino       default:
3419e4b17023SJohn Marino 	gcc_unreachable ();
3420e4b17023SJohn Marino       }
3421e4b17023SJohn Marino 
3422e4b17023SJohn Marino   TREE_READONLY (new_tree) |= TREE_READONLY (exp);
3423e4b17023SJohn Marino 
3424e4b17023SJohn Marino   if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
3425e4b17023SJohn Marino     TREE_THIS_NOTRAP (new_tree) |= TREE_THIS_NOTRAP (exp);
3426e4b17023SJohn Marino 
3427e4b17023SJohn Marino   return new_tree;
3428e4b17023SJohn Marino }
3429e4b17023SJohn Marino 
3430e4b17023SJohn Marino /* Stabilize a reference so that we can use it any number of times
3431e4b17023SJohn Marino    without causing its operands to be evaluated more than once.
3432e4b17023SJohn Marino    Returns the stabilized reference.  This works by means of save_expr,
3433e4b17023SJohn Marino    so see the caveats in the comments about save_expr.
3434e4b17023SJohn Marino 
3435e4b17023SJohn Marino    Also allows conversion expressions whose operands are references.
3436e4b17023SJohn Marino    Any other kind of expression is returned unchanged.  */
3437e4b17023SJohn Marino 
3438e4b17023SJohn Marino tree
stabilize_reference(tree ref)3439e4b17023SJohn Marino stabilize_reference (tree ref)
3440e4b17023SJohn Marino {
3441e4b17023SJohn Marino   tree result;
3442e4b17023SJohn Marino   enum tree_code code = TREE_CODE (ref);
3443e4b17023SJohn Marino 
3444e4b17023SJohn Marino   switch (code)
3445e4b17023SJohn Marino     {
3446e4b17023SJohn Marino     case VAR_DECL:
3447e4b17023SJohn Marino     case PARM_DECL:
3448e4b17023SJohn Marino     case RESULT_DECL:
3449e4b17023SJohn Marino       /* No action is needed in this case.  */
3450e4b17023SJohn Marino       return ref;
3451e4b17023SJohn Marino 
3452e4b17023SJohn Marino     CASE_CONVERT:
3453e4b17023SJohn Marino     case FLOAT_EXPR:
3454e4b17023SJohn Marino     case FIX_TRUNC_EXPR:
3455e4b17023SJohn Marino       result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
3456e4b17023SJohn Marino       break;
3457e4b17023SJohn Marino 
3458e4b17023SJohn Marino     case INDIRECT_REF:
3459e4b17023SJohn Marino       result = build_nt (INDIRECT_REF,
3460e4b17023SJohn Marino 			 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
3461e4b17023SJohn Marino       break;
3462e4b17023SJohn Marino 
3463e4b17023SJohn Marino     case COMPONENT_REF:
3464e4b17023SJohn Marino       result = build_nt (COMPONENT_REF,
3465e4b17023SJohn Marino 			 stabilize_reference (TREE_OPERAND (ref, 0)),
3466e4b17023SJohn Marino 			 TREE_OPERAND (ref, 1), NULL_TREE);
3467e4b17023SJohn Marino       break;
3468e4b17023SJohn Marino 
3469e4b17023SJohn Marino     case BIT_FIELD_REF:
3470e4b17023SJohn Marino       result = build_nt (BIT_FIELD_REF,
3471e4b17023SJohn Marino 			 stabilize_reference (TREE_OPERAND (ref, 0)),
3472e4b17023SJohn Marino 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
3473e4b17023SJohn Marino 			 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
3474e4b17023SJohn Marino       break;
3475e4b17023SJohn Marino 
3476e4b17023SJohn Marino     case ARRAY_REF:
3477e4b17023SJohn Marino       result = build_nt (ARRAY_REF,
3478e4b17023SJohn Marino 			 stabilize_reference (TREE_OPERAND (ref, 0)),
3479e4b17023SJohn Marino 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
3480e4b17023SJohn Marino 			 TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
3481e4b17023SJohn Marino       break;
3482e4b17023SJohn Marino 
3483e4b17023SJohn Marino     case ARRAY_RANGE_REF:
3484e4b17023SJohn Marino       result = build_nt (ARRAY_RANGE_REF,
3485e4b17023SJohn Marino 			 stabilize_reference (TREE_OPERAND (ref, 0)),
3486e4b17023SJohn Marino 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
3487e4b17023SJohn Marino 			 TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
3488e4b17023SJohn Marino       break;
3489e4b17023SJohn Marino 
3490e4b17023SJohn Marino     case COMPOUND_EXPR:
3491e4b17023SJohn Marino       /* We cannot wrap the first expression in a SAVE_EXPR, as then
3492e4b17023SJohn Marino 	 it wouldn't be ignored.  This matters when dealing with
3493e4b17023SJohn Marino 	 volatiles.  */
3494e4b17023SJohn Marino       return stabilize_reference_1 (ref);
3495e4b17023SJohn Marino 
3496e4b17023SJohn Marino       /* If arg isn't a kind of lvalue we recognize, make no change.
3497e4b17023SJohn Marino 	 Caller should recognize the error for an invalid lvalue.  */
3498e4b17023SJohn Marino     default:
3499e4b17023SJohn Marino       return ref;
3500e4b17023SJohn Marino 
3501e4b17023SJohn Marino     case ERROR_MARK:
3502e4b17023SJohn Marino       return error_mark_node;
3503e4b17023SJohn Marino     }
3504e4b17023SJohn Marino 
3505e4b17023SJohn Marino   TREE_TYPE (result) = TREE_TYPE (ref);
3506e4b17023SJohn Marino   TREE_READONLY (result) = TREE_READONLY (ref);
3507e4b17023SJohn Marino   TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
3508e4b17023SJohn Marino   TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
3509e4b17023SJohn Marino 
3510e4b17023SJohn Marino   return result;
3511e4b17023SJohn Marino }
3512e4b17023SJohn Marino 
3513e4b17023SJohn Marino /* Subroutine of stabilize_reference; this is called for subtrees of
3514e4b17023SJohn Marino    references.  Any expression with side-effects must be put in a SAVE_EXPR
3515e4b17023SJohn Marino    to ensure that it is only evaluated once.
3516e4b17023SJohn Marino 
3517e4b17023SJohn Marino    We don't put SAVE_EXPR nodes around everything, because assigning very
3518e4b17023SJohn Marino    simple expressions to temporaries causes us to miss good opportunities
3519e4b17023SJohn Marino    for optimizations.  Among other things, the opportunity to fold in the
3520e4b17023SJohn Marino    addition of a constant into an addressing mode often gets lost, e.g.
3521e4b17023SJohn Marino    "y[i+1] += x;".  In general, we take the approach that we should not make
3522e4b17023SJohn Marino    an assignment unless we are forced into it - i.e., that any non-side effect
3523e4b17023SJohn Marino    operator should be allowed, and that cse should take care of coalescing
3524e4b17023SJohn Marino    multiple utterances of the same expression should that prove fruitful.  */
3525e4b17023SJohn Marino 
3526e4b17023SJohn Marino tree
stabilize_reference_1(tree e)3527e4b17023SJohn Marino stabilize_reference_1 (tree e)
3528e4b17023SJohn Marino {
3529e4b17023SJohn Marino   tree result;
3530e4b17023SJohn Marino   enum tree_code code = TREE_CODE (e);
3531e4b17023SJohn Marino 
3532e4b17023SJohn Marino   /* We cannot ignore const expressions because it might be a reference
3533e4b17023SJohn Marino      to a const array but whose index contains side-effects.  But we can
3534e4b17023SJohn Marino      ignore things that are actual constant or that already have been
3535e4b17023SJohn Marino      handled by this function.  */
3536e4b17023SJohn Marino 
3537e4b17023SJohn Marino   if (tree_invariant_p (e))
3538e4b17023SJohn Marino     return e;
3539e4b17023SJohn Marino 
3540e4b17023SJohn Marino   switch (TREE_CODE_CLASS (code))
3541e4b17023SJohn Marino     {
3542e4b17023SJohn Marino     case tcc_exceptional:
3543e4b17023SJohn Marino     case tcc_type:
3544e4b17023SJohn Marino     case tcc_declaration:
3545e4b17023SJohn Marino     case tcc_comparison:
3546e4b17023SJohn Marino     case tcc_statement:
3547e4b17023SJohn Marino     case tcc_expression:
3548e4b17023SJohn Marino     case tcc_reference:
3549e4b17023SJohn Marino     case tcc_vl_exp:
3550e4b17023SJohn Marino       /* If the expression has side-effects, then encase it in a SAVE_EXPR
3551e4b17023SJohn Marino 	 so that it will only be evaluated once.  */
3552e4b17023SJohn Marino       /* The reference (r) and comparison (<) classes could be handled as
3553e4b17023SJohn Marino 	 below, but it is generally faster to only evaluate them once.  */
3554e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (e))
3555e4b17023SJohn Marino 	return save_expr (e);
3556e4b17023SJohn Marino       return e;
3557e4b17023SJohn Marino 
3558e4b17023SJohn Marino     case tcc_constant:
3559e4b17023SJohn Marino       /* Constants need no processing.  In fact, we should never reach
3560e4b17023SJohn Marino 	 here.  */
3561e4b17023SJohn Marino       return e;
3562e4b17023SJohn Marino 
3563e4b17023SJohn Marino     case tcc_binary:
3564e4b17023SJohn Marino       /* Division is slow and tends to be compiled with jumps,
3565e4b17023SJohn Marino 	 especially the division by powers of 2 that is often
3566e4b17023SJohn Marino 	 found inside of an array reference.  So do it just once.  */
3567e4b17023SJohn Marino       if (code == TRUNC_DIV_EXPR || code == TRUNC_MOD_EXPR
3568e4b17023SJohn Marino 	  || code == FLOOR_DIV_EXPR || code == FLOOR_MOD_EXPR
3569e4b17023SJohn Marino 	  || code == CEIL_DIV_EXPR || code == CEIL_MOD_EXPR
3570e4b17023SJohn Marino 	  || code == ROUND_DIV_EXPR || code == ROUND_MOD_EXPR)
3571e4b17023SJohn Marino 	return save_expr (e);
3572e4b17023SJohn Marino       /* Recursively stabilize each operand.  */
3573e4b17023SJohn Marino       result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)),
3574e4b17023SJohn Marino 			 stabilize_reference_1 (TREE_OPERAND (e, 1)));
3575e4b17023SJohn Marino       break;
3576e4b17023SJohn Marino 
3577e4b17023SJohn Marino     case tcc_unary:
3578e4b17023SJohn Marino       /* Recursively stabilize each operand.  */
3579e4b17023SJohn Marino       result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)));
3580e4b17023SJohn Marino       break;
3581e4b17023SJohn Marino 
3582e4b17023SJohn Marino     default:
3583e4b17023SJohn Marino       gcc_unreachable ();
3584e4b17023SJohn Marino     }
3585e4b17023SJohn Marino 
3586e4b17023SJohn Marino   TREE_TYPE (result) = TREE_TYPE (e);
3587e4b17023SJohn Marino   TREE_READONLY (result) = TREE_READONLY (e);
3588e4b17023SJohn Marino   TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
3589e4b17023SJohn Marino   TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
3590e4b17023SJohn Marino 
3591e4b17023SJohn Marino   return result;
3592e4b17023SJohn Marino }
3593e4b17023SJohn Marino 
3594e4b17023SJohn Marino /* Low-level constructors for expressions.  */
3595e4b17023SJohn Marino 
3596e4b17023SJohn Marino /* A helper function for build1 and constant folders.  Set TREE_CONSTANT,
3597e4b17023SJohn Marino    and TREE_SIDE_EFFECTS for an ADDR_EXPR.  */
3598e4b17023SJohn Marino 
3599e4b17023SJohn Marino void
recompute_tree_invariant_for_addr_expr(tree t)3600e4b17023SJohn Marino recompute_tree_invariant_for_addr_expr (tree t)
3601e4b17023SJohn Marino {
3602e4b17023SJohn Marino   tree node;
3603e4b17023SJohn Marino   bool tc = true, se = false;
3604e4b17023SJohn Marino 
3605e4b17023SJohn Marino   /* We started out assuming this address is both invariant and constant, but
3606e4b17023SJohn Marino      does not have side effects.  Now go down any handled components and see if
3607e4b17023SJohn Marino      any of them involve offsets that are either non-constant or non-invariant.
3608e4b17023SJohn Marino      Also check for side-effects.
3609e4b17023SJohn Marino 
3610e4b17023SJohn Marino      ??? Note that this code makes no attempt to deal with the case where
3611e4b17023SJohn Marino      taking the address of something causes a copy due to misalignment.  */
3612e4b17023SJohn Marino 
3613e4b17023SJohn Marino #define UPDATE_FLAGS(NODE)  \
3614e4b17023SJohn Marino do { tree _node = (NODE); \
3615e4b17023SJohn Marino      if (_node && !TREE_CONSTANT (_node)) tc = false; \
3616e4b17023SJohn Marino      if (_node && TREE_SIDE_EFFECTS (_node)) se = true; } while (0)
3617e4b17023SJohn Marino 
3618e4b17023SJohn Marino   for (node = TREE_OPERAND (t, 0); handled_component_p (node);
3619e4b17023SJohn Marino        node = TREE_OPERAND (node, 0))
3620e4b17023SJohn Marino     {
3621e4b17023SJohn Marino       /* If the first operand doesn't have an ARRAY_TYPE, this is a bogus
3622e4b17023SJohn Marino 	 array reference (probably made temporarily by the G++ front end),
3623e4b17023SJohn Marino 	 so ignore all the operands.  */
3624e4b17023SJohn Marino       if ((TREE_CODE (node) == ARRAY_REF
3625e4b17023SJohn Marino 	   || TREE_CODE (node) == ARRAY_RANGE_REF)
3626e4b17023SJohn Marino 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (node, 0))) == ARRAY_TYPE)
3627e4b17023SJohn Marino 	{
3628e4b17023SJohn Marino 	  UPDATE_FLAGS (TREE_OPERAND (node, 1));
3629e4b17023SJohn Marino 	  if (TREE_OPERAND (node, 2))
3630e4b17023SJohn Marino 	    UPDATE_FLAGS (TREE_OPERAND (node, 2));
3631e4b17023SJohn Marino 	  if (TREE_OPERAND (node, 3))
3632e4b17023SJohn Marino 	    UPDATE_FLAGS (TREE_OPERAND (node, 3));
3633e4b17023SJohn Marino 	}
3634e4b17023SJohn Marino       /* Likewise, just because this is a COMPONENT_REF doesn't mean we have a
3635e4b17023SJohn Marino 	 FIELD_DECL, apparently.  The G++ front end can put something else
3636e4b17023SJohn Marino 	 there, at least temporarily.  */
3637e4b17023SJohn Marino       else if (TREE_CODE (node) == COMPONENT_REF
3638e4b17023SJohn Marino 	       && TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL)
3639e4b17023SJohn Marino 	{
3640e4b17023SJohn Marino 	  if (TREE_OPERAND (node, 2))
3641e4b17023SJohn Marino 	    UPDATE_FLAGS (TREE_OPERAND (node, 2));
3642e4b17023SJohn Marino 	}
3643e4b17023SJohn Marino       else if (TREE_CODE (node) == BIT_FIELD_REF)
3644e4b17023SJohn Marino 	UPDATE_FLAGS (TREE_OPERAND (node, 2));
3645e4b17023SJohn Marino     }
3646e4b17023SJohn Marino 
3647e4b17023SJohn Marino   node = lang_hooks.expr_to_decl (node, &tc, &se);
3648e4b17023SJohn Marino 
3649e4b17023SJohn Marino   /* Now see what's inside.  If it's an INDIRECT_REF, copy our properties from
3650e4b17023SJohn Marino      the address, since &(*a)->b is a form of addition.  If it's a constant, the
3651e4b17023SJohn Marino      address is constant too.  If it's a decl, its address is constant if the
3652e4b17023SJohn Marino      decl is static.  Everything else is not constant and, furthermore,
3653e4b17023SJohn Marino      taking the address of a volatile variable is not volatile.  */
3654e4b17023SJohn Marino   if (TREE_CODE (node) == INDIRECT_REF
3655e4b17023SJohn Marino       || TREE_CODE (node) == MEM_REF)
3656e4b17023SJohn Marino     UPDATE_FLAGS (TREE_OPERAND (node, 0));
3657e4b17023SJohn Marino   else if (CONSTANT_CLASS_P (node))
3658e4b17023SJohn Marino     ;
3659e4b17023SJohn Marino   else if (DECL_P (node))
3660e4b17023SJohn Marino     tc &= (staticp (node) != NULL_TREE);
3661e4b17023SJohn Marino   else
3662e4b17023SJohn Marino     {
3663e4b17023SJohn Marino       tc = false;
3664e4b17023SJohn Marino       se |= TREE_SIDE_EFFECTS (node);
3665e4b17023SJohn Marino     }
3666e4b17023SJohn Marino 
3667e4b17023SJohn Marino 
3668e4b17023SJohn Marino   TREE_CONSTANT (t) = tc;
3669e4b17023SJohn Marino   TREE_SIDE_EFFECTS (t) = se;
3670e4b17023SJohn Marino #undef UPDATE_FLAGS
3671e4b17023SJohn Marino }
3672e4b17023SJohn Marino 
3673e4b17023SJohn Marino /* Build an expression of code CODE, data type TYPE, and operands as
3674e4b17023SJohn Marino    specified.  Expressions and reference nodes can be created this way.
3675e4b17023SJohn Marino    Constants, decls, types and misc nodes cannot be.
3676e4b17023SJohn Marino 
3677e4b17023SJohn Marino    We define 5 non-variadic functions, from 0 to 4 arguments.  This is
3678e4b17023SJohn Marino    enough for all extant tree codes.  */
3679e4b17023SJohn Marino 
3680e4b17023SJohn Marino tree
build0_stat(enum tree_code code,tree tt MEM_STAT_DECL)3681e4b17023SJohn Marino build0_stat (enum tree_code code, tree tt MEM_STAT_DECL)
3682e4b17023SJohn Marino {
3683e4b17023SJohn Marino   tree t;
3684e4b17023SJohn Marino 
3685e4b17023SJohn Marino   gcc_assert (TREE_CODE_LENGTH (code) == 0);
3686e4b17023SJohn Marino 
3687e4b17023SJohn Marino   t = make_node_stat (code PASS_MEM_STAT);
3688e4b17023SJohn Marino   TREE_TYPE (t) = tt;
3689e4b17023SJohn Marino 
3690e4b17023SJohn Marino   return t;
3691e4b17023SJohn Marino }
3692e4b17023SJohn Marino 
3693e4b17023SJohn Marino tree
build1_stat(enum tree_code code,tree type,tree node MEM_STAT_DECL)3694e4b17023SJohn Marino build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
3695e4b17023SJohn Marino {
3696e4b17023SJohn Marino   int length = sizeof (struct tree_exp);
3697e4b17023SJohn Marino   tree t;
3698e4b17023SJohn Marino 
3699e4b17023SJohn Marino   record_node_allocation_statistics (code, length);
3700e4b17023SJohn Marino 
3701e4b17023SJohn Marino   gcc_assert (TREE_CODE_LENGTH (code) == 1);
3702e4b17023SJohn Marino 
3703e4b17023SJohn Marino   t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
3704e4b17023SJohn Marino 
3705e4b17023SJohn Marino   memset (t, 0, sizeof (struct tree_common));
3706e4b17023SJohn Marino 
3707e4b17023SJohn Marino   TREE_SET_CODE (t, code);
3708e4b17023SJohn Marino 
3709e4b17023SJohn Marino   TREE_TYPE (t) = type;
3710e4b17023SJohn Marino   SET_EXPR_LOCATION (t, UNKNOWN_LOCATION);
3711e4b17023SJohn Marino   TREE_OPERAND (t, 0) = node;
3712e4b17023SJohn Marino   TREE_BLOCK (t) = NULL_TREE;
3713e4b17023SJohn Marino   if (node && !TYPE_P (node))
3714e4b17023SJohn Marino     {
3715e4b17023SJohn Marino       TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
3716e4b17023SJohn Marino       TREE_READONLY (t) = TREE_READONLY (node);
3717e4b17023SJohn Marino     }
3718e4b17023SJohn Marino 
3719e4b17023SJohn Marino   if (TREE_CODE_CLASS (code) == tcc_statement)
3720e4b17023SJohn Marino     TREE_SIDE_EFFECTS (t) = 1;
3721e4b17023SJohn Marino   else switch (code)
3722e4b17023SJohn Marino     {
3723e4b17023SJohn Marino     case VA_ARG_EXPR:
3724e4b17023SJohn Marino       /* All of these have side-effects, no matter what their
3725e4b17023SJohn Marino 	 operands are.  */
3726e4b17023SJohn Marino       TREE_SIDE_EFFECTS (t) = 1;
3727e4b17023SJohn Marino       TREE_READONLY (t) = 0;
3728e4b17023SJohn Marino       break;
3729e4b17023SJohn Marino 
3730e4b17023SJohn Marino     case INDIRECT_REF:
3731e4b17023SJohn Marino       /* Whether a dereference is readonly has nothing to do with whether
3732e4b17023SJohn Marino 	 its operand is readonly.  */
3733e4b17023SJohn Marino       TREE_READONLY (t) = 0;
3734e4b17023SJohn Marino       break;
3735e4b17023SJohn Marino 
3736e4b17023SJohn Marino     case ADDR_EXPR:
3737e4b17023SJohn Marino       if (node)
3738e4b17023SJohn Marino 	recompute_tree_invariant_for_addr_expr (t);
3739e4b17023SJohn Marino       break;
3740e4b17023SJohn Marino 
3741e4b17023SJohn Marino     default:
3742e4b17023SJohn Marino       if ((TREE_CODE_CLASS (code) == tcc_unary || code == VIEW_CONVERT_EXPR)
3743e4b17023SJohn Marino 	  && node && !TYPE_P (node)
3744e4b17023SJohn Marino 	  && TREE_CONSTANT (node))
3745e4b17023SJohn Marino 	TREE_CONSTANT (t) = 1;
3746e4b17023SJohn Marino       if (TREE_CODE_CLASS (code) == tcc_reference
3747e4b17023SJohn Marino 	  && node && TREE_THIS_VOLATILE (node))
3748e4b17023SJohn Marino 	TREE_THIS_VOLATILE (t) = 1;
3749e4b17023SJohn Marino       break;
3750e4b17023SJohn Marino     }
3751e4b17023SJohn Marino 
3752e4b17023SJohn Marino   return t;
3753e4b17023SJohn Marino }
3754e4b17023SJohn Marino 
3755e4b17023SJohn Marino #define PROCESS_ARG(N)				\
3756e4b17023SJohn Marino   do {						\
3757e4b17023SJohn Marino     TREE_OPERAND (t, N) = arg##N;		\
3758e4b17023SJohn Marino     if (arg##N &&!TYPE_P (arg##N))		\
3759e4b17023SJohn Marino       {						\
3760e4b17023SJohn Marino         if (TREE_SIDE_EFFECTS (arg##N))		\
3761e4b17023SJohn Marino 	  side_effects = 1;			\
3762e4b17023SJohn Marino         if (!TREE_READONLY (arg##N)		\
3763e4b17023SJohn Marino 	    && !CONSTANT_CLASS_P (arg##N))	\
3764e4b17023SJohn Marino 	  (void) (read_only = 0);		\
3765e4b17023SJohn Marino         if (!TREE_CONSTANT (arg##N))		\
3766e4b17023SJohn Marino 	  (void) (constant = 0);		\
3767e4b17023SJohn Marino       }						\
3768e4b17023SJohn Marino   } while (0)
3769e4b17023SJohn Marino 
3770e4b17023SJohn Marino tree
build2_stat(enum tree_code code,tree tt,tree arg0,tree arg1 MEM_STAT_DECL)3771e4b17023SJohn Marino build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
3772e4b17023SJohn Marino {
3773e4b17023SJohn Marino   bool constant, read_only, side_effects;
3774e4b17023SJohn Marino   tree t;
3775e4b17023SJohn Marino 
3776e4b17023SJohn Marino   gcc_assert (TREE_CODE_LENGTH (code) == 2);
3777e4b17023SJohn Marino 
3778e4b17023SJohn Marino   if ((code == MINUS_EXPR || code == PLUS_EXPR || code == MULT_EXPR)
3779e4b17023SJohn Marino       && arg0 && arg1 && tt && POINTER_TYPE_P (tt)
3780e4b17023SJohn Marino       /* When sizetype precision doesn't match that of pointers
3781e4b17023SJohn Marino          we need to be able to build explicit extensions or truncations
3782e4b17023SJohn Marino 	 of the offset argument.  */
3783e4b17023SJohn Marino       && TYPE_PRECISION (sizetype) == TYPE_PRECISION (tt))
3784e4b17023SJohn Marino     gcc_assert (TREE_CODE (arg0) == INTEGER_CST
3785e4b17023SJohn Marino 		&& TREE_CODE (arg1) == INTEGER_CST);
3786e4b17023SJohn Marino 
3787e4b17023SJohn Marino   if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt)
3788e4b17023SJohn Marino     gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0))
3789e4b17023SJohn Marino 		&& ptrofftype_p (TREE_TYPE (arg1)));
3790e4b17023SJohn Marino 
3791e4b17023SJohn Marino   t = make_node_stat (code PASS_MEM_STAT);
3792e4b17023SJohn Marino   TREE_TYPE (t) = tt;
3793e4b17023SJohn Marino 
3794e4b17023SJohn Marino   /* Below, we automatically set TREE_SIDE_EFFECTS and TREE_READONLY for the
3795e4b17023SJohn Marino      result based on those same flags for the arguments.  But if the
3796e4b17023SJohn Marino      arguments aren't really even `tree' expressions, we shouldn't be trying
3797e4b17023SJohn Marino      to do this.  */
3798e4b17023SJohn Marino 
3799e4b17023SJohn Marino   /* Expressions without side effects may be constant if their
3800e4b17023SJohn Marino      arguments are as well.  */
3801e4b17023SJohn Marino   constant = (TREE_CODE_CLASS (code) == tcc_comparison
3802e4b17023SJohn Marino 	      || TREE_CODE_CLASS (code) == tcc_binary);
3803e4b17023SJohn Marino   read_only = 1;
3804e4b17023SJohn Marino   side_effects = TREE_SIDE_EFFECTS (t);
3805e4b17023SJohn Marino 
3806e4b17023SJohn Marino   PROCESS_ARG(0);
3807e4b17023SJohn Marino   PROCESS_ARG(1);
3808e4b17023SJohn Marino 
3809e4b17023SJohn Marino   TREE_READONLY (t) = read_only;
3810e4b17023SJohn Marino   TREE_CONSTANT (t) = constant;
3811e4b17023SJohn Marino   TREE_SIDE_EFFECTS (t) = side_effects;
3812e4b17023SJohn Marino   TREE_THIS_VOLATILE (t)
3813e4b17023SJohn Marino     = (TREE_CODE_CLASS (code) == tcc_reference
3814e4b17023SJohn Marino        && arg0 && TREE_THIS_VOLATILE (arg0));
3815e4b17023SJohn Marino 
3816e4b17023SJohn Marino   return t;
3817e4b17023SJohn Marino }
3818e4b17023SJohn Marino 
3819e4b17023SJohn Marino 
3820e4b17023SJohn Marino tree
build3_stat(enum tree_code code,tree tt,tree arg0,tree arg1,tree arg2 MEM_STAT_DECL)3821e4b17023SJohn Marino build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
3822e4b17023SJohn Marino 	     tree arg2 MEM_STAT_DECL)
3823e4b17023SJohn Marino {
3824e4b17023SJohn Marino   bool constant, read_only, side_effects;
3825e4b17023SJohn Marino   tree t;
3826e4b17023SJohn Marino 
3827e4b17023SJohn Marino   gcc_assert (TREE_CODE_LENGTH (code) == 3);
3828e4b17023SJohn Marino   gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
3829e4b17023SJohn Marino 
3830e4b17023SJohn Marino   t = make_node_stat (code PASS_MEM_STAT);
3831e4b17023SJohn Marino   TREE_TYPE (t) = tt;
3832e4b17023SJohn Marino 
3833e4b17023SJohn Marino   read_only = 1;
3834e4b17023SJohn Marino 
3835e4b17023SJohn Marino   /* As a special exception, if COND_EXPR has NULL branches, we
3836e4b17023SJohn Marino      assume that it is a gimple statement and always consider
3837e4b17023SJohn Marino      it to have side effects.  */
3838e4b17023SJohn Marino   if (code == COND_EXPR
3839e4b17023SJohn Marino       && tt == void_type_node
3840e4b17023SJohn Marino       && arg1 == NULL_TREE
3841e4b17023SJohn Marino       && arg2 == NULL_TREE)
3842e4b17023SJohn Marino     side_effects = true;
3843e4b17023SJohn Marino   else
3844e4b17023SJohn Marino     side_effects = TREE_SIDE_EFFECTS (t);
3845e4b17023SJohn Marino 
3846e4b17023SJohn Marino   PROCESS_ARG(0);
3847e4b17023SJohn Marino   PROCESS_ARG(1);
3848e4b17023SJohn Marino   PROCESS_ARG(2);
3849e4b17023SJohn Marino 
3850e4b17023SJohn Marino   if (code == COND_EXPR)
3851e4b17023SJohn Marino     TREE_READONLY (t) = read_only;
3852e4b17023SJohn Marino 
3853e4b17023SJohn Marino   TREE_SIDE_EFFECTS (t) = side_effects;
3854e4b17023SJohn Marino   TREE_THIS_VOLATILE (t)
3855e4b17023SJohn Marino     = (TREE_CODE_CLASS (code) == tcc_reference
3856e4b17023SJohn Marino        && arg0 && TREE_THIS_VOLATILE (arg0));
3857e4b17023SJohn Marino 
3858e4b17023SJohn Marino   return t;
3859e4b17023SJohn Marino }
3860e4b17023SJohn Marino 
3861e4b17023SJohn Marino tree
build4_stat(enum tree_code code,tree tt,tree arg0,tree arg1,tree arg2,tree arg3 MEM_STAT_DECL)3862e4b17023SJohn Marino build4_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
3863e4b17023SJohn Marino 	     tree arg2, tree arg3 MEM_STAT_DECL)
3864e4b17023SJohn Marino {
3865e4b17023SJohn Marino   bool constant, read_only, side_effects;
3866e4b17023SJohn Marino   tree t;
3867e4b17023SJohn Marino 
3868e4b17023SJohn Marino   gcc_assert (TREE_CODE_LENGTH (code) == 4);
3869e4b17023SJohn Marino 
3870e4b17023SJohn Marino   t = make_node_stat (code PASS_MEM_STAT);
3871e4b17023SJohn Marino   TREE_TYPE (t) = tt;
3872e4b17023SJohn Marino 
3873e4b17023SJohn Marino   side_effects = TREE_SIDE_EFFECTS (t);
3874e4b17023SJohn Marino 
3875e4b17023SJohn Marino   PROCESS_ARG(0);
3876e4b17023SJohn Marino   PROCESS_ARG(1);
3877e4b17023SJohn Marino   PROCESS_ARG(2);
3878e4b17023SJohn Marino   PROCESS_ARG(3);
3879e4b17023SJohn Marino 
3880e4b17023SJohn Marino   TREE_SIDE_EFFECTS (t) = side_effects;
3881e4b17023SJohn Marino   TREE_THIS_VOLATILE (t)
3882e4b17023SJohn Marino     = (TREE_CODE_CLASS (code) == tcc_reference
3883e4b17023SJohn Marino        && arg0 && TREE_THIS_VOLATILE (arg0));
3884e4b17023SJohn Marino 
3885e4b17023SJohn Marino   return t;
3886e4b17023SJohn Marino }
3887e4b17023SJohn Marino 
3888e4b17023SJohn Marino tree
build5_stat(enum tree_code code,tree tt,tree arg0,tree arg1,tree arg2,tree arg3,tree arg4 MEM_STAT_DECL)3889e4b17023SJohn Marino build5_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
3890e4b17023SJohn Marino 	     tree arg2, tree arg3, tree arg4 MEM_STAT_DECL)
3891e4b17023SJohn Marino {
3892e4b17023SJohn Marino   bool constant, read_only, side_effects;
3893e4b17023SJohn Marino   tree t;
3894e4b17023SJohn Marino 
3895e4b17023SJohn Marino   gcc_assert (TREE_CODE_LENGTH (code) == 5);
3896e4b17023SJohn Marino 
3897e4b17023SJohn Marino   t = make_node_stat (code PASS_MEM_STAT);
3898e4b17023SJohn Marino   TREE_TYPE (t) = tt;
3899e4b17023SJohn Marino 
3900e4b17023SJohn Marino   side_effects = TREE_SIDE_EFFECTS (t);
3901e4b17023SJohn Marino 
3902e4b17023SJohn Marino   PROCESS_ARG(0);
3903e4b17023SJohn Marino   PROCESS_ARG(1);
3904e4b17023SJohn Marino   PROCESS_ARG(2);
3905e4b17023SJohn Marino   PROCESS_ARG(3);
3906e4b17023SJohn Marino   PROCESS_ARG(4);
3907e4b17023SJohn Marino 
3908e4b17023SJohn Marino   TREE_SIDE_EFFECTS (t) = side_effects;
3909e4b17023SJohn Marino   TREE_THIS_VOLATILE (t)
3910e4b17023SJohn Marino     = (TREE_CODE_CLASS (code) == tcc_reference
3911e4b17023SJohn Marino        && arg0 && TREE_THIS_VOLATILE (arg0));
3912e4b17023SJohn Marino 
3913e4b17023SJohn Marino   return t;
3914e4b17023SJohn Marino }
3915e4b17023SJohn Marino 
3916e4b17023SJohn Marino tree
build6_stat(enum tree_code code,tree tt,tree arg0,tree arg1,tree arg2,tree arg3,tree arg4,tree arg5 MEM_STAT_DECL)3917e4b17023SJohn Marino build6_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
3918e4b17023SJohn Marino 	     tree arg2, tree arg3, tree arg4, tree arg5 MEM_STAT_DECL)
3919e4b17023SJohn Marino {
3920e4b17023SJohn Marino   bool constant, read_only, side_effects;
3921e4b17023SJohn Marino   tree t;
3922e4b17023SJohn Marino 
3923e4b17023SJohn Marino   gcc_assert (code == TARGET_MEM_REF);
3924e4b17023SJohn Marino 
3925e4b17023SJohn Marino   t = make_node_stat (code PASS_MEM_STAT);
3926e4b17023SJohn Marino   TREE_TYPE (t) = tt;
3927e4b17023SJohn Marino 
3928e4b17023SJohn Marino   side_effects = TREE_SIDE_EFFECTS (t);
3929e4b17023SJohn Marino 
3930e4b17023SJohn Marino   PROCESS_ARG(0);
3931e4b17023SJohn Marino   PROCESS_ARG(1);
3932e4b17023SJohn Marino   PROCESS_ARG(2);
3933e4b17023SJohn Marino   PROCESS_ARG(3);
3934e4b17023SJohn Marino   PROCESS_ARG(4);
3935e4b17023SJohn Marino   if (code == TARGET_MEM_REF)
3936e4b17023SJohn Marino     side_effects = 0;
3937e4b17023SJohn Marino   PROCESS_ARG(5);
3938e4b17023SJohn Marino 
3939e4b17023SJohn Marino   TREE_SIDE_EFFECTS (t) = side_effects;
3940e4b17023SJohn Marino   TREE_THIS_VOLATILE (t)
3941e4b17023SJohn Marino     = (code == TARGET_MEM_REF
3942e4b17023SJohn Marino        && arg5 && TREE_THIS_VOLATILE (arg5));
3943e4b17023SJohn Marino 
3944e4b17023SJohn Marino   return t;
3945e4b17023SJohn Marino }
3946e4b17023SJohn Marino 
3947e4b17023SJohn Marino /* Build a simple MEM_REF tree with the sematics of a plain INDIRECT_REF
3948e4b17023SJohn Marino    on the pointer PTR.  */
3949e4b17023SJohn Marino 
3950e4b17023SJohn Marino tree
build_simple_mem_ref_loc(location_t loc,tree ptr)3951e4b17023SJohn Marino build_simple_mem_ref_loc (location_t loc, tree ptr)
3952e4b17023SJohn Marino {
3953e4b17023SJohn Marino   HOST_WIDE_INT offset = 0;
3954e4b17023SJohn Marino   tree ptype = TREE_TYPE (ptr);
3955e4b17023SJohn Marino   tree tem;
3956e4b17023SJohn Marino   /* For convenience allow addresses that collapse to a simple base
3957e4b17023SJohn Marino      and offset.  */
3958e4b17023SJohn Marino   if (TREE_CODE (ptr) == ADDR_EXPR
3959e4b17023SJohn Marino       && (handled_component_p (TREE_OPERAND (ptr, 0))
3960e4b17023SJohn Marino 	  || TREE_CODE (TREE_OPERAND (ptr, 0)) == MEM_REF))
3961e4b17023SJohn Marino     {
3962e4b17023SJohn Marino       ptr = get_addr_base_and_unit_offset (TREE_OPERAND (ptr, 0), &offset);
3963e4b17023SJohn Marino       gcc_assert (ptr);
3964e4b17023SJohn Marino       ptr = build_fold_addr_expr (ptr);
3965e4b17023SJohn Marino       gcc_assert (is_gimple_reg (ptr) || is_gimple_min_invariant (ptr));
3966e4b17023SJohn Marino     }
3967e4b17023SJohn Marino   tem = build2 (MEM_REF, TREE_TYPE (ptype),
3968e4b17023SJohn Marino 		ptr, build_int_cst (ptype, offset));
3969e4b17023SJohn Marino   SET_EXPR_LOCATION (tem, loc);
3970e4b17023SJohn Marino   return tem;
3971e4b17023SJohn Marino }
3972e4b17023SJohn Marino 
3973e4b17023SJohn Marino /* Return the constant offset of a MEM_REF or TARGET_MEM_REF tree T.  */
3974e4b17023SJohn Marino 
3975e4b17023SJohn Marino double_int
mem_ref_offset(const_tree t)3976e4b17023SJohn Marino mem_ref_offset (const_tree t)
3977e4b17023SJohn Marino {
3978e4b17023SJohn Marino   tree toff = TREE_OPERAND (t, 1);
3979e4b17023SJohn Marino   return double_int_sext (tree_to_double_int (toff),
3980e4b17023SJohn Marino 			  TYPE_PRECISION (TREE_TYPE (toff)));
3981e4b17023SJohn Marino }
3982e4b17023SJohn Marino 
3983e4b17023SJohn Marino /* Return the pointer-type relevant for TBAA purposes from the
3984e4b17023SJohn Marino    gimple memory reference tree T.  This is the type to be used for
3985e4b17023SJohn Marino    the offset operand of MEM_REF or TARGET_MEM_REF replacements of T.  */
3986e4b17023SJohn Marino 
3987e4b17023SJohn Marino tree
reference_alias_ptr_type(const_tree t)3988e4b17023SJohn Marino reference_alias_ptr_type (const_tree t)
3989e4b17023SJohn Marino {
3990e4b17023SJohn Marino   const_tree base = t;
3991e4b17023SJohn Marino   while (handled_component_p (base))
3992e4b17023SJohn Marino     base = TREE_OPERAND (base, 0);
3993e4b17023SJohn Marino   if (TREE_CODE (base) == MEM_REF)
3994e4b17023SJohn Marino     return TREE_TYPE (TREE_OPERAND (base, 1));
3995e4b17023SJohn Marino   else if (TREE_CODE (base) == TARGET_MEM_REF)
3996e4b17023SJohn Marino     return TREE_TYPE (TMR_OFFSET (base));
3997e4b17023SJohn Marino   else
3998e4b17023SJohn Marino     return build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (base)));
3999e4b17023SJohn Marino }
4000e4b17023SJohn Marino 
4001e4b17023SJohn Marino /* Return an invariant ADDR_EXPR of type TYPE taking the address of BASE
4002e4b17023SJohn Marino    offsetted by OFFSET units.  */
4003e4b17023SJohn Marino 
4004e4b17023SJohn Marino tree
build_invariant_address(tree type,tree base,HOST_WIDE_INT offset)4005e4b17023SJohn Marino build_invariant_address (tree type, tree base, HOST_WIDE_INT offset)
4006e4b17023SJohn Marino {
4007e4b17023SJohn Marino   tree ref = fold_build2 (MEM_REF, TREE_TYPE (type),
4008e4b17023SJohn Marino 			  build_fold_addr_expr (base),
4009e4b17023SJohn Marino 			  build_int_cst (ptr_type_node, offset));
4010e4b17023SJohn Marino   tree addr = build1 (ADDR_EXPR, type, ref);
4011e4b17023SJohn Marino   recompute_tree_invariant_for_addr_expr (addr);
4012e4b17023SJohn Marino   return addr;
4013e4b17023SJohn Marino }
4014e4b17023SJohn Marino 
4015e4b17023SJohn Marino /* Similar except don't specify the TREE_TYPE
4016e4b17023SJohn Marino    and leave the TREE_SIDE_EFFECTS as 0.
4017e4b17023SJohn Marino    It is permissible for arguments to be null,
4018e4b17023SJohn Marino    or even garbage if their values do not matter.  */
4019e4b17023SJohn Marino 
4020e4b17023SJohn Marino tree
build_nt(enum tree_code code,...)4021e4b17023SJohn Marino build_nt (enum tree_code code, ...)
4022e4b17023SJohn Marino {
4023e4b17023SJohn Marino   tree t;
4024e4b17023SJohn Marino   int length;
4025e4b17023SJohn Marino   int i;
4026e4b17023SJohn Marino   va_list p;
4027e4b17023SJohn Marino 
4028e4b17023SJohn Marino   gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
4029e4b17023SJohn Marino 
4030e4b17023SJohn Marino   va_start (p, code);
4031e4b17023SJohn Marino 
4032e4b17023SJohn Marino   t = make_node (code);
4033e4b17023SJohn Marino   length = TREE_CODE_LENGTH (code);
4034e4b17023SJohn Marino 
4035e4b17023SJohn Marino   for (i = 0; i < length; i++)
4036e4b17023SJohn Marino     TREE_OPERAND (t, i) = va_arg (p, tree);
4037e4b17023SJohn Marino 
4038e4b17023SJohn Marino   va_end (p);
4039e4b17023SJohn Marino   return t;
4040e4b17023SJohn Marino }
4041e4b17023SJohn Marino 
4042e4b17023SJohn Marino /* Similar to build_nt, but for creating a CALL_EXPR object with a
4043e4b17023SJohn Marino    tree VEC.  */
4044e4b17023SJohn Marino 
4045e4b17023SJohn Marino tree
build_nt_call_vec(tree fn,VEC (tree,gc)* args)4046e4b17023SJohn Marino build_nt_call_vec (tree fn, VEC(tree,gc) *args)
4047e4b17023SJohn Marino {
4048e4b17023SJohn Marino   tree ret, t;
4049e4b17023SJohn Marino   unsigned int ix;
4050e4b17023SJohn Marino 
4051e4b17023SJohn Marino   ret = build_vl_exp (CALL_EXPR, VEC_length (tree, args) + 3);
4052e4b17023SJohn Marino   CALL_EXPR_FN (ret) = fn;
4053e4b17023SJohn Marino   CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE;
4054e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, args, ix, t)
4055e4b17023SJohn Marino     CALL_EXPR_ARG (ret, ix) = t;
4056e4b17023SJohn Marino   return ret;
4057e4b17023SJohn Marino }
4058e4b17023SJohn Marino 
4059e4b17023SJohn Marino /* Create a DECL_... node of code CODE, name NAME and data type TYPE.
4060e4b17023SJohn Marino    We do NOT enter this node in any sort of symbol table.
4061e4b17023SJohn Marino 
4062e4b17023SJohn Marino    LOC is the location of the decl.
4063e4b17023SJohn Marino 
4064e4b17023SJohn Marino    layout_decl is used to set up the decl's storage layout.
4065e4b17023SJohn Marino    Other slots are initialized to 0 or null pointers.  */
4066e4b17023SJohn Marino 
4067e4b17023SJohn Marino tree
build_decl_stat(location_t loc,enum tree_code code,tree name,tree type MEM_STAT_DECL)4068e4b17023SJohn Marino build_decl_stat (location_t loc, enum tree_code code, tree name,
4069e4b17023SJohn Marino     		 tree type MEM_STAT_DECL)
4070e4b17023SJohn Marino {
4071e4b17023SJohn Marino   tree t;
4072e4b17023SJohn Marino 
4073e4b17023SJohn Marino   t = make_node_stat (code PASS_MEM_STAT);
4074e4b17023SJohn Marino   DECL_SOURCE_LOCATION (t) = loc;
4075e4b17023SJohn Marino 
4076e4b17023SJohn Marino /*  if (type == error_mark_node)
4077e4b17023SJohn Marino     type = integer_type_node; */
4078e4b17023SJohn Marino /* That is not done, deliberately, so that having error_mark_node
4079e4b17023SJohn Marino    as the type can suppress useless errors in the use of this variable.  */
4080e4b17023SJohn Marino 
4081e4b17023SJohn Marino   DECL_NAME (t) = name;
4082e4b17023SJohn Marino   TREE_TYPE (t) = type;
4083e4b17023SJohn Marino 
4084e4b17023SJohn Marino   if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
4085e4b17023SJohn Marino     layout_decl (t, 0);
4086e4b17023SJohn Marino 
4087e4b17023SJohn Marino   return t;
4088e4b17023SJohn Marino }
4089e4b17023SJohn Marino 
4090e4b17023SJohn Marino /* Builds and returns function declaration with NAME and TYPE.  */
4091e4b17023SJohn Marino 
4092e4b17023SJohn Marino tree
build_fn_decl(const char * name,tree type)4093e4b17023SJohn Marino build_fn_decl (const char *name, tree type)
4094e4b17023SJohn Marino {
4095e4b17023SJohn Marino   tree id = get_identifier (name);
4096e4b17023SJohn Marino   tree decl = build_decl (input_location, FUNCTION_DECL, id, type);
4097e4b17023SJohn Marino 
4098e4b17023SJohn Marino   DECL_EXTERNAL (decl) = 1;
4099e4b17023SJohn Marino   TREE_PUBLIC (decl) = 1;
4100e4b17023SJohn Marino   DECL_ARTIFICIAL (decl) = 1;
4101e4b17023SJohn Marino   TREE_NOTHROW (decl) = 1;
4102e4b17023SJohn Marino 
4103e4b17023SJohn Marino   return decl;
4104e4b17023SJohn Marino }
4105e4b17023SJohn Marino 
VEC(tree,gc)4106e4b17023SJohn Marino VEC(tree,gc) *all_translation_units;
4107e4b17023SJohn Marino 
4108e4b17023SJohn Marino /* Builds a new translation-unit decl with name NAME, queues it in the
4109e4b17023SJohn Marino    global list of translation-unit decls and returns it.   */
4110e4b17023SJohn Marino 
4111e4b17023SJohn Marino tree
4112e4b17023SJohn Marino build_translation_unit_decl (tree name)
4113e4b17023SJohn Marino {
4114e4b17023SJohn Marino   tree tu = build_decl (UNKNOWN_LOCATION, TRANSLATION_UNIT_DECL,
4115e4b17023SJohn Marino 			name, NULL_TREE);
4116e4b17023SJohn Marino   TRANSLATION_UNIT_LANGUAGE (tu) = lang_hooks.name;
4117e4b17023SJohn Marino   VEC_safe_push (tree, gc, all_translation_units, tu);
4118e4b17023SJohn Marino   return tu;
4119e4b17023SJohn Marino }
4120e4b17023SJohn Marino 
4121e4b17023SJohn Marino 
4122e4b17023SJohn Marino /* BLOCK nodes are used to represent the structure of binding contours
4123e4b17023SJohn Marino    and declarations, once those contours have been exited and their contents
4124e4b17023SJohn Marino    compiled.  This information is used for outputting debugging info.  */
4125e4b17023SJohn Marino 
4126e4b17023SJohn Marino tree
build_block(tree vars,tree subblocks,tree supercontext,tree chain)4127e4b17023SJohn Marino build_block (tree vars, tree subblocks, tree supercontext, tree chain)
4128e4b17023SJohn Marino {
4129e4b17023SJohn Marino   tree block = make_node (BLOCK);
4130e4b17023SJohn Marino 
4131e4b17023SJohn Marino   BLOCK_VARS (block) = vars;
4132e4b17023SJohn Marino   BLOCK_SUBBLOCKS (block) = subblocks;
4133e4b17023SJohn Marino   BLOCK_SUPERCONTEXT (block) = supercontext;
4134e4b17023SJohn Marino   BLOCK_CHAIN (block) = chain;
4135e4b17023SJohn Marino   return block;
4136e4b17023SJohn Marino }
4137e4b17023SJohn Marino 
4138e4b17023SJohn Marino 
4139e4b17023SJohn Marino /* Like SET_EXPR_LOCATION, but make sure the tree can have a location.
4140e4b17023SJohn Marino 
4141e4b17023SJohn Marino    LOC is the location to use in tree T.  */
4142e4b17023SJohn Marino 
4143e4b17023SJohn Marino void
protected_set_expr_location(tree t,location_t loc)4144e4b17023SJohn Marino protected_set_expr_location (tree t, location_t loc)
4145e4b17023SJohn Marino {
4146e4b17023SJohn Marino   if (t && CAN_HAVE_LOCATION_P (t))
4147e4b17023SJohn Marino     SET_EXPR_LOCATION (t, loc);
4148e4b17023SJohn Marino }
4149e4b17023SJohn Marino 
4150e4b17023SJohn Marino /* Return a declaration like DDECL except that its DECL_ATTRIBUTES
4151e4b17023SJohn Marino    is ATTRIBUTE.  */
4152e4b17023SJohn Marino 
4153e4b17023SJohn Marino tree
build_decl_attribute_variant(tree ddecl,tree attribute)4154e4b17023SJohn Marino build_decl_attribute_variant (tree ddecl, tree attribute)
4155e4b17023SJohn Marino {
4156e4b17023SJohn Marino   DECL_ATTRIBUTES (ddecl) = attribute;
4157e4b17023SJohn Marino   return ddecl;
4158e4b17023SJohn Marino }
4159e4b17023SJohn Marino 
4160e4b17023SJohn Marino /* Borrowed from hashtab.c iterative_hash implementation.  */
4161e4b17023SJohn Marino #define mix(a,b,c) \
4162e4b17023SJohn Marino { \
4163e4b17023SJohn Marino   a -= b; a -= c; a ^= (c>>13); \
4164e4b17023SJohn Marino   b -= c; b -= a; b ^= (a<< 8); \
4165e4b17023SJohn Marino   c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
4166e4b17023SJohn Marino   a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
4167e4b17023SJohn Marino   b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
4168e4b17023SJohn Marino   c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
4169e4b17023SJohn Marino   a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
4170e4b17023SJohn Marino   b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
4171e4b17023SJohn Marino   c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
4172e4b17023SJohn Marino }
4173e4b17023SJohn Marino 
4174e4b17023SJohn Marino 
4175e4b17023SJohn Marino /* Produce good hash value combining VAL and VAL2.  */
4176e4b17023SJohn Marino hashval_t
iterative_hash_hashval_t(hashval_t val,hashval_t val2)4177e4b17023SJohn Marino iterative_hash_hashval_t (hashval_t val, hashval_t val2)
4178e4b17023SJohn Marino {
4179e4b17023SJohn Marino   /* the golden ratio; an arbitrary value.  */
4180e4b17023SJohn Marino   hashval_t a = 0x9e3779b9;
4181e4b17023SJohn Marino 
4182e4b17023SJohn Marino   mix (a, val, val2);
4183e4b17023SJohn Marino   return val2;
4184e4b17023SJohn Marino }
4185e4b17023SJohn Marino 
4186e4b17023SJohn Marino /* Produce good hash value combining VAL and VAL2.  */
4187e4b17023SJohn Marino hashval_t
iterative_hash_host_wide_int(HOST_WIDE_INT val,hashval_t val2)4188e4b17023SJohn Marino iterative_hash_host_wide_int (HOST_WIDE_INT val, hashval_t val2)
4189e4b17023SJohn Marino {
4190e4b17023SJohn Marino   if (sizeof (HOST_WIDE_INT) == sizeof (hashval_t))
4191e4b17023SJohn Marino     return iterative_hash_hashval_t (val, val2);
4192e4b17023SJohn Marino   else
4193e4b17023SJohn Marino     {
4194e4b17023SJohn Marino       hashval_t a = (hashval_t) val;
4195e4b17023SJohn Marino       /* Avoid warnings about shifting of more than the width of the type on
4196e4b17023SJohn Marino          hosts that won't execute this path.  */
4197e4b17023SJohn Marino       int zero = 0;
4198e4b17023SJohn Marino       hashval_t b = (hashval_t) (val >> (sizeof (hashval_t) * 8 + zero));
4199e4b17023SJohn Marino       mix (a, b, val2);
4200e4b17023SJohn Marino       if (sizeof (HOST_WIDE_INT) > 2 * sizeof (hashval_t))
4201e4b17023SJohn Marino 	{
4202e4b17023SJohn Marino 	  hashval_t a = (hashval_t) (val >> (sizeof (hashval_t) * 16 + zero));
4203e4b17023SJohn Marino 	  hashval_t b = (hashval_t) (val >> (sizeof (hashval_t) * 24 + zero));
4204e4b17023SJohn Marino 	  mix (a, b, val2);
4205e4b17023SJohn Marino 	}
4206e4b17023SJohn Marino       return val2;
4207e4b17023SJohn Marino     }
4208e4b17023SJohn Marino }
4209e4b17023SJohn Marino 
4210e4b17023SJohn Marino /* Return a type like TTYPE except that its TYPE_ATTRIBUTE
4211e4b17023SJohn Marino    is ATTRIBUTE and its qualifiers are QUALS.
4212e4b17023SJohn Marino 
4213e4b17023SJohn Marino    Record such modified types already made so we don't make duplicates.  */
4214e4b17023SJohn Marino 
4215e4b17023SJohn Marino tree
build_type_attribute_qual_variant(tree ttype,tree attribute,int quals)4216e4b17023SJohn Marino build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
4217e4b17023SJohn Marino {
4218e4b17023SJohn Marino   if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
4219e4b17023SJohn Marino     {
4220e4b17023SJohn Marino       hashval_t hashcode = 0;
4221e4b17023SJohn Marino       tree ntype;
4222e4b17023SJohn Marino       enum tree_code code = TREE_CODE (ttype);
4223e4b17023SJohn Marino 
4224e4b17023SJohn Marino       /* Building a distinct copy of a tagged type is inappropriate; it
4225e4b17023SJohn Marino 	 causes breakage in code that expects there to be a one-to-one
4226e4b17023SJohn Marino 	 relationship between a struct and its fields.
4227e4b17023SJohn Marino 	 build_duplicate_type is another solution (as used in
4228e4b17023SJohn Marino 	 handle_transparent_union_attribute), but that doesn't play well
4229e4b17023SJohn Marino 	 with the stronger C++ type identity model.  */
4230e4b17023SJohn Marino       if (TREE_CODE (ttype) == RECORD_TYPE
4231e4b17023SJohn Marino 	  || TREE_CODE (ttype) == UNION_TYPE
4232e4b17023SJohn Marino 	  || TREE_CODE (ttype) == QUAL_UNION_TYPE
4233e4b17023SJohn Marino 	  || TREE_CODE (ttype) == ENUMERAL_TYPE)
4234e4b17023SJohn Marino 	{
4235e4b17023SJohn Marino 	  warning (OPT_Wattributes,
4236e4b17023SJohn Marino 		   "ignoring attributes applied to %qT after definition",
4237e4b17023SJohn Marino 		   TYPE_MAIN_VARIANT (ttype));
4238e4b17023SJohn Marino 	  return build_qualified_type (ttype, quals);
4239e4b17023SJohn Marino 	}
4240e4b17023SJohn Marino 
4241e4b17023SJohn Marino       ttype = build_qualified_type (ttype, TYPE_UNQUALIFIED);
4242e4b17023SJohn Marino       ntype = build_distinct_type_copy (ttype);
4243e4b17023SJohn Marino 
4244e4b17023SJohn Marino       TYPE_ATTRIBUTES (ntype) = attribute;
4245e4b17023SJohn Marino 
4246e4b17023SJohn Marino       hashcode = iterative_hash_object (code, hashcode);
4247e4b17023SJohn Marino       if (TREE_TYPE (ntype))
4248e4b17023SJohn Marino 	hashcode = iterative_hash_object (TYPE_HASH (TREE_TYPE (ntype)),
4249e4b17023SJohn Marino 					  hashcode);
4250e4b17023SJohn Marino       hashcode = attribute_hash_list (attribute, hashcode);
4251e4b17023SJohn Marino 
4252e4b17023SJohn Marino       switch (TREE_CODE (ntype))
4253e4b17023SJohn Marino 	{
4254e4b17023SJohn Marino 	case FUNCTION_TYPE:
4255e4b17023SJohn Marino 	  hashcode = type_hash_list (TYPE_ARG_TYPES (ntype), hashcode);
4256e4b17023SJohn Marino 	  break;
4257e4b17023SJohn Marino 	case ARRAY_TYPE:
4258e4b17023SJohn Marino 	  if (TYPE_DOMAIN (ntype))
4259e4b17023SJohn Marino 	    hashcode = iterative_hash_object (TYPE_HASH (TYPE_DOMAIN (ntype)),
4260e4b17023SJohn Marino 					      hashcode);
4261e4b17023SJohn Marino 	  break;
4262e4b17023SJohn Marino 	case INTEGER_TYPE:
4263e4b17023SJohn Marino 	  hashcode = iterative_hash_object
4264e4b17023SJohn Marino 	    (TREE_INT_CST_LOW (TYPE_MAX_VALUE (ntype)), hashcode);
4265e4b17023SJohn Marino 	  hashcode = iterative_hash_object
4266e4b17023SJohn Marino 	    (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (ntype)), hashcode);
4267e4b17023SJohn Marino 	  break;
4268e4b17023SJohn Marino 	case REAL_TYPE:
4269e4b17023SJohn Marino 	case FIXED_POINT_TYPE:
4270e4b17023SJohn Marino 	  {
4271e4b17023SJohn Marino 	    unsigned int precision = TYPE_PRECISION (ntype);
4272e4b17023SJohn Marino 	    hashcode = iterative_hash_object (precision, hashcode);
4273e4b17023SJohn Marino 	  }
4274e4b17023SJohn Marino 	  break;
4275e4b17023SJohn Marino 	default:
4276e4b17023SJohn Marino 	  break;
4277e4b17023SJohn Marino 	}
4278e4b17023SJohn Marino 
4279e4b17023SJohn Marino       ntype = type_hash_canon (hashcode, ntype);
4280e4b17023SJohn Marino 
4281e4b17023SJohn Marino       /* If the target-dependent attributes make NTYPE different from
4282e4b17023SJohn Marino 	 its canonical type, we will need to use structural equality
4283e4b17023SJohn Marino 	 checks for this type. */
4284e4b17023SJohn Marino       if (TYPE_STRUCTURAL_EQUALITY_P (ttype)
4285e4b17023SJohn Marino           || !comp_type_attributes (ntype, ttype))
4286e4b17023SJohn Marino 	SET_TYPE_STRUCTURAL_EQUALITY (ntype);
4287e4b17023SJohn Marino       else if (TYPE_CANONICAL (ntype) == ntype)
4288e4b17023SJohn Marino 	TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype);
4289e4b17023SJohn Marino 
4290e4b17023SJohn Marino       ttype = build_qualified_type (ntype, quals);
4291e4b17023SJohn Marino     }
4292e4b17023SJohn Marino   else if (TYPE_QUALS (ttype) != quals)
4293e4b17023SJohn Marino     ttype = build_qualified_type (ttype, quals);
4294e4b17023SJohn Marino 
4295e4b17023SJohn Marino   return ttype;
4296e4b17023SJohn Marino }
4297e4b17023SJohn Marino 
4298e4b17023SJohn Marino /* Compare two attributes for their value identity.  Return true if the
4299e4b17023SJohn Marino    attribute values are known to be equal; otherwise return false.
4300e4b17023SJohn Marino */
4301e4b17023SJohn Marino 
4302e4b17023SJohn Marino static bool
attribute_value_equal(const_tree attr1,const_tree attr2)4303e4b17023SJohn Marino attribute_value_equal (const_tree attr1, const_tree attr2)
4304e4b17023SJohn Marino {
4305e4b17023SJohn Marino   if (TREE_VALUE (attr1) == TREE_VALUE (attr2))
4306e4b17023SJohn Marino     return true;
4307e4b17023SJohn Marino 
4308e4b17023SJohn Marino   if (TREE_VALUE (attr1) != NULL_TREE
4309e4b17023SJohn Marino       && TREE_CODE (TREE_VALUE (attr1)) == TREE_LIST
4310e4b17023SJohn Marino       && TREE_VALUE (attr2) != NULL
4311e4b17023SJohn Marino       && TREE_CODE (TREE_VALUE (attr2)) == TREE_LIST)
4312e4b17023SJohn Marino     return (simple_cst_list_equal (TREE_VALUE (attr1),
4313e4b17023SJohn Marino 				   TREE_VALUE (attr2)) == 1);
4314e4b17023SJohn Marino 
4315e4b17023SJohn Marino   return (simple_cst_equal (TREE_VALUE (attr1), TREE_VALUE (attr2)) == 1);
4316e4b17023SJohn Marino }
4317e4b17023SJohn Marino 
4318e4b17023SJohn Marino /* Return 0 if the attributes for two types are incompatible, 1 if they
4319e4b17023SJohn Marino    are compatible, and 2 if they are nearly compatible (which causes a
4320e4b17023SJohn Marino    warning to be generated).  */
4321e4b17023SJohn Marino int
comp_type_attributes(const_tree type1,const_tree type2)4322e4b17023SJohn Marino comp_type_attributes (const_tree type1, const_tree type2)
4323e4b17023SJohn Marino {
4324e4b17023SJohn Marino   const_tree a1 = TYPE_ATTRIBUTES (type1);
4325e4b17023SJohn Marino   const_tree a2 = TYPE_ATTRIBUTES (type2);
4326e4b17023SJohn Marino   const_tree a;
4327e4b17023SJohn Marino 
4328e4b17023SJohn Marino   if (a1 == a2)
4329e4b17023SJohn Marino     return 1;
4330e4b17023SJohn Marino   for (a = a1; a != NULL_TREE; a = TREE_CHAIN (a))
4331e4b17023SJohn Marino     {
4332e4b17023SJohn Marino       const struct attribute_spec *as;
4333e4b17023SJohn Marino       const_tree attr;
4334e4b17023SJohn Marino 
4335e4b17023SJohn Marino       as = lookup_attribute_spec (TREE_PURPOSE (a));
4336e4b17023SJohn Marino       if (!as || as->affects_type_identity == false)
4337e4b17023SJohn Marino         continue;
4338e4b17023SJohn Marino 
4339e4b17023SJohn Marino       attr = lookup_attribute (as->name, CONST_CAST_TREE (a2));
4340e4b17023SJohn Marino       if (!attr || !attribute_value_equal (a, attr))
4341e4b17023SJohn Marino         break;
4342e4b17023SJohn Marino     }
4343e4b17023SJohn Marino   if (!a)
4344e4b17023SJohn Marino     {
4345e4b17023SJohn Marino       for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a))
4346e4b17023SJohn Marino 	{
4347e4b17023SJohn Marino 	  const struct attribute_spec *as;
4348e4b17023SJohn Marino 
4349e4b17023SJohn Marino 	  as = lookup_attribute_spec (TREE_PURPOSE (a));
4350e4b17023SJohn Marino 	  if (!as || as->affects_type_identity == false)
4351e4b17023SJohn Marino 	    continue;
4352e4b17023SJohn Marino 
4353e4b17023SJohn Marino 	  if (!lookup_attribute (as->name, CONST_CAST_TREE (a1)))
4354e4b17023SJohn Marino 	    break;
4355e4b17023SJohn Marino 	  /* We don't need to compare trees again, as we did this
4356e4b17023SJohn Marino 	     already in first loop.  */
4357e4b17023SJohn Marino 	}
4358e4b17023SJohn Marino       /* All types - affecting identity - are equal, so
4359e4b17023SJohn Marino          there is no need to call target hook for comparison.  */
4360e4b17023SJohn Marino       if (!a)
4361e4b17023SJohn Marino         return 1;
4362e4b17023SJohn Marino     }
4363e4b17023SJohn Marino   /* As some type combinations - like default calling-convention - might
4364e4b17023SJohn Marino      be compatible, we have to call the target hook to get the final result.  */
4365e4b17023SJohn Marino   return targetm.comp_type_attributes (type1, type2);
4366e4b17023SJohn Marino }
4367e4b17023SJohn Marino 
4368e4b17023SJohn Marino /* Return a type like TTYPE except that its TYPE_ATTRIBUTE
4369e4b17023SJohn Marino    is ATTRIBUTE.
4370e4b17023SJohn Marino 
4371e4b17023SJohn Marino    Record such modified types already made so we don't make duplicates.  */
4372e4b17023SJohn Marino 
4373e4b17023SJohn Marino tree
build_type_attribute_variant(tree ttype,tree attribute)4374e4b17023SJohn Marino build_type_attribute_variant (tree ttype, tree attribute)
4375e4b17023SJohn Marino {
4376e4b17023SJohn Marino   return build_type_attribute_qual_variant (ttype, attribute,
4377e4b17023SJohn Marino 					    TYPE_QUALS (ttype));
4378e4b17023SJohn Marino }
4379e4b17023SJohn Marino 
4380e4b17023SJohn Marino 
4381e4b17023SJohn Marino /* Reset the expression *EXPR_P, a size or position.
4382e4b17023SJohn Marino 
4383e4b17023SJohn Marino    ??? We could reset all non-constant sizes or positions.  But it's cheap
4384e4b17023SJohn Marino    enough to not do so and refrain from adding workarounds to dwarf2out.c.
4385e4b17023SJohn Marino 
4386e4b17023SJohn Marino    We need to reset self-referential sizes or positions because they cannot
4387e4b17023SJohn Marino    be gimplified and thus can contain a CALL_EXPR after the gimplification
4388e4b17023SJohn Marino    is finished, which will run afoul of LTO streaming.  And they need to be
4389e4b17023SJohn Marino    reset to something essentially dummy but not constant, so as to preserve
4390e4b17023SJohn Marino    the properties of the object they are attached to.  */
4391e4b17023SJohn Marino 
4392e4b17023SJohn Marino static inline void
free_lang_data_in_one_sizepos(tree * expr_p)4393e4b17023SJohn Marino free_lang_data_in_one_sizepos (tree *expr_p)
4394e4b17023SJohn Marino {
4395e4b17023SJohn Marino   tree expr = *expr_p;
4396e4b17023SJohn Marino   if (CONTAINS_PLACEHOLDER_P (expr))
4397e4b17023SJohn Marino     *expr_p = build0 (PLACEHOLDER_EXPR, TREE_TYPE (expr));
4398e4b17023SJohn Marino }
4399e4b17023SJohn Marino 
4400e4b17023SJohn Marino 
4401e4b17023SJohn Marino /* Reset all the fields in a binfo node BINFO.  We only keep
4402e4b17023SJohn Marino    BINFO_VTABLE, which is used by gimple_fold_obj_type_ref.  */
4403e4b17023SJohn Marino 
4404e4b17023SJohn Marino static void
free_lang_data_in_binfo(tree binfo)4405e4b17023SJohn Marino free_lang_data_in_binfo (tree binfo)
4406e4b17023SJohn Marino {
4407e4b17023SJohn Marino   unsigned i;
4408e4b17023SJohn Marino   tree t;
4409e4b17023SJohn Marino 
4410e4b17023SJohn Marino   gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
4411e4b17023SJohn Marino 
4412e4b17023SJohn Marino   BINFO_VIRTUALS (binfo) = NULL_TREE;
4413e4b17023SJohn Marino   BINFO_BASE_ACCESSES (binfo) = NULL;
4414e4b17023SJohn Marino   BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE;
4415e4b17023SJohn Marino   BINFO_SUBVTT_INDEX (binfo) = NULL_TREE;
4416e4b17023SJohn Marino 
4417e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, BINFO_BASE_BINFOS (binfo), i, t)
4418e4b17023SJohn Marino     free_lang_data_in_binfo (t);
4419e4b17023SJohn Marino }
4420e4b17023SJohn Marino 
4421e4b17023SJohn Marino 
4422e4b17023SJohn Marino /* Reset all language specific information still present in TYPE.  */
4423e4b17023SJohn Marino 
4424e4b17023SJohn Marino static void
free_lang_data_in_type(tree type)4425e4b17023SJohn Marino free_lang_data_in_type (tree type)
4426e4b17023SJohn Marino {
4427e4b17023SJohn Marino   gcc_assert (TYPE_P (type));
4428e4b17023SJohn Marino 
4429e4b17023SJohn Marino   /* Give the FE a chance to remove its own data first.  */
4430e4b17023SJohn Marino   lang_hooks.free_lang_data (type);
4431e4b17023SJohn Marino 
4432e4b17023SJohn Marino   TREE_LANG_FLAG_0 (type) = 0;
4433e4b17023SJohn Marino   TREE_LANG_FLAG_1 (type) = 0;
4434e4b17023SJohn Marino   TREE_LANG_FLAG_2 (type) = 0;
4435e4b17023SJohn Marino   TREE_LANG_FLAG_3 (type) = 0;
4436e4b17023SJohn Marino   TREE_LANG_FLAG_4 (type) = 0;
4437e4b17023SJohn Marino   TREE_LANG_FLAG_5 (type) = 0;
4438e4b17023SJohn Marino   TREE_LANG_FLAG_6 (type) = 0;
4439e4b17023SJohn Marino 
4440e4b17023SJohn Marino   if (TREE_CODE (type) == FUNCTION_TYPE)
4441e4b17023SJohn Marino     {
4442e4b17023SJohn Marino       /* Remove the const and volatile qualifiers from arguments.  The
4443e4b17023SJohn Marino 	 C++ front end removes them, but the C front end does not,
4444e4b17023SJohn Marino 	 leading to false ODR violation errors when merging two
4445e4b17023SJohn Marino 	 instances of the same function signature compiled by
4446e4b17023SJohn Marino 	 different front ends.  */
4447e4b17023SJohn Marino       tree p;
4448e4b17023SJohn Marino 
4449e4b17023SJohn Marino       for (p = TYPE_ARG_TYPES (type); p; p = TREE_CHAIN (p))
4450e4b17023SJohn Marino 	{
4451e4b17023SJohn Marino 	  tree arg_type = TREE_VALUE (p);
4452e4b17023SJohn Marino 
4453e4b17023SJohn Marino 	  if (TYPE_READONLY (arg_type) || TYPE_VOLATILE (arg_type))
4454e4b17023SJohn Marino 	    {
4455e4b17023SJohn Marino 	      int quals = TYPE_QUALS (arg_type)
4456e4b17023SJohn Marino 			  & ~TYPE_QUAL_CONST
4457e4b17023SJohn Marino 			  & ~TYPE_QUAL_VOLATILE;
4458e4b17023SJohn Marino 	      TREE_VALUE (p) = build_qualified_type (arg_type, quals);
4459e4b17023SJohn Marino 	      free_lang_data_in_type (TREE_VALUE (p));
4460e4b17023SJohn Marino 	    }
4461e4b17023SJohn Marino 	}
4462e4b17023SJohn Marino     }
4463e4b17023SJohn Marino 
4464e4b17023SJohn Marino   /* Remove members that are not actually FIELD_DECLs from the field
4465e4b17023SJohn Marino      list of an aggregate.  These occur in C++.  */
4466e4b17023SJohn Marino   if (RECORD_OR_UNION_TYPE_P (type))
4467e4b17023SJohn Marino     {
4468e4b17023SJohn Marino       tree prev, member;
4469e4b17023SJohn Marino 
4470e4b17023SJohn Marino       /* Note that TYPE_FIELDS can be shared across distinct
4471e4b17023SJohn Marino 	 TREE_TYPEs.  Therefore, if the first field of TYPE_FIELDS is
4472e4b17023SJohn Marino 	 to be removed, we cannot set its TREE_CHAIN to NULL.
4473e4b17023SJohn Marino 	 Otherwise, we would not be able to find all the other fields
4474e4b17023SJohn Marino 	 in the other instances of this TREE_TYPE.
4475e4b17023SJohn Marino 
4476e4b17023SJohn Marino 	 This was causing an ICE in testsuite/g++.dg/lto/20080915.C.  */
4477e4b17023SJohn Marino       prev = NULL_TREE;
4478e4b17023SJohn Marino       member = TYPE_FIELDS (type);
4479e4b17023SJohn Marino       while (member)
4480e4b17023SJohn Marino 	{
4481e4b17023SJohn Marino 	  if (TREE_CODE (member) == FIELD_DECL
4482e4b17023SJohn Marino 	      || TREE_CODE (member) == TYPE_DECL)
4483e4b17023SJohn Marino 	    {
4484e4b17023SJohn Marino 	      if (prev)
4485e4b17023SJohn Marino 		TREE_CHAIN (prev) = member;
4486e4b17023SJohn Marino 	      else
4487e4b17023SJohn Marino 		TYPE_FIELDS (type) = member;
4488e4b17023SJohn Marino 	      prev = member;
4489e4b17023SJohn Marino 	    }
4490e4b17023SJohn Marino 
4491e4b17023SJohn Marino 	  member = TREE_CHAIN (member);
4492e4b17023SJohn Marino 	}
4493e4b17023SJohn Marino 
4494e4b17023SJohn Marino       if (prev)
4495e4b17023SJohn Marino 	TREE_CHAIN (prev) = NULL_TREE;
4496e4b17023SJohn Marino       else
4497e4b17023SJohn Marino 	TYPE_FIELDS (type) = NULL_TREE;
4498e4b17023SJohn Marino 
4499e4b17023SJohn Marino       TYPE_METHODS (type) = NULL_TREE;
4500e4b17023SJohn Marino       if (TYPE_BINFO (type))
4501e4b17023SJohn Marino 	free_lang_data_in_binfo (TYPE_BINFO (type));
4502e4b17023SJohn Marino     }
4503e4b17023SJohn Marino   else
4504e4b17023SJohn Marino     {
4505e4b17023SJohn Marino       /* For non-aggregate types, clear out the language slot (which
4506e4b17023SJohn Marino 	 overloads TYPE_BINFO).  */
4507e4b17023SJohn Marino       TYPE_LANG_SLOT_1 (type) = NULL_TREE;
4508e4b17023SJohn Marino 
4509e4b17023SJohn Marino       if (INTEGRAL_TYPE_P (type)
4510e4b17023SJohn Marino 	  || SCALAR_FLOAT_TYPE_P (type)
4511e4b17023SJohn Marino 	  || FIXED_POINT_TYPE_P (type))
4512e4b17023SJohn Marino 	{
4513e4b17023SJohn Marino 	  free_lang_data_in_one_sizepos (&TYPE_MIN_VALUE (type));
4514e4b17023SJohn Marino 	  free_lang_data_in_one_sizepos (&TYPE_MAX_VALUE (type));
4515e4b17023SJohn Marino 	}
4516e4b17023SJohn Marino     }
4517e4b17023SJohn Marino 
4518e4b17023SJohn Marino   free_lang_data_in_one_sizepos (&TYPE_SIZE (type));
4519e4b17023SJohn Marino   free_lang_data_in_one_sizepos (&TYPE_SIZE_UNIT (type));
4520e4b17023SJohn Marino 
4521e4b17023SJohn Marino   if (TYPE_CONTEXT (type)
4522e4b17023SJohn Marino       && TREE_CODE (TYPE_CONTEXT (type)) == BLOCK)
4523e4b17023SJohn Marino     {
4524e4b17023SJohn Marino       tree ctx = TYPE_CONTEXT (type);
4525e4b17023SJohn Marino       do
4526e4b17023SJohn Marino 	{
4527e4b17023SJohn Marino 	  ctx = BLOCK_SUPERCONTEXT (ctx);
4528e4b17023SJohn Marino 	}
4529e4b17023SJohn Marino       while (ctx && TREE_CODE (ctx) == BLOCK);
4530e4b17023SJohn Marino       TYPE_CONTEXT (type) = ctx;
4531e4b17023SJohn Marino     }
4532e4b17023SJohn Marino }
4533e4b17023SJohn Marino 
4534e4b17023SJohn Marino 
4535e4b17023SJohn Marino /* Return true if DECL may need an assembler name to be set.  */
4536e4b17023SJohn Marino 
4537e4b17023SJohn Marino static inline bool
need_assembler_name_p(tree decl)4538e4b17023SJohn Marino need_assembler_name_p (tree decl)
4539e4b17023SJohn Marino {
4540e4b17023SJohn Marino   /* Only FUNCTION_DECLs and VAR_DECLs are considered.  */
4541e4b17023SJohn Marino   if (TREE_CODE (decl) != FUNCTION_DECL
4542e4b17023SJohn Marino       && TREE_CODE (decl) != VAR_DECL)
4543e4b17023SJohn Marino     return false;
4544e4b17023SJohn Marino 
4545e4b17023SJohn Marino   /* If DECL already has its assembler name set, it does not need a
4546e4b17023SJohn Marino      new one.  */
4547e4b17023SJohn Marino   if (!HAS_DECL_ASSEMBLER_NAME_P (decl)
4548e4b17023SJohn Marino       || DECL_ASSEMBLER_NAME_SET_P (decl))
4549e4b17023SJohn Marino     return false;
4550e4b17023SJohn Marino 
4551e4b17023SJohn Marino   /* Abstract decls do not need an assembler name.  */
4552e4b17023SJohn Marino   if (DECL_ABSTRACT (decl))
4553e4b17023SJohn Marino     return false;
4554e4b17023SJohn Marino 
4555e4b17023SJohn Marino   /* For VAR_DECLs, only static, public and external symbols need an
4556e4b17023SJohn Marino      assembler name.  */
4557e4b17023SJohn Marino   if (TREE_CODE (decl) == VAR_DECL
4558e4b17023SJohn Marino       && !TREE_STATIC (decl)
4559e4b17023SJohn Marino       && !TREE_PUBLIC (decl)
4560e4b17023SJohn Marino       && !DECL_EXTERNAL (decl))
4561e4b17023SJohn Marino     return false;
4562e4b17023SJohn Marino 
4563e4b17023SJohn Marino   if (TREE_CODE (decl) == FUNCTION_DECL)
4564e4b17023SJohn Marino     {
4565e4b17023SJohn Marino       /* Do not set assembler name on builtins.  Allow RTL expansion to
4566e4b17023SJohn Marino 	 decide whether to expand inline or via a regular call.  */
4567e4b17023SJohn Marino       if (DECL_BUILT_IN (decl)
4568e4b17023SJohn Marino 	  && DECL_BUILT_IN_CLASS (decl) != BUILT_IN_FRONTEND)
4569e4b17023SJohn Marino 	return false;
4570e4b17023SJohn Marino 
4571e4b17023SJohn Marino       /* Functions represented in the callgraph need an assembler name.  */
4572e4b17023SJohn Marino       if (cgraph_get_node (decl) != NULL)
4573e4b17023SJohn Marino 	return true;
4574e4b17023SJohn Marino 
4575e4b17023SJohn Marino       /* Unused and not public functions don't need an assembler name.  */
4576e4b17023SJohn Marino       if (!TREE_USED (decl) && !TREE_PUBLIC (decl))
4577e4b17023SJohn Marino 	return false;
4578e4b17023SJohn Marino     }
4579e4b17023SJohn Marino 
4580e4b17023SJohn Marino   return true;
4581e4b17023SJohn Marino }
4582e4b17023SJohn Marino 
4583e4b17023SJohn Marino 
4584e4b17023SJohn Marino /* Reset all language specific information still present in symbol
4585e4b17023SJohn Marino    DECL.  */
4586e4b17023SJohn Marino 
4587e4b17023SJohn Marino static void
free_lang_data_in_decl(tree decl)4588e4b17023SJohn Marino free_lang_data_in_decl (tree decl)
4589e4b17023SJohn Marino {
4590e4b17023SJohn Marino   gcc_assert (DECL_P (decl));
4591e4b17023SJohn Marino 
4592e4b17023SJohn Marino   /* Give the FE a chance to remove its own data first.  */
4593e4b17023SJohn Marino   lang_hooks.free_lang_data (decl);
4594e4b17023SJohn Marino 
4595e4b17023SJohn Marino   TREE_LANG_FLAG_0 (decl) = 0;
4596e4b17023SJohn Marino   TREE_LANG_FLAG_1 (decl) = 0;
4597e4b17023SJohn Marino   TREE_LANG_FLAG_2 (decl) = 0;
4598e4b17023SJohn Marino   TREE_LANG_FLAG_3 (decl) = 0;
4599e4b17023SJohn Marino   TREE_LANG_FLAG_4 (decl) = 0;
4600e4b17023SJohn Marino   TREE_LANG_FLAG_5 (decl) = 0;
4601e4b17023SJohn Marino   TREE_LANG_FLAG_6 (decl) = 0;
4602e4b17023SJohn Marino 
4603e4b17023SJohn Marino   free_lang_data_in_one_sizepos (&DECL_SIZE (decl));
4604e4b17023SJohn Marino   free_lang_data_in_one_sizepos (&DECL_SIZE_UNIT (decl));
4605e4b17023SJohn Marino   if (TREE_CODE (decl) == FIELD_DECL)
4606e4b17023SJohn Marino     {
4607e4b17023SJohn Marino       free_lang_data_in_one_sizepos (&DECL_FIELD_OFFSET (decl));
4608e4b17023SJohn Marino       if (TREE_CODE (DECL_CONTEXT (decl)) == QUAL_UNION_TYPE)
4609e4b17023SJohn Marino 	DECL_QUALIFIER (decl) = NULL_TREE;
4610e4b17023SJohn Marino     }
4611e4b17023SJohn Marino 
4612e4b17023SJohn Marino  if (TREE_CODE (decl) == FUNCTION_DECL)
4613e4b17023SJohn Marino     {
4614e4b17023SJohn Marino       if (gimple_has_body_p (decl))
4615e4b17023SJohn Marino 	{
4616e4b17023SJohn Marino 	  tree t;
4617e4b17023SJohn Marino 
4618e4b17023SJohn Marino 	  /* If DECL has a gimple body, then the context for its
4619e4b17023SJohn Marino 	     arguments must be DECL.  Otherwise, it doesn't really
4620e4b17023SJohn Marino 	     matter, as we will not be emitting any code for DECL.  In
4621e4b17023SJohn Marino 	     general, there may be other instances of DECL created by
4622e4b17023SJohn Marino 	     the front end and since PARM_DECLs are generally shared,
4623e4b17023SJohn Marino 	     their DECL_CONTEXT changes as the replicas of DECL are
4624e4b17023SJohn Marino 	     created.  The only time where DECL_CONTEXT is important
4625e4b17023SJohn Marino 	     is for the FUNCTION_DECLs that have a gimple body (since
4626e4b17023SJohn Marino 	     the PARM_DECL will be used in the function's body).  */
4627e4b17023SJohn Marino 	  for (t = DECL_ARGUMENTS (decl); t; t = TREE_CHAIN (t))
4628e4b17023SJohn Marino 	    DECL_CONTEXT (t) = decl;
4629e4b17023SJohn Marino 	}
4630e4b17023SJohn Marino 
4631e4b17023SJohn Marino       /* DECL_SAVED_TREE holds the GENERIC representation for DECL.
4632e4b17023SJohn Marino 	 At this point, it is not needed anymore.  */
4633e4b17023SJohn Marino       DECL_SAVED_TREE (decl) = NULL_TREE;
4634e4b17023SJohn Marino 
4635e4b17023SJohn Marino       /* Clear the abstract origin if it refers to a method.  Otherwise
4636e4b17023SJohn Marino          dwarf2out.c will ICE as we clear TYPE_METHODS and thus the
4637e4b17023SJohn Marino 	 origin will not be output correctly.  */
4638e4b17023SJohn Marino       if (DECL_ABSTRACT_ORIGIN (decl)
4639e4b17023SJohn Marino 	  && DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))
4640e4b17023SJohn Marino 	  && RECORD_OR_UNION_TYPE_P
4641e4b17023SJohn Marino 	       (DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))))
4642e4b17023SJohn Marino 	DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
4643e4b17023SJohn Marino 
4644e4b17023SJohn Marino       /* Sometimes the C++ frontend doesn't manage to transform a temporary
4645e4b17023SJohn Marino          DECL_VINDEX referring to itself into a vtable slot number as it
4646e4b17023SJohn Marino 	 should.  Happens with functions that are copied and then forgotten
4647e4b17023SJohn Marino 	 about.  Just clear it, it won't matter anymore.  */
4648e4b17023SJohn Marino       if (DECL_VINDEX (decl) && !host_integerp (DECL_VINDEX (decl), 0))
4649e4b17023SJohn Marino 	DECL_VINDEX (decl) = NULL_TREE;
4650e4b17023SJohn Marino     }
4651e4b17023SJohn Marino   else if (TREE_CODE (decl) == VAR_DECL)
4652e4b17023SJohn Marino     {
4653e4b17023SJohn Marino       if ((DECL_EXTERNAL (decl)
4654e4b17023SJohn Marino 	   && (!TREE_STATIC (decl) || !TREE_READONLY (decl)))
4655e4b17023SJohn Marino 	  || (decl_function_context (decl) && !TREE_STATIC (decl)))
4656e4b17023SJohn Marino 	DECL_INITIAL (decl) = NULL_TREE;
4657e4b17023SJohn Marino     }
4658e4b17023SJohn Marino   else if (TREE_CODE (decl) == TYPE_DECL
4659e4b17023SJohn Marino 	   || TREE_CODE (decl) == FIELD_DECL)
4660e4b17023SJohn Marino     DECL_INITIAL (decl) = NULL_TREE;
4661e4b17023SJohn Marino   else if (TREE_CODE (decl) == TRANSLATION_UNIT_DECL
4662e4b17023SJohn Marino            && DECL_INITIAL (decl)
4663e4b17023SJohn Marino            && TREE_CODE (DECL_INITIAL (decl)) == BLOCK)
4664e4b17023SJohn Marino     {
4665e4b17023SJohn Marino       /* Strip builtins from the translation-unit BLOCK.  We still have targets
4666e4b17023SJohn Marino 	 without builtin_decl_explicit support and also builtins are shared
4667e4b17023SJohn Marino 	 nodes and thus we can't use TREE_CHAIN in multiple lists.  */
4668e4b17023SJohn Marino       tree *nextp = &BLOCK_VARS (DECL_INITIAL (decl));
4669e4b17023SJohn Marino       while (*nextp)
4670e4b17023SJohn Marino         {
4671e4b17023SJohn Marino           tree var = *nextp;
4672e4b17023SJohn Marino           if (TREE_CODE (var) == FUNCTION_DECL
4673e4b17023SJohn Marino               && DECL_BUILT_IN (var))
4674e4b17023SJohn Marino 	    *nextp = TREE_CHAIN (var);
4675e4b17023SJohn Marino 	  else
4676e4b17023SJohn Marino 	    nextp = &TREE_CHAIN (var);
4677e4b17023SJohn Marino         }
4678e4b17023SJohn Marino     }
4679e4b17023SJohn Marino }
4680e4b17023SJohn Marino 
4681e4b17023SJohn Marino 
4682e4b17023SJohn Marino /* Data used when collecting DECLs and TYPEs for language data removal.  */
4683e4b17023SJohn Marino 
4684e4b17023SJohn Marino struct free_lang_data_d
4685e4b17023SJohn Marino {
4686e4b17023SJohn Marino   /* Worklist to avoid excessive recursion.  */
4687e4b17023SJohn Marino   VEC(tree,heap) *worklist;
4688e4b17023SJohn Marino 
4689e4b17023SJohn Marino   /* Set of traversed objects.  Used to avoid duplicate visits.  */
4690e4b17023SJohn Marino   struct pointer_set_t *pset;
4691e4b17023SJohn Marino 
4692e4b17023SJohn Marino   /* Array of symbols to process with free_lang_data_in_decl.  */
4693e4b17023SJohn Marino   VEC(tree,heap) *decls;
4694e4b17023SJohn Marino 
4695e4b17023SJohn Marino   /* Array of types to process with free_lang_data_in_type.  */
4696e4b17023SJohn Marino   VEC(tree,heap) *types;
4697e4b17023SJohn Marino };
4698e4b17023SJohn Marino 
4699e4b17023SJohn Marino 
4700e4b17023SJohn Marino /* Save all language fields needed to generate proper debug information
4701e4b17023SJohn Marino    for DECL.  This saves most fields cleared out by free_lang_data_in_decl.  */
4702e4b17023SJohn Marino 
4703e4b17023SJohn Marino static void
save_debug_info_for_decl(tree t)4704e4b17023SJohn Marino save_debug_info_for_decl (tree t)
4705e4b17023SJohn Marino {
4706e4b17023SJohn Marino   /*struct saved_debug_info_d *sdi;*/
4707e4b17023SJohn Marino 
4708e4b17023SJohn Marino   gcc_assert (debug_info_level > DINFO_LEVEL_TERSE && t && DECL_P (t));
4709e4b17023SJohn Marino 
4710e4b17023SJohn Marino   /* FIXME.  Partial implementation for saving debug info removed.  */
4711e4b17023SJohn Marino }
4712e4b17023SJohn Marino 
4713e4b17023SJohn Marino 
4714e4b17023SJohn Marino /* Save all language fields needed to generate proper debug information
4715e4b17023SJohn Marino    for TYPE.  This saves most fields cleared out by free_lang_data_in_type.  */
4716e4b17023SJohn Marino 
4717e4b17023SJohn Marino static void
save_debug_info_for_type(tree t)4718e4b17023SJohn Marino save_debug_info_for_type (tree t)
4719e4b17023SJohn Marino {
4720e4b17023SJohn Marino   /*struct saved_debug_info_d *sdi;*/
4721e4b17023SJohn Marino 
4722e4b17023SJohn Marino   gcc_assert (debug_info_level > DINFO_LEVEL_TERSE && t && TYPE_P (t));
4723e4b17023SJohn Marino 
4724e4b17023SJohn Marino   /* FIXME.  Partial implementation for saving debug info removed.  */
4725e4b17023SJohn Marino }
4726e4b17023SJohn Marino 
4727e4b17023SJohn Marino 
4728e4b17023SJohn Marino /* Add type or decl T to one of the list of tree nodes that need their
4729e4b17023SJohn Marino    language data removed.  The lists are held inside FLD.  */
4730e4b17023SJohn Marino 
4731e4b17023SJohn Marino static void
add_tree_to_fld_list(tree t,struct free_lang_data_d * fld)4732e4b17023SJohn Marino add_tree_to_fld_list (tree t, struct free_lang_data_d *fld)
4733e4b17023SJohn Marino {
4734e4b17023SJohn Marino   if (DECL_P (t))
4735e4b17023SJohn Marino     {
4736e4b17023SJohn Marino       VEC_safe_push (tree, heap, fld->decls, t);
4737e4b17023SJohn Marino       if (debug_info_level > DINFO_LEVEL_TERSE)
4738e4b17023SJohn Marino 	save_debug_info_for_decl (t);
4739e4b17023SJohn Marino     }
4740e4b17023SJohn Marino   else if (TYPE_P (t))
4741e4b17023SJohn Marino     {
4742e4b17023SJohn Marino       VEC_safe_push (tree, heap, fld->types, t);
4743e4b17023SJohn Marino       if (debug_info_level > DINFO_LEVEL_TERSE)
4744e4b17023SJohn Marino 	save_debug_info_for_type (t);
4745e4b17023SJohn Marino     }
4746e4b17023SJohn Marino   else
4747e4b17023SJohn Marino     gcc_unreachable ();
4748e4b17023SJohn Marino }
4749e4b17023SJohn Marino 
4750e4b17023SJohn Marino /* Push tree node T into FLD->WORKLIST.  */
4751e4b17023SJohn Marino 
4752e4b17023SJohn Marino static inline void
fld_worklist_push(tree t,struct free_lang_data_d * fld)4753e4b17023SJohn Marino fld_worklist_push (tree t, struct free_lang_data_d *fld)
4754e4b17023SJohn Marino {
4755e4b17023SJohn Marino   if (t && !is_lang_specific (t) && !pointer_set_contains (fld->pset, t))
4756e4b17023SJohn Marino     VEC_safe_push (tree, heap, fld->worklist, (t));
4757e4b17023SJohn Marino }
4758e4b17023SJohn Marino 
4759e4b17023SJohn Marino 
4760e4b17023SJohn Marino /* Operand callback helper for free_lang_data_in_node.  *TP is the
4761e4b17023SJohn Marino    subtree operand being considered.  */
4762e4b17023SJohn Marino 
4763e4b17023SJohn Marino static tree
find_decls_types_r(tree * tp,int * ws,void * data)4764e4b17023SJohn Marino find_decls_types_r (tree *tp, int *ws, void *data)
4765e4b17023SJohn Marino {
4766e4b17023SJohn Marino   tree t = *tp;
4767e4b17023SJohn Marino   struct free_lang_data_d *fld = (struct free_lang_data_d *) data;
4768e4b17023SJohn Marino 
4769e4b17023SJohn Marino   if (TREE_CODE (t) == TREE_LIST)
4770e4b17023SJohn Marino     return NULL_TREE;
4771e4b17023SJohn Marino 
4772e4b17023SJohn Marino   /* Language specific nodes will be removed, so there is no need
4773e4b17023SJohn Marino      to gather anything under them.  */
4774e4b17023SJohn Marino   if (is_lang_specific (t))
4775e4b17023SJohn Marino     {
4776e4b17023SJohn Marino       *ws = 0;
4777e4b17023SJohn Marino       return NULL_TREE;
4778e4b17023SJohn Marino     }
4779e4b17023SJohn Marino 
4780e4b17023SJohn Marino   if (DECL_P (t))
4781e4b17023SJohn Marino     {
4782e4b17023SJohn Marino       /* Note that walk_tree does not traverse every possible field in
4783e4b17023SJohn Marino 	 decls, so we have to do our own traversals here.  */
4784e4b17023SJohn Marino       add_tree_to_fld_list (t, fld);
4785e4b17023SJohn Marino 
4786e4b17023SJohn Marino       fld_worklist_push (DECL_NAME (t), fld);
4787e4b17023SJohn Marino       fld_worklist_push (DECL_CONTEXT (t), fld);
4788e4b17023SJohn Marino       fld_worklist_push (DECL_SIZE (t), fld);
4789e4b17023SJohn Marino       fld_worklist_push (DECL_SIZE_UNIT (t), fld);
4790e4b17023SJohn Marino 
4791e4b17023SJohn Marino       /* We are going to remove everything under DECL_INITIAL for
4792e4b17023SJohn Marino 	 TYPE_DECLs.  No point walking them.  */
4793e4b17023SJohn Marino       if (TREE_CODE (t) != TYPE_DECL)
4794e4b17023SJohn Marino 	fld_worklist_push (DECL_INITIAL (t), fld);
4795e4b17023SJohn Marino 
4796e4b17023SJohn Marino       fld_worklist_push (DECL_ATTRIBUTES (t), fld);
4797e4b17023SJohn Marino       fld_worklist_push (DECL_ABSTRACT_ORIGIN (t), fld);
4798e4b17023SJohn Marino 
4799e4b17023SJohn Marino       if (TREE_CODE (t) == FUNCTION_DECL)
4800e4b17023SJohn Marino 	{
4801e4b17023SJohn Marino 	  fld_worklist_push (DECL_ARGUMENTS (t), fld);
4802e4b17023SJohn Marino 	  fld_worklist_push (DECL_RESULT (t), fld);
4803e4b17023SJohn Marino 	}
4804e4b17023SJohn Marino       else if (TREE_CODE (t) == TYPE_DECL)
4805e4b17023SJohn Marino 	{
4806e4b17023SJohn Marino 	  fld_worklist_push (DECL_ARGUMENT_FLD (t), fld);
4807e4b17023SJohn Marino 	  fld_worklist_push (DECL_VINDEX (t), fld);
4808e4b17023SJohn Marino 	  fld_worklist_push (DECL_ORIGINAL_TYPE (t), fld);
4809e4b17023SJohn Marino 	}
4810e4b17023SJohn Marino       else if (TREE_CODE (t) == FIELD_DECL)
4811e4b17023SJohn Marino 	{
4812e4b17023SJohn Marino 	  fld_worklist_push (DECL_FIELD_OFFSET (t), fld);
4813e4b17023SJohn Marino 	  fld_worklist_push (DECL_BIT_FIELD_TYPE (t), fld);
4814e4b17023SJohn Marino 	  fld_worklist_push (DECL_FIELD_BIT_OFFSET (t), fld);
4815e4b17023SJohn Marino 	  fld_worklist_push (DECL_FCONTEXT (t), fld);
4816e4b17023SJohn Marino 	}
4817e4b17023SJohn Marino       else if (TREE_CODE (t) == VAR_DECL)
4818e4b17023SJohn Marino 	{
4819e4b17023SJohn Marino 	  fld_worklist_push (DECL_SECTION_NAME (t), fld);
4820e4b17023SJohn Marino 	  fld_worklist_push (DECL_COMDAT_GROUP (t), fld);
4821e4b17023SJohn Marino 	}
4822e4b17023SJohn Marino 
4823e4b17023SJohn Marino       if ((TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL)
4824e4b17023SJohn Marino 	  && DECL_HAS_VALUE_EXPR_P (t))
4825e4b17023SJohn Marino 	fld_worklist_push (DECL_VALUE_EXPR (t), fld);
4826e4b17023SJohn Marino 
4827e4b17023SJohn Marino       if (TREE_CODE (t) != FIELD_DECL
4828e4b17023SJohn Marino 	  && TREE_CODE (t) != TYPE_DECL)
4829e4b17023SJohn Marino 	fld_worklist_push (TREE_CHAIN (t), fld);
4830e4b17023SJohn Marino       *ws = 0;
4831e4b17023SJohn Marino     }
4832e4b17023SJohn Marino   else if (TYPE_P (t))
4833e4b17023SJohn Marino     {
4834e4b17023SJohn Marino       /* Note that walk_tree does not traverse every possible field in
4835e4b17023SJohn Marino 	 types, so we have to do our own traversals here.  */
4836e4b17023SJohn Marino       add_tree_to_fld_list (t, fld);
4837e4b17023SJohn Marino 
4838e4b17023SJohn Marino       if (!RECORD_OR_UNION_TYPE_P (t))
4839e4b17023SJohn Marino 	fld_worklist_push (TYPE_CACHED_VALUES (t), fld);
4840e4b17023SJohn Marino       fld_worklist_push (TYPE_SIZE (t), fld);
4841e4b17023SJohn Marino       fld_worklist_push (TYPE_SIZE_UNIT (t), fld);
4842e4b17023SJohn Marino       fld_worklist_push (TYPE_ATTRIBUTES (t), fld);
4843e4b17023SJohn Marino       fld_worklist_push (TYPE_POINTER_TO (t), fld);
4844e4b17023SJohn Marino       fld_worklist_push (TYPE_REFERENCE_TO (t), fld);
4845e4b17023SJohn Marino       fld_worklist_push (TYPE_NAME (t), fld);
4846e4b17023SJohn Marino       /* Do not walk TYPE_NEXT_PTR_TO or TYPE_NEXT_REF_TO.  We do not stream
4847e4b17023SJohn Marino 	 them and thus do not and want not to reach unused pointer types
4848e4b17023SJohn Marino 	 this way.  */
4849e4b17023SJohn Marino       if (!POINTER_TYPE_P (t))
4850e4b17023SJohn Marino 	fld_worklist_push (TYPE_MINVAL (t), fld);
4851e4b17023SJohn Marino       if (!RECORD_OR_UNION_TYPE_P (t))
4852e4b17023SJohn Marino 	fld_worklist_push (TYPE_MAXVAL (t), fld);
4853e4b17023SJohn Marino       fld_worklist_push (TYPE_MAIN_VARIANT (t), fld);
4854e4b17023SJohn Marino       /* Do not walk TYPE_NEXT_VARIANT.  We do not stream it and thus
4855e4b17023SJohn Marino          do not and want not to reach unused variants this way.  */
4856e4b17023SJohn Marino       if (TYPE_CONTEXT (t))
4857e4b17023SJohn Marino 	{
4858e4b17023SJohn Marino 	  tree ctx = TYPE_CONTEXT (t);
4859e4b17023SJohn Marino 	  /* We adjust BLOCK TYPE_CONTEXTs to the innermost non-BLOCK one.
4860e4b17023SJohn Marino 	     So push that instead.  */
4861e4b17023SJohn Marino 	  while (ctx && TREE_CODE (ctx) == BLOCK)
4862e4b17023SJohn Marino 	    ctx = BLOCK_SUPERCONTEXT (ctx);
4863e4b17023SJohn Marino 	  fld_worklist_push (ctx, fld);
4864e4b17023SJohn Marino 	}
4865e4b17023SJohn Marino       /* Do not walk TYPE_CANONICAL.  We do not stream it and thus do not
4866e4b17023SJohn Marino 	 and want not to reach unused types this way.  */
4867e4b17023SJohn Marino 
4868e4b17023SJohn Marino       if (RECORD_OR_UNION_TYPE_P (t) && TYPE_BINFO (t))
4869e4b17023SJohn Marino 	{
4870e4b17023SJohn Marino 	  unsigned i;
4871e4b17023SJohn Marino 	  tree tem;
4872e4b17023SJohn Marino 	  for (i = 0; VEC_iterate (tree, BINFO_BASE_BINFOS (TYPE_BINFO (t)),
4873e4b17023SJohn Marino 				   i, tem); ++i)
4874e4b17023SJohn Marino 	    fld_worklist_push (TREE_TYPE (tem), fld);
4875e4b17023SJohn Marino 	  tem = BINFO_VIRTUALS (TYPE_BINFO (t));
4876e4b17023SJohn Marino 	  if (tem
4877e4b17023SJohn Marino 	      /* The Java FE overloads BINFO_VIRTUALS for its own purpose.  */
4878e4b17023SJohn Marino 	      && TREE_CODE (tem) == TREE_LIST)
4879e4b17023SJohn Marino 	    do
4880e4b17023SJohn Marino 	      {
4881e4b17023SJohn Marino 		fld_worklist_push (TREE_VALUE (tem), fld);
4882e4b17023SJohn Marino 		tem = TREE_CHAIN (tem);
4883e4b17023SJohn Marino 	      }
4884e4b17023SJohn Marino 	    while (tem);
4885e4b17023SJohn Marino 	}
4886e4b17023SJohn Marino       if (RECORD_OR_UNION_TYPE_P (t))
4887e4b17023SJohn Marino 	{
4888e4b17023SJohn Marino 	  tree tem;
4889e4b17023SJohn Marino 	  /* Push all TYPE_FIELDS - there can be interleaving interesting
4890e4b17023SJohn Marino 	     and non-interesting things.  */
4891e4b17023SJohn Marino 	  tem = TYPE_FIELDS (t);
4892e4b17023SJohn Marino 	  while (tem)
4893e4b17023SJohn Marino 	    {
4894e4b17023SJohn Marino 	      if (TREE_CODE (tem) == FIELD_DECL
4895e4b17023SJohn Marino 		  || TREE_CODE (tem) == TYPE_DECL)
4896e4b17023SJohn Marino 		fld_worklist_push (tem, fld);
4897e4b17023SJohn Marino 	      tem = TREE_CHAIN (tem);
4898e4b17023SJohn Marino 	    }
4899e4b17023SJohn Marino 	}
4900e4b17023SJohn Marino 
4901e4b17023SJohn Marino       fld_worklist_push (TYPE_STUB_DECL (t), fld);
4902e4b17023SJohn Marino       *ws = 0;
4903e4b17023SJohn Marino     }
4904e4b17023SJohn Marino   else if (TREE_CODE (t) == BLOCK)
4905e4b17023SJohn Marino     {
4906e4b17023SJohn Marino       tree tem;
4907e4b17023SJohn Marino       for (tem = BLOCK_VARS (t); tem; tem = TREE_CHAIN (tem))
4908e4b17023SJohn Marino 	fld_worklist_push (tem, fld);
4909e4b17023SJohn Marino       for (tem = BLOCK_SUBBLOCKS (t); tem; tem = BLOCK_CHAIN (tem))
4910e4b17023SJohn Marino 	fld_worklist_push (tem, fld);
4911e4b17023SJohn Marino       fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
4912e4b17023SJohn Marino     }
4913e4b17023SJohn Marino 
4914e4b17023SJohn Marino   if (TREE_CODE (t) != IDENTIFIER_NODE
4915e4b17023SJohn Marino       && CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
4916e4b17023SJohn Marino     fld_worklist_push (TREE_TYPE (t), fld);
4917e4b17023SJohn Marino 
4918e4b17023SJohn Marino   return NULL_TREE;
4919e4b17023SJohn Marino }
4920e4b17023SJohn Marino 
4921e4b17023SJohn Marino 
4922e4b17023SJohn Marino /* Find decls and types in T.  */
4923e4b17023SJohn Marino 
4924e4b17023SJohn Marino static void
find_decls_types(tree t,struct free_lang_data_d * fld)4925e4b17023SJohn Marino find_decls_types (tree t, struct free_lang_data_d *fld)
4926e4b17023SJohn Marino {
4927e4b17023SJohn Marino   while (1)
4928e4b17023SJohn Marino     {
4929e4b17023SJohn Marino       if (!pointer_set_contains (fld->pset, t))
4930e4b17023SJohn Marino 	walk_tree (&t, find_decls_types_r, fld, fld->pset);
4931e4b17023SJohn Marino       if (VEC_empty (tree, fld->worklist))
4932e4b17023SJohn Marino 	break;
4933e4b17023SJohn Marino       t = VEC_pop (tree, fld->worklist);
4934e4b17023SJohn Marino     }
4935e4b17023SJohn Marino }
4936e4b17023SJohn Marino 
4937e4b17023SJohn Marino /* Translate all the types in LIST with the corresponding runtime
4938e4b17023SJohn Marino    types.  */
4939e4b17023SJohn Marino 
4940e4b17023SJohn Marino static tree
get_eh_types_for_runtime(tree list)4941e4b17023SJohn Marino get_eh_types_for_runtime (tree list)
4942e4b17023SJohn Marino {
4943e4b17023SJohn Marino   tree head, prev;
4944e4b17023SJohn Marino 
4945e4b17023SJohn Marino   if (list == NULL_TREE)
4946e4b17023SJohn Marino     return NULL_TREE;
4947e4b17023SJohn Marino 
4948e4b17023SJohn Marino   head = build_tree_list (0, lookup_type_for_runtime (TREE_VALUE (list)));
4949e4b17023SJohn Marino   prev = head;
4950e4b17023SJohn Marino   list = TREE_CHAIN (list);
4951e4b17023SJohn Marino   while (list)
4952e4b17023SJohn Marino     {
4953e4b17023SJohn Marino       tree n = build_tree_list (0, lookup_type_for_runtime (TREE_VALUE (list)));
4954e4b17023SJohn Marino       TREE_CHAIN (prev) = n;
4955e4b17023SJohn Marino       prev = TREE_CHAIN (prev);
4956e4b17023SJohn Marino       list = TREE_CHAIN (list);
4957e4b17023SJohn Marino     }
4958e4b17023SJohn Marino 
4959e4b17023SJohn Marino   return head;
4960e4b17023SJohn Marino }
4961e4b17023SJohn Marino 
4962e4b17023SJohn Marino 
4963e4b17023SJohn Marino /* Find decls and types referenced in EH region R and store them in
4964e4b17023SJohn Marino    FLD->DECLS and FLD->TYPES.  */
4965e4b17023SJohn Marino 
4966e4b17023SJohn Marino static void
find_decls_types_in_eh_region(eh_region r,struct free_lang_data_d * fld)4967e4b17023SJohn Marino find_decls_types_in_eh_region (eh_region r, struct free_lang_data_d *fld)
4968e4b17023SJohn Marino {
4969e4b17023SJohn Marino   switch (r->type)
4970e4b17023SJohn Marino     {
4971e4b17023SJohn Marino     case ERT_CLEANUP:
4972e4b17023SJohn Marino       break;
4973e4b17023SJohn Marino 
4974e4b17023SJohn Marino     case ERT_TRY:
4975e4b17023SJohn Marino       {
4976e4b17023SJohn Marino 	eh_catch c;
4977e4b17023SJohn Marino 
4978e4b17023SJohn Marino 	/* The types referenced in each catch must first be changed to the
4979e4b17023SJohn Marino 	   EH types used at runtime.  This removes references to FE types
4980e4b17023SJohn Marino 	   in the region.  */
4981e4b17023SJohn Marino 	for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
4982e4b17023SJohn Marino 	  {
4983e4b17023SJohn Marino 	    c->type_list = get_eh_types_for_runtime (c->type_list);
4984e4b17023SJohn Marino 	    walk_tree (&c->type_list, find_decls_types_r, fld, fld->pset);
4985e4b17023SJohn Marino 	  }
4986e4b17023SJohn Marino       }
4987e4b17023SJohn Marino       break;
4988e4b17023SJohn Marino 
4989e4b17023SJohn Marino     case ERT_ALLOWED_EXCEPTIONS:
4990e4b17023SJohn Marino       r->u.allowed.type_list
4991e4b17023SJohn Marino 	= get_eh_types_for_runtime (r->u.allowed.type_list);
4992e4b17023SJohn Marino       walk_tree (&r->u.allowed.type_list, find_decls_types_r, fld, fld->pset);
4993e4b17023SJohn Marino       break;
4994e4b17023SJohn Marino 
4995e4b17023SJohn Marino     case ERT_MUST_NOT_THROW:
4996e4b17023SJohn Marino       walk_tree (&r->u.must_not_throw.failure_decl,
4997e4b17023SJohn Marino 		 find_decls_types_r, fld, fld->pset);
4998e4b17023SJohn Marino       break;
4999e4b17023SJohn Marino     }
5000e4b17023SJohn Marino }
5001e4b17023SJohn Marino 
5002e4b17023SJohn Marino 
5003e4b17023SJohn Marino /* Find decls and types referenced in cgraph node N and store them in
5004e4b17023SJohn Marino    FLD->DECLS and FLD->TYPES.  Unlike pass_referenced_vars, this will
5005e4b17023SJohn Marino    look for *every* kind of DECL and TYPE node reachable from N,
5006e4b17023SJohn Marino    including those embedded inside types and decls (i.e,, TYPE_DECLs,
5007e4b17023SJohn Marino    NAMESPACE_DECLs, etc).  */
5008e4b17023SJohn Marino 
5009e4b17023SJohn Marino static void
find_decls_types_in_node(struct cgraph_node * n,struct free_lang_data_d * fld)5010e4b17023SJohn Marino find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld)
5011e4b17023SJohn Marino {
5012e4b17023SJohn Marino   basic_block bb;
5013e4b17023SJohn Marino   struct function *fn;
5014e4b17023SJohn Marino   unsigned ix;
5015e4b17023SJohn Marino   tree t;
5016e4b17023SJohn Marino 
5017e4b17023SJohn Marino   find_decls_types (n->decl, fld);
5018e4b17023SJohn Marino 
5019e4b17023SJohn Marino   if (!gimple_has_body_p (n->decl))
5020e4b17023SJohn Marino     return;
5021e4b17023SJohn Marino 
5022e4b17023SJohn Marino   gcc_assert (current_function_decl == NULL_TREE && cfun == NULL);
5023e4b17023SJohn Marino 
5024e4b17023SJohn Marino   fn = DECL_STRUCT_FUNCTION (n->decl);
5025e4b17023SJohn Marino 
5026e4b17023SJohn Marino   /* Traverse locals. */
5027e4b17023SJohn Marino   FOR_EACH_LOCAL_DECL (fn, ix, t)
5028e4b17023SJohn Marino     find_decls_types (t, fld);
5029e4b17023SJohn Marino 
5030e4b17023SJohn Marino   /* Traverse EH regions in FN.  */
5031e4b17023SJohn Marino   {
5032e4b17023SJohn Marino     eh_region r;
5033e4b17023SJohn Marino     FOR_ALL_EH_REGION_FN (r, fn)
5034e4b17023SJohn Marino       find_decls_types_in_eh_region (r, fld);
5035e4b17023SJohn Marino   }
5036e4b17023SJohn Marino 
5037e4b17023SJohn Marino   /* Traverse every statement in FN.  */
5038e4b17023SJohn Marino   FOR_EACH_BB_FN (bb, fn)
5039e4b17023SJohn Marino     {
5040e4b17023SJohn Marino       gimple_stmt_iterator si;
5041e4b17023SJohn Marino       unsigned i;
5042e4b17023SJohn Marino 
5043e4b17023SJohn Marino       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
5044e4b17023SJohn Marino 	{
5045e4b17023SJohn Marino 	  gimple phi = gsi_stmt (si);
5046e4b17023SJohn Marino 
5047e4b17023SJohn Marino 	  for (i = 0; i < gimple_phi_num_args (phi); i++)
5048e4b17023SJohn Marino 	    {
5049e4b17023SJohn Marino 	      tree *arg_p = gimple_phi_arg_def_ptr (phi, i);
5050e4b17023SJohn Marino 	      find_decls_types (*arg_p, fld);
5051e4b17023SJohn Marino 	    }
5052e4b17023SJohn Marino 	}
5053e4b17023SJohn Marino 
5054e4b17023SJohn Marino       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
5055e4b17023SJohn Marino 	{
5056e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (si);
5057e4b17023SJohn Marino 
5058e4b17023SJohn Marino 	  if (is_gimple_call (stmt))
5059e4b17023SJohn Marino 	    find_decls_types (gimple_call_fntype (stmt), fld);
5060e4b17023SJohn Marino 
5061e4b17023SJohn Marino 	  for (i = 0; i < gimple_num_ops (stmt); i++)
5062e4b17023SJohn Marino 	    {
5063e4b17023SJohn Marino 	      tree arg = gimple_op (stmt, i);
5064e4b17023SJohn Marino 	      find_decls_types (arg, fld);
5065e4b17023SJohn Marino 	    }
5066e4b17023SJohn Marino 	}
5067e4b17023SJohn Marino     }
5068e4b17023SJohn Marino }
5069e4b17023SJohn Marino 
5070e4b17023SJohn Marino 
5071e4b17023SJohn Marino /* Find decls and types referenced in varpool node N and store them in
5072e4b17023SJohn Marino    FLD->DECLS and FLD->TYPES.  Unlike pass_referenced_vars, this will
5073e4b17023SJohn Marino    look for *every* kind of DECL and TYPE node reachable from N,
5074e4b17023SJohn Marino    including those embedded inside types and decls (i.e,, TYPE_DECLs,
5075e4b17023SJohn Marino    NAMESPACE_DECLs, etc).  */
5076e4b17023SJohn Marino 
5077e4b17023SJohn Marino static void
find_decls_types_in_var(struct varpool_node * v,struct free_lang_data_d * fld)5078e4b17023SJohn Marino find_decls_types_in_var (struct varpool_node *v, struct free_lang_data_d *fld)
5079e4b17023SJohn Marino {
5080e4b17023SJohn Marino   find_decls_types (v->decl, fld);
5081e4b17023SJohn Marino }
5082e4b17023SJohn Marino 
5083e4b17023SJohn Marino /* If T needs an assembler name, have one created for it.  */
5084e4b17023SJohn Marino 
5085e4b17023SJohn Marino void
assign_assembler_name_if_neeeded(tree t)5086e4b17023SJohn Marino assign_assembler_name_if_neeeded (tree t)
5087e4b17023SJohn Marino {
5088e4b17023SJohn Marino   if (need_assembler_name_p (t))
5089e4b17023SJohn Marino     {
5090e4b17023SJohn Marino       /* When setting DECL_ASSEMBLER_NAME, the C++ mangler may emit
5091e4b17023SJohn Marino 	 diagnostics that use input_location to show locus
5092e4b17023SJohn Marino 	 information.  The problem here is that, at this point,
5093e4b17023SJohn Marino 	 input_location is generally anchored to the end of the file
5094e4b17023SJohn Marino 	 (since the parser is long gone), so we don't have a good
5095e4b17023SJohn Marino 	 position to pin it to.
5096e4b17023SJohn Marino 
5097e4b17023SJohn Marino 	 To alleviate this problem, this uses the location of T's
5098e4b17023SJohn Marino 	 declaration.  Examples of this are
5099e4b17023SJohn Marino 	 testsuite/g++.dg/template/cond2.C and
5100e4b17023SJohn Marino 	 testsuite/g++.dg/template/pr35240.C.  */
5101e4b17023SJohn Marino       location_t saved_location = input_location;
5102e4b17023SJohn Marino       input_location = DECL_SOURCE_LOCATION (t);
5103e4b17023SJohn Marino 
5104e4b17023SJohn Marino       decl_assembler_name (t);
5105e4b17023SJohn Marino 
5106e4b17023SJohn Marino       input_location = saved_location;
5107e4b17023SJohn Marino     }
5108e4b17023SJohn Marino }
5109e4b17023SJohn Marino 
5110e4b17023SJohn Marino 
5111e4b17023SJohn Marino /* Free language specific information for every operand and expression
5112e4b17023SJohn Marino    in every node of the call graph.  This process operates in three stages:
5113e4b17023SJohn Marino 
5114e4b17023SJohn Marino    1- Every callgraph node and varpool node is traversed looking for
5115e4b17023SJohn Marino       decls and types embedded in them.  This is a more exhaustive
5116e4b17023SJohn Marino       search than that done by find_referenced_vars, because it will
5117e4b17023SJohn Marino       also collect individual fields, decls embedded in types, etc.
5118e4b17023SJohn Marino 
5119e4b17023SJohn Marino    2- All the decls found are sent to free_lang_data_in_decl.
5120e4b17023SJohn Marino 
5121e4b17023SJohn Marino    3- All the types found are sent to free_lang_data_in_type.
5122e4b17023SJohn Marino 
5123e4b17023SJohn Marino    The ordering between decls and types is important because
5124e4b17023SJohn Marino    free_lang_data_in_decl sets assembler names, which includes
5125e4b17023SJohn Marino    mangling.  So types cannot be freed up until assembler names have
5126e4b17023SJohn Marino    been set up.  */
5127e4b17023SJohn Marino 
5128e4b17023SJohn Marino static void
free_lang_data_in_cgraph(void)5129e4b17023SJohn Marino free_lang_data_in_cgraph (void)
5130e4b17023SJohn Marino {
5131e4b17023SJohn Marino   struct cgraph_node *n;
5132e4b17023SJohn Marino   struct varpool_node *v;
5133e4b17023SJohn Marino   struct free_lang_data_d fld;
5134e4b17023SJohn Marino   tree t;
5135e4b17023SJohn Marino   unsigned i;
5136e4b17023SJohn Marino   alias_pair *p;
5137e4b17023SJohn Marino 
5138e4b17023SJohn Marino   /* Initialize sets and arrays to store referenced decls and types.  */
5139e4b17023SJohn Marino   fld.pset = pointer_set_create ();
5140e4b17023SJohn Marino   fld.worklist = NULL;
5141e4b17023SJohn Marino   fld.decls = VEC_alloc (tree, heap, 100);
5142e4b17023SJohn Marino   fld.types = VEC_alloc (tree, heap, 100);
5143e4b17023SJohn Marino 
5144e4b17023SJohn Marino   /* Find decls and types in the body of every function in the callgraph.  */
5145e4b17023SJohn Marino   for (n = cgraph_nodes; n; n = n->next)
5146e4b17023SJohn Marino     find_decls_types_in_node (n, &fld);
5147e4b17023SJohn Marino 
5148e4b17023SJohn Marino   FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p)
5149e4b17023SJohn Marino     find_decls_types (p->decl, &fld);
5150e4b17023SJohn Marino 
5151e4b17023SJohn Marino   /* Find decls and types in every varpool symbol.  */
5152e4b17023SJohn Marino   for (v = varpool_nodes; v; v = v->next)
5153e4b17023SJohn Marino     find_decls_types_in_var (v, &fld);
5154e4b17023SJohn Marino 
5155e4b17023SJohn Marino   /* Set the assembler name on every decl found.  We need to do this
5156e4b17023SJohn Marino      now because free_lang_data_in_decl will invalidate data needed
5157e4b17023SJohn Marino      for mangling.  This breaks mangling on interdependent decls.  */
5158e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, fld.decls, i, t)
5159e4b17023SJohn Marino     assign_assembler_name_if_neeeded (t);
5160e4b17023SJohn Marino 
5161e4b17023SJohn Marino   /* Traverse every decl found freeing its language data.  */
5162e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, fld.decls, i, t)
5163e4b17023SJohn Marino     free_lang_data_in_decl (t);
5164e4b17023SJohn Marino 
5165e4b17023SJohn Marino   /* Traverse every type found freeing its language data.  */
5166e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, fld.types, i, t)
5167e4b17023SJohn Marino     free_lang_data_in_type (t);
5168e4b17023SJohn Marino 
5169e4b17023SJohn Marino   pointer_set_destroy (fld.pset);
5170e4b17023SJohn Marino   VEC_free (tree, heap, fld.worklist);
5171e4b17023SJohn Marino   VEC_free (tree, heap, fld.decls);
5172e4b17023SJohn Marino   VEC_free (tree, heap, fld.types);
5173e4b17023SJohn Marino }
5174e4b17023SJohn Marino 
5175e4b17023SJohn Marino 
5176e4b17023SJohn Marino /* Free resources that are used by FE but are not needed once they are done. */
5177e4b17023SJohn Marino 
5178e4b17023SJohn Marino static unsigned
free_lang_data(void)5179e4b17023SJohn Marino free_lang_data (void)
5180e4b17023SJohn Marino {
5181e4b17023SJohn Marino   unsigned i;
5182e4b17023SJohn Marino 
5183e4b17023SJohn Marino   /* If we are the LTO frontend we have freed lang-specific data already.  */
5184e4b17023SJohn Marino   if (in_lto_p
5185e4b17023SJohn Marino       || !flag_generate_lto)
5186e4b17023SJohn Marino     return 0;
5187e4b17023SJohn Marino 
5188e4b17023SJohn Marino   /* Allocate and assign alias sets to the standard integer types
5189e4b17023SJohn Marino      while the slots are still in the way the frontends generated them.  */
5190e4b17023SJohn Marino   for (i = 0; i < itk_none; ++i)
5191e4b17023SJohn Marino     if (integer_types[i])
5192e4b17023SJohn Marino       TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i]);
5193e4b17023SJohn Marino 
5194e4b17023SJohn Marino   /* Traverse the IL resetting language specific information for
5195e4b17023SJohn Marino      operands, expressions, etc.  */
5196e4b17023SJohn Marino   free_lang_data_in_cgraph ();
5197e4b17023SJohn Marino 
5198e4b17023SJohn Marino   /* Create gimple variants for common types.  */
5199e4b17023SJohn Marino   ptrdiff_type_node = integer_type_node;
5200e4b17023SJohn Marino   fileptr_type_node = ptr_type_node;
5201e4b17023SJohn Marino 
5202e4b17023SJohn Marino   /* Reset some langhooks.  Do not reset types_compatible_p, it may
5203e4b17023SJohn Marino      still be used indirectly via the get_alias_set langhook.  */
5204e4b17023SJohn Marino   lang_hooks.callgraph.analyze_expr = NULL;
5205e4b17023SJohn Marino   lang_hooks.dwarf_name = lhd_dwarf_name;
5206e4b17023SJohn Marino   lang_hooks.decl_printable_name = gimple_decl_printable_name;
5207e4b17023SJohn Marino   /* We do not want the default decl_assembler_name implementation,
5208e4b17023SJohn Marino      rather if we have fixed everything we want a wrapper around it
5209e4b17023SJohn Marino      asserting that all non-local symbols already got their assembler
5210e4b17023SJohn Marino      name and only produce assembler names for local symbols.  Or rather
5211e4b17023SJohn Marino      make sure we never call decl_assembler_name on local symbols and
5212e4b17023SJohn Marino      devise a separate, middle-end private scheme for it.  */
5213e4b17023SJohn Marino 
5214e4b17023SJohn Marino   /* Reset diagnostic machinery.  */
5215e4b17023SJohn Marino   diagnostic_starter (global_dc) = default_tree_diagnostic_starter;
5216e4b17023SJohn Marino   diagnostic_finalizer (global_dc) = default_diagnostic_finalizer;
5217e4b17023SJohn Marino   diagnostic_format_decoder (global_dc) = default_tree_printer;
5218e4b17023SJohn Marino 
5219e4b17023SJohn Marino   return 0;
5220e4b17023SJohn Marino }
5221e4b17023SJohn Marino 
5222e4b17023SJohn Marino 
5223e4b17023SJohn Marino struct simple_ipa_opt_pass pass_ipa_free_lang_data =
5224e4b17023SJohn Marino {
5225e4b17023SJohn Marino  {
5226e4b17023SJohn Marino   SIMPLE_IPA_PASS,
5227e4b17023SJohn Marino   "*free_lang_data",			/* name */
5228e4b17023SJohn Marino   NULL,					/* gate */
5229e4b17023SJohn Marino   free_lang_data,			/* execute */
5230e4b17023SJohn Marino   NULL,					/* sub */
5231e4b17023SJohn Marino   NULL,					/* next */
5232e4b17023SJohn Marino   0,					/* static_pass_number */
5233e4b17023SJohn Marino   TV_IPA_FREE_LANG_DATA,		/* tv_id */
5234e4b17023SJohn Marino   0,	                                /* properties_required */
5235e4b17023SJohn Marino   0,					/* properties_provided */
5236e4b17023SJohn Marino   0,					/* properties_destroyed */
5237e4b17023SJohn Marino   0,					/* todo_flags_start */
5238e4b17023SJohn Marino   TODO_ggc_collect			/* todo_flags_finish */
5239e4b17023SJohn Marino  }
5240e4b17023SJohn Marino };
5241e4b17023SJohn Marino 
5242e4b17023SJohn Marino /* The backbone of is_attribute_p().  ATTR_LEN is the string length of
5243e4b17023SJohn Marino    ATTR_NAME.  Also used internally by remove_attribute().  */
5244e4b17023SJohn Marino bool
private_is_attribute_p(const char * attr_name,size_t attr_len,const_tree ident)5245e4b17023SJohn Marino private_is_attribute_p (const char *attr_name, size_t attr_len, const_tree ident)
5246e4b17023SJohn Marino {
5247e4b17023SJohn Marino   size_t ident_len = IDENTIFIER_LENGTH (ident);
5248e4b17023SJohn Marino 
5249e4b17023SJohn Marino   if (ident_len == attr_len)
5250e4b17023SJohn Marino     {
5251e4b17023SJohn Marino       if (strcmp (attr_name, IDENTIFIER_POINTER (ident)) == 0)
5252e4b17023SJohn Marino 	return true;
5253e4b17023SJohn Marino     }
5254e4b17023SJohn Marino   else if (ident_len == attr_len + 4)
5255e4b17023SJohn Marino     {
5256e4b17023SJohn Marino       /* There is the possibility that ATTR is 'text' and IDENT is
5257e4b17023SJohn Marino 	 '__text__'.  */
5258e4b17023SJohn Marino       const char *p = IDENTIFIER_POINTER (ident);
5259e4b17023SJohn Marino       if (p[0] == '_' && p[1] == '_'
5260e4b17023SJohn Marino 	  && p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
5261e4b17023SJohn Marino 	  && strncmp (attr_name, p + 2, attr_len) == 0)
5262e4b17023SJohn Marino 	return true;
5263e4b17023SJohn Marino     }
5264e4b17023SJohn Marino 
5265e4b17023SJohn Marino   return false;
5266e4b17023SJohn Marino }
5267e4b17023SJohn Marino 
5268e4b17023SJohn Marino /* The backbone of lookup_attribute().  ATTR_LEN is the string length
5269e4b17023SJohn Marino    of ATTR_NAME, and LIST is not NULL_TREE.  */
5270e4b17023SJohn Marino tree
private_lookup_attribute(const char * attr_name,size_t attr_len,tree list)5271e4b17023SJohn Marino private_lookup_attribute (const char *attr_name, size_t attr_len, tree list)
5272e4b17023SJohn Marino {
5273e4b17023SJohn Marino   while (list)
5274e4b17023SJohn Marino     {
5275e4b17023SJohn Marino       size_t ident_len = IDENTIFIER_LENGTH (TREE_PURPOSE (list));
5276e4b17023SJohn Marino 
5277e4b17023SJohn Marino       if (ident_len == attr_len)
5278e4b17023SJohn Marino 	{
5279e4b17023SJohn Marino 	  if (strcmp (attr_name, IDENTIFIER_POINTER (TREE_PURPOSE (list))) == 0)
5280e4b17023SJohn Marino 	    break;
5281e4b17023SJohn Marino 	}
5282e4b17023SJohn Marino       /* TODO: If we made sure that attributes were stored in the
5283e4b17023SJohn Marino 	 canonical form without '__...__' (ie, as in 'text' as opposed
5284e4b17023SJohn Marino 	 to '__text__') then we could avoid the following case.  */
5285e4b17023SJohn Marino       else if (ident_len == attr_len + 4)
5286e4b17023SJohn Marino 	{
5287e4b17023SJohn Marino 	  const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
5288e4b17023SJohn Marino 	  if (p[0] == '_' && p[1] == '_'
5289e4b17023SJohn Marino 	      && p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
5290e4b17023SJohn Marino 	      && strncmp (attr_name, p + 2, attr_len) == 0)
5291e4b17023SJohn Marino 	    break;
5292e4b17023SJohn Marino 	}
5293e4b17023SJohn Marino       list = TREE_CHAIN (list);
5294e4b17023SJohn Marino     }
5295e4b17023SJohn Marino 
5296e4b17023SJohn Marino   return list;
5297e4b17023SJohn Marino }
5298e4b17023SJohn Marino 
5299e4b17023SJohn Marino /* A variant of lookup_attribute() that can be used with an identifier
5300e4b17023SJohn Marino    as the first argument, and where the identifier can be either
5301e4b17023SJohn Marino    'text' or '__text__'.
5302e4b17023SJohn Marino 
5303e4b17023SJohn Marino    Given an attribute ATTR_IDENTIFIER, and a list of attributes LIST,
5304e4b17023SJohn Marino    return a pointer to the attribute's list element if the attribute
5305e4b17023SJohn Marino    is part of the list, or NULL_TREE if not found.  If the attribute
5306e4b17023SJohn Marino    appears more than once, this only returns the first occurrence; the
5307e4b17023SJohn Marino    TREE_CHAIN of the return value should be passed back in if further
5308e4b17023SJohn Marino    occurrences are wanted.  ATTR_IDENTIFIER must be an identifier but
5309e4b17023SJohn Marino    can be in the form 'text' or '__text__'.  */
5310e4b17023SJohn Marino static tree
lookup_ident_attribute(tree attr_identifier,tree list)5311e4b17023SJohn Marino lookup_ident_attribute (tree attr_identifier, tree list)
5312e4b17023SJohn Marino {
5313e4b17023SJohn Marino   gcc_checking_assert (TREE_CODE (attr_identifier) == IDENTIFIER_NODE);
5314e4b17023SJohn Marino 
5315e4b17023SJohn Marino   while (list)
5316e4b17023SJohn Marino     {
5317e4b17023SJohn Marino       gcc_checking_assert (TREE_CODE (TREE_PURPOSE (list)) == IDENTIFIER_NODE);
5318e4b17023SJohn Marino 
5319e4b17023SJohn Marino       /* Identifiers can be compared directly for equality.  */
5320e4b17023SJohn Marino       if (attr_identifier == TREE_PURPOSE (list))
5321e4b17023SJohn Marino 	break;
5322e4b17023SJohn Marino 
5323e4b17023SJohn Marino       /* If they are not equal, they may still be one in the form
5324e4b17023SJohn Marino 	 'text' while the other one is in the form '__text__'.  TODO:
5325e4b17023SJohn Marino 	 If we were storing attributes in normalized 'text' form, then
5326e4b17023SJohn Marino 	 this could all go away and we could take full advantage of
5327e4b17023SJohn Marino 	 the fact that we're comparing identifiers. :-)  */
5328e4b17023SJohn Marino       {
5329e4b17023SJohn Marino 	size_t attr_len = IDENTIFIER_LENGTH (attr_identifier);
5330e4b17023SJohn Marino 	size_t ident_len = IDENTIFIER_LENGTH (TREE_PURPOSE (list));
5331e4b17023SJohn Marino 
5332e4b17023SJohn Marino 	if (ident_len == attr_len + 4)
5333e4b17023SJohn Marino 	  {
5334e4b17023SJohn Marino 	    const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
5335e4b17023SJohn Marino 	    const char *q = IDENTIFIER_POINTER (attr_identifier);
5336e4b17023SJohn Marino 	    if (p[0] == '_' && p[1] == '_'
5337e4b17023SJohn Marino 		&& p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
5338e4b17023SJohn Marino 		&& strncmp (q, p + 2, attr_len) == 0)
5339e4b17023SJohn Marino 	      break;
5340e4b17023SJohn Marino 	  }
5341e4b17023SJohn Marino 	else if (ident_len + 4 == attr_len)
5342e4b17023SJohn Marino 	  {
5343e4b17023SJohn Marino 	    const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
5344e4b17023SJohn Marino 	    const char *q = IDENTIFIER_POINTER (attr_identifier);
5345e4b17023SJohn Marino 	    if (q[0] == '_' && q[1] == '_'
5346e4b17023SJohn Marino 		&& q[attr_len - 2] == '_' && q[attr_len - 1] == '_'
5347e4b17023SJohn Marino 		&& strncmp (q + 2, p, ident_len) == 0)
5348e4b17023SJohn Marino 	      break;
5349e4b17023SJohn Marino 	  }
5350e4b17023SJohn Marino       }
5351e4b17023SJohn Marino       list = TREE_CHAIN (list);
5352e4b17023SJohn Marino     }
5353e4b17023SJohn Marino 
5354e4b17023SJohn Marino   return list;
5355e4b17023SJohn Marino }
5356e4b17023SJohn Marino 
5357e4b17023SJohn Marino /* Remove any instances of attribute ATTR_NAME in LIST and return the
5358e4b17023SJohn Marino    modified list.  */
5359e4b17023SJohn Marino 
5360e4b17023SJohn Marino tree
remove_attribute(const char * attr_name,tree list)5361e4b17023SJohn Marino remove_attribute (const char *attr_name, tree list)
5362e4b17023SJohn Marino {
5363e4b17023SJohn Marino   tree *p;
5364e4b17023SJohn Marino   size_t attr_len = strlen (attr_name);
5365e4b17023SJohn Marino 
5366e4b17023SJohn Marino   gcc_checking_assert (attr_name[0] != '_');
5367e4b17023SJohn Marino 
5368e4b17023SJohn Marino   for (p = &list; *p; )
5369e4b17023SJohn Marino     {
5370e4b17023SJohn Marino       tree l = *p;
5371e4b17023SJohn Marino       /* TODO: If we were storing attributes in normalized form, here
5372e4b17023SJohn Marino 	 we could use a simple strcmp().  */
5373e4b17023SJohn Marino       if (private_is_attribute_p (attr_name, attr_len, TREE_PURPOSE (l)))
5374e4b17023SJohn Marino 	*p = TREE_CHAIN (l);
5375e4b17023SJohn Marino       else
5376e4b17023SJohn Marino 	p = &TREE_CHAIN (l);
5377e4b17023SJohn Marino     }
5378e4b17023SJohn Marino 
5379e4b17023SJohn Marino   return list;
5380e4b17023SJohn Marino }
5381e4b17023SJohn Marino 
5382e4b17023SJohn Marino /* Return an attribute list that is the union of a1 and a2.  */
5383e4b17023SJohn Marino 
5384e4b17023SJohn Marino tree
merge_attributes(tree a1,tree a2)5385e4b17023SJohn Marino merge_attributes (tree a1, tree a2)
5386e4b17023SJohn Marino {
5387e4b17023SJohn Marino   tree attributes;
5388e4b17023SJohn Marino 
5389e4b17023SJohn Marino   /* Either one unset?  Take the set one.  */
5390e4b17023SJohn Marino 
5391e4b17023SJohn Marino   if ((attributes = a1) == 0)
5392e4b17023SJohn Marino     attributes = a2;
5393e4b17023SJohn Marino 
5394e4b17023SJohn Marino   /* One that completely contains the other?  Take it.  */
5395e4b17023SJohn Marino 
5396e4b17023SJohn Marino   else if (a2 != 0 && ! attribute_list_contained (a1, a2))
5397e4b17023SJohn Marino     {
5398e4b17023SJohn Marino       if (attribute_list_contained (a2, a1))
5399e4b17023SJohn Marino 	attributes = a2;
5400e4b17023SJohn Marino       else
5401e4b17023SJohn Marino 	{
5402e4b17023SJohn Marino 	  /* Pick the longest list, and hang on the other list.  */
5403e4b17023SJohn Marino 
5404e4b17023SJohn Marino 	  if (list_length (a1) < list_length (a2))
5405e4b17023SJohn Marino 	    attributes = a2, a2 = a1;
5406e4b17023SJohn Marino 
5407e4b17023SJohn Marino 	  for (; a2 != 0; a2 = TREE_CHAIN (a2))
5408e4b17023SJohn Marino 	    {
5409e4b17023SJohn Marino 	      tree a;
5410e4b17023SJohn Marino 	      for (a = lookup_ident_attribute (TREE_PURPOSE (a2), attributes);
5411e4b17023SJohn Marino 		   a != NULL_TREE && !attribute_value_equal (a, a2);
5412e4b17023SJohn Marino 		   a = lookup_ident_attribute (TREE_PURPOSE (a2), TREE_CHAIN (a)))
5413e4b17023SJohn Marino 		;
5414e4b17023SJohn Marino 	      if (a == NULL_TREE)
5415e4b17023SJohn Marino 		{
5416e4b17023SJohn Marino 		  a1 = copy_node (a2);
5417e4b17023SJohn Marino 		  TREE_CHAIN (a1) = attributes;
5418e4b17023SJohn Marino 		  attributes = a1;
5419e4b17023SJohn Marino 		}
5420e4b17023SJohn Marino 	    }
5421e4b17023SJohn Marino 	}
5422e4b17023SJohn Marino     }
5423e4b17023SJohn Marino   return attributes;
5424e4b17023SJohn Marino }
5425e4b17023SJohn Marino 
5426e4b17023SJohn Marino /* Given types T1 and T2, merge their attributes and return
5427e4b17023SJohn Marino   the result.  */
5428e4b17023SJohn Marino 
5429e4b17023SJohn Marino tree
merge_type_attributes(tree t1,tree t2)5430e4b17023SJohn Marino merge_type_attributes (tree t1, tree t2)
5431e4b17023SJohn Marino {
5432e4b17023SJohn Marino   return merge_attributes (TYPE_ATTRIBUTES (t1),
5433e4b17023SJohn Marino 			   TYPE_ATTRIBUTES (t2));
5434e4b17023SJohn Marino }
5435e4b17023SJohn Marino 
5436e4b17023SJohn Marino /* Given decls OLDDECL and NEWDECL, merge their attributes and return
5437e4b17023SJohn Marino    the result.  */
5438e4b17023SJohn Marino 
5439e4b17023SJohn Marino tree
merge_decl_attributes(tree olddecl,tree newdecl)5440e4b17023SJohn Marino merge_decl_attributes (tree olddecl, tree newdecl)
5441e4b17023SJohn Marino {
5442e4b17023SJohn Marino   return merge_attributes (DECL_ATTRIBUTES (olddecl),
5443e4b17023SJohn Marino 			   DECL_ATTRIBUTES (newdecl));
5444e4b17023SJohn Marino }
5445e4b17023SJohn Marino 
5446e4b17023SJohn Marino #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
5447e4b17023SJohn Marino 
5448e4b17023SJohn Marino /* Specialization of merge_decl_attributes for various Windows targets.
5449e4b17023SJohn Marino 
5450e4b17023SJohn Marino    This handles the following situation:
5451e4b17023SJohn Marino 
5452e4b17023SJohn Marino      __declspec (dllimport) int foo;
5453e4b17023SJohn Marino      int foo;
5454e4b17023SJohn Marino 
5455e4b17023SJohn Marino    The second instance of `foo' nullifies the dllimport.  */
5456e4b17023SJohn Marino 
5457e4b17023SJohn Marino tree
merge_dllimport_decl_attributes(tree old,tree new_tree)5458e4b17023SJohn Marino merge_dllimport_decl_attributes (tree old, tree new_tree)
5459e4b17023SJohn Marino {
5460e4b17023SJohn Marino   tree a;
5461e4b17023SJohn Marino   int delete_dllimport_p = 1;
5462e4b17023SJohn Marino 
5463e4b17023SJohn Marino   /* What we need to do here is remove from `old' dllimport if it doesn't
5464e4b17023SJohn Marino      appear in `new'.  dllimport behaves like extern: if a declaration is
5465e4b17023SJohn Marino      marked dllimport and a definition appears later, then the object
5466e4b17023SJohn Marino      is not dllimport'd.  We also remove a `new' dllimport if the old list
5467e4b17023SJohn Marino      contains dllexport:  dllexport always overrides dllimport, regardless
5468e4b17023SJohn Marino      of the order of declaration.  */
5469e4b17023SJohn Marino   if (!VAR_OR_FUNCTION_DECL_P (new_tree))
5470e4b17023SJohn Marino     delete_dllimport_p = 0;
5471e4b17023SJohn Marino   else if (DECL_DLLIMPORT_P (new_tree)
5472e4b17023SJohn Marino      	   && lookup_attribute ("dllexport", DECL_ATTRIBUTES (old)))
5473e4b17023SJohn Marino     {
5474e4b17023SJohn Marino       DECL_DLLIMPORT_P (new_tree) = 0;
5475e4b17023SJohn Marino       warning (OPT_Wattributes, "%q+D already declared with dllexport attribute: "
5476e4b17023SJohn Marino 	      "dllimport ignored", new_tree);
5477e4b17023SJohn Marino     }
5478e4b17023SJohn Marino   else if (DECL_DLLIMPORT_P (old) && !DECL_DLLIMPORT_P (new_tree))
5479e4b17023SJohn Marino     {
5480e4b17023SJohn Marino       /* Warn about overriding a symbol that has already been used, e.g.:
5481e4b17023SJohn Marino            extern int __attribute__ ((dllimport)) foo;
5482e4b17023SJohn Marino 	   int* bar () {return &foo;}
5483e4b17023SJohn Marino 	   int foo;
5484e4b17023SJohn Marino       */
5485e4b17023SJohn Marino       if (TREE_USED (old))
5486e4b17023SJohn Marino 	{
5487e4b17023SJohn Marino 	  warning (0, "%q+D redeclared without dllimport attribute "
5488e4b17023SJohn Marino 		   "after being referenced with dll linkage", new_tree);
5489e4b17023SJohn Marino 	  /* If we have used a variable's address with dllimport linkage,
5490e4b17023SJohn Marino 	      keep the old DECL_DLLIMPORT_P flag: the ADDR_EXPR using the
5491e4b17023SJohn Marino 	      decl may already have had TREE_CONSTANT computed.
5492e4b17023SJohn Marino 	      We still remove the attribute so that assembler code refers
5493e4b17023SJohn Marino 	      to '&foo rather than '_imp__foo'.  */
5494e4b17023SJohn Marino 	  if (TREE_CODE (old) == VAR_DECL && TREE_ADDRESSABLE (old))
5495e4b17023SJohn Marino 	    DECL_DLLIMPORT_P (new_tree) = 1;
5496e4b17023SJohn Marino 	}
5497e4b17023SJohn Marino 
5498e4b17023SJohn Marino       /* Let an inline definition silently override the external reference,
5499e4b17023SJohn Marino 	 but otherwise warn about attribute inconsistency.  */
5500e4b17023SJohn Marino       else if (TREE_CODE (new_tree) == VAR_DECL
5501e4b17023SJohn Marino 	       || !DECL_DECLARED_INLINE_P (new_tree))
5502e4b17023SJohn Marino 	warning (OPT_Wattributes, "%q+D redeclared without dllimport attribute: "
5503e4b17023SJohn Marino 		  "previous dllimport ignored", new_tree);
5504e4b17023SJohn Marino     }
5505e4b17023SJohn Marino   else
5506e4b17023SJohn Marino     delete_dllimport_p = 0;
5507e4b17023SJohn Marino 
5508e4b17023SJohn Marino   a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new_tree));
5509e4b17023SJohn Marino 
5510e4b17023SJohn Marino   if (delete_dllimport_p)
5511e4b17023SJohn Marino     a = remove_attribute ("dllimport", a);
5512e4b17023SJohn Marino 
5513e4b17023SJohn Marino   return a;
5514e4b17023SJohn Marino }
5515e4b17023SJohn Marino 
5516e4b17023SJohn Marino /* Handle a "dllimport" or "dllexport" attribute; arguments as in
5517e4b17023SJohn Marino    struct attribute_spec.handler.  */
5518e4b17023SJohn Marino 
5519e4b17023SJohn Marino tree
handle_dll_attribute(tree * pnode,tree name,tree args,int flags,bool * no_add_attrs)5520e4b17023SJohn Marino handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
5521e4b17023SJohn Marino 		      bool *no_add_attrs)
5522e4b17023SJohn Marino {
5523e4b17023SJohn Marino   tree node = *pnode;
5524e4b17023SJohn Marino   bool is_dllimport;
5525e4b17023SJohn Marino 
5526e4b17023SJohn Marino   /* These attributes may apply to structure and union types being created,
5527e4b17023SJohn Marino      but otherwise should pass to the declaration involved.  */
5528e4b17023SJohn Marino   if (!DECL_P (node))
5529e4b17023SJohn Marino     {
5530e4b17023SJohn Marino       if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
5531e4b17023SJohn Marino 		   | (int) ATTR_FLAG_ARRAY_NEXT))
5532e4b17023SJohn Marino 	{
5533e4b17023SJohn Marino 	  *no_add_attrs = true;
5534e4b17023SJohn Marino 	  return tree_cons (name, args, NULL_TREE);
5535e4b17023SJohn Marino 	}
5536e4b17023SJohn Marino       if (TREE_CODE (node) == RECORD_TYPE
5537e4b17023SJohn Marino 	  || TREE_CODE (node) == UNION_TYPE)
5538e4b17023SJohn Marino 	{
5539e4b17023SJohn Marino 	  node = TYPE_NAME (node);
5540e4b17023SJohn Marino 	  if (!node)
5541e4b17023SJohn Marino 	    return NULL_TREE;
5542e4b17023SJohn Marino 	}
5543e4b17023SJohn Marino       else
5544e4b17023SJohn Marino 	{
5545e4b17023SJohn Marino 	  warning (OPT_Wattributes, "%qE attribute ignored",
5546e4b17023SJohn Marino 		   name);
5547e4b17023SJohn Marino 	  *no_add_attrs = true;
5548e4b17023SJohn Marino 	  return NULL_TREE;
5549e4b17023SJohn Marino 	}
5550e4b17023SJohn Marino     }
5551e4b17023SJohn Marino 
5552e4b17023SJohn Marino   if (TREE_CODE (node) != FUNCTION_DECL
5553e4b17023SJohn Marino       && TREE_CODE (node) != VAR_DECL
5554e4b17023SJohn Marino       && TREE_CODE (node) != TYPE_DECL)
5555e4b17023SJohn Marino     {
5556e4b17023SJohn Marino       *no_add_attrs = true;
5557e4b17023SJohn Marino       warning (OPT_Wattributes, "%qE attribute ignored",
5558e4b17023SJohn Marino 	       name);
5559e4b17023SJohn Marino       return NULL_TREE;
5560e4b17023SJohn Marino     }
5561e4b17023SJohn Marino 
5562e4b17023SJohn Marino   if (TREE_CODE (node) == TYPE_DECL
5563e4b17023SJohn Marino       && TREE_CODE (TREE_TYPE (node)) != RECORD_TYPE
5564e4b17023SJohn Marino       && TREE_CODE (TREE_TYPE (node)) != UNION_TYPE)
5565e4b17023SJohn Marino     {
5566e4b17023SJohn Marino       *no_add_attrs = true;
5567e4b17023SJohn Marino       warning (OPT_Wattributes, "%qE attribute ignored",
5568e4b17023SJohn Marino 	       name);
5569e4b17023SJohn Marino       return NULL_TREE;
5570e4b17023SJohn Marino     }
5571e4b17023SJohn Marino 
5572e4b17023SJohn Marino   is_dllimport = is_attribute_p ("dllimport", name);
5573e4b17023SJohn Marino 
5574e4b17023SJohn Marino   /* Report error on dllimport ambiguities seen now before they cause
5575e4b17023SJohn Marino      any damage.  */
5576e4b17023SJohn Marino   if (is_dllimport)
5577e4b17023SJohn Marino     {
5578e4b17023SJohn Marino       /* Honor any target-specific overrides. */
5579e4b17023SJohn Marino       if (!targetm.valid_dllimport_attribute_p (node))
5580e4b17023SJohn Marino 	*no_add_attrs = true;
5581e4b17023SJohn Marino 
5582e4b17023SJohn Marino      else if (TREE_CODE (node) == FUNCTION_DECL
5583e4b17023SJohn Marino 	        && DECL_DECLARED_INLINE_P (node))
5584e4b17023SJohn Marino 	{
5585e4b17023SJohn Marino 	  warning (OPT_Wattributes, "inline function %q+D declared as "
5586e4b17023SJohn Marino 		  " dllimport: attribute ignored", node);
5587e4b17023SJohn Marino 	  *no_add_attrs = true;
5588e4b17023SJohn Marino 	}
5589e4b17023SJohn Marino       /* Like MS, treat definition of dllimported variables and
5590e4b17023SJohn Marino 	 non-inlined functions on declaration as syntax errors. */
5591e4b17023SJohn Marino      else if (TREE_CODE (node) == FUNCTION_DECL && DECL_INITIAL (node))
5592e4b17023SJohn Marino 	{
5593e4b17023SJohn Marino 	  error ("function %q+D definition is marked dllimport", node);
5594e4b17023SJohn Marino 	  *no_add_attrs = true;
5595e4b17023SJohn Marino 	}
5596e4b17023SJohn Marino 
5597e4b17023SJohn Marino      else if (TREE_CODE (node) == VAR_DECL)
5598e4b17023SJohn Marino 	{
5599e4b17023SJohn Marino 	  if (DECL_INITIAL (node))
5600e4b17023SJohn Marino 	    {
5601e4b17023SJohn Marino 	      error ("variable %q+D definition is marked dllimport",
5602e4b17023SJohn Marino 		     node);
5603e4b17023SJohn Marino 	      *no_add_attrs = true;
5604e4b17023SJohn Marino 	    }
5605e4b17023SJohn Marino 
5606e4b17023SJohn Marino 	  /* `extern' needn't be specified with dllimport.
5607e4b17023SJohn Marino 	     Specify `extern' now and hope for the best.  Sigh.  */
5608e4b17023SJohn Marino 	  DECL_EXTERNAL (node) = 1;
5609e4b17023SJohn Marino 	  /* Also, implicitly give dllimport'd variables declared within
5610e4b17023SJohn Marino 	     a function global scope, unless declared static.  */
5611e4b17023SJohn Marino 	  if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
5612e4b17023SJohn Marino 	    TREE_PUBLIC (node) = 1;
5613e4b17023SJohn Marino 	}
5614e4b17023SJohn Marino 
5615e4b17023SJohn Marino       if (*no_add_attrs == false)
5616e4b17023SJohn Marino         DECL_DLLIMPORT_P (node) = 1;
5617e4b17023SJohn Marino     }
5618e4b17023SJohn Marino   else if (TREE_CODE (node) == FUNCTION_DECL
5619e4b17023SJohn Marino 	   && DECL_DECLARED_INLINE_P (node)
5620e4b17023SJohn Marino 	   && flag_keep_inline_dllexport)
5621e4b17023SJohn Marino     /* An exported function, even if inline, must be emitted.  */
5622e4b17023SJohn Marino     DECL_EXTERNAL (node) = 0;
5623e4b17023SJohn Marino 
5624e4b17023SJohn Marino   /*  Report error if symbol is not accessible at global scope.  */
5625e4b17023SJohn Marino   if (!TREE_PUBLIC (node)
5626e4b17023SJohn Marino       && (TREE_CODE (node) == VAR_DECL
5627e4b17023SJohn Marino 	  || TREE_CODE (node) == FUNCTION_DECL))
5628e4b17023SJohn Marino     {
5629e4b17023SJohn Marino       error ("external linkage required for symbol %q+D because of "
5630e4b17023SJohn Marino 	     "%qE attribute", node, name);
5631e4b17023SJohn Marino       *no_add_attrs = true;
5632e4b17023SJohn Marino     }
5633e4b17023SJohn Marino 
5634e4b17023SJohn Marino   /* A dllexport'd entity must have default visibility so that other
5635e4b17023SJohn Marino      program units (shared libraries or the main executable) can see
5636e4b17023SJohn Marino      it.  A dllimport'd entity must have default visibility so that
5637e4b17023SJohn Marino      the linker knows that undefined references within this program
5638e4b17023SJohn Marino      unit can be resolved by the dynamic linker.  */
5639e4b17023SJohn Marino   if (!*no_add_attrs)
5640e4b17023SJohn Marino     {
5641e4b17023SJohn Marino       if (DECL_VISIBILITY_SPECIFIED (node)
5642e4b17023SJohn Marino 	  && DECL_VISIBILITY (node) != VISIBILITY_DEFAULT)
5643e4b17023SJohn Marino 	error ("%qE implies default visibility, but %qD has already "
5644e4b17023SJohn Marino 	       "been declared with a different visibility",
5645e4b17023SJohn Marino 	       name, node);
5646e4b17023SJohn Marino       DECL_VISIBILITY (node) = VISIBILITY_DEFAULT;
5647e4b17023SJohn Marino       DECL_VISIBILITY_SPECIFIED (node) = 1;
5648e4b17023SJohn Marino     }
5649e4b17023SJohn Marino 
5650e4b17023SJohn Marino   return NULL_TREE;
5651e4b17023SJohn Marino }
5652e4b17023SJohn Marino 
5653e4b17023SJohn Marino #endif /* TARGET_DLLIMPORT_DECL_ATTRIBUTES  */
5654e4b17023SJohn Marino 
5655e4b17023SJohn Marino /* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask
5656e4b17023SJohn Marino    of the various TYPE_QUAL values.  */
5657e4b17023SJohn Marino 
5658e4b17023SJohn Marino static void
set_type_quals(tree type,int type_quals)5659e4b17023SJohn Marino set_type_quals (tree type, int type_quals)
5660e4b17023SJohn Marino {
5661e4b17023SJohn Marino   TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0;
5662e4b17023SJohn Marino   TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
5663e4b17023SJohn Marino   TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
5664e4b17023SJohn Marino   TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals);
5665e4b17023SJohn Marino }
5666e4b17023SJohn Marino 
5667e4b17023SJohn Marino /* Returns true iff CAND is equivalent to BASE with TYPE_QUALS.  */
5668e4b17023SJohn Marino 
5669e4b17023SJohn Marino bool
check_qualified_type(const_tree cand,const_tree base,int type_quals)5670e4b17023SJohn Marino check_qualified_type (const_tree cand, const_tree base, int type_quals)
5671e4b17023SJohn Marino {
5672e4b17023SJohn Marino   return (TYPE_QUALS (cand) == type_quals
5673e4b17023SJohn Marino 	  && TYPE_NAME (cand) == TYPE_NAME (base)
5674e4b17023SJohn Marino 	  /* Apparently this is needed for Objective-C.  */
5675e4b17023SJohn Marino 	  && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base)
5676e4b17023SJohn Marino 	  /* Check alignment.  */
5677e4b17023SJohn Marino 	  && TYPE_ALIGN (cand) == TYPE_ALIGN (base)
5678e4b17023SJohn Marino 	  && attribute_list_equal (TYPE_ATTRIBUTES (cand),
5679e4b17023SJohn Marino 				   TYPE_ATTRIBUTES (base)));
5680e4b17023SJohn Marino }
5681e4b17023SJohn Marino 
5682e4b17023SJohn Marino /* Returns true iff CAND is equivalent to BASE with ALIGN.  */
5683e4b17023SJohn Marino 
5684e4b17023SJohn Marino static bool
check_aligned_type(const_tree cand,const_tree base,unsigned int align)5685e4b17023SJohn Marino check_aligned_type (const_tree cand, const_tree base, unsigned int align)
5686e4b17023SJohn Marino {
5687e4b17023SJohn Marino   return (TYPE_QUALS (cand) == TYPE_QUALS (base)
5688e4b17023SJohn Marino 	  && TYPE_NAME (cand) == TYPE_NAME (base)
5689e4b17023SJohn Marino 	  /* Apparently this is needed for Objective-C.  */
5690e4b17023SJohn Marino 	  && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base)
5691e4b17023SJohn Marino 	  /* Check alignment.  */
5692e4b17023SJohn Marino 	  && TYPE_ALIGN (cand) == align
5693e4b17023SJohn Marino 	  && attribute_list_equal (TYPE_ATTRIBUTES (cand),
5694e4b17023SJohn Marino 				   TYPE_ATTRIBUTES (base)));
5695e4b17023SJohn Marino }
5696e4b17023SJohn Marino 
5697e4b17023SJohn Marino /* Return a version of the TYPE, qualified as indicated by the
5698e4b17023SJohn Marino    TYPE_QUALS, if one exists.  If no qualified version exists yet,
5699e4b17023SJohn Marino    return NULL_TREE.  */
5700e4b17023SJohn Marino 
5701e4b17023SJohn Marino tree
get_qualified_type(tree type,int type_quals)5702e4b17023SJohn Marino get_qualified_type (tree type, int type_quals)
5703e4b17023SJohn Marino {
5704e4b17023SJohn Marino   tree t;
5705e4b17023SJohn Marino 
5706e4b17023SJohn Marino   if (TYPE_QUALS (type) == type_quals)
5707e4b17023SJohn Marino     return type;
5708e4b17023SJohn Marino 
5709e4b17023SJohn Marino   /* Search the chain of variants to see if there is already one there just
5710e4b17023SJohn Marino      like the one we need to have.  If so, use that existing one.  We must
5711e4b17023SJohn Marino      preserve the TYPE_NAME, since there is code that depends on this.  */
5712e4b17023SJohn Marino   for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
5713e4b17023SJohn Marino     if (check_qualified_type (t, type, type_quals))
5714e4b17023SJohn Marino       return t;
5715e4b17023SJohn Marino 
5716e4b17023SJohn Marino   return NULL_TREE;
5717e4b17023SJohn Marino }
5718e4b17023SJohn Marino 
5719e4b17023SJohn Marino /* Like get_qualified_type, but creates the type if it does not
5720e4b17023SJohn Marino    exist.  This function never returns NULL_TREE.  */
5721e4b17023SJohn Marino 
5722e4b17023SJohn Marino tree
build_qualified_type(tree type,int type_quals)5723e4b17023SJohn Marino build_qualified_type (tree type, int type_quals)
5724e4b17023SJohn Marino {
5725e4b17023SJohn Marino   tree t;
5726e4b17023SJohn Marino 
5727e4b17023SJohn Marino   /* See if we already have the appropriate qualified variant.  */
5728e4b17023SJohn Marino   t = get_qualified_type (type, type_quals);
5729e4b17023SJohn Marino 
5730e4b17023SJohn Marino   /* If not, build it.  */
5731e4b17023SJohn Marino   if (!t)
5732e4b17023SJohn Marino     {
5733e4b17023SJohn Marino       t = build_variant_type_copy (type);
5734e4b17023SJohn Marino       set_type_quals (t, type_quals);
5735e4b17023SJohn Marino 
5736e4b17023SJohn Marino       if (TYPE_STRUCTURAL_EQUALITY_P (type))
5737e4b17023SJohn Marino 	/* Propagate structural equality. */
5738e4b17023SJohn Marino 	SET_TYPE_STRUCTURAL_EQUALITY (t);
5739e4b17023SJohn Marino       else if (TYPE_CANONICAL (type) != type)
5740e4b17023SJohn Marino 	/* Build the underlying canonical type, since it is different
5741e4b17023SJohn Marino 	   from TYPE. */
5742e4b17023SJohn Marino 	TYPE_CANONICAL (t) = build_qualified_type (TYPE_CANONICAL (type),
5743e4b17023SJohn Marino 						   type_quals);
5744e4b17023SJohn Marino       else
5745e4b17023SJohn Marino 	/* T is its own canonical type. */
5746e4b17023SJohn Marino 	TYPE_CANONICAL (t) = t;
5747e4b17023SJohn Marino 
5748e4b17023SJohn Marino     }
5749e4b17023SJohn Marino 
5750e4b17023SJohn Marino   return t;
5751e4b17023SJohn Marino }
5752e4b17023SJohn Marino 
5753e4b17023SJohn Marino /* Create a variant of type T with alignment ALIGN.  */
5754e4b17023SJohn Marino 
5755e4b17023SJohn Marino tree
build_aligned_type(tree type,unsigned int align)5756e4b17023SJohn Marino build_aligned_type (tree type, unsigned int align)
5757e4b17023SJohn Marino {
5758e4b17023SJohn Marino   tree t;
5759e4b17023SJohn Marino 
5760e4b17023SJohn Marino   if (TYPE_PACKED (type)
5761e4b17023SJohn Marino       || TYPE_ALIGN (type) == align)
5762e4b17023SJohn Marino     return type;
5763e4b17023SJohn Marino 
5764e4b17023SJohn Marino   for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
5765e4b17023SJohn Marino     if (check_aligned_type (t, type, align))
5766e4b17023SJohn Marino       return t;
5767e4b17023SJohn Marino 
5768e4b17023SJohn Marino   t = build_variant_type_copy (type);
5769e4b17023SJohn Marino   TYPE_ALIGN (t) = align;
5770e4b17023SJohn Marino 
5771e4b17023SJohn Marino   return t;
5772e4b17023SJohn Marino }
5773e4b17023SJohn Marino 
5774e4b17023SJohn Marino /* Create a new distinct copy of TYPE.  The new type is made its own
5775e4b17023SJohn Marino    MAIN_VARIANT. If TYPE requires structural equality checks, the
5776e4b17023SJohn Marino    resulting type requires structural equality checks; otherwise, its
5777e4b17023SJohn Marino    TYPE_CANONICAL points to itself. */
5778e4b17023SJohn Marino 
5779e4b17023SJohn Marino tree
build_distinct_type_copy(tree type)5780e4b17023SJohn Marino build_distinct_type_copy (tree type)
5781e4b17023SJohn Marino {
5782e4b17023SJohn Marino   tree t = copy_node (type);
5783e4b17023SJohn Marino 
5784e4b17023SJohn Marino   TYPE_POINTER_TO (t) = 0;
5785e4b17023SJohn Marino   TYPE_REFERENCE_TO (t) = 0;
5786e4b17023SJohn Marino 
5787e4b17023SJohn Marino   /* Set the canonical type either to a new equivalence class, or
5788e4b17023SJohn Marino      propagate the need for structural equality checks. */
5789e4b17023SJohn Marino   if (TYPE_STRUCTURAL_EQUALITY_P (type))
5790e4b17023SJohn Marino     SET_TYPE_STRUCTURAL_EQUALITY (t);
5791e4b17023SJohn Marino   else
5792e4b17023SJohn Marino     TYPE_CANONICAL (t) = t;
5793e4b17023SJohn Marino 
5794e4b17023SJohn Marino   /* Make it its own variant.  */
5795e4b17023SJohn Marino   TYPE_MAIN_VARIANT (t) = t;
5796e4b17023SJohn Marino   TYPE_NEXT_VARIANT (t) = 0;
5797e4b17023SJohn Marino 
5798e4b17023SJohn Marino   /* Note that it is now possible for TYPE_MIN_VALUE to be a value
5799e4b17023SJohn Marino      whose TREE_TYPE is not t.  This can also happen in the Ada
5800e4b17023SJohn Marino      frontend when using subtypes.  */
5801e4b17023SJohn Marino 
5802e4b17023SJohn Marino   return t;
5803e4b17023SJohn Marino }
5804e4b17023SJohn Marino 
5805e4b17023SJohn Marino /* Create a new variant of TYPE, equivalent but distinct.  This is so
5806e4b17023SJohn Marino    the caller can modify it. TYPE_CANONICAL for the return type will
5807e4b17023SJohn Marino    be equivalent to TYPE_CANONICAL of TYPE, indicating that the types
5808e4b17023SJohn Marino    are considered equal by the language itself (or that both types
5809e4b17023SJohn Marino    require structural equality checks). */
5810e4b17023SJohn Marino 
5811e4b17023SJohn Marino tree
build_variant_type_copy(tree type)5812e4b17023SJohn Marino build_variant_type_copy (tree type)
5813e4b17023SJohn Marino {
5814e4b17023SJohn Marino   tree t, m = TYPE_MAIN_VARIANT (type);
5815e4b17023SJohn Marino 
5816e4b17023SJohn Marino   t = build_distinct_type_copy (type);
5817e4b17023SJohn Marino 
5818e4b17023SJohn Marino   /* Since we're building a variant, assume that it is a non-semantic
5819e4b17023SJohn Marino      variant. This also propagates TYPE_STRUCTURAL_EQUALITY_P. */
5820e4b17023SJohn Marino   TYPE_CANONICAL (t) = TYPE_CANONICAL (type);
5821e4b17023SJohn Marino 
5822e4b17023SJohn Marino   /* Add the new type to the chain of variants of TYPE.  */
5823e4b17023SJohn Marino   TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
5824e4b17023SJohn Marino   TYPE_NEXT_VARIANT (m) = t;
5825e4b17023SJohn Marino   TYPE_MAIN_VARIANT (t) = m;
5826e4b17023SJohn Marino 
5827e4b17023SJohn Marino   return t;
5828e4b17023SJohn Marino }
5829e4b17023SJohn Marino 
5830e4b17023SJohn Marino /* Return true if the from tree in both tree maps are equal.  */
5831e4b17023SJohn Marino 
5832e4b17023SJohn Marino int
tree_map_base_eq(const void * va,const void * vb)5833e4b17023SJohn Marino tree_map_base_eq (const void *va, const void *vb)
5834e4b17023SJohn Marino {
5835e4b17023SJohn Marino   const struct tree_map_base  *const a = (const struct tree_map_base *) va,
5836e4b17023SJohn Marino     *const b = (const struct tree_map_base *) vb;
5837e4b17023SJohn Marino   return (a->from == b->from);
5838e4b17023SJohn Marino }
5839e4b17023SJohn Marino 
5840e4b17023SJohn Marino /* Hash a from tree in a tree_base_map.  */
5841e4b17023SJohn Marino 
5842e4b17023SJohn Marino unsigned int
tree_map_base_hash(const void * item)5843e4b17023SJohn Marino tree_map_base_hash (const void *item)
5844e4b17023SJohn Marino {
5845e4b17023SJohn Marino   return htab_hash_pointer (((const struct tree_map_base *)item)->from);
5846e4b17023SJohn Marino }
5847e4b17023SJohn Marino 
5848e4b17023SJohn Marino /* Return true if this tree map structure is marked for garbage collection
5849e4b17023SJohn Marino    purposes.  We simply return true if the from tree is marked, so that this
5850e4b17023SJohn Marino    structure goes away when the from tree goes away.  */
5851e4b17023SJohn Marino 
5852e4b17023SJohn Marino int
tree_map_base_marked_p(const void * p)5853e4b17023SJohn Marino tree_map_base_marked_p (const void *p)
5854e4b17023SJohn Marino {
5855e4b17023SJohn Marino   return ggc_marked_p (((const struct tree_map_base *) p)->from);
5856e4b17023SJohn Marino }
5857e4b17023SJohn Marino 
5858e4b17023SJohn Marino /* Hash a from tree in a tree_map.  */
5859e4b17023SJohn Marino 
5860e4b17023SJohn Marino unsigned int
tree_map_hash(const void * item)5861e4b17023SJohn Marino tree_map_hash (const void *item)
5862e4b17023SJohn Marino {
5863e4b17023SJohn Marino   return (((const struct tree_map *) item)->hash);
5864e4b17023SJohn Marino }
5865e4b17023SJohn Marino 
5866e4b17023SJohn Marino /* Hash a from tree in a tree_decl_map.  */
5867e4b17023SJohn Marino 
5868e4b17023SJohn Marino unsigned int
tree_decl_map_hash(const void * item)5869e4b17023SJohn Marino tree_decl_map_hash (const void *item)
5870e4b17023SJohn Marino {
5871e4b17023SJohn Marino   return DECL_UID (((const struct tree_decl_map *) item)->base.from);
5872e4b17023SJohn Marino }
5873e4b17023SJohn Marino 
5874e4b17023SJohn Marino /* Return the initialization priority for DECL.  */
5875e4b17023SJohn Marino 
5876e4b17023SJohn Marino priority_type
decl_init_priority_lookup(tree decl)5877e4b17023SJohn Marino decl_init_priority_lookup (tree decl)
5878e4b17023SJohn Marino {
5879e4b17023SJohn Marino   struct tree_priority_map *h;
5880e4b17023SJohn Marino   struct tree_map_base in;
5881e4b17023SJohn Marino 
5882e4b17023SJohn Marino   gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
5883e4b17023SJohn Marino   in.from = decl;
5884e4b17023SJohn Marino   h = (struct tree_priority_map *) htab_find (init_priority_for_decl, &in);
5885e4b17023SJohn Marino   return h ? h->init : DEFAULT_INIT_PRIORITY;
5886e4b17023SJohn Marino }
5887e4b17023SJohn Marino 
5888e4b17023SJohn Marino /* Return the finalization priority for DECL.  */
5889e4b17023SJohn Marino 
5890e4b17023SJohn Marino priority_type
decl_fini_priority_lookup(tree decl)5891e4b17023SJohn Marino decl_fini_priority_lookup (tree decl)
5892e4b17023SJohn Marino {
5893e4b17023SJohn Marino   struct tree_priority_map *h;
5894e4b17023SJohn Marino   struct tree_map_base in;
5895e4b17023SJohn Marino 
5896e4b17023SJohn Marino   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
5897e4b17023SJohn Marino   in.from = decl;
5898e4b17023SJohn Marino   h = (struct tree_priority_map *) htab_find (init_priority_for_decl, &in);
5899e4b17023SJohn Marino   return h ? h->fini : DEFAULT_INIT_PRIORITY;
5900e4b17023SJohn Marino }
5901e4b17023SJohn Marino 
5902e4b17023SJohn Marino /* Return the initialization and finalization priority information for
5903e4b17023SJohn Marino    DECL.  If there is no previous priority information, a freshly
5904e4b17023SJohn Marino    allocated structure is returned.  */
5905e4b17023SJohn Marino 
5906e4b17023SJohn Marino static struct tree_priority_map *
decl_priority_info(tree decl)5907e4b17023SJohn Marino decl_priority_info (tree decl)
5908e4b17023SJohn Marino {
5909e4b17023SJohn Marino   struct tree_priority_map in;
5910e4b17023SJohn Marino   struct tree_priority_map *h;
5911e4b17023SJohn Marino   void **loc;
5912e4b17023SJohn Marino 
5913e4b17023SJohn Marino   in.base.from = decl;
5914e4b17023SJohn Marino   loc = htab_find_slot (init_priority_for_decl, &in, INSERT);
5915e4b17023SJohn Marino   h = (struct tree_priority_map *) *loc;
5916e4b17023SJohn Marino   if (!h)
5917e4b17023SJohn Marino     {
5918e4b17023SJohn Marino       h = ggc_alloc_cleared_tree_priority_map ();
5919e4b17023SJohn Marino       *loc = h;
5920e4b17023SJohn Marino       h->base.from = decl;
5921e4b17023SJohn Marino       h->init = DEFAULT_INIT_PRIORITY;
5922e4b17023SJohn Marino       h->fini = DEFAULT_INIT_PRIORITY;
5923e4b17023SJohn Marino     }
5924e4b17023SJohn Marino 
5925e4b17023SJohn Marino   return h;
5926e4b17023SJohn Marino }
5927e4b17023SJohn Marino 
5928e4b17023SJohn Marino /* Set the initialization priority for DECL to PRIORITY.  */
5929e4b17023SJohn Marino 
5930e4b17023SJohn Marino void
decl_init_priority_insert(tree decl,priority_type priority)5931e4b17023SJohn Marino decl_init_priority_insert (tree decl, priority_type priority)
5932e4b17023SJohn Marino {
5933e4b17023SJohn Marino   struct tree_priority_map *h;
5934e4b17023SJohn Marino 
5935e4b17023SJohn Marino   gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
5936e4b17023SJohn Marino   if (priority == DEFAULT_INIT_PRIORITY)
5937e4b17023SJohn Marino     return;
5938e4b17023SJohn Marino   h = decl_priority_info (decl);
5939e4b17023SJohn Marino   h->init = priority;
5940e4b17023SJohn Marino }
5941e4b17023SJohn Marino 
5942e4b17023SJohn Marino /* Set the finalization priority for DECL to PRIORITY.  */
5943e4b17023SJohn Marino 
5944e4b17023SJohn Marino void
decl_fini_priority_insert(tree decl,priority_type priority)5945e4b17023SJohn Marino decl_fini_priority_insert (tree decl, priority_type priority)
5946e4b17023SJohn Marino {
5947e4b17023SJohn Marino   struct tree_priority_map *h;
5948e4b17023SJohn Marino 
5949e4b17023SJohn Marino   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
5950e4b17023SJohn Marino   if (priority == DEFAULT_INIT_PRIORITY)
5951e4b17023SJohn Marino     return;
5952e4b17023SJohn Marino   h = decl_priority_info (decl);
5953e4b17023SJohn Marino   h->fini = priority;
5954e4b17023SJohn Marino }
5955e4b17023SJohn Marino 
5956e4b17023SJohn Marino /* Print out the statistics for the DECL_DEBUG_EXPR hash table.  */
5957e4b17023SJohn Marino 
5958e4b17023SJohn Marino static void
print_debug_expr_statistics(void)5959e4b17023SJohn Marino print_debug_expr_statistics (void)
5960e4b17023SJohn Marino {
5961e4b17023SJohn Marino   fprintf (stderr, "DECL_DEBUG_EXPR  hash: size %ld, %ld elements, %f collisions\n",
5962e4b17023SJohn Marino 	   (long) htab_size (debug_expr_for_decl),
5963e4b17023SJohn Marino 	   (long) htab_elements (debug_expr_for_decl),
5964e4b17023SJohn Marino 	   htab_collisions (debug_expr_for_decl));
5965e4b17023SJohn Marino }
5966e4b17023SJohn Marino 
5967e4b17023SJohn Marino /* Print out the statistics for the DECL_VALUE_EXPR hash table.  */
5968e4b17023SJohn Marino 
5969e4b17023SJohn Marino static void
print_value_expr_statistics(void)5970e4b17023SJohn Marino print_value_expr_statistics (void)
5971e4b17023SJohn Marino {
5972e4b17023SJohn Marino   fprintf (stderr, "DECL_VALUE_EXPR  hash: size %ld, %ld elements, %f collisions\n",
5973e4b17023SJohn Marino 	   (long) htab_size (value_expr_for_decl),
5974e4b17023SJohn Marino 	   (long) htab_elements (value_expr_for_decl),
5975e4b17023SJohn Marino 	   htab_collisions (value_expr_for_decl));
5976e4b17023SJohn Marino }
5977e4b17023SJohn Marino 
5978e4b17023SJohn Marino /* Lookup a debug expression for FROM, and return it if we find one.  */
5979e4b17023SJohn Marino 
5980e4b17023SJohn Marino tree
decl_debug_expr_lookup(tree from)5981e4b17023SJohn Marino decl_debug_expr_lookup (tree from)
5982e4b17023SJohn Marino {
5983e4b17023SJohn Marino   struct tree_decl_map *h, in;
5984e4b17023SJohn Marino   in.base.from = from;
5985e4b17023SJohn Marino 
5986e4b17023SJohn Marino   h = (struct tree_decl_map *)
5987e4b17023SJohn Marino       htab_find_with_hash (debug_expr_for_decl, &in, DECL_UID (from));
5988e4b17023SJohn Marino   if (h)
5989e4b17023SJohn Marino     return h->to;
5990e4b17023SJohn Marino   return NULL_TREE;
5991e4b17023SJohn Marino }
5992e4b17023SJohn Marino 
5993e4b17023SJohn Marino /* Insert a mapping FROM->TO in the debug expression hashtable.  */
5994e4b17023SJohn Marino 
5995e4b17023SJohn Marino void
decl_debug_expr_insert(tree from,tree to)5996e4b17023SJohn Marino decl_debug_expr_insert (tree from, tree to)
5997e4b17023SJohn Marino {
5998e4b17023SJohn Marino   struct tree_decl_map *h;
5999e4b17023SJohn Marino   void **loc;
6000e4b17023SJohn Marino 
6001e4b17023SJohn Marino   h = ggc_alloc_tree_decl_map ();
6002e4b17023SJohn Marino   h->base.from = from;
6003e4b17023SJohn Marino   h->to = to;
6004e4b17023SJohn Marino   loc = htab_find_slot_with_hash (debug_expr_for_decl, h, DECL_UID (from),
6005e4b17023SJohn Marino 				  INSERT);
6006e4b17023SJohn Marino   *(struct tree_decl_map **) loc = h;
6007e4b17023SJohn Marino }
6008e4b17023SJohn Marino 
6009e4b17023SJohn Marino /* Lookup a value expression for FROM, and return it if we find one.  */
6010e4b17023SJohn Marino 
6011e4b17023SJohn Marino tree
decl_value_expr_lookup(tree from)6012e4b17023SJohn Marino decl_value_expr_lookup (tree from)
6013e4b17023SJohn Marino {
6014e4b17023SJohn Marino   struct tree_decl_map *h, in;
6015e4b17023SJohn Marino   in.base.from = from;
6016e4b17023SJohn Marino 
6017e4b17023SJohn Marino   h = (struct tree_decl_map *)
6018e4b17023SJohn Marino       htab_find_with_hash (value_expr_for_decl, &in, DECL_UID (from));
6019e4b17023SJohn Marino   if (h)
6020e4b17023SJohn Marino     return h->to;
6021e4b17023SJohn Marino   return NULL_TREE;
6022e4b17023SJohn Marino }
6023e4b17023SJohn Marino 
6024e4b17023SJohn Marino /* Insert a mapping FROM->TO in the value expression hashtable.  */
6025e4b17023SJohn Marino 
6026e4b17023SJohn Marino void
decl_value_expr_insert(tree from,tree to)6027e4b17023SJohn Marino decl_value_expr_insert (tree from, tree to)
6028e4b17023SJohn Marino {
6029e4b17023SJohn Marino   struct tree_decl_map *h;
6030e4b17023SJohn Marino   void **loc;
6031e4b17023SJohn Marino 
6032e4b17023SJohn Marino   h = ggc_alloc_tree_decl_map ();
6033e4b17023SJohn Marino   h->base.from = from;
6034e4b17023SJohn Marino   h->to = to;
6035e4b17023SJohn Marino   loc = htab_find_slot_with_hash (value_expr_for_decl, h, DECL_UID (from),
6036e4b17023SJohn Marino 				  INSERT);
6037e4b17023SJohn Marino   *(struct tree_decl_map **) loc = h;
6038e4b17023SJohn Marino }
6039e4b17023SJohn Marino 
6040e4b17023SJohn Marino /* Lookup a vector of debug arguments for FROM, and return it if we
6041e4b17023SJohn Marino    find one.  */
6042e4b17023SJohn Marino 
VEC(tree,gc)6043e4b17023SJohn Marino VEC(tree, gc) **
6044e4b17023SJohn Marino decl_debug_args_lookup (tree from)
6045e4b17023SJohn Marino {
6046e4b17023SJohn Marino   struct tree_vec_map *h, in;
6047e4b17023SJohn Marino 
6048e4b17023SJohn Marino   if (!DECL_HAS_DEBUG_ARGS_P (from))
6049e4b17023SJohn Marino     return NULL;
6050e4b17023SJohn Marino   gcc_checking_assert (debug_args_for_decl != NULL);
6051e4b17023SJohn Marino   in.base.from = from;
6052e4b17023SJohn Marino   h = (struct tree_vec_map *)
6053e4b17023SJohn Marino       htab_find_with_hash (debug_args_for_decl, &in, DECL_UID (from));
6054e4b17023SJohn Marino   if (h)
6055e4b17023SJohn Marino     return &h->to;
6056e4b17023SJohn Marino   return NULL;
6057e4b17023SJohn Marino }
6058e4b17023SJohn Marino 
6059e4b17023SJohn Marino /* Insert a mapping FROM->empty vector of debug arguments in the value
6060e4b17023SJohn Marino    expression hashtable.  */
6061e4b17023SJohn Marino 
VEC(tree,gc)6062e4b17023SJohn Marino VEC(tree, gc) **
6063e4b17023SJohn Marino decl_debug_args_insert (tree from)
6064e4b17023SJohn Marino {
6065e4b17023SJohn Marino   struct tree_vec_map *h;
6066e4b17023SJohn Marino   void **loc;
6067e4b17023SJohn Marino 
6068e4b17023SJohn Marino   if (DECL_HAS_DEBUG_ARGS_P (from))
6069e4b17023SJohn Marino     return decl_debug_args_lookup (from);
6070e4b17023SJohn Marino   if (debug_args_for_decl == NULL)
6071e4b17023SJohn Marino     debug_args_for_decl = htab_create_ggc (64, tree_vec_map_hash,
6072e4b17023SJohn Marino 					   tree_vec_map_eq, 0);
6073e4b17023SJohn Marino   h = ggc_alloc_tree_vec_map ();
6074e4b17023SJohn Marino   h->base.from = from;
6075e4b17023SJohn Marino   h->to = NULL;
6076e4b17023SJohn Marino   loc = htab_find_slot_with_hash (debug_args_for_decl, h, DECL_UID (from),
6077e4b17023SJohn Marino 				  INSERT);
6078e4b17023SJohn Marino   *(struct tree_vec_map **) loc = h;
6079e4b17023SJohn Marino   DECL_HAS_DEBUG_ARGS_P (from) = 1;
6080e4b17023SJohn Marino   return &h->to;
6081e4b17023SJohn Marino }
6082e4b17023SJohn Marino 
6083e4b17023SJohn Marino /* Hashing of types so that we don't make duplicates.
6084e4b17023SJohn Marino    The entry point is `type_hash_canon'.  */
6085e4b17023SJohn Marino 
6086e4b17023SJohn Marino /* Compute a hash code for a list of types (chain of TREE_LIST nodes
6087e4b17023SJohn Marino    with types in the TREE_VALUE slots), by adding the hash codes
6088e4b17023SJohn Marino    of the individual types.  */
6089e4b17023SJohn Marino 
6090e4b17023SJohn Marino static unsigned int
type_hash_list(const_tree list,hashval_t hashcode)6091e4b17023SJohn Marino type_hash_list (const_tree list, hashval_t hashcode)
6092e4b17023SJohn Marino {
6093e4b17023SJohn Marino   const_tree tail;
6094e4b17023SJohn Marino 
6095e4b17023SJohn Marino   for (tail = list; tail; tail = TREE_CHAIN (tail))
6096e4b17023SJohn Marino     if (TREE_VALUE (tail) != error_mark_node)
6097e4b17023SJohn Marino       hashcode = iterative_hash_object (TYPE_HASH (TREE_VALUE (tail)),
6098e4b17023SJohn Marino 					hashcode);
6099e4b17023SJohn Marino 
6100e4b17023SJohn Marino   return hashcode;
6101e4b17023SJohn Marino }
6102e4b17023SJohn Marino 
6103e4b17023SJohn Marino /* These are the Hashtable callback functions.  */
6104e4b17023SJohn Marino 
6105e4b17023SJohn Marino /* Returns true iff the types are equivalent.  */
6106e4b17023SJohn Marino 
6107e4b17023SJohn Marino static int
type_hash_eq(const void * va,const void * vb)6108e4b17023SJohn Marino type_hash_eq (const void *va, const void *vb)
6109e4b17023SJohn Marino {
6110e4b17023SJohn Marino   const struct type_hash *const a = (const struct type_hash *) va,
6111e4b17023SJohn Marino     *const b = (const struct type_hash *) vb;
6112e4b17023SJohn Marino 
6113e4b17023SJohn Marino   /* First test the things that are the same for all types.  */
6114e4b17023SJohn Marino   if (a->hash != b->hash
6115e4b17023SJohn Marino       || TREE_CODE (a->type) != TREE_CODE (b->type)
6116e4b17023SJohn Marino       || TREE_TYPE (a->type) != TREE_TYPE (b->type)
6117e4b17023SJohn Marino       || !attribute_list_equal (TYPE_ATTRIBUTES (a->type),
6118e4b17023SJohn Marino 				 TYPE_ATTRIBUTES (b->type))
6119e4b17023SJohn Marino       || (TREE_CODE (a->type) != COMPLEX_TYPE
6120e4b17023SJohn Marino           && TYPE_NAME (a->type) != TYPE_NAME (b->type)))
6121e4b17023SJohn Marino     return 0;
6122e4b17023SJohn Marino 
6123e4b17023SJohn Marino   /* Be careful about comparing arrays before and after the element type
6124e4b17023SJohn Marino      has been completed; don't compare TYPE_ALIGN unless both types are
6125e4b17023SJohn Marino      complete.  */
6126e4b17023SJohn Marino   if (COMPLETE_TYPE_P (a->type) && COMPLETE_TYPE_P (b->type)
6127e4b17023SJohn Marino       && (TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type)
6128e4b17023SJohn Marino 	  || TYPE_MODE (a->type) != TYPE_MODE (b->type)))
6129e4b17023SJohn Marino     return 0;
6130e4b17023SJohn Marino 
6131e4b17023SJohn Marino   switch (TREE_CODE (a->type))
6132e4b17023SJohn Marino     {
6133e4b17023SJohn Marino     case VOID_TYPE:
6134e4b17023SJohn Marino     case COMPLEX_TYPE:
6135e4b17023SJohn Marino     case POINTER_TYPE:
6136e4b17023SJohn Marino     case REFERENCE_TYPE:
6137e4b17023SJohn Marino     case NULLPTR_TYPE:
6138e4b17023SJohn Marino       return 1;
6139e4b17023SJohn Marino 
6140e4b17023SJohn Marino     case VECTOR_TYPE:
6141e4b17023SJohn Marino       return TYPE_VECTOR_SUBPARTS (a->type) == TYPE_VECTOR_SUBPARTS (b->type);
6142e4b17023SJohn Marino 
6143e4b17023SJohn Marino     case ENUMERAL_TYPE:
6144e4b17023SJohn Marino       if (TYPE_VALUES (a->type) != TYPE_VALUES (b->type)
6145e4b17023SJohn Marino 	  && !(TYPE_VALUES (a->type)
6146e4b17023SJohn Marino 	       && TREE_CODE (TYPE_VALUES (a->type)) == TREE_LIST
6147e4b17023SJohn Marino 	       && TYPE_VALUES (b->type)
6148e4b17023SJohn Marino 	       && TREE_CODE (TYPE_VALUES (b->type)) == TREE_LIST
6149e4b17023SJohn Marino 	       && type_list_equal (TYPE_VALUES (a->type),
6150e4b17023SJohn Marino 				   TYPE_VALUES (b->type))))
6151e4b17023SJohn Marino 	return 0;
6152e4b17023SJohn Marino 
6153e4b17023SJohn Marino       /* ... fall through ... */
6154e4b17023SJohn Marino 
6155e4b17023SJohn Marino     case INTEGER_TYPE:
6156e4b17023SJohn Marino     case REAL_TYPE:
6157e4b17023SJohn Marino     case BOOLEAN_TYPE:
6158e4b17023SJohn Marino       return ((TYPE_MAX_VALUE (a->type) == TYPE_MAX_VALUE (b->type)
6159e4b17023SJohn Marino 	       || tree_int_cst_equal (TYPE_MAX_VALUE (a->type),
6160e4b17023SJohn Marino 				      TYPE_MAX_VALUE (b->type)))
6161e4b17023SJohn Marino 	      && (TYPE_MIN_VALUE (a->type) == TYPE_MIN_VALUE (b->type)
6162e4b17023SJohn Marino 		  || tree_int_cst_equal (TYPE_MIN_VALUE (a->type),
6163e4b17023SJohn Marino 					 TYPE_MIN_VALUE (b->type))));
6164e4b17023SJohn Marino 
6165e4b17023SJohn Marino     case FIXED_POINT_TYPE:
6166e4b17023SJohn Marino       return TYPE_SATURATING (a->type) == TYPE_SATURATING (b->type);
6167e4b17023SJohn Marino 
6168e4b17023SJohn Marino     case OFFSET_TYPE:
6169e4b17023SJohn Marino       return TYPE_OFFSET_BASETYPE (a->type) == TYPE_OFFSET_BASETYPE (b->type);
6170e4b17023SJohn Marino 
6171e4b17023SJohn Marino     case METHOD_TYPE:
6172e4b17023SJohn Marino       if (TYPE_METHOD_BASETYPE (a->type) == TYPE_METHOD_BASETYPE (b->type)
6173e4b17023SJohn Marino 	  && (TYPE_ARG_TYPES (a->type) == TYPE_ARG_TYPES (b->type)
6174e4b17023SJohn Marino 	      || (TYPE_ARG_TYPES (a->type)
6175e4b17023SJohn Marino 		  && TREE_CODE (TYPE_ARG_TYPES (a->type)) == TREE_LIST
6176e4b17023SJohn Marino 		  && TYPE_ARG_TYPES (b->type)
6177e4b17023SJohn Marino 		  && TREE_CODE (TYPE_ARG_TYPES (b->type)) == TREE_LIST
6178e4b17023SJohn Marino 		  && type_list_equal (TYPE_ARG_TYPES (a->type),
6179e4b17023SJohn Marino 				      TYPE_ARG_TYPES (b->type)))))
6180e4b17023SJohn Marino         break;
6181e4b17023SJohn Marino       return 0;
6182e4b17023SJohn Marino     case ARRAY_TYPE:
6183e4b17023SJohn Marino       return TYPE_DOMAIN (a->type) == TYPE_DOMAIN (b->type);
6184e4b17023SJohn Marino 
6185e4b17023SJohn Marino     case RECORD_TYPE:
6186e4b17023SJohn Marino     case UNION_TYPE:
6187e4b17023SJohn Marino     case QUAL_UNION_TYPE:
6188e4b17023SJohn Marino       return (TYPE_FIELDS (a->type) == TYPE_FIELDS (b->type)
6189e4b17023SJohn Marino 	      || (TYPE_FIELDS (a->type)
6190e4b17023SJohn Marino 		  && TREE_CODE (TYPE_FIELDS (a->type)) == TREE_LIST
6191e4b17023SJohn Marino 		  && TYPE_FIELDS (b->type)
6192e4b17023SJohn Marino 		  && TREE_CODE (TYPE_FIELDS (b->type)) == TREE_LIST
6193e4b17023SJohn Marino 		  && type_list_equal (TYPE_FIELDS (a->type),
6194e4b17023SJohn Marino 				      TYPE_FIELDS (b->type))));
6195e4b17023SJohn Marino 
6196e4b17023SJohn Marino     case FUNCTION_TYPE:
6197e4b17023SJohn Marino       if (TYPE_ARG_TYPES (a->type) == TYPE_ARG_TYPES (b->type)
6198e4b17023SJohn Marino 	  || (TYPE_ARG_TYPES (a->type)
6199e4b17023SJohn Marino 	      && TREE_CODE (TYPE_ARG_TYPES (a->type)) == TREE_LIST
6200e4b17023SJohn Marino 	      && TYPE_ARG_TYPES (b->type)
6201e4b17023SJohn Marino 	      && TREE_CODE (TYPE_ARG_TYPES (b->type)) == TREE_LIST
6202e4b17023SJohn Marino 	      && type_list_equal (TYPE_ARG_TYPES (a->type),
6203e4b17023SJohn Marino 				  TYPE_ARG_TYPES (b->type))))
6204e4b17023SJohn Marino 	break;
6205e4b17023SJohn Marino       return 0;
6206e4b17023SJohn Marino 
6207e4b17023SJohn Marino     default:
6208e4b17023SJohn Marino       return 0;
6209e4b17023SJohn Marino     }
6210e4b17023SJohn Marino 
6211e4b17023SJohn Marino   if (lang_hooks.types.type_hash_eq != NULL)
6212e4b17023SJohn Marino     return lang_hooks.types.type_hash_eq (a->type, b->type);
6213e4b17023SJohn Marino 
6214e4b17023SJohn Marino   return 1;
6215e4b17023SJohn Marino }
6216e4b17023SJohn Marino 
6217e4b17023SJohn Marino /* Return the cached hash value.  */
6218e4b17023SJohn Marino 
6219e4b17023SJohn Marino static hashval_t
type_hash_hash(const void * item)6220e4b17023SJohn Marino type_hash_hash (const void *item)
6221e4b17023SJohn Marino {
6222e4b17023SJohn Marino   return ((const struct type_hash *) item)->hash;
6223e4b17023SJohn Marino }
6224e4b17023SJohn Marino 
6225e4b17023SJohn Marino /* Look in the type hash table for a type isomorphic to TYPE.
6226e4b17023SJohn Marino    If one is found, return it.  Otherwise return 0.  */
6227e4b17023SJohn Marino 
6228e4b17023SJohn Marino tree
type_hash_lookup(hashval_t hashcode,tree type)6229e4b17023SJohn Marino type_hash_lookup (hashval_t hashcode, tree type)
6230e4b17023SJohn Marino {
6231e4b17023SJohn Marino   struct type_hash *h, in;
6232e4b17023SJohn Marino 
6233e4b17023SJohn Marino   /* The TYPE_ALIGN field of a type is set by layout_type(), so we
6234e4b17023SJohn Marino      must call that routine before comparing TYPE_ALIGNs.  */
6235e4b17023SJohn Marino   layout_type (type);
6236e4b17023SJohn Marino 
6237e4b17023SJohn Marino   in.hash = hashcode;
6238e4b17023SJohn Marino   in.type = type;
6239e4b17023SJohn Marino 
6240e4b17023SJohn Marino   h = (struct type_hash *) htab_find_with_hash (type_hash_table, &in,
6241e4b17023SJohn Marino 						hashcode);
6242e4b17023SJohn Marino   if (h)
6243e4b17023SJohn Marino     return h->type;
6244e4b17023SJohn Marino   return NULL_TREE;
6245e4b17023SJohn Marino }
6246e4b17023SJohn Marino 
6247e4b17023SJohn Marino /* Add an entry to the type-hash-table
6248e4b17023SJohn Marino    for a type TYPE whose hash code is HASHCODE.  */
6249e4b17023SJohn Marino 
6250e4b17023SJohn Marino void
type_hash_add(hashval_t hashcode,tree type)6251e4b17023SJohn Marino type_hash_add (hashval_t hashcode, tree type)
6252e4b17023SJohn Marino {
6253e4b17023SJohn Marino   struct type_hash *h;
6254e4b17023SJohn Marino   void **loc;
6255e4b17023SJohn Marino 
6256e4b17023SJohn Marino   h = ggc_alloc_type_hash ();
6257e4b17023SJohn Marino   h->hash = hashcode;
6258e4b17023SJohn Marino   h->type = type;
6259e4b17023SJohn Marino   loc = htab_find_slot_with_hash (type_hash_table, h, hashcode, INSERT);
6260e4b17023SJohn Marino   *loc = (void *)h;
6261e4b17023SJohn Marino }
6262e4b17023SJohn Marino 
6263e4b17023SJohn Marino /* Given TYPE, and HASHCODE its hash code, return the canonical
6264e4b17023SJohn Marino    object for an identical type if one already exists.
6265e4b17023SJohn Marino    Otherwise, return TYPE, and record it as the canonical object.
6266e4b17023SJohn Marino 
6267e4b17023SJohn Marino    To use this function, first create a type of the sort you want.
6268e4b17023SJohn Marino    Then compute its hash code from the fields of the type that
6269e4b17023SJohn Marino    make it different from other similar types.
6270e4b17023SJohn Marino    Then call this function and use the value.  */
6271e4b17023SJohn Marino 
6272e4b17023SJohn Marino tree
type_hash_canon(unsigned int hashcode,tree type)6273e4b17023SJohn Marino type_hash_canon (unsigned int hashcode, tree type)
6274e4b17023SJohn Marino {
6275e4b17023SJohn Marino   tree t1;
6276e4b17023SJohn Marino 
6277e4b17023SJohn Marino   /* The hash table only contains main variants, so ensure that's what we're
6278e4b17023SJohn Marino      being passed.  */
6279e4b17023SJohn Marino   gcc_assert (TYPE_MAIN_VARIANT (type) == type);
6280e4b17023SJohn Marino 
6281e4b17023SJohn Marino   /* See if the type is in the hash table already.  If so, return it.
6282e4b17023SJohn Marino      Otherwise, add the type.  */
6283e4b17023SJohn Marino   t1 = type_hash_lookup (hashcode, type);
6284e4b17023SJohn Marino   if (t1 != 0)
6285e4b17023SJohn Marino     {
6286e4b17023SJohn Marino #ifdef GATHER_STATISTICS
6287e4b17023SJohn Marino       tree_code_counts[(int) TREE_CODE (type)]--;
6288e4b17023SJohn Marino       tree_node_counts[(int) t_kind]--;
6289e4b17023SJohn Marino       tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type_non_common);
6290e4b17023SJohn Marino #endif
6291e4b17023SJohn Marino       return t1;
6292e4b17023SJohn Marino     }
6293e4b17023SJohn Marino   else
6294e4b17023SJohn Marino     {
6295e4b17023SJohn Marino       type_hash_add (hashcode, type);
6296e4b17023SJohn Marino       return type;
6297e4b17023SJohn Marino     }
6298e4b17023SJohn Marino }
6299e4b17023SJohn Marino 
6300e4b17023SJohn Marino /* See if the data pointed to by the type hash table is marked.  We consider
6301e4b17023SJohn Marino    it marked if the type is marked or if a debug type number or symbol
6302e4b17023SJohn Marino    table entry has been made for the type.  */
6303e4b17023SJohn Marino 
6304e4b17023SJohn Marino static int
type_hash_marked_p(const void * p)6305e4b17023SJohn Marino type_hash_marked_p (const void *p)
6306e4b17023SJohn Marino {
6307e4b17023SJohn Marino   const_tree const type = ((const struct type_hash *) p)->type;
6308e4b17023SJohn Marino 
6309e4b17023SJohn Marino   return ggc_marked_p (type);
6310e4b17023SJohn Marino }
6311e4b17023SJohn Marino 
6312e4b17023SJohn Marino static void
print_type_hash_statistics(void)6313e4b17023SJohn Marino print_type_hash_statistics (void)
6314e4b17023SJohn Marino {
6315e4b17023SJohn Marino   fprintf (stderr, "Type hash: size %ld, %ld elements, %f collisions\n",
6316e4b17023SJohn Marino 	   (long) htab_size (type_hash_table),
6317e4b17023SJohn Marino 	   (long) htab_elements (type_hash_table),
6318e4b17023SJohn Marino 	   htab_collisions (type_hash_table));
6319e4b17023SJohn Marino }
6320e4b17023SJohn Marino 
6321e4b17023SJohn Marino /* Compute a hash code for a list of attributes (chain of TREE_LIST nodes
6322e4b17023SJohn Marino    with names in the TREE_PURPOSE slots and args in the TREE_VALUE slots),
6323e4b17023SJohn Marino    by adding the hash codes of the individual attributes.  */
6324e4b17023SJohn Marino 
6325e4b17023SJohn Marino static unsigned int
attribute_hash_list(const_tree list,hashval_t hashcode)6326e4b17023SJohn Marino attribute_hash_list (const_tree list, hashval_t hashcode)
6327e4b17023SJohn Marino {
6328e4b17023SJohn Marino   const_tree tail;
6329e4b17023SJohn Marino 
6330e4b17023SJohn Marino   for (tail = list; tail; tail = TREE_CHAIN (tail))
6331e4b17023SJohn Marino     /* ??? Do we want to add in TREE_VALUE too? */
6332e4b17023SJohn Marino     hashcode = iterative_hash_object
6333e4b17023SJohn Marino       (IDENTIFIER_HASH_VALUE (TREE_PURPOSE (tail)), hashcode);
6334e4b17023SJohn Marino   return hashcode;
6335e4b17023SJohn Marino }
6336e4b17023SJohn Marino 
6337e4b17023SJohn Marino /* Given two lists of attributes, return true if list l2 is
6338e4b17023SJohn Marino    equivalent to l1.  */
6339e4b17023SJohn Marino 
6340e4b17023SJohn Marino int
attribute_list_equal(const_tree l1,const_tree l2)6341e4b17023SJohn Marino attribute_list_equal (const_tree l1, const_tree l2)
6342e4b17023SJohn Marino {
6343e4b17023SJohn Marino   if (l1 == l2)
6344e4b17023SJohn Marino     return 1;
6345e4b17023SJohn Marino 
6346e4b17023SJohn Marino   return attribute_list_contained (l1, l2)
6347e4b17023SJohn Marino 	 && attribute_list_contained (l2, l1);
6348e4b17023SJohn Marino }
6349e4b17023SJohn Marino 
6350e4b17023SJohn Marino /* Given two lists of attributes, return true if list L2 is
6351e4b17023SJohn Marino    completely contained within L1.  */
6352e4b17023SJohn Marino /* ??? This would be faster if attribute names were stored in a canonicalized
6353e4b17023SJohn Marino    form.  Otherwise, if L1 uses `foo' and L2 uses `__foo__', the long method
6354e4b17023SJohn Marino    must be used to show these elements are equivalent (which they are).  */
6355e4b17023SJohn Marino /* ??? It's not clear that attributes with arguments will always be handled
6356e4b17023SJohn Marino    correctly.  */
6357e4b17023SJohn Marino 
6358e4b17023SJohn Marino int
attribute_list_contained(const_tree l1,const_tree l2)6359e4b17023SJohn Marino attribute_list_contained (const_tree l1, const_tree l2)
6360e4b17023SJohn Marino {
6361e4b17023SJohn Marino   const_tree t1, t2;
6362e4b17023SJohn Marino 
6363e4b17023SJohn Marino   /* First check the obvious, maybe the lists are identical.  */
6364e4b17023SJohn Marino   if (l1 == l2)
6365e4b17023SJohn Marino     return 1;
6366e4b17023SJohn Marino 
6367e4b17023SJohn Marino   /* Maybe the lists are similar.  */
6368e4b17023SJohn Marino   for (t1 = l1, t2 = l2;
6369e4b17023SJohn Marino        t1 != 0 && t2 != 0
6370e4b17023SJohn Marino         && TREE_PURPOSE (t1) == TREE_PURPOSE (t2)
6371e4b17023SJohn Marino         && TREE_VALUE (t1) == TREE_VALUE (t2);
6372e4b17023SJohn Marino        t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
6373e4b17023SJohn Marino     ;
6374e4b17023SJohn Marino 
6375e4b17023SJohn Marino   /* Maybe the lists are equal.  */
6376e4b17023SJohn Marino   if (t1 == 0 && t2 == 0)
6377e4b17023SJohn Marino     return 1;
6378e4b17023SJohn Marino 
6379e4b17023SJohn Marino   for (; t2 != 0; t2 = TREE_CHAIN (t2))
6380e4b17023SJohn Marino     {
6381e4b17023SJohn Marino       const_tree attr;
6382e4b17023SJohn Marino       /* This CONST_CAST is okay because lookup_attribute does not
6383e4b17023SJohn Marino 	 modify its argument and the return value is assigned to a
6384e4b17023SJohn Marino 	 const_tree.  */
6385e4b17023SJohn Marino       for (attr = lookup_ident_attribute (TREE_PURPOSE (t2), CONST_CAST_TREE(l1));
6386e4b17023SJohn Marino 	   attr != NULL_TREE && !attribute_value_equal (t2, attr);
6387e4b17023SJohn Marino 	   attr = lookup_ident_attribute (TREE_PURPOSE (t2), TREE_CHAIN (attr)))
6388e4b17023SJohn Marino 	;
6389e4b17023SJohn Marino 
6390e4b17023SJohn Marino       if (attr == NULL_TREE)
6391e4b17023SJohn Marino 	return 0;
6392e4b17023SJohn Marino     }
6393e4b17023SJohn Marino 
6394e4b17023SJohn Marino   return 1;
6395e4b17023SJohn Marino }
6396e4b17023SJohn Marino 
6397e4b17023SJohn Marino /* Given two lists of types
6398e4b17023SJohn Marino    (chains of TREE_LIST nodes with types in the TREE_VALUE slots)
6399e4b17023SJohn Marino    return 1 if the lists contain the same types in the same order.
6400e4b17023SJohn Marino    Also, the TREE_PURPOSEs must match.  */
6401e4b17023SJohn Marino 
6402e4b17023SJohn Marino int
type_list_equal(const_tree l1,const_tree l2)6403e4b17023SJohn Marino type_list_equal (const_tree l1, const_tree l2)
6404e4b17023SJohn Marino {
6405e4b17023SJohn Marino   const_tree t1, t2;
6406e4b17023SJohn Marino 
6407e4b17023SJohn Marino   for (t1 = l1, t2 = l2; t1 && t2; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
6408e4b17023SJohn Marino     if (TREE_VALUE (t1) != TREE_VALUE (t2)
6409e4b17023SJohn Marino 	|| (TREE_PURPOSE (t1) != TREE_PURPOSE (t2)
6410e4b17023SJohn Marino 	    && ! (1 == simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2))
6411e4b17023SJohn Marino 		  && (TREE_TYPE (TREE_PURPOSE (t1))
6412e4b17023SJohn Marino 		      == TREE_TYPE (TREE_PURPOSE (t2))))))
6413e4b17023SJohn Marino       return 0;
6414e4b17023SJohn Marino 
6415e4b17023SJohn Marino   return t1 == t2;
6416e4b17023SJohn Marino }
6417e4b17023SJohn Marino 
6418e4b17023SJohn Marino /* Returns the number of arguments to the FUNCTION_TYPE or METHOD_TYPE
6419e4b17023SJohn Marino    given by TYPE.  If the argument list accepts variable arguments,
6420e4b17023SJohn Marino    then this function counts only the ordinary arguments.  */
6421e4b17023SJohn Marino 
6422e4b17023SJohn Marino int
type_num_arguments(const_tree type)6423e4b17023SJohn Marino type_num_arguments (const_tree type)
6424e4b17023SJohn Marino {
6425e4b17023SJohn Marino   int i = 0;
6426e4b17023SJohn Marino   tree t;
6427e4b17023SJohn Marino 
6428e4b17023SJohn Marino   for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
6429e4b17023SJohn Marino     /* If the function does not take a variable number of arguments,
6430e4b17023SJohn Marino        the last element in the list will have type `void'.  */
6431e4b17023SJohn Marino     if (VOID_TYPE_P (TREE_VALUE (t)))
6432e4b17023SJohn Marino       break;
6433e4b17023SJohn Marino     else
6434e4b17023SJohn Marino       ++i;
6435e4b17023SJohn Marino 
6436e4b17023SJohn Marino   return i;
6437e4b17023SJohn Marino }
6438e4b17023SJohn Marino 
6439e4b17023SJohn Marino /* Nonzero if integer constants T1 and T2
6440e4b17023SJohn Marino    represent the same constant value.  */
6441e4b17023SJohn Marino 
6442e4b17023SJohn Marino int
tree_int_cst_equal(const_tree t1,const_tree t2)6443e4b17023SJohn Marino tree_int_cst_equal (const_tree t1, const_tree t2)
6444e4b17023SJohn Marino {
6445e4b17023SJohn Marino   if (t1 == t2)
6446e4b17023SJohn Marino     return 1;
6447e4b17023SJohn Marino 
6448e4b17023SJohn Marino   if (t1 == 0 || t2 == 0)
6449e4b17023SJohn Marino     return 0;
6450e4b17023SJohn Marino 
6451e4b17023SJohn Marino   if (TREE_CODE (t1) == INTEGER_CST
6452e4b17023SJohn Marino       && TREE_CODE (t2) == INTEGER_CST
6453e4b17023SJohn Marino       && TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
6454e4b17023SJohn Marino       && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2))
6455e4b17023SJohn Marino     return 1;
6456e4b17023SJohn Marino 
6457e4b17023SJohn Marino   return 0;
6458e4b17023SJohn Marino }
6459e4b17023SJohn Marino 
6460e4b17023SJohn Marino /* Nonzero if integer constants T1 and T2 represent values that satisfy <.
6461e4b17023SJohn Marino    The precise way of comparison depends on their data type.  */
6462e4b17023SJohn Marino 
6463e4b17023SJohn Marino int
tree_int_cst_lt(const_tree t1,const_tree t2)6464e4b17023SJohn Marino tree_int_cst_lt (const_tree t1, const_tree t2)
6465e4b17023SJohn Marino {
6466e4b17023SJohn Marino   if (t1 == t2)
6467e4b17023SJohn Marino     return 0;
6468e4b17023SJohn Marino 
6469e4b17023SJohn Marino   if (TYPE_UNSIGNED (TREE_TYPE (t1)) != TYPE_UNSIGNED (TREE_TYPE (t2)))
6470e4b17023SJohn Marino     {
6471e4b17023SJohn Marino       int t1_sgn = tree_int_cst_sgn (t1);
6472e4b17023SJohn Marino       int t2_sgn = tree_int_cst_sgn (t2);
6473e4b17023SJohn Marino 
6474e4b17023SJohn Marino       if (t1_sgn < t2_sgn)
6475e4b17023SJohn Marino 	return 1;
6476e4b17023SJohn Marino       else if (t1_sgn > t2_sgn)
6477e4b17023SJohn Marino 	return 0;
6478e4b17023SJohn Marino       /* Otherwise, both are non-negative, so we compare them as
6479e4b17023SJohn Marino 	 unsigned just in case one of them would overflow a signed
6480e4b17023SJohn Marino 	 type.  */
6481e4b17023SJohn Marino     }
6482e4b17023SJohn Marino   else if (!TYPE_UNSIGNED (TREE_TYPE (t1)))
6483e4b17023SJohn Marino     return INT_CST_LT (t1, t2);
6484e4b17023SJohn Marino 
6485e4b17023SJohn Marino   return INT_CST_LT_UNSIGNED (t1, t2);
6486e4b17023SJohn Marino }
6487e4b17023SJohn Marino 
6488e4b17023SJohn Marino /* Returns -1 if T1 < T2, 0 if T1 == T2, and 1 if T1 > T2.  */
6489e4b17023SJohn Marino 
6490e4b17023SJohn Marino int
tree_int_cst_compare(const_tree t1,const_tree t2)6491e4b17023SJohn Marino tree_int_cst_compare (const_tree t1, const_tree t2)
6492e4b17023SJohn Marino {
6493e4b17023SJohn Marino   if (tree_int_cst_lt (t1, t2))
6494e4b17023SJohn Marino     return -1;
6495e4b17023SJohn Marino   else if (tree_int_cst_lt (t2, t1))
6496e4b17023SJohn Marino     return 1;
6497e4b17023SJohn Marino   else
6498e4b17023SJohn Marino     return 0;
6499e4b17023SJohn Marino }
6500e4b17023SJohn Marino 
6501e4b17023SJohn Marino /* Return 1 if T is an INTEGER_CST that can be manipulated efficiently on
6502e4b17023SJohn Marino    the host.  If POS is zero, the value can be represented in a single
6503e4b17023SJohn Marino    HOST_WIDE_INT.  If POS is nonzero, the value must be non-negative and can
6504e4b17023SJohn Marino    be represented in a single unsigned HOST_WIDE_INT.  */
6505e4b17023SJohn Marino 
6506e4b17023SJohn Marino int
host_integerp(const_tree t,int pos)6507e4b17023SJohn Marino host_integerp (const_tree t, int pos)
6508e4b17023SJohn Marino {
6509e4b17023SJohn Marino   if (t == NULL_TREE)
6510e4b17023SJohn Marino     return 0;
6511e4b17023SJohn Marino 
6512e4b17023SJohn Marino   return (TREE_CODE (t) == INTEGER_CST
6513e4b17023SJohn Marino 	  && ((TREE_INT_CST_HIGH (t) == 0
6514e4b17023SJohn Marino 	       && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
6515e4b17023SJohn Marino 	      || (! pos && TREE_INT_CST_HIGH (t) == -1
6516e4b17023SJohn Marino 		  && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0
6517e4b17023SJohn Marino 		  && (!TYPE_UNSIGNED (TREE_TYPE (t))
6518e4b17023SJohn Marino 		      || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
6519e4b17023SJohn Marino 			  && TYPE_IS_SIZETYPE (TREE_TYPE (t)))))
6520e4b17023SJohn Marino 	      || (pos && TREE_INT_CST_HIGH (t) == 0)));
6521e4b17023SJohn Marino }
6522e4b17023SJohn Marino 
6523e4b17023SJohn Marino /* Return the HOST_WIDE_INT least significant bits of T if it is an
6524e4b17023SJohn Marino    INTEGER_CST and there is no overflow.  POS is nonzero if the result must
6525e4b17023SJohn Marino    be non-negative.  We must be able to satisfy the above conditions.  */
6526e4b17023SJohn Marino 
6527e4b17023SJohn Marino HOST_WIDE_INT
tree_low_cst(const_tree t,int pos)6528e4b17023SJohn Marino tree_low_cst (const_tree t, int pos)
6529e4b17023SJohn Marino {
6530e4b17023SJohn Marino   gcc_assert (host_integerp (t, pos));
6531e4b17023SJohn Marino   return TREE_INT_CST_LOW (t);
6532e4b17023SJohn Marino }
6533e4b17023SJohn Marino 
6534e4b17023SJohn Marino /* Return the HOST_WIDE_INT least significant bits of T, a sizetype
6535e4b17023SJohn Marino    kind INTEGER_CST.  This makes sure to properly sign-extend the
6536e4b17023SJohn Marino    constant.  */
6537e4b17023SJohn Marino 
6538e4b17023SJohn Marino HOST_WIDE_INT
size_low_cst(const_tree t)6539e4b17023SJohn Marino size_low_cst (const_tree t)
6540e4b17023SJohn Marino {
6541e4b17023SJohn Marino   double_int d = tree_to_double_int (t);
6542e4b17023SJohn Marino   return double_int_sext (d, TYPE_PRECISION (TREE_TYPE (t))).low;
6543e4b17023SJohn Marino }
6544e4b17023SJohn Marino 
6545e4b17023SJohn Marino /* Return the most significant (sign) bit of T.  */
6546e4b17023SJohn Marino 
6547e4b17023SJohn Marino int
tree_int_cst_sign_bit(const_tree t)6548e4b17023SJohn Marino tree_int_cst_sign_bit (const_tree t)
6549e4b17023SJohn Marino {
6550e4b17023SJohn Marino   unsigned bitno = TYPE_PRECISION (TREE_TYPE (t)) - 1;
6551e4b17023SJohn Marino   unsigned HOST_WIDE_INT w;
6552e4b17023SJohn Marino 
6553e4b17023SJohn Marino   if (bitno < HOST_BITS_PER_WIDE_INT)
6554e4b17023SJohn Marino     w = TREE_INT_CST_LOW (t);
6555e4b17023SJohn Marino   else
6556e4b17023SJohn Marino     {
6557e4b17023SJohn Marino       w = TREE_INT_CST_HIGH (t);
6558e4b17023SJohn Marino       bitno -= HOST_BITS_PER_WIDE_INT;
6559e4b17023SJohn Marino     }
6560e4b17023SJohn Marino 
6561e4b17023SJohn Marino   return (w >> bitno) & 1;
6562e4b17023SJohn Marino }
6563e4b17023SJohn Marino 
6564e4b17023SJohn Marino /* Return an indication of the sign of the integer constant T.
6565e4b17023SJohn Marino    The return value is -1 if T < 0, 0 if T == 0, and 1 if T > 0.
6566e4b17023SJohn Marino    Note that -1 will never be returned if T's type is unsigned.  */
6567e4b17023SJohn Marino 
6568e4b17023SJohn Marino int
tree_int_cst_sgn(const_tree t)6569e4b17023SJohn Marino tree_int_cst_sgn (const_tree t)
6570e4b17023SJohn Marino {
6571e4b17023SJohn Marino   if (TREE_INT_CST_LOW (t) == 0 && TREE_INT_CST_HIGH (t) == 0)
6572e4b17023SJohn Marino     return 0;
6573e4b17023SJohn Marino   else if (TYPE_UNSIGNED (TREE_TYPE (t)))
6574e4b17023SJohn Marino     return 1;
6575e4b17023SJohn Marino   else if (TREE_INT_CST_HIGH (t) < 0)
6576e4b17023SJohn Marino     return -1;
6577e4b17023SJohn Marino   else
6578e4b17023SJohn Marino     return 1;
6579e4b17023SJohn Marino }
6580e4b17023SJohn Marino 
6581e4b17023SJohn Marino /* Return the minimum number of bits needed to represent VALUE in a
6582e4b17023SJohn Marino    signed or unsigned type, UNSIGNEDP says which.  */
6583e4b17023SJohn Marino 
6584e4b17023SJohn Marino unsigned int
tree_int_cst_min_precision(tree value,bool unsignedp)6585e4b17023SJohn Marino tree_int_cst_min_precision (tree value, bool unsignedp)
6586e4b17023SJohn Marino {
6587e4b17023SJohn Marino   int log;
6588e4b17023SJohn Marino 
6589e4b17023SJohn Marino   /* If the value is negative, compute its negative minus 1.  The latter
6590e4b17023SJohn Marino      adjustment is because the absolute value of the largest negative value
6591e4b17023SJohn Marino      is one larger than the largest positive value.  This is equivalent to
6592e4b17023SJohn Marino      a bit-wise negation, so use that operation instead.  */
6593e4b17023SJohn Marino 
6594e4b17023SJohn Marino   if (tree_int_cst_sgn (value) < 0)
6595e4b17023SJohn Marino     value = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (value), value);
6596e4b17023SJohn Marino 
6597e4b17023SJohn Marino   /* Return the number of bits needed, taking into account the fact
6598e4b17023SJohn Marino      that we need one more bit for a signed than unsigned type.  */
6599e4b17023SJohn Marino 
6600e4b17023SJohn Marino   if (integer_zerop (value))
6601e4b17023SJohn Marino     log = 0;
6602e4b17023SJohn Marino   else
6603e4b17023SJohn Marino     log = tree_floor_log2 (value);
6604e4b17023SJohn Marino 
6605e4b17023SJohn Marino   return log + 1 + !unsignedp;
6606e4b17023SJohn Marino }
6607e4b17023SJohn Marino 
6608e4b17023SJohn Marino /* Compare two constructor-element-type constants.  Return 1 if the lists
6609e4b17023SJohn Marino    are known to be equal; otherwise return 0.  */
6610e4b17023SJohn Marino 
6611e4b17023SJohn Marino int
simple_cst_list_equal(const_tree l1,const_tree l2)6612e4b17023SJohn Marino simple_cst_list_equal (const_tree l1, const_tree l2)
6613e4b17023SJohn Marino {
6614e4b17023SJohn Marino   while (l1 != NULL_TREE && l2 != NULL_TREE)
6615e4b17023SJohn Marino     {
6616e4b17023SJohn Marino       if (simple_cst_equal (TREE_VALUE (l1), TREE_VALUE (l2)) != 1)
6617e4b17023SJohn Marino 	return 0;
6618e4b17023SJohn Marino 
6619e4b17023SJohn Marino       l1 = TREE_CHAIN (l1);
6620e4b17023SJohn Marino       l2 = TREE_CHAIN (l2);
6621e4b17023SJohn Marino     }
6622e4b17023SJohn Marino 
6623e4b17023SJohn Marino   return l1 == l2;
6624e4b17023SJohn Marino }
6625e4b17023SJohn Marino 
6626e4b17023SJohn Marino /* Return truthvalue of whether T1 is the same tree structure as T2.
6627e4b17023SJohn Marino    Return 1 if they are the same.
6628e4b17023SJohn Marino    Return 0 if they are understandably different.
6629e4b17023SJohn Marino    Return -1 if either contains tree structure not understood by
6630e4b17023SJohn Marino    this function.  */
6631e4b17023SJohn Marino 
6632e4b17023SJohn Marino int
simple_cst_equal(const_tree t1,const_tree t2)6633e4b17023SJohn Marino simple_cst_equal (const_tree t1, const_tree t2)
6634e4b17023SJohn Marino {
6635e4b17023SJohn Marino   enum tree_code code1, code2;
6636e4b17023SJohn Marino   int cmp;
6637e4b17023SJohn Marino   int i;
6638e4b17023SJohn Marino 
6639e4b17023SJohn Marino   if (t1 == t2)
6640e4b17023SJohn Marino     return 1;
6641e4b17023SJohn Marino   if (t1 == 0 || t2 == 0)
6642e4b17023SJohn Marino     return 0;
6643e4b17023SJohn Marino 
6644e4b17023SJohn Marino   code1 = TREE_CODE (t1);
6645e4b17023SJohn Marino   code2 = TREE_CODE (t2);
6646e4b17023SJohn Marino 
6647e4b17023SJohn Marino   if (CONVERT_EXPR_CODE_P (code1) || code1 == NON_LVALUE_EXPR)
6648e4b17023SJohn Marino     {
6649e4b17023SJohn Marino       if (CONVERT_EXPR_CODE_P (code2)
6650e4b17023SJohn Marino 	  || code2 == NON_LVALUE_EXPR)
6651e4b17023SJohn Marino 	return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
6652e4b17023SJohn Marino       else
6653e4b17023SJohn Marino 	return simple_cst_equal (TREE_OPERAND (t1, 0), t2);
6654e4b17023SJohn Marino     }
6655e4b17023SJohn Marino 
6656e4b17023SJohn Marino   else if (CONVERT_EXPR_CODE_P (code2)
6657e4b17023SJohn Marino 	   || code2 == NON_LVALUE_EXPR)
6658e4b17023SJohn Marino     return simple_cst_equal (t1, TREE_OPERAND (t2, 0));
6659e4b17023SJohn Marino 
6660e4b17023SJohn Marino   if (code1 != code2)
6661e4b17023SJohn Marino     return 0;
6662e4b17023SJohn Marino 
6663e4b17023SJohn Marino   switch (code1)
6664e4b17023SJohn Marino     {
6665e4b17023SJohn Marino     case INTEGER_CST:
6666e4b17023SJohn Marino       return (TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
6667e4b17023SJohn Marino 	      && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2));
6668e4b17023SJohn Marino 
6669e4b17023SJohn Marino     case REAL_CST:
6670e4b17023SJohn Marino       return REAL_VALUES_IDENTICAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
6671e4b17023SJohn Marino 
6672e4b17023SJohn Marino     case FIXED_CST:
6673e4b17023SJohn Marino       return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1), TREE_FIXED_CST (t2));
6674e4b17023SJohn Marino 
6675e4b17023SJohn Marino     case STRING_CST:
6676e4b17023SJohn Marino       return (TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
6677e4b17023SJohn Marino 	      && ! memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
6678e4b17023SJohn Marino 			 TREE_STRING_LENGTH (t1)));
6679e4b17023SJohn Marino 
6680e4b17023SJohn Marino     case CONSTRUCTOR:
6681e4b17023SJohn Marino       {
6682e4b17023SJohn Marino 	unsigned HOST_WIDE_INT idx;
6683e4b17023SJohn Marino 	VEC(constructor_elt, gc) *v1 = CONSTRUCTOR_ELTS (t1);
6684e4b17023SJohn Marino 	VEC(constructor_elt, gc) *v2 = CONSTRUCTOR_ELTS (t2);
6685e4b17023SJohn Marino 
6686e4b17023SJohn Marino 	if (VEC_length (constructor_elt, v1) != VEC_length (constructor_elt, v2))
6687e4b17023SJohn Marino 	  return false;
6688e4b17023SJohn Marino 
6689e4b17023SJohn Marino         for (idx = 0; idx < VEC_length (constructor_elt, v1); ++idx)
6690e4b17023SJohn Marino 	  /* ??? Should we handle also fields here? */
6691e4b17023SJohn Marino 	  if (!simple_cst_equal (VEC_index (constructor_elt, v1, idx)->value,
6692e4b17023SJohn Marino 				 VEC_index (constructor_elt, v2, idx)->value))
6693e4b17023SJohn Marino 	    return false;
6694e4b17023SJohn Marino 	return true;
6695e4b17023SJohn Marino       }
6696e4b17023SJohn Marino 
6697e4b17023SJohn Marino     case SAVE_EXPR:
6698e4b17023SJohn Marino       return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
6699e4b17023SJohn Marino 
6700e4b17023SJohn Marino     case CALL_EXPR:
6701e4b17023SJohn Marino       cmp = simple_cst_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2));
6702e4b17023SJohn Marino       if (cmp <= 0)
6703e4b17023SJohn Marino 	return cmp;
6704e4b17023SJohn Marino       if (call_expr_nargs (t1) != call_expr_nargs (t2))
6705e4b17023SJohn Marino 	return 0;
6706e4b17023SJohn Marino       {
6707e4b17023SJohn Marino 	const_tree arg1, arg2;
6708e4b17023SJohn Marino 	const_call_expr_arg_iterator iter1, iter2;
6709e4b17023SJohn Marino 	for (arg1 = first_const_call_expr_arg (t1, &iter1),
6710e4b17023SJohn Marino 	       arg2 = first_const_call_expr_arg (t2, &iter2);
6711e4b17023SJohn Marino 	     arg1 && arg2;
6712e4b17023SJohn Marino 	     arg1 = next_const_call_expr_arg (&iter1),
6713e4b17023SJohn Marino 	       arg2 = next_const_call_expr_arg (&iter2))
6714e4b17023SJohn Marino 	  {
6715e4b17023SJohn Marino 	    cmp = simple_cst_equal (arg1, arg2);
6716e4b17023SJohn Marino 	    if (cmp <= 0)
6717e4b17023SJohn Marino 	      return cmp;
6718e4b17023SJohn Marino 	  }
6719e4b17023SJohn Marino 	return arg1 == arg2;
6720e4b17023SJohn Marino       }
6721e4b17023SJohn Marino 
6722e4b17023SJohn Marino     case TARGET_EXPR:
6723e4b17023SJohn Marino       /* Special case: if either target is an unallocated VAR_DECL,
6724e4b17023SJohn Marino 	 it means that it's going to be unified with whatever the
6725e4b17023SJohn Marino 	 TARGET_EXPR is really supposed to initialize, so treat it
6726e4b17023SJohn Marino 	 as being equivalent to anything.  */
6727e4b17023SJohn Marino       if ((TREE_CODE (TREE_OPERAND (t1, 0)) == VAR_DECL
6728e4b17023SJohn Marino 	   && DECL_NAME (TREE_OPERAND (t1, 0)) == NULL_TREE
6729e4b17023SJohn Marino 	   && !DECL_RTL_SET_P (TREE_OPERAND (t1, 0)))
6730e4b17023SJohn Marino 	  || (TREE_CODE (TREE_OPERAND (t2, 0)) == VAR_DECL
6731e4b17023SJohn Marino 	      && DECL_NAME (TREE_OPERAND (t2, 0)) == NULL_TREE
6732e4b17023SJohn Marino 	      && !DECL_RTL_SET_P (TREE_OPERAND (t2, 0))))
6733e4b17023SJohn Marino 	cmp = 1;
6734e4b17023SJohn Marino       else
6735e4b17023SJohn Marino 	cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
6736e4b17023SJohn Marino 
6737e4b17023SJohn Marino       if (cmp <= 0)
6738e4b17023SJohn Marino 	return cmp;
6739e4b17023SJohn Marino 
6740e4b17023SJohn Marino       return simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
6741e4b17023SJohn Marino 
6742e4b17023SJohn Marino     case WITH_CLEANUP_EXPR:
6743e4b17023SJohn Marino       cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
6744e4b17023SJohn Marino       if (cmp <= 0)
6745e4b17023SJohn Marino 	return cmp;
6746e4b17023SJohn Marino 
6747e4b17023SJohn Marino       return simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t1, 1));
6748e4b17023SJohn Marino 
6749e4b17023SJohn Marino     case COMPONENT_REF:
6750e4b17023SJohn Marino       if (TREE_OPERAND (t1, 1) == TREE_OPERAND (t2, 1))
6751e4b17023SJohn Marino 	return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
6752e4b17023SJohn Marino 
6753e4b17023SJohn Marino       return 0;
6754e4b17023SJohn Marino 
6755e4b17023SJohn Marino     case VAR_DECL:
6756e4b17023SJohn Marino     case PARM_DECL:
6757e4b17023SJohn Marino     case CONST_DECL:
6758e4b17023SJohn Marino     case FUNCTION_DECL:
6759e4b17023SJohn Marino       return 0;
6760e4b17023SJohn Marino 
6761e4b17023SJohn Marino     default:
6762e4b17023SJohn Marino       break;
6763e4b17023SJohn Marino     }
6764e4b17023SJohn Marino 
6765e4b17023SJohn Marino   /* This general rule works for most tree codes.  All exceptions should be
6766e4b17023SJohn Marino      handled above.  If this is a language-specific tree code, we can't
6767e4b17023SJohn Marino      trust what might be in the operand, so say we don't know
6768e4b17023SJohn Marino      the situation.  */
6769e4b17023SJohn Marino   if ((int) code1 >= (int) LAST_AND_UNUSED_TREE_CODE)
6770e4b17023SJohn Marino     return -1;
6771e4b17023SJohn Marino 
6772e4b17023SJohn Marino   switch (TREE_CODE_CLASS (code1))
6773e4b17023SJohn Marino     {
6774e4b17023SJohn Marino     case tcc_unary:
6775e4b17023SJohn Marino     case tcc_binary:
6776e4b17023SJohn Marino     case tcc_comparison:
6777e4b17023SJohn Marino     case tcc_expression:
6778e4b17023SJohn Marino     case tcc_reference:
6779e4b17023SJohn Marino     case tcc_statement:
6780e4b17023SJohn Marino       cmp = 1;
6781e4b17023SJohn Marino       for (i = 0; i < TREE_CODE_LENGTH (code1); i++)
6782e4b17023SJohn Marino 	{
6783e4b17023SJohn Marino 	  cmp = simple_cst_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i));
6784e4b17023SJohn Marino 	  if (cmp <= 0)
6785e4b17023SJohn Marino 	    return cmp;
6786e4b17023SJohn Marino 	}
6787e4b17023SJohn Marino 
6788e4b17023SJohn Marino       return cmp;
6789e4b17023SJohn Marino 
6790e4b17023SJohn Marino     default:
6791e4b17023SJohn Marino       return -1;
6792e4b17023SJohn Marino     }
6793e4b17023SJohn Marino }
6794e4b17023SJohn Marino 
6795e4b17023SJohn Marino /* Compare the value of T, an INTEGER_CST, with U, an unsigned integer value.
6796e4b17023SJohn Marino    Return -1, 0, or 1 if the value of T is less than, equal to, or greater
6797e4b17023SJohn Marino    than U, respectively.  */
6798e4b17023SJohn Marino 
6799e4b17023SJohn Marino int
compare_tree_int(const_tree t,unsigned HOST_WIDE_INT u)6800e4b17023SJohn Marino compare_tree_int (const_tree t, unsigned HOST_WIDE_INT u)
6801e4b17023SJohn Marino {
6802e4b17023SJohn Marino   if (tree_int_cst_sgn (t) < 0)
6803e4b17023SJohn Marino     return -1;
6804e4b17023SJohn Marino   else if (TREE_INT_CST_HIGH (t) != 0)
6805e4b17023SJohn Marino     return 1;
6806e4b17023SJohn Marino   else if (TREE_INT_CST_LOW (t) == u)
6807e4b17023SJohn Marino     return 0;
6808e4b17023SJohn Marino   else if (TREE_INT_CST_LOW (t) < u)
6809e4b17023SJohn Marino     return -1;
6810e4b17023SJohn Marino   else
6811e4b17023SJohn Marino     return 1;
6812e4b17023SJohn Marino }
6813e4b17023SJohn Marino 
6814e4b17023SJohn Marino /* Return true if CODE represents an associative tree code.  Otherwise
6815e4b17023SJohn Marino    return false.  */
6816e4b17023SJohn Marino bool
associative_tree_code(enum tree_code code)6817e4b17023SJohn Marino associative_tree_code (enum tree_code code)
6818e4b17023SJohn Marino {
6819e4b17023SJohn Marino   switch (code)
6820e4b17023SJohn Marino     {
6821e4b17023SJohn Marino     case BIT_IOR_EXPR:
6822e4b17023SJohn Marino     case BIT_AND_EXPR:
6823e4b17023SJohn Marino     case BIT_XOR_EXPR:
6824e4b17023SJohn Marino     case PLUS_EXPR:
6825e4b17023SJohn Marino     case MULT_EXPR:
6826e4b17023SJohn Marino     case MIN_EXPR:
6827e4b17023SJohn Marino     case MAX_EXPR:
6828e4b17023SJohn Marino       return true;
6829e4b17023SJohn Marino 
6830e4b17023SJohn Marino     default:
6831e4b17023SJohn Marino       break;
6832e4b17023SJohn Marino     }
6833e4b17023SJohn Marino   return false;
6834e4b17023SJohn Marino }
6835e4b17023SJohn Marino 
6836e4b17023SJohn Marino /* Return true if CODE represents a commutative tree code.  Otherwise
6837e4b17023SJohn Marino    return false.  */
6838e4b17023SJohn Marino bool
commutative_tree_code(enum tree_code code)6839e4b17023SJohn Marino commutative_tree_code (enum tree_code code)
6840e4b17023SJohn Marino {
6841e4b17023SJohn Marino   switch (code)
6842e4b17023SJohn Marino     {
6843e4b17023SJohn Marino     case PLUS_EXPR:
6844e4b17023SJohn Marino     case MULT_EXPR:
6845e4b17023SJohn Marino     case MIN_EXPR:
6846e4b17023SJohn Marino     case MAX_EXPR:
6847e4b17023SJohn Marino     case BIT_IOR_EXPR:
6848e4b17023SJohn Marino     case BIT_XOR_EXPR:
6849e4b17023SJohn Marino     case BIT_AND_EXPR:
6850e4b17023SJohn Marino     case NE_EXPR:
6851e4b17023SJohn Marino     case EQ_EXPR:
6852e4b17023SJohn Marino     case UNORDERED_EXPR:
6853e4b17023SJohn Marino     case ORDERED_EXPR:
6854e4b17023SJohn Marino     case UNEQ_EXPR:
6855e4b17023SJohn Marino     case LTGT_EXPR:
6856e4b17023SJohn Marino     case TRUTH_AND_EXPR:
6857e4b17023SJohn Marino     case TRUTH_XOR_EXPR:
6858e4b17023SJohn Marino     case TRUTH_OR_EXPR:
6859e4b17023SJohn Marino       return true;
6860e4b17023SJohn Marino 
6861e4b17023SJohn Marino     default:
6862e4b17023SJohn Marino       break;
6863e4b17023SJohn Marino     }
6864e4b17023SJohn Marino   return false;
6865e4b17023SJohn Marino }
6866e4b17023SJohn Marino 
6867e4b17023SJohn Marino /* Return true if CODE represents a ternary tree code for which the
6868e4b17023SJohn Marino    first two operands are commutative.  Otherwise return false.  */
6869e4b17023SJohn Marino bool
commutative_ternary_tree_code(enum tree_code code)6870e4b17023SJohn Marino commutative_ternary_tree_code (enum tree_code code)
6871e4b17023SJohn Marino {
6872e4b17023SJohn Marino   switch (code)
6873e4b17023SJohn Marino     {
6874e4b17023SJohn Marino     case WIDEN_MULT_PLUS_EXPR:
6875e4b17023SJohn Marino     case WIDEN_MULT_MINUS_EXPR:
6876e4b17023SJohn Marino       return true;
6877e4b17023SJohn Marino 
6878e4b17023SJohn Marino     default:
6879e4b17023SJohn Marino       break;
6880e4b17023SJohn Marino     }
6881e4b17023SJohn Marino   return false;
6882e4b17023SJohn Marino }
6883e4b17023SJohn Marino 
6884e4b17023SJohn Marino /* Generate a hash value for an expression.  This can be used iteratively
6885e4b17023SJohn Marino    by passing a previous result as the VAL argument.
6886e4b17023SJohn Marino 
6887e4b17023SJohn Marino    This function is intended to produce the same hash for expressions which
6888e4b17023SJohn Marino    would compare equal using operand_equal_p.  */
6889e4b17023SJohn Marino 
6890e4b17023SJohn Marino hashval_t
iterative_hash_expr(const_tree t,hashval_t val)6891e4b17023SJohn Marino iterative_hash_expr (const_tree t, hashval_t val)
6892e4b17023SJohn Marino {
6893e4b17023SJohn Marino   int i;
6894e4b17023SJohn Marino   enum tree_code code;
6895e4b17023SJohn Marino   char tclass;
6896e4b17023SJohn Marino 
6897e4b17023SJohn Marino   if (t == NULL_TREE)
6898e4b17023SJohn Marino     return iterative_hash_hashval_t (0, val);
6899e4b17023SJohn Marino 
6900e4b17023SJohn Marino   code = TREE_CODE (t);
6901e4b17023SJohn Marino 
6902e4b17023SJohn Marino   switch (code)
6903e4b17023SJohn Marino     {
6904e4b17023SJohn Marino     /* Alas, constants aren't shared, so we can't rely on pointer
6905e4b17023SJohn Marino        identity.  */
6906e4b17023SJohn Marino     case INTEGER_CST:
6907e4b17023SJohn Marino       val = iterative_hash_host_wide_int (TREE_INT_CST_LOW (t), val);
6908e4b17023SJohn Marino       return iterative_hash_host_wide_int (TREE_INT_CST_HIGH (t), val);
6909e4b17023SJohn Marino     case REAL_CST:
6910e4b17023SJohn Marino       {
6911e4b17023SJohn Marino 	unsigned int val2 = real_hash (TREE_REAL_CST_PTR (t));
6912e4b17023SJohn Marino 
6913e4b17023SJohn Marino 	return iterative_hash_hashval_t (val2, val);
6914e4b17023SJohn Marino       }
6915e4b17023SJohn Marino     case FIXED_CST:
6916e4b17023SJohn Marino       {
6917e4b17023SJohn Marino 	unsigned int val2 = fixed_hash (TREE_FIXED_CST_PTR (t));
6918e4b17023SJohn Marino 
6919e4b17023SJohn Marino 	return iterative_hash_hashval_t (val2, val);
6920e4b17023SJohn Marino       }
6921e4b17023SJohn Marino     case STRING_CST:
6922e4b17023SJohn Marino       return iterative_hash (TREE_STRING_POINTER (t),
6923e4b17023SJohn Marino 			     TREE_STRING_LENGTH (t), val);
6924e4b17023SJohn Marino     case COMPLEX_CST:
6925e4b17023SJohn Marino       val = iterative_hash_expr (TREE_REALPART (t), val);
6926e4b17023SJohn Marino       return iterative_hash_expr (TREE_IMAGPART (t), val);
6927e4b17023SJohn Marino     case VECTOR_CST:
6928e4b17023SJohn Marino       return iterative_hash_expr (TREE_VECTOR_CST_ELTS (t), val);
6929e4b17023SJohn Marino     case SSA_NAME:
6930e4b17023SJohn Marino       /* We can just compare by pointer.  */
6931e4b17023SJohn Marino       return iterative_hash_host_wide_int (SSA_NAME_VERSION (t), val);
6932e4b17023SJohn Marino     case PLACEHOLDER_EXPR:
6933e4b17023SJohn Marino       /* The node itself doesn't matter.  */
6934e4b17023SJohn Marino       return val;
6935e4b17023SJohn Marino     case TREE_LIST:
6936e4b17023SJohn Marino       /* A list of expressions, for a CALL_EXPR or as the elements of a
6937e4b17023SJohn Marino 	 VECTOR_CST.  */
6938e4b17023SJohn Marino       for (; t; t = TREE_CHAIN (t))
6939e4b17023SJohn Marino 	val = iterative_hash_expr (TREE_VALUE (t), val);
6940e4b17023SJohn Marino       return val;
6941e4b17023SJohn Marino     case CONSTRUCTOR:
6942e4b17023SJohn Marino       {
6943e4b17023SJohn Marino 	unsigned HOST_WIDE_INT idx;
6944e4b17023SJohn Marino 	tree field, value;
6945e4b17023SJohn Marino 	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), idx, field, value)
6946e4b17023SJohn Marino 	  {
6947e4b17023SJohn Marino 	    val = iterative_hash_expr (field, val);
6948e4b17023SJohn Marino 	    val = iterative_hash_expr (value, val);
6949e4b17023SJohn Marino 	  }
6950e4b17023SJohn Marino 	return val;
6951e4b17023SJohn Marino       }
6952e4b17023SJohn Marino     case MEM_REF:
6953e4b17023SJohn Marino       {
6954e4b17023SJohn Marino 	/* The type of the second operand is relevant, except for
6955e4b17023SJohn Marino 	   its top-level qualifiers.  */
6956e4b17023SJohn Marino 	tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (t, 1)));
6957e4b17023SJohn Marino 
6958e4b17023SJohn Marino 	val = iterative_hash_object (TYPE_HASH (type), val);
6959e4b17023SJohn Marino 
6960e4b17023SJohn Marino 	/* We could use the standard hash computation from this point
6961e4b17023SJohn Marino 	   on.  */
6962e4b17023SJohn Marino 	val = iterative_hash_object (code, val);
6963e4b17023SJohn Marino 	val = iterative_hash_expr (TREE_OPERAND (t, 1), val);
6964e4b17023SJohn Marino 	val = iterative_hash_expr (TREE_OPERAND (t, 0), val);
6965e4b17023SJohn Marino 	return val;
6966e4b17023SJohn Marino       }
6967e4b17023SJohn Marino     case FUNCTION_DECL:
6968e4b17023SJohn Marino       /* When referring to a built-in FUNCTION_DECL, use the __builtin__ form.
6969e4b17023SJohn Marino 	 Otherwise nodes that compare equal according to operand_equal_p might
6970e4b17023SJohn Marino 	 get different hash codes.  However, don't do this for machine specific
6971e4b17023SJohn Marino 	 or front end builtins, since the function code is overloaded in those
6972e4b17023SJohn Marino 	 cases.  */
6973e4b17023SJohn Marino       if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
6974e4b17023SJohn Marino 	  && builtin_decl_explicit_p (DECL_FUNCTION_CODE (t)))
6975e4b17023SJohn Marino 	{
6976e4b17023SJohn Marino 	  t = builtin_decl_explicit (DECL_FUNCTION_CODE (t));
6977e4b17023SJohn Marino 	  code = TREE_CODE (t);
6978e4b17023SJohn Marino 	}
6979e4b17023SJohn Marino       /* FALL THROUGH */
6980e4b17023SJohn Marino     default:
6981e4b17023SJohn Marino       tclass = TREE_CODE_CLASS (code);
6982e4b17023SJohn Marino 
6983e4b17023SJohn Marino       if (tclass == tcc_declaration)
6984e4b17023SJohn Marino 	{
6985e4b17023SJohn Marino 	  /* DECL's have a unique ID */
6986e4b17023SJohn Marino 	  val = iterative_hash_host_wide_int (DECL_UID (t), val);
6987e4b17023SJohn Marino 	}
6988e4b17023SJohn Marino       else
6989e4b17023SJohn Marino 	{
6990e4b17023SJohn Marino 	  gcc_assert (IS_EXPR_CODE_CLASS (tclass));
6991e4b17023SJohn Marino 
6992e4b17023SJohn Marino 	  val = iterative_hash_object (code, val);
6993e4b17023SJohn Marino 
6994e4b17023SJohn Marino 	  /* Don't hash the type, that can lead to having nodes which
6995e4b17023SJohn Marino 	     compare equal according to operand_equal_p, but which
6996e4b17023SJohn Marino 	     have different hash codes.  */
6997e4b17023SJohn Marino 	  if (CONVERT_EXPR_CODE_P (code)
6998e4b17023SJohn Marino 	      || code == NON_LVALUE_EXPR)
6999e4b17023SJohn Marino 	    {
7000e4b17023SJohn Marino 	      /* Make sure to include signness in the hash computation.  */
7001e4b17023SJohn Marino 	      val += TYPE_UNSIGNED (TREE_TYPE (t));
7002e4b17023SJohn Marino 	      val = iterative_hash_expr (TREE_OPERAND (t, 0), val);
7003e4b17023SJohn Marino 	    }
7004e4b17023SJohn Marino 
7005e4b17023SJohn Marino 	  else if (commutative_tree_code (code))
7006e4b17023SJohn Marino 	    {
7007e4b17023SJohn Marino 	      /* It's a commutative expression.  We want to hash it the same
7008e4b17023SJohn Marino 		 however it appears.  We do this by first hashing both operands
7009e4b17023SJohn Marino 		 and then rehashing based on the order of their independent
7010e4b17023SJohn Marino 		 hashes.  */
7011e4b17023SJohn Marino 	      hashval_t one = iterative_hash_expr (TREE_OPERAND (t, 0), 0);
7012e4b17023SJohn Marino 	      hashval_t two = iterative_hash_expr (TREE_OPERAND (t, 1), 0);
7013e4b17023SJohn Marino 	      hashval_t t;
7014e4b17023SJohn Marino 
7015e4b17023SJohn Marino 	      if (one > two)
7016e4b17023SJohn Marino 		t = one, one = two, two = t;
7017e4b17023SJohn Marino 
7018e4b17023SJohn Marino 	      val = iterative_hash_hashval_t (one, val);
7019e4b17023SJohn Marino 	      val = iterative_hash_hashval_t (two, val);
7020e4b17023SJohn Marino 	    }
7021e4b17023SJohn Marino 	  else
7022e4b17023SJohn Marino 	    for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
7023e4b17023SJohn Marino 	      val = iterative_hash_expr (TREE_OPERAND (t, i), val);
7024e4b17023SJohn Marino 	}
7025e4b17023SJohn Marino       return val;
7026e4b17023SJohn Marino     }
7027e4b17023SJohn Marino }
7028e4b17023SJohn Marino 
7029e4b17023SJohn Marino /* Generate a hash value for a pair of expressions.  This can be used
7030e4b17023SJohn Marino    iteratively by passing a previous result as the VAL argument.
7031e4b17023SJohn Marino 
7032e4b17023SJohn Marino    The same hash value is always returned for a given pair of expressions,
7033e4b17023SJohn Marino    regardless of the order in which they are presented.  This is useful in
7034e4b17023SJohn Marino    hashing the operands of commutative functions.  */
7035e4b17023SJohn Marino 
7036e4b17023SJohn Marino hashval_t
iterative_hash_exprs_commutative(const_tree t1,const_tree t2,hashval_t val)7037e4b17023SJohn Marino iterative_hash_exprs_commutative (const_tree t1,
7038e4b17023SJohn Marino                                   const_tree t2, hashval_t val)
7039e4b17023SJohn Marino {
7040e4b17023SJohn Marino   hashval_t one = iterative_hash_expr (t1, 0);
7041e4b17023SJohn Marino   hashval_t two = iterative_hash_expr (t2, 0);
7042e4b17023SJohn Marino   hashval_t t;
7043e4b17023SJohn Marino 
7044e4b17023SJohn Marino   if (one > two)
7045e4b17023SJohn Marino     t = one, one = two, two = t;
7046e4b17023SJohn Marino   val = iterative_hash_hashval_t (one, val);
7047e4b17023SJohn Marino   val = iterative_hash_hashval_t (two, val);
7048e4b17023SJohn Marino 
7049e4b17023SJohn Marino   return val;
7050e4b17023SJohn Marino }
7051e4b17023SJohn Marino 
7052e4b17023SJohn Marino /* Constructors for pointer, array and function types.
7053e4b17023SJohn Marino    (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are
7054e4b17023SJohn Marino    constructed by language-dependent code, not here.)  */
7055e4b17023SJohn Marino 
7056e4b17023SJohn Marino /* Construct, lay out and return the type of pointers to TO_TYPE with
7057e4b17023SJohn Marino    mode MODE.  If CAN_ALIAS_ALL is TRUE, indicate this type can
7058e4b17023SJohn Marino    reference all of memory. If such a type has already been
7059e4b17023SJohn Marino    constructed, reuse it.  */
7060e4b17023SJohn Marino 
7061e4b17023SJohn Marino tree
build_pointer_type_for_mode(tree to_type,enum machine_mode mode,bool can_alias_all)7062e4b17023SJohn Marino build_pointer_type_for_mode (tree to_type, enum machine_mode mode,
7063e4b17023SJohn Marino 			     bool can_alias_all)
7064e4b17023SJohn Marino {
7065e4b17023SJohn Marino   tree t;
7066e4b17023SJohn Marino 
7067e4b17023SJohn Marino   if (to_type == error_mark_node)
7068e4b17023SJohn Marino     return error_mark_node;
7069e4b17023SJohn Marino 
7070e4b17023SJohn Marino   /* If the pointed-to type has the may_alias attribute set, force
7071e4b17023SJohn Marino      a TYPE_REF_CAN_ALIAS_ALL pointer to be generated.  */
7072e4b17023SJohn Marino   if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type)))
7073e4b17023SJohn Marino     can_alias_all = true;
7074e4b17023SJohn Marino 
7075e4b17023SJohn Marino   /* In some cases, languages will have things that aren't a POINTER_TYPE
7076e4b17023SJohn Marino      (such as a RECORD_TYPE for fat pointers in Ada) as TYPE_POINTER_TO.
7077e4b17023SJohn Marino      In that case, return that type without regard to the rest of our
7078e4b17023SJohn Marino      operands.
7079e4b17023SJohn Marino 
7080e4b17023SJohn Marino      ??? This is a kludge, but consistent with the way this function has
7081e4b17023SJohn Marino      always operated and there doesn't seem to be a good way to avoid this
7082e4b17023SJohn Marino      at the moment.  */
7083e4b17023SJohn Marino   if (TYPE_POINTER_TO (to_type) != 0
7084e4b17023SJohn Marino       && TREE_CODE (TYPE_POINTER_TO (to_type)) != POINTER_TYPE)
7085e4b17023SJohn Marino     return TYPE_POINTER_TO (to_type);
7086e4b17023SJohn Marino 
7087e4b17023SJohn Marino   /* First, if we already have a type for pointers to TO_TYPE and it's
7088e4b17023SJohn Marino      the proper mode, use it.  */
7089e4b17023SJohn Marino   for (t = TYPE_POINTER_TO (to_type); t; t = TYPE_NEXT_PTR_TO (t))
7090e4b17023SJohn Marino     if (TYPE_MODE (t) == mode && TYPE_REF_CAN_ALIAS_ALL (t) == can_alias_all)
7091e4b17023SJohn Marino       return t;
7092e4b17023SJohn Marino 
7093e4b17023SJohn Marino   t = make_node (POINTER_TYPE);
7094e4b17023SJohn Marino 
7095e4b17023SJohn Marino   TREE_TYPE (t) = to_type;
7096e4b17023SJohn Marino   SET_TYPE_MODE (t, mode);
7097e4b17023SJohn Marino   TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
7098e4b17023SJohn Marino   TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (to_type);
7099e4b17023SJohn Marino   TYPE_POINTER_TO (to_type) = t;
7100e4b17023SJohn Marino 
7101e4b17023SJohn Marino   if (TYPE_STRUCTURAL_EQUALITY_P (to_type))
7102e4b17023SJohn Marino     SET_TYPE_STRUCTURAL_EQUALITY (t);
7103e4b17023SJohn Marino   else if (TYPE_CANONICAL (to_type) != to_type)
7104e4b17023SJohn Marino     TYPE_CANONICAL (t)
7105e4b17023SJohn Marino       = build_pointer_type_for_mode (TYPE_CANONICAL (to_type),
7106e4b17023SJohn Marino 				     mode, can_alias_all);
7107e4b17023SJohn Marino 
7108e4b17023SJohn Marino   /* Lay out the type.  This function has many callers that are concerned
7109e4b17023SJohn Marino      with expression-construction, and this simplifies them all.  */
7110e4b17023SJohn Marino   layout_type (t);
7111e4b17023SJohn Marino 
7112e4b17023SJohn Marino   return t;
7113e4b17023SJohn Marino }
7114e4b17023SJohn Marino 
7115e4b17023SJohn Marino /* By default build pointers in ptr_mode.  */
7116e4b17023SJohn Marino 
7117e4b17023SJohn Marino tree
build_pointer_type(tree to_type)7118e4b17023SJohn Marino build_pointer_type (tree to_type)
7119e4b17023SJohn Marino {
7120e4b17023SJohn Marino   addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
7121e4b17023SJohn Marino 					      : TYPE_ADDR_SPACE (to_type);
7122e4b17023SJohn Marino   enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
7123e4b17023SJohn Marino   return build_pointer_type_for_mode (to_type, pointer_mode, false);
7124e4b17023SJohn Marino }
7125e4b17023SJohn Marino 
7126e4b17023SJohn Marino /* Same as build_pointer_type_for_mode, but for REFERENCE_TYPE.  */
7127e4b17023SJohn Marino 
7128e4b17023SJohn Marino tree
build_reference_type_for_mode(tree to_type,enum machine_mode mode,bool can_alias_all)7129e4b17023SJohn Marino build_reference_type_for_mode (tree to_type, enum machine_mode mode,
7130e4b17023SJohn Marino 			       bool can_alias_all)
7131e4b17023SJohn Marino {
7132e4b17023SJohn Marino   tree t;
7133e4b17023SJohn Marino 
7134e4b17023SJohn Marino   if (to_type == error_mark_node)
7135e4b17023SJohn Marino     return error_mark_node;
7136e4b17023SJohn Marino 
7137e4b17023SJohn Marino   /* If the pointed-to type has the may_alias attribute set, force
7138e4b17023SJohn Marino      a TYPE_REF_CAN_ALIAS_ALL pointer to be generated.  */
7139e4b17023SJohn Marino   if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type)))
7140e4b17023SJohn Marino     can_alias_all = true;
7141e4b17023SJohn Marino 
7142e4b17023SJohn Marino   /* In some cases, languages will have things that aren't a REFERENCE_TYPE
7143e4b17023SJohn Marino      (such as a RECORD_TYPE for fat pointers in Ada) as TYPE_REFERENCE_TO.
7144e4b17023SJohn Marino      In that case, return that type without regard to the rest of our
7145e4b17023SJohn Marino      operands.
7146e4b17023SJohn Marino 
7147e4b17023SJohn Marino      ??? This is a kludge, but consistent with the way this function has
7148e4b17023SJohn Marino      always operated and there doesn't seem to be a good way to avoid this
7149e4b17023SJohn Marino      at the moment.  */
7150e4b17023SJohn Marino   if (TYPE_REFERENCE_TO (to_type) != 0
7151e4b17023SJohn Marino       && TREE_CODE (TYPE_REFERENCE_TO (to_type)) != REFERENCE_TYPE)
7152e4b17023SJohn Marino     return TYPE_REFERENCE_TO (to_type);
7153e4b17023SJohn Marino 
7154e4b17023SJohn Marino   /* First, if we already have a type for pointers to TO_TYPE and it's
7155e4b17023SJohn Marino      the proper mode, use it.  */
7156e4b17023SJohn Marino   for (t = TYPE_REFERENCE_TO (to_type); t; t = TYPE_NEXT_REF_TO (t))
7157e4b17023SJohn Marino     if (TYPE_MODE (t) == mode && TYPE_REF_CAN_ALIAS_ALL (t) == can_alias_all)
7158e4b17023SJohn Marino       return t;
7159e4b17023SJohn Marino 
7160e4b17023SJohn Marino   t = make_node (REFERENCE_TYPE);
7161e4b17023SJohn Marino 
7162e4b17023SJohn Marino   TREE_TYPE (t) = to_type;
7163e4b17023SJohn Marino   SET_TYPE_MODE (t, mode);
7164e4b17023SJohn Marino   TYPE_REF_CAN_ALIAS_ALL (t) = can_alias_all;
7165e4b17023SJohn Marino   TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (to_type);
7166e4b17023SJohn Marino   TYPE_REFERENCE_TO (to_type) = t;
7167e4b17023SJohn Marino 
7168e4b17023SJohn Marino   if (TYPE_STRUCTURAL_EQUALITY_P (to_type))
7169e4b17023SJohn Marino     SET_TYPE_STRUCTURAL_EQUALITY (t);
7170e4b17023SJohn Marino   else if (TYPE_CANONICAL (to_type) != to_type)
7171e4b17023SJohn Marino     TYPE_CANONICAL (t)
7172e4b17023SJohn Marino       = build_reference_type_for_mode (TYPE_CANONICAL (to_type),
7173e4b17023SJohn Marino 				       mode, can_alias_all);
7174e4b17023SJohn Marino 
7175e4b17023SJohn Marino   layout_type (t);
7176e4b17023SJohn Marino 
7177e4b17023SJohn Marino   return t;
7178e4b17023SJohn Marino }
7179e4b17023SJohn Marino 
7180e4b17023SJohn Marino 
7181e4b17023SJohn Marino /* Build the node for the type of references-to-TO_TYPE by default
7182e4b17023SJohn Marino    in ptr_mode.  */
7183e4b17023SJohn Marino 
7184e4b17023SJohn Marino tree
build_reference_type(tree to_type)7185e4b17023SJohn Marino build_reference_type (tree to_type)
7186e4b17023SJohn Marino {
7187e4b17023SJohn Marino   addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC
7188e4b17023SJohn Marino 					      : TYPE_ADDR_SPACE (to_type);
7189e4b17023SJohn Marino   enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as);
7190e4b17023SJohn Marino   return build_reference_type_for_mode (to_type, pointer_mode, false);
7191e4b17023SJohn Marino }
7192e4b17023SJohn Marino 
7193e4b17023SJohn Marino /* Build a type that is compatible with t but has no cv quals anywhere
7194e4b17023SJohn Marino    in its type, thus
7195e4b17023SJohn Marino 
7196e4b17023SJohn Marino    const char *const *const *  ->  char ***.  */
7197e4b17023SJohn Marino 
7198e4b17023SJohn Marino tree
build_type_no_quals(tree t)7199e4b17023SJohn Marino build_type_no_quals (tree t)
7200e4b17023SJohn Marino {
7201e4b17023SJohn Marino   switch (TREE_CODE (t))
7202e4b17023SJohn Marino     {
7203e4b17023SJohn Marino     case POINTER_TYPE:
7204e4b17023SJohn Marino       return build_pointer_type_for_mode (build_type_no_quals (TREE_TYPE (t)),
7205e4b17023SJohn Marino 					  TYPE_MODE (t),
7206e4b17023SJohn Marino 					  TYPE_REF_CAN_ALIAS_ALL (t));
7207e4b17023SJohn Marino     case REFERENCE_TYPE:
7208e4b17023SJohn Marino       return
7209e4b17023SJohn Marino 	build_reference_type_for_mode (build_type_no_quals (TREE_TYPE (t)),
7210e4b17023SJohn Marino 				       TYPE_MODE (t),
7211e4b17023SJohn Marino 				       TYPE_REF_CAN_ALIAS_ALL (t));
7212e4b17023SJohn Marino     default:
7213e4b17023SJohn Marino       return TYPE_MAIN_VARIANT (t);
7214e4b17023SJohn Marino     }
7215e4b17023SJohn Marino }
7216e4b17023SJohn Marino 
7217e4b17023SJohn Marino #define MAX_INT_CACHED_PREC \
7218e4b17023SJohn Marino   (HOST_BITS_PER_WIDE_INT > 64 ? HOST_BITS_PER_WIDE_INT : 64)
7219e4b17023SJohn Marino static GTY(()) tree nonstandard_integer_type_cache[2 * MAX_INT_CACHED_PREC + 2];
7220e4b17023SJohn Marino 
7221e4b17023SJohn Marino /* Builds a signed or unsigned integer type of precision PRECISION.
7222e4b17023SJohn Marino    Used for C bitfields whose precision does not match that of
7223e4b17023SJohn Marino    built-in target types.  */
7224e4b17023SJohn Marino tree
build_nonstandard_integer_type(unsigned HOST_WIDE_INT precision,int unsignedp)7225e4b17023SJohn Marino build_nonstandard_integer_type (unsigned HOST_WIDE_INT precision,
7226e4b17023SJohn Marino 				int unsignedp)
7227e4b17023SJohn Marino {
7228e4b17023SJohn Marino   tree itype, ret;
7229e4b17023SJohn Marino 
7230e4b17023SJohn Marino   if (unsignedp)
7231e4b17023SJohn Marino     unsignedp = MAX_INT_CACHED_PREC + 1;
7232e4b17023SJohn Marino 
7233e4b17023SJohn Marino   if (precision <= MAX_INT_CACHED_PREC)
7234e4b17023SJohn Marino     {
7235e4b17023SJohn Marino       itype = nonstandard_integer_type_cache[precision + unsignedp];
7236e4b17023SJohn Marino       if (itype)
7237e4b17023SJohn Marino 	return itype;
7238e4b17023SJohn Marino     }
7239e4b17023SJohn Marino 
7240e4b17023SJohn Marino   itype = make_node (INTEGER_TYPE);
7241e4b17023SJohn Marino   TYPE_PRECISION (itype) = precision;
7242e4b17023SJohn Marino 
7243e4b17023SJohn Marino   if (unsignedp)
7244e4b17023SJohn Marino     fixup_unsigned_type (itype);
7245e4b17023SJohn Marino   else
7246e4b17023SJohn Marino     fixup_signed_type (itype);
7247e4b17023SJohn Marino 
7248e4b17023SJohn Marino   ret = itype;
7249e4b17023SJohn Marino   if (host_integerp (TYPE_MAX_VALUE (itype), 1))
7250e4b17023SJohn Marino     ret = type_hash_canon (tree_low_cst (TYPE_MAX_VALUE (itype), 1), itype);
7251e4b17023SJohn Marino   if (precision <= MAX_INT_CACHED_PREC)
7252e4b17023SJohn Marino     nonstandard_integer_type_cache[precision + unsignedp] = ret;
7253e4b17023SJohn Marino 
7254e4b17023SJohn Marino   return ret;
7255e4b17023SJohn Marino }
7256e4b17023SJohn Marino 
7257e4b17023SJohn Marino /* Create a range of some discrete type TYPE (an INTEGER_TYPE, ENUMERAL_TYPE
7258e4b17023SJohn Marino    or BOOLEAN_TYPE) with low bound LOWVAL and high bound HIGHVAL.  If SHARED
7259e4b17023SJohn Marino    is true, reuse such a type that has already been constructed.  */
7260e4b17023SJohn Marino 
7261e4b17023SJohn Marino static tree
build_range_type_1(tree type,tree lowval,tree highval,bool shared)7262e4b17023SJohn Marino build_range_type_1 (tree type, tree lowval, tree highval, bool shared)
7263e4b17023SJohn Marino {
7264e4b17023SJohn Marino   tree itype = make_node (INTEGER_TYPE);
7265e4b17023SJohn Marino   hashval_t hashcode = 0;
7266e4b17023SJohn Marino 
7267e4b17023SJohn Marino   TREE_TYPE (itype) = type;
7268e4b17023SJohn Marino 
7269e4b17023SJohn Marino   TYPE_MIN_VALUE (itype) = fold_convert (type, lowval);
7270e4b17023SJohn Marino   TYPE_MAX_VALUE (itype) = highval ? fold_convert (type, highval) : NULL;
7271e4b17023SJohn Marino 
7272e4b17023SJohn Marino   TYPE_PRECISION (itype) = TYPE_PRECISION (type);
7273e4b17023SJohn Marino   SET_TYPE_MODE (itype, TYPE_MODE (type));
7274e4b17023SJohn Marino   TYPE_SIZE (itype) = TYPE_SIZE (type);
7275e4b17023SJohn Marino   TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (type);
7276e4b17023SJohn Marino   TYPE_ALIGN (itype) = TYPE_ALIGN (type);
7277e4b17023SJohn Marino   TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (type);
7278e4b17023SJohn Marino 
7279e4b17023SJohn Marino   if (!shared)
7280e4b17023SJohn Marino     return itype;
7281e4b17023SJohn Marino 
7282e4b17023SJohn Marino   if ((TYPE_MIN_VALUE (itype)
7283e4b17023SJohn Marino        && TREE_CODE (TYPE_MIN_VALUE (itype)) != INTEGER_CST)
7284e4b17023SJohn Marino       || (TYPE_MAX_VALUE (itype)
7285e4b17023SJohn Marino 	  && TREE_CODE (TYPE_MAX_VALUE (itype)) != INTEGER_CST))
7286e4b17023SJohn Marino     {
7287e4b17023SJohn Marino       /* Since we cannot reliably merge this type, we need to compare it using
7288e4b17023SJohn Marino 	 structural equality checks.  */
7289e4b17023SJohn Marino       SET_TYPE_STRUCTURAL_EQUALITY (itype);
7290e4b17023SJohn Marino       return itype;
7291e4b17023SJohn Marino     }
7292e4b17023SJohn Marino 
7293e4b17023SJohn Marino   hashcode = iterative_hash_expr (TYPE_MIN_VALUE (itype), hashcode);
7294e4b17023SJohn Marino   hashcode = iterative_hash_expr (TYPE_MAX_VALUE (itype), hashcode);
7295e4b17023SJohn Marino   hashcode = iterative_hash_hashval_t (TYPE_HASH (type), hashcode);
7296e4b17023SJohn Marino   itype = type_hash_canon (hashcode, itype);
7297e4b17023SJohn Marino 
7298e4b17023SJohn Marino   return itype;
7299e4b17023SJohn Marino }
7300e4b17023SJohn Marino 
7301e4b17023SJohn Marino /* Wrapper around build_range_type_1 with SHARED set to true.  */
7302e4b17023SJohn Marino 
7303e4b17023SJohn Marino tree
build_range_type(tree type,tree lowval,tree highval)7304e4b17023SJohn Marino build_range_type (tree type, tree lowval, tree highval)
7305e4b17023SJohn Marino {
7306e4b17023SJohn Marino   return build_range_type_1 (type, lowval, highval, true);
7307e4b17023SJohn Marino }
7308e4b17023SJohn Marino 
7309e4b17023SJohn Marino /* Wrapper around build_range_type_1 with SHARED set to false.  */
7310e4b17023SJohn Marino 
7311e4b17023SJohn Marino tree
build_nonshared_range_type(tree type,tree lowval,tree highval)7312e4b17023SJohn Marino build_nonshared_range_type (tree type, tree lowval, tree highval)
7313e4b17023SJohn Marino {
7314e4b17023SJohn Marino   return build_range_type_1 (type, lowval, highval, false);
7315e4b17023SJohn Marino }
7316e4b17023SJohn Marino 
7317e4b17023SJohn Marino /* Create a type of integers to be the TYPE_DOMAIN of an ARRAY_TYPE.
7318e4b17023SJohn Marino    MAXVAL should be the maximum value in the domain
7319e4b17023SJohn Marino    (one less than the length of the array).
7320e4b17023SJohn Marino 
7321e4b17023SJohn Marino    The maximum value that MAXVAL can have is INT_MAX for a HOST_WIDE_INT.
7322e4b17023SJohn Marino    We don't enforce this limit, that is up to caller (e.g. language front end).
7323e4b17023SJohn Marino    The limit exists because the result is a signed type and we don't handle
7324e4b17023SJohn Marino    sizes that use more than one HOST_WIDE_INT.  */
7325e4b17023SJohn Marino 
7326e4b17023SJohn Marino tree
build_index_type(tree maxval)7327e4b17023SJohn Marino build_index_type (tree maxval)
7328e4b17023SJohn Marino {
7329e4b17023SJohn Marino   return build_range_type (sizetype, size_zero_node, maxval);
7330e4b17023SJohn Marino }
7331e4b17023SJohn Marino 
7332e4b17023SJohn Marino /* Return true if the debug information for TYPE, a subtype, should be emitted
7333e4b17023SJohn Marino    as a subrange type.  If so, set LOWVAL to the low bound and HIGHVAL to the
7334e4b17023SJohn Marino    high bound, respectively.  Sometimes doing so unnecessarily obfuscates the
7335e4b17023SJohn Marino    debug info and doesn't reflect the source code.  */
7336e4b17023SJohn Marino 
7337e4b17023SJohn Marino bool
subrange_type_for_debug_p(const_tree type,tree * lowval,tree * highval)7338e4b17023SJohn Marino subrange_type_for_debug_p (const_tree type, tree *lowval, tree *highval)
7339e4b17023SJohn Marino {
7340e4b17023SJohn Marino   tree base_type = TREE_TYPE (type), low, high;
7341e4b17023SJohn Marino 
7342e4b17023SJohn Marino   /* Subrange types have a base type which is an integral type.  */
7343e4b17023SJohn Marino   if (!INTEGRAL_TYPE_P (base_type))
7344e4b17023SJohn Marino     return false;
7345e4b17023SJohn Marino 
7346e4b17023SJohn Marino   /* Get the real bounds of the subtype.  */
7347e4b17023SJohn Marino   if (lang_hooks.types.get_subrange_bounds)
7348e4b17023SJohn Marino     lang_hooks.types.get_subrange_bounds (type, &low, &high);
7349e4b17023SJohn Marino   else
7350e4b17023SJohn Marino     {
7351e4b17023SJohn Marino       low = TYPE_MIN_VALUE (type);
7352e4b17023SJohn Marino       high = TYPE_MAX_VALUE (type);
7353e4b17023SJohn Marino     }
7354e4b17023SJohn Marino 
7355e4b17023SJohn Marino   /* If the type and its base type have the same representation and the same
7356e4b17023SJohn Marino      name, then the type is not a subrange but a copy of the base type.  */
7357e4b17023SJohn Marino   if ((TREE_CODE (base_type) == INTEGER_TYPE
7358e4b17023SJohn Marino        || TREE_CODE (base_type) == BOOLEAN_TYPE)
7359e4b17023SJohn Marino       && int_size_in_bytes (type) == int_size_in_bytes (base_type)
7360e4b17023SJohn Marino       && tree_int_cst_equal (low, TYPE_MIN_VALUE (base_type))
7361e4b17023SJohn Marino       && tree_int_cst_equal (high, TYPE_MAX_VALUE (base_type)))
7362e4b17023SJohn Marino     {
7363e4b17023SJohn Marino       tree type_name = TYPE_NAME (type);
7364e4b17023SJohn Marino       tree base_type_name = TYPE_NAME (base_type);
7365e4b17023SJohn Marino 
7366e4b17023SJohn Marino       if (type_name && TREE_CODE (type_name) == TYPE_DECL)
7367e4b17023SJohn Marino 	type_name = DECL_NAME (type_name);
7368e4b17023SJohn Marino 
7369e4b17023SJohn Marino       if (base_type_name && TREE_CODE (base_type_name) == TYPE_DECL)
7370e4b17023SJohn Marino 	base_type_name = DECL_NAME (base_type_name);
7371e4b17023SJohn Marino 
7372e4b17023SJohn Marino       if (type_name == base_type_name)
7373e4b17023SJohn Marino 	return false;
7374e4b17023SJohn Marino     }
7375e4b17023SJohn Marino 
7376e4b17023SJohn Marino   if (lowval)
7377e4b17023SJohn Marino     *lowval = low;
7378e4b17023SJohn Marino   if (highval)
7379e4b17023SJohn Marino     *highval = high;
7380e4b17023SJohn Marino   return true;
7381e4b17023SJohn Marino }
7382e4b17023SJohn Marino 
7383e4b17023SJohn Marino /* Construct, lay out and return the type of arrays of elements with ELT_TYPE
7384e4b17023SJohn Marino    and number of elements specified by the range of values of INDEX_TYPE.
7385e4b17023SJohn Marino    If SHARED is true, reuse such a type that has already been constructed.  */
7386e4b17023SJohn Marino 
7387e4b17023SJohn Marino static tree
build_array_type_1(tree elt_type,tree index_type,bool shared)7388e4b17023SJohn Marino build_array_type_1 (tree elt_type, tree index_type, bool shared)
7389e4b17023SJohn Marino {
7390e4b17023SJohn Marino   tree t;
7391e4b17023SJohn Marino 
7392e4b17023SJohn Marino   if (TREE_CODE (elt_type) == FUNCTION_TYPE)
7393e4b17023SJohn Marino     {
7394e4b17023SJohn Marino       error ("arrays of functions are not meaningful");
7395e4b17023SJohn Marino       elt_type = integer_type_node;
7396e4b17023SJohn Marino     }
7397e4b17023SJohn Marino 
7398e4b17023SJohn Marino   t = make_node (ARRAY_TYPE);
7399e4b17023SJohn Marino   TREE_TYPE (t) = elt_type;
7400e4b17023SJohn Marino   TYPE_DOMAIN (t) = index_type;
7401e4b17023SJohn Marino   TYPE_ADDR_SPACE (t) = TYPE_ADDR_SPACE (elt_type);
7402e4b17023SJohn Marino   layout_type (t);
7403e4b17023SJohn Marino 
7404e4b17023SJohn Marino   /* If the element type is incomplete at this point we get marked for
7405e4b17023SJohn Marino      structural equality.  Do not record these types in the canonical
7406e4b17023SJohn Marino      type hashtable.  */
7407e4b17023SJohn Marino   if (TYPE_STRUCTURAL_EQUALITY_P (t))
7408e4b17023SJohn Marino     return t;
7409e4b17023SJohn Marino 
7410e4b17023SJohn Marino   if (shared)
7411e4b17023SJohn Marino     {
7412e4b17023SJohn Marino       hashval_t hashcode = iterative_hash_object (TYPE_HASH (elt_type), 0);
7413e4b17023SJohn Marino       if (index_type)
7414e4b17023SJohn Marino 	hashcode = iterative_hash_object (TYPE_HASH (index_type), hashcode);
7415e4b17023SJohn Marino       t = type_hash_canon (hashcode, t);
7416e4b17023SJohn Marino     }
7417e4b17023SJohn Marino 
7418e4b17023SJohn Marino   if (TYPE_CANONICAL (t) == t)
7419e4b17023SJohn Marino     {
7420e4b17023SJohn Marino       if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
7421e4b17023SJohn Marino 	  || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)))
7422e4b17023SJohn Marino 	SET_TYPE_STRUCTURAL_EQUALITY (t);
7423e4b17023SJohn Marino       else if (TYPE_CANONICAL (elt_type) != elt_type
7424e4b17023SJohn Marino 	       || (index_type && TYPE_CANONICAL (index_type) != index_type))
7425e4b17023SJohn Marino 	TYPE_CANONICAL (t)
7426e4b17023SJohn Marino 	  = build_array_type_1 (TYPE_CANONICAL (elt_type),
7427e4b17023SJohn Marino 				index_type
7428e4b17023SJohn Marino 				? TYPE_CANONICAL (index_type) : NULL_TREE,
7429e4b17023SJohn Marino 				shared);
7430e4b17023SJohn Marino     }
7431e4b17023SJohn Marino 
7432e4b17023SJohn Marino   return t;
7433e4b17023SJohn Marino }
7434e4b17023SJohn Marino 
7435e4b17023SJohn Marino /* Wrapper around build_array_type_1 with SHARED set to true.  */
7436e4b17023SJohn Marino 
7437e4b17023SJohn Marino tree
build_array_type(tree elt_type,tree index_type)7438e4b17023SJohn Marino build_array_type (tree elt_type, tree index_type)
7439e4b17023SJohn Marino {
7440e4b17023SJohn Marino   return build_array_type_1 (elt_type, index_type, true);
7441e4b17023SJohn Marino }
7442e4b17023SJohn Marino 
7443e4b17023SJohn Marino /* Wrapper around build_array_type_1 with SHARED set to false.  */
7444e4b17023SJohn Marino 
7445e4b17023SJohn Marino tree
build_nonshared_array_type(tree elt_type,tree index_type)7446e4b17023SJohn Marino build_nonshared_array_type (tree elt_type, tree index_type)
7447e4b17023SJohn Marino {
7448e4b17023SJohn Marino   return build_array_type_1 (elt_type, index_type, false);
7449e4b17023SJohn Marino }
7450e4b17023SJohn Marino 
7451e4b17023SJohn Marino /* Return a representation of ELT_TYPE[NELTS], using indices of type
7452e4b17023SJohn Marino    sizetype.  */
7453e4b17023SJohn Marino 
7454e4b17023SJohn Marino tree
build_array_type_nelts(tree elt_type,unsigned HOST_WIDE_INT nelts)7455e4b17023SJohn Marino build_array_type_nelts (tree elt_type, unsigned HOST_WIDE_INT nelts)
7456e4b17023SJohn Marino {
7457e4b17023SJohn Marino   return build_array_type (elt_type, build_index_type (size_int (nelts - 1)));
7458e4b17023SJohn Marino }
7459e4b17023SJohn Marino 
7460e4b17023SJohn Marino /* Recursively examines the array elements of TYPE, until a non-array
7461e4b17023SJohn Marino    element type is found.  */
7462e4b17023SJohn Marino 
7463e4b17023SJohn Marino tree
strip_array_types(tree type)7464e4b17023SJohn Marino strip_array_types (tree type)
7465e4b17023SJohn Marino {
7466e4b17023SJohn Marino   while (TREE_CODE (type) == ARRAY_TYPE)
7467e4b17023SJohn Marino     type = TREE_TYPE (type);
7468e4b17023SJohn Marino 
7469e4b17023SJohn Marino   return type;
7470e4b17023SJohn Marino }
7471e4b17023SJohn Marino 
7472e4b17023SJohn Marino /* Computes the canonical argument types from the argument type list
7473e4b17023SJohn Marino    ARGTYPES.
7474e4b17023SJohn Marino 
7475e4b17023SJohn Marino    Upon return, *ANY_STRUCTURAL_P will be true iff either it was true
7476e4b17023SJohn Marino    on entry to this function, or if any of the ARGTYPES are
7477e4b17023SJohn Marino    structural.
7478e4b17023SJohn Marino 
7479e4b17023SJohn Marino    Upon return, *ANY_NONCANONICAL_P will be true iff either it was
7480e4b17023SJohn Marino    true on entry to this function, or if any of the ARGTYPES are
7481e4b17023SJohn Marino    non-canonical.
7482e4b17023SJohn Marino 
7483e4b17023SJohn Marino    Returns a canonical argument list, which may be ARGTYPES when the
7484e4b17023SJohn Marino    canonical argument list is unneeded (i.e., *ANY_STRUCTURAL_P is
7485e4b17023SJohn Marino    true) or would not differ from ARGTYPES.  */
7486e4b17023SJohn Marino 
7487e4b17023SJohn Marino static tree
maybe_canonicalize_argtypes(tree argtypes,bool * any_structural_p,bool * any_noncanonical_p)7488e4b17023SJohn Marino maybe_canonicalize_argtypes(tree argtypes,
7489e4b17023SJohn Marino 			    bool *any_structural_p,
7490e4b17023SJohn Marino 			    bool *any_noncanonical_p)
7491e4b17023SJohn Marino {
7492e4b17023SJohn Marino   tree arg;
7493e4b17023SJohn Marino   bool any_noncanonical_argtypes_p = false;
7494e4b17023SJohn Marino 
7495e4b17023SJohn Marino   for (arg = argtypes; arg && !(*any_structural_p); arg = TREE_CHAIN (arg))
7496e4b17023SJohn Marino     {
7497e4b17023SJohn Marino       if (!TREE_VALUE (arg) || TREE_VALUE (arg) == error_mark_node)
7498e4b17023SJohn Marino 	/* Fail gracefully by stating that the type is structural.  */
7499e4b17023SJohn Marino 	*any_structural_p = true;
7500e4b17023SJohn Marino       else if (TYPE_STRUCTURAL_EQUALITY_P (TREE_VALUE (arg)))
7501e4b17023SJohn Marino 	*any_structural_p = true;
7502e4b17023SJohn Marino       else if (TYPE_CANONICAL (TREE_VALUE (arg)) != TREE_VALUE (arg)
7503e4b17023SJohn Marino 	       || TREE_PURPOSE (arg))
7504e4b17023SJohn Marino 	/* If the argument has a default argument, we consider it
7505e4b17023SJohn Marino 	   non-canonical even though the type itself is canonical.
7506e4b17023SJohn Marino 	   That way, different variants of function and method types
7507e4b17023SJohn Marino 	   with default arguments will all point to the variant with
7508e4b17023SJohn Marino 	   no defaults as their canonical type.  */
7509e4b17023SJohn Marino         any_noncanonical_argtypes_p = true;
7510e4b17023SJohn Marino     }
7511e4b17023SJohn Marino 
7512e4b17023SJohn Marino   if (*any_structural_p)
7513e4b17023SJohn Marino     return argtypes;
7514e4b17023SJohn Marino 
7515e4b17023SJohn Marino   if (any_noncanonical_argtypes_p)
7516e4b17023SJohn Marino     {
7517e4b17023SJohn Marino       /* Build the canonical list of argument types.  */
7518e4b17023SJohn Marino       tree canon_argtypes = NULL_TREE;
7519e4b17023SJohn Marino       bool is_void = false;
7520e4b17023SJohn Marino 
7521e4b17023SJohn Marino       for (arg = argtypes; arg; arg = TREE_CHAIN (arg))
7522e4b17023SJohn Marino         {
7523e4b17023SJohn Marino           if (arg == void_list_node)
7524e4b17023SJohn Marino             is_void = true;
7525e4b17023SJohn Marino           else
7526e4b17023SJohn Marino             canon_argtypes = tree_cons (NULL_TREE,
7527e4b17023SJohn Marino                                         TYPE_CANONICAL (TREE_VALUE (arg)),
7528e4b17023SJohn Marino                                         canon_argtypes);
7529e4b17023SJohn Marino         }
7530e4b17023SJohn Marino 
7531e4b17023SJohn Marino       canon_argtypes = nreverse (canon_argtypes);
7532e4b17023SJohn Marino       if (is_void)
7533e4b17023SJohn Marino         canon_argtypes = chainon (canon_argtypes, void_list_node);
7534e4b17023SJohn Marino 
7535e4b17023SJohn Marino       /* There is a non-canonical type.  */
7536e4b17023SJohn Marino       *any_noncanonical_p = true;
7537e4b17023SJohn Marino       return canon_argtypes;
7538e4b17023SJohn Marino     }
7539e4b17023SJohn Marino 
7540e4b17023SJohn Marino   /* The canonical argument types are the same as ARGTYPES.  */
7541e4b17023SJohn Marino   return argtypes;
7542e4b17023SJohn Marino }
7543e4b17023SJohn Marino 
7544e4b17023SJohn Marino /* Construct, lay out and return
7545e4b17023SJohn Marino    the type of functions returning type VALUE_TYPE
7546e4b17023SJohn Marino    given arguments of types ARG_TYPES.
7547e4b17023SJohn Marino    ARG_TYPES is a chain of TREE_LIST nodes whose TREE_VALUEs
7548e4b17023SJohn Marino    are data type nodes for the arguments of the function.
7549e4b17023SJohn Marino    If such a type has already been constructed, reuse it.  */
7550e4b17023SJohn Marino 
7551e4b17023SJohn Marino tree
build_function_type(tree value_type,tree arg_types)7552e4b17023SJohn Marino build_function_type (tree value_type, tree arg_types)
7553e4b17023SJohn Marino {
7554e4b17023SJohn Marino   tree t;
7555e4b17023SJohn Marino   hashval_t hashcode = 0;
7556e4b17023SJohn Marino   bool any_structural_p, any_noncanonical_p;
7557e4b17023SJohn Marino   tree canon_argtypes;
7558e4b17023SJohn Marino 
7559e4b17023SJohn Marino   if (TREE_CODE (value_type) == FUNCTION_TYPE)
7560e4b17023SJohn Marino     {
7561e4b17023SJohn Marino       error ("function return type cannot be function");
7562e4b17023SJohn Marino       value_type = integer_type_node;
7563e4b17023SJohn Marino     }
7564e4b17023SJohn Marino 
7565e4b17023SJohn Marino   /* Make a node of the sort we want.  */
7566e4b17023SJohn Marino   t = make_node (FUNCTION_TYPE);
7567e4b17023SJohn Marino   TREE_TYPE (t) = value_type;
7568e4b17023SJohn Marino   TYPE_ARG_TYPES (t) = arg_types;
7569e4b17023SJohn Marino 
7570e4b17023SJohn Marino   /* If we already have such a type, use the old one.  */
7571e4b17023SJohn Marino   hashcode = iterative_hash_object (TYPE_HASH (value_type), hashcode);
7572e4b17023SJohn Marino   hashcode = type_hash_list (arg_types, hashcode);
7573e4b17023SJohn Marino   t = type_hash_canon (hashcode, t);
7574e4b17023SJohn Marino 
7575e4b17023SJohn Marino   /* Set up the canonical type. */
7576e4b17023SJohn Marino   any_structural_p   = TYPE_STRUCTURAL_EQUALITY_P (value_type);
7577e4b17023SJohn Marino   any_noncanonical_p = TYPE_CANONICAL (value_type) != value_type;
7578e4b17023SJohn Marino   canon_argtypes = maybe_canonicalize_argtypes (arg_types,
7579e4b17023SJohn Marino 						&any_structural_p,
7580e4b17023SJohn Marino 						&any_noncanonical_p);
7581e4b17023SJohn Marino   if (any_structural_p)
7582e4b17023SJohn Marino     SET_TYPE_STRUCTURAL_EQUALITY (t);
7583e4b17023SJohn Marino   else if (any_noncanonical_p)
7584e4b17023SJohn Marino     TYPE_CANONICAL (t) = build_function_type (TYPE_CANONICAL (value_type),
7585e4b17023SJohn Marino 					      canon_argtypes);
7586e4b17023SJohn Marino 
7587e4b17023SJohn Marino   if (!COMPLETE_TYPE_P (t))
7588e4b17023SJohn Marino     layout_type (t);
7589e4b17023SJohn Marino   return t;
7590e4b17023SJohn Marino }
7591e4b17023SJohn Marino 
7592e4b17023SJohn Marino /* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the
7593e4b17023SJohn Marino    return value if SKIP_RETURN is true.  */
7594e4b17023SJohn Marino 
7595e4b17023SJohn Marino static tree
build_function_type_skip_args(tree orig_type,bitmap args_to_skip,bool skip_return)7596e4b17023SJohn Marino build_function_type_skip_args (tree orig_type, bitmap args_to_skip,
7597e4b17023SJohn Marino 			       bool skip_return)
7598e4b17023SJohn Marino {
7599e4b17023SJohn Marino   tree new_type = NULL;
7600e4b17023SJohn Marino   tree args, new_args = NULL, t;
7601e4b17023SJohn Marino   tree new_reversed;
7602e4b17023SJohn Marino   int i = 0;
7603e4b17023SJohn Marino 
7604e4b17023SJohn Marino   for (args = TYPE_ARG_TYPES (orig_type); args && args != void_list_node;
7605e4b17023SJohn Marino        args = TREE_CHAIN (args), i++)
7606e4b17023SJohn Marino     if (!args_to_skip || !bitmap_bit_p (args_to_skip, i))
7607e4b17023SJohn Marino       new_args = tree_cons (NULL_TREE, TREE_VALUE (args), new_args);
7608e4b17023SJohn Marino 
7609e4b17023SJohn Marino   new_reversed = nreverse (new_args);
7610e4b17023SJohn Marino   if (args)
7611e4b17023SJohn Marino     {
7612e4b17023SJohn Marino       if (new_reversed)
7613e4b17023SJohn Marino         TREE_CHAIN (new_args) = void_list_node;
7614e4b17023SJohn Marino       else
7615e4b17023SJohn Marino 	new_reversed = void_list_node;
7616e4b17023SJohn Marino     }
7617e4b17023SJohn Marino 
7618e4b17023SJohn Marino   /* Use copy_node to preserve as much as possible from original type
7619e4b17023SJohn Marino      (debug info, attribute lists etc.)
7620e4b17023SJohn Marino      Exception is METHOD_TYPEs must have THIS argument.
7621e4b17023SJohn Marino      When we are asked to remove it, we need to build new FUNCTION_TYPE
7622e4b17023SJohn Marino      instead.  */
7623e4b17023SJohn Marino   if (TREE_CODE (orig_type) != METHOD_TYPE
7624e4b17023SJohn Marino       || !args_to_skip
7625e4b17023SJohn Marino       || !bitmap_bit_p (args_to_skip, 0))
7626e4b17023SJohn Marino     {
7627e4b17023SJohn Marino       new_type = build_distinct_type_copy (orig_type);
7628e4b17023SJohn Marino       TYPE_ARG_TYPES (new_type) = new_reversed;
7629e4b17023SJohn Marino     }
7630e4b17023SJohn Marino   else
7631e4b17023SJohn Marino     {
7632e4b17023SJohn Marino       new_type
7633e4b17023SJohn Marino         = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
7634e4b17023SJohn Marino 							 new_reversed));
7635e4b17023SJohn Marino       TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
7636e4b17023SJohn Marino     }
7637e4b17023SJohn Marino 
7638e4b17023SJohn Marino   if (skip_return)
7639e4b17023SJohn Marino     TREE_TYPE (new_type) = void_type_node;
7640e4b17023SJohn Marino 
7641e4b17023SJohn Marino   /* This is a new type, not a copy of an old type.  Need to reassociate
7642e4b17023SJohn Marino      variants.  We can handle everything except the main variant lazily.  */
7643e4b17023SJohn Marino   t = TYPE_MAIN_VARIANT (orig_type);
7644e4b17023SJohn Marino   if (t != orig_type)
7645e4b17023SJohn Marino     {
7646e4b17023SJohn Marino       t = build_function_type_skip_args (t, args_to_skip, skip_return);
7647e4b17023SJohn Marino       TYPE_MAIN_VARIANT (new_type) = t;
7648e4b17023SJohn Marino       TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t);
7649e4b17023SJohn Marino       TYPE_NEXT_VARIANT (t) = new_type;
7650e4b17023SJohn Marino     }
7651e4b17023SJohn Marino   else
7652e4b17023SJohn Marino     {
7653e4b17023SJohn Marino       TYPE_MAIN_VARIANT (new_type) = new_type;
7654e4b17023SJohn Marino       TYPE_NEXT_VARIANT (new_type) = NULL;
7655e4b17023SJohn Marino     }
7656e4b17023SJohn Marino 
7657e4b17023SJohn Marino   return new_type;
7658e4b17023SJohn Marino }
7659e4b17023SJohn Marino 
7660e4b17023SJohn Marino /* Build variant of function decl ORIG_DECL skipping ARGS_TO_SKIP and the
7661e4b17023SJohn Marino    return value if SKIP_RETURN is true.
7662e4b17023SJohn Marino 
7663e4b17023SJohn Marino    Arguments from DECL_ARGUMENTS list can't be removed now, since they are
7664e4b17023SJohn Marino    linked by TREE_CHAIN directly.  The caller is responsible for eliminating
7665e4b17023SJohn Marino    them when they are being duplicated (i.e. copy_arguments_for_versioning).  */
7666e4b17023SJohn Marino 
7667e4b17023SJohn Marino tree
build_function_decl_skip_args(tree orig_decl,bitmap args_to_skip,bool skip_return)7668e4b17023SJohn Marino build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip,
7669e4b17023SJohn Marino 			       bool skip_return)
7670e4b17023SJohn Marino {
7671e4b17023SJohn Marino   tree new_decl = copy_node (orig_decl);
7672e4b17023SJohn Marino   tree new_type;
7673e4b17023SJohn Marino 
7674e4b17023SJohn Marino   new_type = TREE_TYPE (orig_decl);
7675e4b17023SJohn Marino   if (prototype_p (new_type)
7676e4b17023SJohn Marino       || (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type))))
7677e4b17023SJohn Marino     new_type
7678e4b17023SJohn Marino       = build_function_type_skip_args (new_type, args_to_skip, skip_return);
7679e4b17023SJohn Marino   TREE_TYPE (new_decl) = new_type;
7680e4b17023SJohn Marino 
7681e4b17023SJohn Marino   /* For declarations setting DECL_VINDEX (i.e. methods)
7682e4b17023SJohn Marino      we expect first argument to be THIS pointer.   */
7683e4b17023SJohn Marino   if (args_to_skip && bitmap_bit_p (args_to_skip, 0))
7684e4b17023SJohn Marino     DECL_VINDEX (new_decl) = NULL_TREE;
7685e4b17023SJohn Marino 
7686e4b17023SJohn Marino   /* When signature changes, we need to clear builtin info.  */
7687e4b17023SJohn Marino   if (DECL_BUILT_IN (new_decl)
7688e4b17023SJohn Marino       && args_to_skip
7689e4b17023SJohn Marino       && !bitmap_empty_p (args_to_skip))
7690e4b17023SJohn Marino     {
7691e4b17023SJohn Marino       DECL_BUILT_IN_CLASS (new_decl) = NOT_BUILT_IN;
7692e4b17023SJohn Marino       DECL_FUNCTION_CODE (new_decl) = (enum built_in_function) 0;
7693e4b17023SJohn Marino     }
7694e4b17023SJohn Marino   return new_decl;
7695e4b17023SJohn Marino }
7696e4b17023SJohn Marino 
7697e4b17023SJohn Marino /* Build a function type.  The RETURN_TYPE is the type returned by the
7698e4b17023SJohn Marino    function.  If VAARGS is set, no void_type_node is appended to the
7699e4b17023SJohn Marino    the list.  ARGP must be always be terminated be a NULL_TREE.  */
7700e4b17023SJohn Marino 
7701e4b17023SJohn Marino static tree
build_function_type_list_1(bool vaargs,tree return_type,va_list argp)7702e4b17023SJohn Marino build_function_type_list_1 (bool vaargs, tree return_type, va_list argp)
7703e4b17023SJohn Marino {
7704e4b17023SJohn Marino   tree t, args, last;
7705e4b17023SJohn Marino 
7706e4b17023SJohn Marino   t = va_arg (argp, tree);
7707e4b17023SJohn Marino   for (args = NULL_TREE; t != NULL_TREE; t = va_arg (argp, tree))
7708e4b17023SJohn Marino     args = tree_cons (NULL_TREE, t, args);
7709e4b17023SJohn Marino 
7710e4b17023SJohn Marino   if (vaargs)
7711e4b17023SJohn Marino     {
7712e4b17023SJohn Marino       last = args;
7713e4b17023SJohn Marino       if (args != NULL_TREE)
7714e4b17023SJohn Marino 	args = nreverse (args);
7715e4b17023SJohn Marino       gcc_assert (last != void_list_node);
7716e4b17023SJohn Marino     }
7717e4b17023SJohn Marino   else if (args == NULL_TREE)
7718e4b17023SJohn Marino     args = void_list_node;
7719e4b17023SJohn Marino   else
7720e4b17023SJohn Marino     {
7721e4b17023SJohn Marino       last = args;
7722e4b17023SJohn Marino       args = nreverse (args);
7723e4b17023SJohn Marino       TREE_CHAIN (last) = void_list_node;
7724e4b17023SJohn Marino     }
7725e4b17023SJohn Marino   args = build_function_type (return_type, args);
7726e4b17023SJohn Marino 
7727e4b17023SJohn Marino   return args;
7728e4b17023SJohn Marino }
7729e4b17023SJohn Marino 
7730e4b17023SJohn Marino /* Build a function type.  The RETURN_TYPE is the type returned by the
7731e4b17023SJohn Marino    function.  If additional arguments are provided, they are
7732e4b17023SJohn Marino    additional argument types.  The list of argument types must always
7733e4b17023SJohn Marino    be terminated by NULL_TREE.  */
7734e4b17023SJohn Marino 
7735e4b17023SJohn Marino tree
build_function_type_list(tree return_type,...)7736e4b17023SJohn Marino build_function_type_list (tree return_type, ...)
7737e4b17023SJohn Marino {
7738e4b17023SJohn Marino   tree args;
7739e4b17023SJohn Marino   va_list p;
7740e4b17023SJohn Marino 
7741e4b17023SJohn Marino   va_start (p, return_type);
7742e4b17023SJohn Marino   args = build_function_type_list_1 (false, return_type, p);
7743e4b17023SJohn Marino   va_end (p);
7744e4b17023SJohn Marino   return args;
7745e4b17023SJohn Marino }
7746e4b17023SJohn Marino 
7747e4b17023SJohn Marino /* Build a variable argument function type.  The RETURN_TYPE is the
7748e4b17023SJohn Marino    type returned by the function.  If additional arguments are provided,
7749e4b17023SJohn Marino    they are additional argument types.  The list of argument types must
7750e4b17023SJohn Marino    always be terminated by NULL_TREE.  */
7751e4b17023SJohn Marino 
7752e4b17023SJohn Marino tree
build_varargs_function_type_list(tree return_type,...)7753e4b17023SJohn Marino build_varargs_function_type_list (tree return_type, ...)
7754e4b17023SJohn Marino {
7755e4b17023SJohn Marino   tree args;
7756e4b17023SJohn Marino   va_list p;
7757e4b17023SJohn Marino 
7758e4b17023SJohn Marino   va_start (p, return_type);
7759e4b17023SJohn Marino   args = build_function_type_list_1 (true, return_type, p);
7760e4b17023SJohn Marino   va_end (p);
7761e4b17023SJohn Marino 
7762e4b17023SJohn Marino   return args;
7763e4b17023SJohn Marino }
7764e4b17023SJohn Marino 
7765e4b17023SJohn Marino /* Build a function type.  RETURN_TYPE is the type returned by the
7766e4b17023SJohn Marino    function; VAARGS indicates whether the function takes varargs.  The
7767e4b17023SJohn Marino    function takes N named arguments, the types of which are provided in
7768e4b17023SJohn Marino    ARG_TYPES.  */
7769e4b17023SJohn Marino 
7770e4b17023SJohn Marino static tree
build_function_type_array_1(bool vaargs,tree return_type,int n,tree * arg_types)7771e4b17023SJohn Marino build_function_type_array_1 (bool vaargs, tree return_type, int n,
7772e4b17023SJohn Marino 			     tree *arg_types)
7773e4b17023SJohn Marino {
7774e4b17023SJohn Marino   int i;
7775e4b17023SJohn Marino   tree t = vaargs ? NULL_TREE : void_list_node;
7776e4b17023SJohn Marino 
7777e4b17023SJohn Marino   for (i = n - 1; i >= 0; i--)
7778e4b17023SJohn Marino     t = tree_cons (NULL_TREE, arg_types[i], t);
7779e4b17023SJohn Marino 
7780e4b17023SJohn Marino   return build_function_type (return_type, t);
7781e4b17023SJohn Marino }
7782e4b17023SJohn Marino 
7783e4b17023SJohn Marino /* Build a function type.  RETURN_TYPE is the type returned by the
7784e4b17023SJohn Marino    function.  The function takes N named arguments, the types of which
7785e4b17023SJohn Marino    are provided in ARG_TYPES.  */
7786e4b17023SJohn Marino 
7787e4b17023SJohn Marino tree
build_function_type_array(tree return_type,int n,tree * arg_types)7788e4b17023SJohn Marino build_function_type_array (tree return_type, int n, tree *arg_types)
7789e4b17023SJohn Marino {
7790e4b17023SJohn Marino   return build_function_type_array_1 (false, return_type, n, arg_types);
7791e4b17023SJohn Marino }
7792e4b17023SJohn Marino 
7793e4b17023SJohn Marino /* Build a variable argument function type.  RETURN_TYPE is the type
7794e4b17023SJohn Marino    returned by the function.  The function takes N named arguments, the
7795e4b17023SJohn Marino    types of which are provided in ARG_TYPES.  */
7796e4b17023SJohn Marino 
7797e4b17023SJohn Marino tree
build_varargs_function_type_array(tree return_type,int n,tree * arg_types)7798e4b17023SJohn Marino build_varargs_function_type_array (tree return_type, int n, tree *arg_types)
7799e4b17023SJohn Marino {
7800e4b17023SJohn Marino   return build_function_type_array_1 (true, return_type, n, arg_types);
7801e4b17023SJohn Marino }
7802e4b17023SJohn Marino 
7803e4b17023SJohn Marino /* Build a METHOD_TYPE for a member of BASETYPE.  The RETTYPE (a TYPE)
7804e4b17023SJohn Marino    and ARGTYPES (a TREE_LIST) are the return type and arguments types
7805e4b17023SJohn Marino    for the method.  An implicit additional parameter (of type
7806e4b17023SJohn Marino    pointer-to-BASETYPE) is added to the ARGTYPES.  */
7807e4b17023SJohn Marino 
7808e4b17023SJohn Marino tree
build_method_type_directly(tree basetype,tree rettype,tree argtypes)7809e4b17023SJohn Marino build_method_type_directly (tree basetype,
7810e4b17023SJohn Marino 			    tree rettype,
7811e4b17023SJohn Marino 			    tree argtypes)
7812e4b17023SJohn Marino {
7813e4b17023SJohn Marino   tree t;
7814e4b17023SJohn Marino   tree ptype;
7815e4b17023SJohn Marino   int hashcode = 0;
7816e4b17023SJohn Marino   bool any_structural_p, any_noncanonical_p;
7817e4b17023SJohn Marino   tree canon_argtypes;
7818e4b17023SJohn Marino 
7819e4b17023SJohn Marino   /* Make a node of the sort we want.  */
7820e4b17023SJohn Marino   t = make_node (METHOD_TYPE);
7821e4b17023SJohn Marino 
7822e4b17023SJohn Marino   TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
7823e4b17023SJohn Marino   TREE_TYPE (t) = rettype;
7824e4b17023SJohn Marino   ptype = build_pointer_type (basetype);
7825e4b17023SJohn Marino 
7826e4b17023SJohn Marino   /* The actual arglist for this function includes a "hidden" argument
7827e4b17023SJohn Marino      which is "this".  Put it into the list of argument types.  */
7828e4b17023SJohn Marino   argtypes = tree_cons (NULL_TREE, ptype, argtypes);
7829e4b17023SJohn Marino   TYPE_ARG_TYPES (t) = argtypes;
7830e4b17023SJohn Marino 
7831e4b17023SJohn Marino   /* If we already have such a type, use the old one.  */
7832e4b17023SJohn Marino   hashcode = iterative_hash_object (TYPE_HASH (basetype), hashcode);
7833e4b17023SJohn Marino   hashcode = iterative_hash_object (TYPE_HASH (rettype), hashcode);
7834e4b17023SJohn Marino   hashcode = type_hash_list (argtypes, hashcode);
7835e4b17023SJohn Marino   t = type_hash_canon (hashcode, t);
7836e4b17023SJohn Marino 
7837e4b17023SJohn Marino   /* Set up the canonical type. */
7838e4b17023SJohn Marino   any_structural_p
7839e4b17023SJohn Marino     = (TYPE_STRUCTURAL_EQUALITY_P (basetype)
7840e4b17023SJohn Marino        || TYPE_STRUCTURAL_EQUALITY_P (rettype));
7841e4b17023SJohn Marino   any_noncanonical_p
7842e4b17023SJohn Marino     = (TYPE_CANONICAL (basetype) != basetype
7843e4b17023SJohn Marino        || TYPE_CANONICAL (rettype) != rettype);
7844e4b17023SJohn Marino   canon_argtypes = maybe_canonicalize_argtypes (TREE_CHAIN (argtypes),
7845e4b17023SJohn Marino 						&any_structural_p,
7846e4b17023SJohn Marino 						&any_noncanonical_p);
7847e4b17023SJohn Marino   if (any_structural_p)
7848e4b17023SJohn Marino     SET_TYPE_STRUCTURAL_EQUALITY (t);
7849e4b17023SJohn Marino   else if (any_noncanonical_p)
7850e4b17023SJohn Marino     TYPE_CANONICAL (t)
7851e4b17023SJohn Marino       = build_method_type_directly (TYPE_CANONICAL (basetype),
7852e4b17023SJohn Marino 				    TYPE_CANONICAL (rettype),
7853e4b17023SJohn Marino 				    canon_argtypes);
7854e4b17023SJohn Marino   if (!COMPLETE_TYPE_P (t))
7855e4b17023SJohn Marino     layout_type (t);
7856e4b17023SJohn Marino 
7857e4b17023SJohn Marino   return t;
7858e4b17023SJohn Marino }
7859e4b17023SJohn Marino 
7860e4b17023SJohn Marino /* Construct, lay out and return the type of methods belonging to class
7861e4b17023SJohn Marino    BASETYPE and whose arguments and values are described by TYPE.
7862e4b17023SJohn Marino    If that type exists already, reuse it.
7863e4b17023SJohn Marino    TYPE must be a FUNCTION_TYPE node.  */
7864e4b17023SJohn Marino 
7865e4b17023SJohn Marino tree
build_method_type(tree basetype,tree type)7866e4b17023SJohn Marino build_method_type (tree basetype, tree type)
7867e4b17023SJohn Marino {
7868e4b17023SJohn Marino   gcc_assert (TREE_CODE (type) == FUNCTION_TYPE);
7869e4b17023SJohn Marino 
7870e4b17023SJohn Marino   return build_method_type_directly (basetype,
7871e4b17023SJohn Marino 				     TREE_TYPE (type),
7872e4b17023SJohn Marino 				     TYPE_ARG_TYPES (type));
7873e4b17023SJohn Marino }
7874e4b17023SJohn Marino 
7875e4b17023SJohn Marino /* Construct, lay out and return the type of offsets to a value
7876e4b17023SJohn Marino    of type TYPE, within an object of type BASETYPE.
7877e4b17023SJohn Marino    If a suitable offset type exists already, reuse it.  */
7878e4b17023SJohn Marino 
7879e4b17023SJohn Marino tree
build_offset_type(tree basetype,tree type)7880e4b17023SJohn Marino build_offset_type (tree basetype, tree type)
7881e4b17023SJohn Marino {
7882e4b17023SJohn Marino   tree t;
7883e4b17023SJohn Marino   hashval_t hashcode = 0;
7884e4b17023SJohn Marino 
7885e4b17023SJohn Marino   /* Make a node of the sort we want.  */
7886e4b17023SJohn Marino   t = make_node (OFFSET_TYPE);
7887e4b17023SJohn Marino 
7888e4b17023SJohn Marino   TYPE_OFFSET_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
7889e4b17023SJohn Marino   TREE_TYPE (t) = type;
7890e4b17023SJohn Marino 
7891e4b17023SJohn Marino   /* If we already have such a type, use the old one.  */
7892e4b17023SJohn Marino   hashcode = iterative_hash_object (TYPE_HASH (basetype), hashcode);
7893e4b17023SJohn Marino   hashcode = iterative_hash_object (TYPE_HASH (type), hashcode);
7894e4b17023SJohn Marino   t = type_hash_canon (hashcode, t);
7895e4b17023SJohn Marino 
7896e4b17023SJohn Marino   if (!COMPLETE_TYPE_P (t))
7897e4b17023SJohn Marino     layout_type (t);
7898e4b17023SJohn Marino 
7899e4b17023SJohn Marino   if (TYPE_CANONICAL (t) == t)
7900e4b17023SJohn Marino     {
7901e4b17023SJohn Marino       if (TYPE_STRUCTURAL_EQUALITY_P (basetype)
7902e4b17023SJohn Marino 	  || TYPE_STRUCTURAL_EQUALITY_P (type))
7903e4b17023SJohn Marino 	SET_TYPE_STRUCTURAL_EQUALITY (t);
7904e4b17023SJohn Marino       else if (TYPE_CANONICAL (TYPE_MAIN_VARIANT (basetype)) != basetype
7905e4b17023SJohn Marino 	       || TYPE_CANONICAL (type) != type)
7906e4b17023SJohn Marino 	TYPE_CANONICAL (t)
7907e4b17023SJohn Marino 	  = build_offset_type (TYPE_CANONICAL (TYPE_MAIN_VARIANT (basetype)),
7908e4b17023SJohn Marino 			       TYPE_CANONICAL (type));
7909e4b17023SJohn Marino     }
7910e4b17023SJohn Marino 
7911e4b17023SJohn Marino   return t;
7912e4b17023SJohn Marino }
7913e4b17023SJohn Marino 
7914e4b17023SJohn Marino /* Create a complex type whose components are COMPONENT_TYPE.  */
7915e4b17023SJohn Marino 
7916e4b17023SJohn Marino tree
build_complex_type(tree component_type)7917e4b17023SJohn Marino build_complex_type (tree component_type)
7918e4b17023SJohn Marino {
7919e4b17023SJohn Marino   tree t;
7920e4b17023SJohn Marino   hashval_t hashcode;
7921e4b17023SJohn Marino 
7922e4b17023SJohn Marino   gcc_assert (INTEGRAL_TYPE_P (component_type)
7923e4b17023SJohn Marino 	      || SCALAR_FLOAT_TYPE_P (component_type)
7924e4b17023SJohn Marino 	      || FIXED_POINT_TYPE_P (component_type));
7925e4b17023SJohn Marino 
7926e4b17023SJohn Marino   /* Make a node of the sort we want.  */
7927e4b17023SJohn Marino   t = make_node (COMPLEX_TYPE);
7928e4b17023SJohn Marino 
7929e4b17023SJohn Marino   TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type);
7930e4b17023SJohn Marino 
7931e4b17023SJohn Marino   /* If we already have such a type, use the old one.  */
7932e4b17023SJohn Marino   hashcode = iterative_hash_object (TYPE_HASH (component_type), 0);
7933e4b17023SJohn Marino   t = type_hash_canon (hashcode, t);
7934e4b17023SJohn Marino 
7935e4b17023SJohn Marino   if (!COMPLETE_TYPE_P (t))
7936e4b17023SJohn Marino     layout_type (t);
7937e4b17023SJohn Marino 
7938e4b17023SJohn Marino   if (TYPE_CANONICAL (t) == t)
7939e4b17023SJohn Marino     {
7940e4b17023SJohn Marino       if (TYPE_STRUCTURAL_EQUALITY_P (component_type))
7941e4b17023SJohn Marino 	SET_TYPE_STRUCTURAL_EQUALITY (t);
7942e4b17023SJohn Marino       else if (TYPE_CANONICAL (component_type) != component_type)
7943e4b17023SJohn Marino 	TYPE_CANONICAL (t)
7944e4b17023SJohn Marino 	  = build_complex_type (TYPE_CANONICAL (component_type));
7945e4b17023SJohn Marino     }
7946e4b17023SJohn Marino 
7947e4b17023SJohn Marino   /* We need to create a name, since complex is a fundamental type.  */
7948e4b17023SJohn Marino   if (! TYPE_NAME (t))
7949e4b17023SJohn Marino     {
7950e4b17023SJohn Marino       const char *name;
7951e4b17023SJohn Marino       if (component_type == char_type_node)
7952e4b17023SJohn Marino 	name = "complex char";
7953e4b17023SJohn Marino       else if (component_type == signed_char_type_node)
7954e4b17023SJohn Marino 	name = "complex signed char";
7955e4b17023SJohn Marino       else if (component_type == unsigned_char_type_node)
7956e4b17023SJohn Marino 	name = "complex unsigned char";
7957e4b17023SJohn Marino       else if (component_type == short_integer_type_node)
7958e4b17023SJohn Marino 	name = "complex short int";
7959e4b17023SJohn Marino       else if (component_type == short_unsigned_type_node)
7960e4b17023SJohn Marino 	name = "complex short unsigned int";
7961e4b17023SJohn Marino       else if (component_type == integer_type_node)
7962e4b17023SJohn Marino 	name = "complex int";
7963e4b17023SJohn Marino       else if (component_type == unsigned_type_node)
7964e4b17023SJohn Marino 	name = "complex unsigned int";
7965e4b17023SJohn Marino       else if (component_type == long_integer_type_node)
7966e4b17023SJohn Marino 	name = "complex long int";
7967e4b17023SJohn Marino       else if (component_type == long_unsigned_type_node)
7968e4b17023SJohn Marino 	name = "complex long unsigned int";
7969e4b17023SJohn Marino       else if (component_type == long_long_integer_type_node)
7970e4b17023SJohn Marino 	name = "complex long long int";
7971e4b17023SJohn Marino       else if (component_type == long_long_unsigned_type_node)
7972e4b17023SJohn Marino 	name = "complex long long unsigned int";
7973e4b17023SJohn Marino       else
7974e4b17023SJohn Marino 	name = 0;
7975e4b17023SJohn Marino 
7976e4b17023SJohn Marino       if (name != 0)
7977e4b17023SJohn Marino 	TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
7978e4b17023SJohn Marino 	    			    get_identifier (name), t);
7979e4b17023SJohn Marino     }
7980e4b17023SJohn Marino 
7981e4b17023SJohn Marino   return build_qualified_type (t, TYPE_QUALS (component_type));
7982e4b17023SJohn Marino }
7983e4b17023SJohn Marino 
7984e4b17023SJohn Marino /* If TYPE is a real or complex floating-point type and the target
7985e4b17023SJohn Marino    does not directly support arithmetic on TYPE then return the wider
7986e4b17023SJohn Marino    type to be used for arithmetic on TYPE.  Otherwise, return
7987e4b17023SJohn Marino    NULL_TREE.  */
7988e4b17023SJohn Marino 
7989e4b17023SJohn Marino tree
excess_precision_type(tree type)7990e4b17023SJohn Marino excess_precision_type (tree type)
7991e4b17023SJohn Marino {
7992e4b17023SJohn Marino   if (flag_excess_precision != EXCESS_PRECISION_FAST)
7993e4b17023SJohn Marino     {
7994e4b17023SJohn Marino       int flt_eval_method = TARGET_FLT_EVAL_METHOD;
7995e4b17023SJohn Marino       switch (TREE_CODE (type))
7996e4b17023SJohn Marino 	{
7997e4b17023SJohn Marino 	case REAL_TYPE:
7998e4b17023SJohn Marino 	  switch (flt_eval_method)
7999e4b17023SJohn Marino 	    {
8000e4b17023SJohn Marino 	    case 1:
8001e4b17023SJohn Marino 	      if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
8002e4b17023SJohn Marino 		return double_type_node;
8003e4b17023SJohn Marino 	      break;
8004e4b17023SJohn Marino 	    case 2:
8005e4b17023SJohn Marino 	      if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
8006e4b17023SJohn Marino 		  || TYPE_MODE (type) == TYPE_MODE (double_type_node))
8007e4b17023SJohn Marino 		return long_double_type_node;
8008e4b17023SJohn Marino 	      break;
8009e4b17023SJohn Marino 	    default:
8010e4b17023SJohn Marino 	      gcc_unreachable ();
8011e4b17023SJohn Marino 	    }
8012e4b17023SJohn Marino 	  break;
8013e4b17023SJohn Marino 	case COMPLEX_TYPE:
8014e4b17023SJohn Marino 	  if (TREE_CODE (TREE_TYPE (type)) != REAL_TYPE)
8015e4b17023SJohn Marino 	    return NULL_TREE;
8016e4b17023SJohn Marino 	  switch (flt_eval_method)
8017e4b17023SJohn Marino 	    {
8018e4b17023SJohn Marino 	    case 1:
8019e4b17023SJohn Marino 	      if (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (float_type_node))
8020e4b17023SJohn Marino 		return complex_double_type_node;
8021e4b17023SJohn Marino 	      break;
8022e4b17023SJohn Marino 	    case 2:
8023e4b17023SJohn Marino 	      if (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (float_type_node)
8024e4b17023SJohn Marino 		  || (TYPE_MODE (TREE_TYPE (type))
8025e4b17023SJohn Marino 		      == TYPE_MODE (double_type_node)))
8026e4b17023SJohn Marino 		return complex_long_double_type_node;
8027e4b17023SJohn Marino 	      break;
8028e4b17023SJohn Marino 	    default:
8029e4b17023SJohn Marino 	      gcc_unreachable ();
8030e4b17023SJohn Marino 	    }
8031e4b17023SJohn Marino 	  break;
8032e4b17023SJohn Marino 	default:
8033e4b17023SJohn Marino 	  break;
8034e4b17023SJohn Marino 	}
8035e4b17023SJohn Marino     }
8036e4b17023SJohn Marino   return NULL_TREE;
8037e4b17023SJohn Marino }
8038e4b17023SJohn Marino 
8039e4b17023SJohn Marino /* Return OP, stripped of any conversions to wider types as much as is safe.
8040e4b17023SJohn Marino    Converting the value back to OP's type makes a value equivalent to OP.
8041e4b17023SJohn Marino 
8042e4b17023SJohn Marino    If FOR_TYPE is nonzero, we return a value which, if converted to
8043e4b17023SJohn Marino    type FOR_TYPE, would be equivalent to converting OP to type FOR_TYPE.
8044e4b17023SJohn Marino 
8045e4b17023SJohn Marino    OP must have integer, real or enumeral type.  Pointers are not allowed!
8046e4b17023SJohn Marino 
8047e4b17023SJohn Marino    There are some cases where the obvious value we could return
8048e4b17023SJohn Marino    would regenerate to OP if converted to OP's type,
8049e4b17023SJohn Marino    but would not extend like OP to wider types.
8050e4b17023SJohn Marino    If FOR_TYPE indicates such extension is contemplated, we eschew such values.
8051e4b17023SJohn Marino    For example, if OP is (unsigned short)(signed char)-1,
8052e4b17023SJohn Marino    we avoid returning (signed char)-1 if FOR_TYPE is int,
8053e4b17023SJohn Marino    even though extending that to an unsigned short would regenerate OP,
8054e4b17023SJohn Marino    since the result of extending (signed char)-1 to (int)
8055e4b17023SJohn Marino    is different from (int) OP.  */
8056e4b17023SJohn Marino 
8057e4b17023SJohn Marino tree
get_unwidened(tree op,tree for_type)8058e4b17023SJohn Marino get_unwidened (tree op, tree for_type)
8059e4b17023SJohn Marino {
8060e4b17023SJohn Marino   /* Set UNS initially if converting OP to FOR_TYPE is a zero-extension.  */
8061e4b17023SJohn Marino   tree type = TREE_TYPE (op);
8062e4b17023SJohn Marino   unsigned final_prec
8063e4b17023SJohn Marino     = TYPE_PRECISION (for_type != 0 ? for_type : type);
8064e4b17023SJohn Marino   int uns
8065e4b17023SJohn Marino     = (for_type != 0 && for_type != type
8066e4b17023SJohn Marino        && final_prec > TYPE_PRECISION (type)
8067e4b17023SJohn Marino        && TYPE_UNSIGNED (type));
8068e4b17023SJohn Marino   tree win = op;
8069e4b17023SJohn Marino 
8070e4b17023SJohn Marino   while (CONVERT_EXPR_P (op))
8071e4b17023SJohn Marino     {
8072e4b17023SJohn Marino       int bitschange;
8073e4b17023SJohn Marino 
8074e4b17023SJohn Marino       /* TYPE_PRECISION on vector types has different meaning
8075e4b17023SJohn Marino 	 (TYPE_VECTOR_SUBPARTS) and casts from vectors are view conversions,
8076e4b17023SJohn Marino 	 so avoid them here.  */
8077e4b17023SJohn Marino       if (TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == VECTOR_TYPE)
8078e4b17023SJohn Marino 	break;
8079e4b17023SJohn Marino 
8080e4b17023SJohn Marino       bitschange = TYPE_PRECISION (TREE_TYPE (op))
8081e4b17023SJohn Marino 		   - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0)));
8082e4b17023SJohn Marino 
8083e4b17023SJohn Marino       /* Truncations are many-one so cannot be removed.
8084e4b17023SJohn Marino 	 Unless we are later going to truncate down even farther.  */
8085e4b17023SJohn Marino       if (bitschange < 0
8086e4b17023SJohn Marino 	  && final_prec > TYPE_PRECISION (TREE_TYPE (op)))
8087e4b17023SJohn Marino 	break;
8088e4b17023SJohn Marino 
8089e4b17023SJohn Marino       /* See what's inside this conversion.  If we decide to strip it,
8090e4b17023SJohn Marino 	 we will set WIN.  */
8091e4b17023SJohn Marino       op = TREE_OPERAND (op, 0);
8092e4b17023SJohn Marino 
8093e4b17023SJohn Marino       /* If we have not stripped any zero-extensions (uns is 0),
8094e4b17023SJohn Marino 	 we can strip any kind of extension.
8095e4b17023SJohn Marino 	 If we have previously stripped a zero-extension,
8096e4b17023SJohn Marino 	 only zero-extensions can safely be stripped.
8097e4b17023SJohn Marino 	 Any extension can be stripped if the bits it would produce
8098e4b17023SJohn Marino 	 are all going to be discarded later by truncating to FOR_TYPE.  */
8099e4b17023SJohn Marino 
8100e4b17023SJohn Marino       if (bitschange > 0)
8101e4b17023SJohn Marino 	{
8102e4b17023SJohn Marino 	  if (! uns || final_prec <= TYPE_PRECISION (TREE_TYPE (op)))
8103e4b17023SJohn Marino 	    win = op;
8104e4b17023SJohn Marino 	  /* TYPE_UNSIGNED says whether this is a zero-extension.
8105e4b17023SJohn Marino 	     Let's avoid computing it if it does not affect WIN
8106e4b17023SJohn Marino 	     and if UNS will not be needed again.  */
8107e4b17023SJohn Marino 	  if ((uns
8108e4b17023SJohn Marino 	       || CONVERT_EXPR_P (op))
8109e4b17023SJohn Marino 	      && TYPE_UNSIGNED (TREE_TYPE (op)))
8110e4b17023SJohn Marino 	    {
8111e4b17023SJohn Marino 	      uns = 1;
8112e4b17023SJohn Marino 	      win = op;
8113e4b17023SJohn Marino 	    }
8114e4b17023SJohn Marino 	}
8115e4b17023SJohn Marino     }
8116e4b17023SJohn Marino 
8117e4b17023SJohn Marino   /* If we finally reach a constant see if it fits in for_type and
8118e4b17023SJohn Marino      in that case convert it.  */
8119e4b17023SJohn Marino   if (for_type
8120e4b17023SJohn Marino       && TREE_CODE (win) == INTEGER_CST
8121e4b17023SJohn Marino       && TREE_TYPE (win) != for_type
8122e4b17023SJohn Marino       && int_fits_type_p (win, for_type))
8123e4b17023SJohn Marino     win = fold_convert (for_type, win);
8124e4b17023SJohn Marino 
8125e4b17023SJohn Marino   return win;
8126e4b17023SJohn Marino }
8127e4b17023SJohn Marino 
8128e4b17023SJohn Marino /* Return OP or a simpler expression for a narrower value
8129e4b17023SJohn Marino    which can be sign-extended or zero-extended to give back OP.
8130e4b17023SJohn Marino    Store in *UNSIGNEDP_PTR either 1 if the value should be zero-extended
8131e4b17023SJohn Marino    or 0 if the value should be sign-extended.  */
8132e4b17023SJohn Marino 
8133e4b17023SJohn Marino tree
get_narrower(tree op,int * unsignedp_ptr)8134e4b17023SJohn Marino get_narrower (tree op, int *unsignedp_ptr)
8135e4b17023SJohn Marino {
8136e4b17023SJohn Marino   int uns = 0;
8137e4b17023SJohn Marino   int first = 1;
8138e4b17023SJohn Marino   tree win = op;
8139e4b17023SJohn Marino   bool integral_p = INTEGRAL_TYPE_P (TREE_TYPE (op));
8140e4b17023SJohn Marino 
8141e4b17023SJohn Marino   while (TREE_CODE (op) == NOP_EXPR)
8142e4b17023SJohn Marino     {
8143e4b17023SJohn Marino       int bitschange
8144e4b17023SJohn Marino 	= (TYPE_PRECISION (TREE_TYPE (op))
8145e4b17023SJohn Marino 	   - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0))));
8146e4b17023SJohn Marino 
8147e4b17023SJohn Marino       /* Truncations are many-one so cannot be removed.  */
8148e4b17023SJohn Marino       if (bitschange < 0)
8149e4b17023SJohn Marino 	break;
8150e4b17023SJohn Marino 
8151e4b17023SJohn Marino       /* See what's inside this conversion.  If we decide to strip it,
8152e4b17023SJohn Marino 	 we will set WIN.  */
8153e4b17023SJohn Marino 
8154e4b17023SJohn Marino       if (bitschange > 0)
8155e4b17023SJohn Marino 	{
8156e4b17023SJohn Marino 	  op = TREE_OPERAND (op, 0);
8157e4b17023SJohn Marino 	  /* An extension: the outermost one can be stripped,
8158e4b17023SJohn Marino 	     but remember whether it is zero or sign extension.  */
8159e4b17023SJohn Marino 	  if (first)
8160e4b17023SJohn Marino 	    uns = TYPE_UNSIGNED (TREE_TYPE (op));
8161e4b17023SJohn Marino 	  /* Otherwise, if a sign extension has been stripped,
8162e4b17023SJohn Marino 	     only sign extensions can now be stripped;
8163e4b17023SJohn Marino 	     if a zero extension has been stripped, only zero-extensions.  */
8164e4b17023SJohn Marino 	  else if (uns != TYPE_UNSIGNED (TREE_TYPE (op)))
8165e4b17023SJohn Marino 	    break;
8166e4b17023SJohn Marino 	  first = 0;
8167e4b17023SJohn Marino 	}
8168e4b17023SJohn Marino       else /* bitschange == 0 */
8169e4b17023SJohn Marino 	{
8170e4b17023SJohn Marino 	  /* A change in nominal type can always be stripped, but we must
8171e4b17023SJohn Marino 	     preserve the unsignedness.  */
8172e4b17023SJohn Marino 	  if (first)
8173e4b17023SJohn Marino 	    uns = TYPE_UNSIGNED (TREE_TYPE (op));
8174e4b17023SJohn Marino 	  first = 0;
8175e4b17023SJohn Marino 	  op = TREE_OPERAND (op, 0);
8176e4b17023SJohn Marino 	  /* Keep trying to narrow, but don't assign op to win if it
8177e4b17023SJohn Marino 	     would turn an integral type into something else.  */
8178e4b17023SJohn Marino 	  if (INTEGRAL_TYPE_P (TREE_TYPE (op)) != integral_p)
8179e4b17023SJohn Marino 	    continue;
8180e4b17023SJohn Marino 	}
8181e4b17023SJohn Marino 
8182e4b17023SJohn Marino       win = op;
8183e4b17023SJohn Marino     }
8184e4b17023SJohn Marino 
8185e4b17023SJohn Marino   if (TREE_CODE (op) == COMPONENT_REF
8186e4b17023SJohn Marino       /* Since type_for_size always gives an integer type.  */
8187e4b17023SJohn Marino       && TREE_CODE (TREE_TYPE (op)) != REAL_TYPE
8188e4b17023SJohn Marino       && TREE_CODE (TREE_TYPE (op)) != FIXED_POINT_TYPE
8189e4b17023SJohn Marino       /* Ensure field is laid out already.  */
8190e4b17023SJohn Marino       && DECL_SIZE (TREE_OPERAND (op, 1)) != 0
8191e4b17023SJohn Marino       && host_integerp (DECL_SIZE (TREE_OPERAND (op, 1)), 1))
8192e4b17023SJohn Marino     {
8193e4b17023SJohn Marino       unsigned HOST_WIDE_INT innerprec
8194e4b17023SJohn Marino 	= tree_low_cst (DECL_SIZE (TREE_OPERAND (op, 1)), 1);
8195e4b17023SJohn Marino       int unsignedp = (DECL_UNSIGNED (TREE_OPERAND (op, 1))
8196e4b17023SJohn Marino 		       || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 1))));
8197e4b17023SJohn Marino       tree type = lang_hooks.types.type_for_size (innerprec, unsignedp);
8198e4b17023SJohn Marino 
8199e4b17023SJohn Marino       /* We can get this structure field in a narrower type that fits it,
8200e4b17023SJohn Marino 	 but the resulting extension to its nominal type (a fullword type)
8201e4b17023SJohn Marino 	 must satisfy the same conditions as for other extensions.
8202e4b17023SJohn Marino 
8203e4b17023SJohn Marino 	 Do this only for fields that are aligned (not bit-fields),
8204e4b17023SJohn Marino 	 because when bit-field insns will be used there is no
8205e4b17023SJohn Marino 	 advantage in doing this.  */
8206e4b17023SJohn Marino 
8207e4b17023SJohn Marino       if (innerprec < TYPE_PRECISION (TREE_TYPE (op))
8208e4b17023SJohn Marino 	  && ! DECL_BIT_FIELD (TREE_OPERAND (op, 1))
8209e4b17023SJohn Marino 	  && (first || uns == DECL_UNSIGNED (TREE_OPERAND (op, 1)))
8210e4b17023SJohn Marino 	  && type != 0)
8211e4b17023SJohn Marino 	{
8212e4b17023SJohn Marino 	  if (first)
8213e4b17023SJohn Marino 	    uns = DECL_UNSIGNED (TREE_OPERAND (op, 1));
8214e4b17023SJohn Marino 	  win = fold_convert (type, op);
8215e4b17023SJohn Marino 	}
8216e4b17023SJohn Marino     }
8217e4b17023SJohn Marino 
8218e4b17023SJohn Marino   *unsignedp_ptr = uns;
8219e4b17023SJohn Marino   return win;
8220e4b17023SJohn Marino }
8221e4b17023SJohn Marino 
8222e4b17023SJohn Marino /* Returns true if integer constant C has a value that is permissible
8223e4b17023SJohn Marino    for type TYPE (an INTEGER_TYPE).  */
8224e4b17023SJohn Marino 
8225e4b17023SJohn Marino bool
int_fits_type_p(const_tree c,const_tree type)8226e4b17023SJohn Marino int_fits_type_p (const_tree c, const_tree type)
8227e4b17023SJohn Marino {
8228e4b17023SJohn Marino   tree type_low_bound, type_high_bound;
8229e4b17023SJohn Marino   bool ok_for_low_bound, ok_for_high_bound, unsc;
8230e4b17023SJohn Marino   double_int dc, dd;
8231e4b17023SJohn Marino 
8232e4b17023SJohn Marino   dc = tree_to_double_int (c);
8233e4b17023SJohn Marino   unsc = TYPE_UNSIGNED (TREE_TYPE (c));
8234e4b17023SJohn Marino 
8235e4b17023SJohn Marino   if (TREE_CODE (TREE_TYPE (c)) == INTEGER_TYPE
8236e4b17023SJohn Marino       && TYPE_IS_SIZETYPE (TREE_TYPE (c))
8237e4b17023SJohn Marino       && unsc)
8238e4b17023SJohn Marino     /* So c is an unsigned integer whose type is sizetype and type is not.
8239e4b17023SJohn Marino        sizetype'd integers are sign extended even though they are
8240e4b17023SJohn Marino        unsigned. If the integer value fits in the lower end word of c,
8241e4b17023SJohn Marino        and if the higher end word has all its bits set to 1, that
8242e4b17023SJohn Marino        means the higher end bits are set to 1 only for sign extension.
8243e4b17023SJohn Marino        So let's convert c into an equivalent zero extended unsigned
8244e4b17023SJohn Marino        integer.  */
8245e4b17023SJohn Marino     dc = double_int_zext (dc, TYPE_PRECISION (TREE_TYPE (c)));
8246e4b17023SJohn Marino 
8247e4b17023SJohn Marino retry:
8248e4b17023SJohn Marino   type_low_bound = TYPE_MIN_VALUE (type);
8249e4b17023SJohn Marino   type_high_bound = TYPE_MAX_VALUE (type);
8250e4b17023SJohn Marino 
8251e4b17023SJohn Marino   /* If at least one bound of the type is a constant integer, we can check
8252e4b17023SJohn Marino      ourselves and maybe make a decision. If no such decision is possible, but
8253e4b17023SJohn Marino      this type is a subtype, try checking against that.  Otherwise, use
8254e4b17023SJohn Marino      double_int_fits_to_tree_p, which checks against the precision.
8255e4b17023SJohn Marino 
8256e4b17023SJohn Marino      Compute the status for each possibly constant bound, and return if we see
8257e4b17023SJohn Marino      one does not match. Use ok_for_xxx_bound for this purpose, assigning -1
8258e4b17023SJohn Marino      for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
8259e4b17023SJohn Marino      for "constant known to fit".  */
8260e4b17023SJohn Marino 
8261e4b17023SJohn Marino   /* Check if c >= type_low_bound.  */
8262e4b17023SJohn Marino   if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
8263e4b17023SJohn Marino     {
8264e4b17023SJohn Marino       dd = tree_to_double_int (type_low_bound);
8265e4b17023SJohn Marino       if (TREE_CODE (type) == INTEGER_TYPE
8266e4b17023SJohn Marino 	  && TYPE_IS_SIZETYPE (type)
8267e4b17023SJohn Marino 	  && TYPE_UNSIGNED (type))
8268e4b17023SJohn Marino 	dd = double_int_zext (dd, TYPE_PRECISION (type));
8269e4b17023SJohn Marino       if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_low_bound)))
8270e4b17023SJohn Marino 	{
8271e4b17023SJohn Marino 	  int c_neg = (!unsc && double_int_negative_p (dc));
8272e4b17023SJohn Marino 	  int t_neg = (unsc && double_int_negative_p (dd));
8273e4b17023SJohn Marino 
8274e4b17023SJohn Marino 	  if (c_neg && !t_neg)
8275e4b17023SJohn Marino 	    return false;
8276e4b17023SJohn Marino 	  if ((c_neg || !t_neg) && double_int_ucmp (dc, dd) < 0)
8277e4b17023SJohn Marino 	    return false;
8278e4b17023SJohn Marino 	}
8279e4b17023SJohn Marino       else if (double_int_cmp (dc, dd, unsc) < 0)
8280e4b17023SJohn Marino 	return false;
8281e4b17023SJohn Marino       ok_for_low_bound = true;
8282e4b17023SJohn Marino     }
8283e4b17023SJohn Marino   else
8284e4b17023SJohn Marino     ok_for_low_bound = false;
8285e4b17023SJohn Marino 
8286e4b17023SJohn Marino   /* Check if c <= type_high_bound.  */
8287e4b17023SJohn Marino   if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
8288e4b17023SJohn Marino     {
8289e4b17023SJohn Marino       dd = tree_to_double_int (type_high_bound);
8290e4b17023SJohn Marino       if (TREE_CODE (type) == INTEGER_TYPE
8291e4b17023SJohn Marino 	  && TYPE_IS_SIZETYPE (type)
8292e4b17023SJohn Marino 	  && TYPE_UNSIGNED (type))
8293e4b17023SJohn Marino 	dd = double_int_zext (dd, TYPE_PRECISION (type));
8294e4b17023SJohn Marino       if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_high_bound)))
8295e4b17023SJohn Marino 	{
8296e4b17023SJohn Marino 	  int c_neg = (!unsc && double_int_negative_p (dc));
8297e4b17023SJohn Marino 	  int t_neg = (unsc && double_int_negative_p (dd));
8298e4b17023SJohn Marino 
8299e4b17023SJohn Marino 	  if (t_neg && !c_neg)
8300e4b17023SJohn Marino 	    return false;
8301e4b17023SJohn Marino 	  if ((t_neg || !c_neg) && double_int_ucmp (dc, dd) > 0)
8302e4b17023SJohn Marino 	    return false;
8303e4b17023SJohn Marino 	}
8304e4b17023SJohn Marino       else if (double_int_cmp (dc, dd, unsc) > 0)
8305e4b17023SJohn Marino 	return false;
8306e4b17023SJohn Marino       ok_for_high_bound = true;
8307e4b17023SJohn Marino     }
8308e4b17023SJohn Marino   else
8309e4b17023SJohn Marino     ok_for_high_bound = false;
8310e4b17023SJohn Marino 
8311e4b17023SJohn Marino   /* If the constant fits both bounds, the result is known.  */
8312e4b17023SJohn Marino   if (ok_for_low_bound && ok_for_high_bound)
8313e4b17023SJohn Marino     return true;
8314e4b17023SJohn Marino 
8315e4b17023SJohn Marino   /* Perform some generic filtering which may allow making a decision
8316e4b17023SJohn Marino      even if the bounds are not constant.  First, negative integers
8317e4b17023SJohn Marino      never fit in unsigned types, */
8318e4b17023SJohn Marino   if (TYPE_UNSIGNED (type) && !unsc && double_int_negative_p (dc))
8319e4b17023SJohn Marino     return false;
8320e4b17023SJohn Marino 
8321e4b17023SJohn Marino   /* Second, narrower types always fit in wider ones.  */
8322e4b17023SJohn Marino   if (TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (c)))
8323e4b17023SJohn Marino     return true;
8324e4b17023SJohn Marino 
8325e4b17023SJohn Marino   /* Third, unsigned integers with top bit set never fit signed types.  */
8326e4b17023SJohn Marino   if (! TYPE_UNSIGNED (type) && unsc)
8327e4b17023SJohn Marino     {
8328e4b17023SJohn Marino       int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (c))) - 1;
8329e4b17023SJohn Marino       if (prec < HOST_BITS_PER_WIDE_INT)
8330e4b17023SJohn Marino 	{
8331e4b17023SJohn Marino 	  if (((((unsigned HOST_WIDE_INT) 1) << prec) & dc.low) != 0)
8332e4b17023SJohn Marino 	    return false;
8333e4b17023SJohn Marino         }
8334e4b17023SJohn Marino       else if (((((unsigned HOST_WIDE_INT) 1)
8335e4b17023SJohn Marino 		 << (prec - HOST_BITS_PER_WIDE_INT)) & dc.high) != 0)
8336e4b17023SJohn Marino 	return false;
8337e4b17023SJohn Marino     }
8338e4b17023SJohn Marino 
8339e4b17023SJohn Marino   /* If we haven't been able to decide at this point, there nothing more we
8340e4b17023SJohn Marino      can check ourselves here.  Look at the base type if we have one and it
8341e4b17023SJohn Marino      has the same precision.  */
8342e4b17023SJohn Marino   if (TREE_CODE (type) == INTEGER_TYPE
8343e4b17023SJohn Marino       && TREE_TYPE (type) != 0
8344e4b17023SJohn Marino       && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (type)))
8345e4b17023SJohn Marino     {
8346e4b17023SJohn Marino       type = TREE_TYPE (type);
8347e4b17023SJohn Marino       goto retry;
8348e4b17023SJohn Marino     }
8349e4b17023SJohn Marino 
8350e4b17023SJohn Marino   /* Or to double_int_fits_to_tree_p, if nothing else.  */
8351e4b17023SJohn Marino   return double_int_fits_to_tree_p (type, dc);
8352e4b17023SJohn Marino }
8353e4b17023SJohn Marino 
8354e4b17023SJohn Marino /* Stores bounds of an integer TYPE in MIN and MAX.  If TYPE has non-constant
8355e4b17023SJohn Marino    bounds or is a POINTER_TYPE, the maximum and/or minimum values that can be
8356e4b17023SJohn Marino    represented (assuming two's-complement arithmetic) within the bit
8357e4b17023SJohn Marino    precision of the type are returned instead.  */
8358e4b17023SJohn Marino 
8359e4b17023SJohn Marino void
get_type_static_bounds(const_tree type,mpz_t min,mpz_t max)8360e4b17023SJohn Marino get_type_static_bounds (const_tree type, mpz_t min, mpz_t max)
8361e4b17023SJohn Marino {
8362e4b17023SJohn Marino   if (!POINTER_TYPE_P (type) && TYPE_MIN_VALUE (type)
8363e4b17023SJohn Marino       && TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST)
8364e4b17023SJohn Marino     mpz_set_double_int (min, tree_to_double_int (TYPE_MIN_VALUE (type)),
8365e4b17023SJohn Marino 			TYPE_UNSIGNED (type));
8366e4b17023SJohn Marino   else
8367e4b17023SJohn Marino     {
8368e4b17023SJohn Marino       if (TYPE_UNSIGNED (type))
8369e4b17023SJohn Marino 	mpz_set_ui (min, 0);
8370e4b17023SJohn Marino       else
8371e4b17023SJohn Marino 	{
8372e4b17023SJohn Marino 	  double_int mn;
8373e4b17023SJohn Marino 	  mn = double_int_mask (TYPE_PRECISION (type) - 1);
8374e4b17023SJohn Marino 	  mn = double_int_sext (double_int_add (mn, double_int_one),
8375e4b17023SJohn Marino 				TYPE_PRECISION (type));
8376e4b17023SJohn Marino 	  mpz_set_double_int (min, mn, false);
8377e4b17023SJohn Marino 	}
8378e4b17023SJohn Marino     }
8379e4b17023SJohn Marino 
8380e4b17023SJohn Marino   if (!POINTER_TYPE_P (type) && TYPE_MAX_VALUE (type)
8381e4b17023SJohn Marino       && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST)
8382e4b17023SJohn Marino     mpz_set_double_int (max, tree_to_double_int (TYPE_MAX_VALUE (type)),
8383e4b17023SJohn Marino 			TYPE_UNSIGNED (type));
8384e4b17023SJohn Marino   else
8385e4b17023SJohn Marino     {
8386e4b17023SJohn Marino       if (TYPE_UNSIGNED (type))
8387e4b17023SJohn Marino 	mpz_set_double_int (max, double_int_mask (TYPE_PRECISION (type)),
8388e4b17023SJohn Marino 			    true);
8389e4b17023SJohn Marino       else
8390e4b17023SJohn Marino 	mpz_set_double_int (max, double_int_mask (TYPE_PRECISION (type) - 1),
8391e4b17023SJohn Marino 			    true);
8392e4b17023SJohn Marino     }
8393e4b17023SJohn Marino }
8394e4b17023SJohn Marino 
8395e4b17023SJohn Marino /* Return true if VAR is an automatic variable defined in function FN.  */
8396e4b17023SJohn Marino 
8397e4b17023SJohn Marino bool
auto_var_in_fn_p(const_tree var,const_tree fn)8398e4b17023SJohn Marino auto_var_in_fn_p (const_tree var, const_tree fn)
8399e4b17023SJohn Marino {
8400e4b17023SJohn Marino   return (DECL_P (var) && DECL_CONTEXT (var) == fn
8401e4b17023SJohn Marino 	  && ((((TREE_CODE (var) == VAR_DECL && ! DECL_EXTERNAL (var))
8402e4b17023SJohn Marino 		|| TREE_CODE (var) == PARM_DECL)
8403e4b17023SJohn Marino 	       && ! TREE_STATIC (var))
8404e4b17023SJohn Marino 	      || TREE_CODE (var) == LABEL_DECL
8405e4b17023SJohn Marino 	      || TREE_CODE (var) == RESULT_DECL));
8406e4b17023SJohn Marino }
8407e4b17023SJohn Marino 
8408e4b17023SJohn Marino /* Subprogram of following function.  Called by walk_tree.
8409e4b17023SJohn Marino 
8410e4b17023SJohn Marino    Return *TP if it is an automatic variable or parameter of the
8411e4b17023SJohn Marino    function passed in as DATA.  */
8412e4b17023SJohn Marino 
8413e4b17023SJohn Marino static tree
find_var_from_fn(tree * tp,int * walk_subtrees,void * data)8414e4b17023SJohn Marino find_var_from_fn (tree *tp, int *walk_subtrees, void *data)
8415e4b17023SJohn Marino {
8416e4b17023SJohn Marino   tree fn = (tree) data;
8417e4b17023SJohn Marino 
8418e4b17023SJohn Marino   if (TYPE_P (*tp))
8419e4b17023SJohn Marino     *walk_subtrees = 0;
8420e4b17023SJohn Marino 
8421e4b17023SJohn Marino   else if (DECL_P (*tp)
8422e4b17023SJohn Marino 	   && auto_var_in_fn_p (*tp, fn))
8423e4b17023SJohn Marino     return *tp;
8424e4b17023SJohn Marino 
8425e4b17023SJohn Marino   return NULL_TREE;
8426e4b17023SJohn Marino }
8427e4b17023SJohn Marino 
8428e4b17023SJohn Marino /* Returns true if T is, contains, or refers to a type with variable
8429e4b17023SJohn Marino    size.  For METHOD_TYPEs and FUNCTION_TYPEs we exclude the
8430e4b17023SJohn Marino    arguments, but not the return type.  If FN is nonzero, only return
8431e4b17023SJohn Marino    true if a modifier of the type or position of FN is a variable or
8432e4b17023SJohn Marino    parameter inside FN.
8433e4b17023SJohn Marino 
8434e4b17023SJohn Marino    This concept is more general than that of C99 'variably modified types':
8435e4b17023SJohn Marino    in C99, a struct type is never variably modified because a VLA may not
8436e4b17023SJohn Marino    appear as a structure member.  However, in GNU C code like:
8437e4b17023SJohn Marino 
8438e4b17023SJohn Marino      struct S { int i[f()]; };
8439e4b17023SJohn Marino 
8440e4b17023SJohn Marino    is valid, and other languages may define similar constructs.  */
8441e4b17023SJohn Marino 
8442e4b17023SJohn Marino bool
variably_modified_type_p(tree type,tree fn)8443e4b17023SJohn Marino variably_modified_type_p (tree type, tree fn)
8444e4b17023SJohn Marino {
8445e4b17023SJohn Marino   tree t;
8446e4b17023SJohn Marino 
8447e4b17023SJohn Marino /* Test if T is either variable (if FN is zero) or an expression containing
8448*5ce9237cSJohn Marino    a variable in FN.  If TYPE isn't gimplified, return true also if
8449*5ce9237cSJohn Marino    gimplify_one_sizepos would gimplify the expression into a local
8450*5ce9237cSJohn Marino    variable.  */
8451e4b17023SJohn Marino #define RETURN_TRUE_IF_VAR(T)						\
8452e4b17023SJohn Marino   do { tree _t = (T);							\
8453e4b17023SJohn Marino     if (_t != NULL_TREE							\
8454e4b17023SJohn Marino 	&& _t != error_mark_node					\
8455e4b17023SJohn Marino 	&& TREE_CODE (_t) != INTEGER_CST				\
8456e4b17023SJohn Marino 	&& TREE_CODE (_t) != PLACEHOLDER_EXPR				\
8457*5ce9237cSJohn Marino 	&& (!fn								\
8458*5ce9237cSJohn Marino 	    || (!TYPE_SIZES_GIMPLIFIED (type)				\
8459*5ce9237cSJohn Marino 		&& !is_gimple_sizepos (_t))				\
8460*5ce9237cSJohn Marino 	    || walk_tree (&_t, find_var_from_fn, fn, NULL)))		\
8461e4b17023SJohn Marino       return true;  } while (0)
8462e4b17023SJohn Marino 
8463e4b17023SJohn Marino   if (type == error_mark_node)
8464e4b17023SJohn Marino     return false;
8465e4b17023SJohn Marino 
8466e4b17023SJohn Marino   /* If TYPE itself has variable size, it is variably modified.  */
8467e4b17023SJohn Marino   RETURN_TRUE_IF_VAR (TYPE_SIZE (type));
8468e4b17023SJohn Marino   RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT (type));
8469e4b17023SJohn Marino 
8470e4b17023SJohn Marino   switch (TREE_CODE (type))
8471e4b17023SJohn Marino     {
8472e4b17023SJohn Marino     case POINTER_TYPE:
8473e4b17023SJohn Marino     case REFERENCE_TYPE:
8474e4b17023SJohn Marino     case VECTOR_TYPE:
8475e4b17023SJohn Marino       if (variably_modified_type_p (TREE_TYPE (type), fn))
8476e4b17023SJohn Marino 	return true;
8477e4b17023SJohn Marino       break;
8478e4b17023SJohn Marino 
8479e4b17023SJohn Marino     case FUNCTION_TYPE:
8480e4b17023SJohn Marino     case METHOD_TYPE:
8481e4b17023SJohn Marino       /* If TYPE is a function type, it is variably modified if the
8482e4b17023SJohn Marino 	 return type is variably modified.  */
8483e4b17023SJohn Marino       if (variably_modified_type_p (TREE_TYPE (type), fn))
8484e4b17023SJohn Marino 	  return true;
8485e4b17023SJohn Marino       break;
8486e4b17023SJohn Marino 
8487e4b17023SJohn Marino     case INTEGER_TYPE:
8488e4b17023SJohn Marino     case REAL_TYPE:
8489e4b17023SJohn Marino     case FIXED_POINT_TYPE:
8490e4b17023SJohn Marino     case ENUMERAL_TYPE:
8491e4b17023SJohn Marino     case BOOLEAN_TYPE:
8492e4b17023SJohn Marino       /* Scalar types are variably modified if their end points
8493e4b17023SJohn Marino 	 aren't constant.  */
8494e4b17023SJohn Marino       RETURN_TRUE_IF_VAR (TYPE_MIN_VALUE (type));
8495e4b17023SJohn Marino       RETURN_TRUE_IF_VAR (TYPE_MAX_VALUE (type));
8496e4b17023SJohn Marino       break;
8497e4b17023SJohn Marino 
8498e4b17023SJohn Marino     case RECORD_TYPE:
8499e4b17023SJohn Marino     case UNION_TYPE:
8500e4b17023SJohn Marino     case QUAL_UNION_TYPE:
8501e4b17023SJohn Marino       /* We can't see if any of the fields are variably-modified by the
8502e4b17023SJohn Marino 	 definition we normally use, since that would produce infinite
8503e4b17023SJohn Marino 	 recursion via pointers.  */
8504e4b17023SJohn Marino       /* This is variably modified if some field's type is.  */
8505e4b17023SJohn Marino       for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
8506e4b17023SJohn Marino 	if (TREE_CODE (t) == FIELD_DECL)
8507e4b17023SJohn Marino 	  {
8508e4b17023SJohn Marino 	    RETURN_TRUE_IF_VAR (DECL_FIELD_OFFSET (t));
8509e4b17023SJohn Marino 	    RETURN_TRUE_IF_VAR (DECL_SIZE (t));
8510e4b17023SJohn Marino 	    RETURN_TRUE_IF_VAR (DECL_SIZE_UNIT (t));
8511e4b17023SJohn Marino 
8512e4b17023SJohn Marino 	    if (TREE_CODE (type) == QUAL_UNION_TYPE)
8513e4b17023SJohn Marino 	      RETURN_TRUE_IF_VAR (DECL_QUALIFIER (t));
8514e4b17023SJohn Marino 	  }
8515e4b17023SJohn Marino 	break;
8516e4b17023SJohn Marino 
8517e4b17023SJohn Marino     case ARRAY_TYPE:
8518e4b17023SJohn Marino       /* Do not call ourselves to avoid infinite recursion.  This is
8519e4b17023SJohn Marino 	 variably modified if the element type is.  */
8520e4b17023SJohn Marino       RETURN_TRUE_IF_VAR (TYPE_SIZE (TREE_TYPE (type)));
8521e4b17023SJohn Marino       RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT (TREE_TYPE (type)));
8522e4b17023SJohn Marino       break;
8523e4b17023SJohn Marino 
8524e4b17023SJohn Marino     default:
8525e4b17023SJohn Marino       break;
8526e4b17023SJohn Marino     }
8527e4b17023SJohn Marino 
8528e4b17023SJohn Marino   /* The current language may have other cases to check, but in general,
8529e4b17023SJohn Marino      all other types are not variably modified.  */
8530e4b17023SJohn Marino   return lang_hooks.tree_inlining.var_mod_type_p (type, fn);
8531e4b17023SJohn Marino 
8532e4b17023SJohn Marino #undef RETURN_TRUE_IF_VAR
8533e4b17023SJohn Marino }
8534e4b17023SJohn Marino 
8535e4b17023SJohn Marino /* Given a DECL or TYPE, return the scope in which it was declared, or
8536e4b17023SJohn Marino    NULL_TREE if there is no containing scope.  */
8537e4b17023SJohn Marino 
8538e4b17023SJohn Marino tree
get_containing_scope(const_tree t)8539e4b17023SJohn Marino get_containing_scope (const_tree t)
8540e4b17023SJohn Marino {
8541e4b17023SJohn Marino   return (TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t));
8542e4b17023SJohn Marino }
8543e4b17023SJohn Marino 
8544e4b17023SJohn Marino /* Return the innermost context enclosing DECL that is
8545e4b17023SJohn Marino    a FUNCTION_DECL, or zero if none.  */
8546e4b17023SJohn Marino 
8547e4b17023SJohn Marino tree
decl_function_context(const_tree decl)8548e4b17023SJohn Marino decl_function_context (const_tree decl)
8549e4b17023SJohn Marino {
8550e4b17023SJohn Marino   tree context;
8551e4b17023SJohn Marino 
8552e4b17023SJohn Marino   if (TREE_CODE (decl) == ERROR_MARK)
8553e4b17023SJohn Marino     return 0;
8554e4b17023SJohn Marino 
8555e4b17023SJohn Marino   /* C++ virtual functions use DECL_CONTEXT for the class of the vtable
8556e4b17023SJohn Marino      where we look up the function at runtime.  Such functions always take
8557e4b17023SJohn Marino      a first argument of type 'pointer to real context'.
8558e4b17023SJohn Marino 
8559e4b17023SJohn Marino      C++ should really be fixed to use DECL_CONTEXT for the real context,
8560e4b17023SJohn Marino      and use something else for the "virtual context".  */
8561e4b17023SJohn Marino   else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VINDEX (decl))
8562e4b17023SJohn Marino     context
8563e4b17023SJohn Marino       = TYPE_MAIN_VARIANT
8564e4b17023SJohn Marino 	(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));
8565e4b17023SJohn Marino   else
8566e4b17023SJohn Marino     context = DECL_CONTEXT (decl);
8567e4b17023SJohn Marino 
8568e4b17023SJohn Marino   while (context && TREE_CODE (context) != FUNCTION_DECL)
8569e4b17023SJohn Marino     {
8570e4b17023SJohn Marino       if (TREE_CODE (context) == BLOCK)
8571e4b17023SJohn Marino 	context = BLOCK_SUPERCONTEXT (context);
8572e4b17023SJohn Marino       else
8573e4b17023SJohn Marino 	context = get_containing_scope (context);
8574e4b17023SJohn Marino     }
8575e4b17023SJohn Marino 
8576e4b17023SJohn Marino   return context;
8577e4b17023SJohn Marino }
8578e4b17023SJohn Marino 
8579e4b17023SJohn Marino /* Return the innermost context enclosing DECL that is
8580e4b17023SJohn Marino    a RECORD_TYPE, UNION_TYPE or QUAL_UNION_TYPE, or zero if none.
8581e4b17023SJohn Marino    TYPE_DECLs and FUNCTION_DECLs are transparent to this function.  */
8582e4b17023SJohn Marino 
8583e4b17023SJohn Marino tree
decl_type_context(const_tree decl)8584e4b17023SJohn Marino decl_type_context (const_tree decl)
8585e4b17023SJohn Marino {
8586e4b17023SJohn Marino   tree context = DECL_CONTEXT (decl);
8587e4b17023SJohn Marino 
8588e4b17023SJohn Marino   while (context)
8589e4b17023SJohn Marino     switch (TREE_CODE (context))
8590e4b17023SJohn Marino       {
8591e4b17023SJohn Marino       case NAMESPACE_DECL:
8592e4b17023SJohn Marino       case TRANSLATION_UNIT_DECL:
8593e4b17023SJohn Marino 	return NULL_TREE;
8594e4b17023SJohn Marino 
8595e4b17023SJohn Marino       case RECORD_TYPE:
8596e4b17023SJohn Marino       case UNION_TYPE:
8597e4b17023SJohn Marino       case QUAL_UNION_TYPE:
8598e4b17023SJohn Marino 	return context;
8599e4b17023SJohn Marino 
8600e4b17023SJohn Marino       case TYPE_DECL:
8601e4b17023SJohn Marino       case FUNCTION_DECL:
8602e4b17023SJohn Marino 	context = DECL_CONTEXT (context);
8603e4b17023SJohn Marino 	break;
8604e4b17023SJohn Marino 
8605e4b17023SJohn Marino       case BLOCK:
8606e4b17023SJohn Marino 	context = BLOCK_SUPERCONTEXT (context);
8607e4b17023SJohn Marino 	break;
8608e4b17023SJohn Marino 
8609e4b17023SJohn Marino       default:
8610e4b17023SJohn Marino 	gcc_unreachable ();
8611e4b17023SJohn Marino       }
8612e4b17023SJohn Marino 
8613e4b17023SJohn Marino   return NULL_TREE;
8614e4b17023SJohn Marino }
8615e4b17023SJohn Marino 
8616e4b17023SJohn Marino /* CALL is a CALL_EXPR.  Return the declaration for the function
8617e4b17023SJohn Marino    called, or NULL_TREE if the called function cannot be
8618e4b17023SJohn Marino    determined.  */
8619e4b17023SJohn Marino 
8620e4b17023SJohn Marino tree
get_callee_fndecl(const_tree call)8621e4b17023SJohn Marino get_callee_fndecl (const_tree call)
8622e4b17023SJohn Marino {
8623e4b17023SJohn Marino   tree addr;
8624e4b17023SJohn Marino 
8625e4b17023SJohn Marino   if (call == error_mark_node)
8626e4b17023SJohn Marino     return error_mark_node;
8627e4b17023SJohn Marino 
8628e4b17023SJohn Marino   /* It's invalid to call this function with anything but a
8629e4b17023SJohn Marino      CALL_EXPR.  */
8630e4b17023SJohn Marino   gcc_assert (TREE_CODE (call) == CALL_EXPR);
8631e4b17023SJohn Marino 
8632e4b17023SJohn Marino   /* The first operand to the CALL is the address of the function
8633e4b17023SJohn Marino      called.  */
8634e4b17023SJohn Marino   addr = CALL_EXPR_FN (call);
8635e4b17023SJohn Marino 
8636e4b17023SJohn Marino   STRIP_NOPS (addr);
8637e4b17023SJohn Marino 
8638e4b17023SJohn Marino   /* If this is a readonly function pointer, extract its initial value.  */
8639e4b17023SJohn Marino   if (DECL_P (addr) && TREE_CODE (addr) != FUNCTION_DECL
8640e4b17023SJohn Marino       && TREE_READONLY (addr) && ! TREE_THIS_VOLATILE (addr)
8641e4b17023SJohn Marino       && DECL_INITIAL (addr))
8642e4b17023SJohn Marino     addr = DECL_INITIAL (addr);
8643e4b17023SJohn Marino 
8644e4b17023SJohn Marino   /* If the address is just `&f' for some function `f', then we know
8645e4b17023SJohn Marino      that `f' is being called.  */
8646e4b17023SJohn Marino   if (TREE_CODE (addr) == ADDR_EXPR
8647e4b17023SJohn Marino       && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
8648e4b17023SJohn Marino     return TREE_OPERAND (addr, 0);
8649e4b17023SJohn Marino 
8650e4b17023SJohn Marino   /* We couldn't figure out what was being called.  */
8651e4b17023SJohn Marino   return NULL_TREE;
8652e4b17023SJohn Marino }
8653e4b17023SJohn Marino 
8654e4b17023SJohn Marino /* Print debugging information about tree nodes generated during the compile,
8655e4b17023SJohn Marino    and any language-specific information.  */
8656e4b17023SJohn Marino 
8657e4b17023SJohn Marino void
dump_tree_statistics(void)8658e4b17023SJohn Marino dump_tree_statistics (void)
8659e4b17023SJohn Marino {
8660e4b17023SJohn Marino #ifdef GATHER_STATISTICS
8661e4b17023SJohn Marino   int i;
8662e4b17023SJohn Marino   int total_nodes, total_bytes;
8663e4b17023SJohn Marino #endif
8664e4b17023SJohn Marino 
8665e4b17023SJohn Marino   fprintf (stderr, "\n??? tree nodes created\n\n");
8666e4b17023SJohn Marino #ifdef GATHER_STATISTICS
8667e4b17023SJohn Marino   fprintf (stderr, "Kind                   Nodes      Bytes\n");
8668e4b17023SJohn Marino   fprintf (stderr, "---------------------------------------\n");
8669e4b17023SJohn Marino   total_nodes = total_bytes = 0;
8670e4b17023SJohn Marino   for (i = 0; i < (int) all_kinds; i++)
8671e4b17023SJohn Marino     {
8672e4b17023SJohn Marino       fprintf (stderr, "%-20s %7d %10d\n", tree_node_kind_names[i],
8673e4b17023SJohn Marino 	       tree_node_counts[i], tree_node_sizes[i]);
8674e4b17023SJohn Marino       total_nodes += tree_node_counts[i];
8675e4b17023SJohn Marino       total_bytes += tree_node_sizes[i];
8676e4b17023SJohn Marino     }
8677e4b17023SJohn Marino   fprintf (stderr, "---------------------------------------\n");
8678e4b17023SJohn Marino   fprintf (stderr, "%-20s %7d %10d\n", "Total", total_nodes, total_bytes);
8679e4b17023SJohn Marino   fprintf (stderr, "---------------------------------------\n");
8680e4b17023SJohn Marino   fprintf (stderr, "Code                   Nodes\n");
8681e4b17023SJohn Marino   fprintf (stderr, "----------------------------\n");
8682e4b17023SJohn Marino   for (i = 0; i < (int) MAX_TREE_CODES; i++)
8683e4b17023SJohn Marino     fprintf (stderr, "%-20s %7d\n", tree_code_name[i], tree_code_counts[i]);
8684e4b17023SJohn Marino   fprintf (stderr, "----------------------------\n");
8685e4b17023SJohn Marino   ssanames_print_statistics ();
8686e4b17023SJohn Marino   phinodes_print_statistics ();
8687e4b17023SJohn Marino #else
8688e4b17023SJohn Marino   fprintf (stderr, "(No per-node statistics)\n");
8689e4b17023SJohn Marino #endif
8690e4b17023SJohn Marino   print_type_hash_statistics ();
8691e4b17023SJohn Marino   print_debug_expr_statistics ();
8692e4b17023SJohn Marino   print_value_expr_statistics ();
8693e4b17023SJohn Marino   lang_hooks.print_statistics ();
8694e4b17023SJohn Marino }
8695e4b17023SJohn Marino 
8696e4b17023SJohn Marino #define FILE_FUNCTION_FORMAT "_GLOBAL__%s_%s"
8697e4b17023SJohn Marino 
8698e4b17023SJohn Marino /* Generate a crc32 of a byte.  */
8699e4b17023SJohn Marino 
8700e4b17023SJohn Marino unsigned
crc32_byte(unsigned chksum,char byte)8701e4b17023SJohn Marino crc32_byte (unsigned chksum, char byte)
8702e4b17023SJohn Marino {
8703e4b17023SJohn Marino   unsigned value = (unsigned) byte << 24;
8704e4b17023SJohn Marino       unsigned ix;
8705e4b17023SJohn Marino 
8706e4b17023SJohn Marino       for (ix = 8; ix--; value <<= 1)
8707e4b17023SJohn Marino   	{
8708e4b17023SJohn Marino   	  unsigned feedback;
8709e4b17023SJohn Marino 
8710e4b17023SJohn Marino   	  feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
8711e4b17023SJohn Marino  	  chksum <<= 1;
8712e4b17023SJohn Marino  	  chksum ^= feedback;
8713e4b17023SJohn Marino   	}
8714e4b17023SJohn Marino   return chksum;
8715e4b17023SJohn Marino }
8716e4b17023SJohn Marino 
8717e4b17023SJohn Marino 
8718e4b17023SJohn Marino /* Generate a crc32 of a string.  */
8719e4b17023SJohn Marino 
8720e4b17023SJohn Marino unsigned
crc32_string(unsigned chksum,const char * string)8721e4b17023SJohn Marino crc32_string (unsigned chksum, const char *string)
8722e4b17023SJohn Marino {
8723e4b17023SJohn Marino   do
8724e4b17023SJohn Marino     {
8725e4b17023SJohn Marino       chksum = crc32_byte (chksum, *string);
8726e4b17023SJohn Marino     }
8727e4b17023SJohn Marino   while (*string++);
8728e4b17023SJohn Marino   return chksum;
8729e4b17023SJohn Marino }
8730e4b17023SJohn Marino 
8731e4b17023SJohn Marino /* P is a string that will be used in a symbol.  Mask out any characters
8732e4b17023SJohn Marino    that are not valid in that context.  */
8733e4b17023SJohn Marino 
8734e4b17023SJohn Marino void
clean_symbol_name(char * p)8735e4b17023SJohn Marino clean_symbol_name (char *p)
8736e4b17023SJohn Marino {
8737e4b17023SJohn Marino   for (; *p; p++)
8738e4b17023SJohn Marino     if (! (ISALNUM (*p)
8739e4b17023SJohn Marino #ifndef NO_DOLLAR_IN_LABEL	/* this for `$'; unlikely, but... -- kr */
8740e4b17023SJohn Marino 	    || *p == '$'
8741e4b17023SJohn Marino #endif
8742e4b17023SJohn Marino #ifndef NO_DOT_IN_LABEL		/* this for `.'; unlikely, but...  */
8743e4b17023SJohn Marino 	    || *p == '.'
8744e4b17023SJohn Marino #endif
8745e4b17023SJohn Marino 	   ))
8746e4b17023SJohn Marino       *p = '_';
8747e4b17023SJohn Marino }
8748e4b17023SJohn Marino 
8749e4b17023SJohn Marino /* Generate a name for a special-purpose function.
8750e4b17023SJohn Marino    The generated name may need to be unique across the whole link.
8751e4b17023SJohn Marino    Changes to this function may also require corresponding changes to
8752e4b17023SJohn Marino    xstrdup_mask_random.
8753e4b17023SJohn Marino    TYPE is some string to identify the purpose of this function to the
8754e4b17023SJohn Marino    linker or collect2; it must start with an uppercase letter,
8755e4b17023SJohn Marino    one of:
8756e4b17023SJohn Marino    I - for constructors
8757e4b17023SJohn Marino    D - for destructors
8758e4b17023SJohn Marino    N - for C++ anonymous namespaces
8759e4b17023SJohn Marino    F - for DWARF unwind frame information.  */
8760e4b17023SJohn Marino 
8761e4b17023SJohn Marino tree
get_file_function_name(const char * type)8762e4b17023SJohn Marino get_file_function_name (const char *type)
8763e4b17023SJohn Marino {
8764e4b17023SJohn Marino   char *buf;
8765e4b17023SJohn Marino   const char *p;
8766e4b17023SJohn Marino   char *q;
8767e4b17023SJohn Marino 
8768e4b17023SJohn Marino   /* If we already have a name we know to be unique, just use that.  */
8769e4b17023SJohn Marino   if (first_global_object_name)
8770e4b17023SJohn Marino     p = q = ASTRDUP (first_global_object_name);
8771e4b17023SJohn Marino   /* If the target is handling the constructors/destructors, they
8772e4b17023SJohn Marino      will be local to this file and the name is only necessary for
8773e4b17023SJohn Marino      debugging purposes.
8774e4b17023SJohn Marino      We also assign sub_I and sub_D sufixes to constructors called from
8775e4b17023SJohn Marino      the global static constructors.  These are always local.  */
8776e4b17023SJohn Marino   else if (((type[0] == 'I' || type[0] == 'D') && targetm.have_ctors_dtors)
8777e4b17023SJohn Marino 	   || (strncmp (type, "sub_", 4) == 0
8778e4b17023SJohn Marino 	       && (type[4] == 'I' || type[4] == 'D')))
8779e4b17023SJohn Marino     {
8780e4b17023SJohn Marino       const char *file = main_input_filename;
8781e4b17023SJohn Marino       if (! file)
8782e4b17023SJohn Marino 	file = input_filename;
8783e4b17023SJohn Marino       /* Just use the file's basename, because the full pathname
8784e4b17023SJohn Marino 	 might be quite long.  */
8785e4b17023SJohn Marino       p = q = ASTRDUP (lbasename (file));
8786e4b17023SJohn Marino     }
8787e4b17023SJohn Marino   else
8788e4b17023SJohn Marino     {
8789e4b17023SJohn Marino       /* Otherwise, the name must be unique across the entire link.
8790e4b17023SJohn Marino 	 We don't have anything that we know to be unique to this translation
8791e4b17023SJohn Marino 	 unit, so use what we do have and throw in some randomness.  */
8792e4b17023SJohn Marino       unsigned len;
8793e4b17023SJohn Marino       const char *name = weak_global_object_name;
8794e4b17023SJohn Marino       const char *file = main_input_filename;
8795e4b17023SJohn Marino 
8796e4b17023SJohn Marino       if (! name)
8797e4b17023SJohn Marino 	name = "";
8798e4b17023SJohn Marino       if (! file)
8799e4b17023SJohn Marino 	file = input_filename;
8800e4b17023SJohn Marino 
8801e4b17023SJohn Marino       len = strlen (file);
8802e4b17023SJohn Marino       q = (char *) alloca (9 + 17 + len + 1);
8803e4b17023SJohn Marino       memcpy (q, file, len + 1);
8804e4b17023SJohn Marino 
8805e4b17023SJohn Marino       snprintf (q + len, 9 + 17 + 1, "_%08X_" HOST_WIDE_INT_PRINT_HEX,
8806e4b17023SJohn Marino 		crc32_string (0, name), get_random_seed (false));
8807e4b17023SJohn Marino 
8808e4b17023SJohn Marino       p = q;
8809e4b17023SJohn Marino     }
8810e4b17023SJohn Marino 
8811e4b17023SJohn Marino   clean_symbol_name (q);
8812e4b17023SJohn Marino   buf = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) + strlen (p)
8813e4b17023SJohn Marino 			 + strlen (type));
8814e4b17023SJohn Marino 
8815e4b17023SJohn Marino   /* Set up the name of the file-level functions we may need.
8816e4b17023SJohn Marino      Use a global object (which is already required to be unique over
8817e4b17023SJohn Marino      the program) rather than the file name (which imposes extra
8818e4b17023SJohn Marino      constraints).  */
8819e4b17023SJohn Marino   sprintf (buf, FILE_FUNCTION_FORMAT, type, p);
8820e4b17023SJohn Marino 
8821e4b17023SJohn Marino   return get_identifier (buf);
8822e4b17023SJohn Marino }
8823e4b17023SJohn Marino 
8824e4b17023SJohn Marino #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
8825e4b17023SJohn Marino 
8826e4b17023SJohn Marino /* Complain that the tree code of NODE does not match the expected 0
8827e4b17023SJohn Marino    terminated list of trailing codes. The trailing code list can be
8828e4b17023SJohn Marino    empty, for a more vague error message.  FILE, LINE, and FUNCTION
8829e4b17023SJohn Marino    are of the caller.  */
8830e4b17023SJohn Marino 
8831e4b17023SJohn Marino void
tree_check_failed(const_tree node,const char * file,int line,const char * function,...)8832e4b17023SJohn Marino tree_check_failed (const_tree node, const char *file,
8833e4b17023SJohn Marino 		   int line, const char *function, ...)
8834e4b17023SJohn Marino {
8835e4b17023SJohn Marino   va_list args;
8836e4b17023SJohn Marino   const char *buffer;
8837e4b17023SJohn Marino   unsigned length = 0;
8838e4b17023SJohn Marino   int code;
8839e4b17023SJohn Marino 
8840e4b17023SJohn Marino   va_start (args, function);
8841e4b17023SJohn Marino   while ((code = va_arg (args, int)))
8842e4b17023SJohn Marino     length += 4 + strlen (tree_code_name[code]);
8843e4b17023SJohn Marino   va_end (args);
8844e4b17023SJohn Marino   if (length)
8845e4b17023SJohn Marino     {
8846e4b17023SJohn Marino       char *tmp;
8847e4b17023SJohn Marino       va_start (args, function);
8848e4b17023SJohn Marino       length += strlen ("expected ");
8849e4b17023SJohn Marino       buffer = tmp = (char *) alloca (length);
8850e4b17023SJohn Marino       length = 0;
8851e4b17023SJohn Marino       while ((code = va_arg (args, int)))
8852e4b17023SJohn Marino 	{
8853e4b17023SJohn Marino 	  const char *prefix = length ? " or " : "expected ";
8854e4b17023SJohn Marino 
8855e4b17023SJohn Marino 	  strcpy (tmp + length, prefix);
8856e4b17023SJohn Marino 	  length += strlen (prefix);
8857e4b17023SJohn Marino 	  strcpy (tmp + length, tree_code_name[code]);
8858e4b17023SJohn Marino 	  length += strlen (tree_code_name[code]);
8859e4b17023SJohn Marino 	}
8860e4b17023SJohn Marino       va_end (args);
8861e4b17023SJohn Marino     }
8862e4b17023SJohn Marino   else
8863e4b17023SJohn Marino     buffer = "unexpected node";
8864e4b17023SJohn Marino 
8865e4b17023SJohn Marino   internal_error ("tree check: %s, have %s in %s, at %s:%d",
8866e4b17023SJohn Marino 		  buffer, tree_code_name[TREE_CODE (node)],
8867e4b17023SJohn Marino 		  function, trim_filename (file), line);
8868e4b17023SJohn Marino }
8869e4b17023SJohn Marino 
8870e4b17023SJohn Marino /* Complain that the tree code of NODE does match the expected 0
8871e4b17023SJohn Marino    terminated list of trailing codes. FILE, LINE, and FUNCTION are of
8872e4b17023SJohn Marino    the caller.  */
8873e4b17023SJohn Marino 
8874e4b17023SJohn Marino void
tree_not_check_failed(const_tree node,const char * file,int line,const char * function,...)8875e4b17023SJohn Marino tree_not_check_failed (const_tree node, const char *file,
8876e4b17023SJohn Marino 		       int line, const char *function, ...)
8877e4b17023SJohn Marino {
8878e4b17023SJohn Marino   va_list args;
8879e4b17023SJohn Marino   char *buffer;
8880e4b17023SJohn Marino   unsigned length = 0;
8881e4b17023SJohn Marino   int code;
8882e4b17023SJohn Marino 
8883e4b17023SJohn Marino   va_start (args, function);
8884e4b17023SJohn Marino   while ((code = va_arg (args, int)))
8885e4b17023SJohn Marino     length += 4 + strlen (tree_code_name[code]);
8886e4b17023SJohn Marino   va_end (args);
8887e4b17023SJohn Marino   va_start (args, function);
8888e4b17023SJohn Marino   buffer = (char *) alloca (length);
8889e4b17023SJohn Marino   length = 0;
8890e4b17023SJohn Marino   while ((code = va_arg (args, int)))
8891e4b17023SJohn Marino     {
8892e4b17023SJohn Marino       if (length)
8893e4b17023SJohn Marino 	{
8894e4b17023SJohn Marino 	  strcpy (buffer + length, " or ");
8895e4b17023SJohn Marino 	  length += 4;
8896e4b17023SJohn Marino 	}
8897e4b17023SJohn Marino       strcpy (buffer + length, tree_code_name[code]);
8898e4b17023SJohn Marino       length += strlen (tree_code_name[code]);
8899e4b17023SJohn Marino     }
8900e4b17023SJohn Marino   va_end (args);
8901e4b17023SJohn Marino 
8902e4b17023SJohn Marino   internal_error ("tree check: expected none of %s, have %s in %s, at %s:%d",
8903e4b17023SJohn Marino 		  buffer, tree_code_name[TREE_CODE (node)],
8904e4b17023SJohn Marino 		  function, trim_filename (file), line);
8905e4b17023SJohn Marino }
8906e4b17023SJohn Marino 
8907e4b17023SJohn Marino /* Similar to tree_check_failed, except that we check for a class of tree
8908e4b17023SJohn Marino    code, given in CL.  */
8909e4b17023SJohn Marino 
8910e4b17023SJohn Marino void
tree_class_check_failed(const_tree node,const enum tree_code_class cl,const char * file,int line,const char * function)8911e4b17023SJohn Marino tree_class_check_failed (const_tree node, const enum tree_code_class cl,
8912e4b17023SJohn Marino 			 const char *file, int line, const char *function)
8913e4b17023SJohn Marino {
8914e4b17023SJohn Marino   internal_error
8915e4b17023SJohn Marino     ("tree check: expected class %qs, have %qs (%s) in %s, at %s:%d",
8916e4b17023SJohn Marino      TREE_CODE_CLASS_STRING (cl),
8917e4b17023SJohn Marino      TREE_CODE_CLASS_STRING (TREE_CODE_CLASS (TREE_CODE (node))),
8918e4b17023SJohn Marino      tree_code_name[TREE_CODE (node)], function, trim_filename (file), line);
8919e4b17023SJohn Marino }
8920e4b17023SJohn Marino 
8921e4b17023SJohn Marino /* Similar to tree_check_failed, except that instead of specifying a
8922e4b17023SJohn Marino    dozen codes, use the knowledge that they're all sequential.  */
8923e4b17023SJohn Marino 
8924e4b17023SJohn Marino void
tree_range_check_failed(const_tree node,const char * file,int line,const char * function,enum tree_code c1,enum tree_code c2)8925e4b17023SJohn Marino tree_range_check_failed (const_tree node, const char *file, int line,
8926e4b17023SJohn Marino 			 const char *function, enum tree_code c1,
8927e4b17023SJohn Marino 			 enum tree_code c2)
8928e4b17023SJohn Marino {
8929e4b17023SJohn Marino   char *buffer;
8930e4b17023SJohn Marino   unsigned length = 0;
8931e4b17023SJohn Marino   unsigned int c;
8932e4b17023SJohn Marino 
8933e4b17023SJohn Marino   for (c = c1; c <= c2; ++c)
8934e4b17023SJohn Marino     length += 4 + strlen (tree_code_name[c]);
8935e4b17023SJohn Marino 
8936e4b17023SJohn Marino   length += strlen ("expected ");
8937e4b17023SJohn Marino   buffer = (char *) alloca (length);
8938e4b17023SJohn Marino   length = 0;
8939e4b17023SJohn Marino 
8940e4b17023SJohn Marino   for (c = c1; c <= c2; ++c)
8941e4b17023SJohn Marino     {
8942e4b17023SJohn Marino       const char *prefix = length ? " or " : "expected ";
8943e4b17023SJohn Marino 
8944e4b17023SJohn Marino       strcpy (buffer + length, prefix);
8945e4b17023SJohn Marino       length += strlen (prefix);
8946e4b17023SJohn Marino       strcpy (buffer + length, tree_code_name[c]);
8947e4b17023SJohn Marino       length += strlen (tree_code_name[c]);
8948e4b17023SJohn Marino     }
8949e4b17023SJohn Marino 
8950e4b17023SJohn Marino   internal_error ("tree check: %s, have %s in %s, at %s:%d",
8951e4b17023SJohn Marino 		  buffer, tree_code_name[TREE_CODE (node)],
8952e4b17023SJohn Marino 		  function, trim_filename (file), line);
8953e4b17023SJohn Marino }
8954e4b17023SJohn Marino 
8955e4b17023SJohn Marino 
8956e4b17023SJohn Marino /* Similar to tree_check_failed, except that we check that a tree does
8957e4b17023SJohn Marino    not have the specified code, given in CL.  */
8958e4b17023SJohn Marino 
8959e4b17023SJohn Marino void
tree_not_class_check_failed(const_tree node,const enum tree_code_class cl,const char * file,int line,const char * function)8960e4b17023SJohn Marino tree_not_class_check_failed (const_tree node, const enum tree_code_class cl,
8961e4b17023SJohn Marino 			     const char *file, int line, const char *function)
8962e4b17023SJohn Marino {
8963e4b17023SJohn Marino   internal_error
8964e4b17023SJohn Marino     ("tree check: did not expect class %qs, have %qs (%s) in %s, at %s:%d",
8965e4b17023SJohn Marino      TREE_CODE_CLASS_STRING (cl),
8966e4b17023SJohn Marino      TREE_CODE_CLASS_STRING (TREE_CODE_CLASS (TREE_CODE (node))),
8967e4b17023SJohn Marino      tree_code_name[TREE_CODE (node)], function, trim_filename (file), line);
8968e4b17023SJohn Marino }
8969e4b17023SJohn Marino 
8970e4b17023SJohn Marino 
8971e4b17023SJohn Marino /* Similar to tree_check_failed but applied to OMP_CLAUSE codes.  */
8972e4b17023SJohn Marino 
8973e4b17023SJohn Marino void
omp_clause_check_failed(const_tree node,const char * file,int line,const char * function,enum omp_clause_code code)8974e4b17023SJohn Marino omp_clause_check_failed (const_tree node, const char *file, int line,
8975e4b17023SJohn Marino                          const char *function, enum omp_clause_code code)
8976e4b17023SJohn Marino {
8977e4b17023SJohn Marino   internal_error ("tree check: expected omp_clause %s, have %s in %s, at %s:%d",
8978e4b17023SJohn Marino 		  omp_clause_code_name[code], tree_code_name[TREE_CODE (node)],
8979e4b17023SJohn Marino 		  function, trim_filename (file), line);
8980e4b17023SJohn Marino }
8981e4b17023SJohn Marino 
8982e4b17023SJohn Marino 
8983e4b17023SJohn Marino /* Similar to tree_range_check_failed but applied to OMP_CLAUSE codes.  */
8984e4b17023SJohn Marino 
8985e4b17023SJohn Marino 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)8986e4b17023SJohn Marino omp_clause_range_check_failed (const_tree node, const char *file, int line,
8987e4b17023SJohn Marino 			       const char *function, enum omp_clause_code c1,
8988e4b17023SJohn Marino 			       enum omp_clause_code c2)
8989e4b17023SJohn Marino {
8990e4b17023SJohn Marino   char *buffer;
8991e4b17023SJohn Marino   unsigned length = 0;
8992e4b17023SJohn Marino   unsigned int c;
8993e4b17023SJohn Marino 
8994e4b17023SJohn Marino   for (c = c1; c <= c2; ++c)
8995e4b17023SJohn Marino     length += 4 + strlen (omp_clause_code_name[c]);
8996e4b17023SJohn Marino 
8997e4b17023SJohn Marino   length += strlen ("expected ");
8998e4b17023SJohn Marino   buffer = (char *) alloca (length);
8999e4b17023SJohn Marino   length = 0;
9000e4b17023SJohn Marino 
9001e4b17023SJohn Marino   for (c = c1; c <= c2; ++c)
9002e4b17023SJohn Marino     {
9003e4b17023SJohn Marino       const char *prefix = length ? " or " : "expected ";
9004e4b17023SJohn Marino 
9005e4b17023SJohn Marino       strcpy (buffer + length, prefix);
9006e4b17023SJohn Marino       length += strlen (prefix);
9007e4b17023SJohn Marino       strcpy (buffer + length, omp_clause_code_name[c]);
9008e4b17023SJohn Marino       length += strlen (omp_clause_code_name[c]);
9009e4b17023SJohn Marino     }
9010e4b17023SJohn Marino 
9011e4b17023SJohn Marino   internal_error ("tree check: %s, have %s in %s, at %s:%d",
9012e4b17023SJohn Marino 		  buffer, omp_clause_code_name[TREE_CODE (node)],
9013e4b17023SJohn Marino 		  function, trim_filename (file), line);
9014e4b17023SJohn Marino }
9015e4b17023SJohn Marino 
9016e4b17023SJohn Marino 
9017e4b17023SJohn Marino #undef DEFTREESTRUCT
9018e4b17023SJohn Marino #define DEFTREESTRUCT(VAL, NAME) NAME,
9019e4b17023SJohn Marino 
9020e4b17023SJohn Marino static const char *ts_enum_names[] = {
9021e4b17023SJohn Marino #include "treestruct.def"
9022e4b17023SJohn Marino };
9023e4b17023SJohn Marino #undef DEFTREESTRUCT
9024e4b17023SJohn Marino 
9025e4b17023SJohn Marino #define TS_ENUM_NAME(EN) (ts_enum_names[(EN)])
9026e4b17023SJohn Marino 
9027e4b17023SJohn Marino /* Similar to tree_class_check_failed, except that we check for
9028e4b17023SJohn Marino    whether CODE contains the tree structure identified by EN.  */
9029e4b17023SJohn Marino 
9030e4b17023SJohn Marino void
tree_contains_struct_check_failed(const_tree node,const enum tree_node_structure_enum en,const char * file,int line,const char * function)9031e4b17023SJohn Marino tree_contains_struct_check_failed (const_tree node,
9032e4b17023SJohn Marino 				   const enum tree_node_structure_enum en,
9033e4b17023SJohn Marino 				   const char *file, int line,
9034e4b17023SJohn Marino 				   const char *function)
9035e4b17023SJohn Marino {
9036e4b17023SJohn Marino   internal_error
9037e4b17023SJohn Marino     ("tree check: expected tree that contains %qs structure, have %qs in %s, at %s:%d",
9038e4b17023SJohn Marino      TS_ENUM_NAME(en),
9039e4b17023SJohn Marino      tree_code_name[TREE_CODE (node)], function, trim_filename (file), line);
9040e4b17023SJohn Marino }
9041e4b17023SJohn Marino 
9042e4b17023SJohn Marino 
9043e4b17023SJohn Marino /* Similar to above, except that the check is for the bounds of a TREE_VEC's
9044e4b17023SJohn Marino    (dynamically sized) vector.  */
9045e4b17023SJohn Marino 
9046e4b17023SJohn Marino void
tree_vec_elt_check_failed(int idx,int len,const char * file,int line,const char * function)9047e4b17023SJohn Marino tree_vec_elt_check_failed (int idx, int len, const char *file, int line,
9048e4b17023SJohn Marino 			   const char *function)
9049e4b17023SJohn Marino {
9050e4b17023SJohn Marino   internal_error
9051e4b17023SJohn Marino     ("tree check: accessed elt %d of tree_vec with %d elts in %s, at %s:%d",
9052e4b17023SJohn Marino      idx + 1, len, function, trim_filename (file), line);
9053e4b17023SJohn Marino }
9054e4b17023SJohn Marino 
9055e4b17023SJohn Marino /* Similar to above, except that the check is for the bounds of the operand
9056e4b17023SJohn Marino    vector of an expression node EXP.  */
9057e4b17023SJohn Marino 
9058e4b17023SJohn Marino void
tree_operand_check_failed(int idx,const_tree exp,const char * file,int line,const char * function)9059e4b17023SJohn Marino tree_operand_check_failed (int idx, const_tree exp, const char *file,
9060e4b17023SJohn Marino 			   int line, const char *function)
9061e4b17023SJohn Marino {
9062e4b17023SJohn Marino   int code = TREE_CODE (exp);
9063e4b17023SJohn Marino   internal_error
9064e4b17023SJohn Marino     ("tree check: accessed operand %d of %s with %d operands in %s, at %s:%d",
9065e4b17023SJohn Marino      idx + 1, tree_code_name[code], TREE_OPERAND_LENGTH (exp),
9066e4b17023SJohn Marino      function, trim_filename (file), line);
9067e4b17023SJohn Marino }
9068e4b17023SJohn Marino 
9069e4b17023SJohn Marino /* Similar to above, except that the check is for the number of
9070e4b17023SJohn Marino    operands of an OMP_CLAUSE node.  */
9071e4b17023SJohn Marino 
9072e4b17023SJohn Marino void
omp_clause_operand_check_failed(int idx,const_tree t,const char * file,int line,const char * function)9073e4b17023SJohn Marino omp_clause_operand_check_failed (int idx, const_tree t, const char *file,
9074e4b17023SJohn Marino 			         int line, const char *function)
9075e4b17023SJohn Marino {
9076e4b17023SJohn Marino   internal_error
9077e4b17023SJohn Marino     ("tree check: accessed operand %d of omp_clause %s with %d operands "
9078e4b17023SJohn Marino      "in %s, at %s:%d", idx + 1, omp_clause_code_name[OMP_CLAUSE_CODE (t)],
9079e4b17023SJohn Marino      omp_clause_num_ops [OMP_CLAUSE_CODE (t)], function,
9080e4b17023SJohn Marino      trim_filename (file), line);
9081e4b17023SJohn Marino }
9082e4b17023SJohn Marino #endif /* ENABLE_TREE_CHECKING */
9083e4b17023SJohn Marino 
9084e4b17023SJohn Marino /* Create a new vector type node holding SUBPARTS units of type INNERTYPE,
9085e4b17023SJohn Marino    and mapped to the machine mode MODE.  Initialize its fields and build
9086e4b17023SJohn Marino    the information necessary for debugging output.  */
9087e4b17023SJohn Marino 
9088e4b17023SJohn Marino static tree
make_vector_type(tree innertype,int nunits,enum machine_mode mode)9089e4b17023SJohn Marino make_vector_type (tree innertype, int nunits, enum machine_mode mode)
9090e4b17023SJohn Marino {
9091e4b17023SJohn Marino   tree t;
9092e4b17023SJohn Marino   hashval_t hashcode = 0;
9093e4b17023SJohn Marino 
9094e4b17023SJohn Marino   t = make_node (VECTOR_TYPE);
9095e4b17023SJohn Marino   TREE_TYPE (t) = TYPE_MAIN_VARIANT (innertype);
9096e4b17023SJohn Marino   SET_TYPE_VECTOR_SUBPARTS (t, nunits);
9097e4b17023SJohn Marino   SET_TYPE_MODE (t, mode);
9098e4b17023SJohn Marino 
9099e4b17023SJohn Marino   if (TYPE_STRUCTURAL_EQUALITY_P (innertype))
9100e4b17023SJohn Marino     SET_TYPE_STRUCTURAL_EQUALITY (t);
9101e4b17023SJohn Marino   else if (TYPE_CANONICAL (innertype) != innertype
9102e4b17023SJohn Marino 	   || mode != VOIDmode)
9103e4b17023SJohn Marino     TYPE_CANONICAL (t)
9104e4b17023SJohn Marino       = make_vector_type (TYPE_CANONICAL (innertype), nunits, VOIDmode);
9105e4b17023SJohn Marino 
9106e4b17023SJohn Marino   layout_type (t);
9107e4b17023SJohn Marino 
9108e4b17023SJohn Marino   hashcode = iterative_hash_host_wide_int (VECTOR_TYPE, hashcode);
9109e4b17023SJohn Marino   hashcode = iterative_hash_host_wide_int (nunits, hashcode);
9110e4b17023SJohn Marino   hashcode = iterative_hash_host_wide_int (mode, hashcode);
9111e4b17023SJohn Marino   hashcode = iterative_hash_object (TYPE_HASH (TREE_TYPE (t)), hashcode);
9112e4b17023SJohn Marino   t = type_hash_canon (hashcode, t);
9113e4b17023SJohn Marino 
9114e4b17023SJohn Marino   /* We have built a main variant, based on the main variant of the
9115e4b17023SJohn Marino      inner type. Use it to build the variant we return.  */
9116e4b17023SJohn Marino   if ((TYPE_ATTRIBUTES (innertype) || TYPE_QUALS (innertype))
9117e4b17023SJohn Marino       && TREE_TYPE (t) != innertype)
9118e4b17023SJohn Marino     return build_type_attribute_qual_variant (t,
9119e4b17023SJohn Marino 					      TYPE_ATTRIBUTES (innertype),
9120e4b17023SJohn Marino 					      TYPE_QUALS (innertype));
9121e4b17023SJohn Marino 
9122e4b17023SJohn Marino   return t;
9123e4b17023SJohn Marino }
9124e4b17023SJohn Marino 
9125e4b17023SJohn Marino static tree
make_or_reuse_type(unsigned size,int unsignedp)9126e4b17023SJohn Marino make_or_reuse_type (unsigned size, int unsignedp)
9127e4b17023SJohn Marino {
9128e4b17023SJohn Marino   if (size == INT_TYPE_SIZE)
9129e4b17023SJohn Marino     return unsignedp ? unsigned_type_node : integer_type_node;
9130e4b17023SJohn Marino   if (size == CHAR_TYPE_SIZE)
9131e4b17023SJohn Marino     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
9132e4b17023SJohn Marino   if (size == SHORT_TYPE_SIZE)
9133e4b17023SJohn Marino     return unsignedp ? short_unsigned_type_node : short_integer_type_node;
9134e4b17023SJohn Marino   if (size == LONG_TYPE_SIZE)
9135e4b17023SJohn Marino     return unsignedp ? long_unsigned_type_node : long_integer_type_node;
9136e4b17023SJohn Marino   if (size == LONG_LONG_TYPE_SIZE)
9137e4b17023SJohn Marino     return (unsignedp ? long_long_unsigned_type_node
9138e4b17023SJohn Marino             : long_long_integer_type_node);
9139e4b17023SJohn Marino   if (size == 128 && int128_integer_type_node)
9140e4b17023SJohn Marino     return (unsignedp ? int128_unsigned_type_node
9141e4b17023SJohn Marino             : int128_integer_type_node);
9142e4b17023SJohn Marino 
9143e4b17023SJohn Marino   if (unsignedp)
9144e4b17023SJohn Marino     return make_unsigned_type (size);
9145e4b17023SJohn Marino   else
9146e4b17023SJohn Marino     return make_signed_type (size);
9147e4b17023SJohn Marino }
9148e4b17023SJohn Marino 
9149e4b17023SJohn Marino /* Create or reuse a fract type by SIZE, UNSIGNEDP, and SATP.  */
9150e4b17023SJohn Marino 
9151e4b17023SJohn Marino static tree
make_or_reuse_fract_type(unsigned size,int unsignedp,int satp)9152e4b17023SJohn Marino make_or_reuse_fract_type (unsigned size, int unsignedp, int satp)
9153e4b17023SJohn Marino {
9154e4b17023SJohn Marino   if (satp)
9155e4b17023SJohn Marino     {
9156e4b17023SJohn Marino       if (size == SHORT_FRACT_TYPE_SIZE)
9157e4b17023SJohn Marino 	return unsignedp ? sat_unsigned_short_fract_type_node
9158e4b17023SJohn Marino 			 : sat_short_fract_type_node;
9159e4b17023SJohn Marino       if (size == FRACT_TYPE_SIZE)
9160e4b17023SJohn Marino 	return unsignedp ? sat_unsigned_fract_type_node : sat_fract_type_node;
9161e4b17023SJohn Marino       if (size == LONG_FRACT_TYPE_SIZE)
9162e4b17023SJohn Marino 	return unsignedp ? sat_unsigned_long_fract_type_node
9163e4b17023SJohn Marino 			 : sat_long_fract_type_node;
9164e4b17023SJohn Marino       if (size == LONG_LONG_FRACT_TYPE_SIZE)
9165e4b17023SJohn Marino 	return unsignedp ? sat_unsigned_long_long_fract_type_node
9166e4b17023SJohn Marino 			 : sat_long_long_fract_type_node;
9167e4b17023SJohn Marino     }
9168e4b17023SJohn Marino   else
9169e4b17023SJohn Marino     {
9170e4b17023SJohn Marino       if (size == SHORT_FRACT_TYPE_SIZE)
9171e4b17023SJohn Marino 	return unsignedp ? unsigned_short_fract_type_node
9172e4b17023SJohn Marino 			 : short_fract_type_node;
9173e4b17023SJohn Marino       if (size == FRACT_TYPE_SIZE)
9174e4b17023SJohn Marino 	return unsignedp ? unsigned_fract_type_node : fract_type_node;
9175e4b17023SJohn Marino       if (size == LONG_FRACT_TYPE_SIZE)
9176e4b17023SJohn Marino 	return unsignedp ? unsigned_long_fract_type_node
9177e4b17023SJohn Marino 			 : long_fract_type_node;
9178e4b17023SJohn Marino       if (size == LONG_LONG_FRACT_TYPE_SIZE)
9179e4b17023SJohn Marino 	return unsignedp ? unsigned_long_long_fract_type_node
9180e4b17023SJohn Marino 			 : long_long_fract_type_node;
9181e4b17023SJohn Marino     }
9182e4b17023SJohn Marino 
9183e4b17023SJohn Marino   return make_fract_type (size, unsignedp, satp);
9184e4b17023SJohn Marino }
9185e4b17023SJohn Marino 
9186e4b17023SJohn Marino /* Create or reuse an accum type by SIZE, UNSIGNEDP, and SATP.  */
9187e4b17023SJohn Marino 
9188e4b17023SJohn Marino static tree
make_or_reuse_accum_type(unsigned size,int unsignedp,int satp)9189e4b17023SJohn Marino make_or_reuse_accum_type (unsigned size, int unsignedp, int satp)
9190e4b17023SJohn Marino {
9191e4b17023SJohn Marino   if (satp)
9192e4b17023SJohn Marino     {
9193e4b17023SJohn Marino       if (size == SHORT_ACCUM_TYPE_SIZE)
9194e4b17023SJohn Marino 	return unsignedp ? sat_unsigned_short_accum_type_node
9195e4b17023SJohn Marino 			 : sat_short_accum_type_node;
9196e4b17023SJohn Marino       if (size == ACCUM_TYPE_SIZE)
9197e4b17023SJohn Marino 	return unsignedp ? sat_unsigned_accum_type_node : sat_accum_type_node;
9198e4b17023SJohn Marino       if (size == LONG_ACCUM_TYPE_SIZE)
9199e4b17023SJohn Marino 	return unsignedp ? sat_unsigned_long_accum_type_node
9200e4b17023SJohn Marino 			 : sat_long_accum_type_node;
9201e4b17023SJohn Marino       if (size == LONG_LONG_ACCUM_TYPE_SIZE)
9202e4b17023SJohn Marino 	return unsignedp ? sat_unsigned_long_long_accum_type_node
9203e4b17023SJohn Marino 			 : sat_long_long_accum_type_node;
9204e4b17023SJohn Marino     }
9205e4b17023SJohn Marino   else
9206e4b17023SJohn Marino     {
9207e4b17023SJohn Marino       if (size == SHORT_ACCUM_TYPE_SIZE)
9208e4b17023SJohn Marino 	return unsignedp ? unsigned_short_accum_type_node
9209e4b17023SJohn Marino 			 : short_accum_type_node;
9210e4b17023SJohn Marino       if (size == ACCUM_TYPE_SIZE)
9211e4b17023SJohn Marino 	return unsignedp ? unsigned_accum_type_node : accum_type_node;
9212e4b17023SJohn Marino       if (size == LONG_ACCUM_TYPE_SIZE)
9213e4b17023SJohn Marino 	return unsignedp ? unsigned_long_accum_type_node
9214e4b17023SJohn Marino 			 : long_accum_type_node;
9215e4b17023SJohn Marino       if (size == LONG_LONG_ACCUM_TYPE_SIZE)
9216e4b17023SJohn Marino 	return unsignedp ? unsigned_long_long_accum_type_node
9217e4b17023SJohn Marino 			 : long_long_accum_type_node;
9218e4b17023SJohn Marino     }
9219e4b17023SJohn Marino 
9220e4b17023SJohn Marino   return make_accum_type (size, unsignedp, satp);
9221e4b17023SJohn Marino }
9222e4b17023SJohn Marino 
9223e4b17023SJohn Marino /* Create nodes for all integer types (and error_mark_node) using the sizes
9224e4b17023SJohn Marino    of C datatypes.  SIGNED_CHAR specifies whether char is signed,
9225e4b17023SJohn Marino    SHORT_DOUBLE specifies whether double should be of the same precision
9226e4b17023SJohn Marino    as float.  */
9227e4b17023SJohn Marino 
9228e4b17023SJohn Marino void
build_common_tree_nodes(bool signed_char,bool short_double)9229e4b17023SJohn Marino build_common_tree_nodes (bool signed_char, bool short_double)
9230e4b17023SJohn Marino {
9231e4b17023SJohn Marino   error_mark_node = make_node (ERROR_MARK);
9232e4b17023SJohn Marino   TREE_TYPE (error_mark_node) = error_mark_node;
9233e4b17023SJohn Marino 
9234e4b17023SJohn Marino   initialize_sizetypes ();
9235e4b17023SJohn Marino 
9236e4b17023SJohn Marino   /* Define both `signed char' and `unsigned char'.  */
9237e4b17023SJohn Marino   signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
9238e4b17023SJohn Marino   TYPE_STRING_FLAG (signed_char_type_node) = 1;
9239e4b17023SJohn Marino   unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
9240e4b17023SJohn Marino   TYPE_STRING_FLAG (unsigned_char_type_node) = 1;
9241e4b17023SJohn Marino 
9242e4b17023SJohn Marino   /* Define `char', which is like either `signed char' or `unsigned char'
9243e4b17023SJohn Marino      but not the same as either.  */
9244e4b17023SJohn Marino   char_type_node
9245e4b17023SJohn Marino     = (signed_char
9246e4b17023SJohn Marino        ? make_signed_type (CHAR_TYPE_SIZE)
9247e4b17023SJohn Marino        : make_unsigned_type (CHAR_TYPE_SIZE));
9248e4b17023SJohn Marino   TYPE_STRING_FLAG (char_type_node) = 1;
9249e4b17023SJohn Marino 
9250e4b17023SJohn Marino   short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
9251e4b17023SJohn Marino   short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
9252e4b17023SJohn Marino   integer_type_node = make_signed_type (INT_TYPE_SIZE);
9253e4b17023SJohn Marino   unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE);
9254e4b17023SJohn Marino   long_integer_type_node = make_signed_type (LONG_TYPE_SIZE);
9255e4b17023SJohn Marino   long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE);
9256e4b17023SJohn Marino   long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE);
9257e4b17023SJohn Marino   long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE);
9258e4b17023SJohn Marino #if HOST_BITS_PER_WIDE_INT >= 64
9259e4b17023SJohn Marino     /* TODO: This isn't correct, but as logic depends at the moment on
9260e4b17023SJohn Marino        host's instead of target's wide-integer.
9261e4b17023SJohn Marino        If there is a target not supporting TImode, but has an 128-bit
9262e4b17023SJohn Marino        integer-scalar register, this target check needs to be adjusted. */
9263e4b17023SJohn Marino     if (targetm.scalar_mode_supported_p (TImode))
9264e4b17023SJohn Marino       {
9265e4b17023SJohn Marino         int128_integer_type_node = make_signed_type (128);
9266e4b17023SJohn Marino         int128_unsigned_type_node = make_unsigned_type (128);
9267e4b17023SJohn Marino       }
9268e4b17023SJohn Marino #endif
9269e4b17023SJohn Marino 
9270e4b17023SJohn Marino   /* Define a boolean type.  This type only represents boolean values but
9271e4b17023SJohn Marino      may be larger than char depending on the value of BOOL_TYPE_SIZE.
9272e4b17023SJohn Marino      Front ends which want to override this size (i.e. Java) can redefine
9273e4b17023SJohn Marino      boolean_type_node before calling build_common_tree_nodes_2.  */
9274e4b17023SJohn Marino   boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
9275e4b17023SJohn Marino   TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
9276e4b17023SJohn Marino   TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1);
9277e4b17023SJohn Marino   TYPE_PRECISION (boolean_type_node) = 1;
9278e4b17023SJohn Marino 
9279e4b17023SJohn Marino   /* Define what type to use for size_t.  */
9280e4b17023SJohn Marino   if (strcmp (SIZE_TYPE, "unsigned int") == 0)
9281e4b17023SJohn Marino     size_type_node = unsigned_type_node;
9282e4b17023SJohn Marino   else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
9283e4b17023SJohn Marino     size_type_node = long_unsigned_type_node;
9284e4b17023SJohn Marino   else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
9285e4b17023SJohn Marino     size_type_node = long_long_unsigned_type_node;
9286e4b17023SJohn Marino   else if (strcmp (SIZE_TYPE, "short unsigned int") == 0)
9287e4b17023SJohn Marino     size_type_node = short_unsigned_type_node;
9288e4b17023SJohn Marino   else
9289e4b17023SJohn Marino     gcc_unreachable ();
9290e4b17023SJohn Marino 
9291e4b17023SJohn Marino   /* Fill in the rest of the sized types.  Reuse existing type nodes
9292e4b17023SJohn Marino      when possible.  */
9293e4b17023SJohn Marino   intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 0);
9294e4b17023SJohn Marino   intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 0);
9295e4b17023SJohn Marino   intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 0);
9296e4b17023SJohn Marino   intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 0);
9297e4b17023SJohn Marino   intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 0);
9298e4b17023SJohn Marino 
9299e4b17023SJohn Marino   unsigned_intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 1);
9300e4b17023SJohn Marino   unsigned_intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 1);
9301e4b17023SJohn Marino   unsigned_intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 1);
9302e4b17023SJohn Marino   unsigned_intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 1);
9303e4b17023SJohn Marino   unsigned_intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 1);
9304e4b17023SJohn Marino 
9305e4b17023SJohn Marino   access_public_node = get_identifier ("public");
9306e4b17023SJohn Marino   access_protected_node = get_identifier ("protected");
9307e4b17023SJohn Marino   access_private_node = get_identifier ("private");
9308e4b17023SJohn Marino 
9309e4b17023SJohn Marino   /* Define these next since types below may used them.  */
9310e4b17023SJohn Marino   integer_zero_node = build_int_cst (integer_type_node, 0);
9311e4b17023SJohn Marino   integer_one_node = build_int_cst (integer_type_node, 1);
9312e4b17023SJohn Marino   integer_three_node = build_int_cst (integer_type_node, 3);
9313e4b17023SJohn Marino   integer_minus_one_node = build_int_cst (integer_type_node, -1);
9314e4b17023SJohn Marino 
9315e4b17023SJohn Marino   size_zero_node = size_int (0);
9316e4b17023SJohn Marino   size_one_node = size_int (1);
9317e4b17023SJohn Marino   bitsize_zero_node = bitsize_int (0);
9318e4b17023SJohn Marino   bitsize_one_node = bitsize_int (1);
9319e4b17023SJohn Marino   bitsize_unit_node = bitsize_int (BITS_PER_UNIT);
9320e4b17023SJohn Marino 
9321e4b17023SJohn Marino   boolean_false_node = TYPE_MIN_VALUE (boolean_type_node);
9322e4b17023SJohn Marino   boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
9323e4b17023SJohn Marino 
9324e4b17023SJohn Marino   void_type_node = make_node (VOID_TYPE);
9325e4b17023SJohn Marino   layout_type (void_type_node);
9326e4b17023SJohn Marino 
9327e4b17023SJohn Marino   /* We are not going to have real types in C with less than byte alignment,
9328e4b17023SJohn Marino      so we might as well not have any types that claim to have it.  */
9329e4b17023SJohn Marino   TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
9330e4b17023SJohn Marino   TYPE_USER_ALIGN (void_type_node) = 0;
9331e4b17023SJohn Marino 
9332e4b17023SJohn Marino   null_pointer_node = build_int_cst (build_pointer_type (void_type_node), 0);
9333e4b17023SJohn Marino   layout_type (TREE_TYPE (null_pointer_node));
9334e4b17023SJohn Marino 
9335e4b17023SJohn Marino   ptr_type_node = build_pointer_type (void_type_node);
9336e4b17023SJohn Marino   const_ptr_type_node
9337e4b17023SJohn Marino     = build_pointer_type (build_type_variant (void_type_node, 1, 0));
9338e4b17023SJohn Marino   fileptr_type_node = ptr_type_node;
9339e4b17023SJohn Marino 
9340e4b17023SJohn Marino   float_type_node = make_node (REAL_TYPE);
9341e4b17023SJohn Marino   TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
9342e4b17023SJohn Marino   layout_type (float_type_node);
9343e4b17023SJohn Marino 
9344e4b17023SJohn Marino   double_type_node = make_node (REAL_TYPE);
9345e4b17023SJohn Marino   if (short_double)
9346e4b17023SJohn Marino     TYPE_PRECISION (double_type_node) = FLOAT_TYPE_SIZE;
9347e4b17023SJohn Marino   else
9348e4b17023SJohn Marino     TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE;
9349e4b17023SJohn Marino   layout_type (double_type_node);
9350e4b17023SJohn Marino 
9351e4b17023SJohn Marino   long_double_type_node = make_node (REAL_TYPE);
9352e4b17023SJohn Marino   TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
9353e4b17023SJohn Marino   layout_type (long_double_type_node);
9354e4b17023SJohn Marino 
9355e4b17023SJohn Marino   float_ptr_type_node = build_pointer_type (float_type_node);
9356e4b17023SJohn Marino   double_ptr_type_node = build_pointer_type (double_type_node);
9357e4b17023SJohn Marino   long_double_ptr_type_node = build_pointer_type (long_double_type_node);
9358e4b17023SJohn Marino   integer_ptr_type_node = build_pointer_type (integer_type_node);
9359e4b17023SJohn Marino 
9360e4b17023SJohn Marino   /* Fixed size integer types.  */
9361e4b17023SJohn Marino   uint32_type_node = build_nonstandard_integer_type (32, true);
9362e4b17023SJohn Marino   uint64_type_node = build_nonstandard_integer_type (64, true);
9363e4b17023SJohn Marino 
9364e4b17023SJohn Marino   /* Decimal float types. */
9365e4b17023SJohn Marino   dfloat32_type_node = make_node (REAL_TYPE);
9366e4b17023SJohn Marino   TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE;
9367e4b17023SJohn Marino   layout_type (dfloat32_type_node);
9368e4b17023SJohn Marino   SET_TYPE_MODE (dfloat32_type_node, SDmode);
9369e4b17023SJohn Marino   dfloat32_ptr_type_node = build_pointer_type (dfloat32_type_node);
9370e4b17023SJohn Marino 
9371e4b17023SJohn Marino   dfloat64_type_node = make_node (REAL_TYPE);
9372e4b17023SJohn Marino   TYPE_PRECISION (dfloat64_type_node) = DECIMAL64_TYPE_SIZE;
9373e4b17023SJohn Marino   layout_type (dfloat64_type_node);
9374e4b17023SJohn Marino   SET_TYPE_MODE (dfloat64_type_node, DDmode);
9375e4b17023SJohn Marino   dfloat64_ptr_type_node = build_pointer_type (dfloat64_type_node);
9376e4b17023SJohn Marino 
9377e4b17023SJohn Marino   dfloat128_type_node = make_node (REAL_TYPE);
9378e4b17023SJohn Marino   TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE;
9379e4b17023SJohn Marino   layout_type (dfloat128_type_node);
9380e4b17023SJohn Marino   SET_TYPE_MODE (dfloat128_type_node, TDmode);
9381e4b17023SJohn Marino   dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);
9382e4b17023SJohn Marino 
9383e4b17023SJohn Marino   complex_integer_type_node = build_complex_type (integer_type_node);
9384e4b17023SJohn Marino   complex_float_type_node = build_complex_type (float_type_node);
9385e4b17023SJohn Marino   complex_double_type_node = build_complex_type (double_type_node);
9386e4b17023SJohn Marino   complex_long_double_type_node = build_complex_type (long_double_type_node);
9387e4b17023SJohn Marino 
9388e4b17023SJohn Marino /* Make fixed-point nodes based on sat/non-sat and signed/unsigned.  */
9389e4b17023SJohn Marino #define MAKE_FIXED_TYPE_NODE(KIND,SIZE) \
9390e4b17023SJohn Marino   sat_ ## KIND ## _type_node = \
9391e4b17023SJohn Marino     make_sat_signed_ ## KIND ## _type (SIZE); \
9392e4b17023SJohn Marino   sat_unsigned_ ## KIND ## _type_node = \
9393e4b17023SJohn Marino     make_sat_unsigned_ ## KIND ## _type (SIZE); \
9394e4b17023SJohn Marino   KIND ## _type_node = make_signed_ ## KIND ## _type (SIZE); \
9395e4b17023SJohn Marino   unsigned_ ## KIND ## _type_node = \
9396e4b17023SJohn Marino     make_unsigned_ ## KIND ## _type (SIZE);
9397e4b17023SJohn Marino 
9398e4b17023SJohn Marino #define MAKE_FIXED_TYPE_NODE_WIDTH(KIND,WIDTH,SIZE) \
9399e4b17023SJohn Marino   sat_ ## WIDTH ## KIND ## _type_node = \
9400e4b17023SJohn Marino     make_sat_signed_ ## KIND ## _type (SIZE); \
9401e4b17023SJohn Marino   sat_unsigned_ ## WIDTH ## KIND ## _type_node = \
9402e4b17023SJohn Marino     make_sat_unsigned_ ## KIND ## _type (SIZE); \
9403e4b17023SJohn Marino   WIDTH ## KIND ## _type_node = make_signed_ ## KIND ## _type (SIZE); \
9404e4b17023SJohn Marino   unsigned_ ## WIDTH ## KIND ## _type_node = \
9405e4b17023SJohn Marino     make_unsigned_ ## KIND ## _type (SIZE);
9406e4b17023SJohn Marino 
9407e4b17023SJohn Marino /* Make fixed-point type nodes based on four different widths.  */
9408e4b17023SJohn Marino #define MAKE_FIXED_TYPE_NODE_FAMILY(N1,N2) \
9409e4b17023SJohn Marino   MAKE_FIXED_TYPE_NODE_WIDTH (N1, short_, SHORT_ ## N2 ## _TYPE_SIZE) \
9410e4b17023SJohn Marino   MAKE_FIXED_TYPE_NODE (N1, N2 ## _TYPE_SIZE) \
9411e4b17023SJohn Marino   MAKE_FIXED_TYPE_NODE_WIDTH (N1, long_, LONG_ ## N2 ## _TYPE_SIZE) \
9412e4b17023SJohn Marino   MAKE_FIXED_TYPE_NODE_WIDTH (N1, long_long_, LONG_LONG_ ## N2 ## _TYPE_SIZE)
9413e4b17023SJohn Marino 
9414e4b17023SJohn Marino /* Make fixed-point mode nodes based on sat/non-sat and signed/unsigned.  */
9415e4b17023SJohn Marino #define MAKE_FIXED_MODE_NODE(KIND,NAME,MODE) \
9416e4b17023SJohn Marino   NAME ## _type_node = \
9417e4b17023SJohn Marino     make_or_reuse_signed_ ## KIND ## _type (GET_MODE_BITSIZE (MODE ## mode)); \
9418e4b17023SJohn Marino   u ## NAME ## _type_node = \
9419e4b17023SJohn Marino     make_or_reuse_unsigned_ ## KIND ## _type \
9420e4b17023SJohn Marino       (GET_MODE_BITSIZE (U ## MODE ## mode)); \
9421e4b17023SJohn Marino   sat_ ## NAME ## _type_node = \
9422e4b17023SJohn Marino     make_or_reuse_sat_signed_ ## KIND ## _type \
9423e4b17023SJohn Marino       (GET_MODE_BITSIZE (MODE ## mode)); \
9424e4b17023SJohn Marino   sat_u ## NAME ## _type_node = \
9425e4b17023SJohn Marino     make_or_reuse_sat_unsigned_ ## KIND ## _type \
9426e4b17023SJohn Marino       (GET_MODE_BITSIZE (U ## MODE ## mode));
9427e4b17023SJohn Marino 
9428e4b17023SJohn Marino   /* Fixed-point type and mode nodes.  */
9429e4b17023SJohn Marino   MAKE_FIXED_TYPE_NODE_FAMILY (fract, FRACT)
9430e4b17023SJohn Marino   MAKE_FIXED_TYPE_NODE_FAMILY (accum, ACCUM)
9431e4b17023SJohn Marino   MAKE_FIXED_MODE_NODE (fract, qq, QQ)
9432e4b17023SJohn Marino   MAKE_FIXED_MODE_NODE (fract, hq, HQ)
9433e4b17023SJohn Marino   MAKE_FIXED_MODE_NODE (fract, sq, SQ)
9434e4b17023SJohn Marino   MAKE_FIXED_MODE_NODE (fract, dq, DQ)
9435e4b17023SJohn Marino   MAKE_FIXED_MODE_NODE (fract, tq, TQ)
9436e4b17023SJohn Marino   MAKE_FIXED_MODE_NODE (accum, ha, HA)
9437e4b17023SJohn Marino   MAKE_FIXED_MODE_NODE (accum, sa, SA)
9438e4b17023SJohn Marino   MAKE_FIXED_MODE_NODE (accum, da, DA)
9439e4b17023SJohn Marino   MAKE_FIXED_MODE_NODE (accum, ta, TA)
9440e4b17023SJohn Marino 
9441e4b17023SJohn Marino   {
9442e4b17023SJohn Marino     tree t = targetm.build_builtin_va_list ();
9443e4b17023SJohn Marino 
9444e4b17023SJohn Marino     /* Many back-ends define record types without setting TYPE_NAME.
9445e4b17023SJohn Marino        If we copied the record type here, we'd keep the original
9446e4b17023SJohn Marino        record type without a name.  This breaks name mangling.  So,
9447e4b17023SJohn Marino        don't copy record types and let c_common_nodes_and_builtins()
9448e4b17023SJohn Marino        declare the type to be __builtin_va_list.  */
9449e4b17023SJohn Marino     if (TREE_CODE (t) != RECORD_TYPE)
9450e4b17023SJohn Marino       t = build_variant_type_copy (t);
9451e4b17023SJohn Marino 
9452e4b17023SJohn Marino     va_list_type_node = t;
9453e4b17023SJohn Marino   }
9454e4b17023SJohn Marino }
9455e4b17023SJohn Marino 
9456e4b17023SJohn Marino /* A subroutine of build_common_builtin_nodes.  Define a builtin function.  */
9457e4b17023SJohn Marino 
9458e4b17023SJohn Marino static void
local_define_builtin(const char * name,tree type,enum built_in_function code,const char * library_name,int ecf_flags)9459e4b17023SJohn Marino local_define_builtin (const char *name, tree type, enum built_in_function code,
9460e4b17023SJohn Marino                       const char *library_name, int ecf_flags)
9461e4b17023SJohn Marino {
9462e4b17023SJohn Marino   tree decl;
9463e4b17023SJohn Marino 
9464e4b17023SJohn Marino   decl = add_builtin_function (name, type, code, BUILT_IN_NORMAL,
9465e4b17023SJohn Marino 			       library_name, NULL_TREE);
9466e4b17023SJohn Marino   if (ecf_flags & ECF_CONST)
9467e4b17023SJohn Marino     TREE_READONLY (decl) = 1;
9468e4b17023SJohn Marino   if (ecf_flags & ECF_PURE)
9469e4b17023SJohn Marino     DECL_PURE_P (decl) = 1;
9470e4b17023SJohn Marino   if (ecf_flags & ECF_LOOPING_CONST_OR_PURE)
9471e4b17023SJohn Marino     DECL_LOOPING_CONST_OR_PURE_P (decl) = 1;
9472e4b17023SJohn Marino   if (ecf_flags & ECF_NORETURN)
9473e4b17023SJohn Marino     TREE_THIS_VOLATILE (decl) = 1;
9474e4b17023SJohn Marino   if (ecf_flags & ECF_NOTHROW)
9475e4b17023SJohn Marino     TREE_NOTHROW (decl) = 1;
9476e4b17023SJohn Marino   if (ecf_flags & ECF_MALLOC)
9477e4b17023SJohn Marino     DECL_IS_MALLOC (decl) = 1;
9478e4b17023SJohn Marino   if (ecf_flags & ECF_LEAF)
9479e4b17023SJohn Marino     DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
9480e4b17023SJohn Marino 					NULL, DECL_ATTRIBUTES (decl));
9481e4b17023SJohn Marino   if ((ecf_flags & ECF_TM_PURE) && flag_tm)
9482e4b17023SJohn Marino     apply_tm_attr (decl, get_identifier ("transaction_pure"));
9483e4b17023SJohn Marino 
9484e4b17023SJohn Marino   set_builtin_decl (code, decl, true);
9485e4b17023SJohn Marino }
9486e4b17023SJohn Marino 
9487e4b17023SJohn Marino /* Call this function after instantiating all builtins that the language
9488e4b17023SJohn Marino    front end cares about.  This will build the rest of the builtins that
9489e4b17023SJohn Marino    are relied upon by the tree optimizers and the middle-end.  */
9490e4b17023SJohn Marino 
9491e4b17023SJohn Marino void
build_common_builtin_nodes(void)9492e4b17023SJohn Marino build_common_builtin_nodes (void)
9493e4b17023SJohn Marino {
9494e4b17023SJohn Marino   tree tmp, ftype;
9495e4b17023SJohn Marino   int ecf_flags;
9496e4b17023SJohn Marino 
9497e4b17023SJohn Marino   if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY)
9498e4b17023SJohn Marino       || !builtin_decl_explicit_p (BUILT_IN_MEMMOVE))
9499e4b17023SJohn Marino     {
9500e4b17023SJohn Marino       ftype = build_function_type_list (ptr_type_node,
9501e4b17023SJohn Marino 					ptr_type_node, const_ptr_type_node,
9502e4b17023SJohn Marino 					size_type_node, NULL_TREE);
9503e4b17023SJohn Marino 
9504e4b17023SJohn Marino       if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY))
9505e4b17023SJohn Marino 	local_define_builtin ("__builtin_memcpy", ftype, BUILT_IN_MEMCPY,
9506e4b17023SJohn Marino 			      "memcpy", ECF_NOTHROW | ECF_LEAF);
9507e4b17023SJohn Marino       if (!builtin_decl_explicit_p (BUILT_IN_MEMMOVE))
9508e4b17023SJohn Marino 	local_define_builtin ("__builtin_memmove", ftype, BUILT_IN_MEMMOVE,
9509e4b17023SJohn Marino 			      "memmove", ECF_NOTHROW | ECF_LEAF);
9510e4b17023SJohn Marino     }
9511e4b17023SJohn Marino 
9512e4b17023SJohn Marino   if (!builtin_decl_explicit_p (BUILT_IN_MEMCMP))
9513e4b17023SJohn Marino     {
9514e4b17023SJohn Marino       ftype = build_function_type_list (integer_type_node, const_ptr_type_node,
9515e4b17023SJohn Marino 					const_ptr_type_node, size_type_node,
9516e4b17023SJohn Marino 					NULL_TREE);
9517e4b17023SJohn Marino       local_define_builtin ("__builtin_memcmp", ftype, BUILT_IN_MEMCMP,
9518e4b17023SJohn Marino 			    "memcmp", ECF_PURE | ECF_NOTHROW | ECF_LEAF);
9519e4b17023SJohn Marino     }
9520e4b17023SJohn Marino 
9521e4b17023SJohn Marino   if (!builtin_decl_explicit_p (BUILT_IN_MEMSET))
9522e4b17023SJohn Marino     {
9523e4b17023SJohn Marino       ftype = build_function_type_list (ptr_type_node,
9524e4b17023SJohn Marino 					ptr_type_node, integer_type_node,
9525e4b17023SJohn Marino 					size_type_node, NULL_TREE);
9526e4b17023SJohn Marino       local_define_builtin ("__builtin_memset", ftype, BUILT_IN_MEMSET,
9527e4b17023SJohn Marino 			    "memset", ECF_NOTHROW | ECF_LEAF);
9528e4b17023SJohn Marino     }
9529e4b17023SJohn Marino 
9530e4b17023SJohn Marino   if (!builtin_decl_explicit_p (BUILT_IN_ALLOCA))
9531e4b17023SJohn Marino     {
9532e4b17023SJohn Marino       ftype = build_function_type_list (ptr_type_node,
9533e4b17023SJohn Marino 					size_type_node, NULL_TREE);
9534e4b17023SJohn Marino       local_define_builtin ("__builtin_alloca", ftype, BUILT_IN_ALLOCA,
9535e4b17023SJohn Marino 			    "alloca", ECF_MALLOC | ECF_NOTHROW | ECF_LEAF);
9536e4b17023SJohn Marino     }
9537e4b17023SJohn Marino 
9538e4b17023SJohn Marino   ftype = build_function_type_list (ptr_type_node, size_type_node,
9539e4b17023SJohn Marino 				    size_type_node, NULL_TREE);
9540e4b17023SJohn Marino   local_define_builtin ("__builtin_alloca_with_align", ftype,
9541e4b17023SJohn Marino 			BUILT_IN_ALLOCA_WITH_ALIGN, "alloca",
9542e4b17023SJohn Marino 			ECF_MALLOC | ECF_NOTHROW | ECF_LEAF);
9543e4b17023SJohn Marino 
9544e4b17023SJohn Marino   /* If we're checking the stack, `alloca' can throw.  */
9545e4b17023SJohn Marino   if (flag_stack_check)
9546e4b17023SJohn Marino     {
9547e4b17023SJohn Marino       TREE_NOTHROW (builtin_decl_explicit (BUILT_IN_ALLOCA)) = 0;
9548e4b17023SJohn Marino       TREE_NOTHROW (builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN)) = 0;
9549e4b17023SJohn Marino     }
9550e4b17023SJohn Marino 
9551e4b17023SJohn Marino   ftype = build_function_type_list (void_type_node,
9552e4b17023SJohn Marino 				    ptr_type_node, ptr_type_node,
9553e4b17023SJohn Marino 				    ptr_type_node, NULL_TREE);
9554e4b17023SJohn Marino   local_define_builtin ("__builtin_init_trampoline", ftype,
9555e4b17023SJohn Marino 			BUILT_IN_INIT_TRAMPOLINE,
9556e4b17023SJohn Marino 			"__builtin_init_trampoline", ECF_NOTHROW | ECF_LEAF);
9557e4b17023SJohn Marino   local_define_builtin ("__builtin_init_heap_trampoline", ftype,
9558e4b17023SJohn Marino 			BUILT_IN_INIT_HEAP_TRAMPOLINE,
9559e4b17023SJohn Marino 			"__builtin_init_heap_trampoline",
9560e4b17023SJohn Marino 			ECF_NOTHROW | ECF_LEAF);
9561e4b17023SJohn Marino 
9562e4b17023SJohn Marino   ftype = build_function_type_list (ptr_type_node, ptr_type_node, NULL_TREE);
9563e4b17023SJohn Marino   local_define_builtin ("__builtin_adjust_trampoline", ftype,
9564e4b17023SJohn Marino 			BUILT_IN_ADJUST_TRAMPOLINE,
9565e4b17023SJohn Marino 			"__builtin_adjust_trampoline",
9566e4b17023SJohn Marino 			ECF_CONST | ECF_NOTHROW);
9567e4b17023SJohn Marino 
9568e4b17023SJohn Marino   ftype = build_function_type_list (void_type_node,
9569e4b17023SJohn Marino 				    ptr_type_node, ptr_type_node, NULL_TREE);
9570e4b17023SJohn Marino   local_define_builtin ("__builtin_nonlocal_goto", ftype,
9571e4b17023SJohn Marino 			BUILT_IN_NONLOCAL_GOTO,
9572e4b17023SJohn Marino 			"__builtin_nonlocal_goto",
9573e4b17023SJohn Marino 			ECF_NORETURN | ECF_NOTHROW);
9574e4b17023SJohn Marino 
9575e4b17023SJohn Marino   ftype = build_function_type_list (void_type_node,
9576e4b17023SJohn Marino 				    ptr_type_node, ptr_type_node, NULL_TREE);
9577e4b17023SJohn Marino   local_define_builtin ("__builtin_setjmp_setup", ftype,
9578e4b17023SJohn Marino 			BUILT_IN_SETJMP_SETUP,
9579e4b17023SJohn Marino 			"__builtin_setjmp_setup", ECF_NOTHROW);
9580e4b17023SJohn Marino 
9581e4b17023SJohn Marino   ftype = build_function_type_list (ptr_type_node, ptr_type_node, NULL_TREE);
9582e4b17023SJohn Marino   local_define_builtin ("__builtin_setjmp_dispatcher", ftype,
9583e4b17023SJohn Marino 			BUILT_IN_SETJMP_DISPATCHER,
9584e4b17023SJohn Marino 			"__builtin_setjmp_dispatcher",
9585e4b17023SJohn Marino 			ECF_PURE | ECF_NOTHROW);
9586e4b17023SJohn Marino 
9587e4b17023SJohn Marino   ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
9588e4b17023SJohn Marino   local_define_builtin ("__builtin_setjmp_receiver", ftype,
9589e4b17023SJohn Marino 			BUILT_IN_SETJMP_RECEIVER,
9590e4b17023SJohn Marino 			"__builtin_setjmp_receiver", ECF_NOTHROW);
9591e4b17023SJohn Marino 
9592e4b17023SJohn Marino   ftype = build_function_type_list (ptr_type_node, NULL_TREE);
9593e4b17023SJohn Marino   local_define_builtin ("__builtin_stack_save", ftype, BUILT_IN_STACK_SAVE,
9594e4b17023SJohn Marino 			"__builtin_stack_save", ECF_NOTHROW | ECF_LEAF);
9595e4b17023SJohn Marino 
9596e4b17023SJohn Marino   ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
9597e4b17023SJohn Marino   local_define_builtin ("__builtin_stack_restore", ftype,
9598e4b17023SJohn Marino 			BUILT_IN_STACK_RESTORE,
9599e4b17023SJohn Marino 			"__builtin_stack_restore", ECF_NOTHROW | ECF_LEAF);
9600e4b17023SJohn Marino 
9601e4b17023SJohn Marino   /* If there's a possibility that we might use the ARM EABI, build the
9602e4b17023SJohn Marino     alternate __cxa_end_cleanup node used to resume from C++ and Java.  */
9603e4b17023SJohn Marino   if (targetm.arm_eabi_unwinder)
9604e4b17023SJohn Marino     {
9605e4b17023SJohn Marino       ftype = build_function_type_list (void_type_node, NULL_TREE);
9606e4b17023SJohn Marino       local_define_builtin ("__builtin_cxa_end_cleanup", ftype,
9607e4b17023SJohn Marino 			    BUILT_IN_CXA_END_CLEANUP,
9608e4b17023SJohn Marino 			    "__cxa_end_cleanup", ECF_NORETURN | ECF_LEAF);
9609e4b17023SJohn Marino     }
9610e4b17023SJohn Marino 
9611e4b17023SJohn Marino   ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
9612e4b17023SJohn Marino   local_define_builtin ("__builtin_unwind_resume", ftype,
9613e4b17023SJohn Marino 			BUILT_IN_UNWIND_RESUME,
9614e4b17023SJohn Marino 			((targetm_common.except_unwind_info (&global_options)
9615e4b17023SJohn Marino 			  == UI_SJLJ)
9616e4b17023SJohn Marino 			 ? "_Unwind_SjLj_Resume" : "_Unwind_Resume"),
9617e4b17023SJohn Marino 			ECF_NORETURN);
9618e4b17023SJohn Marino 
9619e4b17023SJohn Marino   if (builtin_decl_explicit (BUILT_IN_RETURN_ADDRESS) == NULL_TREE)
9620e4b17023SJohn Marino     {
9621e4b17023SJohn Marino       ftype = build_function_type_list (ptr_type_node, integer_type_node,
9622e4b17023SJohn Marino 					NULL_TREE);
9623e4b17023SJohn Marino       local_define_builtin ("__builtin_return_address", ftype,
9624e4b17023SJohn Marino 			    BUILT_IN_RETURN_ADDRESS,
9625e4b17023SJohn Marino 			    "__builtin_return_address",
9626e4b17023SJohn Marino 			    ECF_NOTHROW);
9627e4b17023SJohn Marino     }
9628e4b17023SJohn Marino 
9629e4b17023SJohn Marino   if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_ENTER)
9630e4b17023SJohn Marino       || !builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_EXIT))
9631e4b17023SJohn Marino     {
9632e4b17023SJohn Marino       ftype = build_function_type_list (void_type_node, ptr_type_node,
9633e4b17023SJohn Marino 					ptr_type_node, NULL_TREE);
9634e4b17023SJohn Marino       if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_ENTER))
9635e4b17023SJohn Marino 	local_define_builtin ("__cyg_profile_func_enter", ftype,
9636e4b17023SJohn Marino 			      BUILT_IN_PROFILE_FUNC_ENTER,
9637e4b17023SJohn Marino 			      "__cyg_profile_func_enter", 0);
9638e4b17023SJohn Marino       if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_EXIT))
9639e4b17023SJohn Marino 	local_define_builtin ("__cyg_profile_func_exit", ftype,
9640e4b17023SJohn Marino 			      BUILT_IN_PROFILE_FUNC_EXIT,
9641e4b17023SJohn Marino 			      "__cyg_profile_func_exit", 0);
9642e4b17023SJohn Marino     }
9643e4b17023SJohn Marino 
9644e4b17023SJohn Marino   /* The exception object and filter values from the runtime.  The argument
9645e4b17023SJohn Marino      must be zero before exception lowering, i.e. from the front end.  After
9646e4b17023SJohn Marino      exception lowering, it will be the region number for the exception
9647e4b17023SJohn Marino      landing pad.  These functions are PURE instead of CONST to prevent
9648e4b17023SJohn Marino      them from being hoisted past the exception edge that will initialize
9649e4b17023SJohn Marino      its value in the landing pad.  */
9650e4b17023SJohn Marino   ftype = build_function_type_list (ptr_type_node,
9651e4b17023SJohn Marino 				    integer_type_node, NULL_TREE);
9652e4b17023SJohn Marino   ecf_flags = ECF_PURE | ECF_NOTHROW | ECF_LEAF;
9653e4b17023SJohn Marino   /* Only use TM_PURE if we we have TM language support.  */
9654e4b17023SJohn Marino   if (builtin_decl_explicit_p (BUILT_IN_TM_LOAD_1))
9655e4b17023SJohn Marino     ecf_flags |= ECF_TM_PURE;
9656e4b17023SJohn Marino   local_define_builtin ("__builtin_eh_pointer", ftype, BUILT_IN_EH_POINTER,
9657e4b17023SJohn Marino 			"__builtin_eh_pointer", ecf_flags);
9658e4b17023SJohn Marino 
9659e4b17023SJohn Marino   tmp = lang_hooks.types.type_for_mode (targetm.eh_return_filter_mode (), 0);
9660e4b17023SJohn Marino   ftype = build_function_type_list (tmp, integer_type_node, NULL_TREE);
9661e4b17023SJohn Marino   local_define_builtin ("__builtin_eh_filter", ftype, BUILT_IN_EH_FILTER,
9662e4b17023SJohn Marino 			"__builtin_eh_filter", ECF_PURE | ECF_NOTHROW | ECF_LEAF);
9663e4b17023SJohn Marino 
9664e4b17023SJohn Marino   ftype = build_function_type_list (void_type_node,
9665e4b17023SJohn Marino 				    integer_type_node, integer_type_node,
9666e4b17023SJohn Marino 				    NULL_TREE);
9667e4b17023SJohn Marino   local_define_builtin ("__builtin_eh_copy_values", ftype,
9668e4b17023SJohn Marino 			BUILT_IN_EH_COPY_VALUES,
9669e4b17023SJohn Marino 			"__builtin_eh_copy_values", ECF_NOTHROW);
9670e4b17023SJohn Marino 
9671e4b17023SJohn Marino   /* Complex multiplication and division.  These are handled as builtins
9672e4b17023SJohn Marino      rather than optabs because emit_library_call_value doesn't support
9673e4b17023SJohn Marino      complex.  Further, we can do slightly better with folding these
9674e4b17023SJohn Marino      beasties if the real and complex parts of the arguments are separate.  */
9675e4b17023SJohn Marino   {
9676e4b17023SJohn Marino     int mode;
9677e4b17023SJohn Marino 
9678e4b17023SJohn Marino     for (mode = MIN_MODE_COMPLEX_FLOAT; mode <= MAX_MODE_COMPLEX_FLOAT; ++mode)
9679e4b17023SJohn Marino       {
9680e4b17023SJohn Marino 	char mode_name_buf[4], *q;
9681e4b17023SJohn Marino 	const char *p;
9682e4b17023SJohn Marino 	enum built_in_function mcode, dcode;
9683e4b17023SJohn Marino 	tree type, inner_type;
9684e4b17023SJohn Marino 	const char *prefix = "__";
9685e4b17023SJohn Marino 
9686e4b17023SJohn Marino 	if (targetm.libfunc_gnu_prefix)
9687e4b17023SJohn Marino 	  prefix = "__gnu_";
9688e4b17023SJohn Marino 
9689e4b17023SJohn Marino 	type = lang_hooks.types.type_for_mode ((enum machine_mode) mode, 0);
9690e4b17023SJohn Marino 	if (type == NULL)
9691e4b17023SJohn Marino 	  continue;
9692e4b17023SJohn Marino 	inner_type = TREE_TYPE (type);
9693e4b17023SJohn Marino 
9694e4b17023SJohn Marino 	ftype = build_function_type_list (type, inner_type, inner_type,
9695e4b17023SJohn Marino 					  inner_type, inner_type, NULL_TREE);
9696e4b17023SJohn Marino 
9697e4b17023SJohn Marino         mcode = ((enum built_in_function)
9698e4b17023SJohn Marino 		 (BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
9699e4b17023SJohn Marino         dcode = ((enum built_in_function)
9700e4b17023SJohn Marino 		 (BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT));
9701e4b17023SJohn Marino 
9702e4b17023SJohn Marino         for (p = GET_MODE_NAME (mode), q = mode_name_buf; *p; p++, q++)
9703e4b17023SJohn Marino 	  *q = TOLOWER (*p);
9704e4b17023SJohn Marino 	*q = '\0';
9705e4b17023SJohn Marino 
9706e4b17023SJohn Marino 	built_in_names[mcode] = concat (prefix, "mul", mode_name_buf, "3",
9707e4b17023SJohn Marino 					NULL);
9708e4b17023SJohn Marino         local_define_builtin (built_in_names[mcode], ftype, mcode,
9709e4b17023SJohn Marino 			      built_in_names[mcode],
9710e4b17023SJohn Marino 			      ECF_CONST | ECF_NOTHROW | ECF_LEAF);
9711e4b17023SJohn Marino 
9712e4b17023SJohn Marino 	built_in_names[dcode] = concat (prefix, "div", mode_name_buf, "3",
9713e4b17023SJohn Marino 					NULL);
9714e4b17023SJohn Marino         local_define_builtin (built_in_names[dcode], ftype, dcode,
9715e4b17023SJohn Marino 			      built_in_names[dcode],
9716e4b17023SJohn Marino 			      ECF_CONST | ECF_NOTHROW | ECF_LEAF);
9717e4b17023SJohn Marino       }
9718e4b17023SJohn Marino   }
9719e4b17023SJohn Marino }
9720e4b17023SJohn Marino 
9721e4b17023SJohn Marino /* HACK.  GROSS.  This is absolutely disgusting.  I wish there was a
9722e4b17023SJohn Marino    better way.
9723e4b17023SJohn Marino 
9724e4b17023SJohn Marino    If we requested a pointer to a vector, build up the pointers that
9725e4b17023SJohn Marino    we stripped off while looking for the inner type.  Similarly for
9726e4b17023SJohn Marino    return values from functions.
9727e4b17023SJohn Marino 
9728e4b17023SJohn Marino    The argument TYPE is the top of the chain, and BOTTOM is the
9729e4b17023SJohn Marino    new type which we will point to.  */
9730e4b17023SJohn Marino 
9731e4b17023SJohn Marino tree
reconstruct_complex_type(tree type,tree bottom)9732e4b17023SJohn Marino reconstruct_complex_type (tree type, tree bottom)
9733e4b17023SJohn Marino {
9734e4b17023SJohn Marino   tree inner, outer;
9735e4b17023SJohn Marino 
9736e4b17023SJohn Marino   if (TREE_CODE (type) == POINTER_TYPE)
9737e4b17023SJohn Marino     {
9738e4b17023SJohn Marino       inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
9739e4b17023SJohn Marino       outer = build_pointer_type_for_mode (inner, TYPE_MODE (type),
9740e4b17023SJohn Marino 					   TYPE_REF_CAN_ALIAS_ALL (type));
9741e4b17023SJohn Marino     }
9742e4b17023SJohn Marino   else if (TREE_CODE (type) == REFERENCE_TYPE)
9743e4b17023SJohn Marino     {
9744e4b17023SJohn Marino       inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
9745e4b17023SJohn Marino       outer = build_reference_type_for_mode (inner, TYPE_MODE (type),
9746e4b17023SJohn Marino 					     TYPE_REF_CAN_ALIAS_ALL (type));
9747e4b17023SJohn Marino     }
9748e4b17023SJohn Marino   else if (TREE_CODE (type) == ARRAY_TYPE)
9749e4b17023SJohn Marino     {
9750e4b17023SJohn Marino       inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
9751e4b17023SJohn Marino       outer = build_array_type (inner, TYPE_DOMAIN (type));
9752e4b17023SJohn Marino     }
9753e4b17023SJohn Marino   else if (TREE_CODE (type) == FUNCTION_TYPE)
9754e4b17023SJohn Marino     {
9755e4b17023SJohn Marino       inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
9756e4b17023SJohn Marino       outer = build_function_type (inner, TYPE_ARG_TYPES (type));
9757e4b17023SJohn Marino     }
9758e4b17023SJohn Marino   else if (TREE_CODE (type) == METHOD_TYPE)
9759e4b17023SJohn Marino     {
9760e4b17023SJohn Marino       inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
9761e4b17023SJohn Marino       /* The build_method_type_directly() routine prepends 'this' to argument list,
9762e4b17023SJohn Marino          so we must compensate by getting rid of it.  */
9763e4b17023SJohn Marino       outer
9764e4b17023SJohn Marino 	= build_method_type_directly
9765e4b17023SJohn Marino 	    (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))),
9766e4b17023SJohn Marino 	     inner,
9767e4b17023SJohn Marino 	     TREE_CHAIN (TYPE_ARG_TYPES (type)));
9768e4b17023SJohn Marino     }
9769e4b17023SJohn Marino   else if (TREE_CODE (type) == OFFSET_TYPE)
9770e4b17023SJohn Marino     {
9771e4b17023SJohn Marino       inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
9772e4b17023SJohn Marino       outer = build_offset_type (TYPE_OFFSET_BASETYPE (type), inner);
9773e4b17023SJohn Marino     }
9774e4b17023SJohn Marino   else
9775e4b17023SJohn Marino     return bottom;
9776e4b17023SJohn Marino 
9777e4b17023SJohn Marino   return build_type_attribute_qual_variant (outer, TYPE_ATTRIBUTES (type),
9778e4b17023SJohn Marino 					    TYPE_QUALS (type));
9779e4b17023SJohn Marino }
9780e4b17023SJohn Marino 
9781e4b17023SJohn Marino /* Returns a vector tree node given a mode (integer, vector, or BLKmode) and
9782e4b17023SJohn Marino    the inner type.  */
9783e4b17023SJohn Marino tree
build_vector_type_for_mode(tree innertype,enum machine_mode mode)9784e4b17023SJohn Marino build_vector_type_for_mode (tree innertype, enum machine_mode mode)
9785e4b17023SJohn Marino {
9786e4b17023SJohn Marino   int nunits;
9787e4b17023SJohn Marino 
9788e4b17023SJohn Marino   switch (GET_MODE_CLASS (mode))
9789e4b17023SJohn Marino     {
9790e4b17023SJohn Marino     case MODE_VECTOR_INT:
9791e4b17023SJohn Marino     case MODE_VECTOR_FLOAT:
9792e4b17023SJohn Marino     case MODE_VECTOR_FRACT:
9793e4b17023SJohn Marino     case MODE_VECTOR_UFRACT:
9794e4b17023SJohn Marino     case MODE_VECTOR_ACCUM:
9795e4b17023SJohn Marino     case MODE_VECTOR_UACCUM:
9796e4b17023SJohn Marino       nunits = GET_MODE_NUNITS (mode);
9797e4b17023SJohn Marino       break;
9798e4b17023SJohn Marino 
9799e4b17023SJohn Marino     case MODE_INT:
9800e4b17023SJohn Marino       /* Check that there are no leftover bits.  */
9801e4b17023SJohn Marino       gcc_assert (GET_MODE_BITSIZE (mode)
9802e4b17023SJohn Marino 		  % TREE_INT_CST_LOW (TYPE_SIZE (innertype)) == 0);
9803e4b17023SJohn Marino 
9804e4b17023SJohn Marino       nunits = GET_MODE_BITSIZE (mode)
9805e4b17023SJohn Marino 	       / TREE_INT_CST_LOW (TYPE_SIZE (innertype));
9806e4b17023SJohn Marino       break;
9807e4b17023SJohn Marino 
9808e4b17023SJohn Marino     default:
9809e4b17023SJohn Marino       gcc_unreachable ();
9810e4b17023SJohn Marino     }
9811e4b17023SJohn Marino 
9812e4b17023SJohn Marino   return make_vector_type (innertype, nunits, mode);
9813e4b17023SJohn Marino }
9814e4b17023SJohn Marino 
9815e4b17023SJohn Marino /* Similarly, but takes the inner type and number of units, which must be
9816e4b17023SJohn Marino    a power of two.  */
9817e4b17023SJohn Marino 
9818e4b17023SJohn Marino tree
build_vector_type(tree innertype,int nunits)9819e4b17023SJohn Marino build_vector_type (tree innertype, int nunits)
9820e4b17023SJohn Marino {
9821e4b17023SJohn Marino   return make_vector_type (innertype, nunits, VOIDmode);
9822e4b17023SJohn Marino }
9823e4b17023SJohn Marino 
9824e4b17023SJohn Marino /* Similarly, but builds a variant type with TYPE_VECTOR_OPAQUE set.  */
9825e4b17023SJohn Marino 
9826e4b17023SJohn Marino tree
build_opaque_vector_type(tree innertype,int nunits)9827e4b17023SJohn Marino build_opaque_vector_type (tree innertype, int nunits)
9828e4b17023SJohn Marino {
9829e4b17023SJohn Marino   tree t = make_vector_type (innertype, nunits, VOIDmode);
9830e4b17023SJohn Marino   tree cand;
9831e4b17023SJohn Marino   /* We always build the non-opaque variant before the opaque one,
9832e4b17023SJohn Marino      so if it already exists, it is TYPE_NEXT_VARIANT of this one.  */
9833e4b17023SJohn Marino   cand = TYPE_NEXT_VARIANT (t);
9834e4b17023SJohn Marino   if (cand
9835e4b17023SJohn Marino       && TYPE_VECTOR_OPAQUE (cand)
9836e4b17023SJohn Marino       && check_qualified_type (cand, t, TYPE_QUALS (t)))
9837e4b17023SJohn Marino     return cand;
9838e4b17023SJohn Marino   /* Othewise build a variant type and make sure to queue it after
9839e4b17023SJohn Marino      the non-opaque type.  */
9840e4b17023SJohn Marino   cand = build_distinct_type_copy (t);
9841e4b17023SJohn Marino   TYPE_VECTOR_OPAQUE (cand) = true;
9842e4b17023SJohn Marino   TYPE_CANONICAL (cand) = TYPE_CANONICAL (t);
9843e4b17023SJohn Marino   TYPE_NEXT_VARIANT (cand) = TYPE_NEXT_VARIANT (t);
9844e4b17023SJohn Marino   TYPE_NEXT_VARIANT (t) = cand;
9845e4b17023SJohn Marino   TYPE_MAIN_VARIANT (cand) = TYPE_MAIN_VARIANT (t);
9846e4b17023SJohn Marino   return cand;
9847e4b17023SJohn Marino }
9848e4b17023SJohn Marino 
9849e4b17023SJohn Marino 
9850e4b17023SJohn Marino /* Given an initializer INIT, return TRUE if INIT is zero or some
9851e4b17023SJohn Marino    aggregate of zeros.  Otherwise return FALSE.  */
9852e4b17023SJohn Marino bool
initializer_zerop(const_tree init)9853e4b17023SJohn Marino initializer_zerop (const_tree init)
9854e4b17023SJohn Marino {
9855e4b17023SJohn Marino   tree elt;
9856e4b17023SJohn Marino 
9857e4b17023SJohn Marino   STRIP_NOPS (init);
9858e4b17023SJohn Marino 
9859e4b17023SJohn Marino   switch (TREE_CODE (init))
9860e4b17023SJohn Marino     {
9861e4b17023SJohn Marino     case INTEGER_CST:
9862e4b17023SJohn Marino       return integer_zerop (init);
9863e4b17023SJohn Marino 
9864e4b17023SJohn Marino     case REAL_CST:
9865e4b17023SJohn Marino       /* ??? Note that this is not correct for C4X float formats.  There,
9866e4b17023SJohn Marino 	 a bit pattern of all zeros is 1.0; 0.0 is encoded with the most
9867e4b17023SJohn Marino 	 negative exponent.  */
9868e4b17023SJohn Marino       return real_zerop (init)
9869e4b17023SJohn Marino 	&& ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (init));
9870e4b17023SJohn Marino 
9871e4b17023SJohn Marino     case FIXED_CST:
9872e4b17023SJohn Marino       return fixed_zerop (init);
9873e4b17023SJohn Marino 
9874e4b17023SJohn Marino     case COMPLEX_CST:
9875e4b17023SJohn Marino       return integer_zerop (init)
9876e4b17023SJohn Marino 	|| (real_zerop (init)
9877e4b17023SJohn Marino 	    && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_REALPART (init)))
9878e4b17023SJohn Marino 	    && ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_IMAGPART (init))));
9879e4b17023SJohn Marino 
9880e4b17023SJohn Marino     case VECTOR_CST:
9881e4b17023SJohn Marino       for (elt = TREE_VECTOR_CST_ELTS (init); elt; elt = TREE_CHAIN (elt))
9882e4b17023SJohn Marino 	if (!initializer_zerop (TREE_VALUE (elt)))
9883e4b17023SJohn Marino 	  return false;
9884e4b17023SJohn Marino       return true;
9885e4b17023SJohn Marino 
9886e4b17023SJohn Marino     case CONSTRUCTOR:
9887e4b17023SJohn Marino       {
9888e4b17023SJohn Marino 	unsigned HOST_WIDE_INT idx;
9889e4b17023SJohn Marino 
9890e4b17023SJohn Marino 	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), idx, elt)
9891e4b17023SJohn Marino 	  if (!initializer_zerop (elt))
9892e4b17023SJohn Marino 	    return false;
9893e4b17023SJohn Marino 	return true;
9894e4b17023SJohn Marino       }
9895e4b17023SJohn Marino 
9896e4b17023SJohn Marino     case STRING_CST:
9897e4b17023SJohn Marino       {
9898e4b17023SJohn Marino 	int i;
9899e4b17023SJohn Marino 
9900e4b17023SJohn Marino 	/* We need to loop through all elements to handle cases like
9901e4b17023SJohn Marino 	   "\0" and "\0foobar".  */
9902e4b17023SJohn Marino 	for (i = 0; i < TREE_STRING_LENGTH (init); ++i)
9903e4b17023SJohn Marino 	  if (TREE_STRING_POINTER (init)[i] != '\0')
9904e4b17023SJohn Marino 	    return false;
9905e4b17023SJohn Marino 
9906e4b17023SJohn Marino 	return true;
9907e4b17023SJohn Marino       }
9908e4b17023SJohn Marino 
9909e4b17023SJohn Marino     default:
9910e4b17023SJohn Marino       return false;
9911e4b17023SJohn Marino     }
9912e4b17023SJohn Marino }
9913e4b17023SJohn Marino 
9914e4b17023SJohn Marino /* Build an empty statement at location LOC.  */
9915e4b17023SJohn Marino 
9916e4b17023SJohn Marino tree
build_empty_stmt(location_t loc)9917e4b17023SJohn Marino build_empty_stmt (location_t loc)
9918e4b17023SJohn Marino {
9919e4b17023SJohn Marino   tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
9920e4b17023SJohn Marino   SET_EXPR_LOCATION (t, loc);
9921e4b17023SJohn Marino   return t;
9922e4b17023SJohn Marino }
9923e4b17023SJohn Marino 
9924e4b17023SJohn Marino 
9925e4b17023SJohn Marino /* Build an OpenMP clause with code CODE.  LOC is the location of the
9926e4b17023SJohn Marino    clause.  */
9927e4b17023SJohn Marino 
9928e4b17023SJohn Marino tree
build_omp_clause(location_t loc,enum omp_clause_code code)9929e4b17023SJohn Marino build_omp_clause (location_t loc, enum omp_clause_code code)
9930e4b17023SJohn Marino {
9931e4b17023SJohn Marino   tree t;
9932e4b17023SJohn Marino   int size, length;
9933e4b17023SJohn Marino 
9934e4b17023SJohn Marino   length = omp_clause_num_ops[code];
9935e4b17023SJohn Marino   size = (sizeof (struct tree_omp_clause) + (length - 1) * sizeof (tree));
9936e4b17023SJohn Marino 
9937e4b17023SJohn Marino   record_node_allocation_statistics (OMP_CLAUSE, size);
9938e4b17023SJohn Marino 
9939e4b17023SJohn Marino   t = ggc_alloc_tree_node (size);
9940e4b17023SJohn Marino   memset (t, 0, size);
9941e4b17023SJohn Marino   TREE_SET_CODE (t, OMP_CLAUSE);
9942e4b17023SJohn Marino   OMP_CLAUSE_SET_CODE (t, code);
9943e4b17023SJohn Marino   OMP_CLAUSE_LOCATION (t) = loc;
9944e4b17023SJohn Marino 
9945e4b17023SJohn Marino   return t;
9946e4b17023SJohn Marino }
9947e4b17023SJohn Marino 
9948e4b17023SJohn Marino /* Build a tcc_vl_exp object with code CODE and room for LEN operands.  LEN
9949e4b17023SJohn Marino    includes the implicit operand count in TREE_OPERAND 0, and so must be >= 1.
9950e4b17023SJohn Marino    Except for the CODE and operand count field, other storage for the
9951e4b17023SJohn Marino    object is initialized to zeros.  */
9952e4b17023SJohn Marino 
9953e4b17023SJohn Marino tree
build_vl_exp_stat(enum tree_code code,int len MEM_STAT_DECL)9954e4b17023SJohn Marino build_vl_exp_stat (enum tree_code code, int len MEM_STAT_DECL)
9955e4b17023SJohn Marino {
9956e4b17023SJohn Marino   tree t;
9957e4b17023SJohn Marino   int length = (len - 1) * sizeof (tree) + sizeof (struct tree_exp);
9958e4b17023SJohn Marino 
9959e4b17023SJohn Marino   gcc_assert (TREE_CODE_CLASS (code) == tcc_vl_exp);
9960e4b17023SJohn Marino   gcc_assert (len >= 1);
9961e4b17023SJohn Marino 
9962e4b17023SJohn Marino   record_node_allocation_statistics (code, length);
9963e4b17023SJohn Marino 
9964e4b17023SJohn Marino   t = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
9965e4b17023SJohn Marino 
9966e4b17023SJohn Marino   TREE_SET_CODE (t, code);
9967e4b17023SJohn Marino 
9968e4b17023SJohn Marino   /* Can't use TREE_OPERAND to store the length because if checking is
9969e4b17023SJohn Marino      enabled, it will try to check the length before we store it.  :-P  */
9970e4b17023SJohn Marino   t->exp.operands[0] = build_int_cst (sizetype, len);
9971e4b17023SJohn Marino 
9972e4b17023SJohn Marino   return t;
9973e4b17023SJohn Marino }
9974e4b17023SJohn Marino 
9975e4b17023SJohn Marino /* Helper function for build_call_* functions; build a CALL_EXPR with
9976e4b17023SJohn Marino    indicated RETURN_TYPE, FN, and NARGS, but do not initialize any of
9977e4b17023SJohn Marino    the argument slots.  */
9978e4b17023SJohn Marino 
9979e4b17023SJohn Marino static tree
build_call_1(tree return_type,tree fn,int nargs)9980e4b17023SJohn Marino build_call_1 (tree return_type, tree fn, int nargs)
9981e4b17023SJohn Marino {
9982e4b17023SJohn Marino   tree t;
9983e4b17023SJohn Marino 
9984e4b17023SJohn Marino   t = build_vl_exp (CALL_EXPR, nargs + 3);
9985e4b17023SJohn Marino   TREE_TYPE (t) = return_type;
9986e4b17023SJohn Marino   CALL_EXPR_FN (t) = fn;
9987e4b17023SJohn Marino   CALL_EXPR_STATIC_CHAIN (t) = NULL;
9988e4b17023SJohn Marino 
9989e4b17023SJohn Marino   return t;
9990e4b17023SJohn Marino }
9991e4b17023SJohn Marino 
9992e4b17023SJohn Marino /* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
9993e4b17023SJohn Marino    FN and a null static chain slot.  NARGS is the number of call arguments
9994e4b17023SJohn Marino    which are specified as "..." arguments.  */
9995e4b17023SJohn Marino 
9996e4b17023SJohn Marino tree
build_call_nary(tree return_type,tree fn,int nargs,...)9997e4b17023SJohn Marino build_call_nary (tree return_type, tree fn, int nargs, ...)
9998e4b17023SJohn Marino {
9999e4b17023SJohn Marino   tree ret;
10000e4b17023SJohn Marino   va_list args;
10001e4b17023SJohn Marino   va_start (args, nargs);
10002e4b17023SJohn Marino   ret = build_call_valist (return_type, fn, nargs, args);
10003e4b17023SJohn Marino   va_end (args);
10004e4b17023SJohn Marino   return ret;
10005e4b17023SJohn Marino }
10006e4b17023SJohn Marino 
10007e4b17023SJohn Marino /* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
10008e4b17023SJohn Marino    FN and a null static chain slot.  NARGS is the number of call arguments
10009e4b17023SJohn Marino    which are specified as a va_list ARGS.  */
10010e4b17023SJohn Marino 
10011e4b17023SJohn Marino tree
build_call_valist(tree return_type,tree fn,int nargs,va_list args)10012e4b17023SJohn Marino build_call_valist (tree return_type, tree fn, int nargs, va_list args)
10013e4b17023SJohn Marino {
10014e4b17023SJohn Marino   tree t;
10015e4b17023SJohn Marino   int i;
10016e4b17023SJohn Marino 
10017e4b17023SJohn Marino   t = build_call_1 (return_type, fn, nargs);
10018e4b17023SJohn Marino   for (i = 0; i < nargs; i++)
10019e4b17023SJohn Marino     CALL_EXPR_ARG (t, i) = va_arg (args, tree);
10020e4b17023SJohn Marino   process_call_operands (t);
10021e4b17023SJohn Marino   return t;
10022e4b17023SJohn Marino }
10023e4b17023SJohn Marino 
10024e4b17023SJohn Marino /* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
10025e4b17023SJohn Marino    FN and a null static chain slot.  NARGS is the number of call arguments
10026e4b17023SJohn Marino    which are specified as a tree array ARGS.  */
10027e4b17023SJohn Marino 
10028e4b17023SJohn Marino tree
build_call_array_loc(location_t loc,tree return_type,tree fn,int nargs,const tree * args)10029e4b17023SJohn Marino build_call_array_loc (location_t loc, tree return_type, tree fn,
10030e4b17023SJohn Marino 		      int nargs, const tree *args)
10031e4b17023SJohn Marino {
10032e4b17023SJohn Marino   tree t;
10033e4b17023SJohn Marino   int i;
10034e4b17023SJohn Marino 
10035e4b17023SJohn Marino   t = build_call_1 (return_type, fn, nargs);
10036e4b17023SJohn Marino   for (i = 0; i < nargs; i++)
10037e4b17023SJohn Marino     CALL_EXPR_ARG (t, i) = args[i];
10038e4b17023SJohn Marino   process_call_operands (t);
10039e4b17023SJohn Marino   SET_EXPR_LOCATION (t, loc);
10040e4b17023SJohn Marino   return t;
10041e4b17023SJohn Marino }
10042e4b17023SJohn Marino 
10043e4b17023SJohn Marino /* Like build_call_array, but takes a VEC.  */
10044e4b17023SJohn Marino 
10045e4b17023SJohn Marino tree
build_call_vec(tree return_type,tree fn,VEC (tree,gc)* args)10046e4b17023SJohn Marino build_call_vec (tree return_type, tree fn, VEC(tree,gc) *args)
10047e4b17023SJohn Marino {
10048e4b17023SJohn Marino   tree ret, t;
10049e4b17023SJohn Marino   unsigned int ix;
10050e4b17023SJohn Marino 
10051e4b17023SJohn Marino   ret = build_call_1 (return_type, fn, VEC_length (tree, args));
10052e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, args, ix, t)
10053e4b17023SJohn Marino     CALL_EXPR_ARG (ret, ix) = t;
10054e4b17023SJohn Marino   process_call_operands (ret);
10055e4b17023SJohn Marino   return ret;
10056e4b17023SJohn Marino }
10057e4b17023SJohn Marino 
10058e4b17023SJohn Marino 
10059e4b17023SJohn Marino /* Returns true if it is possible to prove that the index of
10060e4b17023SJohn Marino    an array access REF (an ARRAY_REF expression) falls into the
10061e4b17023SJohn Marino    array bounds.  */
10062e4b17023SJohn Marino 
10063e4b17023SJohn Marino bool
in_array_bounds_p(tree ref)10064e4b17023SJohn Marino in_array_bounds_p (tree ref)
10065e4b17023SJohn Marino {
10066e4b17023SJohn Marino   tree idx = TREE_OPERAND (ref, 1);
10067e4b17023SJohn Marino   tree min, max;
10068e4b17023SJohn Marino 
10069e4b17023SJohn Marino   if (TREE_CODE (idx) != INTEGER_CST)
10070e4b17023SJohn Marino     return false;
10071e4b17023SJohn Marino 
10072e4b17023SJohn Marino   min = array_ref_low_bound (ref);
10073e4b17023SJohn Marino   max = array_ref_up_bound (ref);
10074e4b17023SJohn Marino   if (!min
10075e4b17023SJohn Marino       || !max
10076e4b17023SJohn Marino       || TREE_CODE (min) != INTEGER_CST
10077e4b17023SJohn Marino       || TREE_CODE (max) != INTEGER_CST)
10078e4b17023SJohn Marino     return false;
10079e4b17023SJohn Marino 
10080e4b17023SJohn Marino   if (tree_int_cst_lt (idx, min)
10081e4b17023SJohn Marino       || tree_int_cst_lt (max, idx))
10082e4b17023SJohn Marino     return false;
10083e4b17023SJohn Marino 
10084e4b17023SJohn Marino   return true;
10085e4b17023SJohn Marino }
10086e4b17023SJohn Marino 
10087e4b17023SJohn Marino /* Returns true if it is possible to prove that the range of
10088e4b17023SJohn Marino    an array access REF (an ARRAY_RANGE_REF expression) falls
10089e4b17023SJohn Marino    into the array bounds.  */
10090e4b17023SJohn Marino 
10091e4b17023SJohn Marino bool
range_in_array_bounds_p(tree ref)10092e4b17023SJohn Marino range_in_array_bounds_p (tree ref)
10093e4b17023SJohn Marino {
10094e4b17023SJohn Marino   tree domain_type = TYPE_DOMAIN (TREE_TYPE (ref));
10095e4b17023SJohn Marino   tree range_min, range_max, min, max;
10096e4b17023SJohn Marino 
10097e4b17023SJohn Marino   range_min = TYPE_MIN_VALUE (domain_type);
10098e4b17023SJohn Marino   range_max = TYPE_MAX_VALUE (domain_type);
10099e4b17023SJohn Marino   if (!range_min
10100e4b17023SJohn Marino       || !range_max
10101e4b17023SJohn Marino       || TREE_CODE (range_min) != INTEGER_CST
10102e4b17023SJohn Marino       || TREE_CODE (range_max) != INTEGER_CST)
10103e4b17023SJohn Marino     return false;
10104e4b17023SJohn Marino 
10105e4b17023SJohn Marino   min = array_ref_low_bound (ref);
10106e4b17023SJohn Marino   max = array_ref_up_bound (ref);
10107e4b17023SJohn Marino   if (!min
10108e4b17023SJohn Marino       || !max
10109e4b17023SJohn Marino       || TREE_CODE (min) != INTEGER_CST
10110e4b17023SJohn Marino       || TREE_CODE (max) != INTEGER_CST)
10111e4b17023SJohn Marino     return false;
10112e4b17023SJohn Marino 
10113e4b17023SJohn Marino   if (tree_int_cst_lt (range_min, min)
10114e4b17023SJohn Marino       || tree_int_cst_lt (max, range_max))
10115e4b17023SJohn Marino     return false;
10116e4b17023SJohn Marino 
10117e4b17023SJohn Marino   return true;
10118e4b17023SJohn Marino }
10119e4b17023SJohn Marino 
10120e4b17023SJohn Marino /* Return true if T (assumed to be a DECL) must be assigned a memory
10121e4b17023SJohn Marino    location.  */
10122e4b17023SJohn Marino 
10123e4b17023SJohn Marino bool
needs_to_live_in_memory(const_tree t)10124e4b17023SJohn Marino needs_to_live_in_memory (const_tree t)
10125e4b17023SJohn Marino {
10126e4b17023SJohn Marino   if (TREE_CODE (t) == SSA_NAME)
10127e4b17023SJohn Marino     t = SSA_NAME_VAR (t);
10128e4b17023SJohn Marino 
10129e4b17023SJohn Marino   return (TREE_ADDRESSABLE (t)
10130e4b17023SJohn Marino 	  || is_global_var (t)
10131e4b17023SJohn Marino 	  || (TREE_CODE (t) == RESULT_DECL
10132e4b17023SJohn Marino 	      && !DECL_BY_REFERENCE (t)
10133e4b17023SJohn Marino 	      && aggregate_value_p (t, current_function_decl)));
10134e4b17023SJohn Marino }
10135e4b17023SJohn Marino 
10136e4b17023SJohn Marino /* Return value of a constant X and sign-extend it.  */
10137e4b17023SJohn Marino 
10138e4b17023SJohn Marino HOST_WIDE_INT
int_cst_value(const_tree x)10139e4b17023SJohn Marino int_cst_value (const_tree x)
10140e4b17023SJohn Marino {
10141e4b17023SJohn Marino   unsigned bits = TYPE_PRECISION (TREE_TYPE (x));
10142e4b17023SJohn Marino   unsigned HOST_WIDE_INT val = TREE_INT_CST_LOW (x);
10143e4b17023SJohn Marino 
10144e4b17023SJohn Marino   /* Make sure the sign-extended value will fit in a HOST_WIDE_INT.  */
10145e4b17023SJohn Marino   gcc_assert (TREE_INT_CST_HIGH (x) == 0
10146e4b17023SJohn Marino 	      || TREE_INT_CST_HIGH (x) == -1);
10147e4b17023SJohn Marino 
10148e4b17023SJohn Marino   if (bits < HOST_BITS_PER_WIDE_INT)
10149e4b17023SJohn Marino     {
10150e4b17023SJohn Marino       bool negative = ((val >> (bits - 1)) & 1) != 0;
10151e4b17023SJohn Marino       if (negative)
10152e4b17023SJohn Marino 	val |= (~(unsigned HOST_WIDE_INT) 0) << (bits - 1) << 1;
10153e4b17023SJohn Marino       else
10154e4b17023SJohn Marino 	val &= ~((~(unsigned HOST_WIDE_INT) 0) << (bits - 1) << 1);
10155e4b17023SJohn Marino     }
10156e4b17023SJohn Marino 
10157e4b17023SJohn Marino   return val;
10158e4b17023SJohn Marino }
10159e4b17023SJohn Marino 
10160e4b17023SJohn Marino /* Return value of a constant X and sign-extend it.  */
10161e4b17023SJohn Marino 
10162e4b17023SJohn Marino HOST_WIDEST_INT
widest_int_cst_value(const_tree x)10163e4b17023SJohn Marino widest_int_cst_value (const_tree x)
10164e4b17023SJohn Marino {
10165e4b17023SJohn Marino   unsigned bits = TYPE_PRECISION (TREE_TYPE (x));
10166e4b17023SJohn Marino   unsigned HOST_WIDEST_INT val = TREE_INT_CST_LOW (x);
10167e4b17023SJohn Marino 
10168e4b17023SJohn Marino #if HOST_BITS_PER_WIDEST_INT > HOST_BITS_PER_WIDE_INT
10169e4b17023SJohn Marino   gcc_assert (HOST_BITS_PER_WIDEST_INT >= 2 * HOST_BITS_PER_WIDE_INT);
10170e4b17023SJohn Marino   val |= (((unsigned HOST_WIDEST_INT) TREE_INT_CST_HIGH (x))
10171e4b17023SJohn Marino 	  << HOST_BITS_PER_WIDE_INT);
10172e4b17023SJohn Marino #else
10173e4b17023SJohn Marino   /* Make sure the sign-extended value will fit in a HOST_WIDE_INT.  */
10174e4b17023SJohn Marino   gcc_assert (TREE_INT_CST_HIGH (x) == 0
10175e4b17023SJohn Marino 	      || TREE_INT_CST_HIGH (x) == -1);
10176e4b17023SJohn Marino #endif
10177e4b17023SJohn Marino 
10178e4b17023SJohn Marino   if (bits < HOST_BITS_PER_WIDEST_INT)
10179e4b17023SJohn Marino     {
10180e4b17023SJohn Marino       bool negative = ((val >> (bits - 1)) & 1) != 0;
10181e4b17023SJohn Marino       if (negative)
10182e4b17023SJohn Marino 	val |= (~(unsigned HOST_WIDEST_INT) 0) << (bits - 1) << 1;
10183e4b17023SJohn Marino       else
10184e4b17023SJohn Marino 	val &= ~((~(unsigned HOST_WIDEST_INT) 0) << (bits - 1) << 1);
10185e4b17023SJohn Marino     }
10186e4b17023SJohn Marino 
10187e4b17023SJohn Marino   return val;
10188e4b17023SJohn Marino }
10189e4b17023SJohn Marino 
10190e4b17023SJohn Marino /* If TYPE is an integral type, return an equivalent type which is
10191e4b17023SJohn Marino     unsigned iff UNSIGNEDP is true.  If TYPE is not an integral type,
10192e4b17023SJohn Marino     return TYPE itself.  */
10193e4b17023SJohn Marino 
10194e4b17023SJohn Marino tree
signed_or_unsigned_type_for(int unsignedp,tree type)10195e4b17023SJohn Marino signed_or_unsigned_type_for (int unsignedp, tree type)
10196e4b17023SJohn Marino {
10197e4b17023SJohn Marino   tree t = type;
10198e4b17023SJohn Marino   if (POINTER_TYPE_P (type))
10199e4b17023SJohn Marino     {
10200e4b17023SJohn Marino       /* If the pointer points to the normal address space, use the
10201e4b17023SJohn Marino 	 size_type_node.  Otherwise use an appropriate size for the pointer
10202e4b17023SJohn Marino 	 based on the named address space it points to.  */
10203e4b17023SJohn Marino       if (!TYPE_ADDR_SPACE (TREE_TYPE (t)))
10204e4b17023SJohn Marino 	t = size_type_node;
10205e4b17023SJohn Marino       else
10206e4b17023SJohn Marino 	return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp);
10207e4b17023SJohn Marino     }
10208e4b17023SJohn Marino 
10209e4b17023SJohn Marino   if (!INTEGRAL_TYPE_P (t) || TYPE_UNSIGNED (t) == unsignedp)
10210e4b17023SJohn Marino     return t;
10211e4b17023SJohn Marino 
10212e4b17023SJohn Marino   return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp);
10213e4b17023SJohn Marino }
10214e4b17023SJohn Marino 
10215e4b17023SJohn Marino /* Returns unsigned variant of TYPE.  */
10216e4b17023SJohn Marino 
10217e4b17023SJohn Marino tree
unsigned_type_for(tree type)10218e4b17023SJohn Marino unsigned_type_for (tree type)
10219e4b17023SJohn Marino {
10220e4b17023SJohn Marino   return signed_or_unsigned_type_for (1, type);
10221e4b17023SJohn Marino }
10222e4b17023SJohn Marino 
10223e4b17023SJohn Marino /* Returns signed variant of TYPE.  */
10224e4b17023SJohn Marino 
10225e4b17023SJohn Marino tree
signed_type_for(tree type)10226e4b17023SJohn Marino signed_type_for (tree type)
10227e4b17023SJohn Marino {
10228e4b17023SJohn Marino   return signed_or_unsigned_type_for (0, type);
10229e4b17023SJohn Marino }
10230e4b17023SJohn Marino 
10231e4b17023SJohn Marino /* Returns the largest value obtainable by casting something in INNER type to
10232e4b17023SJohn Marino    OUTER type.  */
10233e4b17023SJohn Marino 
10234e4b17023SJohn Marino tree
upper_bound_in_type(tree outer,tree inner)10235e4b17023SJohn Marino upper_bound_in_type (tree outer, tree inner)
10236e4b17023SJohn Marino {
10237e4b17023SJohn Marino   double_int high;
10238e4b17023SJohn Marino   unsigned int det = 0;
10239e4b17023SJohn Marino   unsigned oprec = TYPE_PRECISION (outer);
10240e4b17023SJohn Marino   unsigned iprec = TYPE_PRECISION (inner);
10241e4b17023SJohn Marino   unsigned prec;
10242e4b17023SJohn Marino 
10243e4b17023SJohn Marino   /* Compute a unique number for every combination.  */
10244e4b17023SJohn Marino   det |= (oprec > iprec) ? 4 : 0;
10245e4b17023SJohn Marino   det |= TYPE_UNSIGNED (outer) ? 2 : 0;
10246e4b17023SJohn Marino   det |= TYPE_UNSIGNED (inner) ? 1 : 0;
10247e4b17023SJohn Marino 
10248e4b17023SJohn Marino   /* Determine the exponent to use.  */
10249e4b17023SJohn Marino   switch (det)
10250e4b17023SJohn Marino     {
10251e4b17023SJohn Marino     case 0:
10252e4b17023SJohn Marino     case 1:
10253e4b17023SJohn Marino       /* oprec <= iprec, outer: signed, inner: don't care.  */
10254e4b17023SJohn Marino       prec = oprec - 1;
10255e4b17023SJohn Marino       break;
10256e4b17023SJohn Marino     case 2:
10257e4b17023SJohn Marino     case 3:
10258e4b17023SJohn Marino       /* oprec <= iprec, outer: unsigned, inner: don't care.  */
10259e4b17023SJohn Marino       prec = oprec;
10260e4b17023SJohn Marino       break;
10261e4b17023SJohn Marino     case 4:
10262e4b17023SJohn Marino       /* oprec > iprec, outer: signed, inner: signed.  */
10263e4b17023SJohn Marino       prec = iprec - 1;
10264e4b17023SJohn Marino       break;
10265e4b17023SJohn Marino     case 5:
10266e4b17023SJohn Marino       /* oprec > iprec, outer: signed, inner: unsigned.  */
10267e4b17023SJohn Marino       prec = iprec;
10268e4b17023SJohn Marino       break;
10269e4b17023SJohn Marino     case 6:
10270e4b17023SJohn Marino       /* oprec > iprec, outer: unsigned, inner: signed.  */
10271e4b17023SJohn Marino       prec = oprec;
10272e4b17023SJohn Marino       break;
10273e4b17023SJohn Marino     case 7:
10274e4b17023SJohn Marino       /* oprec > iprec, outer: unsigned, inner: unsigned.  */
10275e4b17023SJohn Marino       prec = iprec;
10276e4b17023SJohn Marino       break;
10277e4b17023SJohn Marino     default:
10278e4b17023SJohn Marino       gcc_unreachable ();
10279e4b17023SJohn Marino     }
10280e4b17023SJohn Marino 
10281e4b17023SJohn Marino   /* Compute 2^^prec - 1.  */
10282e4b17023SJohn Marino   if (prec <= HOST_BITS_PER_WIDE_INT)
10283e4b17023SJohn Marino     {
10284e4b17023SJohn Marino       high.high = 0;
10285e4b17023SJohn Marino       high.low = ((~(unsigned HOST_WIDE_INT) 0)
10286e4b17023SJohn Marino 	    >> (HOST_BITS_PER_WIDE_INT - prec));
10287e4b17023SJohn Marino     }
10288e4b17023SJohn Marino   else
10289e4b17023SJohn Marino     {
10290e4b17023SJohn Marino       high.high = ((~(unsigned HOST_WIDE_INT) 0)
10291e4b17023SJohn Marino 	    >> (2 * HOST_BITS_PER_WIDE_INT - prec));
10292e4b17023SJohn Marino       high.low = ~(unsigned HOST_WIDE_INT) 0;
10293e4b17023SJohn Marino     }
10294e4b17023SJohn Marino 
10295e4b17023SJohn Marino   return double_int_to_tree (outer, high);
10296e4b17023SJohn Marino }
10297e4b17023SJohn Marino 
10298e4b17023SJohn Marino /* Returns the smallest value obtainable by casting something in INNER type to
10299e4b17023SJohn Marino    OUTER type.  */
10300e4b17023SJohn Marino 
10301e4b17023SJohn Marino tree
lower_bound_in_type(tree outer,tree inner)10302e4b17023SJohn Marino lower_bound_in_type (tree outer, tree inner)
10303e4b17023SJohn Marino {
10304e4b17023SJohn Marino   double_int low;
10305e4b17023SJohn Marino   unsigned oprec = TYPE_PRECISION (outer);
10306e4b17023SJohn Marino   unsigned iprec = TYPE_PRECISION (inner);
10307e4b17023SJohn Marino 
10308e4b17023SJohn Marino   /* If OUTER type is unsigned, we can definitely cast 0 to OUTER type
10309e4b17023SJohn Marino      and obtain 0.  */
10310e4b17023SJohn Marino   if (TYPE_UNSIGNED (outer)
10311e4b17023SJohn Marino       /* If we are widening something of an unsigned type, OUTER type
10312e4b17023SJohn Marino 	 contains all values of INNER type.  In particular, both INNER
10313e4b17023SJohn Marino 	 and OUTER types have zero in common.  */
10314e4b17023SJohn Marino       || (oprec > iprec && TYPE_UNSIGNED (inner)))
10315e4b17023SJohn Marino     low.low = low.high = 0;
10316e4b17023SJohn Marino   else
10317e4b17023SJohn Marino     {
10318e4b17023SJohn Marino       /* If we are widening a signed type to another signed type, we
10319e4b17023SJohn Marino 	 want to obtain -2^^(iprec-1).  If we are keeping the
10320e4b17023SJohn Marino 	 precision or narrowing to a signed type, we want to obtain
10321e4b17023SJohn Marino 	 -2^(oprec-1).  */
10322e4b17023SJohn Marino       unsigned prec = oprec > iprec ? iprec : oprec;
10323e4b17023SJohn Marino 
10324e4b17023SJohn Marino       if (prec <= HOST_BITS_PER_WIDE_INT)
10325e4b17023SJohn Marino 	{
10326e4b17023SJohn Marino 	  low.high = ~(unsigned HOST_WIDE_INT) 0;
10327e4b17023SJohn Marino 	  low.low = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1);
10328e4b17023SJohn Marino 	}
10329e4b17023SJohn Marino       else
10330e4b17023SJohn Marino 	{
10331e4b17023SJohn Marino 	  low.high = ((~(unsigned HOST_WIDE_INT) 0)
10332e4b17023SJohn Marino 		<< (prec - HOST_BITS_PER_WIDE_INT - 1));
10333e4b17023SJohn Marino 	  low.low = 0;
10334e4b17023SJohn Marino 	}
10335e4b17023SJohn Marino     }
10336e4b17023SJohn Marino 
10337e4b17023SJohn Marino   return double_int_to_tree (outer, low);
10338e4b17023SJohn Marino }
10339e4b17023SJohn Marino 
10340e4b17023SJohn Marino /* Return nonzero if two operands that are suitable for PHI nodes are
10341e4b17023SJohn Marino    necessarily equal.  Specifically, both ARG0 and ARG1 must be either
10342e4b17023SJohn Marino    SSA_NAME or invariant.  Note that this is strictly an optimization.
10343e4b17023SJohn Marino    That is, callers of this function can directly call operand_equal_p
10344e4b17023SJohn Marino    and get the same result, only slower.  */
10345e4b17023SJohn Marino 
10346e4b17023SJohn Marino int
operand_equal_for_phi_arg_p(const_tree arg0,const_tree arg1)10347e4b17023SJohn Marino operand_equal_for_phi_arg_p (const_tree arg0, const_tree arg1)
10348e4b17023SJohn Marino {
10349e4b17023SJohn Marino   if (arg0 == arg1)
10350e4b17023SJohn Marino     return 1;
10351e4b17023SJohn Marino   if (TREE_CODE (arg0) == SSA_NAME || TREE_CODE (arg1) == SSA_NAME)
10352e4b17023SJohn Marino     return 0;
10353e4b17023SJohn Marino   return operand_equal_p (arg0, arg1, 0);
10354e4b17023SJohn Marino }
10355e4b17023SJohn Marino 
10356e4b17023SJohn Marino /* Returns number of zeros at the end of binary representation of X.
10357e4b17023SJohn Marino 
10358e4b17023SJohn Marino    ??? Use ffs if available?  */
10359e4b17023SJohn Marino 
10360e4b17023SJohn Marino tree
num_ending_zeros(const_tree x)10361e4b17023SJohn Marino num_ending_zeros (const_tree x)
10362e4b17023SJohn Marino {
10363e4b17023SJohn Marino   unsigned HOST_WIDE_INT fr, nfr;
10364e4b17023SJohn Marino   unsigned num, abits;
10365e4b17023SJohn Marino   tree type = TREE_TYPE (x);
10366e4b17023SJohn Marino 
10367e4b17023SJohn Marino   if (TREE_INT_CST_LOW (x) == 0)
10368e4b17023SJohn Marino     {
10369e4b17023SJohn Marino       num = HOST_BITS_PER_WIDE_INT;
10370e4b17023SJohn Marino       fr = TREE_INT_CST_HIGH (x);
10371e4b17023SJohn Marino     }
10372e4b17023SJohn Marino   else
10373e4b17023SJohn Marino     {
10374e4b17023SJohn Marino       num = 0;
10375e4b17023SJohn Marino       fr = TREE_INT_CST_LOW (x);
10376e4b17023SJohn Marino     }
10377e4b17023SJohn Marino 
10378e4b17023SJohn Marino   for (abits = HOST_BITS_PER_WIDE_INT / 2; abits; abits /= 2)
10379e4b17023SJohn Marino     {
10380e4b17023SJohn Marino       nfr = fr >> abits;
10381e4b17023SJohn Marino       if (nfr << abits == fr)
10382e4b17023SJohn Marino 	{
10383e4b17023SJohn Marino 	  num += abits;
10384e4b17023SJohn Marino 	  fr = nfr;
10385e4b17023SJohn Marino 	}
10386e4b17023SJohn Marino     }
10387e4b17023SJohn Marino 
10388e4b17023SJohn Marino   if (num > TYPE_PRECISION (type))
10389e4b17023SJohn Marino     num = TYPE_PRECISION (type);
10390e4b17023SJohn Marino 
10391e4b17023SJohn Marino   return build_int_cst_type (type, num);
10392e4b17023SJohn Marino }
10393e4b17023SJohn Marino 
10394e4b17023SJohn Marino 
10395e4b17023SJohn Marino #define WALK_SUBTREE(NODE)				\
10396e4b17023SJohn Marino   do							\
10397e4b17023SJohn Marino     {							\
10398e4b17023SJohn Marino       result = walk_tree_1 (&(NODE), func, data, pset, lh);	\
10399e4b17023SJohn Marino       if (result)					\
10400e4b17023SJohn Marino 	return result;					\
10401e4b17023SJohn Marino     }							\
10402e4b17023SJohn Marino   while (0)
10403e4b17023SJohn Marino 
10404e4b17023SJohn Marino /* This is a subroutine of walk_tree that walks field of TYPE that are to
10405e4b17023SJohn Marino    be walked whenever a type is seen in the tree.  Rest of operands and return
10406e4b17023SJohn Marino    value are as for walk_tree.  */
10407e4b17023SJohn Marino 
10408e4b17023SJohn Marino static tree
walk_type_fields(tree type,walk_tree_fn func,void * data,struct pointer_set_t * pset,walk_tree_lh lh)10409e4b17023SJohn Marino walk_type_fields (tree type, walk_tree_fn func, void *data,
10410e4b17023SJohn Marino 		  struct pointer_set_t *pset, walk_tree_lh lh)
10411e4b17023SJohn Marino {
10412e4b17023SJohn Marino   tree result = NULL_TREE;
10413e4b17023SJohn Marino 
10414e4b17023SJohn Marino   switch (TREE_CODE (type))
10415e4b17023SJohn Marino     {
10416e4b17023SJohn Marino     case POINTER_TYPE:
10417e4b17023SJohn Marino     case REFERENCE_TYPE:
10418e4b17023SJohn Marino       /* We have to worry about mutually recursive pointers.  These can't
10419e4b17023SJohn Marino 	 be written in C.  They can in Ada.  It's pathological, but
10420e4b17023SJohn Marino 	 there's an ACATS test (c38102a) that checks it.  Deal with this
10421e4b17023SJohn Marino 	 by checking if we're pointing to another pointer, that one
10422e4b17023SJohn Marino 	 points to another pointer, that one does too, and we have no htab.
10423e4b17023SJohn Marino 	 If so, get a hash table.  We check three levels deep to avoid
10424e4b17023SJohn Marino 	 the cost of the hash table if we don't need one.  */
10425e4b17023SJohn Marino       if (POINTER_TYPE_P (TREE_TYPE (type))
10426e4b17023SJohn Marino 	  && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (type)))
10427e4b17023SJohn Marino 	  && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (TREE_TYPE (type))))
10428e4b17023SJohn Marino 	  && !pset)
10429e4b17023SJohn Marino 	{
10430e4b17023SJohn Marino 	  result = walk_tree_without_duplicates (&TREE_TYPE (type),
10431e4b17023SJohn Marino 						 func, data);
10432e4b17023SJohn Marino 	  if (result)
10433e4b17023SJohn Marino 	    return result;
10434e4b17023SJohn Marino 
10435e4b17023SJohn Marino 	  break;
10436e4b17023SJohn Marino 	}
10437e4b17023SJohn Marino 
10438e4b17023SJohn Marino       /* ... fall through ... */
10439e4b17023SJohn Marino 
10440e4b17023SJohn Marino     case COMPLEX_TYPE:
10441e4b17023SJohn Marino       WALK_SUBTREE (TREE_TYPE (type));
10442e4b17023SJohn Marino       break;
10443e4b17023SJohn Marino 
10444e4b17023SJohn Marino     case METHOD_TYPE:
10445e4b17023SJohn Marino       WALK_SUBTREE (TYPE_METHOD_BASETYPE (type));
10446e4b17023SJohn Marino 
10447e4b17023SJohn Marino       /* Fall through.  */
10448e4b17023SJohn Marino 
10449e4b17023SJohn Marino     case FUNCTION_TYPE:
10450e4b17023SJohn Marino       WALK_SUBTREE (TREE_TYPE (type));
10451e4b17023SJohn Marino       {
10452e4b17023SJohn Marino 	tree arg;
10453e4b17023SJohn Marino 
10454e4b17023SJohn Marino 	/* We never want to walk into default arguments.  */
10455e4b17023SJohn Marino 	for (arg = TYPE_ARG_TYPES (type); arg; arg = TREE_CHAIN (arg))
10456e4b17023SJohn Marino 	  WALK_SUBTREE (TREE_VALUE (arg));
10457e4b17023SJohn Marino       }
10458e4b17023SJohn Marino       break;
10459e4b17023SJohn Marino 
10460e4b17023SJohn Marino     case ARRAY_TYPE:
10461e4b17023SJohn Marino       /* Don't follow this nodes's type if a pointer for fear that
10462e4b17023SJohn Marino 	 we'll have infinite recursion.  If we have a PSET, then we
10463e4b17023SJohn Marino 	 need not fear.  */
10464e4b17023SJohn Marino       if (pset
10465e4b17023SJohn Marino 	  || (!POINTER_TYPE_P (TREE_TYPE (type))
10466e4b17023SJohn Marino 	      && TREE_CODE (TREE_TYPE (type)) != OFFSET_TYPE))
10467e4b17023SJohn Marino 	WALK_SUBTREE (TREE_TYPE (type));
10468e4b17023SJohn Marino       WALK_SUBTREE (TYPE_DOMAIN (type));
10469e4b17023SJohn Marino       break;
10470e4b17023SJohn Marino 
10471e4b17023SJohn Marino     case OFFSET_TYPE:
10472e4b17023SJohn Marino       WALK_SUBTREE (TREE_TYPE (type));
10473e4b17023SJohn Marino       WALK_SUBTREE (TYPE_OFFSET_BASETYPE (type));
10474e4b17023SJohn Marino       break;
10475e4b17023SJohn Marino 
10476e4b17023SJohn Marino     default:
10477e4b17023SJohn Marino       break;
10478e4b17023SJohn Marino     }
10479e4b17023SJohn Marino 
10480e4b17023SJohn Marino   return NULL_TREE;
10481e4b17023SJohn Marino }
10482e4b17023SJohn Marino 
10483e4b17023SJohn Marino /* Apply FUNC to all the sub-trees of TP in a pre-order traversal.  FUNC is
10484e4b17023SJohn Marino    called with the DATA and the address of each sub-tree.  If FUNC returns a
10485e4b17023SJohn Marino    non-NULL value, the traversal is stopped, and the value returned by FUNC
10486e4b17023SJohn Marino    is returned.  If PSET is non-NULL it is used to record the nodes visited,
10487e4b17023SJohn Marino    and to avoid visiting a node more than once.  */
10488e4b17023SJohn Marino 
10489e4b17023SJohn Marino tree
walk_tree_1(tree * tp,walk_tree_fn func,void * data,struct pointer_set_t * pset,walk_tree_lh lh)10490e4b17023SJohn Marino walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
10491e4b17023SJohn Marino 	     struct pointer_set_t *pset, walk_tree_lh lh)
10492e4b17023SJohn Marino {
10493e4b17023SJohn Marino   enum tree_code code;
10494e4b17023SJohn Marino   int walk_subtrees;
10495e4b17023SJohn Marino   tree result;
10496e4b17023SJohn Marino 
10497e4b17023SJohn Marino #define WALK_SUBTREE_TAIL(NODE)				\
10498e4b17023SJohn Marino   do							\
10499e4b17023SJohn Marino     {							\
10500e4b17023SJohn Marino        tp = & (NODE);					\
10501e4b17023SJohn Marino        goto tail_recurse;				\
10502e4b17023SJohn Marino     }							\
10503e4b17023SJohn Marino   while (0)
10504e4b17023SJohn Marino 
10505e4b17023SJohn Marino  tail_recurse:
10506e4b17023SJohn Marino   /* Skip empty subtrees.  */
10507e4b17023SJohn Marino   if (!*tp)
10508e4b17023SJohn Marino     return NULL_TREE;
10509e4b17023SJohn Marino 
10510e4b17023SJohn Marino   /* Don't walk the same tree twice, if the user has requested
10511e4b17023SJohn Marino      that we avoid doing so.  */
10512e4b17023SJohn Marino   if (pset && pointer_set_insert (pset, *tp))
10513e4b17023SJohn Marino     return NULL_TREE;
10514e4b17023SJohn Marino 
10515e4b17023SJohn Marino   /* Call the function.  */
10516e4b17023SJohn Marino   walk_subtrees = 1;
10517e4b17023SJohn Marino   result = (*func) (tp, &walk_subtrees, data);
10518e4b17023SJohn Marino 
10519e4b17023SJohn Marino   /* If we found something, return it.  */
10520e4b17023SJohn Marino   if (result)
10521e4b17023SJohn Marino     return result;
10522e4b17023SJohn Marino 
10523e4b17023SJohn Marino   code = TREE_CODE (*tp);
10524e4b17023SJohn Marino 
10525e4b17023SJohn Marino   /* Even if we didn't, FUNC may have decided that there was nothing
10526e4b17023SJohn Marino      interesting below this point in the tree.  */
10527e4b17023SJohn Marino   if (!walk_subtrees)
10528e4b17023SJohn Marino     {
10529e4b17023SJohn Marino       /* But we still need to check our siblings.  */
10530e4b17023SJohn Marino       if (code == TREE_LIST)
10531e4b17023SJohn Marino 	WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
10532e4b17023SJohn Marino       else if (code == OMP_CLAUSE)
10533e4b17023SJohn Marino 	WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
10534e4b17023SJohn Marino       else
10535e4b17023SJohn Marino 	return NULL_TREE;
10536e4b17023SJohn Marino     }
10537e4b17023SJohn Marino 
10538e4b17023SJohn Marino   if (lh)
10539e4b17023SJohn Marino     {
10540e4b17023SJohn Marino       result = (*lh) (tp, &walk_subtrees, func, data, pset);
10541e4b17023SJohn Marino       if (result || !walk_subtrees)
10542e4b17023SJohn Marino         return result;
10543e4b17023SJohn Marino     }
10544e4b17023SJohn Marino 
10545e4b17023SJohn Marino   switch (code)
10546e4b17023SJohn Marino     {
10547e4b17023SJohn Marino     case ERROR_MARK:
10548e4b17023SJohn Marino     case IDENTIFIER_NODE:
10549e4b17023SJohn Marino     case INTEGER_CST:
10550e4b17023SJohn Marino     case REAL_CST:
10551e4b17023SJohn Marino     case FIXED_CST:
10552e4b17023SJohn Marino     case VECTOR_CST:
10553e4b17023SJohn Marino     case STRING_CST:
10554e4b17023SJohn Marino     case BLOCK:
10555e4b17023SJohn Marino     case PLACEHOLDER_EXPR:
10556e4b17023SJohn Marino     case SSA_NAME:
10557e4b17023SJohn Marino     case FIELD_DECL:
10558e4b17023SJohn Marino     case RESULT_DECL:
10559e4b17023SJohn Marino       /* None of these have subtrees other than those already walked
10560e4b17023SJohn Marino 	 above.  */
10561e4b17023SJohn Marino       break;
10562e4b17023SJohn Marino 
10563e4b17023SJohn Marino     case TREE_LIST:
10564e4b17023SJohn Marino       WALK_SUBTREE (TREE_VALUE (*tp));
10565e4b17023SJohn Marino       WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
10566e4b17023SJohn Marino       break;
10567e4b17023SJohn Marino 
10568e4b17023SJohn Marino     case TREE_VEC:
10569e4b17023SJohn Marino       {
10570e4b17023SJohn Marino 	int len = TREE_VEC_LENGTH (*tp);
10571e4b17023SJohn Marino 
10572e4b17023SJohn Marino 	if (len == 0)
10573e4b17023SJohn Marino 	  break;
10574e4b17023SJohn Marino 
10575e4b17023SJohn Marino 	/* Walk all elements but the first.  */
10576e4b17023SJohn Marino 	while (--len)
10577e4b17023SJohn Marino 	  WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
10578e4b17023SJohn Marino 
10579e4b17023SJohn Marino 	/* Now walk the first one as a tail call.  */
10580e4b17023SJohn Marino 	WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
10581e4b17023SJohn Marino       }
10582e4b17023SJohn Marino 
10583e4b17023SJohn Marino     case COMPLEX_CST:
10584e4b17023SJohn Marino       WALK_SUBTREE (TREE_REALPART (*tp));
10585e4b17023SJohn Marino       WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
10586e4b17023SJohn Marino 
10587e4b17023SJohn Marino     case CONSTRUCTOR:
10588e4b17023SJohn Marino       {
10589e4b17023SJohn Marino 	unsigned HOST_WIDE_INT idx;
10590e4b17023SJohn Marino 	constructor_elt *ce;
10591e4b17023SJohn Marino 
10592e4b17023SJohn Marino 	for (idx = 0;
10593e4b17023SJohn Marino 	     VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (*tp), idx, ce);
10594e4b17023SJohn Marino 	     idx++)
10595e4b17023SJohn Marino 	  WALK_SUBTREE (ce->value);
10596e4b17023SJohn Marino       }
10597e4b17023SJohn Marino       break;
10598e4b17023SJohn Marino 
10599e4b17023SJohn Marino     case SAVE_EXPR:
10600e4b17023SJohn Marino       WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
10601e4b17023SJohn Marino 
10602e4b17023SJohn Marino     case BIND_EXPR:
10603e4b17023SJohn Marino       {
10604e4b17023SJohn Marino 	tree decl;
10605e4b17023SJohn Marino 	for (decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
10606e4b17023SJohn Marino 	  {
10607e4b17023SJohn Marino 	    /* Walk the DECL_INITIAL and DECL_SIZE.  We don't want to walk
10608e4b17023SJohn Marino 	       into declarations that are just mentioned, rather than
10609e4b17023SJohn Marino 	       declared; they don't really belong to this part of the tree.
10610e4b17023SJohn Marino 	       And, we can see cycles: the initializer for a declaration
10611e4b17023SJohn Marino 	       can refer to the declaration itself.  */
10612e4b17023SJohn Marino 	    WALK_SUBTREE (DECL_INITIAL (decl));
10613e4b17023SJohn Marino 	    WALK_SUBTREE (DECL_SIZE (decl));
10614e4b17023SJohn Marino 	    WALK_SUBTREE (DECL_SIZE_UNIT (decl));
10615e4b17023SJohn Marino 	  }
10616e4b17023SJohn Marino 	WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
10617e4b17023SJohn Marino       }
10618e4b17023SJohn Marino 
10619e4b17023SJohn Marino     case STATEMENT_LIST:
10620e4b17023SJohn Marino       {
10621e4b17023SJohn Marino 	tree_stmt_iterator i;
10622e4b17023SJohn Marino 	for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
10623e4b17023SJohn Marino 	  WALK_SUBTREE (*tsi_stmt_ptr (i));
10624e4b17023SJohn Marino       }
10625e4b17023SJohn Marino       break;
10626e4b17023SJohn Marino 
10627e4b17023SJohn Marino     case OMP_CLAUSE:
10628e4b17023SJohn Marino       switch (OMP_CLAUSE_CODE (*tp))
10629e4b17023SJohn Marino 	{
10630e4b17023SJohn Marino 	case OMP_CLAUSE_PRIVATE:
10631e4b17023SJohn Marino 	case OMP_CLAUSE_SHARED:
10632e4b17023SJohn Marino 	case OMP_CLAUSE_FIRSTPRIVATE:
10633e4b17023SJohn Marino 	case OMP_CLAUSE_COPYIN:
10634e4b17023SJohn Marino 	case OMP_CLAUSE_COPYPRIVATE:
10635e4b17023SJohn Marino 	case OMP_CLAUSE_FINAL:
10636e4b17023SJohn Marino 	case OMP_CLAUSE_IF:
10637e4b17023SJohn Marino 	case OMP_CLAUSE_NUM_THREADS:
10638e4b17023SJohn Marino 	case OMP_CLAUSE_SCHEDULE:
10639e4b17023SJohn Marino 	  WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0));
10640e4b17023SJohn Marino 	  /* FALLTHRU */
10641e4b17023SJohn Marino 
10642e4b17023SJohn Marino 	case OMP_CLAUSE_NOWAIT:
10643e4b17023SJohn Marino 	case OMP_CLAUSE_ORDERED:
10644e4b17023SJohn Marino 	case OMP_CLAUSE_DEFAULT:
10645e4b17023SJohn Marino 	case OMP_CLAUSE_UNTIED:
10646e4b17023SJohn Marino 	case OMP_CLAUSE_MERGEABLE:
10647e4b17023SJohn Marino 	  WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
10648e4b17023SJohn Marino 
10649e4b17023SJohn Marino 	case OMP_CLAUSE_LASTPRIVATE:
10650e4b17023SJohn Marino 	  WALK_SUBTREE (OMP_CLAUSE_DECL (*tp));
10651e4b17023SJohn Marino 	  WALK_SUBTREE (OMP_CLAUSE_LASTPRIVATE_STMT (*tp));
10652e4b17023SJohn Marino 	  WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
10653e4b17023SJohn Marino 
10654e4b17023SJohn Marino 	case OMP_CLAUSE_COLLAPSE:
10655e4b17023SJohn Marino 	  {
10656e4b17023SJohn Marino 	    int i;
10657e4b17023SJohn Marino 	    for (i = 0; i < 3; i++)
10658e4b17023SJohn Marino 	      WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i));
10659e4b17023SJohn Marino 	    WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
10660e4b17023SJohn Marino 	  }
10661e4b17023SJohn Marino 
10662e4b17023SJohn Marino 	case OMP_CLAUSE_REDUCTION:
10663e4b17023SJohn Marino 	  {
10664e4b17023SJohn Marino 	    int i;
10665e4b17023SJohn Marino 	    for (i = 0; i < 4; i++)
10666e4b17023SJohn Marino 	      WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i));
10667e4b17023SJohn Marino 	    WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
10668e4b17023SJohn Marino 	  }
10669e4b17023SJohn Marino 
10670e4b17023SJohn Marino 	default:
10671e4b17023SJohn Marino 	  gcc_unreachable ();
10672e4b17023SJohn Marino 	}
10673e4b17023SJohn Marino       break;
10674e4b17023SJohn Marino 
10675e4b17023SJohn Marino     case TARGET_EXPR:
10676e4b17023SJohn Marino       {
10677e4b17023SJohn Marino 	int i, len;
10678e4b17023SJohn Marino 
10679e4b17023SJohn Marino 	/* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
10680e4b17023SJohn Marino 	   But, we only want to walk once.  */
10681e4b17023SJohn Marino 	len = (TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1)) ? 2 : 3;
10682e4b17023SJohn Marino 	for (i = 0; i < len; ++i)
10683e4b17023SJohn Marino 	  WALK_SUBTREE (TREE_OPERAND (*tp, i));
10684e4b17023SJohn Marino 	WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len));
10685e4b17023SJohn Marino       }
10686e4b17023SJohn Marino 
10687e4b17023SJohn Marino     case DECL_EXPR:
10688e4b17023SJohn Marino       /* If this is a TYPE_DECL, walk into the fields of the type that it's
10689e4b17023SJohn Marino 	 defining.  We only want to walk into these fields of a type in this
10690e4b17023SJohn Marino 	 case and not in the general case of a mere reference to the type.
10691e4b17023SJohn Marino 
10692e4b17023SJohn Marino 	 The criterion is as follows: if the field can be an expression, it
10693e4b17023SJohn Marino 	 must be walked only here.  This should be in keeping with the fields
10694e4b17023SJohn Marino 	 that are directly gimplified in gimplify_type_sizes in order for the
10695e4b17023SJohn Marino 	 mark/copy-if-shared/unmark machinery of the gimplifier to work with
10696e4b17023SJohn Marino 	 variable-sized types.
10697e4b17023SJohn Marino 
10698e4b17023SJohn Marino 	 Note that DECLs get walked as part of processing the BIND_EXPR.  */
10699e4b17023SJohn Marino       if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL)
10700e4b17023SJohn Marino 	{
10701e4b17023SJohn Marino 	  tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
10702e4b17023SJohn Marino 	  if (TREE_CODE (*type_p) == ERROR_MARK)
10703e4b17023SJohn Marino 	    return NULL_TREE;
10704e4b17023SJohn Marino 
10705e4b17023SJohn Marino 	  /* Call the function for the type.  See if it returns anything or
10706e4b17023SJohn Marino 	     doesn't want us to continue.  If we are to continue, walk both
10707e4b17023SJohn Marino 	     the normal fields and those for the declaration case.  */
10708e4b17023SJohn Marino 	  result = (*func) (type_p, &walk_subtrees, data);
10709e4b17023SJohn Marino 	  if (result || !walk_subtrees)
10710e4b17023SJohn Marino 	    return result;
10711e4b17023SJohn Marino 
10712e4b17023SJohn Marino 	  /* But do not walk a pointed-to type since it may itself need to
10713e4b17023SJohn Marino 	     be walked in the declaration case if it isn't anonymous.  */
10714e4b17023SJohn Marino 	  if (!POINTER_TYPE_P (*type_p))
10715e4b17023SJohn Marino 	    {
10716e4b17023SJohn Marino 	      result = walk_type_fields (*type_p, func, data, pset, lh);
10717e4b17023SJohn Marino 	      if (result)
10718e4b17023SJohn Marino 		return result;
10719e4b17023SJohn Marino 	    }
10720e4b17023SJohn Marino 
10721e4b17023SJohn Marino 	  /* If this is a record type, also walk the fields.  */
10722e4b17023SJohn Marino 	  if (RECORD_OR_UNION_TYPE_P (*type_p))
10723e4b17023SJohn Marino 	    {
10724e4b17023SJohn Marino 	      tree field;
10725e4b17023SJohn Marino 
10726e4b17023SJohn Marino 	      for (field = TYPE_FIELDS (*type_p); field;
10727e4b17023SJohn Marino 		   field = DECL_CHAIN (field))
10728e4b17023SJohn Marino 		{
10729e4b17023SJohn Marino 		  /* We'd like to look at the type of the field, but we can
10730e4b17023SJohn Marino 		     easily get infinite recursion.  So assume it's pointed
10731e4b17023SJohn Marino 		     to elsewhere in the tree.  Also, ignore things that
10732e4b17023SJohn Marino 		     aren't fields.  */
10733e4b17023SJohn Marino 		  if (TREE_CODE (field) != FIELD_DECL)
10734e4b17023SJohn Marino 		    continue;
10735e4b17023SJohn Marino 
10736e4b17023SJohn Marino 		  WALK_SUBTREE (DECL_FIELD_OFFSET (field));
10737e4b17023SJohn Marino 		  WALK_SUBTREE (DECL_SIZE (field));
10738e4b17023SJohn Marino 		  WALK_SUBTREE (DECL_SIZE_UNIT (field));
10739e4b17023SJohn Marino 		  if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
10740e4b17023SJohn Marino 		    WALK_SUBTREE (DECL_QUALIFIER (field));
10741e4b17023SJohn Marino 		}
10742e4b17023SJohn Marino 	    }
10743e4b17023SJohn Marino 
10744e4b17023SJohn Marino 	  /* Same for scalar types.  */
10745e4b17023SJohn Marino 	  else if (TREE_CODE (*type_p) == BOOLEAN_TYPE
10746e4b17023SJohn Marino 		   || TREE_CODE (*type_p) == ENUMERAL_TYPE
10747e4b17023SJohn Marino 		   || TREE_CODE (*type_p) == INTEGER_TYPE
10748e4b17023SJohn Marino 		   || TREE_CODE (*type_p) == FIXED_POINT_TYPE
10749e4b17023SJohn Marino 		   || TREE_CODE (*type_p) == REAL_TYPE)
10750e4b17023SJohn Marino 	    {
10751e4b17023SJohn Marino 	      WALK_SUBTREE (TYPE_MIN_VALUE (*type_p));
10752e4b17023SJohn Marino 	      WALK_SUBTREE (TYPE_MAX_VALUE (*type_p));
10753e4b17023SJohn Marino 	    }
10754e4b17023SJohn Marino 
10755e4b17023SJohn Marino 	  WALK_SUBTREE (TYPE_SIZE (*type_p));
10756e4b17023SJohn Marino 	  WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (*type_p));
10757e4b17023SJohn Marino 	}
10758e4b17023SJohn Marino       /* FALLTHRU */
10759e4b17023SJohn Marino 
10760e4b17023SJohn Marino     default:
10761e4b17023SJohn Marino       if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
10762e4b17023SJohn Marino 	{
10763e4b17023SJohn Marino 	  int i, len;
10764e4b17023SJohn Marino 
10765e4b17023SJohn Marino 	  /* Walk over all the sub-trees of this operand.  */
10766e4b17023SJohn Marino 	  len = TREE_OPERAND_LENGTH (*tp);
10767e4b17023SJohn Marino 
10768e4b17023SJohn Marino 	  /* Go through the subtrees.  We need to do this in forward order so
10769e4b17023SJohn Marino 	     that the scope of a FOR_EXPR is handled properly.  */
10770e4b17023SJohn Marino 	  if (len)
10771e4b17023SJohn Marino 	    {
10772e4b17023SJohn Marino 	      for (i = 0; i < len - 1; ++i)
10773e4b17023SJohn Marino 		WALK_SUBTREE (TREE_OPERAND (*tp, i));
10774e4b17023SJohn Marino 	      WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
10775e4b17023SJohn Marino 	    }
10776e4b17023SJohn Marino 	}
10777e4b17023SJohn Marino       /* If this is a type, walk the needed fields in the type.  */
10778e4b17023SJohn Marino       else if (TYPE_P (*tp))
10779e4b17023SJohn Marino 	return walk_type_fields (*tp, func, data, pset, lh);
10780e4b17023SJohn Marino       break;
10781e4b17023SJohn Marino     }
10782e4b17023SJohn Marino 
10783e4b17023SJohn Marino   /* We didn't find what we were looking for.  */
10784e4b17023SJohn Marino   return NULL_TREE;
10785e4b17023SJohn Marino 
10786e4b17023SJohn Marino #undef WALK_SUBTREE_TAIL
10787e4b17023SJohn Marino }
10788e4b17023SJohn Marino #undef WALK_SUBTREE
10789e4b17023SJohn Marino 
10790e4b17023SJohn Marino /* Like walk_tree, but does not walk duplicate nodes more than once.  */
10791e4b17023SJohn Marino 
10792e4b17023SJohn Marino tree
walk_tree_without_duplicates_1(tree * tp,walk_tree_fn func,void * data,walk_tree_lh lh)10793e4b17023SJohn Marino walk_tree_without_duplicates_1 (tree *tp, walk_tree_fn func, void *data,
10794e4b17023SJohn Marino 				walk_tree_lh lh)
10795e4b17023SJohn Marino {
10796e4b17023SJohn Marino   tree result;
10797e4b17023SJohn Marino   struct pointer_set_t *pset;
10798e4b17023SJohn Marino 
10799e4b17023SJohn Marino   pset = pointer_set_create ();
10800e4b17023SJohn Marino   result = walk_tree_1 (tp, func, data, pset, lh);
10801e4b17023SJohn Marino   pointer_set_destroy (pset);
10802e4b17023SJohn Marino   return result;
10803e4b17023SJohn Marino }
10804e4b17023SJohn Marino 
10805e4b17023SJohn Marino 
10806e4b17023SJohn Marino tree *
tree_block(tree t)10807e4b17023SJohn Marino tree_block (tree t)
10808e4b17023SJohn Marino {
10809e4b17023SJohn Marino   char const c = TREE_CODE_CLASS (TREE_CODE (t));
10810e4b17023SJohn Marino 
10811e4b17023SJohn Marino   if (IS_EXPR_CODE_CLASS (c))
10812e4b17023SJohn Marino     return &t->exp.block;
10813e4b17023SJohn Marino   gcc_unreachable ();
10814e4b17023SJohn Marino   return NULL;
10815e4b17023SJohn Marino }
10816e4b17023SJohn Marino 
10817e4b17023SJohn Marino /* Create a nameless artificial label and put it in the current
10818e4b17023SJohn Marino    function context.  The label has a location of LOC.  Returns the
10819e4b17023SJohn Marino    newly created label.  */
10820e4b17023SJohn Marino 
10821e4b17023SJohn Marino tree
create_artificial_label(location_t loc)10822e4b17023SJohn Marino create_artificial_label (location_t loc)
10823e4b17023SJohn Marino {
10824e4b17023SJohn Marino   tree lab = build_decl (loc,
10825e4b17023SJohn Marino       			 LABEL_DECL, NULL_TREE, void_type_node);
10826e4b17023SJohn Marino 
10827e4b17023SJohn Marino   DECL_ARTIFICIAL (lab) = 1;
10828e4b17023SJohn Marino   DECL_IGNORED_P (lab) = 1;
10829e4b17023SJohn Marino   DECL_CONTEXT (lab) = current_function_decl;
10830e4b17023SJohn Marino   return lab;
10831e4b17023SJohn Marino }
10832e4b17023SJohn Marino 
10833e4b17023SJohn Marino /*  Given a tree, try to return a useful variable name that we can use
10834e4b17023SJohn Marino     to prefix a temporary that is being assigned the value of the tree.
10835e4b17023SJohn Marino     I.E. given  <temp> = &A, return A.  */
10836e4b17023SJohn Marino 
10837e4b17023SJohn Marino const char *
get_name(tree t)10838e4b17023SJohn Marino get_name (tree t)
10839e4b17023SJohn Marino {
10840e4b17023SJohn Marino   tree stripped_decl;
10841e4b17023SJohn Marino 
10842e4b17023SJohn Marino   stripped_decl = t;
10843e4b17023SJohn Marino   STRIP_NOPS (stripped_decl);
10844e4b17023SJohn Marino   if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl))
10845e4b17023SJohn Marino     return IDENTIFIER_POINTER (DECL_NAME (stripped_decl));
10846e4b17023SJohn Marino   else
10847e4b17023SJohn Marino     {
10848e4b17023SJohn Marino       switch (TREE_CODE (stripped_decl))
10849e4b17023SJohn Marino 	{
10850e4b17023SJohn Marino 	case ADDR_EXPR:
10851e4b17023SJohn Marino 	  return get_name (TREE_OPERAND (stripped_decl, 0));
10852e4b17023SJohn Marino 	default:
10853e4b17023SJohn Marino 	  return NULL;
10854e4b17023SJohn Marino 	}
10855e4b17023SJohn Marino     }
10856e4b17023SJohn Marino }
10857e4b17023SJohn Marino 
10858e4b17023SJohn Marino /* Return true if TYPE has a variable argument list.  */
10859e4b17023SJohn Marino 
10860e4b17023SJohn Marino bool
stdarg_p(const_tree fntype)10861e4b17023SJohn Marino stdarg_p (const_tree fntype)
10862e4b17023SJohn Marino {
10863e4b17023SJohn Marino   function_args_iterator args_iter;
10864e4b17023SJohn Marino   tree n = NULL_TREE, t;
10865e4b17023SJohn Marino 
10866e4b17023SJohn Marino   if (!fntype)
10867e4b17023SJohn Marino     return false;
10868e4b17023SJohn Marino 
10869e4b17023SJohn Marino   FOREACH_FUNCTION_ARGS(fntype, t, args_iter)
10870e4b17023SJohn Marino     {
10871e4b17023SJohn Marino       n = t;
10872e4b17023SJohn Marino     }
10873e4b17023SJohn Marino 
10874e4b17023SJohn Marino   return n != NULL_TREE && n != void_type_node;
10875e4b17023SJohn Marino }
10876e4b17023SJohn Marino 
10877e4b17023SJohn Marino /* Return true if TYPE has a prototype.  */
10878e4b17023SJohn Marino 
10879e4b17023SJohn Marino bool
prototype_p(tree fntype)10880e4b17023SJohn Marino prototype_p (tree fntype)
10881e4b17023SJohn Marino {
10882e4b17023SJohn Marino   tree t;
10883e4b17023SJohn Marino 
10884e4b17023SJohn Marino   gcc_assert (fntype != NULL_TREE);
10885e4b17023SJohn Marino 
10886e4b17023SJohn Marino   t = TYPE_ARG_TYPES (fntype);
10887e4b17023SJohn Marino   return (t != NULL_TREE);
10888e4b17023SJohn Marino }
10889e4b17023SJohn Marino 
10890e4b17023SJohn Marino /* If BLOCK is inlined from an __attribute__((__artificial__))
10891e4b17023SJohn Marino    routine, return pointer to location from where it has been
10892e4b17023SJohn Marino    called.  */
10893e4b17023SJohn Marino location_t *
block_nonartificial_location(tree block)10894e4b17023SJohn Marino block_nonartificial_location (tree block)
10895e4b17023SJohn Marino {
10896e4b17023SJohn Marino   location_t *ret = NULL;
10897e4b17023SJohn Marino 
10898e4b17023SJohn Marino   while (block && TREE_CODE (block) == BLOCK
10899e4b17023SJohn Marino 	 && BLOCK_ABSTRACT_ORIGIN (block))
10900e4b17023SJohn Marino     {
10901e4b17023SJohn Marino       tree ao = BLOCK_ABSTRACT_ORIGIN (block);
10902e4b17023SJohn Marino 
10903e4b17023SJohn Marino       while (TREE_CODE (ao) == BLOCK
10904e4b17023SJohn Marino 	     && BLOCK_ABSTRACT_ORIGIN (ao)
10905e4b17023SJohn Marino 	     && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
10906e4b17023SJohn Marino 	ao = BLOCK_ABSTRACT_ORIGIN (ao);
10907e4b17023SJohn Marino 
10908e4b17023SJohn Marino       if (TREE_CODE (ao) == FUNCTION_DECL)
10909e4b17023SJohn Marino 	{
10910e4b17023SJohn Marino 	  /* If AO is an artificial inline, point RET to the
10911e4b17023SJohn Marino 	     call site locus at which it has been inlined and continue
10912e4b17023SJohn Marino 	     the loop, in case AO's caller is also an artificial
10913e4b17023SJohn Marino 	     inline.  */
10914e4b17023SJohn Marino 	  if (DECL_DECLARED_INLINE_P (ao)
10915e4b17023SJohn Marino 	      && lookup_attribute ("artificial", DECL_ATTRIBUTES (ao)))
10916e4b17023SJohn Marino 	    ret = &BLOCK_SOURCE_LOCATION (block);
10917e4b17023SJohn Marino 	  else
10918e4b17023SJohn Marino 	    break;
10919e4b17023SJohn Marino 	}
10920e4b17023SJohn Marino       else if (TREE_CODE (ao) != BLOCK)
10921e4b17023SJohn Marino 	break;
10922e4b17023SJohn Marino 
10923e4b17023SJohn Marino       block = BLOCK_SUPERCONTEXT (block);
10924e4b17023SJohn Marino     }
10925e4b17023SJohn Marino   return ret;
10926e4b17023SJohn Marino }
10927e4b17023SJohn Marino 
10928e4b17023SJohn Marino 
10929e4b17023SJohn Marino /* If EXP is inlined from an __attribute__((__artificial__))
10930e4b17023SJohn Marino    function, return the location of the original call expression.  */
10931e4b17023SJohn Marino 
10932e4b17023SJohn Marino location_t
tree_nonartificial_location(tree exp)10933e4b17023SJohn Marino tree_nonartificial_location (tree exp)
10934e4b17023SJohn Marino {
10935e4b17023SJohn Marino   location_t *loc = block_nonartificial_location (TREE_BLOCK (exp));
10936e4b17023SJohn Marino 
10937e4b17023SJohn Marino   if (loc)
10938e4b17023SJohn Marino     return *loc;
10939e4b17023SJohn Marino   else
10940e4b17023SJohn Marino     return EXPR_LOCATION (exp);
10941e4b17023SJohn Marino }
10942e4b17023SJohn Marino 
10943e4b17023SJohn Marino 
10944e4b17023SJohn Marino /* These are the hash table functions for the hash table of OPTIMIZATION_NODEq
10945e4b17023SJohn Marino    nodes.  */
10946e4b17023SJohn Marino 
10947e4b17023SJohn Marino /* Return the hash code code X, an OPTIMIZATION_NODE or TARGET_OPTION code.  */
10948e4b17023SJohn Marino 
10949e4b17023SJohn Marino static hashval_t
cl_option_hash_hash(const void * x)10950e4b17023SJohn Marino cl_option_hash_hash (const void *x)
10951e4b17023SJohn Marino {
10952e4b17023SJohn Marino   const_tree const t = (const_tree) x;
10953e4b17023SJohn Marino   const char *p;
10954e4b17023SJohn Marino   size_t i;
10955e4b17023SJohn Marino   size_t len = 0;
10956e4b17023SJohn Marino   hashval_t hash = 0;
10957e4b17023SJohn Marino 
10958e4b17023SJohn Marino   if (TREE_CODE (t) == OPTIMIZATION_NODE)
10959e4b17023SJohn Marino     {
10960e4b17023SJohn Marino       p = (const char *)TREE_OPTIMIZATION (t);
10961e4b17023SJohn Marino       len = sizeof (struct cl_optimization);
10962e4b17023SJohn Marino     }
10963e4b17023SJohn Marino 
10964e4b17023SJohn Marino   else if (TREE_CODE (t) == TARGET_OPTION_NODE)
10965e4b17023SJohn Marino     {
10966e4b17023SJohn Marino       p = (const char *)TREE_TARGET_OPTION (t);
10967e4b17023SJohn Marino       len = sizeof (struct cl_target_option);
10968e4b17023SJohn Marino     }
10969e4b17023SJohn Marino 
10970e4b17023SJohn Marino   else
10971e4b17023SJohn Marino     gcc_unreachable ();
10972e4b17023SJohn Marino 
10973e4b17023SJohn Marino   /* assume most opt flags are just 0/1, some are 2-3, and a few might be
10974e4b17023SJohn Marino      something else.  */
10975e4b17023SJohn Marino   for (i = 0; i < len; i++)
10976e4b17023SJohn Marino     if (p[i])
10977e4b17023SJohn Marino       hash = (hash << 4) ^ ((i << 2) | p[i]);
10978e4b17023SJohn Marino 
10979e4b17023SJohn Marino   return hash;
10980e4b17023SJohn Marino }
10981e4b17023SJohn Marino 
10982e4b17023SJohn Marino /* Return nonzero if the value represented by *X (an OPTIMIZATION or
10983e4b17023SJohn Marino    TARGET_OPTION tree node) is the same as that given by *Y, which is the
10984e4b17023SJohn Marino    same.  */
10985e4b17023SJohn Marino 
10986e4b17023SJohn Marino static int
cl_option_hash_eq(const void * x,const void * y)10987e4b17023SJohn Marino cl_option_hash_eq (const void *x, const void *y)
10988e4b17023SJohn Marino {
10989e4b17023SJohn Marino   const_tree const xt = (const_tree) x;
10990e4b17023SJohn Marino   const_tree const yt = (const_tree) y;
10991e4b17023SJohn Marino   const char *xp;
10992e4b17023SJohn Marino   const char *yp;
10993e4b17023SJohn Marino   size_t len;
10994e4b17023SJohn Marino 
10995e4b17023SJohn Marino   if (TREE_CODE (xt) != TREE_CODE (yt))
10996e4b17023SJohn Marino     return 0;
10997e4b17023SJohn Marino 
10998e4b17023SJohn Marino   if (TREE_CODE (xt) == OPTIMIZATION_NODE)
10999e4b17023SJohn Marino     {
11000e4b17023SJohn Marino       xp = (const char *)TREE_OPTIMIZATION (xt);
11001e4b17023SJohn Marino       yp = (const char *)TREE_OPTIMIZATION (yt);
11002e4b17023SJohn Marino       len = sizeof (struct cl_optimization);
11003e4b17023SJohn Marino     }
11004e4b17023SJohn Marino 
11005e4b17023SJohn Marino   else if (TREE_CODE (xt) == TARGET_OPTION_NODE)
11006e4b17023SJohn Marino     {
11007e4b17023SJohn Marino       xp = (const char *)TREE_TARGET_OPTION (xt);
11008e4b17023SJohn Marino       yp = (const char *)TREE_TARGET_OPTION (yt);
11009e4b17023SJohn Marino       len = sizeof (struct cl_target_option);
11010e4b17023SJohn Marino     }
11011e4b17023SJohn Marino 
11012e4b17023SJohn Marino   else
11013e4b17023SJohn Marino     gcc_unreachable ();
11014e4b17023SJohn Marino 
11015e4b17023SJohn Marino   return (memcmp (xp, yp, len) == 0);
11016e4b17023SJohn Marino }
11017e4b17023SJohn Marino 
11018e4b17023SJohn Marino /* Build an OPTIMIZATION_NODE based on the current options.  */
11019e4b17023SJohn Marino 
11020e4b17023SJohn Marino tree
build_optimization_node(void)11021e4b17023SJohn Marino build_optimization_node (void)
11022e4b17023SJohn Marino {
11023e4b17023SJohn Marino   tree t;
11024e4b17023SJohn Marino   void **slot;
11025e4b17023SJohn Marino 
11026e4b17023SJohn Marino   /* Use the cache of optimization nodes.  */
11027e4b17023SJohn Marino 
11028e4b17023SJohn Marino   cl_optimization_save (TREE_OPTIMIZATION (cl_optimization_node),
11029e4b17023SJohn Marino 			&global_options);
11030e4b17023SJohn Marino 
11031e4b17023SJohn Marino   slot = htab_find_slot (cl_option_hash_table, cl_optimization_node, INSERT);
11032e4b17023SJohn Marino   t = (tree) *slot;
11033e4b17023SJohn Marino   if (!t)
11034e4b17023SJohn Marino     {
11035e4b17023SJohn Marino       /* Insert this one into the hash table.  */
11036e4b17023SJohn Marino       t = cl_optimization_node;
11037e4b17023SJohn Marino       *slot = t;
11038e4b17023SJohn Marino 
11039e4b17023SJohn Marino       /* Make a new node for next time round.  */
11040e4b17023SJohn Marino       cl_optimization_node = make_node (OPTIMIZATION_NODE);
11041e4b17023SJohn Marino     }
11042e4b17023SJohn Marino 
11043e4b17023SJohn Marino   return t;
11044e4b17023SJohn Marino }
11045e4b17023SJohn Marino 
11046e4b17023SJohn Marino /* Build a TARGET_OPTION_NODE based on the current options.  */
11047e4b17023SJohn Marino 
11048e4b17023SJohn Marino tree
build_target_option_node(void)11049e4b17023SJohn Marino build_target_option_node (void)
11050e4b17023SJohn Marino {
11051e4b17023SJohn Marino   tree t;
11052e4b17023SJohn Marino   void **slot;
11053e4b17023SJohn Marino 
11054e4b17023SJohn Marino   /* Use the cache of optimization nodes.  */
11055e4b17023SJohn Marino 
11056e4b17023SJohn Marino   cl_target_option_save (TREE_TARGET_OPTION (cl_target_option_node),
11057e4b17023SJohn Marino 			 &global_options);
11058e4b17023SJohn Marino 
11059e4b17023SJohn Marino   slot = htab_find_slot (cl_option_hash_table, cl_target_option_node, INSERT);
11060e4b17023SJohn Marino   t = (tree) *slot;
11061e4b17023SJohn Marino   if (!t)
11062e4b17023SJohn Marino     {
11063e4b17023SJohn Marino       /* Insert this one into the hash table.  */
11064e4b17023SJohn Marino       t = cl_target_option_node;
11065e4b17023SJohn Marino       *slot = t;
11066e4b17023SJohn Marino 
11067e4b17023SJohn Marino       /* Make a new node for next time round.  */
11068e4b17023SJohn Marino       cl_target_option_node = make_node (TARGET_OPTION_NODE);
11069e4b17023SJohn Marino     }
11070e4b17023SJohn Marino 
11071e4b17023SJohn Marino   return t;
11072e4b17023SJohn Marino }
11073e4b17023SJohn Marino 
11074e4b17023SJohn Marino /* Determine the "ultimate origin" of a block.  The block may be an inlined
11075e4b17023SJohn Marino    instance of an inlined instance of a block which is local to an inline
11076e4b17023SJohn Marino    function, so we have to trace all of the way back through the origin chain
11077e4b17023SJohn Marino    to find out what sort of node actually served as the original seed for the
11078e4b17023SJohn Marino    given block.  */
11079e4b17023SJohn Marino 
11080e4b17023SJohn Marino tree
block_ultimate_origin(const_tree block)11081e4b17023SJohn Marino block_ultimate_origin (const_tree block)
11082e4b17023SJohn Marino {
11083e4b17023SJohn Marino   tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block);
11084e4b17023SJohn Marino 
11085e4b17023SJohn Marino   /* output_inline_function sets BLOCK_ABSTRACT_ORIGIN for all the
11086e4b17023SJohn Marino      nodes in the function to point to themselves; ignore that if
11087e4b17023SJohn Marino      we're trying to output the abstract instance of this function.  */
11088e4b17023SJohn Marino   if (BLOCK_ABSTRACT (block) && immediate_origin == block)
11089e4b17023SJohn Marino     return NULL_TREE;
11090e4b17023SJohn Marino 
11091e4b17023SJohn Marino   if (immediate_origin == NULL_TREE)
11092e4b17023SJohn Marino     return NULL_TREE;
11093e4b17023SJohn Marino   else
11094e4b17023SJohn Marino     {
11095e4b17023SJohn Marino       tree ret_val;
11096e4b17023SJohn Marino       tree lookahead = immediate_origin;
11097e4b17023SJohn Marino 
11098e4b17023SJohn Marino       do
11099e4b17023SJohn Marino 	{
11100e4b17023SJohn Marino 	  ret_val = lookahead;
11101e4b17023SJohn Marino 	  lookahead = (TREE_CODE (ret_val) == BLOCK
11102e4b17023SJohn Marino 		       ? BLOCK_ABSTRACT_ORIGIN (ret_val) : NULL);
11103e4b17023SJohn Marino 	}
11104e4b17023SJohn Marino       while (lookahead != NULL && lookahead != ret_val);
11105e4b17023SJohn Marino 
11106e4b17023SJohn Marino       /* The block's abstract origin chain may not be the *ultimate* origin of
11107e4b17023SJohn Marino 	 the block. It could lead to a DECL that has an abstract origin set.
11108e4b17023SJohn Marino 	 If so, we want that DECL's abstract origin (which is what DECL_ORIGIN
11109e4b17023SJohn Marino 	 will give us if it has one).  Note that DECL's abstract origins are
11110e4b17023SJohn Marino 	 supposed to be the most distant ancestor (or so decl_ultimate_origin
11111e4b17023SJohn Marino 	 claims), so we don't need to loop following the DECL origins.  */
11112e4b17023SJohn Marino       if (DECL_P (ret_val))
11113e4b17023SJohn Marino 	return DECL_ORIGIN (ret_val);
11114e4b17023SJohn Marino 
11115e4b17023SJohn Marino       return ret_val;
11116e4b17023SJohn Marino     }
11117e4b17023SJohn Marino }
11118e4b17023SJohn Marino 
11119e4b17023SJohn Marino /* Return true if T1 and T2 are equivalent lists.  */
11120e4b17023SJohn Marino 
11121e4b17023SJohn Marino bool
list_equal_p(const_tree t1,const_tree t2)11122e4b17023SJohn Marino list_equal_p (const_tree t1, const_tree t2)
11123e4b17023SJohn Marino {
11124e4b17023SJohn Marino   for (; t1 && t2; t1 = TREE_CHAIN (t1) , t2 = TREE_CHAIN (t2))
11125e4b17023SJohn Marino     if (TREE_VALUE (t1) != TREE_VALUE (t2))
11126e4b17023SJohn Marino       return false;
11127e4b17023SJohn Marino   return !t1 && !t2;
11128e4b17023SJohn Marino }
11129e4b17023SJohn Marino 
11130e4b17023SJohn Marino /* Return true iff conversion in EXP generates no instruction.  Mark
11131e4b17023SJohn Marino    it inline so that we fully inline into the stripping functions even
11132e4b17023SJohn Marino    though we have two uses of this function.  */
11133e4b17023SJohn Marino 
11134e4b17023SJohn Marino static inline bool
tree_nop_conversion(const_tree exp)11135e4b17023SJohn Marino tree_nop_conversion (const_tree exp)
11136e4b17023SJohn Marino {
11137e4b17023SJohn Marino   tree outer_type, inner_type;
11138e4b17023SJohn Marino 
11139e4b17023SJohn Marino   if (!CONVERT_EXPR_P (exp)
11140e4b17023SJohn Marino       && TREE_CODE (exp) != NON_LVALUE_EXPR)
11141e4b17023SJohn Marino     return false;
11142e4b17023SJohn Marino   if (TREE_OPERAND (exp, 0) == error_mark_node)
11143e4b17023SJohn Marino     return false;
11144e4b17023SJohn Marino 
11145e4b17023SJohn Marino   outer_type = TREE_TYPE (exp);
11146e4b17023SJohn Marino   inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
11147e4b17023SJohn Marino 
11148e4b17023SJohn Marino   if (!inner_type)
11149e4b17023SJohn Marino     return false;
11150e4b17023SJohn Marino 
11151e4b17023SJohn Marino   /* Use precision rather then machine mode when we can, which gives
11152e4b17023SJohn Marino      the correct answer even for submode (bit-field) types.  */
11153e4b17023SJohn Marino   if ((INTEGRAL_TYPE_P (outer_type)
11154e4b17023SJohn Marino        || POINTER_TYPE_P (outer_type)
11155e4b17023SJohn Marino        || TREE_CODE (outer_type) == OFFSET_TYPE)
11156e4b17023SJohn Marino       && (INTEGRAL_TYPE_P (inner_type)
11157e4b17023SJohn Marino 	  || POINTER_TYPE_P (inner_type)
11158e4b17023SJohn Marino 	  || TREE_CODE (inner_type) == OFFSET_TYPE))
11159e4b17023SJohn Marino     return TYPE_PRECISION (outer_type) == TYPE_PRECISION (inner_type);
11160e4b17023SJohn Marino 
11161e4b17023SJohn Marino   /* Otherwise fall back on comparing machine modes (e.g. for
11162e4b17023SJohn Marino      aggregate types, floats).  */
11163e4b17023SJohn Marino   return TYPE_MODE (outer_type) == TYPE_MODE (inner_type);
11164e4b17023SJohn Marino }
11165e4b17023SJohn Marino 
11166e4b17023SJohn Marino /* Return true iff conversion in EXP generates no instruction.  Don't
11167e4b17023SJohn Marino    consider conversions changing the signedness.  */
11168e4b17023SJohn Marino 
11169e4b17023SJohn Marino static bool
tree_sign_nop_conversion(const_tree exp)11170e4b17023SJohn Marino tree_sign_nop_conversion (const_tree exp)
11171e4b17023SJohn Marino {
11172e4b17023SJohn Marino   tree outer_type, inner_type;
11173e4b17023SJohn Marino 
11174e4b17023SJohn Marino   if (!tree_nop_conversion (exp))
11175e4b17023SJohn Marino     return false;
11176e4b17023SJohn Marino 
11177e4b17023SJohn Marino   outer_type = TREE_TYPE (exp);
11178e4b17023SJohn Marino   inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
11179e4b17023SJohn Marino 
11180e4b17023SJohn Marino   return (TYPE_UNSIGNED (outer_type) == TYPE_UNSIGNED (inner_type)
11181e4b17023SJohn Marino 	  && POINTER_TYPE_P (outer_type) == POINTER_TYPE_P (inner_type));
11182e4b17023SJohn Marino }
11183e4b17023SJohn Marino 
11184e4b17023SJohn Marino /* Strip conversions from EXP according to tree_nop_conversion and
11185e4b17023SJohn Marino    return the resulting expression.  */
11186e4b17023SJohn Marino 
11187e4b17023SJohn Marino tree
tree_strip_nop_conversions(tree exp)11188e4b17023SJohn Marino tree_strip_nop_conversions (tree exp)
11189e4b17023SJohn Marino {
11190e4b17023SJohn Marino   while (tree_nop_conversion (exp))
11191e4b17023SJohn Marino     exp = TREE_OPERAND (exp, 0);
11192e4b17023SJohn Marino   return exp;
11193e4b17023SJohn Marino }
11194e4b17023SJohn Marino 
11195e4b17023SJohn Marino /* Strip conversions from EXP according to tree_sign_nop_conversion
11196e4b17023SJohn Marino    and return the resulting expression.  */
11197e4b17023SJohn Marino 
11198e4b17023SJohn Marino tree
tree_strip_sign_nop_conversions(tree exp)11199e4b17023SJohn Marino tree_strip_sign_nop_conversions (tree exp)
11200e4b17023SJohn Marino {
11201e4b17023SJohn Marino   while (tree_sign_nop_conversion (exp))
11202e4b17023SJohn Marino     exp = TREE_OPERAND (exp, 0);
11203e4b17023SJohn Marino   return exp;
11204e4b17023SJohn Marino }
11205e4b17023SJohn Marino 
11206e4b17023SJohn Marino /* Strip out all handled components that produce invariant
11207e4b17023SJohn Marino    offsets.  */
11208e4b17023SJohn Marino 
11209e4b17023SJohn Marino const_tree
strip_invariant_refs(const_tree op)11210e4b17023SJohn Marino strip_invariant_refs (const_tree op)
11211e4b17023SJohn Marino {
11212e4b17023SJohn Marino   while (handled_component_p (op))
11213e4b17023SJohn Marino     {
11214e4b17023SJohn Marino       switch (TREE_CODE (op))
11215e4b17023SJohn Marino 	{
11216e4b17023SJohn Marino 	case ARRAY_REF:
11217e4b17023SJohn Marino 	case ARRAY_RANGE_REF:
11218e4b17023SJohn Marino 	  if (!is_gimple_constant (TREE_OPERAND (op, 1))
11219e4b17023SJohn Marino 	      || TREE_OPERAND (op, 2) != NULL_TREE
11220e4b17023SJohn Marino 	      || TREE_OPERAND (op, 3) != NULL_TREE)
11221e4b17023SJohn Marino 	    return NULL;
11222e4b17023SJohn Marino 	  break;
11223e4b17023SJohn Marino 
11224e4b17023SJohn Marino 	case COMPONENT_REF:
11225e4b17023SJohn Marino 	  if (TREE_OPERAND (op, 2) != NULL_TREE)
11226e4b17023SJohn Marino 	    return NULL;
11227e4b17023SJohn Marino 	  break;
11228e4b17023SJohn Marino 
11229e4b17023SJohn Marino 	default:;
11230e4b17023SJohn Marino 	}
11231e4b17023SJohn Marino       op = TREE_OPERAND (op, 0);
11232e4b17023SJohn Marino     }
11233e4b17023SJohn Marino 
11234e4b17023SJohn Marino   return op;
11235e4b17023SJohn Marino }
11236e4b17023SJohn Marino 
11237e4b17023SJohn Marino static GTY(()) tree gcc_eh_personality_decl;
11238e4b17023SJohn Marino 
11239e4b17023SJohn Marino /* Return the GCC personality function decl.  */
11240e4b17023SJohn Marino 
11241e4b17023SJohn Marino tree
lhd_gcc_personality(void)11242e4b17023SJohn Marino lhd_gcc_personality (void)
11243e4b17023SJohn Marino {
11244e4b17023SJohn Marino   if (!gcc_eh_personality_decl)
11245e4b17023SJohn Marino     gcc_eh_personality_decl = build_personality_function ("gcc");
11246e4b17023SJohn Marino   return gcc_eh_personality_decl;
11247e4b17023SJohn Marino }
11248e4b17023SJohn Marino 
11249e4b17023SJohn Marino /* Try to find a base info of BINFO that would have its field decl at offset
11250e4b17023SJohn Marino    OFFSET within the BINFO type and which is of EXPECTED_TYPE.  If it can be
11251e4b17023SJohn Marino    found, return, otherwise return NULL_TREE.  */
11252e4b17023SJohn Marino 
11253e4b17023SJohn Marino tree
get_binfo_at_offset(tree binfo,HOST_WIDE_INT offset,tree expected_type)11254e4b17023SJohn Marino get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
11255e4b17023SJohn Marino {
11256e4b17023SJohn Marino   tree type = BINFO_TYPE (binfo);
11257e4b17023SJohn Marino 
11258e4b17023SJohn Marino   while (true)
11259e4b17023SJohn Marino     {
11260e4b17023SJohn Marino       HOST_WIDE_INT pos, size;
11261e4b17023SJohn Marino       tree fld;
11262e4b17023SJohn Marino       int i;
11263e4b17023SJohn Marino 
11264e4b17023SJohn Marino       if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (expected_type))
11265e4b17023SJohn Marino 	  return binfo;
11266e4b17023SJohn Marino       if (offset < 0)
11267e4b17023SJohn Marino 	return NULL_TREE;
11268e4b17023SJohn Marino 
11269e4b17023SJohn Marino       for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
11270e4b17023SJohn Marino 	{
11271e4b17023SJohn Marino 	  if (TREE_CODE (fld) != FIELD_DECL)
11272e4b17023SJohn Marino 	    continue;
11273e4b17023SJohn Marino 
11274e4b17023SJohn Marino 	  pos = int_bit_position (fld);
11275e4b17023SJohn Marino 	  size = tree_low_cst (DECL_SIZE (fld), 1);
11276e4b17023SJohn Marino 	  if (pos <= offset && (pos + size) > offset)
11277e4b17023SJohn Marino 	    break;
11278e4b17023SJohn Marino 	}
11279e4b17023SJohn Marino       if (!fld || TREE_CODE (TREE_TYPE (fld)) != RECORD_TYPE)
11280e4b17023SJohn Marino 	return NULL_TREE;
11281e4b17023SJohn Marino 
11282e4b17023SJohn Marino       if (!DECL_ARTIFICIAL (fld))
11283e4b17023SJohn Marino 	{
11284e4b17023SJohn Marino 	  binfo = TYPE_BINFO (TREE_TYPE (fld));
11285e4b17023SJohn Marino 	  if (!binfo)
11286e4b17023SJohn Marino 	    return NULL_TREE;
11287e4b17023SJohn Marino 	}
11288e4b17023SJohn Marino       /* Offset 0 indicates the primary base, whose vtable contents are
11289e4b17023SJohn Marino 	 represented in the binfo for the derived class.  */
11290e4b17023SJohn Marino       else if (offset != 0)
11291e4b17023SJohn Marino 	{
11292e4b17023SJohn Marino 	  tree base_binfo, found_binfo = NULL_TREE;
11293e4b17023SJohn Marino 	  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
11294e4b17023SJohn Marino 	    if (TREE_TYPE (base_binfo) == TREE_TYPE (fld))
11295e4b17023SJohn Marino 	      {
11296e4b17023SJohn Marino 		found_binfo = base_binfo;
11297e4b17023SJohn Marino 		break;
11298e4b17023SJohn Marino 	      }
11299e4b17023SJohn Marino 	  if (!found_binfo)
11300e4b17023SJohn Marino 	    return NULL_TREE;
11301e4b17023SJohn Marino 	  binfo = found_binfo;
11302e4b17023SJohn Marino 	}
11303e4b17023SJohn Marino 
11304e4b17023SJohn Marino       type = TREE_TYPE (fld);
11305e4b17023SJohn Marino       offset -= pos;
11306e4b17023SJohn Marino     }
11307e4b17023SJohn Marino }
11308e4b17023SJohn Marino 
11309e4b17023SJohn Marino /* Returns true if X is a typedef decl.  */
11310e4b17023SJohn Marino 
11311e4b17023SJohn Marino bool
is_typedef_decl(tree x)11312e4b17023SJohn Marino is_typedef_decl (tree x)
11313e4b17023SJohn Marino {
11314e4b17023SJohn Marino   return (x && TREE_CODE (x) == TYPE_DECL
11315e4b17023SJohn Marino           && DECL_ORIGINAL_TYPE (x) != NULL_TREE);
11316e4b17023SJohn Marino }
11317e4b17023SJohn Marino 
11318e4b17023SJohn Marino /* Returns true iff TYPE is a type variant created for a typedef. */
11319e4b17023SJohn Marino 
11320e4b17023SJohn Marino bool
typedef_variant_p(tree type)11321e4b17023SJohn Marino typedef_variant_p (tree type)
11322e4b17023SJohn Marino {
11323e4b17023SJohn Marino   return is_typedef_decl (TYPE_NAME (type));
11324e4b17023SJohn Marino }
11325e4b17023SJohn Marino 
11326e4b17023SJohn Marino /* Warn about a use of an identifier which was marked deprecated.  */
11327e4b17023SJohn Marino void
warn_deprecated_use(tree node,tree attr)11328e4b17023SJohn Marino warn_deprecated_use (tree node, tree attr)
11329e4b17023SJohn Marino {
11330e4b17023SJohn Marino   const char *msg;
11331e4b17023SJohn Marino 
11332e4b17023SJohn Marino   if (node == 0 || !warn_deprecated_decl)
11333e4b17023SJohn Marino     return;
11334e4b17023SJohn Marino 
11335e4b17023SJohn Marino   if (!attr)
11336e4b17023SJohn Marino     {
11337e4b17023SJohn Marino       if (DECL_P (node))
11338e4b17023SJohn Marino 	attr = DECL_ATTRIBUTES (node);
11339e4b17023SJohn Marino       else if (TYPE_P (node))
11340e4b17023SJohn Marino 	{
11341e4b17023SJohn Marino 	  tree decl = TYPE_STUB_DECL (node);
11342e4b17023SJohn Marino 	  if (decl)
11343e4b17023SJohn Marino 	    attr = lookup_attribute ("deprecated",
11344e4b17023SJohn Marino 				     TYPE_ATTRIBUTES (TREE_TYPE (decl)));
11345e4b17023SJohn Marino 	}
11346e4b17023SJohn Marino     }
11347e4b17023SJohn Marino 
11348e4b17023SJohn Marino   if (attr)
11349e4b17023SJohn Marino     attr = lookup_attribute ("deprecated", attr);
11350e4b17023SJohn Marino 
11351e4b17023SJohn Marino   if (attr)
11352e4b17023SJohn Marino     msg = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
11353e4b17023SJohn Marino   else
11354e4b17023SJohn Marino     msg = NULL;
11355e4b17023SJohn Marino 
11356e4b17023SJohn Marino   if (DECL_P (node))
11357e4b17023SJohn Marino     {
11358e4b17023SJohn Marino       expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (node));
11359e4b17023SJohn Marino       if (msg)
11360e4b17023SJohn Marino 	warning (OPT_Wdeprecated_declarations,
11361e4b17023SJohn Marino 		 "%qD is deprecated (declared at %s:%d): %s",
11362e4b17023SJohn Marino 		 node, xloc.file, xloc.line, msg);
11363e4b17023SJohn Marino       else
11364e4b17023SJohn Marino 	warning (OPT_Wdeprecated_declarations,
11365e4b17023SJohn Marino 		 "%qD is deprecated (declared at %s:%d)",
11366e4b17023SJohn Marino 		 node, xloc.file, xloc.line);
11367e4b17023SJohn Marino     }
11368e4b17023SJohn Marino   else if (TYPE_P (node))
11369e4b17023SJohn Marino     {
11370e4b17023SJohn Marino       tree what = NULL_TREE;
11371e4b17023SJohn Marino       tree decl = TYPE_STUB_DECL (node);
11372e4b17023SJohn Marino 
11373e4b17023SJohn Marino       if (TYPE_NAME (node))
11374e4b17023SJohn Marino 	{
11375e4b17023SJohn Marino 	  if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
11376e4b17023SJohn Marino 	    what = TYPE_NAME (node);
11377e4b17023SJohn Marino 	  else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
11378e4b17023SJohn Marino 		   && DECL_NAME (TYPE_NAME (node)))
11379e4b17023SJohn Marino 	    what = DECL_NAME (TYPE_NAME (node));
11380e4b17023SJohn Marino 	}
11381e4b17023SJohn Marino 
11382e4b17023SJohn Marino       if (decl)
11383e4b17023SJohn Marino 	{
11384e4b17023SJohn Marino 	  expanded_location xloc
11385e4b17023SJohn Marino 	    = expand_location (DECL_SOURCE_LOCATION (decl));
11386e4b17023SJohn Marino 	  if (what)
11387e4b17023SJohn Marino 	    {
11388e4b17023SJohn Marino 	      if (msg)
11389e4b17023SJohn Marino 		warning (OPT_Wdeprecated_declarations,
11390e4b17023SJohn Marino 			 "%qE is deprecated (declared at %s:%d): %s",
11391e4b17023SJohn Marino 			 what, xloc.file, xloc.line, msg);
11392e4b17023SJohn Marino 	      else
11393e4b17023SJohn Marino 		warning (OPT_Wdeprecated_declarations,
11394e4b17023SJohn Marino 			 "%qE is deprecated (declared at %s:%d)", what,
11395e4b17023SJohn Marino 			 xloc.file, xloc.line);
11396e4b17023SJohn Marino 	    }
11397e4b17023SJohn Marino 	  else
11398e4b17023SJohn Marino 	    {
11399e4b17023SJohn Marino 	      if (msg)
11400e4b17023SJohn Marino 		warning (OPT_Wdeprecated_declarations,
11401e4b17023SJohn Marino 			 "type is deprecated (declared at %s:%d): %s",
11402e4b17023SJohn Marino 			 xloc.file, xloc.line, msg);
11403e4b17023SJohn Marino 	      else
11404e4b17023SJohn Marino 		warning (OPT_Wdeprecated_declarations,
11405e4b17023SJohn Marino 			 "type is deprecated (declared at %s:%d)",
11406e4b17023SJohn Marino 			 xloc.file, xloc.line);
11407e4b17023SJohn Marino 	    }
11408e4b17023SJohn Marino 	}
11409e4b17023SJohn Marino       else
11410e4b17023SJohn Marino 	{
11411e4b17023SJohn Marino 	  if (what)
11412e4b17023SJohn Marino 	    {
11413e4b17023SJohn Marino 	      if (msg)
11414e4b17023SJohn Marino 		warning (OPT_Wdeprecated_declarations, "%qE is deprecated: %s",
11415e4b17023SJohn Marino 			 what, msg);
11416e4b17023SJohn Marino 	      else
11417e4b17023SJohn Marino 		warning (OPT_Wdeprecated_declarations, "%qE is deprecated", what);
11418e4b17023SJohn Marino 	    }
11419e4b17023SJohn Marino 	  else
11420e4b17023SJohn Marino 	    {
11421e4b17023SJohn Marino 	      if (msg)
11422e4b17023SJohn Marino 		warning (OPT_Wdeprecated_declarations, "type is deprecated: %s",
11423e4b17023SJohn Marino 			 msg);
11424e4b17023SJohn Marino 	      else
11425e4b17023SJohn Marino 		warning (OPT_Wdeprecated_declarations, "type is deprecated");
11426e4b17023SJohn Marino 	    }
11427e4b17023SJohn Marino 	}
11428e4b17023SJohn Marino     }
11429e4b17023SJohn Marino }
11430e4b17023SJohn Marino 
11431e4b17023SJohn Marino #include "gt-tree.h"
11432