1 /* pkl-trans.c - Transformation phases for the poke compiler. */
2
3 /* Copyright (C) 2019, 2020, 2021 Jose E. Marchesi */
4
5 /* This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <config.h>
20
21 #include <gettext.h>
22 #define _(str) gettext (str)
23 #include <ctype.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <xalloc.h>
27 #include <stdlib.h>
28
29 #include "pk-utils.h"
30
31 #include "pkl.h"
32 #include "pkl-diag.h"
33 #include "pkl-ast.h"
34 #include "pkl-pass.h"
35 #include "pkl-trans.h"
36
37 /* This file implements several transformation compiler phases which,
38 generally speaking, are restartable.
39
40 `transl' makes adjustments to the compile-time lexical environment,
41 after parsing. This phase should run on its own pass, and
42 is not restartable.
43
44 `trans1' finishes ARRAY, STRUCT and TYPE_STRUCT nodes by
45 determining its number of elements and characteristics.
46 It also finishes OFFSET nodes by replacing certain unit
47 identifiers with factors and completes/annotates other
48 structures. It also finishes STRING nodes.
49
50 `trans2' scans the AST and annotates nodes that are literals.
51 Henceforth any other phase relying on this information
52 should be executed after trans2.
53
54 `trans3' handles nodes that can be replaced for something else at
55 compilation-time: SIZEOF for complete types. This phase
56 is intended to be executed short before code generation.
57
58 `trans4' is executed just before the code generation pass.
59
60 See the handlers below for details. */
61
62
63 #define PKL_TRANS_PAYLOAD ((pkl_trans_payload) PKL_PASS_PAYLOAD)
64
pkl_trans_in_functions(pkl_ast_node functions[],int next_function,pkl_ast_node function)65 static int pkl_trans_in_functions (pkl_ast_node functions[],
66 int next_function,
67 pkl_ast_node function)
68 {
69 int i;
70 for (i = 0; i < next_function; i++)
71 {
72 if (functions[i] == function)
73 return 1;
74 }
75
76 return 0;
77 }
78
79 #define PKL_TRANS_FUNCTION_IS_RECURSIVE(function) \
80 pkl_trans_in_functions (PKL_TRANS_PAYLOAD->functions, \
81 PKL_TRANS_PAYLOAD->next_function, \
82 (function))
83
84 #define PKL_TRANS_FUNCTION \
85 (PKL_TRANS_PAYLOAD->next_function == 0 \
86 ? NULL \
87 : PKL_TRANS_PAYLOAD->functions[PKL_TRANS_PAYLOAD->next_function - 1])
88
89 #define PKL_TRANS_FUNCTION_BACK \
90 (PKL_TRANS_PAYLOAD->next_function == 0 \
91 ? 0 \
92 : PKL_TRANS_PAYLOAD->function_back[PKL_TRANS_PAYLOAD->next_function - 1])
93
94 #define PKL_TRANS_INCR_FUNCTION_BACK \
95 do \
96 { \
97 if (PKL_TRANS_PAYLOAD->next_function > 0) \
98 PKL_TRANS_PAYLOAD->function_back[PKL_TRANS_PAYLOAD->next_function - 1]++; \
99 } \
100 while (0)
101
102 #define PKL_TRANS_DECR_FUNCTION_BACK \
103 do \
104 { \
105 if (PKL_TRANS_PAYLOAD->next_function > 0) \
106 PKL_TRANS_PAYLOAD->function_back[PKL_TRANS_PAYLOAD->next_function - 1]--; \
107 } \
108 while (0)
109
110 #define PKL_TRANS_PUSH_FUNCTION(function) \
111 do \
112 { \
113 assert (PKL_TRANS_PAYLOAD->next_function < PKL_TRANS_MAX_FUNCTION_NEST); \
114 PKL_TRANS_PAYLOAD->function_back[PKL_TRANS_PAYLOAD->next_function] \
115 = 0; \
116 PKL_TRANS_PAYLOAD->functions[PKL_TRANS_PAYLOAD->next_function++] \
117 = (function); \
118 } \
119 while (0)
120
121 #define PKL_TRANS_POP_FUNCTION \
122 do \
123 { \
124 assert (PKL_TRANS_PAYLOAD->next_function > 0); \
125 PKL_TRANS_PAYLOAD->next_function -= 1; \
126 } \
127 while (0)
128
129 /* The following handler is used in all trans phases and initializes
130 the phase payload. */
131
PKL_PHASE_BEGIN_HANDLER(pkl_trans_pr_program)132 PKL_PHASE_BEGIN_HANDLER (pkl_trans_pr_program)
133 {
134 PKL_TRANS_PAYLOAD->errors = 0;
135 PKL_TRANS_PAYLOAD->add_frames = -1;
136 }
137 PKL_PHASE_END_HANDLER
138
139 /* The following handler is used in all trans phases, and handles
140 changing the source file for diagnostics. */
141
PKL_PHASE_BEGIN_HANDLER(pkl_trans_ps_src)142 PKL_PHASE_BEGIN_HANDLER (pkl_trans_ps_src)
143 {
144 pkl_ast_node src = PKL_PASS_NODE;
145 char *filename = PKL_AST_SRC_FILENAME (src);
146
147 free (PKL_PASS_AST->filename);
148 PKL_PASS_AST->filename = filename ? strdup (filename) : NULL;
149 }
150 PKL_PHASE_END_HANDLER
151
152
153
154 /* Compute and set the number of elements in a STRUCT node. */
155
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_struct)156 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_struct)
157 {
158 pkl_ast_node astruct = PKL_PASS_NODE;
159 pkl_ast_node t;
160 size_t nelem = 0;
161
162 for (t = PKL_AST_STRUCT_FIELDS (astruct); t; t = PKL_AST_CHAIN (t))
163 nelem++;
164
165 PKL_AST_STRUCT_NELEM (astruct) = nelem;
166 }
167 PKL_PHASE_END_HANDLER
168
169 /* Compute and set the number of elements, fields and declarations in
170 a struct TYPE node. */
171
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_type_struct)172 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_type_struct)
173 {
174 pkl_ast_node struct_type = PKL_PASS_NODE;
175 pkl_ast_node t;
176 size_t nelem = 0, nfield = 0, ndecl = 0;
177
178 for (t = PKL_AST_TYPE_S_ELEMS (struct_type); t;
179 t = PKL_AST_CHAIN (t))
180 {
181 nelem++;
182 if (PKL_AST_CODE (t) == PKL_AST_STRUCT_TYPE_FIELD)
183 nfield++;
184 else
185 ndecl++;
186 }
187
188 PKL_AST_TYPE_S_NELEM (struct_type) = nelem;
189 PKL_AST_TYPE_S_NFIELD (struct_type) = nfield;
190 PKL_AST_TYPE_S_NDECL (struct_type) = ndecl;
191 }
192 PKL_PHASE_END_HANDLER
193
194 /* If the magnitude of an offset is not specified then it defaults to
195 1. */
196
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_offset)197 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_offset)
198 {
199 pkl_ast_node offset = PKL_PASS_NODE;
200
201 if (PKL_AST_OFFSET_MAGNITUDE (offset) == NULL)
202 {
203 pkl_ast_node magnitude_type
204 = pkl_ast_make_integral_type (PKL_PASS_AST, 32, 1);
205 pkl_ast_node magnitude
206 = pkl_ast_make_integer (PKL_PASS_AST, 1);
207
208 PKL_AST_LOC (magnitude_type) = PKL_AST_LOC (offset);
209 PKL_AST_LOC (magnitude) = PKL_AST_LOC (offset);
210 PKL_AST_TYPE (magnitude) = ASTREF (magnitude_type);
211
212 PKL_AST_OFFSET_MAGNITUDE (offset) = ASTREF (magnitude);
213 }
214 }
215 PKL_PHASE_END_HANDLER
216
217 /* Calculate the number of arguments in funcalls. */
218
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_funcall)219 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_funcall)
220 {
221 pkl_ast_node arg;
222 int nargs = 0;
223
224 for (arg = PKL_AST_FUNCALL_ARGS (PKL_PASS_NODE);
225 arg;
226 arg = PKL_AST_CHAIN (arg))
227 nargs++;
228
229 PKL_AST_FUNCALL_NARG (PKL_PASS_NODE) = nargs;
230 }
231 PKL_PHASE_END_HANDLER
232
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_pr_decl)233 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_pr_decl)
234 {
235 pkl_ast_node decl = PKL_PASS_NODE;
236
237 if (PKL_PASS_PARENT
238 && PKL_AST_CODE (PKL_PASS_PARENT) == PKL_AST_TYPE
239 && PKL_AST_TYPE_CODE (PKL_PASS_PARENT) == PKL_TYPE_STRUCT)
240 /* Annotate this declaration to be in a struct type. */
241 PKL_AST_DECL_IN_STRUCT_P (decl) = 1;
242
243 if (PKL_AST_DECL_KIND (decl) == PKL_AST_DECL_KIND_FUNC)
244 {
245 pkl_ast_node func = PKL_AST_DECL_INITIAL (decl);
246
247 /* Add this function to the pass stack of functions. */
248 PKL_TRANS_PUSH_FUNCTION (func);
249 }
250 }
251 PKL_PHASE_END_HANDLER
252
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_decl)253 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_decl)
254 {
255 pkl_ast_node decl = PKL_PASS_NODE;
256
257 if (PKL_AST_DECL_KIND (decl) == PKL_AST_DECL_KIND_FUNC)
258 PKL_TRANS_POP_FUNCTION;
259 }
260 PKL_PHASE_END_HANDLER
261
262 /* Variables that refer to the current function (recursive calls)
263 should be marked as such, so `pkl_ast_node_free' knows to not free
264 the declaration. This is to avoid loops in the AST reference
265 counting.
266
267 Variables are annotated with the enclosing function, and with their
268 lexical nesting level with respect the beginning of the enclosing
269 function.
270
271 Variables that refer to parameterless functions are transformed
272 into funcalls to these functions, but only if the variables are not
273 part of funcall themselves! :) */
274
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_var)275 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_var)
276 {
277 pkl_ast_node var = PKL_PASS_NODE;
278 pkl_ast_node decl = PKL_AST_VAR_DECL (var);
279
280 PKL_AST_VAR_FUNCTION (var) = PKL_TRANS_FUNCTION;
281 PKL_AST_VAR_FUNCTION_BACK (var) = PKL_TRANS_FUNCTION_BACK;
282
283 if (PKL_AST_DECL_KIND (decl) == PKL_AST_DECL_KIND_FUNC)
284 PKL_AST_VAR_IS_RECURSIVE (var)
285 = PKL_TRANS_FUNCTION_IS_RECURSIVE (PKL_AST_DECL_INITIAL (decl));
286
287 if (PKL_PASS_PARENT
288 && PKL_AST_CODE (PKL_PASS_PARENT) != PKL_AST_FUNCALL)
289 {
290 pkl_ast_node initial = PKL_AST_DECL_INITIAL (decl);
291 pkl_ast_node initial_type = PKL_AST_TYPE (initial);
292
293 if (PKL_AST_TYPE_CODE (initial_type) == PKL_TYPE_FUNCTION
294 && !PKL_AST_VAR_IS_PARENTHESIZED (var)
295 && (PKL_AST_TYPE_F_NARG (initial_type) == 0
296 || pkl_ast_func_all_optargs (initial_type)))
297 {
298 pkl_ast_node funcall = pkl_ast_make_funcall (PKL_PASS_AST,
299 ASTDEREF (var),
300 NULL /* args */);
301
302 PKL_AST_LOC (funcall) = PKL_AST_LOC (var);
303 PKL_PASS_NODE = funcall;
304 PKL_PASS_RESTART = 1;
305 }
306 }
307 }
308 PKL_PHASE_END_HANDLER
309
310 /* Finish strings, by expanding \-sequences, and emit errors if an
311 invalid \-sequence is found. */
312
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_string)313 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_string)
314 {
315 pkl_ast_node string = PKL_PASS_NODE;
316 char *string_pointer = PKL_AST_STRING_POINTER (string);
317 char *new_string_pointer;
318 char *p;
319 size_t string_length, i;
320 bool found_backslash = false;
321
322 #define ISODIGIT(c) ((unsigned)(c) - '0' < 8) /* is octal digit */
323 #define XDIGIT(x) \
324 ((unsigned)(x) - '0' < 10 ? (x) - '0' : ((x) | 0x20) - 'a' + 10)
325
326 /* Please keep this code in sync with the string printer in
327 pvm-val.c:pvm_print_val. */
328
329 /* First pass: calculate the size of the resulting string after
330 \-expansion, and report errors in the contents of the string. */
331 for (p = string_pointer, string_length = 0; *p != '\0'; ++p)
332 {
333 string_length++;
334 if (*p != '\\')
335 continue;
336
337 found_backslash = true;
338 ++p;
339
340 if (ISODIGIT (p[0]))
341 {
342 if (ISODIGIT (p[1]))
343 p += ISODIGIT (p[2]) ? 2 : 1;
344 continue;
345 }
346
347 switch (*p)
348 {
349 case '\\':
350 case 'n':
351 case 't':
352 case '"':
353 break;
354 case '\n':
355 string_length--;
356 break;
357 case 'x':
358 ++p;
359 if (!isxdigit (p[0]))
360 {
361 PKL_ERROR (PKL_AST_LOC (string),
362 _ ("\\x used with no following hex digits"));
363 PKL_TRANS_PAYLOAD->errors++;
364 PKL_PASS_ERROR;
365 }
366 if (isxdigit (p[1]))
367 ++p;
368 break;
369 default:
370 PKL_ERROR (PKL_AST_LOC (string),
371 _ ("invalid \\%c sequence in string"), *p);
372 PKL_TRANS_PAYLOAD->errors++;
373 PKL_PASS_ERROR;
374 }
375 }
376
377 if (!found_backslash)
378 goto _exit;
379
380 /* Second pass: compose the new string. */
381 new_string_pointer = xmalloc (string_length + 1);
382
383 for (p = string_pointer, i = 0; *p != '\0'; ++p, ++i)
384 {
385 if (*p != '\\')
386 {
387 new_string_pointer[i] = *p;
388 continue;
389 }
390 ++p;
391 if (*p == '\n') {
392 --i;
393 continue;
394 }
395
396
397 /* octal escape sequence */
398 if (ISODIGIT (p[0]))
399 {
400 unsigned int num = p[0] - '0';
401
402 if (ISODIGIT (p[1]))
403 {
404 ++p;
405 num = (num << 3) | (p[0] - '0');
406 if (ISODIGIT (p[1]))
407 {
408 ++p;
409 num = (num << 3) | (p[0] - '0');
410 }
411 }
412 if (num == '\0')
413 {
414 PKL_ERROR (PKL_AST_LOC (string),
415 _ ("string literal cannot contain NULL character"));
416 PKL_TRANS_PAYLOAD->errors++;
417 PKL_PASS_ERROR;
418 }
419 else if (num > 255)
420 {
421 PKL_ERROR (PKL_AST_LOC (string),
422 _ ("octal escape sequence out of range"));
423 PKL_TRANS_PAYLOAD->errors++;
424 PKL_PASS_ERROR;
425 }
426 new_string_pointer[i] = num;
427 continue;
428 }
429
430 switch (*p)
431 {
432 case '\\': new_string_pointer[i] = '\\'; break;
433 case 'n': new_string_pointer[i] = '\n'; break;
434 case 't': new_string_pointer[i] = '\t'; break;
435 case '"': new_string_pointer[i] = '"'; break;
436 case 'x':
437 ++p;
438 new_string_pointer[i] = XDIGIT (p[0]);
439 if (isxdigit (p[1]))
440 {
441 new_string_pointer[i] = (XDIGIT (p[0]) << 4) | XDIGIT (p[1]);
442 ++p;
443 }
444 if (new_string_pointer[i] == '\0')
445 {
446 PKL_ERROR (PKL_AST_LOC (string),
447 _ ("string literal cannot contain NULL character"));
448 PKL_TRANS_PAYLOAD->errors++;
449 PKL_PASS_ERROR;
450 }
451 break;
452 default:
453 assert (0);
454 }
455 }
456 new_string_pointer[i] = '\0';
457
458 #undef ISODIGIT
459 #undef XDIGIT
460
461 free (string_pointer);
462 PKL_AST_STRING_POINTER (string) = new_string_pointer;
463 }
464 PKL_PHASE_END_HANDLER
465
466 /* Determine the attribute code of attribute expressions, emitting an
467 error if the given attribute name is not defined. Finally, turn
468 the binary expression into an unary expression. */
469
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_op_attr)470 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_op_attr)
471 {
472 pkl_ast_node exp = PKL_PASS_NODE;
473
474 pkl_ast_node identifier = PKL_AST_EXP_OPERAND (exp, 1);
475 const char *identifier_name = PKL_AST_IDENTIFIER_POINTER (identifier);
476 enum pkl_ast_attr attr = PKL_AST_ATTR_NONE;
477
478 if (PKL_AST_EXP_ATTR (exp) != PKL_AST_ATTR_NONE)
479 PKL_PASS_DONE;
480
481 for (attr = 0; pkl_attr_name (attr); ++attr)
482 {
483 if (STREQ (pkl_attr_name (attr), identifier_name))
484 break;
485 }
486
487 if (attr == PKL_AST_ATTR_NONE)
488 {
489 PKL_ERROR (PKL_AST_LOC (identifier),
490 "invalid attribute '%s", identifier_name);
491 PKL_TRANS_PAYLOAD->errors++;
492 PKL_PASS_ERROR;
493 }
494
495 PKL_AST_EXP_ATTR (exp) = attr;
496
497 /* Turn the binary expression into an unary expression. */
498 PKL_AST_EXP_NUMOPS (exp) = 1;
499 pkl_ast_node_free (PKL_AST_EXP_OPERAND (exp, 1));
500 }
501 PKL_PHASE_END_HANDLER
502
503 /* Set the function's first optional argument and count the number of
504 formal arguments. */
505
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_func)506 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_func)
507 {
508 pkl_ast_node func = PKL_PASS_NODE;
509 pkl_ast_node func_args = PKL_AST_FUNC_ARGS (func);
510 pkl_ast_node fa;
511 int nargs;
512
513 /* Count the number of formal arguments. */
514 for (fa = func_args, nargs = 0; fa; fa = PKL_AST_CHAIN (fa))
515 nargs++;
516 PKL_AST_FUNC_NARGS (func) = nargs;
517
518 /* Find the first optional formal argument, if any, and set
519 first_opt_arg accordingly. */
520 for (fa = func_args; fa; fa = PKL_AST_CHAIN (fa))
521 {
522 if (PKL_AST_FUNC_ARG_INITIAL (fa))
523 {
524 PKL_AST_FUNC_FIRST_OPT_ARG (func) = ASTREF (fa);
525 break;
526 }
527 }
528 }
529 PKL_PHASE_END_HANDLER
530
531 /* Function types from function type literals don't have the number of
532 elements set. Do it here. */
533
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_type_function)534 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_type_function)
535 {
536 pkl_ast_node function_type = PKL_PASS_NODE;
537 pkl_ast_node function_type_args = PKL_AST_TYPE_F_ARGS (function_type);
538
539 pkl_ast_node arg;
540 size_t nargs = 0;
541
542 /* Count the number of formal arguments taken by functions of this
543 type. */
544 for (arg = function_type_args; arg; arg = PKL_AST_CHAIN (arg))
545 nargs++;
546 PKL_AST_TYPE_F_NARG (function_type) = nargs;
547
548 /* Find the first optional formal argument, if any, and set
549 first_op_arg accordingly. */
550 for (arg = function_type_args; arg; arg = PKL_AST_CHAIN (arg))
551 {
552 if (PKL_AST_FUNC_TYPE_ARG_OPTIONAL (arg))
553 {
554 PKL_AST_TYPE_F_FIRST_OPT_ARG (function_type)
555 = ASTREF (arg);
556 break;
557 }
558 }
559
560 /* Determine whether the function type gets a vararg. */
561 for (arg = PKL_AST_TYPE_F_ARGS (function_type);
562 arg;
563 arg = PKL_AST_CHAIN (arg))
564 {
565 if (PKL_AST_FUNC_TYPE_ARG_VARARG (arg))
566 {
567 PKL_AST_TYPE_F_VARARG (function_type) = 1;
568 break;
569 }
570 }
571 }
572 PKL_PHASE_END_HANDLER
573
574 /* Complete trimmers lacking some of their indexes. */
575
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_trimmer)576 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_trimmer)
577 {
578 pkl_ast_node trimmer = PKL_PASS_NODE;
579 pkl_ast_node entity = PKL_AST_TRIMMER_ENTITY (trimmer);
580 pkl_ast_node from = PKL_AST_TRIMMER_FROM (trimmer);
581 pkl_ast_node to = PKL_AST_TRIMMER_TO (trimmer);
582 pkl_ast_node addend = PKL_AST_TRIMMER_ADDEND (trimmer);
583
584 /* If the FROM index of a trimmer isn't specified, it defaults to
585 0UL. */
586 if (!from)
587 {
588 pkl_ast_node idx_type
589 = pkl_ast_make_integral_type (PKL_PASS_AST, 64, 0);
590
591 from = pkl_ast_make_integer (PKL_PASS_AST, 0);
592 PKL_AST_TYPE (from) = ASTREF (idx_type);
593 PKL_AST_LOC (idx_type) = PKL_AST_LOC (trimmer);
594 PKL_AST_LOC (from) = PKL_AST_LOC (trimmer);
595
596 PKL_AST_TRIMMER_FROM (trimmer) = ASTREF (from);
597 }
598
599 if (addend)
600 {
601 /* If an ADDEND is specified, we set `TO' to an expression that
602 evaluates to FROM + ADDEND. */
603 pkl_ast_node plus_exp
604 = pkl_ast_make_binary_exp (PKL_PASS_AST,
605 PKL_AST_OP_ADD,
606 from, addend);
607
608 PKL_AST_TRIMMER_TO (trimmer) = ASTREF (plus_exp);
609 PKL_PASS_RESTART = 1;
610 }
611 else if (!to)
612 {
613 /* If the TO index of a trimmer isn't specified, it defaults to
614 an expression that evaluates to the size of the
615 container. */
616 pkl_ast_node length_op = pkl_ast_make_unary_exp (PKL_PASS_AST,
617 PKL_AST_OP_ATTR,
618 entity);
619
620 PKL_AST_EXP_ATTR (length_op) = PKL_AST_ATTR_LENGTH;
621 PKL_AST_TRIMMER_TO (trimmer) = ASTREF (length_op);
622 PKL_PASS_RESTART = 1;
623 }
624 }
625 PKL_PHASE_END_HANDLER
626
627 /* Decode format strings in `printf' instructions. */
628
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_print_stmt)629 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_print_stmt)
630 {
631 pkl_ast_node print_stmt = PKL_PASS_NODE;
632 pkl_ast_node args = PKL_AST_PRINT_STMT_ARGS (print_stmt);
633 pkl_ast_node print_fmt = PKL_AST_PRINT_STMT_FMT (print_stmt);
634 char *fmt, *p;
635 pkl_ast_node t, arg;
636 int ntag, nargs = 0;
637 pkl_ast_node types = NULL, prev_arg = NULL;
638 const char *msg = NULL;
639 /* XXX this hard limit should go away. */
640 #define MAX_CLASS_TAGS 32
641 int nclasses = 0;
642 char *classes[MAX_CLASS_TAGS];
643
644 /* Calculate the number of arguments. */
645 for (t = args; t; t = PKL_AST_CHAIN (t))
646 nargs++;
647 PKL_AST_PRINT_STMT_NARGS (print_stmt) = nargs;
648
649 /* If this is a `print', or if the format string has been already
650 processed, then we are done. */
651 if (!print_fmt
652 || PKL_AST_PRINT_STMT_FMT_PROCESSED_P (print_stmt))
653 PKL_PASS_DONE;
654
655 fmt = PKL_AST_STRING_POINTER (print_fmt);
656 p = fmt;
657
658 /* Process the prefix string, if any. */
659 if (*p != '%')
660 {
661 p = strchrnul (fmt, '%');
662 PKL_AST_PRINT_STMT_PREFIX (print_stmt) = strndup (fmt, p - fmt);
663 if (!PKL_AST_PRINT_STMT_PREFIX (print_stmt))
664 PKL_ICE (PKL_AST_LOC (print_stmt), _("out of memory"));
665 }
666
667 /* Process the format string. */
668 prev_arg = NULL;
669 for (types = NULL, ntag = 0, arg = args, nclasses = 0;
670 *p != '\0';
671 prev_arg = arg, arg = PKL_AST_CHAIN (arg))
672 {
673 pkl_ast_node atype;
674 char flag = 0;
675 int prefix = -1;
676
677 assert (*p == '%');
678 if (ntag >= nargs && p[1] != '>' && p[1] != '<')
679 {
680 PKL_ERROR (PKL_AST_LOC (print_stmt),
681 "not enough arguments in printf");
682 PKL_TRANS_PAYLOAD->errors++;
683 PKL_PASS_ERROR;
684 }
685
686 /* Process the optional numerical prefix. */
687 if (p[1] >= '0' && p[1] <= '9')
688 {
689 prefix = p[1] - '0';
690 p++;
691 }
692
693 /* Process an optional flag (uppercase letter.) */
694 if (p[1] >= 'A' && p[1] <= 'Z')
695 {
696 flag = p[1];
697 p++;
698 }
699
700 /* Make sure this tag supports the given numerical prefix and
701 tag. */
702 if ((flag != 0 || prefix != -1)
703 && p[1] != 'v')
704 {
705 if (flag != 0)
706 msg = _("invalid flag");
707 else
708 msg = _("invalid numerical prefix");
709 goto invalid_tag;
710 }
711
712 /* Now process the rest of the tag. */
713 switch (p[1])
714 {
715 case 'v':
716 p += 2;
717 PKL_AST_PRINT_STMT_ARG_BASE (arg) = 0; /* Arbitrary. */
718 atype = pkl_ast_make_any_type (PKL_PASS_AST);
719 PKL_AST_PRINT_STMT_ARG_VALUE_P (arg) = 1;
720 PKL_AST_PRINT_STMT_ARG_PRINT_DEPTH (arg)
721 = (prefix == -1 ? 0 : prefix);
722 switch (flag)
723 {
724 case 'T':
725 PKL_AST_PRINT_STMT_ARG_PRINT_MODE (arg)
726 = PKL_AST_PRINT_MODE_TREE;
727 break;
728 case 'F':
729 /* Fallthrough. */
730 case 0:
731 PKL_AST_PRINT_STMT_ARG_PRINT_MODE (arg)
732 = PKL_AST_PRINT_MODE_FLAT;
733 break;
734 default:
735 msg = _("invalid flag");
736 goto invalid_tag;
737 }
738 PKL_AST_LOC (atype) = PKL_AST_LOC (print_fmt);
739 types = pkl_ast_chainon (types, atype);
740 ntag++;
741 break;
742 case 's':
743 p += 2;
744 PKL_AST_PRINT_STMT_ARG_BASE (arg) = 10; /* Arbitrary. */
745 atype = pkl_ast_make_string_type (PKL_PASS_AST);
746 PKL_AST_LOC (atype) = PKL_AST_LOC (print_fmt);
747 types = pkl_ast_chainon (types, atype);
748 ntag++;
749 break;
750 case 'c':
751 p += 2;
752 PKL_AST_PRINT_STMT_ARG_BASE (arg) = 256; /* Arbitrary */
753 atype = pkl_ast_make_integral_type (PKL_PASS_AST, 8, 0);
754 PKL_AST_LOC (atype) = PKL_AST_LOC (print_fmt);
755 types = pkl_ast_chainon (types, atype);
756 ntag++;
757 break;
758 case 'i':
759 case 'u':
760 {
761 unsigned int bits;
762
763 if (p[2] >= '0' && p[2] <= '9')
764 {
765 int base_idx;
766
767 if (p[3] >= '0' && p[3] <= '9')
768 {
769 bits = (p[2] - '0') * 10 + (p[3] - '0');
770 base_idx = 4;
771 }
772 else
773 {
774 bits = p[2] - '0';
775 base_idx = 3;
776 }
777
778 if (bits > 64)
779 {
780 msg = _("base with more than 64 bits");
781 goto invalid_tag;
782 }
783
784 switch (p[base_idx])
785 {
786 case 'b': PKL_AST_PRINT_STMT_ARG_BASE (arg) = 2; break;
787 case 'o': PKL_AST_PRINT_STMT_ARG_BASE (arg) = 8; break;
788 case 'd': PKL_AST_PRINT_STMT_ARG_BASE (arg) = 10; break;
789 case 'x': PKL_AST_PRINT_STMT_ARG_BASE (arg) = 16; break;
790 case 'c':
791 PKL_AST_PRINT_STMT_ARG_BASE (arg) = 256;
792 if (bits != 8)
793 {
794 msg = _("char format only makes sense with 8 bits");
795 goto invalid_tag;
796 }
797 break;
798 default:
799 msg = _("invalid base");
800 goto invalid_tag;
801 }
802
803 atype = pkl_ast_make_integral_type (PKL_PASS_AST,
804 bits, p[1] == 'i');
805 PKL_AST_LOC (atype) = PKL_AST_LOC (print_fmt);
806 types = pkl_ast_chainon (types, atype);
807
808 if (base_idx == 4)
809 p += 5;
810 else
811 p += 4;
812 }
813 else
814 {
815 msg = _("expected decimal digit after %u");
816 goto invalid_tag;
817 }
818 ntag++;
819 break;
820 }
821 case '<':
822 /* Fallthrough. */
823 case '>':
824 {
825 int end_sc = 0;
826 char *class = xmalloc (strlen (fmt) + 1);
827 size_t j;
828 pkl_ast_node new_arg;
829
830 end_sc = (p[1] == '>');
831 p += 2;
832
833 if (!end_sc)
834 {
835 /* Empty classes are not allowed. */
836 if (*p == ':')
837 {
838 free (class);
839 msg = _("invalid format specifier");
840 goto invalid_tag;
841 }
842
843 /* Get the name of the styling class. */
844 j = 0;
845 while (*p != ':' && *p != '%' && *p != '\0')
846 {
847 class[j++] = *p;
848 p++;
849 }
850 class[j] = '\0';
851
852 if (*p != ':')
853 {
854 free (class);
855 msg = _("invalid format specifier");
856 goto invalid_tag;
857 }
858 p++; /* Skip the : */
859
860 assert (nclasses < MAX_CLASS_TAGS);
861 classes[nclasses++] = class;
862 }
863 else
864 {
865 if (nclasses == 0)
866 {
867 free (class);
868 msg = _("unpaired styling class");
869 goto invalid_tag;
870 }
871 assert (nclasses > 0);
872 class = classes[--nclasses];
873 }
874
875 /* Create the new arg and add it to the list of
876 arguments. */
877 new_arg = pkl_ast_make_print_stmt_arg (PKL_PASS_AST,
878 NULL);
879 PKL_AST_LOC (new_arg) = PKL_AST_LOC (print_fmt);
880
881 if (end_sc)
882 PKL_AST_PRINT_STMT_ARG_END_SC (new_arg) = xstrdup (class);
883 else
884 PKL_AST_PRINT_STMT_ARG_BEGIN_SC (new_arg) = class;
885
886 if (arg)
887 {
888 if (arg == PKL_AST_PRINT_STMT_ARGS (print_stmt))
889 {
890 /* Prepend. */
891 PKL_AST_CHAIN (new_arg) = arg;
892 PKL_AST_PRINT_STMT_ARGS (print_stmt)
893 = ASTREF (new_arg);
894 }
895 else
896 {
897 /* Add after. */
898 PKL_AST_CHAIN (new_arg) = PKL_AST_CHAIN (prev_arg);
899 PKL_AST_CHAIN (prev_arg) = ASTREF (new_arg);
900 }
901 }
902 else
903 {
904 /* Append. */
905 if (!PKL_AST_PRINT_STMT_ARGS (print_stmt))
906 PKL_AST_PRINT_STMT_ARGS (print_stmt)
907 = ASTREF (new_arg);
908 else
909 PKL_AST_PRINT_STMT_ARGS (print_stmt)
910 = pkl_ast_chainon (PKL_AST_PRINT_STMT_ARGS (print_stmt),
911 new_arg);
912 }
913
914 arg = new_arg;
915
916 /* The type corresponding to a styling class format
917 directive is `void'. */
918 atype = pkl_ast_make_void_type (PKL_PASS_AST);
919 PKL_AST_LOC (atype) = PKL_AST_LOC (print_fmt);
920 types = pkl_ast_chainon (types, atype);
921
922 break;
923 }
924 default:
925 msg = _("invalid format specifier");
926 goto invalid_tag;
927 }
928
929 /* Add the optional suffix to the argument. */
930 if (*p != '\0' && *p != '%')
931 {
932 char *end = strchrnul (p, '%');
933 PKL_AST_PRINT_STMT_ARG_SUFFIX (arg) = strndup (p, end - p);
934 if (!PKL_AST_PRINT_STMT_ARG_SUFFIX (arg))
935 PKL_ICE (PKL_AST_LOC (print_stmt), _("out of memory"));
936 p = end;
937 }
938 }
939
940 /* Check that we are not leaving unclosed styling classes. */
941 if (nclasses > 0)
942 {
943 msg = _("unclosed styling tag");
944 goto invalid_tag;
945 }
946
947 if (nargs > ntag)
948 {
949 PKL_ERROR (PKL_AST_LOC (print_stmt),
950 "too many arguments in printf");
951 PKL_TRANS_PAYLOAD->errors++;
952 PKL_PASS_ERROR;
953 }
954
955 PKL_AST_PRINT_STMT_TYPES (print_stmt) = ASTREF (types);
956
957 PKL_AST_PRINT_STMT_FMT_PROCESSED_P (print_stmt) = 1;
958 PKL_PASS_DONE;
959
960 invalid_tag:
961 PKL_ERROR (PKL_AST_LOC (print_fmt),
962 "invalid %%- tag in format string: %s", msg);
963 PKL_TRANS_PAYLOAD->errors++;
964 PKL_PASS_ERROR;
965 }
966 PKL_PHASE_END_HANDLER
967
968 /* Compute and set the indexes of all the elements of an ARRAY node
969 and set the size of the array consequently. */
970
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_array)971 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_array)
972 {
973 pkl_ast_node array = PKL_PASS_NODE;
974 pkl_ast_node initializers
975 = PKL_AST_ARRAY_INITIALIZERS (array);
976
977 pkl_ast_node tmp;
978 size_t index, nelem, ninitializer;
979
980 nelem = 0;
981 for (index = 0, tmp = initializers, ninitializer = 0;
982 tmp;
983 tmp = PKL_AST_CHAIN (tmp), ++ninitializer)
984 {
985 pkl_ast_node initializer_index_node
986 = PKL_AST_ARRAY_INITIALIZER_INDEX (tmp);
987 size_t initializer_index;
988 size_t elems_appended, effective_index;
989
990 /* Set the index of the initializer. */
991 if (initializer_index_node == NULL)
992 {
993 pkl_ast_node initializer_index_type
994 = pkl_ast_make_integral_type (PKL_PASS_AST, 64, 0);
995 PKL_AST_LOC (initializer_index_type)
996 = PKL_AST_LOC (tmp);
997
998
999 initializer_index_node
1000 = pkl_ast_make_integer (PKL_PASS_AST, index);
1001 PKL_AST_TYPE (initializer_index_node)
1002 = ASTREF (initializer_index_type);
1003 PKL_AST_LOC (initializer_index_node)
1004 = PKL_AST_LOC (tmp);
1005
1006 PKL_AST_ARRAY_INITIALIZER_INDEX (tmp)
1007 = ASTREF (initializer_index_node);
1008
1009 PKL_PASS_RESTART = 1;
1010 elems_appended = 1;
1011 }
1012 else
1013 {
1014 if (PKL_AST_CODE (initializer_index_node)
1015 != PKL_AST_INTEGER)
1016 {
1017 PKL_ICE (PKL_AST_NOLOC,
1018 "array initialize index should be an integer node");
1019 PKL_PASS_ERROR;
1020 }
1021
1022 initializer_index
1023 = PKL_AST_INTEGER_VALUE (initializer_index_node);
1024
1025 if ((int64_t) initializer_index < 0)
1026 {
1027 PKL_ERROR (PKL_AST_LOC (initializer_index_node),
1028 "array dimentions may not be negative");
1029 PKL_TRANS_PAYLOAD->errors++;
1030 PKL_PASS_ERROR;
1031 }
1032 else if ((int64_t) initializer_index < index)
1033 elems_appended = 0;
1034 else
1035 elems_appended = initializer_index - index + 1;
1036 effective_index = initializer_index;
1037
1038 PKL_AST_INTEGER_VALUE (initializer_index_node)
1039 = effective_index;
1040 }
1041
1042 index += elems_appended;
1043 nelem += elems_appended;
1044 }
1045
1046 PKL_AST_ARRAY_NELEM (array) = nelem;
1047 PKL_AST_ARRAY_NINITIALIZER (array) = ninitializer;
1048 }
1049 PKL_PHASE_END_HANDLER
1050
1051 /* Compound statements introduce a lexical level. Update the function
1052 back. */
1053
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_pr_comp_stmt)1054 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_pr_comp_stmt)
1055 {
1056 PKL_TRANS_INCR_FUNCTION_BACK;
1057 }
1058 PKL_PHASE_END_HANDLER
1059
1060 /* FOR-IN statements introduce a lexical level if they use an
1061 iterator. Update the function back. */
1062
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_loop_stmt_iterator)1063 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_loop_stmt_iterator)
1064 {
1065 PKL_TRANS_INCR_FUNCTION_BACK;
1066 }
1067 PKL_PHASE_END_HANDLER
1068
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_loop_stmt)1069 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_loop_stmt)
1070 {
1071 pkl_ast_node stmt = PKL_PASS_NODE;
1072
1073
1074 if (PKL_AST_LOOP_STMT_ITERATOR (stmt))
1075 PKL_TRANS_DECR_FUNCTION_BACK;
1076 }
1077 PKL_PHASE_END_HANDLER
1078
1079 /* Annotate compount statement nodes with the number of variable and
1080 function declarations occurring in the statement.
1081
1082 Update the function back. */
1083
PKL_PHASE_BEGIN_HANDLER(pkl_trans1_ps_comp_stmt)1084 PKL_PHASE_BEGIN_HANDLER (pkl_trans1_ps_comp_stmt)
1085 {
1086 pkl_ast_node t, comp_stmt = PKL_PASS_NODE;
1087 int numvars = 0;
1088
1089 for (t = PKL_AST_COMP_STMT_STMTS (comp_stmt);
1090 t;
1091 t = PKL_AST_CHAIN (t))
1092 {
1093 if (PKL_AST_CODE (t) == PKL_AST_DECL
1094 && (PKL_AST_DECL_KIND (t) == PKL_AST_DECL_KIND_VAR
1095 || PKL_AST_DECL_KIND (t) == PKL_AST_DECL_KIND_FUNC))
1096 numvars++;
1097 }
1098
1099 PKL_AST_COMP_STMT_NUMVARS (comp_stmt) = numvars;
1100 PKL_TRANS_DECR_FUNCTION_BACK;
1101 }
1102 PKL_PHASE_END_HANDLER
1103
1104 struct pkl_phase pkl_phase_trans1 =
1105 {
1106 PKL_PHASE_PS_HANDLER (PKL_AST_SRC, pkl_trans_ps_src),
1107 PKL_PHASE_PR_HANDLER (PKL_AST_PROGRAM, pkl_trans_pr_program),
1108 PKL_PHASE_PS_HANDLER (PKL_AST_STRUCT, pkl_trans1_ps_struct),
1109 PKL_PHASE_PS_HANDLER (PKL_AST_OFFSET, pkl_trans1_ps_offset),
1110 PKL_PHASE_PS_HANDLER (PKL_AST_FUNCALL, pkl_trans1_ps_funcall),
1111 PKL_PHASE_PS_HANDLER (PKL_AST_STRING, pkl_trans1_ps_string),
1112 PKL_PHASE_PS_HANDLER (PKL_AST_VAR, pkl_trans1_ps_var),
1113 PKL_PHASE_PS_HANDLER (PKL_AST_FUNC, pkl_trans1_ps_func),
1114 PKL_PHASE_PS_HANDLER (PKL_AST_TRIMMER, pkl_trans1_ps_trimmer),
1115 PKL_PHASE_PS_HANDLER (PKL_AST_PRINT_STMT, pkl_trans1_ps_print_stmt),
1116 PKL_PHASE_PR_HANDLER (PKL_AST_DECL, pkl_trans1_pr_decl),
1117 PKL_PHASE_PS_HANDLER (PKL_AST_DECL, pkl_trans1_ps_decl),
1118 PKL_PHASE_PS_HANDLER (PKL_AST_ARRAY, pkl_trans1_ps_array),
1119 PKL_PHASE_PR_HANDLER (PKL_AST_COMP_STMT, pkl_trans1_pr_comp_stmt),
1120 PKL_PHASE_PS_HANDLER (PKL_AST_COMP_STMT, pkl_trans1_ps_comp_stmt),
1121 PKL_PHASE_PS_HANDLER (PKL_AST_LOOP_STMT_ITERATOR, pkl_trans1_ps_loop_stmt_iterator),
1122 PKL_PHASE_PS_HANDLER (PKL_AST_LOOP_STMT, pkl_trans1_ps_loop_stmt),
1123 PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_ATTR, pkl_trans1_ps_op_attr),
1124 PKL_PHASE_PS_TYPE_HANDLER (PKL_TYPE_STRUCT, pkl_trans1_ps_type_struct),
1125 PKL_PHASE_PS_TYPE_HANDLER (PKL_TYPE_FUNCTION, pkl_trans1_ps_type_function),
1126 };
1127
1128
1129
1130 /* The following handlers annotate expression nodes to reflect whether
1131 they are literals. Entities created by the lexer (INTEGER, STRING,
1132 etc) already have this attribute set if needed. */
1133
1134 /* Expressions having only literal operands are literal. */
1135
PKL_PHASE_BEGIN_HANDLER(pkl_trans2_ps_exp)1136 PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_exp)
1137 {
1138 pkl_ast_node exp = PKL_PASS_NODE;
1139 int o, literal_p = 1;
1140
1141 for (o = 0; o < PKL_AST_EXP_NUMOPS (exp); ++o)
1142 {
1143 pkl_ast_node op = PKL_AST_EXP_OPERAND (exp, o);
1144
1145 literal_p &= PKL_AST_LITERAL_P (op);
1146 if (!literal_p)
1147 break;
1148 }
1149
1150 PKL_AST_LITERAL_P (exp) = literal_p;
1151 }
1152 PKL_PHASE_END_HANDLER
1153
1154 /* An offset is a literal if its magnitude is also a literal. */
1155
PKL_PHASE_BEGIN_HANDLER(pkl_trans2_ps_offset)1156 PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_offset)
1157 {
1158 pkl_ast_node magnitude
1159 = PKL_AST_OFFSET_MAGNITUDE (PKL_PASS_NODE);
1160
1161 PKL_AST_LITERAL_P (PKL_PASS_NODE) = PKL_AST_LITERAL_P (magnitude);
1162 }
1163 PKL_PHASE_END_HANDLER
1164
1165 /* An array is a literal if all its initializers are literal. */
1166
PKL_PHASE_BEGIN_HANDLER(pkl_trans2_ps_array)1167 PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_array)
1168 {
1169 int literal_p = 1;
1170 pkl_ast_node t, array = PKL_PASS_NODE;
1171
1172 for (t = PKL_AST_ARRAY_INITIALIZERS (array); t;
1173 t = PKL_AST_CHAIN (t))
1174 {
1175 pkl_ast_node array_initializer_exp
1176 = PKL_AST_ARRAY_INITIALIZER_EXP (t);
1177
1178 literal_p &= PKL_AST_LITERAL_P (array_initializer_exp);
1179 if (!literal_p)
1180 break;
1181 }
1182
1183 PKL_AST_LITERAL_P (array) = literal_p;
1184 }
1185 PKL_PHASE_END_HANDLER
1186
1187 /* An indexer is a literal if the referred entity element is also a
1188 literal. */
1189
PKL_PHASE_BEGIN_HANDLER(pkl_trans2_ps_indexer)1190 PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_indexer)
1191 {
1192 pkl_ast_node entity = PKL_AST_INDEXER_ENTITY (PKL_PASS_NODE);
1193 PKL_AST_LITERAL_P (PKL_PASS_NODE) = PKL_AST_LITERAL_P (entity);
1194 }
1195 PKL_PHASE_END_HANDLER
1196
1197 /* A trim is a literal if the trimmed entity is also a literal. */
1198
PKL_PHASE_BEGIN_HANDLER(pkl_trans2_ps_trimmer)1199 PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_trimmer)
1200 {
1201 pkl_ast_node entity = PKL_AST_TRIMMER_ENTITY (PKL_PASS_NODE);
1202 PKL_AST_LITERAL_P (PKL_PASS_NODE) = PKL_AST_LITERAL_P (entity);
1203 }
1204 PKL_PHASE_END_HANDLER
1205
1206 /* A struct is a literal if all its element values are literals. */
1207
PKL_PHASE_BEGIN_HANDLER(pkl_trans2_ps_struct)1208 PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_struct)
1209 {
1210 pkl_ast_node t;
1211 int literal_p = 1;
1212
1213 for (t = PKL_AST_STRUCT_FIELDS (PKL_PASS_NODE); t;
1214 t = PKL_AST_CHAIN (t))
1215 {
1216 pkl_ast_node struct_field_exp = PKL_AST_STRUCT_FIELD_EXP (t);
1217
1218 literal_p &= PKL_AST_LITERAL_P (struct_field_exp);
1219 if (!literal_p)
1220 break;
1221 }
1222
1223 PKL_AST_LITERAL_P (PKL_PASS_NODE) = literal_p;
1224 }
1225 PKL_PHASE_END_HANDLER
1226
1227 /* A struct ref is a literal if the value of the referred element is
1228 also a literal.
1229
1230 Also, struct references that refer to parameterless methods are
1231 transformed into funcalls to these methods, but only if the struct
1232 references are not part of funcall themselves. This is similar to
1233 what is done with variable nodes. */
1234
1235
PKL_PHASE_BEGIN_HANDLER(pkl_trans2_ps_struct_ref)1236 PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_struct_ref)
1237 {
1238 pkl_ast_node struct_ref = PKL_PASS_NODE;
1239 pkl_ast_node stct = PKL_AST_STRUCT_REF_STRUCT (struct_ref);
1240
1241 PKL_AST_LITERAL_P (PKL_PASS_NODE) = PKL_AST_LITERAL_P (stct);
1242
1243 if (PKL_PASS_PARENT
1244 && PKL_AST_CODE (PKL_PASS_PARENT) != PKL_AST_FUNCALL)
1245 {
1246 pkl_ast_node type = PKL_AST_TYPE (struct_ref);
1247
1248 if (PKL_AST_TYPE_CODE (type) == PKL_TYPE_FUNCTION
1249 && !PKL_AST_STRUCT_REF_IS_PARENTHESIZED (struct_ref)
1250 && (PKL_AST_TYPE_F_NARG (type) == 0
1251 || pkl_ast_func_all_optargs (type)))
1252 {
1253 pkl_ast_node function_rtype = PKL_AST_TYPE_F_RTYPE (type);
1254 pkl_ast_node funcall = pkl_ast_make_funcall (PKL_PASS_AST,
1255 ASTDEREF (struct_ref),
1256 NULL /* args */);
1257
1258 /* Note that we have to set the type here, because typify1
1259 is performed before trans2. */
1260 PKL_AST_TYPE (funcall) = ASTREF (function_rtype);
1261 PKL_AST_LOC (funcall) = PKL_AST_LOC (struct_ref);
1262
1263 PKL_PASS_NODE = funcall;
1264 PKL_PASS_RESTART = 1;
1265 }
1266 }
1267 }
1268 PKL_PHASE_END_HANDLER
1269
1270 /* A cast is considered a literal if the value of the referred element
1271 is also a literal. */
1272
PKL_PHASE_BEGIN_HANDLER(pkl_trans2_ps_cast)1273 PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_cast)
1274 {
1275 PKL_AST_LITERAL_P (PKL_PASS_NODE)
1276 = PKL_AST_LITERAL_P (PKL_AST_CAST_EXP (PKL_PASS_NODE));
1277 }
1278 PKL_PHASE_END_HANDLER
1279
1280 /* In offset types having another type as their unit, replace it with
1281 its size in bits. Emit a diagnostic if the type is not
1282 complete. */
1283
PKL_PHASE_BEGIN_HANDLER(pkl_trans2_ps_type_offset)1284 PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_type_offset)
1285 {
1286 pkl_ast_node type = PKL_PASS_NODE;
1287 pkl_ast_node unit_type = PKL_AST_TYPE_O_UNIT (type);
1288 pkl_ast_node unit;
1289
1290 if (PKL_AST_CODE (unit_type) != PKL_AST_TYPE)
1291 /* The unit of this offset is not a type. Nothing to do. */
1292 PKL_PASS_DONE;
1293
1294 if (PKL_AST_TYPE_COMPLETE (unit_type) != PKL_AST_TYPE_COMPLETE_YES)
1295 {
1296 PKL_ERROR (PKL_AST_LOC (type),
1297 "offset types only work on complete types");
1298 PKL_TRANS_PAYLOAD->errors++;
1299 PKL_PASS_ERROR;
1300 }
1301
1302 /* Calculate the size of the complete type in bytes and put it in
1303 an integer node. */
1304 unit = pkl_ast_sizeof_type (PKL_PASS_AST, unit_type);
1305 PKL_AST_LOC (unit) = PKL_AST_LOC (unit_type);
1306 PKL_AST_LOC (PKL_AST_TYPE (unit)) = PKL_AST_LOC (unit_type);
1307
1308 /* Replace the unit type with this expression. */
1309 PKL_AST_TYPE_O_UNIT (type) = ASTREF (unit);
1310 pkl_ast_node_free (unit_type);
1311
1312 PKL_PASS_RESTART = 1;
1313 }
1314 PKL_PHASE_END_HANDLER
1315
1316 /* Add an assignment statement to INCRDECR expressions. */
1317
PKL_PHASE_BEGIN_HANDLER(pkl_trans2_ps_incrdecr)1318 PKL_PHASE_BEGIN_HANDLER (pkl_trans2_ps_incrdecr)
1319 {
1320 pkl_ast_node incrdecr = PKL_PASS_NODE;
1321 pkl_ast_node incrdecr_stmt = PKL_AST_INCRDECR_ASS_STMT (incrdecr);
1322
1323 if (!incrdecr_stmt)
1324 {
1325 pkl_ast_node incrdecr_exp = PKL_AST_INCRDECR_EXP (incrdecr);
1326 pkl_ast_node incrdecr_exp_type = PKL_AST_TYPE (incrdecr_exp);
1327 int incrdecr_sign = PKL_AST_INCRDECR_SIGN (incrdecr);
1328 pkl_ast_node step, ass_stmt, exp_plus_one;
1329
1330 int op = (incrdecr_sign == PKL_AST_SIGN_INCR
1331 ? PKL_AST_OP_ADD : PKL_AST_OP_SUB);
1332
1333 /* Get the step. The type of the expression is safe as per
1334 typify. */
1335 step = pkl_ast_type_incr_step (PKL_PASS_AST, incrdecr_exp_type);
1336 assert (step); /* XXX turn to ICE. */
1337
1338 /* Build a statement EXP = EXP +/- STEP */
1339 exp_plus_one = pkl_ast_make_binary_exp (PKL_PASS_AST, op,
1340 incrdecr_exp, step);
1341 PKL_AST_TYPE (exp_plus_one) = ASTREF (incrdecr_exp_type);
1342 ass_stmt = pkl_ast_make_ass_stmt (PKL_PASS_AST,
1343 incrdecr_exp, exp_plus_one);
1344
1345 PKL_AST_INCRDECR_ASS_STMT (incrdecr) = ASTREF (ass_stmt);
1346 PKL_PASS_RESTART = 1;
1347 }
1348 }
1349 PKL_PHASE_END_HANDLER
1350
1351 struct pkl_phase pkl_phase_trans2 =
1352 {
1353 PKL_PHASE_PS_HANDLER (PKL_AST_SRC, pkl_trans_ps_src),
1354 PKL_PHASE_PR_HANDLER (PKL_AST_PROGRAM, pkl_trans_pr_program),
1355 PKL_PHASE_PS_HANDLER (PKL_AST_EXP, pkl_trans2_ps_exp),
1356 PKL_PHASE_PS_HANDLER (PKL_AST_OFFSET, pkl_trans2_ps_offset),
1357 PKL_PHASE_PS_HANDLER (PKL_AST_ARRAY, pkl_trans2_ps_array),
1358 PKL_PHASE_PS_HANDLER (PKL_AST_INDEXER, pkl_trans2_ps_indexer),
1359 PKL_PHASE_PS_HANDLER (PKL_AST_TRIMMER, pkl_trans2_ps_trimmer),
1360 PKL_PHASE_PS_HANDLER (PKL_AST_STRUCT, pkl_trans2_ps_struct),
1361 PKL_PHASE_PS_HANDLER (PKL_AST_STRUCT_REF, pkl_trans2_ps_struct_ref),
1362 PKL_PHASE_PS_HANDLER (PKL_AST_CAST, pkl_trans2_ps_cast),
1363 PKL_PHASE_PS_HANDLER (PKL_AST_INCRDECR, pkl_trans2_ps_incrdecr),
1364 PKL_PHASE_PS_TYPE_HANDLER (PKL_TYPE_OFFSET, pkl_trans2_ps_type_offset),
1365 };
1366
1367
1368
1369 /* SIZEOF nodes whose operand is a complete type should be replaced
1370 with an offset. */
1371
PKL_PHASE_BEGIN_HANDLER(pkl_trans3_ps_op_sizeof)1372 PKL_PHASE_BEGIN_HANDLER (pkl_trans3_ps_op_sizeof)
1373 {
1374 pkl_ast_node node = PKL_PASS_NODE;
1375 pkl_ast_node op = PKL_AST_EXP_OPERAND (node, 0);
1376 pkl_ast_node offset, offset_type, unit, unit_type;
1377
1378 if (PKL_AST_TYPE_COMPLETE (op)
1379 != PKL_AST_TYPE_COMPLETE_YES)
1380 {
1381 PKL_ERROR (PKL_AST_LOC (op),
1382 "invalid operand to sizeof");
1383 PKL_TRANS_PAYLOAD->errors++;
1384 PKL_PASS_ERROR;
1385 }
1386
1387 {
1388 /* Calculate the size of the complete type in bytes and put it in
1389 an integer node. */
1390 pkl_ast_node magnitude
1391 = pkl_ast_sizeof_type (PKL_PASS_AST, op);
1392 PKL_AST_LOC (magnitude) = PKL_AST_LOC (node);
1393 PKL_AST_LOC (PKL_AST_TYPE (magnitude)) = PKL_AST_LOC (node);
1394
1395 /* Build an offset with that magnitude, and unit bits. */
1396 unit_type = pkl_ast_make_integral_type (PKL_PASS_AST, 64, 0);
1397 PKL_AST_LOC (unit_type) = PKL_AST_LOC (node);
1398
1399 unit = pkl_ast_make_integer (PKL_PASS_AST, PKL_AST_OFFSET_UNIT_BITS);
1400 PKL_AST_LOC (unit) = PKL_AST_LOC (node);
1401 PKL_AST_TYPE (unit) = ASTREF (unit_type);
1402
1403 offset = pkl_ast_make_offset (PKL_PASS_AST, magnitude, unit);
1404
1405 PKL_AST_LOC (offset) = PKL_AST_LOC (node);
1406 offset_type = pkl_ast_make_offset_type (PKL_PASS_AST,
1407 PKL_AST_TYPE (magnitude),
1408 unit);
1409 PKL_AST_LOC (offset_type) = PKL_AST_LOC (node);
1410 PKL_AST_TYPE (offset) = ASTREF (offset_type);
1411 }
1412
1413 pkl_ast_node_free (PKL_PASS_NODE);
1414 PKL_PASS_NODE = offset;
1415 PKL_PASS_RESTART = 1;
1416 }
1417 PKL_PHASE_END_HANDLER
1418
1419 struct pkl_phase pkl_phase_trans3 =
1420 {
1421 PKL_PHASE_PS_HANDLER (PKL_AST_SRC, pkl_trans_ps_src),
1422 PKL_PHASE_PR_HANDLER (PKL_AST_PROGRAM, pkl_trans_pr_program),
1423 PKL_PHASE_PS_OP_HANDLER (PKL_AST_OP_SIZEOF, pkl_trans3_ps_op_sizeof),
1424 };
1425
1426
1427
1428 struct pkl_phase pkl_phase_trans4 =
1429 {
1430 PKL_PHASE_PS_HANDLER (PKL_AST_SRC, pkl_trans_ps_src),
1431 PKL_PHASE_PR_HANDLER (PKL_AST_PROGRAM, pkl_trans_pr_program),
1432 };
1433