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