changeset 10:26e357f6275f

add cbc_make_nested_function
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Tue, 08 Sep 2009 21:04:27 +0900
parents ddf292032e7d
children 8f2e43f937f3
files gcc/c-parser.c
diffstat 1 files changed, 141 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/gcc/c-parser.c	Wed Aug 26 15:11:42 2009 +0900
+++ b/gcc/c-parser.c	Tue Sep 08 21:04:27 2009 +0900
@@ -59,6 +59,7 @@
 #include "cgraph.h"
 #ifndef noCbC
 #include "cbc-tree.h"
+static tree cbc_make_nested_function (location_t);
 #endif
 
 
@@ -3795,8 +3796,11 @@
 		  tree env = NULL_TREE;
 //		  if (c_parser_next_token_is (parser, CPP_COMMA)) 
 //		    env = c_parser_cbc_make_env(parser);
-		  CbC_IS_CbC_GOTO (expr.value) = 1;
-		  CALL_EXPR_TAILCALL (expr.value) = 1;
+		  if (CbC_IS_CODE_SEGMENT(TREE_TYPE(current_function_decl)))
+		    {
+		      CbC_IS_CbC_GOTO (expr.value) = 1;
+		      CALL_EXPR_TAILCALL (expr.value) = 1;
+		    }
 		  add_stmt(expr.value);
 		  CbC_HAVE_CbC_GOTO (current_function_decl) = 1;
 		  // should be match with function type?
@@ -5603,7 +5607,9 @@
 	case RID_CbC_RET:
 	case RID_RETURN:
 
- if (cbc_return_f==0) {  tree retval; 
+#if 0
+	  if (cbc_return_f==0)
+	    {  tree retval; 
 
               /*
                    Generates something like...
@@ -5694,15 +5700,40 @@
 	      expr.value = c_finish_stmt_expr (stmt);
 	      expr.original_code = ERROR_MARK;
 
-	  } else {
+
+	    }
+	  else
+	    {
 	      //tree label = lookup_label(c_parser_peek_token (parser)->value);
 	      //TREE_USED(label) = 1;
 	      //expr.value = build1(ADDR_EXPR, ptr_type_node, label);
 	      expr.value = build1(ADDR_EXPR, ptr_type_node, return_label1);
 	      c_parser_consume_token (parser);
-          }
-	  break;
-#endif
+            }
+#else //by KENT.
+	  {
+	  c_parser_consume_token (parser);
+
+	  tree stmt = c_begin_stmt_expr ();
+	  cbc_return_f = c_parser_peek_token (parser)->value;
+	  location_t location = c_parser_peek_token (parser)->location;
+
+	  //add_stmt (cbc_make_nested_function (location));
+	  tree nested_func = cbc_make_nested_function (location);
+	  add_stmt (build_stmt (DECL_EXPR, nested_func));
+
+	  tree value = build_addr (nested_func , current_function_decl);
+	  SET_EXPR_LOCATION (value, location);
+	  add_stmt (value);
+
+	  TREE_SIDE_EFFECTS (stmt) = 1;
+	  expr.value = c_finish_stmt_expr (stmt);
+	  expr.original_code = ERROR_MARK;
+	  }
+	  
+#endif //0
+	  break;
+#endif  //noCbC
 	default:
 	  c_parser_error (parser, "expected expression");
 	  expr.value = error_mark_node;
@@ -5734,6 +5765,109 @@
   return c_parser_postfix_expression_after_primary (parser, expr);
 }
 
+static tree
+cbc_make_nested_function (location_t loc)
+{
+
+  /*
+   * void __return_func(int _retval, void *fp){
+   *   retval = _retval;
+   *   goto exit0;
+   * }
+   */
+
+  tree fnbody;
+  struct c_declarator *declarator;
+  tree ident;
+  struct c_arg_info *args;
+  struct c_declspecs *specs;
+  struct c_typespec t;
+
+  { /* nested function's parameters (int _retval,void *fp) */
+    struct c_declspecs *_retval_specs,
+		       *_envp_specs;
+    struct c_declarator*_retval_decl,
+		       *_envp_decl;
+    struct c_parm      *_retval,
+		       *_envp;
+    tree                _retval_ident,
+			_envp_ident;
+    struct c_typespec t;
+
+    push_scope ();
+    declare_parm_level ();
+
+    _retval_specs = build_null_declspecs();
+    t.kind = ctsk_resword;
+    //t.spec = integer_type_node;
+    t.spec = get_identifier("int");
+    declspecs_add_type (_retval_specs, t);
+    finish_declspecs (_retval_specs);
+    _retval_decl = build_id_declarator (get_identifier ("_retval"));
+    _retval = build_c_parm (_retval_specs, NULL_TREE, _retval_decl);
+
+    push_parm_decl(_retval);
+
+    _envp_specs = build_null_declspecs();
+    t.kind = ctsk_resword;
+    t.spec = get_identifier("void");
+    declspecs_add_type (_envp_specs, t);
+    finish_declspecs (_envp_specs);
+    _envp_decl = build_id_declarator (get_identifier ("_envp"));
+    _envp_decl = make_pointer_declarator (build_null_declspecs (), _envp_decl);
+    _envp   = build_c_parm (_envp_specs, NULL_TREE, _envp_decl);
+
+    push_parm_decl(_envp);
+
+    args = get_parm_info(false);
+    pop_scope();
+  }
+
+  t.kind = ctsk_resword;
+  t.spec = get_identifier("void");
+  specs = build_null_declspecs();
+  declspecs_add_type (specs, t);
+  finish_declspecs (specs);
+
+  /* make nested function.  */
+  //ident = build_decl (/*TODO:*/VAR_DECL, get_identifier ("_cbc_internal_return"), specs->type);
+  declarator = build_id_declarator (get_identifier ("_cbc_internal_return"));
+  //declarator->id_loc = ;
+  declarator = build_function_declarator (args, declarator);
+
+  c_push_function_context ();
+
+  if (!start_function (specs, declarator, NULL_TREE))
+    {
+      c_pop_function_context();
+      gcc_assert (0);
+    }
+  store_parm_decls ();
+
+
+  /* start compound statement.  */
+  tree cstmt = c_begin_compound_stmt (true);
+
+  tree lhs = build_external_ref (get_identifier("retval"), false, loc);
+  tree rhs = build_external_ref (get_identifier("_retval"), false, loc);
+  add_stmt (build_modify_expr (loc, lhs, NOP_EXPR, rhs));
+  tree stmt = c_finish_goto_label (get_identifier ("_cbc_exit0"));
+
+  /* end compound statement.  */
+  fnbody = c_end_compound_stmt (cstmt, true);
+  TREE_SIDE_EFFECTS (cstmt) = 1;
+
+  /* finish declaration of nested function.  */
+  tree decl = current_function_decl;
+  add_stmt (fnbody);
+  finish_function ();
+  c_pop_function_context ();
+
+  //add_stmt (build_stmt (DECL_EXPR, decl));
+  //return build_stmt (DECL_EXPR, decl);
+  return decl;
+}
+
 /* Parse a postfix expression after a parenthesized type name: the
    brace-enclosed initializer of a compound literal, possibly followed
    by some postfix operators.  This is separate because it is not