1 /* Array and structure constructors
2 Copyright (C) 2009, 2010, 2011, 2012
3 Free Software Foundation, Inc.
5 This file is part of GCC.
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
9 Software Foundation; either version 3, or (at your option) any later
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
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
25 #include "constructor.h"
29 node_free (splay_tree_value value
)
31 gfc_constructor
*c
= (gfc_constructor
*)value
;
34 gfc_free_expr (c
->expr
);
37 gfc_free_iterator (c
->iterator
, 1);
39 mpz_clear (c
->offset
);
40 mpz_clear (c
->repeat
);
46 static gfc_constructor
*
47 node_copy (splay_tree_node node
, void *base
)
49 gfc_constructor
*c
, *src
= (gfc_constructor
*)node
->value
;
51 c
= XCNEW (gfc_constructor
);
52 c
->base
= (gfc_constructor_base
)base
;
53 c
->expr
= gfc_copy_expr (src
->expr
);
54 c
->iterator
= gfc_copy_iterator (src
->iterator
);
55 c
->where
= src
->where
;
56 c
->n
.component
= src
->n
.component
;
58 mpz_init_set (c
->offset
, src
->offset
);
59 mpz_init_set (c
->repeat
, src
->repeat
);
66 node_copy_and_insert (splay_tree_node node
, void *base
)
68 int n
= mpz_get_si (((gfc_constructor
*)node
->value
)->offset
);
69 gfc_constructor_insert ((gfc_constructor_base
*)base
,
70 node_copy (node
, base
), n
);
76 gfc_constructor_get (void)
78 gfc_constructor
*c
= XCNEW (gfc_constructor
);
83 mpz_init_set_si (c
->offset
, 0);
84 mpz_init_set_si (c
->repeat
, 1);
89 gfc_constructor_base
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_expr_foreach (gfc_constructor
*ctor ATTRIBUTE_UNUSED
,
215 int(*f
)(gfc_expr
*) ATTRIBUTE_UNUSED
)
222 gfc_constructor_swap (gfc_constructor
*ctor ATTRIBUTE_UNUSED
,
223 int n ATTRIBUTE_UNUSED
, int m ATTRIBUTE_UNUSED
)
231 gfc_constructor_first (gfc_constructor_base base
)
235 splay_tree_node node
= splay_tree_min (base
);
236 return node
? (gfc_constructor
*) node
->value
: NULL
;
244 gfc_constructor_next (gfc_constructor
*ctor
)
248 splay_tree_node node
= splay_tree_successor (ctor
->base
,
249 mpz_get_si (ctor
->offset
));
250 return node
? (gfc_constructor
*) node
->value
: NULL
;
258 gfc_constructor_remove (gfc_constructor
*ctor
)
261 splay_tree_remove (ctor
->base
, mpz_get_si (ctor
->offset
));
266 gfc_constructor_lookup_next (gfc_constructor_base base
, int offset
)
268 splay_tree_node node
;
273 node
= splay_tree_successor (base
, (splay_tree_key
) offset
);
277 return (gfc_constructor
*) node
->value
;