1 /* Array and structure constructors
2 Copyright (C) 2009-2017 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 gfc_constructor_base
gfc_constructor_get_base (void)
90 return splay_tree_new (splay_tree_compare_ints
, NULL
, node_free
);
95 gfc_constructor_copy (gfc_constructor_base base
)
97 gfc_constructor_base new_base
;
102 new_base
= gfc_constructor_get_base ();
103 splay_tree_foreach (base
, node_copy_and_insert
, &new_base
);
110 gfc_constructor_free (gfc_constructor_base base
)
113 splay_tree_delete (base
);
118 gfc_constructor_append (gfc_constructor_base
*base
, gfc_constructor
*c
)
122 offset
= (int)(splay_tree_max (*base
)->key
) + 1;
124 return gfc_constructor_insert (base
, c
, offset
);
129 gfc_constructor_append_expr (gfc_constructor_base
*base
,
130 gfc_expr
*e
, locus
*where
)
132 gfc_constructor
*c
= gfc_constructor_get ();
137 return gfc_constructor_append (base
, c
);
142 gfc_constructor_insert (gfc_constructor_base
*base
, gfc_constructor
*c
, int n
)
144 splay_tree_node node
;
147 *base
= splay_tree_new (splay_tree_compare_ints
, NULL
, node_free
);
150 mpz_set_si (c
->offset
, n
);
152 node
= splay_tree_insert (*base
, (splay_tree_key
) n
, (splay_tree_value
) c
);
155 return (gfc_constructor
*)node
->value
;
160 gfc_constructor_insert_expr (gfc_constructor_base
*base
,
161 gfc_expr
*e
, locus
*where
, int n
)
163 gfc_constructor
*c
= gfc_constructor_get ();
168 return gfc_constructor_insert (base
, c
, n
);
173 gfc_constructor_lookup (gfc_constructor_base base
, int offset
)
176 splay_tree_node node
;
181 node
= splay_tree_lookup (base
, (splay_tree_key
) offset
);
183 return (gfc_constructor
*) node
->value
;
185 /* Check if the previous node has a repeat count big enough to
186 cover the offset looked for. */
187 node
= splay_tree_predecessor (base
, (splay_tree_key
) offset
);
191 c
= (gfc_constructor
*) node
->value
;
192 if (mpz_cmp_si (c
->repeat
, 1) > 0)
194 if (mpz_get_si (c
->offset
) + mpz_get_si (c
->repeat
) <= offset
)
205 gfc_constructor_lookup_expr (gfc_constructor_base base
, int offset
)
207 gfc_constructor
*c
= gfc_constructor_lookup (base
, offset
);
208 return c
? c
->expr
: NULL
;
213 gfc_constructor_expr_foreach (gfc_constructor
*ctor ATTRIBUTE_UNUSED
,
214 int(*f
)(gfc_expr
*) ATTRIBUTE_UNUSED
)
221 gfc_constructor_swap (gfc_constructor
*ctor ATTRIBUTE_UNUSED
,
222 int n ATTRIBUTE_UNUSED
, int m ATTRIBUTE_UNUSED
)
230 gfc_constructor_first (gfc_constructor_base base
)
234 splay_tree_node node
= splay_tree_min (base
);
235 return node
? (gfc_constructor
*) node
->value
: NULL
;
243 gfc_constructor_next (gfc_constructor
*ctor
)
247 splay_tree_node node
= splay_tree_successor (ctor
->base
,
248 mpz_get_si (ctor
->offset
));
249 return node
? (gfc_constructor
*) node
->value
: NULL
;
257 gfc_constructor_remove (gfc_constructor
*ctor
)
260 splay_tree_remove (ctor
->base
, mpz_get_si (ctor
->offset
));
265 gfc_constructor_lookup_next (gfc_constructor_base base
, int offset
)
267 splay_tree_node node
;
272 node
= splay_tree_successor (base
, (splay_tree_key
) offset
);
276 return (gfc_constructor
*) node
->value
;