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