1*38fd1498Szrj /* This file contains subroutine used by the C front-end to construct GENERIC.
2*38fd1498Szrj Copyright (C) 2000-2018 Free Software Foundation, Inc.
3*38fd1498Szrj Written by Benjamin Chelf (chelf@codesourcery.com).
4*38fd1498Szrj
5*38fd1498Szrj This file is part of GCC.
6*38fd1498Szrj
7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
8*38fd1498Szrj the terms of the GNU General Public License as published by the Free
9*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
10*38fd1498Szrj version.
11*38fd1498Szrj
12*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15*38fd1498Szrj for more details.
16*38fd1498Szrj
17*38fd1498Szrj You should have received a copy of the GNU General Public License
18*38fd1498Szrj along with GCC; see the file COPYING3. If not see
19*38fd1498Szrj <http://www.gnu.org/licenses/>. */
20*38fd1498Szrj
21*38fd1498Szrj #include "config.h"
22*38fd1498Szrj #include "system.h"
23*38fd1498Szrj #include "coretypes.h"
24*38fd1498Szrj #include "c-common.h"
25*38fd1498Szrj #include "tree-iterator.h"
26*38fd1498Szrj
27*38fd1498Szrj /* Create an empty statement tree rooted at T. */
28*38fd1498Szrj
29*38fd1498Szrj tree
push_stmt_list(void)30*38fd1498Szrj push_stmt_list (void)
31*38fd1498Szrj {
32*38fd1498Szrj tree t;
33*38fd1498Szrj t = alloc_stmt_list ();
34*38fd1498Szrj vec_safe_push (stmt_list_stack, t);
35*38fd1498Szrj return t;
36*38fd1498Szrj }
37*38fd1498Szrj
38*38fd1498Szrj /* Return TRUE if, after I, there are any nondebug stmts. */
39*38fd1498Szrj
40*38fd1498Szrj static inline bool
only_debug_stmts_after_p(tree_stmt_iterator i)41*38fd1498Szrj only_debug_stmts_after_p (tree_stmt_iterator i)
42*38fd1498Szrj {
43*38fd1498Szrj for (tsi_next (&i); !tsi_end_p (i); tsi_next (&i))
44*38fd1498Szrj if (TREE_CODE (tsi_stmt (i)) != DEBUG_BEGIN_STMT)
45*38fd1498Szrj return false;
46*38fd1498Szrj return true;
47*38fd1498Szrj }
48*38fd1498Szrj
49*38fd1498Szrj /* Finish the statement tree rooted at T. */
50*38fd1498Szrj
51*38fd1498Szrj tree
pop_stmt_list(tree t)52*38fd1498Szrj pop_stmt_list (tree t)
53*38fd1498Szrj {
54*38fd1498Szrj tree u = NULL_TREE;
55*38fd1498Szrj
56*38fd1498Szrj /* Pop statement lists until we reach the target level. The extra
57*38fd1498Szrj nestings will be due to outstanding cleanups. */
58*38fd1498Szrj while (1)
59*38fd1498Szrj {
60*38fd1498Szrj u = stmt_list_stack->pop ();
61*38fd1498Szrj if (!stmt_list_stack->is_empty ())
62*38fd1498Szrj {
63*38fd1498Szrj tree x = stmt_list_stack->last ();
64*38fd1498Szrj STATEMENT_LIST_HAS_LABEL (x) |= STATEMENT_LIST_HAS_LABEL (u);
65*38fd1498Szrj }
66*38fd1498Szrj if (t == u)
67*38fd1498Szrj break;
68*38fd1498Szrj }
69*38fd1498Szrj
70*38fd1498Szrj gcc_assert (u != NULL_TREE);
71*38fd1498Szrj
72*38fd1498Szrj /* If the statement list is completely empty, just return it. This is
73*38fd1498Szrj just as good small as build_empty_stmt, with the advantage that
74*38fd1498Szrj statement lists are merged when they appended to one another. So
75*38fd1498Szrj using the STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P
76*38fd1498Szrj statements. */
77*38fd1498Szrj if (TREE_SIDE_EFFECTS (t))
78*38fd1498Szrj {
79*38fd1498Szrj tree_stmt_iterator i = tsi_start (t);
80*38fd1498Szrj
81*38fd1498Szrj /* If the statement list contained exactly one statement, then
82*38fd1498Szrj extract it immediately. */
83*38fd1498Szrj if (tsi_one_before_end_p (i))
84*38fd1498Szrj {
85*38fd1498Szrj u = tsi_stmt (i);
86*38fd1498Szrj tsi_delink (&i);
87*38fd1498Szrj free_stmt_list (t);
88*38fd1498Szrj t = u;
89*38fd1498Szrj }
90*38fd1498Szrj /* If the statement list contained a debug begin stmt and a
91*38fd1498Szrj statement list, move the debug begin stmt into the statement
92*38fd1498Szrj list and return it. */
93*38fd1498Szrj else if (!tsi_end_p (i)
94*38fd1498Szrj && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
95*38fd1498Szrj {
96*38fd1498Szrj u = tsi_stmt (i);
97*38fd1498Szrj tsi_next (&i);
98*38fd1498Szrj if (tsi_one_before_end_p (i)
99*38fd1498Szrj && TREE_CODE (tsi_stmt (i)) == STATEMENT_LIST)
100*38fd1498Szrj {
101*38fd1498Szrj tree l = tsi_stmt (i);
102*38fd1498Szrj tsi_prev (&i);
103*38fd1498Szrj tsi_delink (&i);
104*38fd1498Szrj tsi_delink (&i);
105*38fd1498Szrj i = tsi_start (l);
106*38fd1498Szrj free_stmt_list (t);
107*38fd1498Szrj t = l;
108*38fd1498Szrj tsi_link_before (&i, u, TSI_SAME_STMT);
109*38fd1498Szrj }
110*38fd1498Szrj while (!tsi_end_p (i)
111*38fd1498Szrj && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
112*38fd1498Szrj tsi_next (&i);
113*38fd1498Szrj /* If there are only debug stmts in the list, without them
114*38fd1498Szrj we'd have an empty stmt without side effects. If there's
115*38fd1498Szrj only one nondebug stmt, we'd have extracted the stmt and
116*38fd1498Szrj dropped the list, and we'd take TREE_SIDE_EFFECTS from
117*38fd1498Szrj that statement. In either case, keep the list's
118*38fd1498Szrj TREE_SIDE_EFFECTS in sync. */
119*38fd1498Szrj if (tsi_end_p (i))
120*38fd1498Szrj TREE_SIDE_EFFECTS (t) = 0;
121*38fd1498Szrj else if (only_debug_stmts_after_p (i))
122*38fd1498Szrj TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (tsi_stmt (i));
123*38fd1498Szrj }
124*38fd1498Szrj }
125*38fd1498Szrj
126*38fd1498Szrj return t;
127*38fd1498Szrj }
128*38fd1498Szrj
129*38fd1498Szrj /* Build a generic statement based on the given type of node and
130*38fd1498Szrj arguments. Similar to `build_nt', except that we set
131*38fd1498Szrj EXPR_LOCATION to LOC. */
132*38fd1498Szrj /* ??? This should be obsolete with the lineno_stmt productions
133*38fd1498Szrj in the grammar. */
134*38fd1498Szrj
135*38fd1498Szrj tree
build_stmt(location_t loc,enum tree_code code,...)136*38fd1498Szrj build_stmt (location_t loc, enum tree_code code, ...)
137*38fd1498Szrj {
138*38fd1498Szrj tree ret;
139*38fd1498Szrj int length, i;
140*38fd1498Szrj va_list p;
141*38fd1498Szrj bool side_effects;
142*38fd1498Szrj
143*38fd1498Szrj /* This function cannot be used to construct variably-sized nodes. */
144*38fd1498Szrj gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
145*38fd1498Szrj
146*38fd1498Szrj va_start (p, code);
147*38fd1498Szrj
148*38fd1498Szrj ret = make_node (code);
149*38fd1498Szrj TREE_TYPE (ret) = void_type_node;
150*38fd1498Szrj length = TREE_CODE_LENGTH (code);
151*38fd1498Szrj SET_EXPR_LOCATION (ret, loc);
152*38fd1498Szrj
153*38fd1498Szrj /* TREE_SIDE_EFFECTS will already be set for statements with
154*38fd1498Szrj implicit side effects. Here we make sure it is set for other
155*38fd1498Szrj expressions by checking whether the parameters have side
156*38fd1498Szrj effects. */
157*38fd1498Szrj
158*38fd1498Szrj side_effects = false;
159*38fd1498Szrj for (i = 0; i < length; i++)
160*38fd1498Szrj {
161*38fd1498Szrj tree t = va_arg (p, tree);
162*38fd1498Szrj if (t && !TYPE_P (t))
163*38fd1498Szrj side_effects |= TREE_SIDE_EFFECTS (t);
164*38fd1498Szrj TREE_OPERAND (ret, i) = t;
165*38fd1498Szrj }
166*38fd1498Szrj
167*38fd1498Szrj TREE_SIDE_EFFECTS (ret) |= side_effects;
168*38fd1498Szrj
169*38fd1498Szrj va_end (p);
170*38fd1498Szrj return ret;
171*38fd1498Szrj }
172*38fd1498Szrj
173*38fd1498Szrj /* Build a REALPART_EXPR or IMAGPART_EXPR, according to CODE, from ARG. */
174*38fd1498Szrj
175*38fd1498Szrj tree
build_real_imag_expr(location_t location,enum tree_code code,tree arg)176*38fd1498Szrj build_real_imag_expr (location_t location, enum tree_code code, tree arg)
177*38fd1498Szrj {
178*38fd1498Szrj tree ret;
179*38fd1498Szrj tree arg_type = TREE_TYPE (arg);
180*38fd1498Szrj
181*38fd1498Szrj gcc_assert (code == REALPART_EXPR || code == IMAGPART_EXPR);
182*38fd1498Szrj
183*38fd1498Szrj if (TREE_CODE (arg_type) == COMPLEX_TYPE)
184*38fd1498Szrj {
185*38fd1498Szrj ret = build1 (code, TREE_TYPE (TREE_TYPE (arg)), arg);
186*38fd1498Szrj SET_EXPR_LOCATION (ret, location);
187*38fd1498Szrj }
188*38fd1498Szrj else if (INTEGRAL_TYPE_P (arg_type) || SCALAR_FLOAT_TYPE_P (arg_type))
189*38fd1498Szrj {
190*38fd1498Szrj ret = (code == REALPART_EXPR
191*38fd1498Szrj ? arg
192*38fd1498Szrj : omit_one_operand_loc (location, arg_type,
193*38fd1498Szrj integer_zero_node, arg));
194*38fd1498Szrj }
195*38fd1498Szrj else
196*38fd1498Szrj {
197*38fd1498Szrj error_at (location, "wrong type argument to %s",
198*38fd1498Szrj code == REALPART_EXPR ? "__real" : "__imag");
199*38fd1498Szrj ret = error_mark_node;
200*38fd1498Szrj }
201*38fd1498Szrj
202*38fd1498Szrj return ret;
203*38fd1498Szrj }
204