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