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