1 /* Array and structure constructors
2 Copyright (C) 2009-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
22 #include "coretypes.h"
24 #include "constructor.h"
28 node_free (splay_tree_value value
)
30 gfc_constructor
*c
= (gfc_constructor
*)value
;
33 gfc_free_expr (c
->expr
);
36 gfc_free_iterator (c
->iterator
, 1);
38 mpz_clear (c
->offset
);
39 mpz_clear (c
->repeat
);
45 static gfc_constructor
*
46 node_copy (splay_tree_node node
, void *base
)
48 gfc_constructor
*c
, *src
= (gfc_constructor
*)node
->value
;
50 c
= XCNEW (gfc_constructor
);
51 c
->base
= (gfc_constructor_base
)base
;
52 c
->expr
= gfc_copy_expr (src
->expr
);
53 c
->iterator
= gfc_copy_iterator (src
->iterator
);
54 c
->where
= src
->where
;
55 c
->n
.component
= src
->n
.component
;
57 mpz_init_set (c
->offset
, src
->offset
);
58 mpz_init_set (c
->repeat
, src
->repeat
);
65 node_copy_and_insert (splay_tree_node node
, void *base
)
67 int n
= mpz_get_si (((gfc_constructor
*)node
->value
)->offset
);
68 gfc_constructor_insert ((gfc_constructor_base
*)base
,
69 node_copy (node
, base
), n
);
75 gfc_constructor_get (void)
77 gfc_constructor
*c
= XCNEW (gfc_constructor
);
82 mpz_init_set_si (c
->offset
, 0);
83 mpz_init_set_si (c
->repeat
, 1);
88 static gfc_constructor_base
89 gfc_constructor_get_base (void)
91 return splay_tree_new (splay_tree_compare_ints
, NULL
, node_free
);
96 gfc_constructor_copy (gfc_constructor_base base
)
98 gfc_constructor_base new_base
;
103 new_base
= gfc_constructor_get_base ();
104 splay_tree_foreach (base
, node_copy_and_insert
, &new_base
);
111 gfc_constructor_free (gfc_constructor_base base
)
114 splay_tree_delete (base
);
119 gfc_constructor_append (gfc_constructor_base
*base
, gfc_constructor
*c
)
123 offset
= (int)(splay_tree_max (*base
)->key
) + 1;
125 return gfc_constructor_insert (base
, c
, offset
);
130 gfc_constructor_append_expr (gfc_constructor_base
*base
,
131 gfc_expr
*e
, locus
*where
)
133 gfc_constructor
*c
= gfc_constructor_get ();
138 return gfc_constructor_append (base
, c
);
143 gfc_constructor_insert (gfc_constructor_base
*base
, gfc_constructor
*c
, int n
)
145 splay_tree_node node
;
148 *base
= splay_tree_new (splay_tree_compare_ints
, NULL
, node_free
);
151 mpz_set_si (c
->offset
, n
);
153 node
= splay_tree_insert (*base
, (splay_tree_key
) n
, (splay_tree_value
) c
);
156 return (gfc_constructor
*)node
->value
;
161 gfc_constructor_insert_expr (gfc_constructor_base
*base
,
162 gfc_expr
*e
, locus
*where
, int n
)
164 gfc_constructor
*c
= gfc_constructor_get ();
169 return gfc_constructor_insert (base
, c
, n
);
174 gfc_constructor_lookup (gfc_constructor_base base
, int offset
)
177 splay_tree_node node
;
182 node
= splay_tree_lookup (base
, (splay_tree_key
) offset
);
184 return (gfc_constructor
*) node
->value
;
186 /* Check if the previous node has a repeat count big enough to
187 cover the offset looked for. */
188 node
= splay_tree_predecessor (base
, (splay_tree_key
) offset
);
192 c
= (gfc_constructor
*) node
->value
;
193 if (mpz_cmp_si (c
->repeat
, 1) > 0)
195 if (mpz_get_si (c
->offset
) + mpz_get_si (c
->repeat
) <= offset
)
206 gfc_constructor_lookup_expr (gfc_constructor_base base
, int offset
)
208 gfc_constructor
*c
= gfc_constructor_lookup (base
, offset
);
209 return c
? c
->expr
: NULL
;
214 gfc_constructor_first (gfc_constructor_base base
)
218 splay_tree_node node
= splay_tree_min (base
);
219 return node
? (gfc_constructor
*) node
->value
: NULL
;
227 gfc_constructor_next (gfc_constructor
*ctor
)
231 splay_tree_node node
= splay_tree_successor (ctor
->base
,
232 mpz_get_si (ctor
->offset
));
233 return node
? (gfc_constructor
*) node
->value
: NULL
;
241 gfc_constructor_remove (gfc_constructor
*ctor
)
244 splay_tree_remove (ctor
->base
, mpz_get_si (ctor
->offset
));
249 gfc_constructor_lookup_next (gfc_constructor_base base
, int offset
)
251 splay_tree_node node
;
256 node
= splay_tree_successor (base
, (splay_tree_key
) offset
);
260 return (gfc_constructor
*) node
->value
;