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