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 #include "coretypes.h"
24 #include "tree-iterator.h"
25 #include "tree-pass.h"
32 #include "diagnostic-core.h"
33 #include "langhooks.h"
34 #include "langhooks-def.h"
48 #include "py-builtins.h"
50 static VEC(tree
,gc
) * gpy_stmt_pass_lower_genericify (gpy_hash_tab_t
*, VEC(gpydot
,gc
) *);
51 static tree
gpy_stmt_pass_lower_get_module_type (const char *, gpy_hash_tab_t
*);
52 static void gpy_stmt_pass_lower_gen_toplevl_context (tree
, tree
, gpy_hash_tab_t
*);
54 static tree
gpy_stmt_pass_lower_gen_concat_identifier (const char *, const char *);
55 static tree
gpy_stmt_pass_lower_gen_main (tree
);
58 tree
gpy_stmt_pass_lower_gen_concat_identifier (const char * s1
,
61 debug ("s1 = <%s> s2 = <%s>!\n", s1
, s2
);
62 size_t s1len
= strlen (s1
);
63 size_t s2len
= strlen (s2
);
64 size_t tlen
= s1len
+ s2len
;
66 size_t idx
= 0, idy
= 0;
68 strncpy (buffer
,s1
,s1len
);
71 for (idx
= s1len
+1; idx
<tlen
+2; ++idx
)
73 buffer
[idx
] = s2
[idy
];
76 buffer
[tlen
+1] = '\0';
77 debug ("buffer = <%s>!\n", buffer
);
79 return get_identifier (buffer
);
83 tree
gpy_stmt_pass_lower_get_module_type (const char * s
,
84 gpy_hash_tab_t
* modules
)
86 tree retval
= error_mark_node
;
88 gpy_hashval_t h
= gpy_dd_hash_string (s
);
89 gpy_hash_entry_t
* e
= gpy_dd_hash_lookup_table (modules
, h
);
93 retval
= (tree
) e
->data
;
100 void gpy_stmt_pass_lower_gen_toplevl_context (tree module
, tree param_decl
,
101 gpy_hash_tab_t
* context
)
103 if (module
== error_mark_node
)
107 tree field
= TYPE_FIELDS (module
);
109 gcc_assert (TREE_CODE (field
) == FIELD_DECL
);
111 debug ("generating refernence to <%s>!\n", IDENTIFIER_POINTER(DECL_NAME (field
)));
112 gpy_hashval_t h
= gpy_dd_hash_string (IDENTIFIER_POINTER(DECL_NAME (field
)));
113 tree ref
= build3 (COMPONENT_REF
, TREE_TYPE (field
), build_fold_indirect_ref(param_decl
),
115 void ** e
= gpy_dd_hash_insert (h
, ref
, context
);
119 fatal_error ("problem inserting component reference into context!\n");
120 } while ((field
= DECL_CHAIN (field
)));
125 Creates a DECL_CHAIN of stmts to fold the scalar
126 with the last tree being the address of the primitive
128 tree
gpy_stmt_decl_lower_scalar (gpy_dot_tree_t
* decl
, tree
* cblock
)
130 tree retval
= error_mark_node
;
132 gcc_assert (DOT_TYPE (decl
) == D_PRIMITIVE
);
133 gcc_assert (DOT_lhs_T (decl
) == D_TD_COM
);
135 switch (DOT_lhs_TC (decl
)->T
)
139 retval
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
140 create_tmp_var_name ("P"),
141 gpy_object_type_ptr
);
142 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
, retval
,
143 gpy_builtin_get_fold_int_call (DOT_lhs_TC (decl
)->o
.integer
)),
149 error ("invalid scalar type!\n");
156 tree
gpy_stmt_decl_lower_modify (gpy_dot_tree_t
* decl
, tree
* cblock
,
157 VEC(gpy_ctx_t
,gc
) * context
)
159 tree retval
= error_mark_node
;
160 gpy_dot_tree_t
* lhs
= DOT_lhs_TT (decl
);
161 gpy_dot_tree_t
* rhs
= DOT_rhs_TT (decl
);
164 We dont handle full target lists yet
165 all targets are in the lhs tree.
167 To implment a target list such as:
170 The lhs should be a DOT_CHAIN of identifiers!
171 So we just iterate over them and deal with it as such!
174 gcc_assert (DOT_TYPE (lhs
) == D_IDENTIFIER
);
176 tree addr
= gpy_ctx_lookup_decl (context
, DOT_IDENTIFIER_POINTER (lhs
));
179 /* since not previously declared we need to declare the variable! */
180 gpy_hash_tab_t
* current_context
= VEC_index (gpy_ctx_t
, context
,
181 (VEC_length (gpy_ctx_t
, context
)
184 addr
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
,
185 get_identifier (DOT_IDENTIFIER_POINTER (lhs
)),
186 gpy_object_type_ptr
);
188 if (!gpy_ctx_push_decl (addr
, DOT_IDENTIFIER_POINTER (lhs
),
190 fatal_error ("error pushing decl <%q+E>!\n", addr
);
192 gcc_assert (addr
!= error_mark_node
);
194 tree addr_rhs_tree
= gpy_stmt_decl_lower_expr (rhs
, cblock
, context
);
196 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
, addr
, addr_rhs_tree
), cblock
);
197 append_to_statement_list (gpy_builtin_get_incr_ref_call (addr
), cblock
);
203 tree
gpy_stmt_decl_lower_binary_op (gpy_dot_tree_t
* decl
, tree
* cblock
,
204 VEC(gpy_ctx_t
,gc
) * context
)
206 tree retval
= error_mark_node
;
208 gcc_assert (DOT_T_FIELD (decl
) == D_D_EXPR
);
210 gpy_dot_tree_t
* lhs
= DOT_lhs_TT (decl
);
211 gpy_dot_tree_t
* rhs
= DOT_rhs_TT (decl
);
213 tree lhs_eval
= gpy_stmt_decl_lower_expr (lhs
, cblock
, context
);
214 tree rhs_eval
= gpy_stmt_decl_lower_expr (rhs
, cblock
, context
);
216 tree op
= error_mark_node
;
217 switch (DOT_TYPE (decl
))
220 op
= gpy_builtin_get_eval_expression_call (lhs_eval
, rhs_eval
, DOT_TYPE (decl
));
226 error ("unhandled binary operation type!\n");
229 gcc_assert (op
!= error_mark_node
);
232 tree retaddr
= build_decl (UNKNOWN_LOCATION
, VAR_DECL
, create_tmp_var_name("T"),
233 gpy_object_type_ptr
);
234 append_to_statement_list (build2 (MODIFY_EXPR
, gpy_object_type_ptr
, retaddr
, op
), cblock
);
240 tree
gpy_stmt_decl_lower_expr (gpy_dot_tree_t
* decl
, tree
* cblock
,
241 VEC(gpy_ctx_t
,gc
) * context
)
243 tree retval
= error_mark_node
;
245 switch (DOT_TYPE (decl
))
248 retval
= gpy_stmt_decl_lower_scalar (decl
, cblock
);
252 retval
= gpy_ctx_lookup_decl (context
,
253 DOT_IDENTIFIER_POINTER (decl
));
258 switch (DOT_TYPE (decl
))
261 retval
= gpy_stmt_decl_lower_modify (decl
, cblock
, context
);
265 retval
= gpy_stmt_decl_lower_binary_op (decl
, cblock
, context
);
268 // ... the rest of the binary operators!
271 error ("unhandled operation type!\n");
281 tree
gpy_stmt_pass_lower_functor (gpy_dot_tree_t
* decl
,
282 gpy_hash_tab_t
* modules
)
284 tree block
= alloc_stmt_list ();
286 gpy_hash_tab_t toplvl
, topnxt
;
287 gpy_dd_hash_init_table (&toplvl
);
288 gpy_dd_hash_init_table (&topnxt
);
290 tree main_init_module
= gpy_stmt_pass_lower_get_module_type ("main.main",
292 tree pdecl_t
= build_pointer_type (main_init_module
);
293 tree fntype
= build_function_type_list (void_type_node
, pdecl_t
,
295 handle function parameters
299 tree concat_ident
= gpy_stmt_pass_lower_gen_concat_identifier ("main.main",
300 DOT_IDENTIFIER_POINTER (DOT_FIELD (decl
)));
301 tree fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
, concat_ident
, fntype
);
303 DECL_EXTERNAL (fndecl
) = 0;
304 TREE_PUBLIC (fndecl
) = 1;
305 TREE_STATIC (fndecl
) = 1;
306 tree arglist
= NULL_TREE
;
308 tree result_decl
= build_decl (BUILTINS_LOCATION
, RESULT_DECL
, NULL_TREE
,
310 DECL_RESULT (fndecl
) = result_decl
;
312 SET_DECL_ASSEMBLER_NAME (fndecl
, concat_ident
);
314 tree self_parm_decl
= build_decl (BUILTINS_LOCATION
, PARM_DECL
,
315 get_identifier ("__self__"),
318 DECL_CONTEXT (self_parm_decl
) = fndecl
;
319 DECL_ARG_TYPE (self_parm_decl
) = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl
)));
320 TREE_READONLY (self_parm_decl
) = 1;
321 arglist
= chainon (arglist
, self_parm_decl
);
323 TREE_USED (self_parm_decl
) = 1;
324 DECL_ARGUMENTS (fndecl
) = arglist
;
326 gpy_stmt_pass_lower_gen_toplevl_context (main_init_module
, self_parm_decl
,
329 VEC(gpy_ctx_t
,gc
) * toplevl_context
= VEC_alloc (gpy_ctx_t
, gc
, 0);
330 VEC_safe_push (gpy_ctx_t
, gc
, toplevl_context
, &toplvl
);
331 VEC_safe_push (gpy_ctx_t
, gc
, toplevl_context
, &topnxt
);
333 DECL_INITIAL(fndecl
) = block
;
334 gpy_dot_tree_t
* idtx
= DOT_rhs_TT (decl
);
336 Iterating over the DOT IL to lower/generate the GENERIC code
337 required to compile the stmts and decls
340 if (DOT_T_FIELD (idtx
) == D_D_EXPR
)
342 // append to stmt list as this goes into the module initilizer...
343 gpy_stmt_decl_lower_expr (idtx
, &block
, toplevl_context
);
347 switch (DOT_TYPE (idtx
))
350 fatal_error ("unhandled dot tree code <%i>!\n", DOT_TYPE (idtx
));
353 } while ((idtx
= DOT_CHAIN (idtx
)));
355 tree bl
= make_node(BLOCK
);
356 BLOCK_SUPERCONTEXT(bl
) = fndecl
;
357 DECL_INITIAL(fndecl
) = bl
;
358 BLOCK_VARS(bl
) = NULL_TREE
;
360 tree bind
= build3(BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
362 TREE_SIDE_EFFECTS(bind
) = 1;
364 BIND_EXPR_BODY(bind
) = block
;
366 DECL_SAVED_TREE(fndecl
) = block
;
368 gimplify_function_tree (fndecl
);
370 cgraph_add_new_function (fndecl
, false);
371 cgraph_finalize_function (fndecl
, true);
377 VEC(tree
,gc
) * gpy_stmt_pass_lower_genericify (gpy_hash_tab_t
* modules
,
378 VEC(gpydot
,gc
) * decls
)
380 VEC(tree
,gc
) * retval
= VEC_alloc (tree
,gc
,0);
382 tree block
= alloc_stmt_list ();
383 // tree declvars = NULL_TREE;
385 gpy_hash_tab_t toplvl
, topnxt
;
386 gpy_dd_hash_init_table (&toplvl
);
387 gpy_dd_hash_init_table (&topnxt
);
389 tree main_init_module
= gpy_stmt_pass_lower_get_module_type ("main.main", modules
);
390 tree pdecl_t
= build_pointer_type (main_init_module
);
392 tree main_init_fntype
= build_function_type_list (void_type_node
, pdecl_t
, NULL_TREE
);
393 tree main_init_fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
394 get_identifier ("main.main.init"),
396 DECL_EXTERNAL (main_init_fndecl
) = 0;
397 TREE_PUBLIC (main_init_fndecl
) = 1;
398 TREE_STATIC (main_init_fndecl
) = 1;
400 tree result_decl
= build_decl (BUILTINS_LOCATION
, RESULT_DECL
, NULL_TREE
,
402 DECL_RESULT (main_init_fndecl
) = result_decl
;
404 tree arglist
= NULL_TREE
;
406 SET_DECL_ASSEMBLER_NAME (main_init_fndecl
, get_identifier("main.main.init"));
407 tree self_parm_decl
= build_decl (BUILTINS_LOCATION
, PARM_DECL
,
408 get_identifier ("__self__"),
410 DECL_CONTEXT (self_parm_decl
) = main_init_fndecl
;
411 DECL_ARG_TYPE (self_parm_decl
) = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (main_init_fndecl
)));
412 TREE_READONLY (self_parm_decl
) = 1;
413 arglist
= chainon (arglist
, self_parm_decl
);
415 TREE_USED (self_parm_decl
) = 1;
416 DECL_ARGUMENTS (main_init_fndecl
) = arglist
;
418 gpy_stmt_pass_lower_gen_toplevl_context (main_init_module
, self_parm_decl
,
421 VEC(gpy_ctx_t
,gc
) * toplevl_context
= VEC_alloc (gpy_ctx_t
, gc
, 0);
422 VEC_safe_push (gpy_ctx_t
, gc
, toplevl_context
, &toplvl
);
423 VEC_safe_push (gpy_ctx_t
, gc
, toplevl_context
, &topnxt
);
425 DECL_INITIAL(main_init_fndecl
) = block
;
428 gpy_dot_tree_t
* idtx
= NULL_DOT
;
430 Iterating over the DOT IL to lower/generate the GENERIC code
431 required to compile the stmts and decls
433 for (idx
= 0; VEC_iterate (gpydot
, decls
, idx
, idtx
); ++idx
)
435 if (DOT_T_FIELD (idtx
) == D_D_EXPR
)
437 // append to stmt list as this goes into the module initilizer...
438 gpy_stmt_decl_lower_expr (idtx
, &block
, toplevl_context
);
442 switch (DOT_TYPE (idtx
))
444 case D_STRUCT_METHOD
:
447 They are self contained decls so we just pass them to the
448 return vector for gimplification
450 debug ("lowering function toplevel!\n");
451 VEC_safe_push (tree
, gc
, retval
,
452 gpy_stmt_pass_lower_functor (idtx
, modules
)
454 debug ("lowered function toplevel!\n");
459 fatal_error ("unhandled dot tree code <%i>!\n", DOT_TYPE (idtx
));
464 tree bl
= make_node(BLOCK
);
465 BLOCK_SUPERCONTEXT(bl
) = main_init_fndecl
;
466 DECL_INITIAL(main_init_fndecl
) = bl
;
467 BLOCK_VARS(bl
) = NULL_TREE
;
469 tree bind
= build3(BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
471 TREE_SIDE_EFFECTS(bind
) = 1;
473 BIND_EXPR_BODY(bind
) = block
;
475 DECL_SAVED_TREE(main_init_fndecl
) = block
;
477 gimplify_function_tree (main_init_fndecl
);
479 cgraph_add_new_function (main_init_fndecl
, false);
480 cgraph_finalize_function (main_init_fndecl
, true);
482 VEC_safe_push (tree
,gc
,retval
, main_init_fndecl
);
488 tree
gpy_stmt_pass_lower_gen_main (tree module
)
490 tree main_fn_type
= build_function_type_list (integer_type_node
, NULL_TREE
);
491 tree main_fn_decl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
492 get_identifier("main"), main_fn_type
);
494 DECL_CONTEXT (main_fn_decl
) = NULL_TREE
;
495 TREE_STATIC (main_fn_decl
) = 1;
496 TREE_PUBLIC (main_fn_decl
) = 1;
497 DECL_ARGUMENTS (main_fn_decl
) = NULL_TREE
;
499 /* Define the return type (represented by RESULT_DECL) for the main functin */
500 tree main_ret
= build_decl (BUILTINS_LOCATION
, RESULT_DECL
,
501 NULL_TREE
, TREE_TYPE(main_fn_type
));
502 DECL_CONTEXT(main_ret
) = main_fn_decl
;
503 DECL_ARTIFICIAL(main_ret
) = 1;
504 DECL_IGNORED_P(main_ret
) = 1;
505 DECL_RESULT(main_fn_decl
) = main_ret
;
507 tree main_art_block
= build_block(NULL_TREE
, NULL_TREE
, NULL_TREE
, NULL_TREE
);
508 DECL_INITIAL(main_fn_decl
) = main_art_block
;
510 tree declare_vars
= NULL_TREE
;
511 tree main_stmts
= alloc_stmt_list ();
513 append_to_statement_list (gpy_builtin_get_init_call(), &main_stmts
);
514 tree mod_decl
= build_decl (BUILTINS_LOCATION
, VAR_DECL
, create_tmp_var_name ("I"),
516 declare_vars
= mod_decl
;
517 tree module_init_fndecl
= build_decl (BUILTINS_LOCATION
, FUNCTION_DECL
,
518 get_identifier ("main.main.init"),
519 build_function_type_list (void_type_node
,
520 build_pointer_type (module
), NULL_TREE
)
522 append_to_statement_list (build_call_expr (module_init_fndecl
, 1, build_fold_addr_expr(mod_decl
)),
524 append_to_statement_list ( gpy_builtin_get_cleanup_final_call (), &main_stmts
);
526 tree main_set_ret
= build2 (MODIFY_EXPR
, TREE_TYPE(main_ret
),
527 main_ret
, build_int_cst(integer_type_node
, 0));
528 tree main_ret_expr
= build1 (RETURN_EXPR
, void_type_node
, main_set_ret
);
529 append_to_statement_list (main_ret_expr
, &main_stmts
);
531 tree bind
= NULL_TREE
;
532 tree bl
= make_node(BLOCK
);
533 BLOCK_SUPERCONTEXT(bl
) = main_fn_decl
;
534 DECL_INITIAL(main_fn_decl
) = bl
;
535 BLOCK_VARS(bl
) = declare_vars
;
537 bind
= build3( BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
539 TREE_SIDE_EFFECTS(bind
) = 1;
541 BIND_EXPR_BODY(bind
) = main_stmts
;
543 DECL_SAVED_TREE(main_fn_decl
) = main_stmts
;
545 gimplify_function_tree (main_fn_decl
);
546 cgraph_finalize_function (main_fn_decl
, false);
551 /* Now we start to iterate over the dot IL to lower it down to */
552 /* a vector of GENERIC decls */
554 /* Which is then passed over to the pass manager for any other */
555 /* defined passes which can be placed into the queue but arent */
556 /* nessecary for now. */
557 VEC(tree
,gc
) * gpy_stmt_pass_lower (VEC(tree
,gc
) *modules
,
558 VEC(gpydot
,gc
) *decls
)
560 VEC(tree
,gc
) * retval
;
562 gpy_hash_tab_t module_ctx
;
563 gpy_dd_hash_init_table (&module_ctx
);
566 tree itx
= NULL_TREE
;
568 for (; VEC_iterate (tree
, modules
, idx
, itx
); ++idx
)
570 debug ("hashing module name <%s>!\n", IDENTIFIER_POINTER (TYPE_NAME(itx
)));
571 gpy_hashval_t h
= gpy_dd_hash_string (IDENTIFIER_POINTER (TYPE_NAME(itx
)));
572 void ** e
= gpy_dd_hash_insert (h
, itx
, &module_ctx
);
575 fatal_error ("module <%q+E> is already defined!\n", itx
);
578 retval
= gpy_stmt_pass_lower_genericify (&module_ctx
, decls
);
579 VEC_safe_push (tree
, gc
, retval
,
580 gpy_stmt_pass_lower_gen_main (gpy_stmt_pass_lower_get_module_type ("main.main",
584 // free (context.array);