Mercurial > hg > CbC > CbC_gcc
comparison gcc/c-parser.c @ 1:caeb520cebed
patch for CbC
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 17:43:54 +0900 |
parents | a06113de4d67 |
children | 0b3575e68bac |
comparison
equal
deleted
inserted
replaced
0:a06113de4d67 | 1:caeb520cebed |
---|---|
55 #include "ggc.h" | 55 #include "ggc.h" |
56 #include "c-common.h" | 56 #include "c-common.h" |
57 #include "vec.h" | 57 #include "vec.h" |
58 #include "target.h" | 58 #include "target.h" |
59 #include "cgraph.h" | 59 #include "cgraph.h" |
60 #ifndef noCbC | |
61 #include "cbc-tree.h" | |
62 #endif | |
60 | 63 |
61 | 64 |
62 /* Initialization routine for this file. */ | 65 /* Initialization routine for this file. */ |
63 | 66 |
64 void | 67 void |
463 case RID_RESTRICT: | 466 case RID_RESTRICT: |
464 case RID_ATTRIBUTE: | 467 case RID_ATTRIBUTE: |
465 case RID_FRACT: | 468 case RID_FRACT: |
466 case RID_ACCUM: | 469 case RID_ACCUM: |
467 case RID_SAT: | 470 case RID_SAT: |
471 #ifndef noCbC | |
472 case RID_CbC_CODE: | |
473 #endif | |
474 #ifndef noCbC | |
475 case RID_CbC_CODE: | |
476 #endif | |
468 return true; | 477 return true; |
469 default: | 478 default: |
470 return false; | 479 return false; |
471 } | 480 } |
472 case CPP_LESS: | 481 case CPP_LESS: |
1516 case RID_DFLOAT128: | 1525 case RID_DFLOAT128: |
1517 case RID_BOOL: | 1526 case RID_BOOL: |
1518 case RID_FRACT: | 1527 case RID_FRACT: |
1519 case RID_ACCUM: | 1528 case RID_ACCUM: |
1520 case RID_SAT: | 1529 case RID_SAT: |
1530 #ifndef noCbC | |
1531 case RID_CbC_CODE: | |
1532 #endif | |
1521 if (!typespec_ok) | 1533 if (!typespec_ok) |
1522 goto out; | 1534 goto out; |
1523 attrs_ok = true; | 1535 attrs_ok = true; |
1524 seen_type = true; | 1536 seen_type = true; |
1525 if (c_dialect_objc ()) | 1537 if (c_dialect_objc ()) |
3699 case RID_FOR: | 3711 case RID_FOR: |
3700 c_parser_for_statement (parser); | 3712 c_parser_for_statement (parser); |
3701 break; | 3713 break; |
3702 case RID_GOTO: | 3714 case RID_GOTO: |
3703 c_parser_consume_token (parser); | 3715 c_parser_consume_token (parser); |
3716 #ifndef noCbC | |
3717 if ( c_parser_next_token_is (parser, CPP_NAME) | |
3718 && c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON ) | |
3719 { | |
3720 #else | |
3704 if (c_parser_next_token_is (parser, CPP_NAME)) | 3721 if (c_parser_next_token_is (parser, CPP_NAME)) |
3705 { | 3722 { |
3723 #endif | |
3706 stmt = c_finish_goto_label (c_parser_peek_token (parser)->value); | 3724 stmt = c_finish_goto_label (c_parser_peek_token (parser)->value); |
3707 c_parser_consume_token (parser); | 3725 c_parser_consume_token (parser); |
3708 } | 3726 } |
3709 else if (c_parser_next_token_is (parser, CPP_MULT)) | 3727 else if (c_parser_next_token_is (parser, CPP_MULT)) |
3710 { | 3728 { |
3711 c_parser_consume_token (parser); | 3729 c_parser_consume_token (parser); |
3712 stmt = c_finish_goto_ptr (c_parser_expression (parser).value); | 3730 stmt = c_finish_goto_ptr (c_parser_expression (parser).value); |
3713 } | 3731 } |
3714 else | 3732 else |
3733 #ifndef noCbC | |
3734 { | |
3735 struct c_expr expr; | |
3736 if (c_parser_next_token_is (parser, CPP_NAME)) | |
3737 { | |
3738 tree id = c_parser_peek_token (parser)->value; | |
3739 location_t loc = c_parser_peek_token (parser)->location; | |
3740 build_external_ref (id,RID_CbC_CODE , loc); | |
3741 } | |
3742 expr = c_parser_expr_no_commas (parser, NULL); | |
3743 if (TREE_CODE(expr.value) == CALL_EXPR ) | |
3744 { | |
3745 TREE_TYPE(expr.value) = void_type_node; | |
3746 if (c_parser_next_token_is (parser, CPP_COMMA)) | |
3747 { | |
3748 struct c_expr env; | |
3749 tree field, fields=NULL_TREE; | |
3750 tree env_struct, env_struct_type; | |
3751 tree ebp, argsp; | |
3752 tree tmp; | |
3753 | |
3754 c_parser_consume_token (parser); | |
3755 env = c_parser_expr_no_commas (parser, NULL); | |
3756 env = default_function_array_conversion (env); | |
3757 | |
3758 /* build type_node of environment structure */ | |
3759 env_struct_type = start_struct (RECORD_TYPE, NULL_TREE); | |
3760 field = build_decl (FIELD_DECL, get_identifier("sp"), ptr_type_node); | |
3761 fields = chainon (field, fields); | |
3762 field = build_decl (FIELD_DECL, get_identifier("argsp"), ptr_type_node); | |
3763 fields = chainon (field, fields); | |
3764 //field = build_decl (FIELD_DECL, get_identifier("retval"), intSI_type_node); | |
3765 //fields = chainon (field, fields); | |
3766 fields = nreverse(fields); | |
3767 finish_struct (env_struct_type, fields, NULL_TREE); | |
3768 | |
3769 env_struct = build_c_cast (build_pointer_type(env_struct_type), env.value); | |
3770 //build_component_ref (cbc_env, get_identifier("argsp")); | |
3771 ebp = build_component_ref (build_indirect_ref (env_struct, "CbCenv->sp"), get_identifier("sp")); | |
3772 argsp = build_component_ref (build_indirect_ref (env_struct, "CbCenv->sp"), get_identifier("argsp")); | |
3773 //ebp = chainon (ebp, argsp); | |
3774 tmp = build_tree_list (ebp, argsp); | |
3775 | |
3776 TREE_OPERAND (expr.value, 2) = tmp; | |
3777 | |
3778 | |
3779 /* | |
3780 c_parser_consume_token (parser); | |
3781 expr = default_function_array_conversion (expr); | |
3782 ident = c_parser_peek_token (parser)->value; | |
3783 c_parser_consume_token (parser); | |
3784 expr.value = build_component_ref (build_indirect_ref (expr.value, | |
3785 "->"), ident); | |
3786 expr.original_code = ERROR_MARK; | |
3787 */ | |
3788 | |
3789 | |
3790 } | |
3791 else | |
3792 TREE_OPERAND (expr.value, 2) = NULL_TREE; | |
3793 CbC_IS_CbC_GOTO (expr.value) = 1; | |
3794 CALL_EXPR_TAILCALL (expr.value) = 1; | |
3795 add_stmt(expr.value); | |
3796 CbC_HAVE_CbC_GOTO (current_function_decl) = 1; | |
3797 // should be match with function type? | |
3798 stmt = c_finish_return (0); | |
3799 } | |
3800 else | |
3801 c_parser_error (parser, "expected code segment jump or %<*%>"); | |
3802 } | |
3803 #else | |
3715 c_parser_error (parser, "expected identifier or %<*%>"); | 3804 c_parser_error (parser, "expected identifier or %<*%>"); |
3805 #endif | |
3716 goto expect_semicolon; | 3806 goto expect_semicolon; |
3717 case RID_CONTINUE: | 3807 case RID_CONTINUE: |
3718 c_parser_consume_token (parser); | 3808 c_parser_consume_token (parser); |
3719 stmt = c_finish_bc_stmt (&c_cont_label, false); | 3809 stmt = c_finish_bc_stmt (&c_cont_label, false); |
3720 goto expect_semicolon; | 3810 goto expect_semicolon; |
5091 static struct c_expr | 5181 static struct c_expr |
5092 c_parser_postfix_expression (c_parser *parser) | 5182 c_parser_postfix_expression (c_parser *parser) |
5093 { | 5183 { |
5094 struct c_expr expr, e1, e2, e3; | 5184 struct c_expr expr, e1, e2, e3; |
5095 struct c_type_name *t1, *t2; | 5185 struct c_type_name *t1, *t2; |
5186 static tree return_label1; | |
5096 location_t loc; | 5187 location_t loc; |
5097 switch (c_parser_peek_token (parser)->type) | 5188 switch (c_parser_peek_token (parser)->type) |
5098 { | 5189 { |
5099 case CPP_NUMBER: | 5190 case CPP_NUMBER: |
5100 expr.value = c_parser_peek_token (parser)->value; | 5191 expr.value = c_parser_peek_token (parser)->value; |
5488 tree type = groktypename (t1); | 5579 tree type = groktypename (t1); |
5489 expr.value = objc_build_encode_expr (type); | 5580 expr.value = objc_build_encode_expr (type); |
5490 expr.original_code = ERROR_MARK; | 5581 expr.original_code = ERROR_MARK; |
5491 } | 5582 } |
5492 break; | 5583 break; |
5584 #ifndef noCbC | |
5585 case RID_CbC_ENV: | |
5586 { | |
5587 #if 0 | |
5588 tree valuep_tree; | |
5589 tree value_tree; | |
5590 tree env_tree; | |
5591 | |
5592 tree exprstmt; | |
5593 tree stmt = c_begin_stmt_expr (); | |
5594 /* | |
5595 * __value = { | |
5596 * void *ebp; | |
5597 * char args[sizeof(arguments)]; | |
5598 * }; | |
5599 * | |
5600 * __env = ({ | |
5601 * ebp = __builtin_frame_address(0); | |
5602 * *__value=ebp; | |
5603 * __value; | |
5604 * }) | |
5605 */ | |
5606 | |
5607 /* get value of %ebp. */ | |
5608 env_tree = build_external_ref ( | |
5609 get_identifier ("__builtin_frame_address"), 0, | |
5610 c_parser_peek_token (parser)->location); | |
5611 env_tree = build_function_call(env_tree, | |
5612 build_tree_list (NULL_TREE, build_int_cst (NULL_TREE,0))); | |
5613 | |
5614 /* ebp = __builtin_frame_address(0) */ | |
5615 valuep_tree = build_decl (VAR_DECL, get_identifier("__value"), intTI_type_node); | |
5616 TREE_STATIC (valuep_tree) = 1; | |
5617 lang_hooks.decls.pushdecl(valuep_tree); | |
5618 /* cast __value to pointer to pointer to void. */ | |
5619 valuep_tree = build_c_cast (build_pointer_type(ptr_type_node), valuep_tree); | |
5620 value_tree = build_indirect_ref (valuep_tree, "cbc: *__value"); | |
5621 | |
5622 /* *__value = ebp; */ | |
5623 exprstmt = build_modify_expr (value_tree, NOP_EXPR, env_tree); | |
5624 add_stmt(exprstmt); | |
5625 | |
5626 /* __value; */ | |
5627 add_stmt(valuep_tree); | |
5628 #else | |
5629 | |
5630 //tree env; // environment structure | |
5631 tree env_struct; // type of environment structure | |
5632 tree field; | |
5633 tree fields=NULL_TREE; | |
5634 tree comp, comp0; // component of environment | |
5635 tree ebp; | |
5636 | |
5637 tree stmt = c_begin_stmt_expr (); | |
5638 | |
5639 /* | |
5640 * struct { | |
5641 * void *sp; <= %ebp | |
5642 * void *argp; <= &__environment.retval | |
5643 * int retval; // int? or return type of this function | |
5644 * } __CbCenv; | |
5645 * | |
5646 * __environment = &__CbCenv; | |
5647 * | |
5648 */ | |
5649 | |
5650 if (!cbc_env) | |
5651 { | |
5652 /* build type_node of environment structure */ | |
5653 env_struct = start_struct (RECORD_TYPE, NULL_TREE); | |
5654 field = build_decl (FIELD_DECL, get_identifier("sp"), ptr_type_node); | |
5655 fields = chainon (field, fields); | |
5656 field = build_decl (FIELD_DECL, get_identifier("argsp"), ptr_type_node); | |
5657 fields = chainon (field, fields); | |
5658 field = build_decl (FIELD_DECL, get_identifier("retval"), intSI_type_node); | |
5659 fields = chainon (field, fields); | |
5660 fields = nreverse(fields); | |
5661 //env_struct = make_node(RECORD_TYPE); | |
5662 //TYPE_FIELDS (env_struct) = fields; | |
5663 finish_struct (env_struct, fields, NULL_TREE); | |
5664 | |
5665 /* declare __environment structure. */ | |
5666 cbc_env = build_decl (VAR_DECL, get_identifier("__CbCenv"), env_struct); | |
5667 TREE_STATIC (cbc_env) = 1; | |
5668 lang_hooks.decls.pushdecl(cbc_env); | |
5669 } | |
5670 | |
5671 /* get value of %ebp. */ | |
5672 ebp = build_external_ref ( | |
5673 get_identifier ("__builtin_frame_address"), 0, | |
5674 c_parser_peek_token (parser)->location); | |
5675 ebp = build_function_call(ebp, | |
5676 build_tree_list (NULL_TREE, build_int_cst (NULL_TREE,0))); | |
5677 | |
5678 /* assignment void *sp = %ebp */ | |
5679 comp = build_component_ref (cbc_env, get_identifier("sp")); | |
5680 add_stmt (build_modify_expr (comp, NOP_EXPR, ebp)); | |
5681 | |
5682 /* void *argsp = &__environment.retval */ | |
5683 comp = build_component_ref (cbc_env, get_identifier("argsp")); | |
5684 comp0 = build_component_ref (cbc_env, get_identifier("retval")); | |
5685 comp0 = build_unary_op (ADDR_EXPR, comp0, 0); | |
5686 add_stmt (build_modify_expr (comp, NOP_EXPR, comp0)); | |
5687 | |
5688 | |
5689 /* &__environment for value of stmt_expr. */ | |
5690 add_stmt (build_unary_op (ADDR_EXPR, cbc_env, 0)); | |
5691 #endif | |
5692 //expr.value = valuep_tree; | |
5693 TREE_SIDE_EFFECTS (stmt) = 1; | |
5694 expr.value = c_finish_stmt_expr (stmt); | |
5695 //expr.value = build_unary_op (ADDR_EXPR, env, 0); | |
5696 c_parser_consume_token (parser); | |
5697 } | |
5698 break; | |
5699 case RID_CbC_RET: | |
5700 case RID_RETURN: | |
5701 #if 1 | |
5702 if (cbc_return_f==0) { | |
5703 tree retval; | |
5704 | |
5705 /* | |
5706 Generates something like... | |
5707 | |
5708 __return = ({ | |
5709 static volatile int __return; | |
5710 if (__return) { | |
5711 return_label: | |
5712 return value; | |
5713 } | |
5714 &&return_label; | |
5715 }) | |
5716 */ | |
5717 | |
5718 tree stmt = c_begin_stmt_expr (); | |
5719 cbc_return_f = c_parser_peek_token (parser)->value; | |
5720 cbc_return = c_parser_peek_token (parser)->location; | |
5721 c_parser_consume_token (parser); | |
5722 location_t next = c_parser_peek_token (parser)->location; | |
5723 | |
5724 // dummy variable for hidden condition | |
5725 struct c_expr cexpr; | |
5726 tree cond; | |
5727 location_t loc; | |
5728 loc = next; | |
5729 tree decl_cond = | |
5730 build_decl (VAR_DECL, get_identifier ("__return"), | |
5731 intHI_type_node); | |
5732 TREE_STATIC (decl_cond) = 1; | |
5733 cexpr.value = lang_hooks.decls.pushdecl(decl_cond); | |
5734 | |
5735 cexpr.original_code = ERROR_MARK; | |
5736 cond = c_objc_common_truthvalue_conversion(cexpr.value); | |
5737 if (EXPR_P (cond)) | |
5738 SET_EXPR_LOCATION (cond, loc); | |
5739 | |
5740 | |
5741 | |
5742 | |
5743 tree fwlabel = create_artificial_label (); | |
5744 //TREE_USED(fwlabel) = 1; | |
5745 | |
5746 //add_stmt (build1 (GOTO_EXPR, void_type_node, fwlabel)); | |
5747 tree block = c_begin_compound_stmt (flag_isoc99); | |
5748 | |
5749 tree tlab = lookup_label(cbc_return_f); | |
5750 | |
5751 tree decl= build_stmt (LABEL_EXPR, tlab); | |
5752 //TREE_USED(decl) = 1; | |
5753 add_stmt(decl); | |
5754 | |
5755 //tree hoge = build_int_cst(NULL_TREE,55); | |
5756 if (!cbc_env) | |
5757 { | |
5758 tree field,fields,env_struct; | |
5759 /* build type_node of environment structure */ | |
5760 env_struct = start_struct (RECORD_TYPE, NULL_TREE); | |
5761 field = build_decl (FIELD_DECL, get_identifier("sp"), ptr_type_node); | |
5762 fields = chainon (field, fields); | |
5763 field = build_decl (FIELD_DECL, get_identifier("argsp"), ptr_type_node); | |
5764 fields = chainon (field, fields); | |
5765 field = build_decl (FIELD_DECL, get_identifier("retval"), intSI_type_node); | |
5766 fields = chainon (field, fields); | |
5767 fields = nreverse(fields); | |
5768 //env_struct = make_node(RECORD_TYPE); | |
5769 //TYPE_FIELDS (env_struct) = fields; | |
5770 finish_struct (env_struct, fields, NULL_TREE); | |
5771 | |
5772 /* declare __environment structure. */ | |
5773 cbc_env = build_decl (VAR_DECL, get_identifier("__CbCenv"), env_struct); | |
5774 TREE_STATIC (cbc_env) = 1; | |
5775 lang_hooks.decls.pushdecl(cbc_env); | |
5776 } | |
5777 retval = build_component_ref (cbc_env, get_identifier("retval")); | |
5778 tree ret = c_finish_return (retval); | |
5779 TREE_USED(ret) = 1; | |
5780 tree first_body = c_end_compound_stmt (block, flag_isoc99); | |
5781 | |
5782 c_finish_if_stmt (loc, cond, first_body, NULL_TREE, false); | |
5783 | |
5784 // define_label(EXPR_LOCATION(decl) ,cbc_return_f); | |
5785 return_label1 = | |
5786 define_label(cbc_return ,cbc_return_f); | |
5787 tree fwdef= build_stmt (LABEL_EXPR, fwlabel); | |
5788 | |
5789 //TREE_USED(fwdef) = 1; | |
5790 add_stmt(fwdef); | |
5791 TREE_SIDE_EFFECTS (block) = 1; | |
5792 | |
5793 // tree label = lookup_label(c_parser_peek_token (parser)->value); | |
5794 //TREE_USED(label) = 1; | |
5795 | |
5796 tree value = build1(ADDR_EXPR, ptr_type_node, return_label1); | |
5797 SET_EXPR_LOCATION (value, next); | |
5798 TREE_SIDE_EFFECTS (value) = 1; | |
5799 add_stmt(value); | |
5800 | |
5801 TREE_SIDE_EFFECTS (stmt) = 1; | |
5802 expr.value = c_finish_stmt_expr (stmt); | |
5803 expr.original_code = ERROR_MARK; | |
5804 | |
5805 // cbc_return_f =0; | |
5806 | |
5807 } else { | |
5808 //tree label = lookup_label(c_parser_peek_token (parser)->value); | |
5809 //TREE_USED(label) = 1; | |
5810 //expr.value = build1(ADDR_EXPR, ptr_type_node, label); | |
5811 expr.value = build1(ADDR_EXPR, ptr_type_node, return_label1); | |
5812 c_parser_consume_token (parser); | |
5813 } | |
5814 break; | |
5815 #endif | |
5816 #endif | |
5493 default: | 5817 default: |
5494 c_parser_error (parser, "expected expression"); | 5818 c_parser_error (parser, "expected expression"); |
5495 expr.value = error_mark_node; | 5819 expr.value = error_mark_node; |
5496 expr.original_code = ERROR_MARK; | 5820 expr.original_code = ERROR_MARK; |
5497 break; | 5821 break; |