1 /* This file is part of GCC.
3 GCC is free software; you can redistribute it and/or modify it under
4 the terms of the GNU General Public License as published by the Free
5 Software Foundation; either version 3, or (at your option) any later
8 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
9 WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 You should have received a copy of the GNU General Public License
14 along with GCC; see the file COPYING3. If not see
15 <http://www.gnu.org/licenses/>. */
20 #define DOT_CURRENT_CONTEXT(x_) \
21 VEC_index (dot_contextEntry_t, x_, VEC_length (x_) - 1)
24 static tree moduleInit
= NULL_TREE
;
27 static tree
dot_pass_genFndecl_Basic (tree
, tree
);
29 static tree
dot_pass_getModuleType (const char *, gpy_hash_tab_t
*);
30 static void dot_pass_setupContext (tree
, dot_contextTable_t
, vec
<tree
,va_gc
> *, tree
*);
31 static void dot_pass_generic_TU (gpy_hash_tab_t
*, vec
<gpydot
,va_gc
> *, vec
<tree
,va_gc
> *);
33 static tree
dot_pass_genFindAddr (const char *, const char *, vec
<tree
,va_gc
> *);
34 static void dot_pass_genWalkClass (tree
*, tree
, tree
, vec
<tree
,va_gc
> *);
35 static void dot_pass_setupClassFieldContext (tree
, tree
, dot_contextEntry_t
);
37 static tree
dot_pass_lookupDecl (dot_contextTable_t
, const char *);
38 static int dot_pass_pushDecl (tree
, const char *, dot_contextEntry_t
);
40 static tree
dot_pass_genFunction (gpy_dot_tree_t
*, dot_contextTable_t
, const char *);
41 static vec
<tree
,va_gc
> * dot_pass_genClass (gpy_dot_tree_t
*, dot_contextTable_t
, tree
, const char *);
43 static tree
dot_pass_genScalar (gpy_dot_tree_t
*, tree
*);
44 static tree
dot_pass_genEnclosure (gpy_dot_tree_t
*, tree
*, dot_contextTable_t
);
45 static void dot_pass_genCBlock (gpy_dot_tree_t
*, tree
*, dot_contextTable_t
, tree
, tree
);
47 static tree
dot_pass_lowerExpr (gpy_dot_tree_t
*, dot_contextTable_t
, tree
*);
48 static void dot_pass_genPrintStmt (gpy_dot_tree_t
* , tree
*, dot_contextTable_t
);
49 static void dot_pass_genReturnStmt (gpy_dot_tree_t
* , tree
*, dot_contextTable_t
);
50 static tree
dot_pass_genModifyExpr (gpy_dot_tree_t
*, tree
*, dot_contextTable_t
);
51 static tree
dot_pass_genBinExpr (gpy_dot_tree_t
*, tree
*, dot_contextTable_t
);
53 static void dot_pass_genConditional (gpy_dot_tree_t
*, tree
*, dot_contextTable_t
);
54 static void dot_pass_genWhile (gpy_dot_tree_t
*, tree
*, dot_contextTable_t
);
55 static void dot_pass_genFor (gpy_dot_tree_t
*, tree
*, dot_contextTable_t
);
56 static void dot_pass_genImport (gpy_dot_tree_t
*, tree
*, dot_contextTable_t
);
57 static void dot_pass_genSuite (gpy_dot_tree_t
* , tree
*, dot_contextTable_t
);
61 tree
dot_pass_genFndecl_Basic (tree ident
, tree fntype
)
63 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
, ident
, fntype
);
65 TREE_STATIC (fndecl
) = 0;
66 TREE_USED (fndecl
) = 1;
67 DECL_ARTIFICIAL (fndecl
) = 1;
68 TREE_PUBLIC (fndecl
) = 1;
70 tree argslist
= NULL_TREE
;
71 DECL_ARGUMENTS (fndecl
) = argslist
;
72 /* Define the return type (represented by RESULT_DECL) for the main functin */
73 tree resdecl
= build_decl (BUILTINS_LOCATION
, RESULT_DECL
,
74 NULL_TREE
, TREE_TYPE (fntype
));
75 DECL_CONTEXT (resdecl
) = fndecl
;
76 DECL_ARTIFICIAL (resdecl
) = true;
77 DECL_IGNORED_P (resdecl
) = true;
78 DECL_RESULT (fndecl
) = resdecl
;
80 if (DECL_STRUCT_FUNCTION(fndecl
) == NULL
)
81 push_struct_function(fndecl
);
83 push_cfun(DECL_STRUCT_FUNCTION(fndecl
));
89 tree
dot_pass_getModuleType (const char * s
,
90 gpy_hash_tab_t
* modules
)
92 tree retval
= error_mark_node
;
94 gpy_hashval_t h
= gpy_dd_hash_string (s
);
95 gpy_hash_entry_t
* e
= gpy_dd_hash_lookup_table (modules
, h
);
99 retval
= (tree
) e
->data
;
105 void dot_pass_setupClassFieldContext (tree type
, tree self
,
106 dot_contextEntry_t context
)
108 tree field
= NULL_TREE
;
109 for (field
= TYPE_FIELDS (type
); field
!= NULL_TREE
;
110 field
= DECL_CHAIN (field
))
112 const char * ident
= IDENTIFIER_POINTER (DECL_NAME (field
));
113 tree ref
= build3 (COMPONENT_REF
, TREE_TYPE (field
),
114 build_fold_indirect_ref (self
),
116 gcc_assert (dot_pass_pushDecl (ref
, ident
, context
));
121 tree
dot_pass_genFindAddr (const char * id
,
122 const char * parent_ident
,
123 vec
<tree
,va_gc
> * decls
)
125 tree retval
= null_pointer_node
;
126 tree ident
= dot_pass_concat_identifier (parent_ident
, id
);
127 const char * search
= IDENTIFIER_POINTER (ident
);
130 tree decl
= NULL_TREE
;
131 for (idx
= 0; decls
->iterate (idx
, &decl
); ++idx
)
133 tree decl_name
= DECL_NAME (decl
);
134 if (!strcmp (search
, IDENTIFIER_POINTER (decl_name
)))
144 void dot_pass_genWalkClass (tree
* block
, tree type
,
146 vec
<tree
,va_gc
> * ldecls
)
148 const char * type_name
= IDENTIFIER_POINTER (TYPE_NAME (type
));
149 vec
<tree
,va_gc
> * attribs
;
150 vec_alloc (attribs
, 0);
152 tree field
= NULL_TREE
;
154 for (field
= TYPE_FIELDS (type
); field
!= NULL_TREE
;
155 field
= DECL_CHAIN (field
))
157 const char * ident
= IDENTIFIER_POINTER (DECL_NAME (field
));
158 tree element_size
= TYPE_SIZE_UNIT (TREE_TYPE (field
));
159 tree offs
= fold_build2_loc (UNKNOWN_LOCATION
, MULT_EXPR
, sizetype
,
160 build_int_cst (sizetype
, offset
),
162 tree str
= gpy_dot_type_const_string_tree (ident
);
163 tree fnaddr
= dot_pass_genFindAddr (ident
, type_name
, ldecls
);
165 tree fnaddr_tmp
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
166 create_tmp_var_name ("FNAD"),
168 tree arguments
= NULL_TREE
;
170 if (fnaddr
!= null_pointer_node
)
172 gcc_assert (TREE_CODE (fnaddr
) == FUNCTION_DECL
);
173 arguments
= DECL_ARGUMENTS (fnaddr
);
175 for (args
= arguments
; args
!= NULL_TREE
;
176 args
= DECL_CHAIN (args
))
178 append_to_statement_list (build2 (MODIFY_EXPR
, ptr_type_node
,
180 build_fold_addr_expr (fnaddr
)),
184 append_to_statement_list (build2 (MODIFY_EXPR
, ptr_type_node
,
186 build_int_cst (ptr_type_node
, 0)),
189 tree nargs
= build_int_cst (integer_type_node
, n
);
190 tree atdecl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
191 create_tmp_var_name ("AT"),
192 gpy_attrib_type_ptr
);
193 tree a
= GPY_RR_fold_attrib (build_fold_addr_expr (str
),
196 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
199 vec_safe_push (attribs
, atdecl
);
202 vec
<tree
,va_gc
> * args
;
204 vec_safe_push (args
, build_int_cst (integer_type_node
,
205 attribs
->length ()));
206 GPY_VEC_stmts_append (tree
, args
, attribs
);
208 tree attribs_decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
209 create_tmp_var_name ("AL"),
210 gpy_attrib_type_ptr_ptr
);
211 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_attrib_type_ptr_ptr
,
213 GPY_RR_fold_attrib_list (args
)),
215 tree class_str
= gpy_dot_type_const_string_tree (type_name
);
216 tree fold_class
= GPY_RR_fold_class_decl (attribs_decl
, TYPE_SIZE_UNIT (type
),
217 build_fold_addr_expr (class_str
));
219 switch (TREE_CODE (decl
))
221 case POINTER_PLUS_EXPR
:
223 tree fold
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
224 create_tmp_var_name ("__MOD_DECL_ACC"),
225 gpy_object_type_ptr_ptr
);
226 append_to_statement_list (build2 (MODIFY_EXPR
,
227 gpy_object_type_ptr_ptr
,
231 tree class_tmp
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
232 create_tmp_var_name ("ATFC"),
233 gpy_object_type_ptr
);
234 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
235 class_tmp
, fold_class
),
237 tree refer
= build_fold_indirect_ref (fold
);
238 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
246 fatal_error ("Error seting up class decl!\n");
252 tree
dot_pass_foldCIDS (int len
, char ** cids
)
254 tree fntype
= build_function_type_list (ptr_type_node
,
258 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
259 get_identifier ("gpy_rr_modAttribList"),
261 tree restype
= TREE_TYPE (fndecl
);
262 tree resdecl
= build_decl (BUILTINS_LOCATION
, RESULT_DECL
, NULL_TREE
,
264 DECL_CONTEXT (resdecl
) = fndecl
;
265 DECL_RESULT (fndecl
) = resdecl
;
266 DECL_EXTERNAL (fndecl
) = 1;
267 TREE_PUBLIC (fndecl
) = 1;
270 vec
<tree
,va_gc
> *args
;
273 vec_safe_push (args
, build_int_cst (integer_type_node
, len
));
274 for (i
= 0; i
< len
; ++i
)
276 char * id
= cids
[i
];
277 tree tid
= gpy_dot_type_const_string_tree (id
);
278 vec_safe_push (args
, build_fold_addr_expr (tid
));
280 return build_call_expr_loc_vec (BUILTINS_LOCATION
, fndecl
, args
);
284 void dot_pass_setupContext (tree module
,
285 dot_contextTable_t context
,
286 vec
<tree
,va_gc
> * generic
,
289 dot_contextEntry_t globls
= VEC_index (dot_contextEntry_t
, context
, 0);
290 dot_contextEntry_t globls_symbols
= VEC_index (dot_contextEntry_t
, context
, 1);
292 tree stack_pointer
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
293 get_identifier (GPY_RR_stack_ptr
),
294 gpy_object_type_ptr_ptr
);
295 TREE_PUBLIC (stack_pointer
) = 1;
296 TREE_USED (stack_pointer
) = 1;
297 DECL_EXTERNAL (stack_pointer
) = 1;
299 DECL_INITIAL (stack_pointer
) = build_int_cst (integer_type_node
, 0);
300 rest_of_decl_compilation (stack_pointer
, 1, 0);
302 gpy_dd_hash_insert (gpy_dd_hash_string (GPY_RR_stack_ptr
), stack_pointer
, globls
);
303 vec_safe_push (generic
, stack_pointer
);
305 int offset
= 0, field_count
= 0;
307 for (field
= TYPE_FIELDS (module
); field
!= NULL_TREE
;
308 field
= DECL_CHAIN (field
))
311 char ** cids
= (char **) xcalloc (field_count
, sizeof (char *));
312 memset (cids
, 0, sizeof (char *)*field_count
);
315 for (field
= TYPE_FIELDS (module
); field
!= NULL_TREE
;
316 field
= DECL_CHAIN (field
))
318 gcc_assert (TREE_CODE (field
) == FIELD_DECL
);
319 const char * ident
= IDENTIFIER_POINTER (DECL_NAME (field
));
321 cids
[i
] = xstrdup (ident
);
325 tree fcids
= dot_pass_foldCIDS (field_count
, cids
);
326 tree fcids_decl
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
327 create_tmp_var_name ("FCIDS"),
329 append_to_statement_list (build2 (MODIFY_EXPR
, ptr_type_node
,
332 tree str
= gpy_dot_type_const_string_tree (GPY_current_module_name
);
333 tree stack_extendCall
= GPY_RR_extendRRStack (build_int_cst (integer_type_node
,
335 build_fold_addr_expr (str
),
338 tree stack_offset
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
339 create_tmp_var_name ("__MODULE_STK_OFFS"),
341 TREE_STATIC (stack_offset
) = 1;
342 TREE_PUBLIC (stack_offset
) = 0;
343 TREE_USED (stack_offset
) = 1;
344 DECL_INITIAL (stack_offset
) = build_int_cst (integer_type_node
, 0);
345 rest_of_decl_compilation (stack_offset
, 1, 0);
347 append_to_statement_list (build2 (MODIFY_EXPR
, integer_type_node
,
348 stack_offset
, stack_extendCall
),
353 for (field
= TYPE_FIELDS (module
); field
!= NULL_TREE
;
354 field
= DECL_CHAIN (field
))
356 gcc_assert (TREE_CODE (field
) == FIELD_DECL
);
357 const char * ident
= IDENTIFIER_POINTER (DECL_NAME (field
));
359 tree element_size
= TYPE_SIZE_UNIT (TREE_TYPE (field
));
361 tree offs1
= build2 (MULT_EXPR
, sizetype
,
362 build_int_cst (sizetype
, offset
),
364 tree offs2
= build2 (MULT_EXPR
, sizetype
,
368 tree offs
= build2 (PLUS_EXPR
, sizetype
,
370 tree addr
= build2 (POINTER_PLUS_EXPR
,
371 TREE_TYPE (stack_pointer
),
372 stack_pointer
, offs
);
374 gcc_assert (dot_pass_pushDecl (addr
, ident
, globls_symbols
));
379 // the module_init shizzle!
380 moduleInit
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
381 get_identifier ("__MOD_INIT_CHK"),
383 TREE_STATIC (moduleInit
) = 1;
384 TREE_PUBLIC (moduleInit
) = 0;
385 TREE_USED (moduleInit
) = 1;
386 DECL_INITIAL(moduleInit
) = boolean_false_node
;
387 rest_of_decl_compilation (moduleInit
, 1, 0);
391 int dot_pass_pushDecl (tree decl
, const char * ident
,
392 dot_contextEntry_t context
)
395 gpy_hashval_t h
= gpy_dd_hash_string (ident
);
396 void ** slot
= gpy_dd_hash_insert (h
, decl
, context
);
399 error ("error pushing decl <%s>!\n", ident
);
406 tree
dot_pass_lookupDecl (dot_contextTable_t context
,
407 const char * identifier
)
409 tree retval
= error_mark_node
;
410 gpy_hashval_t h
= gpy_dd_hash_string (identifier
);
411 int length
= VEC_length (context
);
414 for (i
= length
- 1; i
>= 0; --i
)
416 dot_contextEntry_t ctx
= VEC_index (dot_contextEntry_t
, context
, i
);
417 gpy_hash_entry_t
* o
= NULL
;
418 o
= gpy_dd_hash_lookup_table (ctx
, h
);
423 retval
= (tree
) o
->data
;
431 tree
dot_pass_genScalar (gpy_dot_tree_t
* decl
, tree
* block
)
433 tree retval
= error_mark_node
;
435 gcc_assert (DOT_TYPE (decl
) == D_PRIMITIVE
);
436 gcc_assert (DOT_lhs_T (decl
) == D_TD_COM
);
438 switch (DOT_lhs_TC (decl
)->T
)
442 retval
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
443 create_tmp_var_name ("PI"),
444 gpy_object_type_ptr
);
445 tree fold_call
= GPY_RR_fold_integer (build_int_cst (integer_type_node
,
446 DOT_lhs_TC (decl
)->o
.integer
));
447 append_to_statement_list (build2 (MODIFY_EXPR
,
456 retval
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
457 create_tmp_var_name ("PI"),
458 gpy_object_type_ptr
);
459 tree fstr
= gpy_dot_type_const_string_tree (DOT_lhs_TC (decl
)->o
.string
);
460 tree fold_call
= GPY_RR_fold_string (build_fold_addr_expr (fstr
));
461 append_to_statement_list (build2 (MODIFY_EXPR
,
469 error ("invalid scalar type!\n");
477 tree
dot_pass_genEnclosure (gpy_dot_tree_t
* decl
,
479 dot_contextTable_t context
)
481 tree retval
= error_mark_node
;
482 gcc_assert (DOT_TYPE (decl
) == D_T_LIST
);
484 gpy_dot_tree_t
* node
;
486 for (node
= DOT_lhs_TT (decl
); node
!= NULL_DOT
;
487 node
= DOT_CHAIN (node
))
490 vec
<tree
,va_gc
> * elms
;
492 vec_safe_push (elms
, build_int_cst (integer_type_node
, length
));
493 for (node
= DOT_lhs_TT (decl
); node
!= NULL_DOT
;
494 node
= DOT_CHAIN (node
))
496 tree tmp
= dot_pass_lowerExpr (node
, context
, block
);
497 vec_safe_push (elms
, tmp
);
499 retval
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
500 create_tmp_var_name ("PL"),
501 gpy_object_type_ptr
);
502 tree fold_call
= GPY_RR_fold_encList (elms
);
503 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
510 void dot_pass_genSuite (gpy_dot_tree_t
* decl
,
512 dot_contextTable_t context
)
514 gpy_hash_tab_t suite
;
515 gpy_dd_hash_init_table (&suite
);
517 gpy_vec_push (context
, &suite
);
519 gpy_dot_tree_t
* node
;
520 for (node
= decl
; node
!= NULL_DOT
;
521 node
= DOT_CHAIN (node
))
523 if (DOT_T_FIELD (node
) == D_D_EXPR
)
525 dot_pass_lowerExpr (node
, context
, block
);
528 switch (DOT_TYPE (node
))
531 dot_pass_genPrintStmt (node
, block
, context
);
535 dot_pass_genReturnStmt (node
, block
, context
);
538 case D_STRUCT_CONDITIONAL
:
539 dot_pass_genConditional (node
, block
, context
);
543 dot_pass_genWhile (node
, block
, context
);
547 dot_pass_genFor (node
, block
, context
);
551 error ("unhandled syntax within suite");
556 gpy_vec_pop (context
);
560 void dot_pass_genCBlock (gpy_dot_tree_t
* decl
,
562 dot_contextTable_t context
,
563 tree cval
, tree endif
)
565 gpy_dot_tree_t
* suite
= NULL_DOT
;
566 tree ifcval
= error_mark_node
;
567 if (DOT_TYPE (decl
) == D_STRUCT_IF
568 || DOT_TYPE (decl
) == D_STRUCT_ELIF
)
570 gpy_dot_tree_t
* expr
= DOT_lhs_TT (decl
);
571 tree val
= dot_pass_lowerExpr (expr
, context
, block
);
573 if (TREE_TYPE (lval
) == gpy_object_type_ptr_ptr
)
575 lval
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
576 create_tmp_var_name ("CDRD"),
577 gpy_object_type_ptr
);
578 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
579 lval
, build_fold_indirect_ref (val
)),
582 tree fold
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
583 create_tmp_var_name ("COND"),
585 append_to_statement_list (build2 (MODIFY_EXPR
, boolean_type_node
,
586 fold
, GPY_RR_eval_boolean (lval
)),
589 suite
= DOT_rhs_TT (decl
);
593 gcc_assert (DOT_TYPE (decl
) == D_STRUCT_ELSE
);
594 suite
= DOT_lhs_TT (decl
);
597 tree label_decl
= build_decl (UNKNOWN_LOCATION
, LABEL_DECL
,
598 create_tmp_var_name ("LBIF"),
600 tree label_expr
= fold_build1_loc (UNKNOWN_LOCATION
, LABEL_EXPR
,
601 void_type_node
, label_decl
);
603 tree label_exit_decl
= build_decl (UNKNOWN_LOCATION
, LABEL_DECL
,
604 create_tmp_var_name ("LBFI"),
606 tree label_exit_expr
= fold_build1_loc (UNKNOWN_LOCATION
, LABEL_EXPR
,
607 void_type_node
, label_exit_decl
);
609 DECL_CONTEXT (label_decl
) = current_function_decl
;
610 DECL_CONTEXT (label_exit_decl
) = current_function_decl
;
614 if (ifcval
!= error_mark_node
)
617 evalto
= boolean_true_node
;
622 evalto
= boolean_false_node
;
624 tree conditional
= fold_build2_loc (UNKNOWN_LOCATION
, EQ_EXPR
,
628 tree cond
= build3_loc (UNKNOWN_LOCATION
, COND_EXPR
, void_type_node
,
630 build1 (GOTO_EXPR
, void_type_node
, label_decl
),
631 build1 (GOTO_EXPR
, void_type_node
, label_exit_decl
));
633 append_to_statement_list (cond
, block
);
634 append_to_statement_list (label_expr
, block
);
636 dot_pass_genSuite (suite
, block
, context
);
638 append_to_statement_list (build2 (MODIFY_EXPR
, boolean_type_node
,
639 cval
, boolean_true_node
),
641 append_to_statement_list (build1 (GOTO_EXPR
, void_type_node
, endif
),
643 append_to_statement_list (label_exit_expr
, block
);
648 void dot_pass_genImport (gpy_dot_tree_t
* decl
,
650 dot_contextTable_t context
)
652 const char * import
= DOT_IDENTIFIER_POINTER (DOT_lhs_TT (decl
));
653 tree lookup
= dot_pass_lookupDecl (context
, import
);
654 gcc_assert (lookup
!= error_mark_node
);
656 struct gpy_dataExport
* exp
= gpy_readExportData (import
);
658 error ("No export data for module <%s>\n", import
);
661 if (GPY_OPT_gen_main
&& exp
->main
)
662 error ("Module %s already has main!\n", import
);
664 // ... setup runtime to call module entry...
666 tree ident
= get_identifier (exp
->entry
);
668 tree fntype
= build_function_type_list (void_type_node
, NULL_TREE
);
669 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
671 tree restype
= TREE_TYPE (fndecl
);
672 tree resdecl
= build_decl (BUILTINS_LOCATION
, RESULT_DECL
, NULL_TREE
,
674 DECL_CONTEXT (resdecl
) = fndecl
;
675 DECL_RESULT (fndecl
) = resdecl
;
676 DECL_EXTERNAL (fndecl
) = 1;
677 TREE_PUBLIC (fndecl
) = 1;
678 append_to_statement_list (build_call_expr (fndecl
, 0), block
);
680 tree tstr
= gpy_dot_type_const_string_tree (import
);
681 tree imp
= GPY_RR_foldImport (decl
, build_fold_addr_expr (tstr
));
682 append_to_statement_list (imp
, block
);
687 void dot_pass_genFor (gpy_dot_tree_t
* decl
,
689 dot_contextTable_t context
)
691 debug ("Trying to compile the for loop!\n");
693 /* gpy_dot_tree_t * it = DOT_FIELD (decl);
694 gpy_dot_tree_t * in = DOT_lhs_TT (decl);
695 gpy_dot_tree_t * suite = DOT_rhs (decl);*/
697 fatal_error ("For loops/iterators not implemented yet!\n");
702 void dot_pass_genWhile (gpy_dot_tree_t
* decl
,
704 dot_contextTable_t context
)
706 tree label_decl
= build_decl (UNKNOWN_LOCATION
, LABEL_DECL
,
707 create_tmp_var_name ("WHLIF"),
709 tree label_expr
= fold_build1_loc (UNKNOWN_LOCATION
, LABEL_EXPR
,
710 void_type_node
, label_decl
);
712 tree label_exit_decl
= build_decl (UNKNOWN_LOCATION
, LABEL_DECL
,
713 create_tmp_var_name ("WHLFI"),
715 tree label_exit_expr
= fold_build1_loc (UNKNOWN_LOCATION
, LABEL_EXPR
,
716 void_type_node
, label_exit_decl
);
718 DECL_CONTEXT (label_decl
) = current_function_decl
;
719 DECL_CONTEXT (label_exit_decl
) = current_function_decl
;
721 append_to_statement_list (label_expr
, block
);
723 gpy_dot_tree_t
* expr
= DOT_lhs_TT (decl
);
724 tree val
= dot_pass_lowerExpr (expr
, context
, block
);
726 if (TREE_TYPE (lval
) == gpy_object_type_ptr_ptr
)
728 lval
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
729 create_tmp_var_name ("CDRD"),
730 gpy_object_type_ptr
);
731 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
732 lval
, build_fold_indirect_ref (val
)),
735 tree fold
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
736 create_tmp_var_name ("COND"),
740 append_to_statement_list (build2 (MODIFY_EXPR
, boolean_type_node
,
741 fold
, GPY_RR_eval_boolean (lval
)),
744 gpy_dot_tree_t
* suite
= DOT_rhs_TT (decl
);
746 tree conditional
= fold_build2_loc (UNKNOWN_LOCATION
, EQ_EXPR
,
748 fold
, boolean_true_node
);
749 tree cond
= build3_loc (UNKNOWN_LOCATION
, COND_EXPR
, void_type_node
,
752 build1 (GOTO_EXPR
, void_type_node
, label_exit_decl
));
754 append_to_statement_list (cond
, block
);
755 dot_pass_genSuite (suite
, block
, context
);
756 append_to_statement_list (build1 (GOTO_EXPR
, void_type_node
, label_decl
),
758 append_to_statement_list (label_exit_expr
, block
);
762 void dot_pass_genConditional (gpy_dot_tree_t
* decl
,
764 dot_contextTable_t context
)
766 tree cval
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
767 create_tmp_var_name ("CELSE"),
769 DECL_INITIAL (cval
) = boolean_false_node
;
770 append_to_statement_list (cval
, block
);
773 Make each conditional block exit out of the whole thing properly
775 tree endif_label_decl
= build_decl (UNKNOWN_LOCATION
, LABEL_DECL
,
776 create_tmp_var_name ("ENDIF"),
778 tree endif_label_expr
= fold_build1_loc (UNKNOWN_LOCATION
, LABEL_EXPR
,
779 void_type_node
, endif_label_decl
);
780 DECL_CONTEXT (endif_label_decl
) = current_function_decl
;
782 gpy_dot_tree_t
* ifblock
= DOT_FIELD (decl
);
783 gpy_dot_tree_t
* elifchain
= DOT_lhs_TT (decl
);
784 gpy_dot_tree_t
* elseblock
= DOT_rhs_TT (decl
);
786 dot_pass_genCBlock (ifblock
, block
, context
, cval
, endif_label_decl
);
788 gpy_dot_tree_t
* elifnode
;
789 for (elifnode
= elifchain
; elifnode
!= NULL_DOT
;
790 elifnode
= DOT_CHAIN (elifnode
))
791 dot_pass_genCBlock (elifnode
, block
, context
, cval
, endif_label_decl
);
794 dot_pass_genCBlock (elseblock
, block
, context
, cval
, endif_label_decl
);
796 append_to_statement_list (endif_label_expr
, block
);
800 tree
dot_pass_genModifyExpr (gpy_dot_tree_t
* decl
,
802 dot_contextTable_t context
)
804 tree retval
= error_mark_node
;
805 gpy_dot_tree_t
* lhs
= DOT_lhs_TT (decl
);
806 gpy_dot_tree_t
* rhs
= DOT_rhs_TT (decl
);
809 We dont handle full target lists yet
810 all targets are in the lhs tree.
812 To implment a target list such as:
815 The lhs should be a DOT_CHAIN of identifiers!
816 So we just iterate over them and deal with it as such!
819 switch (DOT_TYPE (lhs
))
823 tree addr
= dot_pass_lookupDecl (context
,
824 DOT_IDENTIFIER_POINTER (lhs
));
825 /* means id isn't previously declared and we can just make it locally. */
826 if (addr
== error_mark_node
)
828 dot_contextEntry_t current_context
= DOT_CURRENT_CONTEXT (context
);
829 addr
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
830 get_identifier (DOT_IDENTIFIER_POINTER (lhs
)),
831 gpy_object_type_ptr
);
832 gcc_assert (dot_pass_pushDecl (addr
, DOT_IDENTIFIER_POINTER (lhs
), current_context
));
834 tree addr_rhs_tree
= dot_pass_lowerExpr (rhs
, context
, block
);
836 switch (TREE_CODE (addr
))
838 case POINTER_PLUS_EXPR
:
840 tree fold
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
841 create_tmp_var_name ("__MOD_DECL_ACC"),
842 gpy_object_type_ptr_ptr
);
843 append_to_statement_list (build2 (MODIFY_EXPR
,
844 gpy_object_type_ptr_ptr
,
848 tree refer
= build_fold_indirect_ref (fold
);
849 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
861 if (TREE_TYPE (addr
) == gpy_object_type_ptr_ptr
)
864 tree refer
= build_fold_indirect_ref (addr
);
865 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
873 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
883 error ("unhandled shizzle!\n");
891 tree addr_rhs_tree
= dot_pass_lowerExpr (rhs
, context
, block
);
892 tree addr_lhs_tree
= dot_pass_lowerExpr (lhs
, context
, block
);
894 gcc_assert (TREE_TYPE (addr_lhs_tree
) == gpy_object_type_ptr_ptr
);
895 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr_ptr
,
896 build_fold_indirect_ref (addr_lhs_tree
),
899 retval
= addr_lhs_tree
;
905 tree addr_rhs_tree
= dot_pass_lowerExpr (rhs
, context
, block
);
906 gcc_assert (TREE_TYPE (addr_rhs_tree
) == gpy_object_type_ptr
);
908 tree ident
= dot_pass_lowerExpr (DOT_lhs_TT (lhs
), context
, block
);
909 tree slice
= dot_pass_lowerExpr (DOT_rhs_TT (lhs
), context
, block
);
911 tree sla
= GPY_RR_makeRefSlice (ident
, slice
);
912 gcc_assert (TREE_TYPE (sla
) == gpy_object_type_ptr_ptr
);
914 tree tmp
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
915 create_tmp_var_name ("MSLA"),
916 gpy_object_type_ptr_ptr
);
917 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr_ptr
,
920 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr_ptr
,
921 build_fold_indirect_ref (tmp
), addr_rhs_tree
),
928 error ("unhandled target or target list in modify expression\n");
936 tree
dot_pass_cleanRef (tree decl
, tree
* block
)
939 if (TREE_TYPE (decl
) == gpy_object_type_ptr_ptr
)
941 tree fold
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
942 create_tmp_var_name ("CLRF"),
943 gpy_object_type_ptr
);
944 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
945 fold
, build_fold_indirect_ref (decl
)),
953 tree
dot_pass_genBinExpr (gpy_dot_tree_t
* decl
, tree
* block
,
954 dot_contextTable_t context
)
956 tree retval
= error_mark_node
;
957 gcc_assert (DOT_T_FIELD (decl
) == D_D_EXPR
);
959 gpy_dot_tree_t
* lhs
= DOT_lhs_TT (decl
);
960 gpy_dot_tree_t
* rhs
= DOT_rhs_TT (decl
);
961 tree lhs_eval
= dot_pass_lowerExpr (lhs
, context
, block
);
962 tree rhs_eval
= dot_pass_lowerExpr (rhs
, context
, block
);
964 lhs_eval
= dot_pass_cleanRef (lhs_eval
, block
);
965 rhs_eval
= dot_pass_cleanRef (rhs_eval
, block
);
967 tree op
= error_mark_node
;
968 switch (DOT_TYPE (decl
))
970 // @see libgpython/runtime/gpy-module-stack.c::gpy_rr_eval_expression
972 op
= GPY_RR_eval_expression (lhs_eval
, rhs_eval
,
973 build_int_cst (integer_type_node
, 1));
977 op
= GPY_RR_eval_expression (lhs_eval
, rhs_eval
,
978 build_int_cst (integer_type_node
, 2));
982 op
= GPY_RR_eval_expression (lhs_eval
, rhs_eval
,
983 build_int_cst (integer_type_node
, 4));
987 op
= GPY_RR_eval_expression (lhs_eval
, rhs_eval
,
988 build_int_cst (integer_type_node
, 6));
992 op
= GPY_RR_eval_expression (lhs_eval
, rhs_eval
,
993 build_int_cst (integer_type_node
, 8));
997 op
= GPY_RR_eval_expression (lhs_eval
, rhs_eval
,
998 build_int_cst (integer_type_node
, 10));
1002 op
= GPY_RR_eval_expression (lhs_eval
, rhs_eval
,
1003 build_int_cst (integer_type_node
, 11));
1007 error ("unhandled binary operation type!\n");
1010 gcc_assert (op
!= error_mark_node
);
1012 tree retaddr
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1013 create_tmp_var_name ("T"),
1014 gpy_object_type_ptr
);
1015 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
1023 void dot_pass_genReturnStmt (gpy_dot_tree_t
* decl
, tree
* block
,
1024 dot_contextTable_t context
)
1026 /* Remember we have have return x or we can simply just have a return */
1027 if (DOT_lhs_TT (decl
))
1029 tree lexpr
= dot_pass_lowerExpr (DOT_lhs_TT (decl
), context
, block
);
1031 if (TREE_TYPE (tmp
) == gpy_object_type_ptr_ptr
)
1033 tmp
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1034 create_tmp_var_name ("ATAR"),
1035 gpy_object_type_ptr
);
1036 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
1038 build_fold_indirect_ref (lexpr
)),
1041 append_to_statement_list (GPY_RR_eval_return (tmp
), block
);
1043 append_to_statement_list (fold_build1_loc (UNKNOWN_LOCATION
, RETURN_EXPR
,
1044 void_type_node
, NULL_TREE
),
1049 void dot_pass_genPrintStmt (gpy_dot_tree_t
* decl
, tree
* block
,
1050 dot_contextTable_t context
)
1052 gpy_dot_tree_t
* arguments
= decl
->opa
.t
;
1054 vec
<tree
,va_gc
> * callvec_tmp
;
1055 vec_alloc (callvec_tmp
, 0);
1057 gpy_dot_tree_t
* it
= NULL
;
1058 for (it
= arguments
; it
!= NULL
; it
= DOT_CHAIN (it
))
1060 tree lexpr
= dot_pass_lowerExpr (it
, context
, block
);
1062 if (TREE_TYPE (lexpr
) == gpy_object_type_ptr_ptr
)
1065 tmp
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1066 create_tmp_var_name ("ATAR"),
1067 gpy_object_type_ptr
);
1068 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
1070 build_fold_indirect_ref (lexpr
)),
1073 vec_safe_push (callvec_tmp
, tmp
);
1075 vec
<tree
,va_gc
> * callvec
;
1076 vec_alloc (callvec
, 0);
1077 vec_safe_push (callvec
, build_int_cst (integer_type_node
, 1));
1078 vec_safe_push (callvec
, build_int_cst (integer_type_node
, callvec_tmp
->length ()));
1080 GPY_VEC_stmts_append (tree
, callvec
, callvec_tmp
);
1081 append_to_statement_list (GPY_RR_eval_print (callvec
), block
);
1085 tree
dot_pass_lowerExpr (gpy_dot_tree_t
* dot
,
1086 dot_contextTable_t context
,
1089 tree retval
= error_mark_node
;
1090 switch (DOT_TYPE (dot
))
1093 retval
= dot_pass_genScalar (dot
, block
);
1097 retval
= dot_pass_genEnclosure (dot
, block
, context
);
1102 tree ident
= dot_pass_lowerExpr (DOT_lhs_TT (dot
), context
, block
);
1103 tree slice
= dot_pass_lowerExpr (DOT_rhs_TT (dot
), context
, block
);
1105 tree sla
= GPY_RR_makeSlice (ident
, slice
);
1106 tree tmp
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1107 create_tmp_var_name ("SLA"),
1108 gpy_object_type_ptr
);
1109 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
1118 tree lookup
= dot_pass_lookupDecl (context
,
1119 DOT_IDENTIFIER_POINTER (dot
));
1121 //debug ("IDENT lExpr lookup %s!\n", DOT_IDENTIFIER_POINTER (dot));
1122 //gcc_assert (lookup != error_mark_node);
1123 if (lookup
== error_mark_node
)
1124 fatal_error ("Identifier <%s> was not found in this scope\n",
1125 DOT_IDENTIFIER_POINTER (dot
));
1127 switch (TREE_CODE (lookup
))
1137 tree tmp
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1138 create_tmp_var_name ("VA"),
1139 gpy_object_type_ptr_ptr
);
1140 append_to_statement_list (build2 (MODIFY_EXPR
,
1141 gpy_object_type_ptr_ptr
,
1144 tree atmp
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1145 create_tmp_var_name ("VP"),
1146 gpy_object_type_ptr
);
1147 append_to_statement_list (build2 (MODIFY_EXPR
,
1148 gpy_object_type_ptr
,
1149 atmp
, build_fold_indirect_ref (tmp
)),
1160 tree addr_1
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1161 create_tmp_var_name ("ATRD"),
1162 gpy_object_type_ptr_ptr
);
1163 gpy_dot_tree_t
* xlhs
= DOT_lhs_TT (dot
);
1164 gpy_dot_tree_t
* xrhs
= DOT_rhs_TT (dot
);
1166 gcc_assert (DOT_TYPE (xrhs
) == D_IDENTIFIER
);
1167 tree lhs_tree
= dot_pass_lowerExpr (xlhs
, context
, block
);
1168 const char * attrib_ident
= DOT_IDENTIFIER_POINTER (xrhs
);
1170 tree str
= gpy_dot_type_const_string_tree (attrib_ident
);
1171 tree lhs_tree_fold
= lhs_tree
;
1172 if (TREE_TYPE (lhs_tree
) == gpy_object_type_ptr_ptr
)
1174 lhs_tree_fold
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1175 create_tmp_var_name ("ATRDF"),
1176 gpy_object_type_ptr
);
1177 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
1179 build_fold_indirect_ref (lhs_tree
)),
1182 tree attrib_ref
= build2 (MODIFY_EXPR
, gpy_object_type_ptr_ptr
, addr_1
,
1183 GPY_RR_fold_attrib_ref (lhs_tree_fold
,
1184 build_fold_addr_expr (str
))
1186 append_to_statement_list (attrib_ref
, block
);
1193 gpy_dot_tree_t
* callid
= DOT_lhs_TT (dot
);
1195 tree lcall_decl
= dot_pass_lowerExpr (callid
, context
, block
);
1196 tree call_decl
= lcall_decl
;
1197 if (TREE_TYPE (lcall_decl
) == gpy_object_type_ptr_ptr
)
1200 call_decl
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1201 create_tmp_var_name ("ATAR"),
1202 gpy_object_type_ptr
);
1203 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
1205 build_fold_indirect_ref (lcall_decl
)),
1209 gpy_dot_tree_t
* argslist
;
1210 vec
<tree
,va_gc
> * argsvec
= NULL
;
1211 if (DOT_TYPE (callid
) == D_ATTRIB_REF
)
1213 tree basetree
= dot_pass_lowerExpr (DOT_lhs_TT (callid
),
1215 tree basetree_fold
= basetree
;
1216 if (TREE_TYPE (basetree
) == gpy_object_type_ptr_ptr
)
1218 basetree_fold
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1219 create_tmp_var_name ("ATRDF"),
1220 gpy_object_type_ptr
);
1221 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
1223 build_fold_indirect_ref (basetree
)),
1226 vec_safe_push (argsvec
, basetree_fold
);
1230 // we push in a null entry...
1231 tree nullp
= build_int_cst (ptr_type_node
, 0);
1232 vec_safe_push (argsvec
, nullp
);
1235 for (argslist
= DOT_rhs_TT (dot
); argslist
!= NULL_DOT
;
1236 argslist
= DOT_CHAIN (argslist
))
1238 tree lexpr
= dot_pass_lowerExpr (argslist
, context
, block
);
1239 tree argument
= lexpr
;
1240 if (TREE_TYPE (argument
) == gpy_object_type_ptr_ptr
)
1242 argument
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1243 create_tmp_var_name ("ATRDF"),
1244 gpy_object_type_ptr
);
1245 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
1247 build_fold_indirect_ref (lexpr
)),
1250 vec_safe_push (argsvec
, argument
);
1252 vec
<tree
,va_gc
> * args
= NULL
;
1253 vec_alloc (args
, 0);
1254 vec_safe_push (args
, call_decl
);
1259 tmp
= argsvec
->length ();
1260 vec_safe_push (args
, build_int_cst (integer_type_node
, tmp
));
1261 GPY_VEC_stmts_append (tree
, args
, argsvec
);
1264 vec_safe_push (args
, build_int_cst (integer_type_node
, tmp
));
1266 tree retaddr
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1267 create_tmp_var_name ("RET"),
1268 gpy_object_type_ptr
);
1269 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
1271 GPY_RR_fold_call (args
)),
1279 switch (DOT_TYPE (dot
))
1282 retval
= dot_pass_genModifyExpr (dot
, block
, context
);
1290 case D_GREATER_EXPR
:
1293 /* TODO remember to add the rest of the bin ops */
1294 retval
= dot_pass_genBinExpr (dot
, block
, context
);
1298 error ("unhandled operation type!\n");
1308 vec
<tree
,va_gc
> * dot_pass_genClass (gpy_dot_tree_t
* dot
,
1309 dot_contextTable_t context
,
1313 vec
<tree
,va_gc
> * lowered_decls
;
1314 vec_alloc (lowered_decls
, 0);
1316 tree class_type_ptr
= build_pointer_type (class_type
);
1317 tree fntype
= build_function_type_list (void_type_node
,
1320 tree ident
= dot_pass_concat_identifier (GPY_current_module_name
,
1321 DOT_IDENTIFIER_POINTER (DOT_FIELD (dot
)));
1322 ident
= dot_pass_concat_identifier (IDENTIFIER_POINTER (ident
),
1324 tree fndecl
= dot_pass_genFndecl_Basic (ident
, fntype
);
1325 current_function_decl
= fndecl
;
1327 tree arglist
= NULL_TREE
;
1328 tree self_parm_decl
= build_decl (BUILTINS_LOCATION
, PARM_DECL
,
1329 get_identifier ("__object_state__"),
1331 DECL_CONTEXT (self_parm_decl
) = fndecl
;
1332 DECL_ARG_TYPE (self_parm_decl
) = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
1333 TREE_READONLY (self_parm_decl
) = 1;
1334 arglist
= chainon (arglist
, self_parm_decl
);
1335 TREE_USED (self_parm_decl
) = 1;
1336 DECL_ARGUMENTS (fndecl
) = arglist
;
1338 gpy_hash_tab_t field_type_namespace
;
1339 gpy_dd_hash_init_table (&field_type_namespace
);
1340 dot_pass_setupClassFieldContext (class_type
, self_parm_decl
, &field_type_namespace
);
1342 gpy_vec_push (context
, &field_type_namespace
);
1344 tree block
= alloc_stmt_list ();
1345 gpy_dot_tree_t
* node
;
1346 for (node
= DOT_lhs_TT (dot
); node
!= NULL_DOT
;
1347 node
= DOT_CHAIN (node
))
1349 if (DOT_T_FIELD (node
) == D_D_EXPR
)
1351 dot_pass_lowerExpr (node
, context
, &block
);
1354 switch (DOT_TYPE (node
))
1357 dot_pass_genPrintStmt (node
, &block
, context
);
1361 dot_pass_genReturnStmt (node
, &block
, context
);
1364 case D_STRUCT_WHILE
:
1365 dot_pass_genWhile (node
, &block
, context
);
1368 case D_STRUCT_METHOD
:
1370 const char * modID
= DOT_IDENTIFIER_POINTER (DOT_FIELD (dot
));
1371 const char * npid
= dot_pass_concat (pid
, modID
);
1372 tree attrib
= dot_pass_genFunction (node
, context
, npid
);
1373 vec_safe_push (lowered_decls
, attrib
);
1378 error ("unhandled syntax within class!\n");
1382 tree bind
= NULL_TREE
;
1383 tree bl
= build_block (DECL_RESULT (fndecl
), NULL_TREE
, fndecl
, NULL_TREE
);
1384 DECL_INITIAL (fndecl
) = bl
;
1387 bind
= build3 (BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
1389 TREE_SIDE_EFFECTS (bind
) = 1;
1390 /* Finalize the main function */
1391 BIND_EXPR_BODY (bind
) = block
;
1393 DECL_SAVED_TREE (fndecl
) = block
;
1395 gimplify_function_tree (fndecl
);
1396 cgraph_finalize_function (fndecl
, false);
1398 vec_safe_push (lowered_decls
, fndecl
);
1399 gpy_vec_pop (context
);
1402 return lowered_decls
;
1406 tree
dot_pass_genFunction (gpy_dot_tree_t
* dot
,
1407 dot_contextTable_t context
,
1408 const char * parentID
)
1410 /* setup next context */
1412 gpy_dd_hash_init_table (&ctx
);
1413 gpy_vec_push (context
, &ctx
);
1415 gpy_dot_tree_t
* pnode
;
1416 tree params
= NULL_TREE
;
1417 for (pnode
= DOT_lhs_TT (dot
); pnode
!= NULL_DOT
;
1418 pnode
= DOT_CHAIN (pnode
))
1419 chainon (params
, tree_cons (NULL_TREE
, gpy_object_type_ptr
, NULL_TREE
));
1420 chainon (params
, tree_cons (NULL_TREE
, void_type_node
, NULL_TREE
));
1422 tree fntype
= build_function_type_list (void_type_node
, params
);
1423 tree ident
= dot_pass_concat_identifier (parentID
,
1424 DOT_IDENTIFIER_POINTER (DOT_FIELD (dot
)));
1425 tree fndecl
= dot_pass_genFndecl_Basic (ident
, fntype
);
1426 current_function_decl
= fndecl
;
1428 tree arglist
= NULL_TREE
;
1429 for (pnode
= DOT_lhs_TT (dot
); pnode
!= NULL_DOT
;
1430 pnode
= DOT_CHAIN (pnode
))
1432 const char * parmid
= DOT_IDENTIFIER_POINTER (pnode
);
1433 tree parm_decl
= build_decl (BUILTINS_LOCATION
, PARM_DECL
,
1434 get_identifier (parmid
),
1435 gpy_object_type_ptr
);
1436 DECL_CONTEXT (parm_decl
) = fndecl
;
1437 DECL_ARG_TYPE (parm_decl
) = gpy_object_type_ptr
;
1438 TREE_READONLY (parm_decl
) = 1;
1439 arglist
= chainon (arglist
, parm_decl
);
1440 TREE_USED (parm_decl
) = 1;
1442 gcc_assert (dot_pass_pushDecl (parm_decl
, parmid
, &ctx
));
1444 DECL_ARGUMENTS (fndecl
) = arglist
;
1446 tree block
= alloc_stmt_list ();
1447 gpy_dot_tree_t
* node
;
1448 for (node
= DOT_rhs_TT (dot
); node
!= NULL_DOT
;
1449 node
= DOT_CHAIN (node
))
1451 if (DOT_T_FIELD (node
) == D_D_EXPR
)
1453 dot_pass_lowerExpr (node
, context
, &block
);
1456 switch (DOT_TYPE (node
))
1459 dot_pass_genPrintStmt (node
, &block
, context
);
1463 dot_pass_genReturnStmt (node
, &block
, context
);
1466 case D_STRUCT_CONDITIONAL
:
1467 dot_pass_genConditional (node
, &block
, context
);
1470 case D_STRUCT_WHILE
:
1471 dot_pass_genWhile (node
, &block
, context
);
1475 error ("unhandled syntax within toplevel function!\n");
1479 tree bind
= NULL_TREE
;
1480 tree bl
= build_block (DECL_RESULT (fndecl
), NULL_TREE
, fndecl
, NULL_TREE
);
1481 DECL_INITIAL (fndecl
) = bl
;
1484 bind
= build3 (BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
1486 TREE_SIDE_EFFECTS (bind
) = 1;
1487 /* Finalize the main function */
1488 BIND_EXPR_BODY (bind
) = block
;
1490 DECL_SAVED_TREE (fndecl
) = block
;
1492 gimplify_function_tree (fndecl
);
1493 cgraph_finalize_function (fndecl
, false);
1496 gpy_vec_pop (context
);
1501 void dot_pass_mainInitCheck (tree
* block
)
1503 // if we have already initilized we should just return...
1504 tree label_decl
= build_decl (UNKNOWN_LOCATION
, LABEL_DECL
,
1505 create_tmp_var_name ("LBIF"),
1507 tree label_expr
= fold_build1_loc (UNKNOWN_LOCATION
, LABEL_EXPR
,
1508 void_type_node
, label_decl
);
1510 tree endif_label_decl
= build_decl (UNKNOWN_LOCATION
, LABEL_DECL
,
1511 create_tmp_var_name ("ENDIF"),
1513 tree endif_label_expr
= fold_build1_loc (UNKNOWN_LOCATION
, LABEL_EXPR
,
1514 void_type_node
, endif_label_decl
);
1515 DECL_CONTEXT (endif_label_decl
) = current_function_decl
;
1516 DECL_CONTEXT (label_decl
) = current_function_decl
;
1518 tree conditional
= fold_build2_loc (UNKNOWN_LOCATION
, EQ_EXPR
,
1522 tree cond
= build3_loc (UNKNOWN_LOCATION
, COND_EXPR
, void_type_node
,
1524 build1 (GOTO_EXPR
, void_type_node
, label_decl
),
1525 build1 (GOTO_EXPR
, void_type_node
, endif_label_decl
));
1527 append_to_statement_list (cond
, block
);
1528 append_to_statement_list (label_expr
, block
);
1529 append_to_statement_list (fold_build1_loc (UNKNOWN_LOCATION
, RETURN_EXPR
,
1530 void_type_node
, NULL_TREE
),
1532 append_to_statement_list (endif_label_expr
, block
);
1533 append_to_statement_list (build2 (MODIFY_EXPR
, boolean_type_node
,
1534 moduleInit
, boolean_true_node
),
1539 void dot_pass_generic_TU (gpy_hash_tab_t
* types
,
1540 vec
<gpydot
,va_gc
> * decls
,
1541 vec
<tree
,va_gc
> * generic
)
1543 gpy_hash_tab_t toplvl
, topnxt
;
1544 gpy_dd_hash_init_table (&toplvl
);
1545 gpy_dd_hash_init_table (&topnxt
);
1547 gpy_vector_t context
;
1548 memset (&context
, 0, sizeof (gpy_vector_t
));
1550 gpy_vec_push (&context
, &toplvl
);
1551 gpy_vec_push (&context
, &topnxt
);
1553 tree block
= alloc_stmt_list ();
1554 tree module
= dot_pass_getModuleType (GPY_current_module_name
, types
);
1555 dot_pass_setupContext (module
, &context
, generic
, &block
);
1557 tree fntype
= build_function_type_list (void_type_node
, NULL_TREE
);
1558 tree ident
= dot_pass_concat_identifier (GPY_current_module_name
,
1560 tree fndecl
= dot_pass_genFndecl_Basic (ident
, fntype
);
1561 current_function_decl
= fndecl
;
1562 dot_pass_mainInitCheck (&block
);
1565 gpy_dot_tree_t
* dot
= NULL_DOT
;
1566 for (i
= 0; decls
->iterate (i
, &dot
); ++i
)
1568 if (DOT_T_FIELD (dot
) == D_D_EXPR
)
1570 dot_pass_lowerExpr (dot
, &context
, &block
);
1574 switch (DOT_TYPE (dot
))
1577 dot_pass_genPrintStmt (dot
, &block
, &context
);
1580 case D_STRUCT_CONDITIONAL
:
1581 dot_pass_genConditional (dot
, &block
, &context
);
1584 case D_STRUCT_WHILE
:
1585 dot_pass_genWhile (dot
, &block
, &context
);
1589 dot_pass_genFor (dot
, &block
, &context
);
1593 error ("Return in toplevel context is invalid!\n");
1597 dot_pass_genImport (dot
, &block
, &context
);
1600 case D_STRUCT_METHOD
:
1602 tree func
= dot_pass_genFunction (dot
, &context
, GPY_current_module_name
);
1603 /* assign the function to the decl */
1604 const char * funcid
= DOT_IDENTIFIER_POINTER (DOT_FIELD (dot
));
1605 tree funcdecl
= dot_pass_lookupDecl (&context
, funcid
);
1607 gpy_dot_tree_t
* pnode
;
1608 for (pnode
= DOT_lhs_TT (dot
); pnode
!= NULL_DOT
;
1609 pnode
= DOT_CHAIN (pnode
))
1611 tree nargs
= build_int_cst (integer_type_node
, n
);
1612 tree str
= gpy_dot_type_const_string_tree (funcid
);
1613 tree fold_functor
= GPY_RR_fold_func_decl (build_fold_addr_expr (str
),
1615 tree decl_func
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
1616 create_tmp_var_name ("FN"),
1617 gpy_object_type_ptr
);
1618 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
1619 decl_func
, fold_functor
),
1621 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
,
1622 build_fold_indirect_ref (funcdecl
),
1625 vec_safe_push (generic
, func
);
1629 case D_STRUCT_CLASS
:
1631 char * classID
= dot_pass_concat (GPY_current_module_name
,
1632 DOT_IDENTIFIER_POINTER (DOT_FIELD (dot
)));
1633 tree classType
= dot_pass_getModuleType (classID
, types
);
1634 vec
<tree
,va_gc
> * cdecls
= dot_pass_genClass (dot
, &context
, classType
,
1635 GPY_current_module_name
);
1636 GPY_VEC_stmts_append (tree
, generic
, cdecls
);
1637 tree class_decl_ptr
= dot_pass_lookupDecl (&context
,
1638 DOT_IDENTIFIER_POINTER (DOT_FIELD (dot
)));
1639 dot_pass_genWalkClass (&block
, classType
, class_decl_ptr
, cdecls
);
1644 fatal_error ("unhandled tree!\n");
1649 tree entry_decl
= NULL_TREE
;
1650 if (GPY_OPT_gen_main
)
1652 tree entry_fntype
= gpy_unsigned_char_ptr
;
1653 entry_decl
= build_decl (BUILTINS_LOCATION
, VAR_DECL
,
1654 get_identifier (GPY_RR_entry
),
1656 TREE_STATIC (entry_decl
) = 1;
1657 TREE_PUBLIC (entry_decl
) = 1;
1658 TREE_USED (entry_decl
) = 1;
1659 DECL_ARTIFICIAL (entry_decl
) = 1;
1660 DECL_EXTERNAL (entry_decl
) = 0;
1661 DECL_INITIAL (entry_decl
) = build_fold_addr_expr (fndecl
);
1662 rest_of_decl_compilation (entry_decl
, 1, 0);
1665 tree bind
= NULL_TREE
;
1666 tree bl
= build_block (DECL_RESULT (fndecl
), NULL_TREE
, fndecl
, NULL_TREE
);
1667 DECL_INITIAL (fndecl
) = bl
;
1670 bind
= build3 (BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
1672 TREE_SIDE_EFFECTS (bind
) = 1;
1673 /* Finalize the main function */
1674 BIND_EXPR_BODY (bind
) = block
;
1676 DECL_SAVED_TREE (fndecl
) = block
;
1678 gimplify_function_tree (fndecl
);
1679 cgraph_finalize_function (fndecl
, false);
1683 /* Here we need to write out export data to object */
1684 char * exportFile
= (char *) alloca (512);
1685 const char * main_FNDECL
= IDENTIFIER_POINTER (DECL_NAME (fndecl
));
1686 snprintf (exportFile
, 511, "%s.export.gpyx", GPY_current_module_name
);
1687 gpy_writeExport (exportFile
, (bool) GPY_OPT_gen_main
,
1688 GPY_current_module_name
, main_FNDECL
);
1690 vec_safe_push (generic
, fndecl
);
1691 if (GPY_OPT_gen_main
)
1692 vec_safe_push (generic
, entry_decl
);
1695 vec
<tree
,va_gc
> * dot_pass_genericify (vec
<tree
,va_gc
> * modules
,
1696 vec
<gpydot
,va_gc
> * decls
)
1698 vec
<tree
,va_gc
> * retval
;
1699 vec_alloc (retval
, 0);
1701 gpy_hash_tab_t types
;
1702 gpy_dd_hash_init_table (&types
);
1705 tree type
= NULL_TREE
;
1706 for (i
= 0; modules
->iterate (i
, &type
); ++i
)
1708 gpy_hashval_t h
= gpy_dd_hash_string (IDENTIFIER_POINTER (TYPE_NAME(type
)));
1709 void ** e
= gpy_dd_hash_insert (h
, type
, &types
);
1711 fatal_error ("module <%s> is already defined!\n",
1712 IDENTIFIER_POINTER (DECL_NAME (type
)));
1714 dot_pass_generic_TU (&types
, decls
, retval
);