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
This commit is contained in:
James A. Morrison 2004-08-08 04:47:17 +00:00
parent c30ff96bd5
commit 352a77c8dc
15 changed files with 406 additions and 308 deletions

View 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.

View 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[])

View File

@ -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" }
}

View File

@ -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

View File

@ -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" } }

View File

@ -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;
}

View File

@ -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;
}

View 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.

View File

@ -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.

View 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' )

View 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;

View 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
@ -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

View 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. */

View 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. */
@ -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 &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"

View 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);