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