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