Make-lang.in (TREE_BE_LIBS): Remove.
authorJames A. Morrison <phython@gcc.gnu.org>
Sun, 8 Aug 2004 04:47:17 +0000 (04:47 +0000)
committerJames A. Morrison <phython@gcc.gnu.org>
Sun, 8 Aug 2004 04:47:17 +0000 (04:47 +0000)
treelang:
2004-08-01  James A. Morrison  <phython@gcc.gnu.org>

        * Make-lang.in (TREE_BE_LIBS): Remove.
        (tree1): Depend on BACKEND and LIBDEPS.  Use BACKEND and LIBS instead
        of TREE_BE_LIBS.
        * parse.y: Add variable_defs_opt before statements_opt.
        Use tree_code_get_type instead of get_type_for_numeric_type.
        Reformat long lines.
        (parameters_opt): New rule.
        (function_prototype): Use parameters_opt.
        (return): Remove calls to print_token in error cases.  Use VOID_TYPE.
        (check_type_match): Use VOID_TYPE.
        * lex.l (update_lineno_charno): Ensure INPUT_LINE starts at 1.
        * tree1.c: Include version.h and cgraph.h
        (treelang_parse_file): Call cgraph_finalize_compilation_unit and
        cgraph_optimize.
        * treelang.h (item): Remove extraneous GTY.
        * treetree.h (get_type_for_numeric_type): Remove.
        * treetree.c: Include tree-dump.h, tree-iterator.h, tree-gimple.h,
        function.h, and cgraph.h.  Don't include rtl.h
        (keep_level_p): Remove.
        (tree_push_atomic_type_decl): Remove.
         (get_type_for_numeric_type): Remove.
        (tree_code_get_numeric_type): Remove.
        (global_bindings_p): Make static.
        (getdecls): Likewise.
        (insert_block): Likewise.
        (tree_code_if_start): Create a COND_EXPR and add it to the tree
        instead of creating rtl.
        (tree_code_if_else): Create a BIND_EXPR if any variables were created
        in the if statement.
        (tree_code_end_if): Likewise.
        (tree_code_create_function_prototype): Use tree_code_get_type.
        Don't use SET_DECL_ASSEMBLER_NAME.
        (tree_code_create_function_initial): Set DECL_ARTIFICIAL and
        DECL_IGNORING_P on RESULT_DECL.  Use tree_code_get_type.  Don't call
        layout_decl on RESULT_DECL.  Don't call rtl expand functions.
        (tree_code_create_function_wrapup): Don't call rtl expand functions.
        Create a BIND_EXPR for each function.  Dump original and gimplified
        copies of the function tree.  Gimplify function.
        (tree_code_create_variable): Use tree_code_get_type.  Don't call
        layout_decl or expand_decl.  Fold CONVERT_EXPRs.
        (tree_code_generate_return): Fold CONVERT_EXPRs and MODIFY_EXPRs.
        Add RETURN_EXPR to the current statement list.  Don't call rtl expand
        functions.
        (tree_code_output_expression_statement): Append CODE to current
        statement list.
        (tree_code_get_expression): Fold expressions.  Build a pointer to
        a FUNCTION_TYPE intead of the called functions return type.
        (struct binding_level): Add statement list STMTS.
        (getstmtlist): New Function.
        (pushlevel): Make static.  Allocate an empty statement list.
        (poplevel): Make static.  Don't clear BLOCK_NODE's BLOCK_VARS.
        Don't use DECL_ASSEMBLER_NAME.
        (tree_push_type_decl): Set TYPE_NAME of TYPE_NODE to ID.
        (treelang_init_decl_processing): Define basic types after unused types.
        Don't call tree_push_atomic_type_decl.
        (builtin_function): Don't call make_decl_rtl.
        (treelang_expand_function). New Function.

testsuite/treelang:
        * compile/vars_def.tree: New File.
        * compile/badreturn.tree: New File.

From-SVN: r85684

15 files changed:
gcc/testsuite/treelang/ChangeLog
gcc/testsuite/treelang/a01gcci01.c
gcc/testsuite/treelang/compile/badreturn.tree [new file with mode: 0644]
gcc/testsuite/treelang/compile/compile.exp [new file with mode: 0644]
gcc/testsuite/treelang/compile/full_unit.tree [new file with mode: 0644]
gcc/testsuite/treelang/compile/tabs.tree [new file with mode: 0644]
gcc/testsuite/treelang/compile/var_defs.tree [new file with mode: 0644]
gcc/treelang/ChangeLog
gcc/treelang/Make-lang.in
gcc/treelang/lex.l
gcc/treelang/parse.y
gcc/treelang/tree1.c
gcc/treelang/treelang.h
gcc/treelang/treetree.c
gcc/treelang/treetree.h

index 5a594a12c6de458e3d59b088c8f68261fa27a043..e0e38637a60fb7b468351724ef34fcdfd4954551 100644 (file)
@@ -1,3 +1,8 @@
+2004-07-31  James A. Morrison  <phython@gcc.gnu.org>
+
+       * compile/vars_def.tree: New File.
+       * compile/badreturn.tree: New File.
+
 2004-01-18  James A. Morrison  <ja2morri@uwaterloo.ca>
 
         * compile/compile.exp: New File.
index 4d857fac9cbe98ef9d65df0835a0c8ec91dfaabc..b7140199d4d88b4aaaf108ff5d01eb6023dfc791 100644 (file)
@@ -27,6 +27,7 @@
 int add(int, int);
 int subtract(int, int);
 int first_nonzero(int, int);
+extern int printf(char *template, ...);
 
 int 
 main (int argc, char *argv[])
diff --git a/gcc/testsuite/treelang/compile/badreturn.tree b/gcc/testsuite/treelang/compile/badreturn.tree
new file mode 100644 (file)
index 0000000..60d3b12
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-do compile }
+
+external_definition void bar ();
+external_definition int gar (int arg0);
+
+bar
+{
+       return 0; // { dg-warning "return" }
+}
+
+gar
+{
+       return; // { dg-error "return" }
+}
diff --git a/gcc/testsuite/treelang/compile/compile.exp b/gcc/testsuite/treelang/compile/compile.exp
new file mode 100644 (file)
index 0000000..836c325
--- /dev/null
@@ -0,0 +1,31 @@
+# Tests for treelang; run from gcc/treelang/Make-lang.in => gcc/Makefile
+
+# Copyright (C) 2004 by The Free Software Foundation
+
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+# In other words, you are welcome to use, share and improve this program.
+# You are forbidden to forbid anyone else to use, share and improve
+# what you give them.   Help stamp out software-hoarding!
+
+# Treelang tests that only need to compile.
+
+# Load support procs.
+load_lib treelang-dg.exp
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.tree]] "" ""
+dg-finish
diff --git a/gcc/testsuite/treelang/compile/full_unit.tree b/gcc/testsuite/treelang/compile/full_unit.tree
new file mode 100644 (file)
index 0000000..2d50323
--- /dev/null
@@ -0,0 +1,16 @@
+// { dg-do compile }
+// { dg-options "-funit-at-a-time" }
+external_definition int add (int arga, int argb);
+external_definition char sub (char argc, char argd);
+
+add
+{
+       return arga + argb + +3;
+}
+
+sub
+{
+       return argd - argc + +2;
+}
+// { dg-final { scan-assembler "add" } }
+// { dg-final { scan-assembler "sub" } }
diff --git a/gcc/testsuite/treelang/compile/tabs.tree b/gcc/testsuite/treelang/compile/tabs.tree
new file mode 100644 (file)
index 0000000..6294c15
--- /dev/null
@@ -0,0 +1,11 @@
+// { dg-do compile }
+external_definition int main(int argc);
+
+main {
+       automatic int v1;
+       automatic int v2;
+       v1 = argc;
+       v2 = 3;
+
+        return v2;
+}
diff --git a/gcc/testsuite/treelang/compile/var_defs.tree b/gcc/testsuite/treelang/compile/var_defs.tree
new file mode 100644 (file)
index 0000000..ed03b62
--- /dev/null
@@ -0,0 +1,39 @@
+// { dg-do compile }
+external_definition void boring (int arg0);
+external_definition char condition (char arg1, char arg2);
+external_definition int first_nonzero (int arg5, int arg6);
+
+boring
+{
+  arg0 = +5  + +3;  // Force 3 and 5 to be signed numbers.
+  arg0 = arg0 + +3;
+}
+
+condition
+{
+  if (arg1)
+    {
+      automatic int i;
+      return arg1;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+first_nonzero
+{
+  if (arg5)
+    {
+      return arg5;
+    }
+  else
+    {
+      automatic int j;
+      j = arg6;
+      return j;
+    }
+  return arg6;
+}
+
index bd6955ff3a32f99c02ac621880ab8b571e5718e8..73d367fe2e75b667463d51e1618706dbd9026f9f 100644 (file)
@@ -1,3 +1,63 @@
+2004-07-31  James A. Morrison  <phython@gcc.gnu.org>
+
+       * Make-lang.in (TREE_BE_LIBS): Remove.
+       (tree1): Depend on BACKEND and LIBDEPS.  Use BACKEND and LIBS instead
+       of TREE_BE_LIBS.
+       * parse.y: Add variable_defs_opt before statements_opt.
+       Use tree_code_get_type instead of get_type_for_numeric_type.
+       Reformat long lines.
+       (parameters_opt): New rule.
+       (function_prototype): Use parameters_opt.
+       (return): Remove calls to print_token in error cases.  Use VOID_TYPE.
+       (check_type_match): Use VOID_TYPE.
+       * lex.l (update_lineno_charno): Ensure INPUT_LINE starts at 1.
+       * tree1.c: Include version.h and cgraph.h
+       (treelang_parse_file): Call cgraph_finalize_compilation_unit and
+       cgraph_optimize.
+       * treelang.h (item): Remove extraneous GTY.
+       * treetree.h (get_type_for_numeric_type): Remove.
+       * treetree.c: Include tree-dump.h, tree-iterator.h, tree-gimple.h,
+       function.h, and cgraph.h.  Don't include rtl.h
+       (keep_level_p): Remove.
+       (tree_push_atomic_type_decl): Remove.
+       (get_type_for_numeric_type): Remove.
+       (tree_code_get_numeric_type): Remove.
+       (global_bindings_p): Make static.
+       (getdecls): Likewise.
+       (insert_block): Likewise.
+       (tree_code_if_start): Create a COND_EXPR and add it to the tree
+       instead of creating rtl.
+       (tree_code_if_else): Create a BIND_EXPR if any variables were created
+       in the if statement.
+       (tree_code_end_if): Likewise.
+       (tree_code_create_function_prototype): Use tree_code_get_type.
+       Don't use SET_DECL_ASSEMBLER_NAME.
+       (tree_code_create_function_initial): Set DECL_ARTIFICIAL and
+       DECL_IGNORING_P on RESULT_DECL.  Use tree_code_get_type.  Don't call
+       layout_decl on RESULT_DECL.  Don't call rtl expand functions.
+       (tree_code_create_function_wrapup): Don't call rtl expand functions.
+       Create a BIND_EXPR for each function.  Dump original and gimplified
+       copies of the function tree.  Gimplify function.
+       (tree_code_create_variable): Use tree_code_get_type.  Don't call
+       layout_decl or expand_decl.  Fold CONVERT_EXPRs.
+       (tree_code_generate_return): Fold CONVERT_EXPRs and MODIFY_EXPRs.
+       Add RETURN_EXPR to the current statement list.  Don't call rtl expand
+       functions.
+       (tree_code_output_expression_statement): Append CODE to current
+       statement list.
+       (tree_code_get_expression): Fold expressions.  Build a pointer to
+       a FUNCTION_TYPE intead of the called functions return type.
+       (struct binding_level): Add statement list STMTS.
+       (getstmtlist): New Function.
+       (pushlevel): Make static.  Allocate an empty statement list.
+       (poplevel): Make static.  Don't clear BLOCK_NODE's BLOCK_VARS.
+       Don't use DECL_ASSEMBLER_NAME.
+       (tree_push_type_decl): Set TYPE_NAME of TYPE_NODE to ID.
+       (treelang_init_decl_processing): Define basic types after unused types.
+       Don't call tree_push_atomic_type_decl.
+       (builtin_function): Don't call make_decl_rtl.
+       (treelang_expand_function). New Function.
+
 2004-07-11  Joseph S. Myers  <jsm@polyomino.org.uk>
 
        * treetree.c (set_block): Remove.
index 5ddf1d60ca05f08d164209ff42c1295137c13bca..2ea3b656c3868a2643ea3e455a016a347e9d745d 100644 (file)
 TREELANGSED = sed
 TREELANGSEDFLAGS = -n
 
-# back end compiler libraries etc
-TREE_BE_LIBS = $(BACKEND) $(LIBIBERTY) $(INTLIBS) $(LIBS) $(LIBDEPS)
-
-
 GCC_EXTRAS = -B./ -B$(build_tooldir)/bin/ -isystem $(build_tooldir)/include
 
 # ./xgcc is the just built compiler. See GCC_FOR_TARGET in the GCC Makefile.in.
@@ -83,11 +79,11 @@ treelang.done: tree1$(exeext)
 # core compiler
 tree1$(exeext): treelang/tree1.o treelang/treetree.o treelang/tree-convert.o \
        treelang/lex.o treelang/parse.o \
-       $(TREE_BE_LIBS) attribs.o
+       $(BACKEND) $(LIBSDEPS) attribs.o
        $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
        treelang/tree1.o treelang/treetree.o treelang/tree-convert.o \
        treelang/lex.o treelang/parse.o \
-       $(TREE_BE_LIBS) attribs.o
+       $(BACKEND) $(LIBS) attribs.o
 
 #\f
 # Compiling object files from source files.
index 12b211e5b2fd75f0f97e20e54c2ec6ceaa9ab6ed..a93432f94bac4a22630bc61e411390bef7f45bae 100644 (file)
@@ -4,7 +4,7 @@
 
    ---------------------------------------------------------------------
 
-   Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003
+   Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
    
    This program is free software; you can redistribute it and/or modify it 
@@ -233,6 +233,9 @@ update_lineno_charno (void)
    int yyl;
    ((struct prod_token_parm_item *)yylval)->tp.tok.location = input_location;
    ((struct prod_token_parm_item *)yylval)->tp.tok.charno = next_tree_charno;
+   if (input_line == 0)
+     input_line = 1;
+
    for ( yyl = 0; yyl < yyleng; ++yyl ) 
       {
          if ( yytext[yyl] == '\n' ) 
index e7c98386aaba4d3f0533921f816cb2f40de0b6f2..29da1629b34efa186a5f2daf493789e7217d78b5 100644 (file)
@@ -5,7 +5,8 @@
 
      ---------------------------------------------------------------------
 
-     Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+     Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+     Free Software Foundation, Inc.
 
      This program is free software; you can redistribute it and/or modify it
      under the terms of the GNU General Public License as published by the
@@ -254,7 +255,7 @@ typename NAME {
 ;
 
 function_prototype:
-storage typename NAME LEFT_PARENTHESIS parameters RIGHT_PARENTHESIS SEMICOLON {
+storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLON {
   struct prod_token_parm_item* tok;
   struct prod_token_parm_item *prod;
   struct prod_token_parm_item *type;
@@ -450,6 +451,14 @@ INT {
 }
 ;
 
+parameters_opt:
+/* Nothing to do.  */ {
+ $$ = 0;
+}
+| parameters {
+ $$ = $1;
+}
+
 parameters:
 parameter {
   /* Nothing to do.  */
@@ -496,7 +505,7 @@ IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS {
   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
   tree_code_if_start (exp->tp.pro.code, tok->tp.tok.location);
 }
-LEFT_BRACE statements_opt RIGHT_BRACE {
+LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
   /* Just let the statements flow.  */
 }
 ELSE {
@@ -504,7 +513,7 @@ ELSE {
   tok = $1;
   tree_code_if_else (tok->tp.tok.location);
 }
-LEFT_BRACE statements_opt RIGHT_BRACE {
+LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
   struct prod_token_parm_item* tok;
   tok = $12;
   tree_code_if_end (tok->tp.tok.location);
@@ -518,25 +527,23 @@ tl_RETURN expression_opt {
   struct prod_token_parm_item* ret_tok;
   ret_tok = $1;
   type_prod = EXPRESSION_TYPE (current_function);
-  if (NUMERIC_TYPE (type_prod) == VOID)
+  if (NUMERIC_TYPE (type_prod) == VOID_TYPE)
     if ($2 == NULL)
       tree_code_generate_return (type_prod->tp.pro.code, NULL);
     else
       {
         fprintf (stderr, "%s:%i:%i: Redundant expression in return\n",
-                ret_tok->tp.tok.location.file,
-                ret_tok->tp.tok.location.line, ret_tok->tp.tok.charno);
-        print_token (stderr, 0, ret_tok);
+                ret_tok->tp.tok.location.file,
+                ret_tok->tp.tok.location.line, ret_tok->tp.tok.charno);
         errorcount++;
         tree_code_generate_return (type_prod->tp.pro.code, NULL);
-      }
+       }
   else
     if ($2 == NULL)
       {
         fprintf (stderr, "%s:%i:%i: Expression missing in return\n",
-                ret_tok->tp.tok.location.file,
-                ret_tok->tp.tok.location.line, ret_tok->tp.tok.charno); 
-        print_token (stderr, 0, ret_tok);
+                ret_tok->tp.tok.location.file,
+                ret_tok->tp.tok.location.line, ret_tok->tp.tok.charno);
         errorcount++;
       }
     else
@@ -687,7 +694,7 @@ NAME LEFT_PARENTHESIS expressions_with_commas RIGHT_PARENTHESIS {
       abort ();
     parms = tree_code_add_parameter (parms, var->tp.pro.code, exp->tp.pro.code);
   }
-  type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+  type = tree_code_get_type (NUMERIC_TYPE (prod));
   prod->tp.pro.code = tree_code_get_expression
     (EXP_FUNCTION_INVOCATION, type, proto->tp.pro.code, parms, NULL);
   $$ = prod;
@@ -734,7 +741,7 @@ NAME {
 
   prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
   NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
-  type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+  type = tree_code_get_type (NUMERIC_TYPE (prod));
   if (!NUMERIC_TYPE (prod))
     YYERROR;
   OP1 (prod) = $1;
@@ -832,7 +839,7 @@ reverse_prod_list (struct prod_token_parm_item *old_first)
 static void
 ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
 {
-  if (type == VOID)
+  if (type == VOID_TYPE)
     {
       fprintf (stderr, "%s:%i:%i: Type must not be void in this context\n",
               name->tp.tok.location.file,
@@ -877,7 +884,7 @@ check_type_match (int type_num, struct prod_token_parm_item *exp)
         case UNSIGNED_CHAR:
           return 1;
           
-        case VOID:
+        case VOID_TYPE:
           abort ();
       
         default: 
@@ -885,7 +892,7 @@ check_type_match (int type_num, struct prod_token_parm_item *exp)
         }
       break;
       
-    case VOID:
+    case VOID_TYPE:
       abort ();
       
     default:
@@ -903,7 +910,8 @@ make_integer_constant (struct prod_token_parm_item* value)
   struct prod_token_parm_item *prod;
   tok = value;
   prod = make_production (PROD_INTEGER_CONSTANT, tok);
-  if ((tok->tp.tok.chars[0] == (unsigned char)'-')|| (tok->tp.tok.chars[0] == (unsigned char)'+'))
+  if ((tok->tp.tok.chars[0] == (unsigned char)'-')
+      || (tok->tp.tok.chars[0] == (unsigned char)'+'))
     NUMERIC_TYPE (prod) = SIGNED_INT;
   else
     NUMERIC_TYPE (prod) = UNSIGNED_INT;
@@ -930,7 +938,7 @@ make_plus_expression (struct prod_token_parm_item* tok,
   prod = make_production (PROD_PLUS_EXPRESSION, tok);
 
   NUMERIC_TYPE (prod) = type_code;
-  type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+  type = tree_code_get_type (type_code);
   if (!type)
     abort ();
   OP1 (prod) = op1;
index 3ee7c161944ebcf29d24ccff940c8dd9bfcc857a..4ce2c76a79da8f48c3b87f13685910c158500808 100644 (file)
@@ -3,7 +3,8 @@
     TREELANG Compiler almost main (tree1)
     Called by GCC's toplev.c
 
-    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004
+    Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
 #include "tm.h"
 #include "flags.h"
 #include "toplev.h"
+#include "version.h"
 
 #include "ggc.h"
 #include "tree.h"
+#include "cgraph.h"
 #include "diagnostic.h"
 
 #include "treelang.h"
@@ -141,7 +144,7 @@ bool
 treelang_init (void)
 {
   input_filename = main_input_filename;
-  input_line = 0;
+  input_line = 1;
 
   /* Init decls etc.  */
 
@@ -185,6 +188,8 @@ treelang_parse_file (int debug_flag ATTRIBUTE_UNUSED)
 {
   treelang_debug ();
   yyparse ();
+  cgraph_finalize_compilation_unit ();
+  cgraph_optimize ();
 }
 
 /* Allocate SIZE bytes and clear them.  Not to be used for strings
index 656f41826d4479b33eeb1a6c52fef1783f53941a..c0d85de1090ec71a2faba5ff0bee3aa62c1d28f2 100644 (file)
@@ -2,7 +2,8 @@
 
     TREELANG Compiler common definitions (treelang.h)
 
-    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004
+    Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
@@ -48,7 +49,7 @@ extern FILE* yyin;
 struct token_part;
 struct production_part;
 struct prod_token_parm_item;
-typedef struct GTY(()) prod_token_parm_item item;
+typedef struct prod_token_parm_item item;
 
 /* A token from the input file.  */
 
index 5a31b8b300d2eb3f11ad8e9758e91cb5304352c3..9e5bca244e63c057d60e93d2216c9a5049a86792 100644 (file)
@@ -1,13 +1,13 @@
 /*
 
-    TREELANG Compiler back end interface (treetree.c)
+    TREELANG Compiler interface to GCC's middle end (treetree.c)
     Called by the parser.
 
     If you want a working example of how to write a front end to GCC,
     you are in the right place.
 
     Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-    1999, 2000, 2001, 2002, 2003, Free Software Foundation, Inc.
+    1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
     This code is based on toy.c written by Richard Kenner.
 
@@ -19,6 +19,8 @@
 
     It was adapted to TREELANG by Tim Josling 2001.
 
+    Updated to function-at-a-time by James A. Morrison, 2004.
+
     ---------------------------------------------------------------------------
 
     This program is free software; you can redistribute it and/or modify it
@@ -51,8 +53,8 @@
   need for a *lot* of bother to ensure everything is in the mark trees
   at all times.  */
 
-  /* Note it is OK to use GCC extensions such as long long in a compiler front end.
-     This is because the GCC front ends are built using GCC. */
+/* Note, it is OK to use GCC extensions such as long long in a compiler front
+   end.  This is because the GCC front ends are built using GCC.   */
 
 /* GCC headers.  */
 
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
+#include "tree-dump.h"
+#include "tree-iterator.h"
+#include "tree-gimple.h"
+#include "function.h"
 #include "flags.h"
 #include "output.h"
-#include "rtl.h"
 #include "ggc.h"
 #include "toplev.h"
 #include "varray.h"
@@ -71,6 +76,8 @@
 #include "langhooks.h"
 #include "target.h"
 
+#include "cgraph.h"
+
 #include "treelang.h"
 #include "treetree.h"
 #include "opts.h"
@@ -130,17 +137,22 @@ static tree tree_lang_unsigned_type (tree type_node);
 static tree tree_lang_signed_type (tree type_node);
 static tree tree_lang_signed_or_unsigned_type (int unsignedp, tree type);
 
-/* XXX these should be static */
-void pushlevel (int ignore);
-tree poplevel (int keep, int reverse, int functionbody);
-int global_bindings_p (void);
-void insert_block (tree block);
-tree pushdecl (tree decl);
-tree getdecls (void);
-int kept_level_p (void);
+/* Functions to keep track of the current scope.  */
+static void pushlevel (int ignore);
+static tree poplevel (int keep, int reverse, int functionbody);
+static tree pushdecl (tree decl);
+static tree* getstmtlist (void);
+
+/* Langhooks.  */
+static tree builtin_function (const char *name, tree type, int function_code,
+                 enum built_in_class class, const char *library_name,
+                 tree attrs);
+static tree getdecls (void);
+static int global_bindings_p (void);
+static void insert_block (tree);
 
 static void tree_push_type_decl (tree id, tree type_node);
-static void tree_push_atomic_type_decl (tree id, tree type_node);
+static void treelang_expand_function (tree fndecl);
 
 /* The front end language hooks (addresses of code for this front
    end).  These are not really very language-dependent, i.e.
@@ -163,6 +175,12 @@ static void tree_push_atomic_type_decl (tree id, tree type_node);
 #undef LANG_HOOKS_PARSE_FILE
 #define LANG_HOOKS_PARSE_FILE treelang_parse_file
 
+#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
+#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION treelang_expand_function
+
+/* #undef LANG_HOOKS_TYPES_COMPATIBLE_P
+#define LANG_HOOKS_TYPES_COMPATIBLE_P hook_bool_tree_tree_true
+*/
 /* Hook routines and data unique to treelang.  */
 
 #undef LANG_HOOKS_INIT
@@ -243,33 +261,54 @@ tree_code_get_type (int type_num)
 void
 tree_code_if_start (tree exp, location_t loc)
 {
-  tree cond_exp;
-  cond_exp = build (NE_EXPR,
-                 TREE_TYPE (exp),
-                 exp,
-                 build1 (CONVERT_EXPR, TREE_TYPE (exp), integer_zero_node));
-  emit_line_note (loc); /* Output the line number information.  */
-  expand_start_cond (cond_exp, /* Exit-able if nonzero.  */ 0);
+  tree cond_exp, cond;
+  cond_exp = fold (build2 (NE_EXPR, boolean_type_node, exp,
+                     fold (build1 (CONVERT_EXPR, TREE_TYPE (exp), integer_zero_node))));
+  SET_EXPR_LOCATION (cond_exp, loc);
+  cond = build3 (COND_EXPR, void_type_node, cond_exp, NULL_TREE,
+                 NULL_TREE);
+  SET_EXPR_LOCATION (cond, loc);
+  append_to_statement_list_force (cond, getstmtlist ());
+  pushlevel (0);
 }
 
 /* Output the code for the else of an if statement.  The else occurred
    at line LINENO in file FILENAME.  */
 
 void
-tree_code_if_else (location_t loc)
+tree_code_if_else (location_t loc ATTRIBUTE_UNUSED)
 {
-  emit_line_note (loc); /* Output the line number information.  */
-  expand_start_else ();
+  tree stmts = *getstmtlist ();
+  tree block = poplevel (1, 0, 0);
+  if (BLOCK_VARS (block))
+    {
+      tree bindexpr = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
+                              stmts, block);
+      stmts = alloc_stmt_list ();
+      append_to_statement_list (bindexpr, &stmts);
+    }
+
+  TREE_OPERAND (STATEMENT_LIST_TAIL (*getstmtlist ())->stmt, 1) = stmts;
+  pushlevel (0);
 }
 
-/* Output the code for the end_if an if statement.  The end_if (final brace) occurred
-   at line LINENO in file FILENAME.  */
+/* Output the code for the end_if an if statement.  The end_if (final brace)
+   occurred at line LINENO in file FILENAME.  */
 
 void
-tree_code_if_end (location_t loc)
+tree_code_if_end (location_t loc ATTRIBUTE_UNUSED)
 {
-  emit_line_note (loc); /* Output the line number information.  */
-  expand_end_cond ();
+  tree stmts = *getstmtlist ();
+  tree block = poplevel (1, 0, 0);
+  if (BLOCK_VARS (block))
+    {
+       tree bindexpr = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
+                               stmts, block);
+       stmts = alloc_stmt_list ();
+       append_to_statement_list (bindexpr, &stmts);
+    }
+
+  TREE_OPERAND (STATEMENT_LIST_TAIL (*getstmtlist ())->stmt, 2) = stmts;
 }
 
 /* Create a function.  The prototype name is NAME, storage class is
@@ -297,7 +336,7 @@ tree_code_create_function_prototype (unsigned char* chars,
     {
       if (parm->category != parameter_category)
         abort ();
-      type_node = get_type_for_numeric_type (parm->type);
+      type_node = tree_code_get_type (parm->type);
       type_list = tree_cons (NULL_TREE, type_node, type_list);
     }
   /* Last parm if void indicates fixed length list (as opposed to
@@ -306,20 +345,18 @@ tree_code_create_function_prototype (unsigned char* chars,
   /* The back end needs them in reverse order.  */
   type_list = nreverse (type_list);
 
-  type_node = get_type_for_numeric_type (ret_type);
+  type_node = tree_code_get_type (ret_type);
   fn_type = build_function_type (type_node, type_list);
 
   id = get_identifier ((const char*)chars);
   fn_decl = build_decl (FUNCTION_DECL, id, fn_type);
 
-  DECL_CONTEXT (fn_decl) = NULL_TREE; /* Nested functions not supported here.  */
+  /* Nested functions not supported here.  */
+  DECL_CONTEXT (fn_decl) = NULL_TREE;
   DECL_SOURCE_LOCATION (fn_decl) = loc;
 
   TREE_USED (fn_decl) = 1;
 
-  /* Real name (optional).  */
-  SET_DECL_ASSEMBLER_NAME (fn_decl, DECL_NAME (fn_decl));
-
   TREE_PUBLIC (fn_decl) = 0;
   DECL_EXTERNAL (fn_decl) = 0;
   TREE_STATIC (fn_decl) = 0;
@@ -340,7 +377,6 @@ tree_code_create_function_prototype (unsigned char* chars,
       DECL_EXTERNAL (fn_decl) = 1;
       break;
 
-
     case AUTOMATIC_STORAGE:
     default:
       abort ();
@@ -364,8 +400,6 @@ tree_code_create_function_initial (tree prev_saved,
 {
   tree fn_decl;
   tree param_decl;
-  tree next_param;
-  tree first_param;
   tree parm_decl;
   tree parm_list;
   tree resultdecl;
@@ -388,15 +422,14 @@ tree_code_create_function_initial (tree prev_saved,
 
   DECL_SOURCE_LOCATION (fn_decl) = loc;
 
-  /* Prepare creation of rtl for a new function.  */
-
-  resultdecl = DECL_RESULT (fn_decl) 
-    = build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (TREE_TYPE (fn_decl)));
-  DECL_CONTEXT (DECL_RESULT (fn_decl)) = fn_decl;
+  /* Create a DECL for the functions result.  */
+  resultdecl =
+    build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (TREE_TYPE (fn_decl)));
+  DECL_CONTEXT (resultdecl) = fn_decl;
+  DECL_ARTIFICIAL (resultdecl) = 1;
+  DECL_IGNORED_P (resultdecl) = 1;
   DECL_SOURCE_LOCATION (resultdecl) = loc;
-
-  /* Work out the size. ??? is this needed.  */
-  layout_decl (DECL_RESULT (fn_decl), 0);
+  DECL_RESULT (fn_decl) = resultdecl;
 
   /* Make the argument variable decls.  */
   parm_list = NULL_TREE;
@@ -404,7 +437,7 @@ tree_code_create_function_initial (tree prev_saved,
     {
       parm_decl = build_decl (PARM_DECL, get_identifier
                               ((const char*) (parm->tp.par.variable_name)),
-                              get_type_for_numeric_type (parm->type));
+                              tree_code_get_type (parm->type));
 
       /* Some languages have different nominal and real types.  */
       DECL_ARG_TYPE (parm_decl) = TREE_TYPE (parm_decl);
@@ -436,58 +469,15 @@ tree_code_create_function_initial (tree prev_saved,
   if (this_parm)
     abort (); /* Too many.  */
 
-  /* Output the decl rtl (not the rtl for the function code).  ???.
-     If the function is not defined in this file, when should you
-     execute this?  */
-  make_decl_rtl (fn_decl);
-
-  init_function_start (fn_decl);
-
-  /* Create rtl for startup code of function, such as saving registers.  */
-
-  expand_function_start (fn_decl, 0);
-
-  /* Function.c requires a push at the start of the function. that
-     looks like a bug to me but let's make it happy.  */
+  /* Create a new level at the start of the function.  */
 
   pushlevel (0);
 
-  /* Create rtl for the start of a new scope.  */
-
-  expand_start_bindings (2);
-
-  /* Put the parameters into the symbol table.  */
-
-  for (first_param = param_decl = nreverse (DECL_ARGUMENTS (fn_decl));
-       param_decl;
-       param_decl = next_param)
-    {
-      next_param = TREE_CHAIN (param_decl);
-      TREE_CHAIN (param_decl) = NULL;
-      /* layout_decl (param_decl, 0);  Already done in build_decl tej 13/4/2002.  */
-      pushdecl (param_decl);
-      if (DECL_CONTEXT (param_decl) != current_function_decl)
-        abort ();
-    }
-
-  /* Store back the PARM_DECL nodes.  They appear in the right order.  */
-  DECL_ARGUMENTS (fn_decl) = getdecls ();
-
   /* Force it to be output, else may be solely inlined.  */
   TREE_ADDRESSABLE (fn_decl) = 1;
 
   /* Stop -O3 from deleting it.  */
   TREE_USED (fn_decl) = 1;
-
-  /* Add a new level to the debugger symbol table.  */
-
-  pushlevel (0);
-
-  /* Create rtl for the start of a new scope.  */
-
-  expand_start_bindings (0);
-
-  emit_line_note (loc); /* Output the line number information.  */
 }
 
 /* Wrapup a function contained in file FILENAME, ending at line LINENO.  */
@@ -496,42 +486,38 @@ tree_code_create_function_wrapup (location_t loc)
 {
   tree block;
   tree fn_decl;
+  tree stmts = *getstmtlist ();
 
   fn_decl = current_function_decl;
 
-  emit_line_note (loc); /* Output the line number information.  */
-
-  /* Get completely built level from debugger symbol table.  */
-
-  block = poplevel (1, 0, 0);
-
-  /* Emit rtl for end of scope.  */
-
-  expand_end_bindings (block, 0, 1);
-
-  /* Emit rtl for end of function.  */
-
-  expand_function_end ();
-
   /* Pop the level.  */
 
   block = poplevel (1, 0, 1);
 
   /* And attach it to the function.  */
 
-  DECL_INITIAL (fn_decl) = block;
+  DECL_SAVED_TREE (fn_decl) = build3 (BIND_EXPR, void_type_node,
+                                      BLOCK_VARS (block),
+                                     stmts, block);
 
-  /* Emit rtl for end of scope.  */
+  allocate_struct_function (fn_decl);
+  cfun->function_end_locus = loc;
 
-  expand_end_bindings (block, 0, 1);
 
-  /* Call optimization and convert optimized rtl to assembly code.  */
+  /* Dump the original tree to a file.  */
+  dump_function (TDI_original, fn_decl);
 
-  rest_of_compilation (fn_decl);
+  /* Convert current function to GIMPLE for the middle end.  */
+  gimplify_function_tree (fn_decl);
+  dump_function (TDI_generic, fn_decl);
 
   /* We are not inside of any scope now.  */
-
   current_function_decl = NULL_TREE;
+  cfun = NULL;
+
+  /* Pass the current function off to the middle end.  */
+  (void)cgraph_node (fn_decl);
+  cgraph_finalize_function (fn_decl, false);
 }
 
 /*
@@ -556,7 +542,7 @@ tree_code_create_variable (unsigned int storage_class,
   tree var_decl;
 
   /* 1. Build the type.  */
-  var_type = get_type_for_numeric_type (expression_type);
+  var_type = tree_code_get_type (expression_type);
 
   /* 2. Build the name.  */
   if (chars[length] != 0)
@@ -569,13 +555,10 @@ tree_code_create_variable (unsigned int storage_class,
 
   /* 3a. Initialization.  */
   if (init)
-    DECL_INITIAL (var_decl) = build1 (CONVERT_EXPR, var_type, init);
+    DECL_INITIAL (var_decl) = fold (build1 (CONVERT_EXPR, var_type, init));
   else
     DECL_INITIAL (var_decl) = NULL_TREE;
 
-  /* 4. Compute size etc.  */
-  layout_decl (var_decl, 0);
-
   if (TYPE_SIZE (var_type) == 0)
     abort (); /* Did not calculate size.  */
 
@@ -617,13 +600,8 @@ tree_code_create_variable (unsigned int storage_class,
 
   if (TREE_STATIC (var_decl))
     rest_of_decl_compilation (var_decl, 0, 0);
-  else
-    {
-      expand_decl (var_decl);
-      if (DECL_INITIAL (var_decl))
-        expand_decl_init (var_decl);
-    }
 
+  TYPE_NAME (TREE_TYPE (var_decl)) = TYPE_NAME (var_type);
   return pushdecl (copy_node (var_decl));
 
 }
@@ -646,28 +624,33 @@ tree_code_generate_return (tree type, tree exp)
         abort ();
     }
 
-  if (exp)
+  if (exp && TREE_TYPE (TREE_TYPE (current_function_decl)) != void_type_node)
     {
-      setret = build (MODIFY_EXPR, type, DECL_RESULT (current_function_decl),
-                     build1 (CONVERT_EXPR, type, exp));
+      setret = fold (build2 (MODIFY_EXPR, type, 
+                             DECL_RESULT (current_function_decl),
+                             fold (build1 (CONVERT_EXPR, type, exp))));
       TREE_SIDE_EFFECTS (setret) = 1;
       TREE_USED (setret) = 1;
-      expand_expr_stmt (setret);
+      setret = build1 (RETURN_EXPR, type, setret);
     }
-  expand_return (DECL_RESULT (current_function_decl));
+   else
+     setret = build1 (RETURN_EXPR, type, NULL_TREE);
+
+   append_to_statement_list_force (setret, getstmtlist ());
 }
 
-/* Output the code for this expression statement CODE.  */
 
+/* Output the code for this expression statement CODE.  */
 
 void
 tree_code_output_expression_statement (tree code, location_t loc)
 {
   /* Output the line number information.  */
-  emit_line_note (loc);
+  SET_EXPR_LOCATION (code, loc);
   TREE_USED (code) = 1;
   TREE_SIDE_EFFECTS (code) = 1;
-  expand_expr_stmt (code);
+  /* put CODE into the code list.  */
+  append_to_statement_list_force (code, getstmtlist ());
 }
 
 /* Return a tree for a constant integer value in the token TOK.  No
@@ -716,9 +699,8 @@ tree_code_get_expression (unsigned int exp_type,
       if (!op1 || !op2)
         abort ();
       operator = MODIFY_EXPR;
-      ret1 = build (operator, type,
-                 op1,
-                 build1 (CONVERT_EXPR, type, op2));
+      ret1 = fold (build2 (operator, void_type_node, op1,
+                           fold (build1 (CONVERT_EXPR, TREE_TYPE (op1), op2))));
 
       break;
 
@@ -734,13 +716,13 @@ tree_code_get_expression (unsigned int exp_type,
       operator = EQ_EXPR;
       goto binary_expression;
 
-      /* Expand a binary expression.  Ensure the operands are the right type.  */
+    /* Expand a binary expression.  Ensure the operands are the right type.  */
     binary_expression:
       if (!op1 || !op2)
         abort ();
-      ret1  =  build (operator, type,
-                   build1 (CONVERT_EXPR, type, op1),
-                   build1 (CONVERT_EXPR, type, op2));
+      ret1  =  fold (build2 (operator, type,
+                       fold (build1 (CONVERT_EXPR, type, op1)),
+                       fold (build1 (CONVERT_EXPR, type, op2))));
       break;
 
       /* Reference to a variable.  This is dead easy, just return the
@@ -752,16 +734,18 @@ tree_code_get_expression (unsigned int exp_type,
       if (type == TREE_TYPE (op1))
         ret1 = op1;
       else
-        ret1 = build1 (CONVERT_EXPR, type, op1);
+        ret1 = fold (build1 (CONVERT_EXPR, type, op1));
       break;
 
     case EXP_FUNCTION_INVOCATION:
       if (!op1 || !op2)
         abort ();
+
       {
         tree fun_ptr;
-        fun_ptr = build1 (ADDR_EXPR, build_pointer_type (type), op1);
-        ret1 = build (CALL_EXPR, type, fun_ptr, nreverse (op2));
+        fun_ptr = fold (build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (op1)),
+                                op1));
+        ret1 = build3 (CALL_EXPR, type, fun_ptr, nreverse (op2), NULL_TREE);
       }
       break;
 
@@ -788,83 +772,13 @@ tree_code_add_parameter (tree list, tree proto_exp, tree exp)
 {
   tree new_exp;
   new_exp = tree_cons (NULL_TREE,
-                    build1 (CONVERT_EXPR, TREE_TYPE (proto_exp), exp),
-                    NULL_TREE);
+                       fold (build1 (CONVERT_EXPR, TREE_TYPE (proto_exp), exp)),
+                       NULL_TREE);
   if (!list)
     return new_exp;
   return chainon (new_exp, list);
 }
 
-/* Get the tree type for this type whose number is NUMERIC_TYPE.  */
-
-tree
-get_type_for_numeric_type (unsigned int numeric_type)
-{
-
-  int size1;
-  int sign1;
-  switch (numeric_type)
-    {
-    case VOID_TYPE:
-      return void_type_node;
-
-    case SIGNED_INT:
-      size1 = tree_code_int_size;
-      sign1 = 1;
-      break;
-
-    case UNSIGNED_INT:
-      size1 = tree_code_int_size;
-      sign1 = 0;
-      break;
-
-    case SIGNED_CHAR:
-      size1 = tree_code_char_size;
-      sign1 = 1;
-      break;
-
-    case UNSIGNED_CHAR:
-      size1 = tree_code_char_size;
-      sign1 = 0;
-      break;
-
-    default:
-      abort ();
-    }
-
-  return tree_code_get_numeric_type (size1, sign1);
-
-}
-
-/* Return tree representing a numeric type of size SIZE1 bits and
-   signed if SIGN1 !=  0.  */
-tree
-tree_code_get_numeric_type (unsigned int size1, unsigned int sign1)
-{
-  tree ret1;
-  if (!size1)
-    abort ();
-  if (size1 == tree_code_int_size)
-    {
-      if (sign1)
-        ret1 = integer_type_node;
-      else
-        ret1 = unsigned_type_node;
-    }
-  else
-    if (size1 == tree_code_char_size)
-      {
-        if (sign1)
-          ret1 = signed_char_type_node;
-        else
-          ret1 = unsigned_char_type_node;
-      }
-    else
-      abort ();
-
-  return ret1;
-}
-
 /* Get a stringpool entry for a string S of length L.  This is needed
    because the GTY routines don't mark strings, forcing you to put
    them into stringpool, which is never freed.  */
@@ -1056,6 +970,8 @@ struct binding_level
   /* For each level (except the global one), a chain of BLOCK nodes for all
      the levels that were entered and exited one level down from this one.  */
   tree blocks;
+
+  tree stmts;
   /* The binding level containing this one (the enclosing binding level). */
   struct binding_level *level_chain;
 };
@@ -1068,37 +984,38 @@ static struct binding_level *current_binding_level = NULL;
 static struct binding_level *global_binding_level;
 
 /* Binding level structures are initialized by copying this one.  */
-static struct binding_level clear_binding_level = {NULL, NULL, NULL };
+static struct binding_level clear_binding_level = {NULL, NULL, NULL, NULL };
 \f
 /* Return non-zero if we are currently in the global binding level.  */
 
-int
+static int
 global_bindings_p (void)
 {
   return current_binding_level == global_binding_level ? -1 : 0;
 }
 
+
 /* Return the list of declarations in the current level. Note that this list
    is in reverse order (it has to be so for back-end compatibility).  */
 
-tree
+static tree
 getdecls (void)
 {
   return current_binding_level->names;
 }
 
-/* Nonzero if the current level needs to have a BLOCK made.  */
+/* Return a STATMENT_LIST for the current block.  */
 
-int
-kept_level_p (void)
+static tree*
+getstmtlist (void)
 {
-  return (current_binding_level->names != 0);
+  return &current_binding_level->stmts;
 }
 
 /* Enter a new binding level. The input parameter is ignored, but has to be
    specified for back-end compatibility.  */
 
-void
+static void
 pushlevel (int ignore ATTRIBUTE_UNUSED)
 {
   struct binding_level *newlevel = xmalloc (sizeof (struct binding_level));
@@ -1109,6 +1026,7 @@ pushlevel (int ignore ATTRIBUTE_UNUSED)
      active.  */
   newlevel->level_chain = current_binding_level;
   current_binding_level = newlevel;
+  current_binding_level->stmts = alloc_stmt_list ();
 }
 
 /* Exit a binding level.
@@ -1126,7 +1044,7 @@ pushlevel (int ignore ATTRIBUTE_UNUSED)
    If REVERSE is nonzero, reverse the order of decls before putting
    them into the BLOCK.  */
 
-tree
+static tree
 poplevel (int keep, int reverse, int functionbody)
 {
   /* Points to a BLOCK tree node. This is the BLOCK node construted for the
@@ -1166,8 +1084,6 @@ poplevel (int keep, int reverse, int functionbody)
        {
          if (TREE_USED (subblock_node))
            TREE_USED (DECL_NAME (subblock_node)) = 1;
-         if (TREE_ADDRESSABLE (subblock_node))
-           TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (subblock_node)) = 1;
        }
 
   /* Pop the current level.  */
@@ -1175,12 +1091,8 @@ poplevel (int keep, int reverse, int functionbody)
 
   if (functionbody)
     {
-      /* This is the top level block of a function. The ..._DECL chain stored
-        in BLOCK_VARS are the function's parameters (PARM_DECL nodes). Don't
-        leave them in the BLOCK because they are found in the FUNCTION_DECL
-        instead.  */
+      /* This is the top level block of a function.  */
       DECL_INITIAL (current_function_decl) = block_node;
-      BLOCK_VARS (block_node) = 0;
     }
   else if (block_node)
     {
@@ -1205,7 +1117,7 @@ poplevel (int keep, int reverse, int functionbody)
    current binding level.  This is used when a BIND_EXPR is expanded,
    to handle the BLOCK node inside the BIND_EXPR.  */
 
-void
+static void
 insert_block (tree block)
 {
   TREE_USED (block) = 1;
@@ -1213,6 +1125,7 @@ insert_block (tree block)
     = chainon (current_binding_level->blocks, block);
 }
 
+
 /* Records a ..._DECL node DECL as belonging to the current lexical scope.
    Returns the ..._DECL node. */
 
@@ -1247,22 +1160,10 @@ static void
 tree_push_type_decl(tree id, tree type_node)
 {
   tree decl = build_decl (TYPE_DECL, id, type_node);
-  TYPE_NAME (type_node) = decl;
-  TYPE_STUB_DECL (type_node) = decl;
+  TYPE_NAME (type_node) = id;
   pushdecl (decl);
 }
 
-/* push_atomic_type_decl() ensures that the type's type is itself. 
-   Needed for DBX.  Must only be used for atomic types,
-   not for e.g. pointer or array types.  */
-
-static void
-tree_push_atomic_type_decl(tree id, tree type_node)
-{
-  TREE_TYPE (type_node) = type_node;
-  tree_push_type_decl (id, type_node);
-}
-
 #define NULL_BINDING_LEVEL (struct binding_level *) NULL                        
 
 /* Create the predefined scalar types of C,
@@ -1282,53 +1183,52 @@ treelang_init_decl_processing (void)
 
   /* set standard type names */
 
-  /* Define `int' and `char' first so that dbx will output them first.  */
+  /* Define `int' and `char' last so that they are not overwritten.  */
+  tree_push_type_decl (NULL_TREE, intQI_type_node);
+  tree_push_type_decl (NULL_TREE, intHI_type_node);
+  tree_push_type_decl (NULL_TREE, intSI_type_node);
+  tree_push_type_decl (NULL_TREE, intDI_type_node);
+#if HOST_BITS_PER_WIDE_INT >= 64
+  tree_push_type_decl (NULL_TREE, intTI_type_node);
+#endif
+  tree_push_type_decl (NULL_TREE, unsigned_intQI_type_node);
+  tree_push_type_decl (NULL_TREE, unsigned_intHI_type_node);
+  tree_push_type_decl (NULL_TREE, unsigned_intSI_type_node);
+  tree_push_type_decl (NULL_TREE, unsigned_intDI_type_node);
+#if HOST_BITS_PER_WIDE_INT >= 64
+  tree_push_type_decl (NULL_TREE, unsigned_intTI_type_node);
+#endif
 
-  tree_push_atomic_type_decl (get_identifier ("int"), integer_type_node);
-  tree_push_atomic_type_decl (get_identifier ("char"), char_type_node);
-  tree_push_atomic_type_decl (get_identifier ("long int"),
+  tree_push_type_decl (get_identifier ("int"), integer_type_node);
+  tree_push_type_decl (get_identifier ("char"), char_type_node);
+  tree_push_type_decl (get_identifier ("long int"),
                              long_integer_type_node);
-  tree_push_atomic_type_decl (get_identifier ("unsigned int"),
+  tree_push_type_decl (get_identifier ("unsigned int"),
                              unsigned_type_node);
-  tree_push_atomic_type_decl (get_identifier ("long unsigned int"),
+  tree_push_type_decl (get_identifier ("long unsigned int"),
                              long_unsigned_type_node);
-  tree_push_atomic_type_decl (get_identifier ("long long int"),
+  tree_push_type_decl (get_identifier ("long long int"),
                              long_long_integer_type_node);
-  tree_push_atomic_type_decl (get_identifier ("long long unsigned int"),
+  tree_push_type_decl (get_identifier ("long long unsigned int"),
                              long_long_unsigned_type_node);
-  tree_push_atomic_type_decl (get_identifier ("short int"),
+  tree_push_type_decl (get_identifier ("short int"),
                              short_integer_type_node);
-  tree_push_atomic_type_decl (get_identifier ("short unsigned int"),
+  tree_push_type_decl (get_identifier ("short unsigned int"),
                              short_unsigned_type_node);
-  tree_push_atomic_type_decl (get_identifier ("signed char"),
+  tree_push_type_decl (get_identifier ("signed char"),
                              signed_char_type_node);
-  tree_push_atomic_type_decl (get_identifier ("unsigned char"),
+  tree_push_type_decl (get_identifier ("unsigned char"),
                              unsigned_char_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, intQI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, intHI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, intSI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, intDI_type_node);
-#if HOST_BITS_PER_WIDE_INT >= 64
-  tree_push_atomic_type_decl (NULL_TREE, intTI_type_node);
-#endif
-  tree_push_atomic_type_decl (NULL_TREE, unsigned_intQI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, unsigned_intHI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, unsigned_intSI_type_node);
-  tree_push_atomic_type_decl (NULL_TREE, unsigned_intDI_type_node);
-#if HOST_BITS_PER_WIDE_INT >= 64
-  tree_push_atomic_type_decl (NULL_TREE, unsigned_intTI_type_node);
-#endif
-  
   size_type_node = make_unsigned_type (POINTER_SIZE);
-  tree_push_atomic_type_decl (get_identifier ("size_t"), size_type_node);
+  tree_push_type_decl (get_identifier ("size_t"), size_type_node);
   set_sizetype (size_type_node);
 
   build_common_tree_nodes_2 (/* short_double= */ 0);
 
-  tree_push_atomic_type_decl (get_identifier ("float"), float_type_node);
-  tree_push_atomic_type_decl (get_identifier ("double"), double_type_node);
-  tree_push_atomic_type_decl (get_identifier ("long double"), long_double_type_node);
-  tree_push_atomic_type_decl (get_identifier ("void"), void_type_node);
+  tree_push_type_decl (get_identifier ("float"), float_type_node);
+  tree_push_type_decl (get_identifier ("double"), double_type_node);
+  tree_push_type_decl (get_identifier ("long double"), long_double_type_node);
+  tree_push_type_decl (get_identifier ("void"), void_type_node);
 
   /* Add any target-specific builtin functions.  */
   (*targetm.init_builtins) ();
@@ -1348,7 +1248,7 @@ treelang_init_decl_processing (void)
    copied from gcc/c-decl.c
 */
 
-tree
+static tree
 builtin_function (const char *name, tree type, int function_code,
                  enum built_in_class class, const char *library_name,
                  tree attrs)
@@ -1358,7 +1258,6 @@ builtin_function (const char *name, tree type, int function_code,
   TREE_PUBLIC (decl) = 1;
   if (library_name)
     SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
-  make_decl_rtl (decl);
   pushdecl (decl);
   DECL_BUILT_IN_CLASS (decl) = class;
   DECL_FUNCTION_CODE (decl) = function_code;
@@ -1372,5 +1271,14 @@ builtin_function (const char *name, tree type, int function_code,
   return decl;
 }
 
+/* Treelang expand function langhook.  */
+
+static void
+treelang_expand_function (tree fndecl)
+{
+  /* We have nothing special to do while expanding functions for treelang.  */
+  tree_rest_of_compilation (fndecl, 0);
+}
+
 #include "debug.h" /* for debug_hooks, needed by gt-treelang-treetree.h */
 #include "gt-treelang-treetree.h"
index 72004809b45785ab2271ee3cd496fe9226afd347..ac75d8c87d71800b91f44d37c9445aeeb442c003 100644 (file)
@@ -3,7 +3,8 @@
     TREELANG Compiler definitions for interfacing to treetree.c
     (compiler back end interface).
 
-    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+    Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004
+    Free Software Foundation, Inc.
 
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
@@ -55,7 +56,6 @@ tree tree_code_create_variable (unsigned int storage_class,
                                location_t loc);
 void tree_code_output_expression_statement (tree code,
                                            location_t loc);
-tree get_type_for_numeric_type (unsigned int numeric_type);
 void tree_code_if_start (tree exp, location_t loc);
 void tree_code_if_else (location_t loc);
 void tree_code_if_end (location_t loc);