11debfc3dSmrg /* This file contains subroutine used by the C front-end to construct GENERIC.
2*8feb0f0bSmrg Copyright (C) 2000-2020 Free Software Foundation, Inc.
31debfc3dSmrg Written by Benjamin Chelf (chelf@codesourcery.com).
41debfc3dSmrg
51debfc3dSmrg This file is part of GCC.
61debfc3dSmrg
71debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
81debfc3dSmrg the terms of the GNU General Public License as published by the Free
91debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
101debfc3dSmrg version.
111debfc3dSmrg
121debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
131debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
141debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
151debfc3dSmrg for more details.
161debfc3dSmrg
171debfc3dSmrg You should have received a copy of the GNU General Public License
181debfc3dSmrg along with GCC; see the file COPYING3. If not see
191debfc3dSmrg <http://www.gnu.org/licenses/>. */
201debfc3dSmrg
211debfc3dSmrg #include "config.h"
221debfc3dSmrg #include "system.h"
231debfc3dSmrg #include "coretypes.h"
241debfc3dSmrg #include "c-common.h"
251debfc3dSmrg #include "tree-iterator.h"
261debfc3dSmrg
271debfc3dSmrg /* Create an empty statement tree rooted at T. */
281debfc3dSmrg
291debfc3dSmrg tree
push_stmt_list(void)301debfc3dSmrg push_stmt_list (void)
311debfc3dSmrg {
321debfc3dSmrg tree t;
331debfc3dSmrg t = alloc_stmt_list ();
341debfc3dSmrg vec_safe_push (stmt_list_stack, t);
351debfc3dSmrg return t;
361debfc3dSmrg }
371debfc3dSmrg
38a2dc1f3fSmrg /* Return TRUE if, after I, there are any nondebug stmts. */
39a2dc1f3fSmrg
40a2dc1f3fSmrg static inline bool
only_debug_stmts_after_p(tree_stmt_iterator i)41a2dc1f3fSmrg only_debug_stmts_after_p (tree_stmt_iterator i)
42a2dc1f3fSmrg {
43a2dc1f3fSmrg for (tsi_next (&i); !tsi_end_p (i); tsi_next (&i))
44a2dc1f3fSmrg if (TREE_CODE (tsi_stmt (i)) != DEBUG_BEGIN_STMT)
45a2dc1f3fSmrg return false;
46a2dc1f3fSmrg return true;
47a2dc1f3fSmrg }
48a2dc1f3fSmrg
491debfc3dSmrg /* Finish the statement tree rooted at T. */
501debfc3dSmrg
511debfc3dSmrg tree
pop_stmt_list(tree t)521debfc3dSmrg pop_stmt_list (tree t)
531debfc3dSmrg {
541debfc3dSmrg tree u = NULL_TREE;
551debfc3dSmrg
561debfc3dSmrg /* Pop statement lists until we reach the target level. The extra
571debfc3dSmrg nestings will be due to outstanding cleanups. */
581debfc3dSmrg while (1)
591debfc3dSmrg {
601debfc3dSmrg u = stmt_list_stack->pop ();
611debfc3dSmrg if (!stmt_list_stack->is_empty ())
621debfc3dSmrg {
631debfc3dSmrg tree x = stmt_list_stack->last ();
641debfc3dSmrg STATEMENT_LIST_HAS_LABEL (x) |= STATEMENT_LIST_HAS_LABEL (u);
651debfc3dSmrg }
661debfc3dSmrg if (t == u)
671debfc3dSmrg break;
681debfc3dSmrg }
691debfc3dSmrg
701debfc3dSmrg gcc_assert (u != NULL_TREE);
711debfc3dSmrg
721debfc3dSmrg /* If the statement list is completely empty, just return it. This is
731debfc3dSmrg just as good small as build_empty_stmt, with the advantage that
741debfc3dSmrg statement lists are merged when they appended to one another. So
751debfc3dSmrg using the STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P
761debfc3dSmrg statements. */
771debfc3dSmrg if (TREE_SIDE_EFFECTS (t))
781debfc3dSmrg {
791debfc3dSmrg tree_stmt_iterator i = tsi_start (t);
801debfc3dSmrg
811debfc3dSmrg /* If the statement list contained exactly one statement, then
821debfc3dSmrg extract it immediately. */
831debfc3dSmrg if (tsi_one_before_end_p (i))
841debfc3dSmrg {
851debfc3dSmrg u = tsi_stmt (i);
861debfc3dSmrg tsi_delink (&i);
871debfc3dSmrg free_stmt_list (t);
881debfc3dSmrg t = u;
891debfc3dSmrg }
90a2dc1f3fSmrg /* If the statement list contained a debug begin stmt and a
91a2dc1f3fSmrg statement list, move the debug begin stmt into the statement
92a2dc1f3fSmrg list and return it. */
93a2dc1f3fSmrg else if (!tsi_end_p (i)
94a2dc1f3fSmrg && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
95a2dc1f3fSmrg {
96a2dc1f3fSmrg u = tsi_stmt (i);
97a2dc1f3fSmrg tsi_next (&i);
98a2dc1f3fSmrg if (tsi_one_before_end_p (i)
99a2dc1f3fSmrg && TREE_CODE (tsi_stmt (i)) == STATEMENT_LIST)
100a2dc1f3fSmrg {
101a2dc1f3fSmrg tree l = tsi_stmt (i);
102a2dc1f3fSmrg tsi_prev (&i);
103a2dc1f3fSmrg tsi_delink (&i);
104a2dc1f3fSmrg tsi_delink (&i);
105a2dc1f3fSmrg i = tsi_start (l);
106a2dc1f3fSmrg free_stmt_list (t);
107a2dc1f3fSmrg t = l;
108a2dc1f3fSmrg tsi_link_before (&i, u, TSI_SAME_STMT);
109a2dc1f3fSmrg }
110a2dc1f3fSmrg while (!tsi_end_p (i)
111a2dc1f3fSmrg && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
112a2dc1f3fSmrg tsi_next (&i);
113a2dc1f3fSmrg /* If there are only debug stmts in the list, without them
114a2dc1f3fSmrg we'd have an empty stmt without side effects. If there's
115a2dc1f3fSmrg only one nondebug stmt, we'd have extracted the stmt and
116a2dc1f3fSmrg dropped the list, and we'd take TREE_SIDE_EFFECTS from
117a2dc1f3fSmrg that statement. In either case, keep the list's
118a2dc1f3fSmrg TREE_SIDE_EFFECTS in sync. */
119a2dc1f3fSmrg if (tsi_end_p (i))
120a2dc1f3fSmrg TREE_SIDE_EFFECTS (t) = 0;
121a2dc1f3fSmrg else if (only_debug_stmts_after_p (i))
122a2dc1f3fSmrg TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (tsi_stmt (i));
123a2dc1f3fSmrg }
1241debfc3dSmrg }
1251debfc3dSmrg
1261debfc3dSmrg return t;
1271debfc3dSmrg }
1281debfc3dSmrg
1291debfc3dSmrg /* Build a generic statement based on the given type of node and
1301debfc3dSmrg arguments. Similar to `build_nt', except that we set
1311debfc3dSmrg EXPR_LOCATION to LOC. */
1321debfc3dSmrg /* ??? This should be obsolete with the lineno_stmt productions
1331debfc3dSmrg in the grammar. */
1341debfc3dSmrg
1351debfc3dSmrg tree
build_stmt(location_t loc,enum tree_code code,...)1361debfc3dSmrg build_stmt (location_t loc, enum tree_code code, ...)
1371debfc3dSmrg {
1381debfc3dSmrg tree ret;
1391debfc3dSmrg int length, i;
1401debfc3dSmrg va_list p;
1411debfc3dSmrg bool side_effects;
1421debfc3dSmrg
1431debfc3dSmrg /* This function cannot be used to construct variably-sized nodes. */
1441debfc3dSmrg gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
1451debfc3dSmrg
1461debfc3dSmrg va_start (p, code);
1471debfc3dSmrg
1481debfc3dSmrg ret = make_node (code);
1491debfc3dSmrg TREE_TYPE (ret) = void_type_node;
1501debfc3dSmrg length = TREE_CODE_LENGTH (code);
1511debfc3dSmrg SET_EXPR_LOCATION (ret, loc);
1521debfc3dSmrg
1531debfc3dSmrg /* TREE_SIDE_EFFECTS will already be set for statements with
1541debfc3dSmrg implicit side effects. Here we make sure it is set for other
1551debfc3dSmrg expressions by checking whether the parameters have side
1561debfc3dSmrg effects. */
1571debfc3dSmrg
1581debfc3dSmrg side_effects = false;
1591debfc3dSmrg for (i = 0; i < length; i++)
1601debfc3dSmrg {
1611debfc3dSmrg tree t = va_arg (p, tree);
1621debfc3dSmrg if (t && !TYPE_P (t))
1631debfc3dSmrg side_effects |= TREE_SIDE_EFFECTS (t);
1641debfc3dSmrg TREE_OPERAND (ret, i) = t;
1651debfc3dSmrg }
1661debfc3dSmrg
1671debfc3dSmrg TREE_SIDE_EFFECTS (ret) |= side_effects;
1681debfc3dSmrg
1691debfc3dSmrg va_end (p);
1701debfc3dSmrg return ret;
1711debfc3dSmrg }
1721debfc3dSmrg
1731debfc3dSmrg /* Build a REALPART_EXPR or IMAGPART_EXPR, according to CODE, from ARG. */
1741debfc3dSmrg
1751debfc3dSmrg tree
build_real_imag_expr(location_t location,enum tree_code code,tree arg)1761debfc3dSmrg build_real_imag_expr (location_t location, enum tree_code code, tree arg)
1771debfc3dSmrg {
1781debfc3dSmrg tree ret;
1791debfc3dSmrg tree arg_type = TREE_TYPE (arg);
1801debfc3dSmrg
1811debfc3dSmrg gcc_assert (code == REALPART_EXPR || code == IMAGPART_EXPR);
1821debfc3dSmrg
1831debfc3dSmrg if (TREE_CODE (arg_type) == COMPLEX_TYPE)
1841debfc3dSmrg {
1851debfc3dSmrg ret = build1 (code, TREE_TYPE (TREE_TYPE (arg)), arg);
1861debfc3dSmrg SET_EXPR_LOCATION (ret, location);
1871debfc3dSmrg }
1881debfc3dSmrg else if (INTEGRAL_TYPE_P (arg_type) || SCALAR_FLOAT_TYPE_P (arg_type))
1891debfc3dSmrg {
1901debfc3dSmrg ret = (code == REALPART_EXPR
1911debfc3dSmrg ? arg
1921debfc3dSmrg : omit_one_operand_loc (location, arg_type,
1931debfc3dSmrg integer_zero_node, arg));
1941debfc3dSmrg }
1951debfc3dSmrg else
1961debfc3dSmrg {
1971debfc3dSmrg error_at (location, "wrong type argument to %s",
1981debfc3dSmrg code == REALPART_EXPR ? "__real" : "__imag");
1991debfc3dSmrg ret = error_mark_node;
2001debfc3dSmrg }
2011debfc3dSmrg
2021debfc3dSmrg return ret;
2031debfc3dSmrg }
204