changeset 114:e234ee7b7292

fix c-parser.c
author mir3636
date Fri, 17 Nov 2017 19:25:43 +0900
parents bdf41c9fa0b7
children 4cb7a319550d
files gcc/c/c-parser.c gcc/tree.h
diffstat 2 files changed, 188 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/gcc/c/c-parser.c	Fri Nov 17 06:33:55 2017 +0900
+++ b/gcc/c/c-parser.c	Fri Nov 17 19:25:43 2017 +0900
@@ -2771,7 +2771,7 @@
 
           if(!TARGET_64BIT) {
             attrs = build_tree_list (get_identifier("fastcall"), NULL_TREE);
-            declspecs_add_attrs(specs, attrs);
+            declspecs_add_attrs(loc, specs, attrs);
       }
 
           c_parser_consume_token (parser);
@@ -5497,10 +5497,49 @@
    which is not enclosed in braces and has an else clause.  This is used to
    implement -Wparentheses.  */
 
+static tree
+cbc_replace_arguments (location_t loc, tree call)
+{
+  tree arg;
+  tree fn;
+  tree tmp_decl;
+  int i=0;
+  call_expr_arg_iterator iter;
+
+  fn = CALL_EXPR_FN (call);
+  if ( TREE_CODE (fn)==PARM_DECL || !TREE_CONSTANT (fn) )
+    {
+      tmp_decl = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE(fn));
+      pushdecl (tmp_decl);
+
+      add_stmt (build_modify_expr (loc, tmp_decl, NULL_TREE, NOP_EXPR, loc, fn, NULL_TREE));
+      CALL_EXPR_FN (call) = tmp_decl;
+    }
+
+  FOR_EACH_CALL_EXPR_ARG (arg, iter, call) 
+    {
+      /* if ( !CONSTANT_CLASS_P (arg) && !VAR_OR_FUNCTION_DECL_P (arg) ) */
+      if ( TREE_CODE (arg)==PARM_DECL || !TREE_CONSTANT (arg) )
+       {
+         tmp_decl = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE(arg));
+         pushdecl (tmp_decl);
+
+         add_stmt (build_modify_expr (loc, tmp_decl, NULL_TREE, NOP_EXPR, loc, arg, NULL_TREE));
+         CALL_EXPR_ARG (call, i) = tmp_decl;
+       }
+       i++;
+    }
+
+  return call;
+}
+
 static void
 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
 				 vec<tree> *chain)
 {
+#ifndef noCbC
+  struct c_expr expr;
+#endif
   location_t loc = c_parser_peek_token (parser)->location;
   tree stmt = NULL_TREE;
   bool in_if_block = parser->in_if_block;
@@ -7951,6 +7990,146 @@
      Classname . identifier
 */
 
+static void
+cbc_finish_labeled_goto (location_t loc, tree label, tree retval)
+{
+  /* add statement below.
+   *
+   * if (0) {
+   *   _cbc_exit0:
+   *   return retval;
+   * }
+   */
+  tree tlab;
+  tree cond;
+
+  cond = integer_zero_node;
+  tree block_outside = c_begin_compound_stmt (false);
+  tree block_inside = c_begin_compound_stmt (false);
+
+  tree stmt = c_begin_compound_stmt (true);
+  tlab = define_label (loc, label);
+  gcc_assert (tlab);
+  decl_attributes (&tlab, NULL_TREE, 0);
+  TREE_USED (tlab) = 1;
+  /* add_stmt (LABEL_EXPR) */
+  add_stmt (build_stmt (loc, LABEL_EXPR, tlab));
+
+  /* add_stmt (RETURN_EXPR) */
+  tree ret = c_finish_return (loc, retval, retval);
+  DECL_READ_P(retval) = 1; // (NODE)->decl_common.decl_read_flag = 1;
+  //  TREE_USED(ret) = 1;
+  tree stmt_body = c_end_compound_stmt (loc, stmt, true);
+
+  /* add_stmt (STATEMENT_LIST) : STATEMENT_LIST -> LABEL_EXPR -> RETURN_EXPR */
+  add_stmt (stmt_body);
+  
+  tree body = c_end_compound_stmt (loc, block_inside, false);
+
+  /* add_stmt (COND_EXPR) */
+  c_finish_if_stmt (loc, cond, body, NULL_TREE);
+
+  /* add_stmt (BIND_EXPR) : BIND_EXPR -> COND_EXPR -> STATEMENT_LIST */
+  tree bind = c_end_compound_stmt (loc, block_outside, false);
+  TREE_SIDE_EFFECTS (bind) = 1;
+  add_stmt (bind);
+
+  TREE_USED (retval) = 1;
+
+}
+static tree
+cbc_finish_nested_function (location_t loc, tree label, tree retval_decl)
+{
+
+  /* add statement below.
+   * void ___cbc_internal_return(int _retval, void *_envp){
+   *   retval = _retval;
+   *   goto exit0;
+   * }
+   */
+  /* TODO:
+   * retval(lhs)のTREE_DECLを引数から取得するように
+   * int _retvalパラメータのタイプはretvalに合わせる
+   */
+
+  tree fnbody;
+  tree _retval_decl, _envp_decl;
+  struct c_declarator *declarator;
+  //tree ident;
+  struct c_arg_info *args;
+  struct c_declspecs *specs;
+  struct c_typespec t;
+  {
+    tree expr;
+    push_scope ();
+    declare_parm_level ();
+    /*tree retval_type = TREE_TYPE(retval_decl);*/
+
+    _retval_decl = build_decl (loc, PARM_DECL, get_identifier ("_retval"), TREE_TYPE(retval_decl));
+    DECL_SOURCE_LOCATION (_retval_decl) = loc;
+    DECL_ARTIFICIAL (_retval_decl) = 1;
+    DECL_ARG_TYPE (_retval_decl) = TREE_TYPE(retval_decl);
+    pushdecl (_retval_decl);
+    finish_decl (_retval_decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); 
+    _envp_decl = build_decl (loc, PARM_DECL, get_identifier ("_envp"), ptr_type_node);
+    DECL_SOURCE_LOCATION (_envp_decl) = loc;
+    DECL_ARTIFICIAL (_envp_decl) = 1;
+    DECL_ARG_TYPE (_envp_decl) = ptr_type_node;
+    pushdecl (_envp_decl);
+    finish_decl (_envp_decl, loc, NULL_TREE, NULL_TREE, NULL_TREE);
+    struct c_declarator declarator;
+    struct c_parm* parm;
+    struct c_declspecs *specs_parm = build_null_declspecs();
+    declspecs_add_type (loc, specs_parm, TREE_TYPE(retval_decl));
+    finish_declspecs (specs_parm);
+    parm = build_c_parm (specs_parm, NULL_TREE,
+                       &declarator, loc);
+
+    args = get_parm_info(false, expr);
+    pop_scope();
+  }
+
+  t.kind = ctsk_resword;
+  t.spec = get_identifier("void");
+  specs = build_null_declspecs();
+  declspecs_add_type (loc, specs, t);
+  finish_declspecs (specs);
+
+  /* make nested function.  */
+  declarator = build_id_declarator (get_identifier ("_cbc_internal_return"));
+  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);
+
+  add_stmt (build_modify_expr (loc, retval_decl, NULL_TREE, NOP_EXPR, loc, _retval_decl, NULL_TREE));
+  tree stmt = c_finish_goto_label (loc, label);
+
+  /* end compound statement.  */
+  fnbody = c_end_compound_stmt (loc, 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 (loc, DECL_EXPR, decl));
+  return decl;
+
+}
+
 static struct c_expr
 c_parser_postfix_expression (c_parser *parser)
 {
@@ -8626,7 +8805,8 @@
         TREE_USED (decl_cond) = 1;
 
         /* Use thread-local */
-        DECL_TLS_MODEL (decl_cond) = decl_default_tls_model (decl_cond);
+        //DECL_TLS_MODEL (decl_cond) = decl_default_tls_model (decl_cond);
+        set_decl_tls_model (decl_cond, decl_default_tls_model (decl_cond));
         DECL_NONLOCAL (decl_cond) = 1;
         DECL_ARTIFICIAL (decl_cond) = 1;
         add_stmt (build_stmt(location, DECL_EXPR,  pushdecl (decl_cond)));
@@ -8641,7 +8821,8 @@
         cbc_finish_labeled_goto (location, label, decl_cond);
 
         /* get pointer to nested function.  */
-        value = build_addr (decl , current_function_decl);
+        //value = build_addr (decl , current_function_decl);
+        value = build_addr (decl);
         TREE_USED (current_function_decl) = 1;
         SET_EXPR_LOCATION (value, location);
         add_stmt (value);
--- a/gcc/tree.h	Fri Nov 17 06:33:55 2017 +0900
+++ b/gcc/tree.h	Fri Nov 17 19:25:43 2017 +0900
@@ -4740,6 +4740,10 @@
 extern location_t tree_nonartificial_location (tree);
 extern tree block_ultimate_origin (const_tree);
 extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree);
+#ifndef noCbC
+extern tree build_addr (tree);
+#endif
+
 extern bool virtual_method_call_p (const_tree);
 extern tree obj_type_ref_class (const_tree ref);
 extern bool types_same_for_odr (const_tree type1, const_tree type2,