OSDN Git Service

gcc/fortran/:
[pf3gnuchains/gcc-fork.git] / gcc / fortran / constructor.c
1 /* Array and structure constructors
2    Copyright (C) 2009, 2010
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
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
10 version.
11
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
15 for more details.
16
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/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "gfortran.h"
24 #include "constructor.h"
25
26
27 static void
28 node_free (splay_tree_value value)
29 {
30   gfc_constructor *c = (gfc_constructor*)value;
31
32   if (c->expr)
33     gfc_free_expr (c->expr);
34
35   if (c->iterator)
36     gfc_free_iterator (c->iterator, 1);
37
38   mpz_clear (c->offset);
39
40   gfc_free (c);
41 }
42
43
44 static gfc_constructor *
45 node_copy (splay_tree_node node, void *base)
46 {
47   gfc_constructor *c, *src = (gfc_constructor*)node->value;
48
49   c = XCNEW (gfc_constructor);
50   c->base = (gfc_constructor_base)base;
51   c->expr = gfc_copy_expr (src->expr);
52   c->iterator = gfc_copy_iterator (src->iterator);
53   c->where = src->where;
54   c->n.component = src->n.component;
55
56   mpz_init_set (c->offset, src->offset);
57
58   return c;
59 }
60
61
62 static int
63 node_copy_and_insert (splay_tree_node node, void *base)
64 {
65   int n = mpz_get_si (((gfc_constructor*)node->value)->offset);
66   gfc_constructor_insert ((gfc_constructor_base*)base,
67                           node_copy (node, base), n);
68   return 0;
69 }
70
71
72 gfc_constructor *
73 gfc_constructor_get (void)
74 {
75   gfc_constructor *c = XCNEW (gfc_constructor);
76   c->base = NULL;
77   c->expr = NULL;
78   c->iterator = NULL;
79
80   mpz_init_set_si (c->offset, 0);
81
82   return c;
83 }
84
85 gfc_constructor_base gfc_constructor_get_base (void)
86 {
87   return splay_tree_new (splay_tree_compare_ints, NULL, node_free);
88 }
89
90
91 gfc_constructor_base
92 gfc_constructor_copy (gfc_constructor_base base)
93 {
94   gfc_constructor_base new_base;
95
96   if (!base)
97     return NULL;
98
99   new_base = gfc_constructor_get_base ();
100   splay_tree_foreach (base, node_copy_and_insert, &new_base);
101
102   return new_base;
103 }
104
105
106 void
107 gfc_constructor_free (gfc_constructor_base base)
108 {
109   if (base)
110     splay_tree_delete (base);
111 }
112
113
114 gfc_constructor *
115 gfc_constructor_append (gfc_constructor_base *base, gfc_constructor *c)
116 {
117   int offset = 0;
118   if (*base)
119     offset = (int)(splay_tree_max (*base)->key) + 1;
120
121   return gfc_constructor_insert (base, c, offset);
122 }
123
124
125 gfc_constructor *
126 gfc_constructor_append_expr (gfc_constructor_base *base,
127                              gfc_expr *e, locus *where)
128 {
129   gfc_constructor *c = gfc_constructor_get ();
130   c->expr = e;
131   if (where)
132     c->where = *where;
133
134   return gfc_constructor_append (base, c);
135 }
136
137
138 gfc_constructor *
139 gfc_constructor_insert (gfc_constructor_base *base, gfc_constructor *c, int n)
140 {
141   splay_tree_node node;
142
143   if (*base == NULL)
144     *base = splay_tree_new (splay_tree_compare_ints, NULL, node_free);
145
146   c->base = *base;
147   mpz_set_si (c->offset, n);
148
149   node = splay_tree_insert (*base, (splay_tree_key) n, (splay_tree_value) c);
150   gcc_assert (node);
151
152   return (gfc_constructor*)node->value;
153 }
154
155
156 gfc_constructor *
157 gfc_constructor_insert_expr (gfc_constructor_base *base,
158                              gfc_expr *e, locus *where, int n)
159 {
160   gfc_constructor *c = gfc_constructor_get ();
161   c->expr = e;
162   if (where)
163     c->where = *where;
164
165   return gfc_constructor_insert (base, c, n);
166 }
167
168
169 gfc_constructor *
170 gfc_constructor_lookup (gfc_constructor_base base, int offset)
171 {
172   splay_tree_node node;
173
174   if (!base)
175     return NULL;
176
177   node = splay_tree_lookup (base, (splay_tree_key) offset);
178   if (node)
179     return (gfc_constructor*) node->value;
180
181   return NULL;
182 }
183
184
185 gfc_expr *
186 gfc_constructor_lookup_expr (gfc_constructor_base base, int offset)
187 {
188   gfc_constructor *c = gfc_constructor_lookup (base, offset);
189   return c ? c->expr : NULL;
190 }
191
192
193 int
194 gfc_constructor_expr_foreach (gfc_constructor *ctor ATTRIBUTE_UNUSED,
195                               int(*f)(gfc_expr *) ATTRIBUTE_UNUSED)
196 {
197   gcc_assert (0);
198   return 0;
199 }
200
201 void
202 gfc_constructor_swap (gfc_constructor *ctor ATTRIBUTE_UNUSED,
203                       int n ATTRIBUTE_UNUSED, int m ATTRIBUTE_UNUSED)
204 {
205   gcc_assert (0);
206 }
207
208
209
210 gfc_constructor *
211 gfc_constructor_first (gfc_constructor_base base)
212 {
213   if (base)
214     {
215       splay_tree_node node = splay_tree_min (base);
216       return node ? (gfc_constructor*) node->value : NULL;
217     }
218   else
219     return NULL;
220 }
221
222
223 gfc_constructor *
224 gfc_constructor_next (gfc_constructor *ctor)
225 {
226   if (ctor)
227     {
228       splay_tree_node node = splay_tree_successor (ctor->base,
229                                                    mpz_get_si (ctor->offset));
230       return node ? (gfc_constructor*) node->value : NULL;
231     }
232   else
233     return NULL;
234 }