diff options
author | James A. Morrison <phython@gcc.gnu.org> | 2004-08-08 04:47:17 +0000 |
---|---|---|
committer | James A. Morrison <phython@gcc.gnu.org> | 2004-08-08 04:47:17 +0000 |
commit | 352a77c8dc72715bbe230e04cd72583d5a900291 (patch) | |
tree | 664241e1e8c5de43d446667d9fa32444b7f9d395 /gcc | |
parent | c30ff96bd5accd7eca47ee060ee1e7f1f702cc11 (diff) | |
download | gcc-352a77c8dc72715bbe230e04cd72583d5a900291.zip gcc-352a77c8dc72715bbe230e04cd72583d5a900291.tar.gz gcc-352a77c8dc72715bbe230e04cd72583d5a900291.tar.bz2 |
Make-lang.in (TREE_BE_LIBS): Remove.
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/treelang/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/treelang/a01gcci01.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/treelang/compile/badreturn.tree | 14 | ||||
-rw-r--r-- | gcc/testsuite/treelang/compile/compile.exp | 31 | ||||
-rw-r--r-- | gcc/testsuite/treelang/compile/full_unit.tree | 16 | ||||
-rw-r--r-- | gcc/testsuite/treelang/compile/tabs.tree | 11 | ||||
-rw-r--r-- | gcc/testsuite/treelang/compile/var_defs.tree | 39 | ||||
-rw-r--r-- | gcc/treelang/ChangeLog | 60 | ||||
-rw-r--r-- | gcc/treelang/Make-lang.in | 8 | ||||
-rw-r--r-- | gcc/treelang/lex.l | 5 | ||||
-rw-r--r-- | gcc/treelang/parse.y | 46 | ||||
-rw-r--r-- | gcc/treelang/tree1.c | 9 | ||||
-rw-r--r-- | gcc/treelang/treelang.h | 5 | ||||
-rw-r--r-- | gcc/treelang/treetree.c | 460 | ||||
-rw-r--r-- | gcc/treelang/treetree.h | 4 |
15 files changed, 406 insertions, 308 deletions
diff --git a/gcc/testsuite/treelang/ChangeLog b/gcc/testsuite/treelang/ChangeLog index 5a594a1..e0e3863 100644 --- a/gcc/testsuite/treelang/ChangeLog +++ b/gcc/testsuite/treelang/ChangeLog @@ -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. diff --git a/gcc/testsuite/treelang/a01gcci01.c b/gcc/testsuite/treelang/a01gcci01.c index 4d857fa..b714019 100644 --- a/gcc/testsuite/treelang/a01gcci01.c +++ b/gcc/testsuite/treelang/a01gcci01.c @@ -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 index 0000000..60d3b12 --- /dev/null +++ b/gcc/testsuite/treelang/compile/badreturn.tree @@ -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 index 0000000..836c325 --- /dev/null +++ b/gcc/testsuite/treelang/compile/compile.exp @@ -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 index 0000000..2d50323 --- /dev/null +++ b/gcc/testsuite/treelang/compile/full_unit.tree @@ -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 index 0000000..6294c15 --- /dev/null +++ b/gcc/testsuite/treelang/compile/tabs.tree @@ -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 index 0000000..ed03b62 --- /dev/null +++ b/gcc/testsuite/treelang/compile/var_defs.tree @@ -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; +} + diff --git a/gcc/treelang/ChangeLog b/gcc/treelang/ChangeLog index bd6955f..73d367f 100644 --- a/gcc/treelang/ChangeLog +++ b/gcc/treelang/ChangeLog @@ -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. diff --git a/gcc/treelang/Make-lang.in b/gcc/treelang/Make-lang.in index 5ddf1d6..2ea3b65 100644 --- a/gcc/treelang/Make-lang.in +++ b/gcc/treelang/Make-lang.in @@ -45,10 +45,6 @@ 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 # # Compiling object files from source files. diff --git a/gcc/treelang/lex.l b/gcc/treelang/lex.l index 12b211e..a93432f 100644 --- a/gcc/treelang/lex.l +++ b/gcc/treelang/lex.l @@ -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' ) diff --git a/gcc/treelang/parse.y b/gcc/treelang/parse.y index e7c9838..29da162 100644 --- a/gcc/treelang/parse.y +++ b/gcc/treelang/parse.y @@ -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; diff --git a/gcc/treelang/tree1.c b/gcc/treelang/tree1.c index 3ee7c16..4ce2c76 100644 --- a/gcc/treelang/tree1.c +++ b/gcc/treelang/tree1.c @@ -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 @@ -37,9 +38,11 @@ #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 diff --git a/gcc/treelang/treelang.h b/gcc/treelang/treelang.h index 656f418..c0d85de 100644 --- a/gcc/treelang/treelang.h +++ b/gcc/treelang/treelang.h @@ -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. */ diff --git a/gcc/treelang/treetree.c b/gcc/treelang/treetree.c index 5a31b8b..9e5bca2 100644 --- a/gcc/treelang/treetree.c +++ b/gcc/treelang/treetree.c @@ -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. */ @@ -61,9 +63,12 @@ #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 }; /* 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 ¤t_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" diff --git a/gcc/treelang/treetree.h b/gcc/treelang/treetree.h index 7200480..ac75d8c 100644 --- a/gcc/treelang/treetree.h +++ b/gcc/treelang/treetree.h @@ -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); |