annotate gcc/fortran/constructor.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Array and structure constructors
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2009-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 This file is part of GCC.
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
9 version.
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
14 for more details.
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 #include "config.h"
kono
parents:
diff changeset
21 #include "system.h"
kono
parents:
diff changeset
22 #include "coretypes.h"
kono
parents:
diff changeset
23 #include "gfortran.h"
kono
parents:
diff changeset
24 #include "constructor.h"
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26
kono
parents:
diff changeset
27 static void
kono
parents:
diff changeset
28 node_free (splay_tree_value value)
kono
parents:
diff changeset
29 {
kono
parents:
diff changeset
30 gfc_constructor *c = (gfc_constructor*)value;
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 if (c->expr)
kono
parents:
diff changeset
33 gfc_free_expr (c->expr);
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 if (c->iterator)
kono
parents:
diff changeset
36 gfc_free_iterator (c->iterator, 1);
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 mpz_clear (c->offset);
kono
parents:
diff changeset
39 mpz_clear (c->repeat);
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 free (c);
kono
parents:
diff changeset
42 }
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 static gfc_constructor *
kono
parents:
diff changeset
46 node_copy (splay_tree_node node, void *base)
kono
parents:
diff changeset
47 {
kono
parents:
diff changeset
48 gfc_constructor *c, *src = (gfc_constructor*)node->value;
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 c = XCNEW (gfc_constructor);
kono
parents:
diff changeset
51 c->base = (gfc_constructor_base)base;
kono
parents:
diff changeset
52 c->expr = gfc_copy_expr (src->expr);
kono
parents:
diff changeset
53 c->iterator = gfc_copy_iterator (src->iterator);
kono
parents:
diff changeset
54 c->where = src->where;
kono
parents:
diff changeset
55 c->n.component = src->n.component;
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 mpz_init_set (c->offset, src->offset);
kono
parents:
diff changeset
58 mpz_init_set (c->repeat, src->repeat);
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 return c;
kono
parents:
diff changeset
61 }
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 static int
kono
parents:
diff changeset
65 node_copy_and_insert (splay_tree_node node, void *base)
kono
parents:
diff changeset
66 {
kono
parents:
diff changeset
67 int n = mpz_get_si (((gfc_constructor*)node->value)->offset);
kono
parents:
diff changeset
68 gfc_constructor_insert ((gfc_constructor_base*)base,
kono
parents:
diff changeset
69 node_copy (node, base), n);
kono
parents:
diff changeset
70 return 0;
kono
parents:
diff changeset
71 }
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 gfc_constructor *
kono
parents:
diff changeset
75 gfc_constructor_get (void)
kono
parents:
diff changeset
76 {
kono
parents:
diff changeset
77 gfc_constructor *c = XCNEW (gfc_constructor);
kono
parents:
diff changeset
78 c->base = NULL;
kono
parents:
diff changeset
79 c->expr = NULL;
kono
parents:
diff changeset
80 c->iterator = NULL;
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 mpz_init_set_si (c->offset, 0);
kono
parents:
diff changeset
83 mpz_init_set_si (c->repeat, 1);
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 return c;
kono
parents:
diff changeset
86 }
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 gfc_constructor_base gfc_constructor_get_base (void)
kono
parents:
diff changeset
89 {
kono
parents:
diff changeset
90 return splay_tree_new (splay_tree_compare_ints, NULL, node_free);
kono
parents:
diff changeset
91 }
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 gfc_constructor_base
kono
parents:
diff changeset
95 gfc_constructor_copy (gfc_constructor_base base)
kono
parents:
diff changeset
96 {
kono
parents:
diff changeset
97 gfc_constructor_base new_base;
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 if (!base)
kono
parents:
diff changeset
100 return NULL;
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 new_base = gfc_constructor_get_base ();
kono
parents:
diff changeset
103 splay_tree_foreach (base, node_copy_and_insert, &new_base);
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 return new_base;
kono
parents:
diff changeset
106 }
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 void
kono
parents:
diff changeset
110 gfc_constructor_free (gfc_constructor_base base)
kono
parents:
diff changeset
111 {
kono
parents:
diff changeset
112 if (base)
kono
parents:
diff changeset
113 splay_tree_delete (base);
kono
parents:
diff changeset
114 }
kono
parents:
diff changeset
115
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 gfc_constructor *
kono
parents:
diff changeset
118 gfc_constructor_append (gfc_constructor_base *base, gfc_constructor *c)
kono
parents:
diff changeset
119 {
kono
parents:
diff changeset
120 int offset = 0;
kono
parents:
diff changeset
121 if (*base)
kono
parents:
diff changeset
122 offset = (int)(splay_tree_max (*base)->key) + 1;
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 return gfc_constructor_insert (base, c, offset);
kono
parents:
diff changeset
125 }
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 gfc_constructor *
kono
parents:
diff changeset
129 gfc_constructor_append_expr (gfc_constructor_base *base,
kono
parents:
diff changeset
130 gfc_expr *e, locus *where)
kono
parents:
diff changeset
131 {
kono
parents:
diff changeset
132 gfc_constructor *c = gfc_constructor_get ();
kono
parents:
diff changeset
133 c->expr = e;
kono
parents:
diff changeset
134 if (where)
kono
parents:
diff changeset
135 c->where = *where;
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 return gfc_constructor_append (base, c);
kono
parents:
diff changeset
138 }
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 gfc_constructor *
kono
parents:
diff changeset
142 gfc_constructor_insert (gfc_constructor_base *base, gfc_constructor *c, int n)
kono
parents:
diff changeset
143 {
kono
parents:
diff changeset
144 splay_tree_node node;
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 if (*base == NULL)
kono
parents:
diff changeset
147 *base = splay_tree_new (splay_tree_compare_ints, NULL, node_free);
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 c->base = *base;
kono
parents:
diff changeset
150 mpz_set_si (c->offset, n);
kono
parents:
diff changeset
151
kono
parents:
diff changeset
152 node = splay_tree_insert (*base, (splay_tree_key) n, (splay_tree_value) c);
kono
parents:
diff changeset
153 gcc_assert (node);
kono
parents:
diff changeset
154
kono
parents:
diff changeset
155 return (gfc_constructor*)node->value;
kono
parents:
diff changeset
156 }
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 gfc_constructor *
kono
parents:
diff changeset
160 gfc_constructor_insert_expr (gfc_constructor_base *base,
kono
parents:
diff changeset
161 gfc_expr *e, locus *where, int n)
kono
parents:
diff changeset
162 {
kono
parents:
diff changeset
163 gfc_constructor *c = gfc_constructor_get ();
kono
parents:
diff changeset
164 c->expr = e;
kono
parents:
diff changeset
165 if (where)
kono
parents:
diff changeset
166 c->where = *where;
kono
parents:
diff changeset
167
kono
parents:
diff changeset
168 return gfc_constructor_insert (base, c, n);
kono
parents:
diff changeset
169 }
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 gfc_constructor *
kono
parents:
diff changeset
173 gfc_constructor_lookup (gfc_constructor_base base, int offset)
kono
parents:
diff changeset
174 {
kono
parents:
diff changeset
175 gfc_constructor *c;
kono
parents:
diff changeset
176 splay_tree_node node;
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 if (!base)
kono
parents:
diff changeset
179 return NULL;
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 node = splay_tree_lookup (base, (splay_tree_key) offset);
kono
parents:
diff changeset
182 if (node)
kono
parents:
diff changeset
183 return (gfc_constructor *) node->value;
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 /* Check if the previous node has a repeat count big enough to
kono
parents:
diff changeset
186 cover the offset looked for. */
kono
parents:
diff changeset
187 node = splay_tree_predecessor (base, (splay_tree_key) offset);
kono
parents:
diff changeset
188 if (!node)
kono
parents:
diff changeset
189 return NULL;
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 c = (gfc_constructor *) node->value;
kono
parents:
diff changeset
192 if (mpz_cmp_si (c->repeat, 1) > 0)
kono
parents:
diff changeset
193 {
kono
parents:
diff changeset
194 if (mpz_get_si (c->offset) + mpz_get_si (c->repeat) <= offset)
kono
parents:
diff changeset
195 c = NULL;
kono
parents:
diff changeset
196 }
kono
parents:
diff changeset
197 else
kono
parents:
diff changeset
198 c = NULL;
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 return c;
kono
parents:
diff changeset
201 }
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 gfc_expr *
kono
parents:
diff changeset
205 gfc_constructor_lookup_expr (gfc_constructor_base base, int offset)
kono
parents:
diff changeset
206 {
kono
parents:
diff changeset
207 gfc_constructor *c = gfc_constructor_lookup (base, offset);
kono
parents:
diff changeset
208 return c ? c->expr : NULL;
kono
parents:
diff changeset
209 }
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 int
kono
parents:
diff changeset
213 gfc_constructor_expr_foreach (gfc_constructor *ctor ATTRIBUTE_UNUSED,
kono
parents:
diff changeset
214 int(*f)(gfc_expr *) ATTRIBUTE_UNUSED)
kono
parents:
diff changeset
215 {
kono
parents:
diff changeset
216 gcc_assert (0);
kono
parents:
diff changeset
217 return 0;
kono
parents:
diff changeset
218 }
kono
parents:
diff changeset
219
kono
parents:
diff changeset
220 void
kono
parents:
diff changeset
221 gfc_constructor_swap (gfc_constructor *ctor ATTRIBUTE_UNUSED,
kono
parents:
diff changeset
222 int n ATTRIBUTE_UNUSED, int m ATTRIBUTE_UNUSED)
kono
parents:
diff changeset
223 {
kono
parents:
diff changeset
224 gcc_assert (0);
kono
parents:
diff changeset
225 }
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 gfc_constructor *
kono
parents:
diff changeset
230 gfc_constructor_first (gfc_constructor_base base)
kono
parents:
diff changeset
231 {
kono
parents:
diff changeset
232 if (base)
kono
parents:
diff changeset
233 {
kono
parents:
diff changeset
234 splay_tree_node node = splay_tree_min (base);
kono
parents:
diff changeset
235 return node ? (gfc_constructor*) node->value : NULL;
kono
parents:
diff changeset
236 }
kono
parents:
diff changeset
237 else
kono
parents:
diff changeset
238 return NULL;
kono
parents:
diff changeset
239 }
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241
kono
parents:
diff changeset
242 gfc_constructor *
kono
parents:
diff changeset
243 gfc_constructor_next (gfc_constructor *ctor)
kono
parents:
diff changeset
244 {
kono
parents:
diff changeset
245 if (ctor)
kono
parents:
diff changeset
246 {
kono
parents:
diff changeset
247 splay_tree_node node = splay_tree_successor (ctor->base,
kono
parents:
diff changeset
248 mpz_get_si (ctor->offset));
kono
parents:
diff changeset
249 return node ? (gfc_constructor*) node->value : NULL;
kono
parents:
diff changeset
250 }
kono
parents:
diff changeset
251 else
kono
parents:
diff changeset
252 return NULL;
kono
parents:
diff changeset
253 }
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 void
kono
parents:
diff changeset
257 gfc_constructor_remove (gfc_constructor *ctor)
kono
parents:
diff changeset
258 {
kono
parents:
diff changeset
259 if (ctor)
kono
parents:
diff changeset
260 splay_tree_remove (ctor->base, mpz_get_si (ctor->offset));
kono
parents:
diff changeset
261 }
kono
parents:
diff changeset
262
kono
parents:
diff changeset
263
kono
parents:
diff changeset
264 gfc_constructor *
kono
parents:
diff changeset
265 gfc_constructor_lookup_next (gfc_constructor_base base, int offset)
kono
parents:
diff changeset
266 {
kono
parents:
diff changeset
267 splay_tree_node node;
kono
parents:
diff changeset
268
kono
parents:
diff changeset
269 if (!base)
kono
parents:
diff changeset
270 return NULL;
kono
parents:
diff changeset
271
kono
parents:
diff changeset
272 node = splay_tree_successor (base, (splay_tree_key) offset);
kono
parents:
diff changeset
273 if (!node)
kono
parents:
diff changeset
274 return NULL;
kono
parents:
diff changeset
275
kono
parents:
diff changeset
276 return (gfc_constructor *) node->value;
kono
parents:
diff changeset
277 }