xref: /dflybsd-src/contrib/gcc-8.0/gcc/c-family/c-semantics.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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