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"
29 #include "diagnostic-core.h"
30 #include "langhooks.h"
31 #include "langhooks-def.h"
34 #include "tree-iterator.h"
44 #include "py-dot-codes.def"
48 #include "py-runtime.h"
50 static gpy_symbol_obj
* gpy_process_AST_Align( gpy_symbol_obj
** );
51 static void gpy_finish_type( tree
);
52 static tree
gpy_add_field_to_struct_1( tree
, tree
, tree
, tree
** );
53 static tree
gpy_build_callable_record_type( void );
55 static VEC( gpy_sym
,gc
) * gpy_decls
;
56 VEC(gpy_ctx_t
,gc
) * gpy_ctx_table
;
57 VEC(tree
,gc
) * global_decls
;
58 VEC(tree
,gc
) * gpy_toplev_fncs
;
60 void gpy_process_decl( gpy_symbol_obj
* sym
)
62 /* Push the declaration! */
63 VEC_safe_push( gpy_sym
, gc
, gpy_decls
, sym
);
64 debug("decl <%p> was pushed!\n", (void*)sym
);
68 * Fairly Confusing Function to read.
71 * >>> x = y = z = 2 + 2 + 2;
73 * --- Currently Yacc parses that expression into this Tree:
87 -- Is converted into the procedure:
93 -- Tree structure as so:
108 gpy_symbol_obj
* gpy_process_AST_Align( gpy_symbol_obj
** sym
)
110 gpy_symbol_obj
*nn
= NULL
;
111 gpy_symbol_obj
*retval
= NULL
;
119 if( (*sym
)->exp
== OP_EXPRESS
)
121 debug("Processing Expression AST!\n");
122 if( retval
->type
!= OP_ASSIGN_EVAL
)
124 gpy_symbol_obj
*o
= retval
;
125 gpy_symbol_obj
*h
= NULL
;
128 if( o
->op_a_t
== TYPE_SYMBOL
)
130 if( o
->op_a
.symbol_table
->type
== OP_ASSIGN_EVAL
)
137 o
= o
->op_a
.symbol_table
;
144 gpy_symbol_obj
*head
= h
->op_a
.symbol_table
;
145 if( head
->op_b
.symbol_table
->type
== OP_ASSIGN_EVAL
)
147 gpy_symbol_obj
*t
= head
, *m
= NULL
;
150 if( t
->op_b_t
== TYPE_SYMBOL
)
152 if( t
->op_b
.symbol_table
->type
!= OP_ASSIGN_EVAL
)
159 t
= t
->op_b
.symbol_table
;
166 h
->op_a
.symbol_table
= m
->op_b
.symbol_table
;
167 m
->op_b
.symbol_table
= retval
;
171 fatal_error("error processing the expression AST!\n");
176 h
->op_a
.symbol_table
= head
->op_b
.symbol_table
;
177 head
->op_b
.symbol_table
= retval
;
193 VEC(tree
,gc
) * gpy_process_expression( const gpy_symbol_obj
* const sym
,
194 VEC(gpy_ctx_t
,gc
) * context
)
196 VEC(tree
,gc
) * retval
= NULL
;
197 if( sym
->type
== SYMBOL_PRIMARY
)
199 retval
= VEC_alloc(tree
,gc
,0);
200 VEC(tree
,gc
) *primitive
= gpy_fold_primitive( sym
);
201 gcc_assert( VEC_length(tree
,primitive
) == 1 );
202 VEC_safe_push( tree
,gc
,retval
,VEC_index(tree
,primitive
,0) );
204 else if( sym
->type
== SYMBOL_REFERENCE
)
206 gcc_assert( sym
->op_a_t
== TYPE_STRING
);
207 tree decl
= gpy_ctx_lookup_decl( context
, sym
->op_a
.string
, VAR
);
210 retval
= VEC_alloc(tree
,gc
,0);
211 debug("tree reference <%s>!\n", sym
->op_a
.string
);
212 VEC_safe_push( tree
,gc
,retval
,decl
);
216 error("undeclared symbol reference <%s>!\n",
222 gpy_symbol_obj
*opa
= NULL
, *opb
= NULL
; VEC(tree
,gc
) *res
= NULL
;
223 debug("expression evalution <0x%x>!\n", sym
->type
);
225 opa
= sym
->op_a
.symbol_table
;
226 opb
= sym
->op_b
.symbol_table
;
228 debug( "opa->type = <0x%x>, opb->type = <0x%x>!\n",
229 opa
->type
, opb
->type
);
234 res
= gpy_process_assign( &opa
, &opb
, context
);
237 case OP_BIN_ADDITION
:
238 res
= gpy_process_bin_expression( &opa
, &opb
, sym
->type
, context
);
242 fatal_error( "invalid expression evaluation symbol type <0x%x>!\n",
246 if( res
) { retval
= res
; }
247 else { fatal_error("error evaluating expression!\n"); }
253 VEC(tree
,gc
) * gpy_process_functor( const gpy_symbol_obj
* const functor
,
254 const char * base_ident
,
255 VEC(gpy_ctx_t
,gc
) * context
)
257 VEC(tree
,gc
) * retval_vec
= VEC_alloc( tree
,gc
,0 );
259 gpy_symbol_obj
* o
= functor
->op_a
.symbol_table
;
260 tree fntype
= build_function_type(void_type_node
, void_list_node
);
261 tree retval
= build_decl( UNKNOWN_LOCATION
, FUNCTION_DECL
,
262 get_identifier( functor
->identifier
),
265 tree declare_vars
= NULL_TREE
;
266 tree bind
= NULL_TREE
;
267 tree block
= alloc_stmt_list( );
268 tree resdecl
= NULL_TREE
;
269 tree restype
= TREE_TYPE(retval
);
272 gpy_context_branch
*co
= NULL
;
277 size_t len
= strlen( functor
->identifier
) + strlen( base_ident
);
278 size_t idx
= 0, idy
= 0;
279 char * buffer
= (char *) xmalloc( (sizeof(char) * len
)+2 );
280 for( ; idx
<strlen( base_ident
); ++idx
)
282 buffer
[ idy
] = base_ident
[ idx
];
285 buffer
[ idy
] = '.'; idy
++;
286 for( idx
=0; idx
<strlen( functor
->identifier
); ++idx
)
288 buffer
[ idy
] = functor
->identifier
[ idx
];
292 debug("buffer = <%s>!\n", buffer
);
293 SET_DECL_ASSEMBLER_NAME( retval
, get_identifier( buffer
) );
297 SET_DECL_ASSEMBLER_NAME( retval
, get_identifier(functor
->identifier
) );
299 TREE_PUBLIC(retval
) = 1;
300 TREE_STATIC(retval
) = 1;
302 resdecl
= build_decl( UNKNOWN_LOCATION
, RESULT_DECL
, NULL_TREE
,
304 DECL_CONTEXT(resdecl
) = retval
;
305 DECL_RESULT(retval
) = resdecl
;
307 DECL_INITIAL(retval
) = block
;
309 /* push a new context for local symbols */
310 co
= (gpy_context_branch
*)
311 xmalloc( sizeof(gpy_context_branch
) );
312 gpy_init_ctx_branch( &co
);
313 VEC_safe_push( gpy_ctx_t
, gc
, context
, co
);
317 /* looping over the gpy_symbol_obj block of function statements
318 and getting the respective tree's and creating the GENERIC block
320 VEC(tree
,gc
) * x
= gpy_get_tree( o
,context
);
321 int itx
= 0; tree xt
;
322 for( ; VEC_iterate(tree
,x
,itx
,xt
); ++itx
)
325 append_to_statement_list( xt
, &block
);
330 for( ; VEC_iterate( gpy_ident
,co
->var_decl_t
, idx
, it
); ++idx
)
332 /* get all block var_decls */
333 tree x
= gpy_ctx_lookup_decl( context
, it
->ident
, VAR
);
334 gcc_assert( TREE_CODE( x
) == VAR_DECL
);
335 debug("got var decl <%p>:<%s> within func <%s>!\n", (void*)x
,
336 it
->ident
, functor
->identifier
);
337 TREE_CHAIN( x
) = declare_vars
;
341 if( declare_vars
!= NULL_TREE
)
343 tree bl
= make_node(BLOCK
);
344 BLOCK_SUPERCONTEXT(bl
) = retval
;
345 DECL_INITIAL(retval
) = bl
;
346 BLOCK_VARS(bl
) = declare_vars
;
348 bind
= build3(BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
350 TREE_SIDE_EFFECTS(bind
) = 1;
352 BIND_EXPR_BODY(bind
) = block
;
354 DECL_SAVED_TREE(retval
) = block
;
356 VEC_pop( gpy_ctx_t
, gpy_ctx_table
);
358 gimplify_function_tree( retval
);
360 cgraph_add_new_function(retval
, false);
361 cgraph_finalize_function(retval
, true);
363 VEC_safe_push( tree
,gc
,retval_vec
,retval
);
368 VEC(tree
,gc
) * gpy_process_print( gpy_symbol_obj
*sym
, VEC(gpy_ctx_t
,gc
) * context
)
370 VEC(tree
,gc
) * retval
= NULL
;
371 gcc_assert( sym
->op_a_t
== TYPE_SYMBOL
);
372 gpy_symbol_obj
* argument_list
= sym
->op_a
.symbol_table
;
377 gpy_symbol_obj
* t
= argument_list
;
384 int idx
, idy
= 0; t
= argument_list
;
385 tree
* args
= XNEWVEC( tree
,len
);
386 for( idx
=0; idx
<len
; ++idx
)
388 VEC(tree
,gc
) * x
= gpy_get_tree( t
, context
);
389 gcc_assert( VEC_length(tree
,x
) == 1 );
390 args
[ idy
] = VEC_index(tree
,x
,0);
395 VEC_safe_push( tree
,gc
,retval
,gpy_builtin_get_print_call( len
, args
) );
398 error("print call without any arguments!\n");
403 VEC(tree
,gc
) * gpy_process_class( gpy_symbol_obj
* const sym
,
404 VEC(gpy_ctx_t
,gc
) * context
)
406 VEC(tree
,gc
) * retval
= NULL
;
410 VEC(tree
,gc
) * gpy_get_tree( gpy_symbol_obj
* sym
, VEC(gpy_ctx_t
,gc
) * context
)
412 VEC(tree
,gc
) * retval
= NULL
;
414 debug( "processing decl of type <0x%X> object <%p>\n",
415 sym
->type
, (void*) sym
);
417 if( sym
->exp
== OP_EXPRESS
)
419 sym
= gpy_process_AST_Align( &sym
);
420 retval
= gpy_process_expression( sym
, context
);
426 case STRUCTURE_OBJECT_DEF
:
428 VEC(gpy_ctx_t
,gc
) * class_ctx
= VEC_alloc(gpy_ctx_t
,gc
,0);
429 retval
= gpy_process_class( sym
, class_ctx
);
433 case STRUCTURE_FUNCTION_DEF
:
435 VEC(gpy_ctx_t
,gc
) * func_ctx
= VEC_alloc(gpy_ctx_t
,gc
,0);
436 retval
= gpy_process_functor( sym
, NULL
, func_ctx
);
441 retval
= gpy_process_print( sym
, context
);
445 fatal_error("unhandled symbol type <0x%x>\n", sym
->type
);
453 tree
gpy_main_method_decl( VEC(tree
,gc
) * block
, gpy_context_branch
* co
)
455 tree retval
= NULL_TREE
; int idx
;
457 tree main_fn_type
= build_function_type_list( integer_type_node
, NULL_TREE
);
458 tree main_fn_decl
= build_decl( BUILTINS_LOCATION
, FUNCTION_DECL
,
459 get_identifier("main"), main_fn_type
);
461 DECL_CONTEXT(main_fn_decl
) = NULL_TREE
;
462 TREE_STATIC(main_fn_decl
) = true;
463 TREE_PUBLIC(main_fn_decl
) = true;
464 DECL_ARGUMENTS(main_fn_decl
) = NULL_TREE
;
466 /* Define the return type (represented by RESULT_DECL) for the main functin */
467 tree main_ret
= build_decl( BUILTINS_LOCATION
, RESULT_DECL
,
468 NULL_TREE
, TREE_TYPE(main_fn_type
) );
469 DECL_CONTEXT(main_ret
) = main_fn_decl
;
470 DECL_ARTIFICIAL(main_ret
) = true;
471 DECL_IGNORED_P(main_ret
) = true;
473 DECL_RESULT(main_fn_decl
) = main_ret
;
475 tree main_art_block
= build_block(NULL_TREE
, NULL_TREE
, NULL_TREE
, NULL_TREE
);
476 DECL_INITIAL(main_fn_decl
) = main_art_block
;
478 tree declare_vars
= NULL_TREE
;
479 tree main_stmts
= alloc_stmt_list( );
481 append_to_statement_list( gpy_builtin_get_init_call( ), &main_stmts
);
484 for( idx
= 0; VEC_iterate(tree
,block
,idx
,it
); ++idx
)
487 append_to_statement_list( it
, &main_stmts
);
490 int block_decl_len
= 0; gpy_ident vit
= NULL
;
491 for( idx
= 0; VEC_iterate( gpy_ident
,co
->var_decl_t
, idx
, vit
); ++idx
)
493 /* get all block var_decls */
494 tree x
= gpy_ctx_lookup_decl( gpy_ctx_table
, vit
->ident
, VAR
);
495 gcc_assert( TREE_CODE( x
) == VAR_DECL
);
496 debug("got var decl <%p>:<%s> within func <%s>!\n", (void*)x
,
497 vit
->ident
, "main" );
498 TREE_CHAIN( x
) = declare_vars
;
503 if( block_decl_len
> 0 )
505 tree
* block_decl_vec
= XNEWVEC( tree
, block_decl_len
);
508 for( idx
= 0; VEC_iterate( gpy_ident
,co
->var_decl_t
, idx
, vit
); ++idx
)
510 tree x
= gpy_ctx_lookup_decl( gpy_ctx_table
, vit
->ident
, VAR
);
511 gcc_assert( TREE_CODE( x
) == VAR_DECL
);
513 block_decl_vec
[ idy
] = x
;
516 //block_decl_vec[ idy ] = main_ret; idy++;
517 append_to_statement_list( gpy_builtin_get_finalize_block_call( block_decl_len
,
523 declare_vars
= main_ret
;
526 append_to_statement_list( gpy_builtin_get_cleanup_final_call( ), &main_stmts
);
528 tree main_set_ret
= build2( MODIFY_EXPR
, TREE_TYPE(main_ret
),
529 main_ret
, build_int_cst(integer_type_node
, 0));
530 tree main_ret_expr
= build1( RETURN_EXPR
, void_type_node
, main_set_ret
);
531 append_to_statement_list( main_ret_expr
, &main_stmts
);
533 tree bind
= NULL_TREE
;
534 if( declare_vars
!= NULL_TREE
)
536 tree bl
= make_node(BLOCK
);
537 BLOCK_SUPERCONTEXT(bl
) = main_fn_decl
;
538 DECL_INITIAL(main_fn_decl
) = bl
;
539 BLOCK_VARS(bl
) = declare_vars
;
541 bind
= build3( BIND_EXPR
, void_type_node
, BLOCK_VARS(bl
),
543 TREE_SIDE_EFFECTS(bind
) = 1;
545 BIND_EXPR_BODY(bind
) = main_stmts
;
547 DECL_SAVED_TREE(main_fn_decl
) = main_stmts
;
549 gimplify_function_tree( main_fn_decl
);
550 cgraph_finalize_function( main_fn_decl
, false );
552 retval
= main_fn_decl
;
557 /* Layout and output debug info for a record type. */
560 gpy_finish_type (tree type
)
564 decl
= build_decl (input_location
,
565 TYPE_DECL
, NULL_TREE
, type
);
566 TYPE_STUB_DECL (type
) = decl
;
568 rest_of_type_compilation (type
, 1);
569 rest_of_decl_compilation (decl
, 1, 0);
572 /* Add a field of given NAME and TYPE to the context of a UNION_TYPE
573 or RECORD_TYPE pointed to by CONTEXT. The new field is chained
574 to the end of the field list pointed to by *CHAIN.
576 Returns a pointer to the new field. */
579 gpy_add_field_to_struct_1 (tree context
, tree name
, tree type
, tree
**chain
)
581 tree decl
= build_decl (BUILTINS_LOCATION
, FIELD_DECL
, name
, type
);
583 DECL_CONTEXT (decl
) = context
;
584 DECL_CHAIN (decl
) = NULL_TREE
;
585 if (TYPE_FIELDS (context
) == NULL_TREE
)
586 TYPE_FIELDS (context
) = decl
;
591 *chain
= &DECL_CHAIN (decl
);
597 /* @see coverage.c build_fn_info_type ( unsigned int )
598 for more examples on RECORD_TYPE's
600 Better still @see fortran/trans-types.c - gfc_get_desc_dim_type
602 typedef gpy_object_state_t * (*__callable)( void );
604 typedef struct gpy_callable_def_t {
605 char * ident; int n_args;
606 bool class; __callable call;
607 } gpy_callable_def_t;
611 tree
gpy_build_callable_record_type( void )
616 type
= make_node( RECORD_TYPE
);
618 TYPE_NAME(type
) = get_identifier("__gpy_callable_t");
619 TYPE_PACKED(type
) = 1;
621 /* Consists of the stride, lbound and ubound members. */
622 decl
= gpy_add_field_to_struct_1 (type
,
623 get_identifier ("ident"),
624 ptr_type_node
, &chain
);
626 decl
= gpy_add_field_to_struct_1 (type
,
627 get_identifier ("n_args"),
628 integer_type_node
, &chain
);
630 decl
= gpy_add_field_to_struct_1 (type
,
631 get_identifier ("class"),
632 boolean_type_node
, &chain
);
634 decl
= gpy_add_field_to_struct_1 (type
,
635 get_identifier ("call"),
636 ptr_type_node
, &chain
);
638 gpy_finish_type( type
);
643 void gpy_write_globals( void )
645 gpy_context_branch
*co
= NULL
;
646 gpy_symbol_obj
* it
= NULL
;
647 VEC(tree
,gc
) * main_stmts_vec
= VEC_alloc(tree
,gc
,0);
649 /* push a new context for local symbols */
650 co
= (gpy_context_branch
*)
651 xmalloc( sizeof(gpy_context_branch
) );
652 gpy_init_ctx_branch( &co
);
653 VEC_safe_push( gpy_ctx_t
, gc
, gpy_ctx_table
, co
);
656 for( idx
= 0; VEC_iterate(gpy_sym
,gpy_decls
,idx
,it
); ++idx
)
658 VEC(tree
,gc
) * x
= gpy_get_tree( it
, gpy_ctx_table
);
659 gcc_assert( x
); int itx
= 0; tree xt
;
660 for( ; VEC_iterate(tree
,x
,itx
,xt
); ++itx
)
662 if( TREE_CODE(xt
) == FUNCTION_DECL
)
664 VEC_safe_push( tree
,gc
,global_decls
,xt
);
666 else if( TREE_CODE(xt
) == VAR_DECL
)
668 VEC_safe_push( tree
,gc
,global_decls
,xt
);
672 VEC_safe_push( tree
,gc
,main_stmts_vec
,xt
);
677 /* Need to generate table of gpy_callable_def_t[] and gpy_type_obj_def_t[] */
678 VEC(constructor_elt
,gc
) *array_data
= NULL
;
682 VEC(constructor_elt
,gc
) *struct_data
;
683 const char * ident
= NULL
;
685 CONSTRUCTOR_APPEND_ELT (struct_data
, build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
688 build_string(strlen(ident
), ident
)
691 CONSTRUCTOR_APPEND_ELT (struct_data
, build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
694 build_int_cst(integer_type_node
, 0 )
697 CONSTRUCTOR_APPEND_ELT (struct_data
, build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
700 build_int_cst(boolean_type_node
,0)
703 CONSTRUCTOR_APPEND_ELT (struct_data
, build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
709 CONSTRUCTOR_APPEND_ELT (array_data
, NULL_TREE
,
710 build_constructor(gpy_build_callable_record_type(),struct_data
));
713 VEC(constructor_elt
,gc
) *struct_data
;
714 CONSTRUCTOR_APPEND_ELT (struct_data
, build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
720 CONSTRUCTOR_APPEND_ELT (struct_data
, build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
723 build_int_cst(integer_type_node
, 0 )
726 CONSTRUCTOR_APPEND_ELT (struct_data
, build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
729 build_int_cst(boolean_type_node
,0)
732 CONSTRUCTOR_APPEND_ELT (struct_data
, build_decl (BUILTINS_LOCATION
, FIELD_DECL
,
738 CONSTRUCTOR_APPEND_ELT (array_data
, NULL_TREE
,
739 build_constructor(gpy_build_callable_record_type(),struct_data
));
741 tree array_type
= build_array_type( gpy_build_callable_record_type(),
742 build_index_type( build_int_cst(integer_type_node
,table_len
) ));
744 tree array
= build_constructor(array_type
, array_data
);
745 tree table_decl
= build_decl(BUILTINS_LOCATION
,VAR_DECL
,
746 get_identifier("__gpy_module_main_callables"),
749 TREE_CONSTANT (table_decl
) = 1;
750 TREE_STATIC (table_decl
) = 1;
751 TREE_READONLY (table_decl
) = 1;
752 DECL_INITIAL (table_decl
) = array
;
754 /* Add in the main method decl! */
755 VEC_safe_push( tree
,gc
,global_decls
,gpy_main_method_decl( main_stmts_vec
,co
) );
756 /* Add the callables table */
757 VEC_safe_push( tree
,gc
,global_decls
,table_decl
);
759 VEC_pop( gpy_ctx_t
, gpy_ctx_table
);
761 tree itx
= NULL_TREE
; int idy
= 0; int global_vec_len
= VEC_length(tree
, global_decls
);
762 tree
* global_vec
= XNEWVEC( tree
, global_vec_len
);
763 for( idx
=0; VEC_iterate(tree
,global_decls
,idx
,itx
); ++idx
)
765 global_vec
[ idy
] = itx
;
769 debug("Finished processing!\n\n");
771 wrapup_global_declarations( global_vec
, global_vec_len
);
773 check_global_declarations( global_vec
, global_vec_len
);
774 emit_debug_global_declarations( global_vec
, global_vec_len
);
776 cgraph_finalize_compilation_unit( );
778 debug("finished passing to middle-end!\n\n");