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