]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/target-memory.c
Update copyright years in gcc/
[thirdparty/gcc.git] / gcc / fortran / target-memory.c
CommitLineData
7433458d 1/* Simulate storage of variables into target memory.
23a5b65a 2 Copyright (C) 2007-2014 Free Software Foundation, Inc.
7433458d
PT
3 Contributed by Paul Thomas and Brooks Moses
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
d234d788 9Software Foundation; either version 3, or (at your option) any later
7433458d
PT
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
d234d788
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
7433458d
PT
20
21#include "config.h"
22#include "system.h"
953bee7c 23#include "coretypes.h"
7433458d
PT
24#include "flags.h"
25#include "machmode.h"
26#include "tree.h"
d8a2d370 27#include "stor-layout.h"
7433458d
PT
28#include "gfortran.h"
29#include "arith.h"
b7e75771 30#include "constructor.h"
7433458d
PT
31#include "trans.h"
32#include "trans-const.h"
33#include "trans-types.h"
34#include "target-memory.h"
35
25812571 36/* --------------------------------------------------------------- */
7433458d
PT
37/* Calculate the size of an expression. */
38
7433458d
PT
39
40static size_t
41size_integer (int kind)
42{
43 return GET_MODE_SIZE (TYPE_MODE (gfc_get_int_type (kind)));;
44}
45
46
47static size_t
48size_float (int kind)
49{
50 return GET_MODE_SIZE (TYPE_MODE (gfc_get_real_type (kind)));;
51}
52
53
54static size_t
55size_complex (int kind)
56{
57 return 2 * size_float (kind);
58}
59
60
61static size_t
62size_logical (int kind)
63{
64 return GET_MODE_SIZE (TYPE_MODE (gfc_get_logical_type (kind)));;
65}
66
67
68static size_t
00660189 69size_character (int length, int kind)
7433458d 70{
d393bbd7
FXC
71 int i = gfc_validate_kind (BT_CHARACTER, kind, false);
72 return length * gfc_character_kinds[i].bit_size / 8;
7433458d
PT
73}
74
75
e361d18d
JW
76/* Return the size of a single element of the given expression.
77 Identical to gfc_target_expr_size for scalars. */
78
7433458d 79size_t
e361d18d 80gfc_element_size (gfc_expr *e)
7433458d
PT
81{
82 tree type;
83
7433458d
PT
84 switch (e->ts.type)
85 {
86 case BT_INTEGER:
87 return size_integer (e->ts.kind);
88 case BT_REAL:
89 return size_float (e->ts.kind);
90 case BT_COMPLEX:
91 return size_complex (e->ts.kind);
92 case BT_LOGICAL:
93 return size_logical (e->ts.kind);
94 case BT_CHARACTER:
86dbed7d
TK
95 if (e->expr_type == EXPR_CONSTANT)
96 return size_character (e->value.character.length, e->ts.kind);
97 else if (e->ts.u.cl != NULL && e->ts.u.cl->length != NULL
98 && e->ts.u.cl->length->expr_type == EXPR_CONSTANT
99 && e->ts.u.cl->length->ts.type == BT_INTEGER)
100 {
101 int length;
102
103 gfc_extract_int (e->ts.u.cl->length, &length);
104 return size_character (length, e->ts.kind);
105 }
b7d36ea3 106 else
86dbed7d
TK
107 return 0;
108
3b45d6c4
BM
109 case BT_HOLLERITH:
110 return e->representation.length;
7433458d 111 case BT_DERIVED:
fa1ed658 112 case BT_CLASS:
25812571
PT
113 case BT_VOID:
114 case BT_ASSUMED:
48b155b9
TK
115 {
116 /* Determine type size without clobbering the typespec for ISO C
117 binding types. */
118 gfc_typespec ts;
c6423ef3 119 HOST_WIDE_INT size;
48b155b9
TK
120 ts = e->ts;
121 type = gfc_typenode_for_spec (&ts);
c6423ef3
TB
122 size = int_size_in_bytes (type);
123 gcc_assert (size >= 0);
124 return size;
48b155b9 125 }
7433458d 126 default:
e361d18d 127 gfc_internal_error ("Invalid expression in gfc_element_size.");
7433458d
PT
128 return 0;
129 }
130}
131
132
e361d18d
JW
133/* Return the size of an expression in its target representation. */
134
135size_t
136gfc_target_expr_size (gfc_expr *e)
137{
138 mpz_t tmp;
139 size_t asz;
140
141 gcc_assert (e != NULL);
142
143 if (e->rank)
144 {
145 if (gfc_array_size (e, &tmp))
146 asz = mpz_get_ui (tmp);
147 else
148 asz = 0;
149 }
150 else
151 asz = 1;
152
153 return asz * gfc_element_size (e);
154}
155
156
25812571 157/* The encode_* functions export a value into a buffer, and
7433458d
PT
158 return the number of bytes of the buffer that have been
159 used. */
160
fd2805e1 161static unsigned HOST_WIDE_INT
7433458d
PT
162encode_array (gfc_expr *expr, unsigned char *buffer, size_t buffer_size)
163{
164 mpz_t array_size;
165 int i;
166 int ptr = 0;
167
b7e75771
JD
168 gfc_constructor_base ctor = expr->value.constructor;
169
7433458d
PT
170 gfc_array_size (expr, &array_size);
171 for (i = 0; i < (int)mpz_get_ui (array_size); i++)
172 {
b7e75771 173 ptr += gfc_target_encode_expr (gfc_constructor_lookup_expr (ctor, i),
7433458d
PT
174 &buffer[ptr], buffer_size - ptr);
175 }
176
177 mpz_clear (array_size);
178 return ptr;
179}
180
181
182static int
183encode_integer (int kind, mpz_t integer, unsigned char *buffer,
184 size_t buffer_size)
185{
186 return native_encode_expr (gfc_conv_mpz_to_tree (integer, kind),
187 buffer, buffer_size);
188}
189
190
191static int
192encode_float (int kind, mpfr_t real, unsigned char *buffer, size_t buffer_size)
193{
346a77d1 194 return native_encode_expr (gfc_conv_mpfr_to_tree (real, kind, 0), buffer,
7433458d
PT
195 buffer_size);
196}
197
198
199static int
d0d92baf 200encode_complex (int kind, mpc_t cmplx,
eb6f9a86 201 unsigned char *buffer, size_t buffer_size)
7433458d
PT
202{
203 int size;
d0d92baf
KG
204 size = encode_float (kind, mpc_realref (cmplx), &buffer[0], buffer_size);
205 size += encode_float (kind, mpc_imagref (cmplx),
eb6f9a86 206 &buffer[size], buffer_size - size);
7433458d
PT
207 return size;
208}
209
210
211static int
212encode_logical (int kind, int logical, unsigned char *buffer, size_t buffer_size)
213{
214 return native_encode_expr (build_int_cst (gfc_get_logical_type (kind),
215 logical),
216 buffer, buffer_size);
217}
218
219
d393bbd7
FXC
220int
221gfc_encode_character (int kind, int length, const gfc_char_t *string,
222 unsigned char *buffer, size_t buffer_size)
7433458d 223{
d393bbd7
FXC
224 size_t elsize = size_character (1, kind);
225 tree type = gfc_get_char_type (kind);
226 int i;
00660189
FXC
227
228 gcc_assert (buffer_size >= size_character (length, kind));
00660189 229
d393bbd7
FXC
230 for (i = 0; i < length; i++)
231 native_encode_expr (build_int_cst (type, string[i]), &buffer[i*elsize],
232 elsize);
00660189 233
7433458d
PT
234 return length;
235}
236
237
fd2805e1 238static unsigned HOST_WIDE_INT
7433458d
PT
239encode_derived (gfc_expr *source, unsigned char *buffer, size_t buffer_size)
240{
b7e75771 241 gfc_constructor *c;
7433458d
PT
242 gfc_component *cmp;
243 int ptr;
244 tree type;
fd2805e1 245 HOST_WIDE_INT size;
7433458d
PT
246
247 type = gfc_typenode_for_spec (&source->ts);
248
b7e75771
JD
249 for (c = gfc_constructor_first (source->value.constructor),
250 cmp = source->ts.u.derived->components;
251 c;
252 c = gfc_constructor_next (c), cmp = cmp->next)
7433458d 253 {
9d99ee7b 254 gcc_assert (cmp);
b7e75771 255 if (!c->expr)
9d99ee7b
PT
256 continue;
257 ptr = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(cmp->backend_decl))
258 + TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(cmp->backend_decl))/8;
51df93ba 259
b7e75771 260 if (c->expr->expr_type == EXPR_NULL)
fd2805e1
TB
261 {
262 size = int_size_in_bytes (TREE_TYPE (cmp->backend_decl));
263 gcc_assert (size >= 0);
264 memset (&buffer[ptr], 0, size);
265 }
51df93ba 266 else
b7e75771 267 gfc_target_encode_expr (c->expr, &buffer[ptr],
51df93ba 268 buffer_size - ptr);
7433458d
PT
269 }
270
fd2805e1
TB
271 size = int_size_in_bytes (type);
272 gcc_assert (size >= 0);
273 return size;
7433458d
PT
274}
275
276
277/* Write a constant expression in binary form to a buffer. */
fd2805e1 278unsigned HOST_WIDE_INT
7433458d
PT
279gfc_target_encode_expr (gfc_expr *source, unsigned char *buffer,
280 size_t buffer_size)
281{
282 if (source == NULL)
283 return 0;
284
285 if (source->expr_type == EXPR_ARRAY)
286 return encode_array (source, buffer, buffer_size);
287
288 gcc_assert (source->expr_type == EXPR_CONSTANT
b7d36ea3
FXC
289 || source->expr_type == EXPR_STRUCTURE
290 || source->expr_type == EXPR_SUBSTRING);
7433458d 291
25812571 292 /* If we already have a target-memory representation, we use that rather
20585ad6
BM
293 than recreating one. */
294 if (source->representation.string)
295 {
296 memcpy (buffer, source->representation.string,
297 source->representation.length);
298 return source->representation.length;
299 }
300
7433458d
PT
301 switch (source->ts.type)
302 {
303 case BT_INTEGER:
304 return encode_integer (source->ts.kind, source->value.integer, buffer,
305 buffer_size);
306 case BT_REAL:
307 return encode_float (source->ts.kind, source->value.real, buffer,
308 buffer_size);
309 case BT_COMPLEX:
d0d92baf 310 return encode_complex (source->ts.kind, source->value.complex,
eb6f9a86 311 buffer, buffer_size);
7433458d
PT
312 case BT_LOGICAL:
313 return encode_logical (source->ts.kind, source->value.logical, buffer,
314 buffer_size);
315 case BT_CHARACTER:
b7d36ea3 316 if (source->expr_type == EXPR_CONSTANT || source->ref == NULL)
d393bbd7
FXC
317 return gfc_encode_character (source->ts.kind,
318 source->value.character.length,
319 source->value.character.string,
320 buffer, buffer_size);
b7d36ea3
FXC
321 else
322 {
323 int start, end;
324
325 gcc_assert (source->expr_type == EXPR_SUBSTRING);
326 gfc_extract_int (source->ref->u.ss.start, &start);
327 gfc_extract_int (source->ref->u.ss.end, &end);
d393bbd7
FXC
328 return gfc_encode_character (source->ts.kind, MAX(end - start + 1, 0),
329 &source->value.character.string[start-1],
330 buffer, buffer_size);
b7d36ea3
FXC
331 }
332
7433458d 333 case BT_DERIVED:
cadddfdd
TB
334 if (source->ts.u.derived->ts.f90_type == BT_VOID)
335 {
336 gfc_constructor *c;
337 gcc_assert (source->expr_type == EXPR_STRUCTURE);
338 c = gfc_constructor_first (source->value.constructor);
339 gcc_assert (c->expr->expr_type == EXPR_CONSTANT
340 && c->expr->ts.type == BT_INTEGER);
341 return encode_integer (gfc_index_integer_kind, c->expr->value.integer,
342 buffer, buffer_size);
343 }
344
7433458d
PT
345 return encode_derived (source, buffer, buffer_size);
346 default:
347 gfc_internal_error ("Invalid expression in gfc_target_encode_expr.");
348 return 0;
349 }
350}
351
352
353static int
354interpret_array (unsigned char *buffer, size_t buffer_size, gfc_expr *result)
355{
b7e75771 356 gfc_constructor_base base = NULL;
7433458d
PT
357 int array_size = 1;
358 int i;
359 int ptr = 0;
7433458d
PT
360
361 /* Calculate array size from its shape and rank. */
362 gcc_assert (result->rank > 0 && result->shape);
363
364 for (i = 0; i < result->rank; i++)
365 array_size *= (int)mpz_get_ui (result->shape[i]);
366
367 /* Iterate over array elements, producing constructors. */
368 for (i = 0; i < array_size; i++)
369 {
b7e75771
JD
370 gfc_expr *e = gfc_get_constant_expr (result->ts.type, result->ts.kind,
371 &result->where);
372 e->ts = result->ts;
7433458d 373
b7e75771
JD
374 if (e->ts.type == BT_CHARACTER)
375 e->value.character.length = result->value.character.length;
7433458d 376
b7e75771 377 gfc_constructor_append_expr (&base, e, &result->where);
7433458d 378
86dbed7d
TK
379 ptr += gfc_target_interpret_expr (&buffer[ptr], buffer_size - ptr, e,
380 true);
7433458d 381 }
7433458d 382
b7e75771 383 result->value.constructor = base;
7433458d
PT
384 return ptr;
385}
386
387
20585ad6
BM
388int
389gfc_interpret_integer (int kind, unsigned char *buffer, size_t buffer_size,
7433458d
PT
390 mpz_t integer)
391{
392 mpz_init (integer);
393 gfc_conv_tree_to_mpz (integer,
394 native_interpret_expr (gfc_get_int_type (kind),
395 buffer, buffer_size));
396 return size_integer (kind);
397}
398
399
20585ad6
BM
400int
401gfc_interpret_float (int kind, unsigned char *buffer, size_t buffer_size,
ace428e3 402 mpfr_t real)
7433458d 403{
ace428e3 404 gfc_set_model_kind (kind);
7433458d
PT
405 mpfr_init (real);
406 gfc_conv_tree_to_mpfr (real,
407 native_interpret_expr (gfc_get_real_type (kind),
408 buffer, buffer_size));
409
410 return size_float (kind);
411}
412
413
20585ad6
BM
414int
415gfc_interpret_complex (int kind, unsigned char *buffer, size_t buffer_size,
d0d92baf 416 mpc_t complex)
7433458d
PT
417{
418 int size;
eb6f9a86 419 size = gfc_interpret_float (kind, &buffer[0], buffer_size,
d0d92baf 420 mpc_realref (complex));
b7d36ea3 421 size += gfc_interpret_float (kind, &buffer[size], buffer_size - size,
d0d92baf 422 mpc_imagref (complex));
7433458d
PT
423 return size;
424}
425
426
20585ad6
BM
427int
428gfc_interpret_logical (int kind, unsigned char *buffer, size_t buffer_size,
7433458d
PT
429 int *logical)
430{
431 tree t = native_interpret_expr (gfc_get_logical_type (kind), buffer,
432 buffer_size);
9be0ac8c 433 *logical = tree_to_double_int (t).is_zero () ? 0 : 1;
7433458d
PT
434 return size_logical (kind);
435}
436
437
20585ad6 438int
00660189
FXC
439gfc_interpret_character (unsigned char *buffer, size_t buffer_size,
440 gfc_expr *result)
7433458d 441{
00660189
FXC
442 int i;
443
bc21d315 444 if (result->ts.u.cl && result->ts.u.cl->length)
7433458d 445 result->value.character.length =
bc21d315 446 (int) mpz_get_ui (result->ts.u.cl->length->value.integer);
7433458d 447
00660189
FXC
448 gcc_assert (buffer_size >= size_character (result->value.character.length,
449 result->ts.kind));
7433458d 450 result->value.character.string =
00660189
FXC
451 gfc_get_wide_string (result->value.character.length + 1);
452
12ba225d
TB
453 if (result->ts.kind == gfc_default_character_kind)
454 for (i = 0; i < result->value.character.length; i++)
455 result->value.character.string[i] = (gfc_char_t) buffer[i];
456 else
457 {
458 mpz_t integer;
459 unsigned bytes = size_character (1, result->ts.kind);
460 mpz_init (integer);
461 gcc_assert (bytes <= sizeof (unsigned long));
462
463 for (i = 0; i < result->value.character.length; i++)
464 {
465 gfc_conv_tree_to_mpz (integer,
466 native_interpret_expr (gfc_get_char_type (result->ts.kind),
467 &buffer[bytes*i], buffer_size-bytes*i));
468 result->value.character.string[i]
469 = (gfc_char_t) mpz_get_ui (integer);
470 }
471
472 mpz_clear (integer);
473 }
474
00660189 475 result->value.character.string[result->value.character.length] = '\0';
7433458d
PT
476
477 return result->value.character.length;
478}
479
480
20585ad6
BM
481int
482gfc_interpret_derived (unsigned char *buffer, size_t buffer_size, gfc_expr *result)
7433458d
PT
483{
484 gfc_component *cmp;
7433458d
PT
485 int ptr;
486 tree type;
487
488 /* The attributes of the derived type need to be bolted to the floor. */
489 result->expr_type = EXPR_STRUCTURE;
490
bc21d315 491 cmp = result->ts.u.derived->components;
7433458d 492
b5dca6ea
TB
493 if (result->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
494 && (result->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
495 || result->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
496 {
497 gfc_constructor *c;
498 gfc_expr *e;
499 /* Needed as gfc_typenode_for_spec as gfc_typenode_for_spec
500 sets this to BT_INTEGER. */
501 result->ts.type = BT_DERIVED;
25812571 502 e = gfc_get_constant_expr (cmp->ts.type, cmp->ts.kind, &result->where);
b5dca6ea
TB
503 c = gfc_constructor_append_expr (&result->value.constructor, e, NULL);
504 c->n.component = cmp;
86dbed7d 505 gfc_target_interpret_expr (buffer, buffer_size, e, true);
b5dca6ea
TB
506 e->ts.is_iso_c = 1;
507 return int_size_in_bytes (ptr_type_node);
508 }
509
510 type = gfc_typenode_for_spec (&result->ts);
511
7433458d
PT
512 /* Run through the derived type components. */
513 for (;cmp; cmp = cmp->next)
514 {
b7e75771
JD
515 gfc_constructor *c;
516 gfc_expr *e = gfc_get_constant_expr (cmp->ts.type, cmp->ts.kind,
25812571 517 &result->where);
b7e75771 518 e->ts = cmp->ts;
7433458d
PT
519
520 /* Copy shape, if needed. */
521 if (cmp->as && cmp->as->rank)
522 {
523 int n;
524
b7e75771
JD
525 e->expr_type = EXPR_ARRAY;
526 e->rank = cmp->as->rank;
7433458d 527
b7e75771
JD
528 e->shape = gfc_get_shape (e->rank);
529 for (n = 0; n < e->rank; n++)
7433458d 530 {
b7e75771
JD
531 mpz_init_set_ui (e->shape[n], 1);
532 mpz_add (e->shape[n], e->shape[n],
7433458d 533 cmp->as->upper[n]->value.integer);
b7e75771 534 mpz_sub (e->shape[n], e->shape[n],
7433458d
PT
535 cmp->as->lower[n]->value.integer);
536 }
537 }
538
b7e75771 539 c = gfc_constructor_append_expr (&result->value.constructor, e, NULL);
7433458d 540
b7e75771
JD
541 /* The constructor points to the component. */
542 c->n.component = cmp;
543
dd5a833e 544 /* Calculate the offset, which consists of the FIELD_OFFSET in
6a227990
TB
545 bytes, which appears in multiples of DECL_OFFSET_ALIGN-bit-sized,
546 and additional bits of FIELD_BIT_OFFSET. The code assumes that all
547 sizes of the components are multiples of BITS_PER_UNIT,
548 i.e. there are, e.g., no bit fields. */
549
b5dca6ea 550 gcc_assert (cmp->backend_decl);
6a227990
TB
551 ptr = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (cmp->backend_decl));
552 gcc_assert (ptr % 8 == 0);
553 ptr = ptr/8 + TREE_INT_CST_LOW (DECL_FIELD_OFFSET (cmp->backend_decl));
554
86dbed7d 555 gfc_target_interpret_expr (&buffer[ptr], buffer_size - ptr, e, true);
7433458d 556 }
25812571 557
7433458d
PT
558 return int_size_in_bytes (type);
559}
560
561
562/* Read a binary buffer to a constant expression. */
563int
564gfc_target_interpret_expr (unsigned char *buffer, size_t buffer_size,
86dbed7d 565 gfc_expr *result, bool convert_widechar)
7433458d
PT
566{
567 if (result->expr_type == EXPR_ARRAY)
568 return interpret_array (buffer, buffer_size, result);
569
570 switch (result->ts.type)
571 {
572 case BT_INTEGER:
25812571 573 result->representation.length =
20585ad6
BM
574 gfc_interpret_integer (result->ts.kind, buffer, buffer_size,
575 result->value.integer);
576 break;
577
7433458d 578 case BT_REAL:
25812571 579 result->representation.length =
20585ad6
BM
580 gfc_interpret_float (result->ts.kind, buffer, buffer_size,
581 result->value.real);
582 break;
583
7433458d 584 case BT_COMPLEX:
25812571 585 result->representation.length =
20585ad6 586 gfc_interpret_complex (result->ts.kind, buffer, buffer_size,
d0d92baf 587 result->value.complex);
20585ad6
BM
588 break;
589
7433458d 590 case BT_LOGICAL:
25812571 591 result->representation.length =
20585ad6
BM
592 gfc_interpret_logical (result->ts.kind, buffer, buffer_size,
593 &result->value.logical);
594 break;
595
7433458d 596 case BT_CHARACTER:
25812571 597 result->representation.length =
20585ad6
BM
598 gfc_interpret_character (buffer, buffer_size, result);
599 break;
600
fa1ed658
JW
601 case BT_CLASS:
602 result->ts = CLASS_DATA (result)->ts;
603 /* Fall through. */
7433458d 604 case BT_DERIVED:
25812571 605 result->representation.length =
20585ad6 606 gfc_interpret_derived (buffer, buffer_size, result);
fd2805e1 607 gcc_assert (result->representation.length >= 0);
20585ad6
BM
608 break;
609
7433458d
PT
610 default:
611 gfc_internal_error ("Invalid expression in gfc_target_interpret_expr.");
20585ad6
BM
612 break;
613 }
614
86dbed7d 615 if (result->ts.type == BT_CHARACTER && convert_widechar)
00660189
FXC
616 result->representation.string
617 = gfc_widechar_to_char (result->value.character.string,
618 result->value.character.length);
20585ad6
BM
619 else
620 {
621 result->representation.string =
93acb62c 622 XCNEWVEC (char, result->representation.length + 1);
20585ad6
BM
623 memcpy (result->representation.string, buffer,
624 result->representation.length);
625 result->representation.string[result->representation.length] = '\0';
7433458d 626 }
20585ad6
BM
627
628 return result->representation.length;
7433458d 629}
9d99ee7b
PT
630
631
25812571 632/* --------------------------------------------------------------- */
9d99ee7b
PT
633/* Two functions used by trans-common.c to write overlapping
634 equivalence initializers to a buffer. This is added to the union
635 and the original initializers freed. */
636
637
638/* Writes the values of a constant expression to a char buffer. If another
639 unequal initializer has already been written to the buffer, this is an
640 error. */
641
642static size_t
643expr_to_char (gfc_expr *e, unsigned char *data, unsigned char *chk, size_t len)
644{
645 int i;
646 int ptr;
b7e75771 647 gfc_constructor *c;
9d99ee7b
PT
648 gfc_component *cmp;
649 unsigned char *buffer;
650
651 if (e == NULL)
652 return 0;
653
654 /* Take a derived type, one component at a time, using the offsets from the backend
655 declaration. */
656 if (e->ts.type == BT_DERIVED)
657 {
b7e75771
JD
658 for (c = gfc_constructor_first (e->value.constructor),
659 cmp = e->ts.u.derived->components;
660 c; c = gfc_constructor_next (c), cmp = cmp->next)
9d99ee7b
PT
661 {
662 gcc_assert (cmp && cmp->backend_decl);
b7e75771 663 if (!c->expr)
9d99ee7b
PT
664 continue;
665 ptr = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(cmp->backend_decl))
666 + TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(cmp->backend_decl))/8;
b7e75771 667 expr_to_char (c->expr, &data[ptr], &chk[ptr], len);
9d99ee7b
PT
668 }
669 return len;
670 }
671
672 /* Otherwise, use the target-memory machinery to write a bitwise image, appropriate
673 to the target, in a buffer and check off the initialized part of the buffer. */
674 len = gfc_target_expr_size (e);
675 buffer = (unsigned char*)alloca (len);
676 len = gfc_target_encode_expr (e, buffer, len);
677
678 for (i = 0; i < (int)len; i++)
679 {
680 if (chk[i] && (buffer[i] != data[i]))
681 {
682 gfc_error ("Overlapping unequal initializers in EQUIVALENCE "
683 "at %L", &e->where);
684 return 0;
685 }
686 chk[i] = 0xFF;
687 }
688
689 memcpy (data, buffer, len);
690 return len;
691}
692
693
694/* Writes the values from the equivalence initializers to a char* array
695 that will be written to the constructor to make the initializer for
696 the union declaration. */
697
698size_t
699gfc_merge_initializers (gfc_typespec ts, gfc_expr *e, unsigned char *data,
700 unsigned char *chk, size_t length)
701{
702 size_t len = 0;
703 gfc_constructor * c;
704
705 switch (e->expr_type)
706 {
707 case EXPR_CONSTANT:
708 case EXPR_STRUCTURE:
709 len = expr_to_char (e, &data[0], &chk[0], length);
710
711 break;
712
713 case EXPR_ARRAY:
b7e75771
JD
714 for (c = gfc_constructor_first (e->value.constructor);
715 c; c = gfc_constructor_next (c))
9d99ee7b
PT
716 {
717 size_t elt_size = gfc_target_expr_size (c->expr);
718
fd2805e1 719 if (mpz_cmp_si (c->offset, 0) != 0)
b7e75771 720 len = elt_size * (size_t)mpz_get_si (c->offset);
9d99ee7b
PT
721
722 len = len + gfc_merge_initializers (ts, c->expr, &data[len],
723 &chk[len], length - len);
724 }
725 break;
726
727 default:
728 return 0;
729 }
730
731 return len;
732}
00a4618b 733
c7abc45c
TB
734
735/* Transfer the bitpattern of a (integer) BOZ to real or complex variables.
736 When successful, no BOZ or nothing to do, true is returned. */
737
738bool
00a4618b
TB
739gfc_convert_boz (gfc_expr *expr, gfc_typespec *ts)
740{
c7abc45c
TB
741 size_t buffer_size, boz_bit_size, ts_bit_size;
742 int index;
00a4618b
TB
743 unsigned char *buffer;
744
745 if (!expr->is_boz)
c7abc45c 746 return true;
00a4618b
TB
747
748 gcc_assert (expr->expr_type == EXPR_CONSTANT
749 && expr->ts.type == BT_INTEGER);
750
751 /* Don't convert BOZ to logical, character, derived etc. */
752 if (ts->type == BT_REAL)
c7abc45c
TB
753 {
754 buffer_size = size_float (ts->kind);
755 ts_bit_size = buffer_size * 8;
756 }
00a4618b 757 else if (ts->type == BT_COMPLEX)
c7abc45c
TB
758 {
759 buffer_size = size_complex (ts->kind);
760 ts_bit_size = buffer_size * 8 / 2;
761 }
00a4618b 762 else
c7abc45c
TB
763 return true;
764
765 /* Convert BOZ to the smallest possible integer kind. */
766 boz_bit_size = mpz_sizeinbase (expr->value.integer, 2);
00a4618b 767
c7abc45c
TB
768 if (boz_bit_size > ts_bit_size)
769 {
770 gfc_error_now ("BOZ constant at %L is too large (%ld vs %ld bits)",
771 &expr->where, (long) boz_bit_size, (long) ts_bit_size);
772 return false;
773 }
774
775 for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
ace428e3
DK
776 if ((unsigned) gfc_integer_kinds[index].bit_size >= ts_bit_size)
777 break;
c7abc45c
TB
778
779 expr->ts.kind = gfc_integer_kinds[index].kind;
00a4618b
TB
780 buffer_size = MAX (buffer_size, size_integer (expr->ts.kind));
781
782 buffer = (unsigned char*)alloca (buffer_size);
783 encode_integer (expr->ts.kind, expr->value.integer, buffer, buffer_size);
784 mpz_clear (expr->value.integer);
785
786 if (ts->type == BT_REAL)
787 {
788 mpfr_init (expr->value.real);
789 gfc_interpret_float (ts->kind, buffer, buffer_size, expr->value.real);
790 }
791 else
792 {
eb6f9a86 793 mpc_init2 (expr->value.complex, mpfr_get_default_prec());
00a4618b 794 gfc_interpret_complex (ts->kind, buffer, buffer_size,
d0d92baf 795 expr->value.complex);
00a4618b 796 }
25812571 797 expr->is_boz = 0;
00a4618b
TB
798 expr->ts.type = ts->type;
799 expr->ts.kind = ts->kind;
c7abc45c
TB
800
801 return true;
00a4618b 802}