aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/testsuite/lib/treelang.exp20
-rw-r--r--gcc/testsuite/treelang/ChangeLog40
-rw-r--r--gcc/testsuite/treelang/Makefile.in9
-rw-r--r--gcc/testsuite/treelang/a01gcci01.c19
-rw-r--r--gcc/testsuite/treelang/a01gcci01.tree39
-rw-r--r--gcc/testsuite/treelang/a01gcco01runpgm8
-rw-r--r--gcc/testsuite/treelang/treetests.exp289
-rw-r--r--gcc/treelang/ChangeLog24
-rw-r--r--gcc/treelang/Make-lang.in297
-rw-r--r--gcc/treelang/README16
-rw-r--r--gcc/treelang/config-lang.in37
-rw-r--r--gcc/treelang/lang-options.h29
-rw-r--r--gcc/treelang/lang-specs.h63
-rw-r--r--gcc/treelang/lex.l294
-rw-r--r--gcc/treelang/parse.y1001
-rw-r--r--gcc/treelang/tree1.c382
-rw-r--r--gcc/treelang/treelang.h116
-rw-r--r--gcc/treelang/treelang.texi1311
-rw-r--r--gcc/treelang/treetree.c1288
-rw-r--r--gcc/treelang/treetree.h101
20 files changed, 5383 insertions, 0 deletions
diff --git a/gcc/testsuite/lib/treelang.exp b/gcc/testsuite/lib/treelang.exp
new file mode 100644
index 0000000..e3d6c49
--- /dev/null
+++ b/gcc/testsuite/lib/treelang.exp
@@ -0,0 +1,20 @@
+# Copyright (C) 1988, 90, 91, 92, 95, 96, 1997, 1999, 2000, 2001, 2002 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 Free Software Foundation; either version 2 of the License, 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.
+
+# Having this file here magically tells dejagnu that the treelang
+# directory is worthy of testing
+
+
diff --git a/gcc/testsuite/treelang/ChangeLog b/gcc/testsuite/treelang/ChangeLog
new file mode 100644
index 0000000..d7f7c78
--- /dev/null
+++ b/gcc/testsuite/treelang/ChangeLog
@@ -0,0 +1,40 @@
+2002-04-13 Tim Josling <tej@melbpc.org.au>
+ * treetree.c (tree_code_create_function_initial)
+ Remove duplicate call to layout_decl
+
+2001-12-02 Tim Josling <tej@melbpc.org.au>
+ * Make-lang.in
+ Ensure directory is built during install (installdirs dependency)
+
+ * lex.l
+ Work around poisoned malloc (undef IN_GCC)
+ Remove fake definition of tree.
+
+ * parse.y
+ Work around poisoned malloc (undef IN_GCC)
+
+ * tree1.c
+ New front end interface.
+ (top level) New structure lang_hooks.
+ (tree_post_options) Remove.
+ errorcount now a macro so do not define it.
+ current_nesting_level => work_nesting_level due to clash.
+
+ * treelang.h
+ errorcount now a macro so do not reference it.
+
+ * treetree.c
+ Replace NULL_PTR by NULL.
+ (tree_code_get_expression) Mark op3 unused.
+ Do not init builtins.
+
+2001-06-11 Tim Josling <tej@melbpc.org.au>
+
+ * treelang.exp (global) remove COBOL specific code.
+
+2001-05-24 Tim Josling <tej@melbpc.org.au>
+
+ Created this directory and its tests. All derived from the cobol
+ test swamp which was also all written by me.
+
+
diff --git a/gcc/testsuite/treelang/Makefile.in b/gcc/testsuite/treelang/Makefile.in
new file mode 100644
index 0000000..908131b
--- /dev/null
+++ b/gcc/testsuite/treelang/Makefile.in
@@ -0,0 +1,9 @@
+# Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+
+all:
+
+clean:
+ -rm -f *.o *.diff *~ *.bad core *.x
+
+distclean: clean
+ -rm -f Makefile config.status
diff --git a/gcc/testsuite/treelang/a01gcci01.c b/gcc/testsuite/treelang/a01gcci01.c
new file mode 100644
index 0000000..69ab63d
--- /dev/null
+++ b/gcc/testsuite/treelang/a01gcci01.c
@@ -0,0 +1,19 @@
+/* Driver for treelang test pgm */
+
+int add(int, int);
+int subtract(int, int);
+int first_nonzero(int, int);
+
+int
+main (int argc, char *argv[])
+{
+ printf("2:%d\n", add(1,1));
+ printf("7:%d\n", add(3,4));
+ printf("-1:%d\n", subtract(3,4));
+ printf("1:%d\n", subtract(2,1));
+ printf("3:%d\n", first_nonzero(0,3));
+ printf("0:%d\n", first_nonzero(0,0));
+ printf("1:%d\n", first_nonzero(1,0));
+ printf("15:%d\n", double_plus_one(7));
+ return 0;
+}
diff --git a/gcc/testsuite/treelang/a01gcci01.tree b/gcc/testsuite/treelang/a01gcci01.tree
new file mode 100644
index 0000000..e1e1ac1
--- /dev/null
+++ b/gcc/testsuite/treelang/a01gcci01.tree
@@ -0,0 +1,39 @@
+// -*- c -*- c mode in emacs
+
+external_definition int add(int arg1, int arg2);
+external_definition int subtract(int arg3, int arg4);
+external_definition int first_nonzero(int arg5, int arg6);
+external_definition int double_plus_one(int arg7);
+
+add
+{
+ return arg1 + arg2;
+}
+
+
+subtract
+{
+ return arg3 - arg4;
+}
+
+double_plus_one
+{
+ automatic int aaa;
+ aaa=add(arg7, arg7);
+ aaa=add(aaa, aaa);
+ aaa=subtract(subtract(aaa, arg7), arg7) + 1;
+ return aaa;
+}
+
+first_nonzero
+{
+ if (arg5)
+ {
+ return arg5;
+ }
+ else
+ {
+ }
+ return arg6;
+}
+
diff --git a/gcc/testsuite/treelang/a01gcco01runpgm b/gcc/testsuite/treelang/a01gcco01runpgm
new file mode 100644
index 0000000..3c2c743
--- /dev/null
+++ b/gcc/testsuite/treelang/a01gcco01runpgm
@@ -0,0 +1,8 @@
+2:2
+7:7
+-1:-1
+1:1
+3:3
+0:0
+1:1
+15:15
diff --git a/gcc/testsuite/treelang/treetests.exp b/gcc/testsuite/treelang/treetests.exp
new file mode 100644
index 0000000..10e6f84
--- /dev/null
+++ b/gcc/testsuite/treelang/treetests.exp
@@ -0,0 +1,289 @@
+
+# Tests for treelang; run from gcc/treelang/Make-lang.in => gcc/Makefile
+
+# Copyright (C) 1999, 2000, 2001, 2002 by The Free Software Foundation
+
+# find ttt for the actual tests
+
+# Check the pgm is even there and set up the basics
+proc init_utility {pgm} {
+ global transform
+ global pgm_actual
+ global pgm_base
+ global fix_progname
+ global path
+# maybe add "X" to front of fail to say it is an expected failure
+ global X
+
+ set pgm_base ${pgm}
+ set pgm_actual ${pgm}
+
+ if { ${transform} != "s,x,x,"} {
+ verbose "1. program name was ${pgm}" 2
+ set sed_rc [catch {eval exec sed -e "${transform}" <<${pgm} } catch_res]
+ if { ${sed_rc} != "0" } {
+ verbose "2. Program name transform failed rc=${sed_rc} stat=${catch_res}" 1
+ ${X}fail "${pgm} sed"
+ return 0
+ }
+ set pgm_actual ${catch_res}
+ verbose "3. program name after transformation is ${pgm_actual}" 2
+ }
+
+ set which_rc [catch {exec which ${pgm_actual}} stat]
+ if { ${which_rc} != "0" } {
+ verbose "4. ${pgm_base} cannot be found rc=${which_rc} stat=${stat}" 1
+ ${X}fail "${pgm} = ${pgm_actual} not found in path (${path})"
+ return 0
+ }
+ set fix_progname "s,${pgm_actual},${pgm_base},"
+ verbose "5. fix program name value = ${fix_progname}" 4
+ return 1
+}
+
+#run pgm, option to remove file names from outputs
+proc run3 {srcdd testdd parms group_nbr item_nbr nonzero_RC_expected check_file sanitize_output tree1 pipe} {
+
+ global transform
+ global pgm_actual
+ global pgm_base
+ global fix_progname
+ global X
+ global extras
+
+ set error_msg 0
+ set basefile "a${group_nbr}${pgm_base}.out${item_nbr}"
+ set infile ""
+ set outfile ""
+ set suffix ""
+ set temp_extras "-O3 "
+ set real_pgm_actual ${pgm_actual}
+
+ if {${tree1} > 0} {
+ if {"${pgm_actual}" == "gcc"} {
+ set real_pgm_actual "xgcc"
+ set temp_extras "${extras}"
+ }
+ set infile "${srcdd}/a${group_nbr}${pgm_base}i${item_nbr}.tree"
+ set mainfile "${srcdd}/a${group_nbr}${pgm_base}i${item_nbr}.c"
+ set outfile "-o ${testdd}/a${group_nbr}${pgm_base}o${item_nbr}${suffix}"
+ }
+
+ verbose "6. exec ${real_pgm_actual} ${temp_extras} ${parms} ${mainfile} ${infile} ${outfile} >${testdd}/${basefile} 2>${testdd}/${basefile}err" 2
+ set run_rc [catch {eval exec ${real_pgm_actual} ${temp_extras} ${parms} ${mainfile} ${infile} ${outfile} >${testdd}/${basefile} 2>${testdd}/${basefile}err} catch_res]
+ if {${run_rc} == 1} {
+ if {${nonzero_RC_expected} == 0} {
+ verbose "7. ${real_pgm_actual} ${group_nbr} ${item_nbr} failed due to rc=${run_rc} status=${catch_res}" 1
+ ${X}fail "${pgm_base} ${group_nbr} ${item_nbr} rc!=0"
+ return
+ }
+ } else {
+ if {${nonzero_RC_expected} == 1} {
+ verbose "8. ${pgm_actual} ${group_nbr} ${item_nbr} failed - did not produce nonzero return code as expected rc=${run_rc} status=${catch_res}" 1
+ ${X}fail "${pgm_base} ${group_nbr} ${item_nbr} rc=0"
+ return
+ }
+ }
+
+# change the filenames to (file) in output if needed to allow testing
+ set checkfile1 "${srcdd}/${basefile}"
+ set checkfile2 "${testdd}/${basefile}"
+ if {${sanitize_output} != 0} {
+ set oldcheckfile1 "${checkfile1}"
+ set oldcheckfile2 "${checkfile2}"
+ set checkfile1 "${testdd}/${basefile}.test.nofilename"
+ set checkfile2 "${testdd}/${basefile}.run.nofilename"
+ set run_rc [catch {eval exec sed -f ${srcdd}/filefix.sed <${oldcheckfile1} >${checkfile1}} catch_res]
+ if {${run_rc} == 1} {
+ verbose "9. sed to cleanup filenames (std 1) in pgm output failed due to rc=${run_rc} status=${catch_res}" 1
+ if {${error_msg} == 0} {
+ set error_msg "9. sed to cleanup filenames (std 1) in pgm output failed due to rc=${run_rc} status=${catch_res}"
+ }
+ }
+ set run_rc [catch {eval exec sed -f ${srcdd}/filefix.sed <${oldcheckfile2} | sed -e "${fix_progname}" >${checkfile2}} catch_res]
+ if {${run_rc} == 1} {
+ verbose "10. sed to cleanup filenames (std 2) in pgm output failed due to rc=${run_rc} status=${catch_res}" 1
+ if {${error_msg} == 0} {
+ set error_msg "10. sed to cleanup filenames (std 2) in pgm output failed due to rc=${run_rc} status=${catch_res}"
+ }
+ }
+ }
+ set diff [diff ${checkfile1} ${checkfile2}]
+ if {${diff} != 1} {
+ verbose "11. ${pgm_actual} ${group_nbr} ${item_nbr} diff stdout failed rc=${diff}" 1
+ if {${error_msg} == 0} {
+ set error_msg "11. ${pgm_actual} ${group_nbr} ${item_nbr} diff stdout failed rc=${diff}"
+ }
+ }
+
+ set checkfile1 "${srcdd}/${basefile}err"
+ set checkfile2 "${testdd}/${basefile}err"
+ if {${sanitize_output} != 0} {
+ set oldcheckfile1 "${checkfile1}"
+ set oldcheckfile2 "${checkfile2}"
+ set checkfile1 "${testdd}/${basefile}err.test.nofilename"
+ set checkfile2 "${testdd}/${basefile}err.run.nofilename"
+ set run_rc [catch {eval exec sed -f ${srcdd}/filefix.sed <${oldcheckfile1} >${checkfile1}} catch_res]
+ if {${run_rc} == 1} {
+ verbose "12. sed to cleanup filenames (err 1) in pgm output failed due to rc=${run_rc} status=${catch_res}" 1
+ if {${error_msg} == 0} {
+ set error_msg "12. sed to cleanup filenames (err 1) in pgm output failed due to rc=${run_rc} status=${catch_res}"
+ }
+ }
+ set run_rc [catch {eval exec sed -f ${srcdd}/filefix.sed <${oldcheckfile2} | sed -e "${fix_progname}" >${checkfile2}} catch_res]
+ if {${run_rc} == 1} {
+ verbose "13. sed to cleanup filenames (err 2) in pgm output failed due to rc=${run_rc} status=${catch_res}" 1
+ if {${error_msg} == 0} {
+ set error_msg "13. sed to cleanup filenames (err 2) in pgm output failed due to rc=${run_rc} status=${catch_res}"
+ }
+ }
+ }
+ set diff [diff ${checkfile1} ${checkfile2}]
+ if {${diff} != 1} {
+ verbose "14. ${pgm_actual} ${group_nbr} ${item_nbr} diff stderr failed rc=${diff}" 1
+ if {${error_msg} == 0} {
+ set error_msg "14. ${pgm_actual} ${group_nbr} ${item_nbr} diff stderr failed rc=${diff}"
+ }
+ }
+
+ if {${check_file} >0} {
+ if {${tree1} == 0} {
+ set checkfile1 "${srcdd}/${basefile}file"
+ set checkfile2 "${testdd}/${basefile}file"
+ if {${sanitize_output} != 0} {
+ set oldcheckfile1 "${checkfile1}"
+ set oldcheckfile2 "${checkfile2}"
+ set checkfile1 "${testdd}/${basefile}file.test.nofilename"
+ set checkfile2 "${testdd}/${basefile}file.run.nofilename"
+ set run_rc [catch {eval exec sed -f ${srcdd}/filefix.sed <${oldcheckfile1} >${checkfile1}} catch_res]
+ if {${run_rc} == 1} {
+ verbose "15. sed to cleanup filenames (err 1) in pgm stdout failed due to rc=${run_rc} status=${catch_res}" 1
+ if {${error_msg} == 0} {
+ set error_msg "15. sed to cleanup filenames (err 1) in pgm stdout failed due to rc=${run_rc} status=${catch_res}"
+ }
+ }
+ set run_rc [catch {eval exec sed -f ${srcdd}/filefix.sed <${oldcheckfile2} | sed -e "${fix_progname}" >${checkfile2}} catch_res]
+ if {${run_rc} == 1} {
+ verbose "16. sed to cleanup filenames (err 2) in pgm stdout failed due to rc=${run_rc} status=${catch_res}" 1
+ if {${error_msg} == 0} {
+ set error_msg "16. sed to cleanup filenames (err 2) in pgm stdout failed due to rc=${run_rc} status=${catch_res}"
+ }
+ }
+ }
+ set diff [diff ${checkfile1} ${checkfile2}]
+ if {${diff} != 1} {
+ verbose "17. ${pgm_actual} ${group_nbr} ${item_nbr} diff stdout file failed rc=${diff}" 1
+ if {${error_msg} == 0} {
+ set error_msg "17. ${pgm_actual} ${group_nbr} ${item_nbr} diff stdout file failed rc=${diff}"
+ }
+ }
+ }
+ }
+
+ if {${check_file} >1} {
+ if {${tree1} == 0} {
+ set checkfile1 "${srcdd}/${outfile}"
+ set checkfile2 "${testdd}/${outfile}"
+ if {${sanitize_output} != 0} {
+ set oldcheckfile1 "${checkfile1}"
+ set oldcheckfile2 "${checkfile2}"
+ set checkfile1 "${testdd}/${basefile}out.test.nofilename"
+ set checkfile2 "${testdd}/${basefile}out.run.nofilename"
+ set run_rc [catch {eval exec sed -f ${srcdd}/filefix.sed <${oldcheckfile1} >${checkfile1}} catch_res]
+ if {${run_rc} == 1} {
+ verbose "18. sed to cleanup filenames (err 1) in pgm output failed due to rc=${run_rc} status=${catch_res}" 1
+ if {${error_msg} == 0} {
+ set error_msg "18. sed to cleanup filenames (err 1) in pgm output failed due to rc=${run_rc} status=${catch_res}"
+ }
+ }
+ set run_rc [catch {eval exec sed -f ${srcdd}/filefix.sed <${oldcheckfile2} | sed -e "${fix_progname}" >${checkfile2}} catch_res]
+ if {${run_rc} == 1} {
+ verbose "19. sed to cleanup filenames (err 2) in pgm output failed due to rc=${run_rc} status=${catch_res}" 1
+ if {${error_msg} == 0} {
+ set error_msg "19. sed to cleanup filenames (err 2) in pgm output failed due to rc=${run_rc} status=${catch_res}"
+ }
+ }
+ }
+ set diff [diff ${checkfile1} ${checkfile2}]
+ if {${diff} != 1} {
+ verbose "20. ${pgm_actual} ${group_nbr} ${item_nbr} diff output file failed rc=${diff}" 1
+ if {${error_msg} == 0} {
+ set error_msg "20. ${pgm_actual} ${group_nbr} ${item_nbr} diff output file failed rc=${diff}"
+ }
+ }
+ }
+ }
+
+ if {${check_file} >2} {
+ set outfile "a${group_nbr}${pgm_base}o${item_nbr}${suffix}"
+ set pgmrun "${testdd}/a${group_nbr}${pgm_base}o${item_nbr}${suffix}"
+ set checkfile1 "${srcdd}/${outfile}runpgm"
+ set checkfile2 "${testdd}/${outfile}runpgm"
+ verbose "21. exec ${pgmrun} >${checkfile2} 2>${checkfile2}err" 2
+ set run_rc [catch {eval exec ${pgmrun} >${checkfile2} 2>${checkfile2}err} catch_res]
+ if {${run_rc} == 1} {
+ if {${nonzero_RC_expected} == 0} {
+ verbose "22. ${pgm_actual} ${group_nbr} ${item_nbr} failed due to rc=${run_rc} status=${catch_res}" 1
+ ${X}fail "${pgm_base} ${group_nbr} ${item_nbr} run"
+ return
+ }
+ } else {
+ if {${nonzero_RC_expected} == 1} {
+ verbose "23. ${pgm_actual} ${group_nbr} ${item_nbr} failed - did not produce nonzero return code as expected rc=${run_rc} status=${catch_res}" 1
+ ${X}fail "${pgm_base} ${group_nbr} ${item_nbr} run"
+ return
+ }
+ }
+ set diff [diff ${checkfile1} ${checkfile2}]
+ if {${diff} != 1} {
+ verbose "24. ${pgm_actual} ${group_nbr} ${item_nbr} diff run output file failed rc=${diff}" 1
+ if {${error_msg} == 0} {
+ set error_msg "24. ${pgm_actual} ${group_nbr} ${item_nbr} diff run output file failed rc=${diff}"
+ }
+ }
+ set diff [diff ${checkfile1}err ${checkfile2}err]
+ if {${diff} != 1} {
+ verbose "25. ${pgm_actual} ${group_nbr} ${item_nbr} diff run stderr file failed rc=${diff}" 1
+ if {${error_msg} == 0} {
+ set error_msg "25. ${pgm_actual} ${group_nbr} ${item_nbr} diff run stderr file failed rc=${diff}"
+ }
+ }
+ }
+
+ if {${error_msg}>0} {
+ ${X}fail "${pgm_base} ${group_nbr} ${item_nbr} fail code=${error_msg}"
+ } else {
+ pass "${pgm_base} ${group_nbr} ${item_nbr}"
+ }
+ return
+}
+
+set extras "$env(gcc_extras)"
+set path $env(PATH)
+set transform $env(TRANSFORM)
+set srcdir $env(srcdir)
+verbose "source directory ${srcdir}\n" 2
+verbose "transform ${transform}\n" 2
+set sourcedir "${srcdir}/testsuite/treelang"
+set testdir "treelang"
+
+set pgm_actual ""
+
+# srcdd testdd parms group_nbr item_nbr nonzero_RC_expected check_file sanitize_output tree1
+
+# ttt
+
+#GCC - main C compiler tests via GCC
+
+set X ""
+
+set check_rc [init_utility "gcc"]
+
+if {${check_rc} == 1} {
+#
+#set X "x"
+set X ""
+ run3 "${sourcedir}" "${testdir}" " -g -O3 " 01 01 0 3 0 1 0
+set X ""
+}
+
diff --git a/gcc/treelang/ChangeLog b/gcc/treelang/ChangeLog
new file mode 100644
index 0000000..18b7e08
--- /dev/null
+++ b/gcc/treelang/ChangeLog
@@ -0,0 +1,24 @@
+2002-05-05 Tim Josling <tej@melbpc.org.au>
+
+ * Updated for gcc3.2 experimental. Major changes throughout.
+
+2002-03-31 Tim Josling <tej@melbpc.org.au>
+
+ * Make-lang.in: Changes so build and check work more reliably
+
+2001-07-30 Tim Josling <tej@melbpc.org.au>
+
+ * root.texi: remove
+ * treelang.texi: updates based on feedback
+
+2001-06-11 Tim Josling <tej@melbpc.org.au>
+
+ * all (all) Revamp code to conform to GCC coding standards, fix
+ typos in texi files.
+
+2001-05-11 Tim Josling <tej@melbpc.org.au>
+
+ Create the new language.
+
+
+
diff --git a/gcc/treelang/Make-lang.in b/gcc/treelang/Make-lang.in
new file mode 100644
index 0000000..bd6f7e3
--- /dev/null
+++ b/gcc/treelang/Make-lang.in
@@ -0,0 +1,297 @@
+# Top level makefile fragment for TREELANG For GCC. -*- makefile -*-
+
+# Copyright (C) 1994, 1995, 1997, 1998, 1999 2000, 2001, 2002 Free
+# Software Foundation, Inc.
+
+#This file is part of GCC.
+
+#GCC 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.
+
+#GCC 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 GCC; see the file COPYING. If not, write to
+#the Free Software Foundation, 59 Temple Place - Suite 330,
+#Boston, MA 02111-1307, USA.
+
+# This file provides the language dependent support in the main Makefile.
+# Each language makefile fragment must provide the following targets:
+#
+# foo.all.build, foo.all.cross, foo.start.encap, foo.rest.encap,
+# foo.info, foo.dvi,
+# foo.install-normal, foo.install-common, foo.install-info, foo.install-man,
+# foo.uninstall, foo.distdir,
+# foo.mostlyclean, foo.clean, foo.distclean, foo.extraclean,
+# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4
+#
+# where `foo' is the name of the language.
+#
+# It should also provide rules for:
+#
+# - making any compiler driver (eg: GCC)
+# - the compiler proper (eg: treelang)
+# - define the names for selecting the language in LANGUAGES.
+#
+
+## note program-prefix and program-suffix options are not supported
+## just program_transform_name which is a sed script to transform the
+## names
+
+TREELANGSED = sed
+TREELANGSEDFLAGS = -n
+
+# back end compiler libraries etc
+TREE_BE_LIBS = $(BACKEND) $(LIBIBERTY) $(INTLLIBS) $(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.
+# If this can't be found, you probably have not done a bootstrap of GCC,
+# which you need to do.
+
+# GCC_FOR_TREELANG = ./xgcc $(GCC_EXTRAS)
+
+TREE_GENERATED = $(srcdir)/treelang/lex.c $(srcdir)/treelang/parse.c\
+ $(srcdir)/treelang/parse.h $(srcdir)/treelang/parse.output $(srcdir)/treelang/TAGS
+
+TREE_SOURCE = ${srcdir}/treelang/parse.y ${srcdir}/treelang/lex.l ${srcdir}/treelang/tree1.c ${srcdir}/treelang/treelang.h ${srcdir}/treelang/treetree.c $(srcdir)/treelang/treetree.h
+
+TREE_EXES = tree1$(exeext)
+
+#no -Wtraditional warnings, allow long long
+treelang-warn = $(LOOSE_WARN) -pedantic -Wno-long-long -Wmissing-prototypes -Wmissing-declarations
+
+#
+# Define the names for selecting treelang in LANGUAGES.
+
+.phony: treelang TREELANG
+
+treelang TREELANG:treelang.done
+
+treelang.done: tree1$(exeext)
+ $(STAMP) treelang.done
+
+# no preprocessor
+
+# core compiler
+tree1$(exeext): treelang/tree1.o treelang/treetree.o treelang/lex.o treelang/parse.o\
+ $(TREE_BE_LIBS) c-convert.o c-typeck.o c-common.o c-decl.o attribs.o
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ treelang/tree1.o treelang/treetree.o treelang/lex.o treelang/parse.o c-convert.o\
+ c-typeck.o c-common.o c-decl.o attribs.o $(TREE_BE_LIBS)
+
+#
+# Compiling object files from source files.
+
+# object file makes
+
+treelang/tree1.o: $(srcdir)/treelang/tree1.c $(srcdir)/treelang/treelang.h $(srcdir)/treelang/parse.h
+ $(CC) -o $@ -c $(ALL_CFLAGS) $(INCLUDES) $<
+
+treelang/treetree.o: $(srcdir)/treelang/treetree.c $(srcdir)/treelang/treetree.h
+ $(CC) -o $@ -c $(ALL_CFLAGS) $(INCLUDES) $<
+
+treelang/parse.o: $(srcdir)/treelang/parse.c $(srcdir)/treelang/treelang.h $(srcdir)/treelang/treetree.h
+ $(CC) -o $@ -c $(ALL_CFLAGS) $(INCLUDES) $<
+
+treelang/lex.o: $(srcdir)/treelang/lex.c $(srcdir)/treelang/parse.h $(srcdir)/treelang/treelang.h
+ $(CC) -o $@ -c $(ALL_CFLAGS) $(INCLUDES) $<
+
+# generated files the files from lex and yacc are put into the source
+# directory in case someone wants to build but does not have
+# lex/yacc
+
+$(srcdir)/treelang/lex.c: $(srcdir)/treelang/lex.l
+ $(LEX) $(LEXFLAGS) -o$(srcdir)/treelang/lex.c $(srcdir)/treelang/lex.l
+
+$(srcdir)/treelang/parse.c $(srcdir)/treelang/parse.h: $(srcdir)/treelang/parse.y
+ $(BISON) $(BISONFLAGS) -v $(srcdir)/treelang/parse.y\
+ --output=$(srcdir)/treelang/parse.c --defines
+# -v
+
+#
+# Build hooks:
+
+treelang.all.build: treelang
+treelang.all.cross:
+ _error_not_here_yet - havent even thought about it - it may even work
+
+treelang.start.encap:
+treelang.rest.encap:
+
+.phony:treelang.info
+treelang.info: $(srcdir)/treelang/treelang.info
+
+$(srcdir)/treelang/treelang.info: $(srcdir)/treelang/treelang.texi
+ cd $(srcdir)/treelang && $(MAKEINFO) $(MAKEINFOFLAGS) -I../doc/include \
+ -o $(srcdir)/treelang/treelang.info $(srcdir)/treelang/treelang.texi
+
+treelang.dvi: $(srcdir)/treelang/treelang.texi
+ TEXINPUTS=$(srcdir)/treelang:$(srcdir):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/treelang/treelang.texi; \
+ texindex treelang.??; \
+ TEXINPUTS=$(srcdir)/treelang:$(srcdir):$$TEXINPUTS $(TEXI2DVI) $(srcdir)/treelang/treelang.texi; \
+ mv treelang.dvi treelang;
+
+#
+# Install hooks:
+
+# Nothing to do here.
+treelang.install-normal: treelang.install.common
+
+# Install
+.phony:treelang.install.common
+.phony:treelang.install
+
+treelang.install treelang.install.common treelang.install-common: treelang.install.common.done
+
+treelang.install.common.done: installdirs treelang.done
+ for name in $(TREE_EXES); \
+ do \
+ if [ -f $$name ] ; then \
+ name2="`echo \`basename $$name\` | sed -e '$(program_transform_name)' `"; \
+ rm -f $(bindir)/$$name2$(exeext); \
+ $(INSTALL_PROGRAM) $$name$(exeext) $(bindir)/$$name2$(exeext); \
+ chmod a+x $(bindir)/$$name2$(exeext); \
+ fi ; \
+ done
+ $(STAMP) treelang.install.common.done
+
+treelang.install-info: $(srcdir)/treelang/treelang.info
+ for name in $(srcdir)/treelang/treelang.info; \
+ do \
+ if [ -f $$name ] ; then \
+ name2="`echo \`basename $$name\` | sed -e '$(program_transform_name)' `"; \
+ rm -f $(libsubdir)/$$name2$(exeext); \
+ $(INSTALL_PROGRAM) $$name$(exeext) $(libsubdir)/$$name2$(exeext); \
+ chmod a+x $(libsubdir)/$$name2$(exeext); \
+ fi ; \
+ done
+
+treelang.install-man:
+
+treelang.uninstall:
+ for name in $(TREE_EXES); \
+ do \
+ echo $$name; \
+ name2="`echo $$name | sed -e '$(program_transform_name)' `"; \
+ echo becomes $$name2; \
+ echo -rm -rf $(bindir)/$$name2$(exeext); \
+ rm -rf $(bindir)/$$name2$(exeext); \
+ done
+ -rm treelang.install.common.done
+
+#
+# Clean hooks:
+# A lot of the ancillary files are deleted by the main makefile.
+# We just have to delete files specific to us.
+
+treelang.mostlyclean:
+ for name in $(TREE_EXES); \
+ do \
+ echo deleting $$name; \
+ if [ -f treelang/$$name$(exeext) ] ; then \
+ rm -f treelang/$$name$(exeext); \
+ fi ; \
+ done
+ -rm -f treelang/*.o
+ -rm treelang.done
+
+
+treelang.clean: treelang.mostlyclean
+
+treelang.distclean: treelang.clean
+ -rm -f treelang/config.status
+ -rm -f treelang/*.output
+
+treelang.extraclean: treelang.distclean
+
+treelang.maintainer-clean: treelang.extraclean
+ for name in $(TREE_GENERATED); \
+ do \
+ if [ -f $(srcdir)/treelang/$$name ] ; then \
+ echo deleting $(srcdir)/treelang/$$name; \
+ rm -f $(srcdir)/treelang/$$name; \
+ fi ; \
+ done
+ -rm -R $(srcdir)/treelang/*~
+
+
+#
+# Stage hooks:
+# The main makefile has already created stage?/treelang.
+
+treelang.stage1: stage1-start
+ -mv treelang/*$(objext) stage1/treelang
+treelang.stage2: stage2-start
+ -mv treelang/*$(objext) stage2/treelang
+treelang.stage3: stage3-start
+ -mv treelang/*$(objext) stage3/treelang
+treelang.stage4: stage4-start
+ -mv treelang/*$(objext) stage4/treelang
+#
+# Maintenance hooks:
+
+# This target creates the files that can be rebuilt, but go in the
+# distribution anyway. It then copies the files to the distdir directory.
+treelang.distdir:
+# not here yet sorry not sure if this is needed or not???
+
+# test hook
+# the other languages are hard coded in the main makefile.in - that seems to be wrong
+
+check: treelang.check
+
+TESTSUITEDIR = testsuite
+
+treelang.check: $(TESTSUITEDIR)/site.exp
+ -mkdir testsuite/treelang
+
+# these three files are empty and it seems diff has trouble generating
+# patch files for new empty files as required for cvs.
+# STAMP does not cut it here as I need an empty file.
+ touch $(srcdir)/testsuite/treelang/{a01gcco01runpgmerr,a01gcc.out01,a01gcc.out01err}
+ -rootme=`pwd`; export rootme; \
+ srcdir=`cd ${srcdir}; pwd` ; export srcdir ; \
+ cd testsuite; \
+ EXPECT=${EXPECT} ; export EXPECT ; \
+ TRANSFORM=$(program_transform_name); export TRANSFORM; \
+ if [ -f $${rootme}/../expect/expect ] ; then \
+ TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; pwd` ; \
+ export TCL_LIBRARY ; fi ; \
+ PATH=`cd ..;pwd`:$$PATH; export PATH; \
+ gcc_extras="-B`cd ..;pwd` -B`cd ..;pwd`/treelang"; export gcc_extras; \
+ $(RUNTEST) --tool treelang $(RUNTESTFLAGS)
+ rm $(srcdir)/testsuite/treelang/{a01gcco01runpgmerr,a01gcc.out01,a01gcc.out01err}
+# GCC_EXTRAS="$(GCC_EXTRAS)"; export GCC_EXTRAS; \
+
+# copy the output files from the current test to source ie say the new results are OK
+treelang.check.fix: force
+ srcdir=`cd ${srcdir}; pwd` ; export srcdir ;
+ -cp testsuite/treelang/*.out* t
+ -cp testsuite/treelang/*runpgm* t
+ -rm -f t/*nofilename
+
+treelang.wc: force
+ wc ${TREE_SOURCE}
+
+#
+
+# Update the tags table for emacs find label (alt-.) function
+TAGS: treelang.tags
+
+.PHONY: treelang.tags
+
+treelang.tags:
+ cd $(srcdir)/treelang; \
+ etags -l c ${TREE_SOURCE}
+
+.PHONY: treelang.html
+
+treelang.html:
+ cd $(srcdir)/treelang && texi2html -I ../doc/include -verbose -menu -split_chapter -number treelang.texi
+# mv treelang*.html $(srcdir)/treelang
diff --git a/gcc/treelang/README b/gcc/treelang/README
new file mode 100644
index 0000000..f16eafc
--- /dev/null
+++ b/gcc/treelang/README
@@ -0,0 +1,16 @@
+This is a sample language front end for GCC.
+
+This is a replacement for 'toy' which had potential copyright issues,
+but more importantly it did not exercise very much of GCC. The intent
+of this language is that it should provide a cookbook of language
+elements that you can use in any language front end.
+
+To this end, treelang is essentially an implementation of a subset of
+the GCC back end 'tree' interface in syntax.
+
+Thanks to Richard Kenner, Joachim Nadler and many others for helping
+me to understand enough of GCC to do this.
+
+Tim Josling
+May 2001
+
diff --git a/gcc/treelang/config-lang.in b/gcc/treelang/config-lang.in
new file mode 100644
index 0000000..6cf1f45
--- /dev/null
+++ b/gcc/treelang/config-lang.in
@@ -0,0 +1,37 @@
+# Top level configure fragment for GNU C++.
+# Copyright (C) 1994, 1995, 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+#This file is part of GCC.
+
+#GCC 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.
+
+#GCC 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 GCC; see the file COPYING. If not, write to
+#the Free Software Foundation, 59 Temple Place - Suite 330,
+#Boston, MA 02111-1307, USA.
+
+# Configure looks for the existence of this file to auto-config each language.
+# We define several parameters used by configure:
+#
+# language - name of language as it would appear in $(LANGUAGES)
+# compilers - value to add to $(COMPILERS)
+# stagestuff - files to add to $(STAGESTUFF)
+# diff_excludes - files to ignore when building diffs between two versions.
+
+language="treelang"
+
+compilers="tree1\$(exeext)"
+
+stagestuff=
+
+diff_excludes="-x lex.c -x parse.c -x parse.h"
+headers=
+build_by_default="no"
diff --git a/gcc/treelang/lang-options.h b/gcc/treelang/lang-options.h
new file mode 100644
index 0000000..2d60c3e
--- /dev/null
+++ b/gcc/treelang/lang-options.h
@@ -0,0 +1,29 @@
+/* Definitions for switches for TREELANG.
+
+ Copyright (C) 1995, 96-98, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+DEFINE_LANG_NAME ("treelang")
+
+/* This is the contribution to the `lang_options' array in gcc.c for
+ treelang. */
+ {"-fparser-trace", N_("(debug) trace parsing process")},
+ {"-flexer-trace", N_("(debug) trace lexical analysis")},
+
+
diff --git a/gcc/treelang/lang-specs.h b/gcc/treelang/lang-specs.h
new file mode 100644
index 0000000..4bf8e5d
--- /dev/null
+++ b/gcc/treelang/lang-specs.h
@@ -0,0 +1,63 @@
+/* Definitions for specs for TREELANG
+
+ The format of the specs file is documented in gcc.c
+
+ Copyright (C) 1995, 96-98, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/*
+ This is the contribution to the `default_compilers' array in GCC.c for
+ treelang.
+
+ This file must compile with 'traditional', so no ANSI string concatenations
+
+*/
+
+{".tree", "@treelang", NULL},
+{".TREE", "@treelang", NULL},
+{".tre", "@treelang", NULL},
+{".TRE", "@treelang", NULL},
+{"@treelang",
+ "tree1\
+ %{!Q:-quiet}\
+ %{d*}\
+ %{m*}\
+ %{a}\
+ %{g*}\
+ %{O*}\
+ %{W*}\
+ %{w}\
+ %{ansi}\
+ %{v}\
+ %{--help:--help}\
+ %{pg:-p}\
+ %{p}\
+ %{f*}\
+ %{pg|p:%{fomit-frame-pointer:%e-pg or -p and -fomit-frame-pointer are incompatible}}\
+ %{S:%W{o*}%{!o*:-o %b.s}}\
+ %{!S:-o %g.s}\
+ %i\n\
+ %{!S:as %a\
+ %Y\
+ %{c:%W{o*}%{!o*:-o %w%b%O}}\
+ %{!c:-o %d%w%u%O}\
+ %g.s\
+ %A\n}\
+ ", NULL
+},
diff --git a/gcc/treelang/lex.l b/gcc/treelang/lex.l
new file mode 100644
index 0000000..97b06a6
--- /dev/null
+++ b/gcc/treelang/lex.l
@@ -0,0 +1,294 @@
+%{ /* -*- c -*- = mode for emacs editor
+/*
+
+ TREELANG lexical analysis
+
+ ---------------------------------------------------------------------
+
+ Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002 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
+ 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!
+
+ ---------------------------------------------------------------------
+
+ Written by Tim Josling 1999-2001, based in part on other parts of
+ the GCC compiler.
+
+*/
+
+/* Avoid poisoned malloc problem. */
+#undef IN_GCC
+
+#if 0
+/* tree is defined as void* here to avoid any knowledge of tree stuff in this file. */
+typedef void *tree;
+#endif
+#include <stdio.h>
+#if 0
+#include <ctype.h>
+#endif
+#include <memory.h>
+#include "ansidecl.h"
+#include "config.h"
+#include "system.h"
+#include "diagnostic.h"
+
+/* Token defs. */
+#include "treelang.h"
+#include "parse.h"
+
+extern int option_lexer_trace;
+
+int yylex (void);
+void update_yylval (int a);
+
+static int next_tree_lineno=1;
+static int next_tree_charno=1;
+
+static void update_lineno_charno (void);
+static void dump_lex_value (int lexret);
+
+#define SAVE_RETURN(a) {update_yylval (a); if (option_lexer_trace)\
+ {fprintf (stderr, "\nlexer returning"); dump_lex_value (a);} return a;}
+#define NOT_RETURN(a) {update_yylval (a); if (option_lexer_trace)\
+ {fprintf (stderr, "\nlexer swallowing"); dump_lex_value (a);}}
+
+%}
+
+%option nostack
+%option nounput
+%option noyywrap
+%option pointer
+%option nodefault
+
+%%
+
+ {
+ yylval = my_malloc (sizeof (struct token));
+ ((struct token*)yylval)->lineno = next_tree_lineno;
+ ((struct token*)yylval)->charno = next_tree_charno;
+ }
+
+[ \n]+ {
+ update_lineno_charno ();
+ NOT_RETURN (WHITESPACE);
+}
+
+"//".* {
+ /* Comment. */
+ update_lineno_charno ();
+ NOT_RETURN (COMMENT);
+}
+
+"{" {
+ update_lineno_charno ();
+ SAVE_RETURN (LEFT_BRACE);
+}
+
+"}" {
+ update_lineno_charno ();
+ SAVE_RETURN (RIGHT_BRACE);
+}
+
+"(" {
+ update_lineno_charno ();
+ SAVE_RETURN (LEFT_PARENTHESIS);
+}
+
+")" {
+ update_lineno_charno ();
+ SAVE_RETURN (RIGHT_PARENTHESIS);
+}
+
+"," {
+ update_lineno_charno ();
+ SAVE_RETURN (COMMA);
+}
+
+";" {
+ update_lineno_charno ();
+ SAVE_RETURN (SEMICOLON);
+}
+
+"+" {
+ update_lineno_charno ();
+ SAVE_RETURN (PLUS);
+}
+
+"-" {
+ update_lineno_charno ();
+ SAVE_RETURN (MINUS);
+}
+
+"=" {
+ update_lineno_charno ();
+ SAVE_RETURN (ASSIGN);
+}
+
+"==" {
+ update_lineno_charno ();
+ SAVE_RETURN (EQUALS);
+}
+
+[+-]?[0-9]+ {
+ update_lineno_charno ();
+ SAVE_RETURN (INTEGER);
+}
+
+"external_reference" {
+ update_lineno_charno ();
+ SAVE_RETURN (EXTERNAL_REFERENCE);
+}
+
+"external_definition" {
+ update_lineno_charno ();
+ SAVE_RETURN (EXTERNAL_DEFINITION);
+}
+
+"static" {
+ update_lineno_charno ();
+ SAVE_RETURN (STATIC);
+}
+
+"automatic" {
+ update_lineno_charno ();
+ SAVE_RETURN (STATIC);
+}
+
+"int" {
+ update_lineno_charno ();
+ SAVE_RETURN (INT);
+}
+
+"char" {
+ update_lineno_charno ();
+ SAVE_RETURN (CHAR);
+}
+
+"void" {
+ update_lineno_charno ();
+ SAVE_RETURN (VOID);
+}
+
+"unsigned" {
+ update_lineno_charno ();
+ SAVE_RETURN (UNSIGNED);
+}
+
+"return" {
+ update_lineno_charno ();
+ SAVE_RETURN (RETURN);
+}
+
+"if" {
+ update_lineno_charno ();
+ SAVE_RETURN (IF);
+}
+
+"else" {
+ update_lineno_charno ();
+ SAVE_RETURN (ELSE);
+}
+
+[A-Za-z_]+[A-Za-z_0-9]* {
+ update_lineno_charno ();
+ update_yylval (NAME);
+ if (option_lexer_trace)
+ {
+ fprintf (stderr, "\nlexer returning");
+ dump_lex_value (NAME);
+ }
+ return NAME;
+}
+
+[^\n] {
+ update_lineno_charno ();
+ fprintf (stderr, "%s:%i:%i: Unrecognized character %c\n", in_fname,
+ ((struct token*)yylval)->lineno,
+ ((struct token*)yylval)->charno, yytext[0]);
+ errorcount++;
+}
+
+%%
+
+/*
+ Update line number (1-) and character number (1-). Call this
+ before processing the token. */
+
+static void
+update_lineno_charno (void)
+{
+ /* Update the values we send to caller in case we sometimes don't
+ tell them about all the 'tokens' eg comments etc. */
+ int yyl;
+ ((struct token*)yylval)->lineno = next_tree_lineno;
+ ((struct token*)yylval)->charno = next_tree_charno;
+ for ( yyl = 0; yyl < yyleng; ++yyl )
+ {
+ if ( yytext[yyl] == '\n' )
+ {
+ ++next_tree_lineno;
+ next_tree_charno = 1;
+ }
+ else
+ next_tree_charno++;
+ }
+}
+
+/* Fill in the fields of yylval - the value of the token. The token
+ type is A. */
+void
+update_yylval (int a)
+{
+ struct token* tok;
+ tok=yylval;
+
+ tok->category = token_category;
+ tok->type = a;
+ tok->length = yyleng;
+ /* Have to copy yytext as it is just a ptr into the buffer at the
+ moment. */
+ tok->chars = my_malloc (yyleng + 1);
+ memcpy (tok->chars, yytext, yyleng);
+}
+
+/* Trace the value LEXRET and the position and token details being
+ returned by the lexical analyser. */
+
+static void
+dump_lex_value (int lexret)
+{
+ int ix;
+ fprintf (stderr, " %d l:%d c:%d ln:%d text=", lexret,
+ ((struct token*) yylval)->lineno,
+ ((struct token*) yylval)->charno,
+ ((struct token*) yylval)->length);
+ for (ix = 0; ix < yyleng; ix++)
+ {
+ fprintf (stderr, "%c", yytext[ix]);
+ }
+ fprintf (stderr, " in hex:");
+ for (ix = 0; ix < yyleng; ix++)
+ {
+ fprintf (stderr, " %2.2x", yytext[ix]);
+ }
+ fprintf (stderr, "\n");
+}
+
diff --git a/gcc/treelang/parse.y b/gcc/treelang/parse.y
new file mode 100644
index 0000000..f0c0cef
--- /dev/null
+++ b/gcc/treelang/parse.y
@@ -0,0 +1,1001 @@
+%{ /* -*- c -*- emacs mode c */
+ /*
+
+ TREELANG Compiler parser.
+
+ ---------------------------------------------------------------------
+
+ Copyright (C) 1999, 2000, 2001, 2002 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
+ 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!
+
+ ---------------------------------------------------------------------
+
+ Written by Tim Josling 1999-2001, based in part on other parts of
+ the GCC compiler.
+
+ */
+
+ /*
+
+ Grammar Conflicts
+ *****************
+
+ There are no conflicts in this grammar. Please keep it that way.
+
+ */
+
+#undef IN_GCC
+
+typedef void *tree;
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ansidecl.h"
+#include "config.h"
+#include "system.h"
+#include "diagnostic.h"
+
+#include "treelang.h"
+#include "treetree.h"
+
+#define YYDEBUG 1
+#define YYPRINT(file, type, value) print_token (file, type, value)
+#define YYERROR_VERBOSE YES
+
+
+extern int option_parser_trace;
+
+/* Local prototypes. */
+
+static void yyerror (const char *error_message);
+int yylex (void);
+int yyparse (void);
+void print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value);
+static struct production *reverse_prod_list (struct production *old_first);
+static void ensure_not_void (unsigned int type, struct token* name);
+static int check_type_match (int type_num, struct production *exp);
+static int get_common_type (struct production *type1, struct production *type2);
+static struct production *make_integer_constant (struct token* value);
+static void set_storage (struct production *prod);
+
+/* File global variables. */
+
+static struct production *current_function=NULL;
+
+%}
+
+/* Not %raw - seems to have bugs. */
+%token_table
+
+/* Punctuation. */
+%token RIGHT_BRACE
+%token LEFT_BRACE
+%token RIGHT_SQUARE_BRACKET
+%token LEFT_SQUARE_BRACKET
+%token RIGHT_PARENTHESIS
+%token LEFT_PARENTHESIS
+%token SEMICOLON
+%token ASTERISK
+%token COMMA
+%right EQUALS
+%right ASSIGN
+%left PLUS
+%left MINUS
+
+/* Literals. */
+%token INTEGER
+
+/* Keywords. */
+%token IF
+%token ELSE
+%token RETURN
+%token CHAR
+%token INT
+%token UNSIGNED
+%token VOID
+%token TYPEDEF
+%token NAME
+%token STATIC
+%token AUTOMATIC
+%token EXTERNAL_DEFINITION
+%token EXTERNAL_REFERENCE
+
+/* Tokens not passed to parser. */
+%token WHITESPACE
+%token COMMENT
+
+/* Pseudo tokens - productions. */
+%token PROD_VARIABLE_NAME
+%token PROD_TYPE_NAME
+%token PROD_FUNCTION_NAME
+%token PROD_INTEGER_CONSTANT
+%token PROD_PLUS_EXPRESSION
+%token PROD_MINUS_EXPRESSION
+%token PROD_ASSIGN_EXPRESSION
+%token PROD_VARIABLE_REFERENCE_EXPRESSION
+%token PROD_PARAMETER
+%token PROD_FUNCTION_INVOCATION
+%expect 0
+%%
+
+file:
+/* Nil. */ {
+ /* Nothing to do. */
+}
+|declarations {
+ /* Nothing to do. */
+}
+;
+
+
+declarations:
+declaration {
+ /* Nothing to do. */
+}
+| declarations declaration {
+ /* Nothing to do. */
+}
+;
+
+declaration:
+variable_def {
+ /* Nothing to do. */
+}
+|function_prototype {
+ /* Nothing to do. */
+}
+|function {
+ /* Nothing to do. */
+}
+;
+
+variable_def:
+storage typename NAME init_opt SEMICOLON {
+ struct token* tok;
+ struct production *prod;
+ tok = $3;
+ prod = make_production (PROD_VARIABLE_NAME, tok);
+ SYMBOL_TABLE_NAME (prod) = tok;
+ EXPRESSION_TYPE (prod) = $2;
+ VAR_INIT (prod) = $4;
+ NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct production*)EXPRESSION_TYPE (prod)));
+ ensure_not_void (NUMERIC_TYPE (prod), tok);
+ if (insert_tree_name (prod))
+ {
+ YYERROR;
+ }
+ STORAGE_CLASS_TOKEN (prod) = $1;
+ set_storage (prod);
+
+ if (VAR_INIT (prod))
+ {
+ if (! ((struct production*)VAR_INIT (prod))->code)
+ abort ();
+ if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
+ {
+ fprintf (stderr, "%s:%i:%i: External reference variables may not have initial value\n", in_fname,
+ tok->lineno, tok->charno);
+ print_token (stderr, 0, tok);
+ errorcount++;
+ YYERROR;
+ }
+ }
+ prod->code = tree_code_create_variable
+ (STORAGE_CLASS (prod),
+ ((struct token*)SYMBOL_TABLE_NAME (prod))->chars,
+ ((struct token*)SYMBOL_TABLE_NAME (prod))->length,
+ NUMERIC_TYPE (prod),
+ VAR_INIT (prod)? ((struct production*)VAR_INIT (prod))->code:NULL,
+ in_fname,
+ tok->lineno);
+ if (!prod->code)
+ abort ();
+}
+;
+
+storage:
+STATIC
+|AUTOMATIC
+|EXTERNAL_DEFINITION
+|EXTERNAL_REFERENCE
+;
+
+parameter:
+typename NAME {
+ struct token* tok;
+ struct production *prod;
+ struct production *prod2;
+ tok = $2;
+ prod = make_production (PROD_VARIABLE_NAME, tok);
+ SYMBOL_TABLE_NAME (prod) = $2;
+ EXPRESSION_TYPE (prod) = $1;
+ NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct production*)EXPRESSION_TYPE (prod)));
+ ensure_not_void (NUMERIC_TYPE (prod), tok);
+ if (insert_tree_name (prod))
+ {
+ YYERROR;
+ }
+ prod2 = make_production (PROD_PARAMETER, tok);
+ VARIABLE (prod2) = prod;
+ $$ = prod2;
+}
+;
+
+function_prototype:
+storage typename NAME LEFT_PARENTHESIS parameters RIGHT_PARENTHESIS SEMICOLON {
+ struct token* tok;
+ struct production *prod;
+ struct production *type;
+ struct tree_parameter_list* first_parms;
+ struct tree_parameter_list* last_parms;
+ struct tree_parameter_list* this_parms;
+ struct production *this_parm;
+ struct production *this_parm_var;
+ tok = $3;
+ prod = make_production (PROD_FUNCTION_NAME, $3);
+ SYMBOL_TABLE_NAME (prod) = $3;
+ EXPRESSION_TYPE (prod) = $2;
+ NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct production*)EXPRESSION_TYPE (prod)));
+ PARAMETERS (prod) = reverse_prod_list ($5);
+ insert_tree_name (prod);
+ STORAGE_CLASS_TOKEN (prod) = $1;
+ set_storage (prod);
+ switch (STORAGE_CLASS (prod))
+ {
+ case STATIC_STORAGE:
+ case EXTERNAL_DEFINITION_STORAGE:
+ break;
+
+ case AUTOMATIC_STORAGE:
+ fprintf (stderr, "%s:%i:%i: A function cannot be automatic\n", in_fname,
+ tok->lineno, tok->charno);
+ print_token (stderr, 0, tok);
+ errorcount++;
+ YYERROR;
+ break;
+
+ default:
+ abort ();
+ }
+ type = EXPRESSION_TYPE (prod);
+ /* Create a parameter list in a non-front end specific format. */
+ for (first_parms = NULL, last_parms = NULL, this_parm = PARAMETERS (prod);
+ this_parm;
+ this_parm = this_parm->next)
+ {
+ if (this_parm->category != production_category)
+ abort ();
+ this_parm_var = VARIABLE (this_parm);
+ if (!this_parm_var)
+ abort ();
+ if (this_parm_var->category != production_category)
+ abort ();
+ this_parms = my_malloc (sizeof (struct tree_parameter_list));
+ if (!this_parm_var->main_token)
+ abort ();
+ this_parms->variable_name = this_parm_var->main_token->chars;
+ this_parms->type = NUMERIC_TYPE (( (struct production*)EXPRESSION_TYPE (this_parm_var)));
+ if (last_parms)
+ {
+ last_parms->next = this_parms;
+ last_parms = this_parms;
+ }
+ else
+ {
+ first_parms = this_parms;
+ last_parms = this_parms;
+ }
+ this_parms->where_to_put_var_tree = & (( (struct production*)VARIABLE (this_parm))->code);
+ }
+ FIRST_PARMS (prod) = first_parms;
+
+ prod->code = tree_code_create_function_prototype
+ (tok->chars, STORAGE_CLASS (prod), NUMERIC_TYPE (type),
+ first_parms, in_fname, tok->lineno);
+
+}
+;
+
+function:
+NAME LEFT_BRACE {
+ struct production *proto;
+ struct production search_prod;
+ struct token* tok;
+ struct production *this_parm;
+ tok = $1;
+ SYMBOL_TABLE_NAME ((&search_prod)) = tok;
+ current_function = proto = lookup_tree_name (&search_prod);
+ if (!proto)
+ {
+ fprintf (stderr, "%s:%i:%i: Function prototype not found\n", in_fname,
+ tok->lineno, tok->charno);
+ print_token (stderr, 0, tok);
+ errorcount++;
+ YYERROR;
+ }
+ if (!proto->code)
+ abort ();
+ tree_code_create_function_initial
+ (proto->code, in_fname, tok->lineno,
+ FIRST_PARMS (current_function));
+
+ /* Check all the parameters have code. */
+ for (this_parm = PARAMETERS (proto);
+ this_parm;
+ this_parm = this_parm->next)
+ {
+ if (! (struct production*)VARIABLE (this_parm))
+ abort ();
+ if (! (( (struct production*)VARIABLE (this_parm))->code))
+ abort ();
+ }
+}
+variable_defs_opt statements_opt RIGHT_BRACE {
+ struct token* tok;
+ tok = $1;
+ tree_code_create_function_wrapup (in_fname, tok->lineno);
+ current_function = NULL;
+}
+;
+
+variable_defs_opt:
+/* Nil. */ {
+ $$ = 0;
+}
+|variable_defs {
+ $$ = $1;
+}
+;
+
+statements_opt:
+/* Nil. */ {
+ $$ = 0;
+}
+|statements {
+ $$ = $1;
+}
+;
+
+variable_defs:
+variable_def {
+ /* Nothing to do. */
+}
+|variable_defs variable_def {
+ /* Nothing to do. */
+}
+;
+
+typename:
+INT {
+ struct token* tok;
+ struct production *prod;
+ tok = $1;
+ prod = make_production (PROD_TYPE_NAME, tok);
+ NUMERIC_TYPE (prod) = SIGNED_INT;
+ prod->code = tree_code_get_type (NUMERIC_TYPE (prod));
+ $$ = prod;
+}
+|UNSIGNED INT {
+ struct token* tok;
+ struct production *prod;
+ tok = $1;
+ prod = make_production (PROD_TYPE_NAME, tok);
+ NUMERIC_TYPE (prod) = UNSIGNED_INT;
+ prod->code = tree_code_get_type (NUMERIC_TYPE (prod));
+ $$ = prod;
+}
+|CHAR {
+ struct token* tok;
+ struct production *prod;
+ tok = $1;
+ prod = make_production (PROD_TYPE_NAME, tok);
+ NUMERIC_TYPE (prod) = SIGNED_CHAR;
+ prod->code = tree_code_get_type (NUMERIC_TYPE (prod));
+ $$ = prod;
+}
+|UNSIGNED CHAR {
+ struct token* tok;
+ struct production *prod;
+ tok = $1;
+ prod = make_production (PROD_TYPE_NAME, tok);
+ NUMERIC_TYPE (prod) = UNSIGNED_CHAR;
+ prod->code = tree_code_get_type (NUMERIC_TYPE (prod));
+ $$ = prod;
+}
+|VOID {
+ struct token* tok;
+ struct production *prod;
+ tok = $1;
+ prod = make_production (PROD_TYPE_NAME, tok);
+ NUMERIC_TYPE (prod) = VOID_TYPE;
+ prod->code = tree_code_get_type (NUMERIC_TYPE (prod));
+ $$ = prod;
+}
+;
+
+parameters:
+parameter {
+ /* Nothing to do. */
+ $$ = $1;
+}
+|parameters COMMA parameter {
+ struct production *prod1;
+ prod1 = $3;
+ prod1->next = $1; /* Insert in reverse order. */
+ $$ = prod1;
+}
+;
+
+statements:
+statement {
+ /* Nothing to do. */
+}
+|statements statement {
+ /* Nothing to do. */
+}
+;
+
+statement:
+expression SEMICOLON {
+ struct production *exp;
+ exp = $1;
+ tree_code_output_expression_statement (exp->code, in_fname, exp->main_token->lineno);
+}
+|return SEMICOLON {
+ /* Nothing to do. */
+}
+|if_statement {
+ /* Nothing to do. */
+}
+;
+
+if_statement:
+IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS {
+ struct token* tok;
+ struct production *exp;
+ tok = $1;
+ exp = $3;
+ ensure_not_void (NUMERIC_TYPE (exp), exp->main_token);
+ tree_code_if_start (exp->code, in_fname, tok->lineno);
+}
+LEFT_BRACE statements_opt RIGHT_BRACE {
+ /* Just let the statements flow. */
+}
+ELSE {
+ struct token* tok;
+ tok = $1;
+ tree_code_if_else (in_fname, tok->lineno);
+}
+LEFT_BRACE statements_opt RIGHT_BRACE {
+ struct token* tok;
+ tok = $12;
+ tree_code_if_end (in_fname, tok->lineno);
+}
+;
+
+
+return:
+RETURN expression_opt {
+ struct production *type_prod;
+ struct token* ret_tok;
+ ret_tok = $1;
+ type_prod = EXPRESSION_TYPE (current_function);
+ if (NUMERIC_TYPE (type_prod) == VOID)
+ if ($2 == NULL)
+ tree_code_generate_return (type_prod->code, NULL);
+ else
+ {
+ fprintf (stderr, "%s:%i:%i: Redundant expression in return\n", in_fname,
+ ret_tok->lineno, ret_tok->charno);
+ print_token (stderr, 0, ret_tok);
+ errorcount++;
+ tree_code_generate_return (type_prod->code, NULL);
+ }
+ else
+ if ($2 == NULL)
+ {
+ fprintf (stderr, "%s:%i:%i: Expression missing in return\n", in_fname,
+ ret_tok->lineno, ret_tok->charno);
+ print_token (stderr, 0, ret_tok);
+ errorcount++;
+ }
+ else
+ {
+ struct production *exp;
+ exp = $2;
+ /* Check same type. */
+ if (check_type_match (NUMERIC_TYPE (type_prod), $2))
+ {
+ if (!type_prod->code)
+ abort ();
+ if (!exp->code)
+ abort ();
+ /* Generate the code. */
+ tree_code_generate_return (type_prod->code, exp->code);
+ }
+ }
+}
+;
+
+expression_opt:
+/* Nil. */ {
+ $$ = 0;
+}
+|expression {
+ struct production *exp;
+ exp = $1;
+ if (!exp->code)
+ abort ();
+
+ $$ = $1;
+}
+;
+
+expression:
+INTEGER {
+ $$ = make_integer_constant ($1);
+}
+|variable_ref {
+ $$ = $1;
+}
+|expression PLUS expression {
+ struct token* tok;
+ struct production *prod;
+ struct production *op1;
+ struct production *op2;
+ tree type;
+
+ op1 = $1;
+ op2 = $3;
+ tok = $2;
+ ensure_not_void (NUMERIC_TYPE (op1), op1->main_token);
+ ensure_not_void (NUMERIC_TYPE (op2), op2->main_token);
+ prod = make_production (PROD_PLUS_EXPRESSION, tok);
+ NUMERIC_TYPE (prod) = get_common_type (op1, op2);
+ if (!NUMERIC_TYPE (prod))
+ YYERROR;
+ else
+ {
+ type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+ if (!type)
+ abort ();
+ OP1 (prod) = $1;
+ OP2 (prod) = $3;
+
+ prod->code = tree_code_get_expression
+ (EXP_PLUS, type, op1->code, op2->code, NULL);
+ }
+ $$ = prod;
+}
+|expression MINUS expression %prec PLUS {
+ struct token* tok;
+ struct production *prod;
+ struct production *op1;
+ struct production *op2;
+ tree type;
+
+ op1 = $1;
+ op2 = $3;
+ ensure_not_void (NUMERIC_TYPE (op1), op1->main_token);
+ ensure_not_void (NUMERIC_TYPE (op2), op2->main_token);
+ tok = $2;
+ prod = make_production (PROD_PLUS_EXPRESSION, tok);
+ NUMERIC_TYPE (prod) = get_common_type (op1, op2);
+ if (!NUMERIC_TYPE (prod))
+ YYERROR;
+ else
+ {
+ type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+ if (!type)
+ abort ();
+ OP1 (prod) = $1;
+ OP2 (prod) = $3;
+
+ prod->code = tree_code_get_expression (EXP_MINUS,
+ type, op1->code, op2->code, NULL);
+ }
+ $$ = prod;
+}
+|expression EQUALS expression {
+ struct token* tok;
+ struct production *prod;
+ struct production *op1;
+ struct production *op2;
+ tree type;
+
+ op1 = $1;
+ op2 = $3;
+ ensure_not_void (NUMERIC_TYPE (op1), op1->main_token);
+ ensure_not_void (NUMERIC_TYPE (op2), op2->main_token);
+ tok = $2;
+ prod = make_production (PROD_PLUS_EXPRESSION, tok);
+ NUMERIC_TYPE (prod) = SIGNED_INT;
+ if (!NUMERIC_TYPE (prod))
+ YYERROR;
+ else
+ {
+ type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+ if (!type)
+ abort ();
+ OP1 (prod) = $1;
+ OP2 (prod) = $3;
+
+ prod->code = tree_code_get_expression (EXP_EQUALS,
+ type, op1->code, op2->code, NULL);
+ }
+ $$ = prod;
+}
+|variable_ref ASSIGN expression {
+ struct token* tok;
+ struct production *prod;
+ struct production *op1;
+ struct production *op2;
+ tree type;
+
+ op1 = $1;
+ op2 = $3;
+ tok = $2;
+ ensure_not_void (NUMERIC_TYPE (op2), op2->main_token);
+ prod = make_production (PROD_ASSIGN_EXPRESSION, tok);
+ NUMERIC_TYPE (prod) = NUMERIC_TYPE (op1);
+ if (!NUMERIC_TYPE (prod))
+ YYERROR;
+ else
+ {
+ type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+ if (!type)
+ abort ();
+ OP1 (prod) = $1;
+ OP2 (prod) = $3;
+ prod->code = tree_code_get_expression (EXP_ASSIGN,
+ type, op1->code, op2->code, NULL);
+ }
+ $$ = prod;
+}
+|function_invocation {
+ $$ = $1;
+}
+;
+
+function_invocation:
+NAME LEFT_PARENTHESIS expressions_with_commas RIGHT_PARENTHESIS {
+ struct production *prod;
+ struct token* tok;
+ struct production search_prod;
+ struct production *proto;
+ struct production *exp;
+ struct production *exp_proto;
+ struct production *var;
+ int exp_proto_count;
+ int exp_count;
+ tree parms;
+ tree type;
+
+ tok = $1;
+ prod = make_production (PROD_FUNCTION_INVOCATION, tok);
+ SYMBOL_TABLE_NAME (prod) = tok;
+ PARAMETERS (prod) = reverse_prod_list ($3);
+ SYMBOL_TABLE_NAME ((&search_prod)) = tok;
+ proto = lookup_tree_name (&search_prod);
+ if (!proto)
+ {
+ fprintf (stderr, "%s:%i:%i: Function prototype not found\n", in_fname,
+ tok->lineno, tok->charno);
+ print_token (stderr, 0, tok);
+ errorcount++;
+ YYERROR;
+ }
+ EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
+ NUMERIC_TYPE (prod) = NUMERIC_TYPE (proto);
+ /* Count the expressions and ensure they match the prototype. */
+ for (exp_proto_count = 0, exp_proto = PARAMETERS (proto);
+ exp_proto; exp_proto = exp_proto->next)
+ exp_proto_count++;
+
+ for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->next)
+ exp_count++;
+
+ if (exp_count != exp_proto_count)
+ {
+ fprintf (stderr, "%s:%i:%i: expression count mismatch with prototype\n", in_fname,
+ tok->lineno, tok->charno);
+ print_token (stderr, 0, tok);
+ errorcount++;
+ YYERROR;
+ }
+ parms = tree_code_init_parameters ();
+ for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
+ exp_proto;
+ exp = exp->next, exp_proto = exp_proto->next)
+ {
+ if (!exp)
+ abort ();
+ if (!exp_proto)
+ abort ();
+ if (!exp->code)
+ abort ();
+ var = VARIABLE (exp_proto);
+ if (!var)
+ abort ();
+ if (!var->code)
+ abort ();
+ parms = tree_code_add_parameter (parms, var->code, exp->code);
+ }
+ type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
+ prod->code = tree_code_get_expression
+ (EXP_FUNCTION_INVOCATION, type, proto->code, parms, NULL);
+ $$ = prod;
+}
+;
+
+expressions_with_commas:
+expression {
+ struct production *exp;
+ exp = $1;
+ ensure_not_void (NUMERIC_TYPE (exp), exp->main_token);
+ $$ = $1;
+}
+|expressions_with_commas COMMA expression {
+ struct production *exp;
+ exp = $3;
+ ensure_not_void (NUMERIC_TYPE (exp), exp->main_token);
+ exp->next = $1; /* Reverse order. */
+ $$ = exp;
+}
+;
+
+variable_ref:
+NAME {
+ struct production search_prod;
+ struct production *prod;
+ struct production *symbol_table_entry;
+ struct token* tok;
+ tree type;
+
+ tok = $1;
+ SYMBOL_TABLE_NAME ((&search_prod)) = tok;
+ symbol_table_entry = lookup_tree_name (&search_prod);
+ if (!symbol_table_entry)
+ {
+ fprintf (stderr, "%s:%i:%i: Variable referred to but not defined\n", in_fname,
+ tok->lineno, tok->charno);
+ print_token (stderr, 0, tok);
+ errorcount++;
+ YYERROR;
+ }
+
+ 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));
+ if (!NUMERIC_TYPE (prod))
+ YYERROR;
+ OP1 (prod) = $1;
+
+ prod->code = tree_code_get_expression (EXP_REFERENCE, type,
+ symbol_table_entry->code, NULL, NULL);
+ $$ = prod;
+}
+;
+
+init_opt:
+/* Nil. */ {
+ $$ = 0;
+}
+|init {
+ /* Nothing to do. */
+}
+
+init:
+ASSIGN init_element {
+}
+;
+
+init_element:
+INTEGER {
+ $$ = make_integer_constant ($1);
+}
+;
+
+%%
+
+/* Print a token VALUE to file FILE. Ignore TYPE which is the token
+ type. */
+
+void
+print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value)
+{
+ struct token *tok;
+ unsigned int ix;
+
+ tok = value;
+ fprintf (file, "%d \"", tok->lineno);
+ for (ix = 0; ix < tok->length; ix++)
+ fprintf (file, "%c", tok->chars[ix]);
+ fprintf (file, "\"");
+}
+
+/* Output a message ERROR_MESSAGE from the parser. */
+void
+yyerror (const char *error_message)
+{
+ struct token *tok;
+
+ tok = yylval;
+ if (tok)
+ {
+ fprintf (stderr, "%s:%i:%i: %s\n", in_fname, tok->lineno, tok->charno, error_message);
+ print_token (stderr, 0, tok);
+ }
+ else
+ fprintf (stderr, "%s\n", error_message);
+
+ errorcount++;
+
+}
+
+/* Reverse the order of a token list, linked by parse_next, old first
+ token is OLD_FIRST. */
+
+static struct production*
+reverse_prod_list (struct production *old_first)
+{
+ struct production *current;
+ struct production *next;
+ struct production *prev = NULL;
+
+ current = old_first;
+ prev = NULL;
+
+ while (current)
+ {
+ if (current->category != production_category)
+ abort ();
+ next = current->next;
+ current->next = prev;
+ prev = current;
+ current = next;
+ }
+ return prev;
+}
+
+/* Ensure TYPE is not VOID. Use NAME as the token for the error location. */
+
+static void
+ensure_not_void (unsigned int type, struct token* name)
+{
+ if (type == VOID)
+ {
+ fprintf (stderr, "%s:%i:%i: Type must not be void in this context\n", in_fname,
+ name->lineno, name->charno);
+ print_token (stderr, 0, name);
+ errorcount++;
+ }
+}
+
+/* Check TYPE1 and TYPE2 which are integral types. Return the lowest
+ common type (min is signed int). */
+
+static int
+get_common_type (struct production *type1, struct production *type2)
+{
+ if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
+ return UNSIGNED_INT;
+ if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
+ return UNSIGNED_INT;
+
+ return SIGNED_INT;
+}
+
+/* Check type (TYPE_NUM) and expression (EXP) match. Return the 1 if
+ OK else 0. Must be exact match - same name unless it is an
+ integral type. */
+
+static int
+check_type_match (int type_num, struct production *exp)
+{
+ switch (type_num)
+ {
+ case SIGNED_INT:
+ case UNSIGNED_INT:
+ case SIGNED_CHAR:
+ case UNSIGNED_CHAR:
+ switch (NUMERIC_TYPE (exp))
+ {
+ case SIGNED_INT:
+ case UNSIGNED_INT:
+ case SIGNED_CHAR:
+ case UNSIGNED_CHAR:
+ return 1;
+
+ case VOID:
+ abort ();
+
+ default:
+ abort ();
+ }
+ break;
+
+ case VOID:
+ abort ();
+
+ default:
+ abort ();
+
+ }
+}
+
+/* Make a production for an integer constant VALUE. */
+
+static struct production *
+make_integer_constant (struct token* value)
+{
+ struct token* tok;
+ struct production *prod;
+ tok = value;
+ prod = make_production (PROD_INTEGER_CONSTANT, tok);
+ if ((tok->chars[0] == (unsigned char)'-')|| (tok->chars[0] == (unsigned char)'+'))
+ NUMERIC_TYPE (prod) = SIGNED_INT;
+ else
+ NUMERIC_TYPE (prod) = UNSIGNED_INT;
+ prod->code = tree_code_get_integer_value (tok->chars, tok->length);
+ return prod;
+}
+
+/* Set STORAGE_CLASS in PROD according to CLASS_TOKEN. */
+
+static void
+set_storage (struct production *prod)
+{
+ struct token* stg_class;
+ stg_class = STORAGE_CLASS_TOKEN (prod);
+ switch (stg_class->type)
+ {
+ case STATIC:
+ STORAGE_CLASS (prod) = STATIC_STORAGE;
+ break;
+
+ case AUTOMATIC:
+ STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
+ break;
+
+ case EXTERNAL_DEFINITION:
+ STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
+ break;
+
+ case EXTERNAL_REFERENCE:
+ STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+/* Set parse trace. */
+
+void
+treelang_debug (void)
+{
+ if (option_parser_trace)
+ yydebug = 1;
+}
diff --git a/gcc/treelang/tree1.c b/gcc/treelang/tree1.c
new file mode 100644
index 0000000..5067bea
--- /dev/null
+++ b/gcc/treelang/tree1.c
@@ -0,0 +1,382 @@
+ /*
+
+ TREELANG Compiler almost main (tree1)
+ Called by GCC's toplev.c
+
+ Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002 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
+ 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!
+
+ ---------------------------------------------------------------------------
+
+ Written by Tim Josling 1999, 2000, 2001, based in part on other
+ parts of the GCC compiler.
+
+*/
+
+#include "config.h"
+#include "system.h"
+#include "ansidecl.h"
+#include "flags.h"
+#include "output.h"
+#include "toplev.h"
+
+#include "ggc.h"
+#include "tree.h"
+#include "diagnostic.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "treelang.h"
+#include "treetree.h"
+
+extern int yyparse (void);
+/* Linked list of symbols - all must be unique in treelang. */
+
+struct production *symbol_table = NULL;
+
+/* Language for usage for messages. */
+
+const char *const language_string = "TREELANG - sample front end for GCC ";
+
+/* Local prototypes. */
+
+void version (void);
+
+/* GC routine for symbol table. */
+static void symbol_table_ggc (void *m);
+
+/* Global variables. */
+
+extern struct cbl_tree_struct_parse_tree_top* parse_tree_top;
+
+/*
+ Options.
+*/
+
+/* Trace the parser. */
+unsigned int option_parser_trace = 0;
+
+/* Trace the lexical analysis. */
+
+unsigned int option_lexer_trace = 0;
+
+/* Warning levels. */
+
+/* Local variables. */
+
+unsigned char *in_fname = NULL; /* Input file name. */
+
+/* This is 1 if we have output the version string. */
+
+static int version_done = 0;
+
+/* Variable nesting level. */
+
+static unsigned int work_nesting_level = 0;
+
+/* Process one switch - called by toplev.c. */
+
+int
+treelang_decode_option (num_options_left, first_option_left)
+ int num_options_left ATTRIBUTE_UNUSED;
+ char** first_option_left;
+{
+
+ /*
+ Process options - bear in mind I may get options that are really
+ meant for someone else (eg the main compiler) so I have to be very
+ permissive.
+
+ */
+
+ if (first_option_left[0][0] != '-')
+ return 0;
+
+ switch (first_option_left[0][1])
+ {
+ case '-':
+ if (!strcmp (first_option_left[0],"--help"))
+ {
+ if (!version_done)
+ {
+ fputs (language_string, stdout);
+ fputs (version_string, stdout);
+ fputs ("\n", stdout);
+ version_done = 1;
+ }
+ fprintf (stdout, "Usage: tree1 [switches] -o output input\n");
+ return 1;
+ }
+ case 'v':
+ if (!strcmp (first_option_left[0],"-v"))
+ {
+ if (!version_done)
+ {
+ fputs (language_string, stdout);
+ fputs (version_string, stdout);
+ fputs ("\n", stdout);
+ version_done = 1;
+ }
+ return 1;
+ }
+ case 'y':
+ if (!strcmp (first_option_left[0],"-y"))
+ {
+ option_lexer_trace = 1;
+ option_parser_trace = 1;
+ return 1;
+ }
+ case 'f':
+ if (!strcmp (first_option_left[0],"-fparser-trace"))
+ {
+ option_parser_trace = 1;
+ return 1;
+ }
+ if (!strcmp (first_option_left[0],"-flexer-trace"))
+ {
+ option_lexer_trace = 1;
+ return 1;
+ }
+ return 0;
+
+ case 'w':
+ if (!strcmp (first_option_left[0],"-w"))
+ {
+ /* Tolerate this option but ignore it - we always put out
+ all warnings. */
+ return 1;
+ }
+ return 0;
+
+ case 'W':
+ if (!strcmp (first_option_left[0],"-Wall"))
+ {
+ return 1;
+ }
+ return 0;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+
+}
+
+/* Language dependent parser setup. */
+
+const char*
+treelang_init (const char* filename)
+{
+
+ /* Define my garbage collection routines. */
+ ggc_add_root (&symbol_table, 1,
+ /* Unused size. */ sizeof (void*), symbol_table_ggc);
+ /* Note: only storage that has to be kept across functions needs to
+ be protected from GC. */
+ /* Define my garbage collection routines. */
+ ggc_add_root (&symbol_table, 1,
+ /* Unused size. */ sizeof (void*), symbol_table_ggc);
+ /* Note: only storage that has to be kept across functions needs to
+ be protected from GC. */
+
+ /* Set up the declarations needed for this front end. */
+
+ input_filename = "";
+ lineno = 0;
+
+ treelang_init_decl_processing ();
+
+ /* This error will not happen from GCC as it will always create a
+ fake input file. */
+ if (!filename || (filename[0] == ' ') || (!filename[0]))
+ {
+ if (!version_done)
+ {
+ fprintf (stderr, "No input file specified, try --help for help\n");
+ exit (1);
+ }
+
+ in_fname = NULL;
+ return NULL;
+ }
+ yyin = fopen (filename, "r");
+ if (!yyin)
+ {
+ fprintf (stderr, "Unable to open input file %s\n", filename);
+ exit (1);
+ }
+ input_filename = filename;
+ return (char*) (in_fname = (unsigned char*)filename);
+}
+
+/* Language dependent wrapup. */
+
+void
+treelang_finish (void)
+{
+ fclose (yyin);
+}
+
+/* Parse a file. Debug flag doesn't seem to work. */
+
+void
+treelang_parse_file (int debug_flag ATTRIBUTE_UNUSED)
+{
+ treelang_debug ();
+ yyparse ();
+}
+
+
+/* Scan the symbol table* M, marking storage used. */
+
+static void
+symbol_table_ggc (void *m)
+{
+ struct production *pp;
+ pp = * (struct production**)m;
+ /* Actually it is a pointer to a pointer, to allow reallocation and
+ relinking. */
+ mark_production_used (pp);
+}
+
+/* Mark a production PP as used so it wont be garbage collected. */
+
+void
+mark_production_used (struct production *pp)
+{
+ int sub_ix;
+ loop:
+ if (!pp)
+ return;
+ ggc_mark (pp);
+
+ if (pp->category == token_category)
+ {
+ mark_token_used ((struct token*)pp);
+ return;
+ }
+ if (pp->category != production_category)
+ abort ();
+ mark_token_used (pp->main_token);
+ for (sub_ix = 0; sub_ix < SUB_COUNT; sub_ix++)
+ mark_production_used (pp->sub[sub_ix]);
+ /* The macro tests for NULL so I don't need to. */
+ ggc_mark_tree (pp->code);
+ pp = pp->next;
+ goto loop;
+}
+
+/* Mark a token TT as used so it wont be garbage collected. */
+
+void
+mark_token_used (struct token* tt)
+{
+ if (!tt)
+ return;
+ ggc_mark (tt);
+ if (tt->chars)
+ ggc_mark (tt->chars);
+}
+
+/* Allocate SIZE bytes and clear them. */
+
+void *
+my_malloc (size_t size)
+{
+ void *mem;
+ mem = ggc_alloc (size);
+ if (!mem)
+ {
+ fprintf (stderr, "\nOut of memory\n");
+ abort ();
+ }
+ memset (mem, 0, size);
+ return mem;
+}
+
+/* Look up a name in PROD->SYMBOL_TABLE_NAME in the symbol table;
+ return the symbol table entry from the symbol table if found there,
+ else 0. */
+
+struct production*
+lookup_tree_name (struct production *prod)
+{
+ struct production *this;
+ struct token* this_tok;
+ struct token* tok;
+ tok = SYMBOL_TABLE_NAME (prod);
+ for (this = symbol_table; this; this = this->next)
+ {
+ this_tok = this->main_token;
+ if (tok->length != this_tok->length)
+ continue;
+ if (memcmp (tok->chars, this_tok->chars, this_tok->length))
+ continue;
+ if (option_parser_trace)
+ fprintf (stderr, "Found symbol %s (%i:%i) as %i \n", tok->chars,
+ tok->lineno, tok->charno, NUMERIC_TYPE (this));
+ return this;
+ }
+ if (option_parser_trace)
+ fprintf (stderr, "Not found symbol %s (%i:%i) as %i \n", tok->chars,
+ tok->lineno, tok->charno, tok->type);
+ return NULL;
+}
+
+/* Insert name PROD into the symbol table. Return 1 if duplicate, 0 if OK. */
+
+int
+insert_tree_name (struct production *prod)
+{
+ struct token* tok;
+ tok = SYMBOL_TABLE_NAME (prod);
+ if (lookup_tree_name (prod))
+ {
+ fprintf (stderr, "%s:%i:%i duplicate name %s\n", in_fname, tok->lineno, tok->charno, tok->chars);
+ errorcount++;
+ return 1;
+ }
+ prod->next = symbol_table;
+ NESTING_LEVEL (prod) = work_nesting_level;
+ symbol_table = prod;
+ return 0;
+}
+
+/* Create a struct productions of type TYPE, main token MAIN_TOK. */
+
+struct production *
+make_production (int type, struct token* main_tok)
+{
+ struct production *prod;
+ prod = my_malloc (sizeof (struct production));
+ prod->category = production_category;
+ prod->type = type;
+ prod->main_token = main_tok;
+ return prod;
+}
+
+
diff --git a/gcc/treelang/treelang.h b/gcc/treelang/treelang.h
new file mode 100644
index 0000000..a265738
--- /dev/null
+++ b/gcc/treelang/treelang.h
@@ -0,0 +1,116 @@
+/*
+
+ TREELANG Compiler common definitions (treelang.h)
+
+ Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002 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
+ 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!
+
+ ---------------------------------------------------------------------------
+
+ Written by Tim Josling 1999, 2000, 2001, based in part on other
+ parts of the GCC compiler.
+
+*/
+
+/* Parse structure type. */
+enum category_enum
+{ /* These values less likely to be there by chance unlike 0/1,
+ make checks more meaningful */
+ token_category = 111,
+ production_category = 222
+};
+
+/* Input file name and FILE. */
+extern unsigned char* in_fname;
+extern FILE* yyin;
+
+#if 0
+extern int errorcount; /* In toplev.c. */
+#endif
+
+struct token
+{
+ enum category_enum category; /* Token or production. */
+ unsigned int type; /* Token type. */
+ /* Prior to this point, production must match token. */
+ unsigned int lineno;
+ unsigned int charno;
+ unsigned int length; /* The value. */
+ unsigned char* chars;
+};
+
+struct production
+{
+ enum category_enum category; /* Token or Production. */
+ unsigned int type; /* Production type - a fake token name. */
+ /* Prior to this point, production must match token. */
+ struct token* main_token; /* Main token for error msgs; variable name token. */
+
+ unsigned int info[2]; /* Extra information. */
+#define NESTING_LEVEL(a) a->info[0] /* Level used for variable definitions. */
+#define NUMERIC_TYPE(a) a->info[1] /* Numeric type used in type definitions and expressions. */
+
+
+#define SUB_COUNT 5
+ void *sub[SUB_COUNT]; /* Sub productions or tokens. */
+
+#define SYMBOL_TABLE_NAME(a) (a->sub[0]) /* Name token. */
+
+#define EXPRESSION_TYPE(a) (a->sub[1]) /* Type identifier. */
+
+#define OP1(a) (a->sub[2]) /* Exp operand1. */
+#define PARAMETERS(a) (a->sub[2]) /* Function parameters. */
+#define VARIABLE(a) (a->sub[2]) /* Parameter variable ptr. */
+#define VAR_INIT(a) (a->sub[2]) /* Variable init. */
+
+#define OP2(a) (a->sub[3]) /* Exp operand2. */
+#define FIRST_PARMS(a) (a->sub[3]) /* Function parameters linked via struct tree_parameter_list. */
+
+#define OP3(a) (a->sub[4]) /* Exp operand3. */
+#define STORAGE_CLASS_TOKEN(a) (a->sub[4]) /* Storage class token. */
+
+ void *code; /* Back end hook for this item. */
+ struct production *next; /* Next in chains of various types. */
+
+ unsigned int flag1:2;
+#define STORAGE_CLASS(a) a->flag1 /* Values in treetree.h. */
+
+ unsigned int flag2:1;
+ unsigned int flag3:1;
+ unsigned int flag4:1;
+ unsigned int flag5:1;
+ unsigned int flag6:1;
+ unsigned int flag7:1;
+
+};
+
+/* For parser. Alternatively you can define it using %union (bison) or
+ union. */
+#define YYSTYPE void *
+
+void *my_malloc (size_t size);
+int insert_tree_name (struct production *prod);
+struct production *lookup_tree_name (struct production *prod);
+struct production *make_production (int type, struct token* main_tok);
+void mark_production_used (struct production * pp);
+void mark_token_used (struct token* tt);
+void treelang_debug (void);
+
diff --git a/gcc/treelang/treelang.texi b/gcc/treelang/treelang.texi
new file mode 100644
index 0000000..499f160
--- /dev/null
+++ b/gcc/treelang/treelang.texi
@@ -0,0 +1,1311 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename treelang.info
+
+@set last-update 2001-07-30
+@set copyrights-treelang 1995,1996,1997,1998,1999,2000,2001,2002
+@c DEVELOPMENT is set to indicate an in-development version,
+@c as compared to a release version. When making a release
+@c (e.g. a release branch in the CVS repository for GCC),
+@c clear this and set the version information correctly.
+@clear DEVELOPMENT
+@set version-treelang 1.0
+@set version-GCC 3.0
+
+@set email-general gcc@@gcc.gnu.org
+@set email-bugs gcc-bugs@@gcc.gnu.org or bug-gcc@@gnu.org
+@set email-patches gcc-patches@@gcc.gnu.org
+@set path-treelang gcc/gcc/treelang
+
+@set which-treelang GCC-@value{version-GCC}
+@set which-GCC GCC
+
+@set email-josling tej@@melbpc.org.au
+@set www-josling http://www.geocities.com/timjosling
+
+@c This tells @include'd files that they're part of the overall TREELANG doc
+@c set. (They might be part of a higher-level doc set too.)
+@set DOC-TREELANG
+
+@c @setfilename usetreelang.info
+@c @setfilename maintaintreelang.info
+@c To produce the full manual, use the "treelang.info" setfilename, and
+@c make sure the following do NOT begin with '@c' (and the @clear lines DO)
+@set INTERNALS
+@set USING
+@c To produce a user-only manual, use the "usetreelang.info" setfilename, and
+@c make sure the following does NOT begin with '@c':
+@c @clear INTERNALS
+@c To produce a maintainer-only manual, use the "maintaintreelang.info" setfilename,
+@c and make sure the following does NOT begin with '@c':
+@c @clear USING
+
+@c 6/27/96 FSF DO wants smallbook fmt for 1st bound edition. (from gcc.texi)
+@c @smallbook
+
+@c i also commented out the finalout command, so if there *are* any
+@c overfulls, you'll (hopefully) see the rectangle in the right hand
+@c margin. -- burley 1999-03-13 (from mew's comment in GCC.texi).
+@c @finalout
+
+@ifset INTERNALS
+@ifset USING
+@settitle Using and Maintaining GNU Treelang
+@end ifset
+@end ifset
+@c seems reasonable to assume at least one of INTERNALS or USING is set...
+@ifclear INTERNALS
+@settitle Using GNU Treelang
+@end ifclear
+@ifclear USING
+@settitle Maintaining GNU Treelang
+@end ifclear
+@c then again, have some fun
+@ifclear INTERNALS
+@ifclear USING
+@settitle Doing Very Little at all with GNU Treelang
+@end ifclear
+@end ifclear
+
+@syncodeindex fn cp
+@syncodeindex vr cp
+@c %**end of header
+
+@c Cause even numbered pages to be printed on the left hand side of
+@c the page and odd numbered pages to be printed on the right hand
+@c side of the page. Using this, you can print on both sides of a
+@c sheet of paper and have the text on the same part of the sheet.
+
+@c The text on right hand pages is pushed towards the right hand
+@c margin and the text on left hand pages is pushed toward the left
+@c hand margin.
+@c (To provide the reverse effect, set bindingoffset to -0.75in.)
+
+@c @tex
+@c \global\bindingoffset=0.75in
+@c \global\normaloffset =0.75in
+@c @end tex
+
+@ifinfo
+@dircategory Programming
+@direntry
+* treelang: (treelang). The GNU Treelang compiler.
+@end direntry
+@ifset INTERNALS
+@ifset USING
+This file documents the use and the internals of the GNU Treelang
+(@code{treelang}) compiler. At the moment this manual is not
+incorporated into the main GCC manual as it is too incomplete. It
+corresponds to the @value{which-treelang} version of @code{treelang}.
+@end ifset
+@end ifset
+@ifclear USING
+This file documents the internals of the GNU Treelang (@code{treelang}) compiler.
+It corresponds to the @value{which-treelang} version of @code{treelang}.
+@end ifclear
+@ifclear INTERNALS
+This file documents the use of the GNU Treelang (@code{treelang}) compiler.
+It corresponds to the @value{which-treelang} version of @code{treelang}.
+@end ifclear
+
+Published by the Free Software Foundation
+59 Temple Place - Suite 330
+Boston, MA 02111-1307 USA
+
+Copyright (C) @value{copyrights-treelang} Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'', the Front-Cover
+texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below). A copy of the license is included in the section entitled
+``GNU Free Documentation License''.
+
+(a) The FSF's Front-Cover Text is:
+
+ A GNU Manual
+
+(b) The FSF's Back-Cover Text is:
+
+ You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development.
+@end ifinfo
+
+treelang was Contributed by Tim Josling (@email{@value{email-josling}}).
+Inspired by and based on the 'toy' language, written by Richard Kenner.
+
+This document was written by Tim Josling, based on the GNU C++
+documentation.
+
+@setchapternewpage odd
+@c @finalout
+@titlepage
+@ifset INTERNALS
+@ifset USING
+@center @titlefont{Using and Maintaining GNU Treelang}
+
+@end ifset
+@end ifset
+@ifclear INTERNALS
+@title Using GNU Treelang
+@end ifclear
+@ifclear USING
+@title Maintaining GNU Treelang
+@end ifclear
+@sp 2
+@center Tim Josling
+@sp 3
+@center Last updated @value{last-update}
+@sp 1
+@center for version @value{version-treelang}
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} @value{copyrights-treelang} Free Software Foundation, Inc.
+@sp 2
+For the @value{which-treelang} Version*
+@sp 1
+Published by the Free Software Foundation @*
+59 Temple Place - Suite 330@*
+Boston, MA 02111-1307, USA@*
+@c Last printed ??ber, 19??.@*
+@c Printed copies are available for $? each.@*
+@c ISBN ???
+@sp 1
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'', the Front-Cover
+texts being (a) (see below), and with the Back-Cover Texts being (b)
+(see below). A copy of the license is included in the section entitled
+``GNU Free Documentation License''.
+
+(a) The FSF's Front-Cover Text is:
+
+ A GNU Manual
+
+(b) The FSF's Back-Cover Text is:
+
+ You have freedom to copy and modify this GNU Manual, like GNU
+ software. Copies published by the Free Software Foundation raise
+ funds for GNU development.
+@end titlepage
+@page
+
+@ifinfo
+
+@node Top, Copying,, (dir)
+@top Introduction
+@cindex Introduction
+
+@ifset INTERNALS
+@ifset USING
+This manual documents how to run, install and maintain @code{treelang},
+as well as its new features and incompatibilities,
+and how to report bugs.
+It corresponds to the @value{which-treelang} version of @code{treelang}.
+@end ifset
+@end ifset
+
+@ifclear INTERNALS
+This manual documents how to run and install @code{treelang},
+as well as its new features and incompatibilities, and how to report
+bugs.
+It corresponds to the @value{which-treelang} version of @code{treelang}.
+@end ifclear
+@ifclear USING
+This manual documents how to maintain @code{treelang}, as well as its
+new features and incompatibilities, and how to report bugs. It
+corresponds to the @value{which-treelang} version of @code{treelang}.
+@end ifclear
+
+@end ifinfo
+
+@ifset DEVELOPMENT
+@emph{Warning:} This document is still under development, and might not
+accurately reflect the @code{treelang} code base of which it is a part.
+@end ifset
+
+@menu
+* Copying::
+* Contributors::
+* GNU Free Documentation License::
+* Funding::
+* Getting Started::
+* What is GNU Treelang?::
+* Lexical Syntax::
+* Parsing Syntax::
+* Compiler Overview::
+* TREELANG and GCC::
+* Compiler::
+* Other Languages::
+* treelang internals::
+* Open Questions::
+* Bugs::
+* Service::
+* Projects::
+* Index::
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Other Languages
+
+* Interoperating with C and C++::
+
+treelang internals
+
+* treelang files::
+* treelang compiler interfaces::
+* Hints and tips::
+
+treelang compiler interfaces
+
+* treelang driver::
+* treelang main compiler::
+
+treelang main compiler
+
+* Interfacing to toplev.c::
+* Interfacing to the garbage collection::
+* Interfacing to the code generation code. ::
+
+Reporting Bugs
+
+* Sending Patches::
+
+@end detailmenu
+@end menu
+
+@include gpl.texi
+
+@include fdl.texi
+
+@node Contributors
+
+@unnumbered Contributors to GNU Treelang
+@cindex contributors
+@cindex credits
+
+Treelang was based on 'toy' by Richard Kenner, and also uses code from
+the GCC core code tree. Tim Josling first created the language and
+documentation, based on the GCC Fortran compiler's documentation
+framework.
+
+@itemize @bullet
+@item
+The packaging and compiler portions of GNU Treelang are based largely
+on the GCC compiler.
+@xref{Contributors,,Contributors to GCC,GCC,Using and Maintaining GCC},
+for more information.
+
+@item
+There is no specific run-time library for treelang, other than the
+standard C runtime.
+
+@item
+It would have been difficult to build treelang without access to Joachim
+Nadler's guide to writing a front end to GCC (written in German). A
+translation of this document into English is available via the
+CobolForGCC project or via the documentation links from the GCC home
+page @uref{http://GCC.gnu.org}.
+@end itemize
+
+@include funding.texi
+
+@node Getting Started
+@chapter Getting Started
+@cindex getting started
+@cindex new users
+@cindex newbies
+@cindex beginners
+
+Treelang is a sample language, useful only to help people understand how
+to implement a new language front end to GCC. It is not a useful
+language in itself other than as an example or basis for building a new
+language. Therefore only language developers are likely to have an
+interest in it.
+
+This manual assumes familiarity with GCC, which you can obtain by using
+it and by reading the manual @samp{Using and Porting GCC}.
+
+To install treelang, follow the GCC installation instructions,
+taking care to ensure you specify treelang in the configure step.
+
+If you're generally curious about the future of
+@code{treelang}, see @ref{Projects}.
+If you're curious about its past,
+see @ref{Contributors}.
+
+To see a few of the questions maintainers of @code{treelang} have,
+and that you might be able to answer,
+see @ref{Open Questions}.
+
+@ifset USING
+@node What is GNU Treelang?, Lexical Syntax, Getting Started, Top
+@chapter What is GNU Treelang?
+@cindex concepts, basic
+@cindex basic concepts
+
+GNU Treelang, or @code{treelang}, is designed initially as a free
+replacement for, or alternative to, the 'toy' language, but which is
+amenable to inclusion within the GCC source tree.
+
+@code{treelang} is largely a cut down version of C, designed to showcase
+the features of the GCC code generation back end. Only those features
+that are directly supported by the GCC code generation back end are
+implemented. Features are implemented in a manner which is easiest and
+clearest to implement. Not all or even most code generation back end
+features are implemented. The intention is to add features incrementally
+until most features of the GCC back end are implemented in treelang.
+
+The main features missing are structures, arrays and pointers.
+
+A sample program follows:
+
+@example
+// function prototypes
+// function 'add' taking two ints and returning an int
+external_definition int add(int arg1, int arg2);
+external_definition int subtract(int arg3, int arg4);
+external_definition int first_nonzero(int arg5, int arg6);
+external_definition int double_plus_one(int arg7);
+
+// function definition
+add
+@{
+// return the sum of arg1 and arg2
+ return arg1 + arg2;
+@}
+
+
+subtract
+@{
+ return arg3 - arg4;
+@}
+
+double_plus_one
+@{
+// aaa is a variable, of type integer and allocated at the start of the function
+ automatic int aaa;
+// set aaa to the value returned from aaa, when passed arg7 and arg7 as the two parameters
+ aaa=add(arg7, arg7);
+ aaa=add(aaa, aaa);
+ aaa=subtract(subtract(aaa, arg7), arg7) + 1;
+ return aaa;
+@}
+
+first_nonzero
+@{
+// C-like if statement
+ if (arg5)
+ @{
+ return arg5;
+ @}
+ else
+ @{
+ @}
+ return arg6;
+@}
+@end example
+
+@node Lexical Syntax, Parsing Syntax, What is GNU Treelang?, Top
+@chapter Lexical Syntax
+@cindex Lexical Syntax
+
+Treelang programs consist of whitespace, comments, keywords and names.
+@itemize @bullet
+
+@item
+Whitespace consists of the space character and the end of line
+character. Tabs are not allowed. Line terminations are as defined by the
+standard C library. Whitespace is ignored except within comments,
+and where it separates parts of the program. In the example below, A and
+B are two separate names separated by whitespace.
+
+@smallexample
+A B
+@end smallexample
+
+@item
+Comments consist of @samp{//} followed by any characters up to the end
+of the line. C style comments (/* */) are not supported. For example,
+the assignment below is followed by a not very helpful comment.
+
+@smallexample
+x=1; // Set X to 1
+@end smallexample
+
+@item
+Keywords consist of any reserved words or symbols as described
+later. The list of keywords follows:
+
+@smallexample
+@{ - used to start the statements in a function
+@} - used to end the statements in a function
+( - start list of function arguments, or to change the precedence of operators in an expression
+) - end list or prioritised operators in expression
+, - used to separate parameters in a function prototype or in a function call
+; - used to end a statement
++ - addition
+- - subtraction
+= - assignment
+== - equality test
+if - begin IF statement
+else - begin 'else' portion of IF statement
+static - indicate variable is permanent, or function has file scope only
+automatic - indicate that variable is allocated for the life of the function
+external_reference - indicate that variable or function is defined in another file
+external_definition - indicate that variable or function is to be accessible from other files
+int - variable is an integer (same as C int)
+char - variable is a character (same as C char)
+unsigned - variable is unsigned. If this is not present, the variable is signed
+return - start function return statement
+void - used as function type to indicate function returns nothing
+@end smallexample
+
+
+@item
+Names consist of any letter or "_" followed by any number of letters or
+numbers or "_". "$" is not allowed in a name. All names must be globally
+unique - the same name may not be used twice in any context - and must
+not be a keyword. Names and keywords are case sensitive. For example:
+
+@smallexample
+a A _a a_ IF_X
+@end smallexample
+
+are all different names.
+
+@end itemize
+
+@node Parsing Syntax, Compiler Overview, Lexical Syntax, Top
+@chapter Parsing Syntax
+@cindex Parsing Syntax
+
+Declarations are built up from the lexical elements described above. A
+file may contain one of more declarations.
+
+@itemize @bullet
+
+@item
+declaration: variable declaration OR function prototype OR function declaration
+
+@item
+Function Prototype: storage type NAME ( parameter_list )
+
+@smallexample
+static int add (int a, int b)
+@end smallexample
+
+@item
+variable_declaration: storage type NAME initial;
+
+Example:
+
+@smallexample
+int temp1=1;
+@end smallexample
+
+A variable declaration can be outside a function, or at the start of a function.
+
+@item
+storage: automatic OR static OR external_reference OR external_definition
+
+This defines the scope, duration and visibility of a function or variable
+
+@enumerate 1
+
+@item
+automatic: This means a variable is allocated at start of function and
+released when the function returns. This can only be used for variables
+within functions. It cannot be used for functions.
+
+@item
+static: This means a variable is allocated at start of program and
+remains allocated until the program as a whole ends. For a function, it
+means that the function is only visible within the current file.
+
+@item
+external_definition: For a variable, which must be defined outside a
+function, it means that the variable is visible from other files. For a
+function, it means that the function is visible from another file.
+
+@item
+external_reference: For a variable, which must be defined outside a
+function, it means that the variable is defined in another file. For a
+function, it means that the function is defined in another file.
+
+@end enumerate
+
+@item
+type: int OR unsigned int OR char OR unsigned char OR void
+
+This defines the data type of a variable or the return type of a function.
+
+@enumerate a
+
+@item
+int: The variable is a signed integer. The function returns a signed integer.
+
+@item
+unsigned int: The variable is an unsigned integer. The function returns an unsigned integer.
+
+@item
+char: The variable is a signed character. The function returns a signed character.
+
+@item
+unsigned char: The variable is an unsigned character. The function returns an unsigned character.
+
+@end enumerate
+
+@item
+parameter_list OR parameter [, parameter]...
+
+@item
+parameter: variable_declaration ,
+
+The variable declarations must not have initialisations.
+
+@item
+initial: = value
+
+@item
+value: integer_constant
+
+@smallexample
+eg 1 +2 -3
+@end smallexample
+
+@item
+function_declaration: name @{variable_declarations statements @}
+
+A function consists of the function name then the declarations (if any)
+and statements (if any) within one pair of braces.
+
+The details of the function arguments come from the function
+prototype. The function prototype must precede the function declaration
+in the file.
+
+@item
+statement: if_statement OR expression_statement OR return_statement
+
+@item
+if_statement: if (expression) @{ statements @} else @{ statements @}
+
+The first lot of statements is executed if the expression is
+non-zero. Otherwise the second lot of statements is executed. Either
+list of statements may be empty, but both sets of braces and the else must be present.
+
+@smallexample
+if (a==b)
+@{
+// nothing
+@}
+else
+@{
+a=b;
+@}
+@end smallexample
+
+@item
+expression_statement: expression;
+
+The expression is executed and any side effects, such
+
+@item
+return_statement: return expression_opt;
+
+Returns from the function. If the function is void, the expression must
+be absent, and if the function is not void the expression must be
+present.
+
+@item
+expression: variable OR integer_constant OR expression+expression OR expression-expression
+ OR expression==expression OR (expression) OR variable=expression OR function_call
+
+An expression can be a constant or a variable reference or a
+function_call. Expressions can be combined as a sum of two expressions
+or the difference of two expressions, or an equality test of two
+expresions. An assignment is also an expression. Expresions and operator
+precedence work as in C.
+
+@item
+function_call: function_name (comma_separated_expressions)
+
+This invokes the function, passing to it the values of the expressions
+as actual parameters.
+
+@end itemize
+
+@cindex compilers
+@node Compiler Overview, TREELANG and GCC, Parsing Syntax, Top
+@chapter Compiler Overview
+treelang is run as part of the GCC compiler.
+
+@itemize @bullet
+@cindex source code
+@cindex file, source
+@cindex code, source
+@cindex source file
+@item
+It reads a user's program, stored in a file and containing instructions
+written in the appropriate language (Treelang, C, and so on). This file
+contains @dfn{source code}.
+
+@cindex translation of user programs
+@cindex machine code
+@cindex code, machine
+@cindex mistakes
+@item
+It translates the user's program into instructions a computer can carry
+out more quickly than it takes to translate the instructions in the
+first place. These instructions are called @dfn{machine code}---code
+designed to be efficiently translated and processed by a machine such as
+a computer. Humans usually aren't as good writing machine code as they
+are at writing Treelang or C, because it is easy to make tiny mistakes
+writing machine code. When writing Treelang or C, it is easy to make
+big mistakes. But you can only make one mistake, because the compiler
+stops after it finds any problem.
+
+@cindex debugger
+@cindex bugs, finding
+@cindex @code{gdb}, command
+@cindex commands, @code{gdb}
+@item
+It provides information in the generated machine code
+that can make it easier to find bugs in the program
+(using a debugging tool, called a @dfn{debugger},
+such as @code{gdb}).
+
+@cindex libraries
+@cindex linking
+@cindex @code{ld} command
+@cindex commands, @code{ld}
+@item
+It locates and gathers machine code already generated to perform actions
+requested by statements in the user's program. This machine code is
+organized into @dfn{libraries} and is located and gathered during the
+@dfn{link} phase of the compilation process. (Linking often is thought
+of as a separate step, because it can be directly invoked via the
+@code{ld} command. However, the @code{gcc} command, as with most
+compiler commands, automatically performs the linking step by calling on
+@code{ld} directly, unless asked to not do so by the user.)
+
+@cindex language, incorrect use of
+@cindex incorrect use of language
+@item
+It attempts to diagnose cases where the user's program contains
+incorrect usages of the language. The @dfn{diagnostics} produced by the
+compiler indicate the problem and the location in the user's source file
+where the problem was first noticed. The user can use this information
+to locate and fix the problem.
+
+The compiler stops after the first error. There are no plans to fix
+this, ever, as it would vastly complicate the implementation of treelang
+to little or no benefit.
+
+@cindex diagnostics, incorrect
+@cindex incorrect diagnostics
+@cindex error messages, incorrect
+@cindex incorrect error messages
+(Sometimes an incorrect usage of the language leads to a situation where
+the compiler can not make any sense of what it reads---while a human
+might be able to---and thus ends up complaining about an incorrect
+``problem'' it encounters that, in fact, reflects a misunderstanding of
+the programmer's intention.)
+
+@cindex warnings
+@cindex questionable instructions
+@item
+There are no warnings in treelang. A program is either correct or in
+error.
+@end itemize
+
+@cindex components of treelang
+@cindex @code{treelang}, components of
+@code{treelang} consists of several components:
+
+@cindex @code{gcc}, command
+@cindex commands, @code{gcc}
+@itemize @bullet
+@item
+A modified version of the @code{gcc} command, which also might be
+installed as the system's @code{cc} command.
+(In many cases, @code{cc} refers to the
+system's ``native'' C compiler, which
+might be a non-GNU compiler, or an older version
+of @code{GCC} considered more stable or that is
+used to build the operating system kernel.)
+
+@cindex @code{treelang}, command
+@cindex commands, @code{treelang}
+@item
+The @code{treelang} command itself.
+
+@item
+The @code{libc} run-time library. This library contains the machine
+code needed to support capabilities of the Treelang language that are
+not directly provided by the machine code generated by the
+@code{treelang} compilation phase. This is the same library that the
+main c compiler uses (libc).
+
+@cindex @code{tree1}, program
+@cindex programs, @code{tree1}
+@cindex assembler
+@cindex @code{as} command
+@cindex commands, @code{as}
+@cindex assembly code
+@cindex code, assembly
+@item
+The compiler itself, is internally named @code{tree1}.
+
+Note that @code{tree1} does not generate machine code directly---it
+generates @dfn{assembly code} that is a more readable form
+of machine code, leaving the conversion to actual machine code
+to an @dfn{assembler}, usually named @code{as}.
+@end itemize
+
+@code{GCC} is often thought of as ``the C compiler'' only,
+but it does more than that.
+Based on command-line options and the names given for files
+on the command line, @code{gcc} determines which actions to perform, including
+preprocessing, compiling (in a variety of possible languages), assembling,
+and linking.
+
+@cindex driver, gcc command as
+@cindex @code{gcc}, command as driver
+@cindex executable file
+@cindex files, executable
+@cindex cc1 program
+@cindex programs, cc1
+@cindex preprocessor
+@cindex cpp program
+@cindex programs, cpp
+For example, the command @samp{gcc foo.c} @dfn{drives} the file
+@file{foo.c} through the preprocessor @code{cpp}, then
+the C compiler (internally named
+@code{cc1}), then the assembler (usually @code{as}), then the linker
+(@code{ld}), producing an executable program named @file{a.out} (on
+UNIX systems).
+
+@cindex treelang program
+@cindex programs, treelang
+As another example, the command @samp{gcc foo.tree} would do much the
+same as @samp{gcc foo.c}, but instead of using the C compiler named
+@code{cc1}, @code{gcc} would use the treelang compiler (named
+@code{tree1}). However there is no preprocessor for treelang.
+
+@cindex @code{tree1}, program
+@cindex programs, @code{tree1}
+In a GNU Treelang installation, @code{gcc} recognizes Treelang source
+files by name just like it does C and C++ source files. It knows to use
+the Treelang compiler named @code{tree1}, instead of @code{cc1} or
+@code{cc1plus}, to compile Treelang files. If a file's name ends in
+@code{.tree} then GCC knows that the program is written in treelang. You
+can also manually override the language.
+
+@cindex @code{gcc}, not recognizing Treelang source
+@cindex unrecognized file format
+@cindex file format not recognized
+Non-Treelang-related operation of @code{gcc} is generally
+unaffected by installing the GNU Treelang version of @code{gcc}.
+However, without the installed version of @code{gcc} being the
+GNU Treelang version, @code{gcc} will not be able to compile
+and link Treelang programs.
+
+@cindex printing version information
+@cindex version information, printing
+The command @samp{gcc -v x.tree} where @samp{x.tree} is a file which
+must exist but whose contents are ignored, is a quick way to display
+version information for the various programs used to compile a typical
+Treelang source file.
+
+The @code{tree1} program represents most of what is unique to GNU
+Treelang; @code{tree1} is a combination of two rather large chunks of
+code.
+
+@cindex GCC Back End (GBE)
+@cindex GBE
+@cindex @code{GCC}, back end
+@cindex back end, GCC
+@cindex code generator
+One chunk is the so-called @dfn{GNU Back End}, or GBE,
+which knows how to generate fast code for a wide variety of processors.
+The same GBE is used by the C, C++, and Treelang compiler programs @code{cc1},
+@code{cc1plus}, and @code{tree1}, plus others.
+Often the GBE is referred to as the ``GCC back end'' or
+even just ``GCC''---in this manual, the term GBE is used
+whenever the distinction is important.
+
+@cindex GNU Treelang Front End (TFE)
+@cindex tree1
+@cindex @code{treelang}, front end
+@cindex front end, @code{treelang}
+The other chunk of @code{tree1} is the majority of what is unique about
+GNU Treelang---the code that knows how to interpret Treelang programs to
+determine what they are intending to do, and then communicate that
+knowledge to the GBE for actual compilation of those programs. This
+chunk is called the @dfn{Treelang Front End} (TFE). The @code{cc1} and
+@code{cc1plus} programs have their own front ends, for the C and C++
+languages, respectively. These fronts ends are responsible for
+diagnosing incorrect usage of their respective languages by the programs
+the process, and are responsible for most of the warnings about
+questionable constructs as well. (The GBE in principle handles
+producing some warnings, like those concerning possible references to
+undefined variables, but these warnings should not occur in treelang
+programs as the front end is meant to pick them up first).
+
+Because so much is shared among the compilers for various languages,
+much of the behavior and many of the user-selectable options for these
+compilers are similar.
+For example, diagnostics (error messages and
+warnings) are similar in appearance; command-line
+options like @samp{-Wall} have generally similar effects; and the quality
+of generated code (in terms of speed and size) is roughly similar
+(since that work is done by the shared GBE).
+
+@node TREELANG and GCC, Compiler, Compiler Overview, Top
+@chapter Compile Treelang, C, or Other Programs
+@cindex compiling programs
+@cindex programs, compiling
+
+@cindex @code{gcc}, command
+@cindex commands, @code{gcc}
+A GNU Treelang installation includes a modified version of the @code{gcc}
+command.
+
+In a non-Treelang installation, @code{gcc} recognizes C, C++,
+and Objective-C source files.
+
+In a GNU Treelang installation, @code{gcc} also recognizes Treelang source
+files and accepts Treelang-specific command-line options, plus some
+command-line options that are designed to cater to Treelang users
+but apply to other languages as well.
+
+@xref{G++ and GCC,,Compile C; C++; or Objective-C,GCC,Using and Porting GCC},
+for information on the way different languages are handled
+by the GCC compiler (@code{gcc}).
+
+You can use this, combined with the output of the @samp{GCC -v x.tree}
+command to get the options applicable to treelang. Treelang programs
+must end with the suffix @samp{.tree}.
+
+@cindex preprocessor
+
+Treelang programs are not by default run through the C
+preprocessor by @code{gcc}. There is no reason why they cannot be run through the
+preprocessor manually, but you would need to prevent the preprocessor
+from generating #line directives, using the @samp{-P} option, otherwise
+tree1 will not accept the input.
+
+@node Compiler, Other Languages, TREELANG and GCC, Top
+@chapter The GNU Treelang Compiler
+
+The GNU Treelang compiler, @code{treelang}, supports programs written
+in the GNU Treelang language.
+
+@node Other Languages, treelang internals, Compiler, Top
+@chapter Other Languages
+
+@menu
+* Interoperating with C and C++::
+@end menu
+
+@node Interoperating with C and C++, , Other Languages, Other Languages
+@section Tools and advice for interoperating with C and C++
+
+The output of treelang programs looks like C program code to the linker
+and everybody else, so you should be able to freely mix treelang and C
+(and C++) code, with one proviso.
+
+C promotes small integer types to 'int' when used as function parameters and
+return values. The treelang compiler does not do this, so if you want to interface
+to C, you need to specify the promoted value, not the nominal value.
+
+@ifset INTERNALS
+@node treelang internals, Open Questions, Other Languages, Top
+@chapter treelang internals
+
+@menu
+* treelang files::
+* treelang compiler interfaces::
+* Hints and tips::
+@end menu
+
+@node treelang files, treelang compiler interfaces, treelang internals, treelang internals
+@section treelang files
+
+To create a compiler that integrates into GCC, you need create many
+files. Some of the files are integrated into the main GCC makefile, to
+build the various parts of the compiler and to run the test
+suite. Others are incorporated into various GCC programs such as
+GCC.c. Finally you must provide the actual programs comprising your
+compiler.
+
+@cindex files
+
+The files are:
+
+@enumerate 1
+
+@item
+COPYING. This is the copyright file, assuming you are going to use the
+GNU General Public Licence. You probably need to use the GPL because if
+you use the GCC back end your program and the back end are one program,
+and the back end is GPLed.
+
+This need not be present if the language is incorporated into the main
+GCC tree, as the main GCC directory has this file.
+
+@item
+COPYING.LIB. This is the copyright file for those parts of your program
+that are not to be covered by the GPL, but are instead to be covered by
+the LGPL (Library or Lesser GPL). This licence may be appropriate for
+the library routines associated with your compiler. These are the
+routines that are linked with the @emph{output} of the compiler. Using
+the LGPL for these programs allows programs written using your compiler
+to be closed source. For example LIBC is under the LGPL.
+
+This need not be present if the language is incorporated into the main
+GCC tree, as the main GCC directory has this file.
+
+@item
+ChangeLog. Record all the changes to your compiler. Use the same format
+as used in treelang as it is supported by an emacs editing mode and is
+part of the FSF coding standard. Normally each directory has its own
+changelog. The FSF standard allows but does not require a meaningful
+comment on why the changes were made, above and beyond @emph{why} they
+were made. In the author's opinion it is useful to provide this
+information.
+
+@item
+treelang.texi. The manual, written in texinfo. Your manual would have a
+different file name. You need not write it in texinfo if you don't want
+do, but a lot of GNU software does use texinfo.
+
+@cindex Make-lang.in
+@item
+Make-lang.in. This file is part of the make file which in incorporated
+with the GCC make file skeleton (Makefile.in in the GCC directory) to
+make Makefile, as part of the configuration process.
+
+Makefile in turn is the main instruction to actually build
+everything. The build instructions are held in the main GCC manual and
+web site so they are not repeated here.
+
+There are some comments at the top which will help you understand what
+you need to do.
+
+There are make commands to build things, remove generated files with
+various degrees of thoroughness, count the lines of code (so you know
+how much progress you are making), build info and html files from the
+texinfo source, run the tests etc.
+
+@item
+README. Just a brief informative text file saying what is in this
+directory.
+
+@cindex config-lang.in
+@item
+config-lang.in. This file is read by the configuration progress and must
+be present. You specify the name of your language, the name(s) of the
+compiler(s) incouding preprocessors you are going to build, whether any,
+usually generated, files should be excluded from diffs (ie when making
+diff files to send in patches). Whether the equate 'stagestuff' is used
+is unknown (???).
+
+@cindex lang-options
+@item
+lang-options. This file is included into GCC.c, the main GCC driver, and
+tells it what options your language supports. This is only used to
+display help (is this true ???).
+
+@cindex lang-specs
+@item
+lang-specs. This file is also included in GCC.c. It tells GCC.c when to
+call your programs and what options to send them. The mini-language
+'specs' is documented in the source of GCC.c. Do not attempt to write a
+specs file from scratch - use an existing one as the base and enhance
+it.
+
+@item
+Your texi files. Texinfo can be used to build documentation in HTML,
+info, dvi and postscript formats. It is a tagged language, is documented
+in its own manual, and has its own emacs mode.
+
+@item
+Your programs. The relationships between all the programs are explained
+in the next section. You need to write or use the following programs:
+
+@itemize @bullet
+
+@item
+lexer. This breaks the input into words and passes these to the
+parser. This is lex.l in treelang, which is passed through flex, a lex
+variant, to produce C code lex.c. Note there is a school of thought that
+says real men hand code their own lexers, however you may prefer to
+write far less code and use flex, as was done with treelang.
+
+@item
+parser. This breaks the program into recognizable constructs such as
+expressions, statements etc. This is parse.y in treelang, which is
+passed through bison, which is a yacc variant, to produce C code parse.c.
+
+@item
+back end interface. This interfaces to the code generation back end. In
+treelang, this is tree1.c which mainly interfaces to toplev.c and
+treetree.c which mainly interfaces to everything else. Many languages
+mix up the back end interface with the parser, as in the C compiler for
+example. It is a matter of taste which way to do it, but with treelang
+it is separated out to make the back end interface cleaner and easier to
+understand.
+
+@item
+header files. For function prototypes and common data items. One point
+to note here is that bison can generate a header files with all the
+numbers is has assigned to the keywords and symbols, and you can include
+the same header in your lexer. This technique is demonstrated in
+treelang.
+
+@item
+compiler main file. GCC comes with a program toplev.c which is a
+perfectly serviceable main program for your compiler. treelang uses
+toplev.c but other languages have been known to replace it with their
+own main program. Again this is a matter of taste and how much code you
+want to write.
+
+@end itemize
+
+@end enumerate
+
+@node treelang compiler interfaces, Hints and tips, treelang files, treelang internals
+@section treelang compiler interfaces
+
+@cindex driver
+@cindex toplev.c
+
+@menu
+* treelang driver::
+* treelang main compiler::
+@end menu
+
+@node treelang driver, treelang main compiler, treelang compiler interfaces, treelang compiler interfaces
+@subsection treelang driver
+
+The GCC compiler consists of a driver, which then executes the various
+compiler phases based on the instructions in the specs files.
+
+Typically a program's language will be identified from its suffix (eg
+.tree) for treelang programs.
+
+The driver (gcc.c) will then drive (exec) in turn a preprocessor, the main
+compiler, the assembler and the link editor. Options to GCC allow you to
+override all of this. In the case of treelang programs there is no
+preprocessor, and mostly these days the C preprocessor is run within the
+main C compiler rather than as a separate process, apparently for reasons of speed.
+
+You will be using the standard assembler and linkage editor so these are
+ignored from now on.
+
+You have to write your own preprocessor if you want one. This is usually
+totally language specific. The main point to be aware of is to ensure
+that you find some way to pass file name and line number information
+through to the main compiler so that it can tell the back end this
+information and so the debugger can find the right source line for each
+piece of code. That is all there is to say about the preprocessor except
+that the preprocessor will probably not be the slowest part of the
+compiler and will probably not use the most memory so don't waste too
+much time tuning it until you know you need to do so.
+
+@node treelang main compiler, , treelang driver, treelang compiler interfaces
+@subsection treelang main compiler
+
+The main compiler for treelang consists of toplev.c from the main GCC
+compiler, the parser, lexer and back end interface routines, and the
+back end routines themselves, of which there are many.
+
+toplev.c does a lot of work for you and you should almost certainly use it,
+
+Writing this code is the hard part of creating a compiler using GCC. The
+back end interface documentation is incomplete and the interface is
+complex.
+
+There are three main aspects to interfacing to the other GCC code.
+
+@menu
+* Interfacing to toplev.c::
+* Interfacing to the garbage collection::
+* Interfacing to the code generation code. ::
+@end menu
+
+@node Interfacing to toplev.c, Interfacing to the garbage collection, treelang main compiler, treelang main compiler
+@subsubsection Interfacing to toplev.c
+
+In treelang this is handled mainly in tree1.c
+and partly in treetree.c. Peruse toplev.c for details of what you need
+to do.
+
+@node Interfacing to the garbage collection, Interfacing to the code generation code. , Interfacing to toplev.c, treelang main compiler
+@subsubsection Interfacing to the garbage collection
+
+Interfacing to the garbage collection. In treelang this is mainly in
+tree1.c.
+
+Memory allocation in the compiler should be done using the ggc_alloc and
+kindred routines in ggc*.*. At the end of every 'function' in your language, toplev.c calls
+the garbage collection several times. The garbage collection calls mark
+routines which go through the memory which is still used, telling the
+garbage collection not to free it. Then all the memory not used is
+freed.
+
+What this means is that you need a way to hook into this marking
+process. This is done by calling ggc_add_root. This provides the address
+of a callback routine which will be called duing garbage collection and
+which can call ggc_mark to save the storage. If storage is only
+used within the parsing of a function, you do not need to provide a way
+to mark it.
+
+Note that you can also call ggc_mark_tree to mark any of the back end
+internal 'tree' nodes. This routine will follow the branches of the
+trees and mark all the subordinate structures. This is useful for
+example when you have created a variable declaaration that will be used
+across multiple functions, or for a function declaration (from a
+prototype) that may be used later on. See the next item for more on the
+tree nodes.
+
+@node Interfacing to the code generation code. , , Interfacing to the garbage collection, treelang main compiler
+@subsubsection Interfacing to the code generation code.
+
+In treelang this is done in treetree.c. A typedef called 'tree' which is
+defined in tree.h and tree.def in the GCC directory and largely
+implemented in tree.c and stmt.c forms the basic interface to the
+compiler back end.
+
+In general you call various tree routines to generate code, either
+directly or through toplev.c. You build up data structures and
+expressions in similar ways.
+
+You can read some documentation on this which can be found via the GCC
+main web page. In particular, the documentation produced by Joachim
+Nadler and translated by Tim Josling can be quite useful. the C compiler
+also has documentation in the main GCC manual (particularly the current
+CVS version) which is useful on a lot of the details.
+
+In time it is hoped to enhance this document to provide a more
+comprehensive overview of this topic. The main gap is in explaining how
+it all works together.
+
+@node Hints and tips, , treelang compiler interfaces, treelang internals
+@section Hints and tips
+
+@itemize @bullet
+
+@item
+TAGS: Use the make ETAGS commands to create TAGS files which can be used in
+emacs to jump to any symbol quickly.
+
+@item
+GREP: grep is also a useful way to find all uses of a symbol.
+
+@item
+TREE: The main routines to look at are tree.h and tree.def. You will
+probably want a hardcopy of these.
+
+@item
+SAMPLE: look at the sample interfacing code in treetree.c. You can use
+gdb to trace through the code and learn about how it all works.
+
+@item
+GDB: the GCC back end works well with gdb. It traps abort() and allows
+you to trace back what went wrong.
+
+@item
+Error Checking: The compiler back end does some error and consistency
+checking. Often the result of an error is just no code being
+generated. You will then need to trace through and find out what is
+going wrong. The rtl dump files can help here also.
+
+@item
+rtl dump files: The main compiler documents these files which are dumps
+of the rtl (intermediate code) which is manipulated doing the code
+generation process. This can provide useful clues about what is going
+wrong. The rtl 'language' is documented in the main GCC manual.
+
+@end itemize
+
+@end ifset
+
+@node Open Questions, Bugs, treelang internals, Top
+@chapter Open Questions
+
+If you know GCC well, please consider looking at the file treetree.c and
+resolving any questions marked "???".
+
+@node Bugs, Service, Open Questions, Top
+@chapter Reporting Bugs
+@cindex bugs
+@cindex reporting bugs
+
+You can report bugs to @email{@value{email-bugs}}. Please make
+sure bugs are real before reporting them. Follow the guidelines in the
+main GCC manual for submitting bug reports.
+
+@menu
+* Sending Patches::
+@end menu
+
+@node Sending Patches, , Bugs, Bugs
+@section Sending Patches for GNU Treelang
+
+If you would like to write bug fixes or improvements for the GNU
+Treelang compiler, that is very helpful. Send suggested fixes to
+@email{@value{email-patches}}.
+
+@node Service, Projects, Bugs, Top
+@chapter How To Get Help with GNU Treelang
+
+If you need help installing, using or changing GNU Treelang, there are two
+ways to find it:
+
+@itemize @bullet
+
+@item
+Look in the service directory for someone who might help you for a fee.
+The service directory is found in the file named @file{SERVICE} in the
+GCC distribution.
+
+@item
+Send a message to @email{@value{email-general}}.
+
+@end itemize
+
+@end ifset
+@ifset INTERNALS
+
+@node Projects, Index, Service, Top
+@chapter Projects
+@cindex projects
+
+If you want to contribute to @code{treelang} by doing research,
+design, specification, documentation, coding, or testing,
+the following information should give you some ideas.
+
+Send a message to @email{@value{email-general}} if you plan to add a
+feature.
+
+The main requirement for treelang is to add features and to add
+documentation. Features are things that the GCC back end can do but
+which are not reflected in treelang. Examples include structures,
+unions, pointers, arrays.
+
+@end ifset
+
+@node Index, , Projects, Top
+@unnumbered Index
+
+@printindex cp
+@summarycontents
+@contents
+@bye
diff --git a/gcc/treelang/treetree.c b/gcc/treelang/treetree.c
new file mode 100644
index 0000000..07cb1a5
--- /dev/null
+++ b/gcc/treelang/treetree.c
@@ -0,0 +1,1288 @@
+/*
+
+ TREELANG Compiler back end interface (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 Free Software Foundation, Inc.
+
+ This code is based on toy.c written by Richard Kenner.
+
+ It was later modified by Jonathan Bartlett whose changes have all
+ been removed (by Tim Josling).
+
+ Various bits and pieces were cloned from the GCC main tree, as
+ GCC evolved, for COBOLForGCC, by Tim Josling.
+
+ It was adapted to TREELANG by Tim Josling 2001.
+
+ ---------------------------------------------------------------------------
+
+ 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!
+
+ ---------------------------------------------------------------------------
+
+ */
+
+/*
+ Assumption: garbage collection is never called implicitly. It will
+ not be called 'at any time' when short of memory. It will only be
+ called explicitly at the end of each function. This removes the
+ 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. */
+
+/* Standard/OS headers. */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include "safe-ctype.h"
+#include <errno.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <getopt.h>
+#include <stdio.h>
+
+/* GCC headers. */
+
+#include "ansidecl.h"
+#include "config.h"
+#include "system.h"
+#include "tree.h"
+#include "flags.h"
+#include "output.h"
+#include "c-lex.h"
+#include "c-tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "ggc.h"
+#include "toplev.h"
+#include "varray.h"
+#include "langhooks-def.h"
+#include "langhooks.h"
+
+#include "treetree.h"
+
+extern int option_main;
+extern char **file_names;
+
+/* Flags etc required by c code. */
+
+int warn_format = 0;
+int warn_format_y2k = 0;
+int warn_format_extra_args = 0;
+int warn_format_nonliteral = 0;
+int warn_format_security = 0;
+
+/* The front end language hooks (addresses of code for this front
+ end). Mostly just use the C routines. */
+
+#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
+#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion
+#undef LANG_HOOKS_MARK_ADDRESSABLE
+#define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable
+#undef LANG_HOOKS_SIGNED_TYPE
+#define LANG_HOOKS_SIGNED_TYPE c_common_signed_type
+#undef LANG_HOOKS_UNSIGNED_TYPE
+#define LANG_HOOKS_UNSIGNED_TYPE c_common_unsigned_type
+#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
+#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE c_common_signed_or_unsigned_type
+#undef LANG_HOOKS_TYPE_FOR_MODE
+#define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode
+#undef LANG_HOOKS_TYPE_FOR_SIZE
+#define LANG_HOOKS_TYPE_FOR_SIZE c_common_type_for_size
+#undef LANG_HOOKS_PARSE_FILE
+#define LANG_HOOKS_PARSE_FILE treelang_parse_file
+
+/* Hook routines and data unique to treelang. */
+
+#undef LANG_HOOKS_INIT
+#define LANG_HOOKS_INIT treelang_init
+#undef LANG_HOOKS_NAME
+#define LANG_HOOKS_NAME "GNU treelang"
+#undef LANG_HOOKS_FINISH
+#define LANG_HOOKS_FINISH treelang_finish
+#undef LANG_HOOKS_DECODE_OPTION
+#define LANG_HOOKS_DECODE_OPTION treelang_decode_option
+const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
+
+/* Tree code type/name/code tables. */
+
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
+
+const char tree_code_type[] = {
+#include "tree.def"
+ 'x'
+};
+#undef DEFTREECODE
+
+#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
+
+const unsigned char tree_code_length[] = {
+#include "tree.def"
+ 0
+};
+#undef DEFTREECODE
+
+#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
+
+const char *const tree_code_name[] = {
+#include "tree.def"
+ "@@dummy"
+};
+#undef DEFTREECODE
+
+/* Number of bits in int and char - accessed by front end. */
+
+unsigned int tree_code_int_size = 0;
+unsigned int tree_code_char_size = 0;
+
+/* In this case there is very little to keep between functions - we
+ keep the symbol table only and the things that hang off that - see
+ tree1.c. Garbage collection is only invoked when we call
+ rest_of_compilation at the end of a function. */
+
+#define ADDROOT(where) ggc_add_root (&where, 1, /* Unused size. */ sizeof (void*), \
+ tree_ggc_storage_always_used);
+
+/* Return the tree stuff for this type TYPE_NUM. */
+
+tree
+tree_code_get_type (int type_num)
+{
+ switch (type_num)
+ {
+ case SIGNED_CHAR:
+ return signed_char_type_node;
+
+ case UNSIGNED_CHAR:
+ return unsigned_char_type_node;
+
+ case SIGNED_INT:
+ return integer_type_node;
+
+ case UNSIGNED_INT:
+ return unsigned_type_node;
+
+ case VOID_TYPE:
+ return void_type_node;
+
+ default:
+ abort ();
+ }
+}
+
+/* Output the code for the start of an if statement. The test
+ expression is EXP (true if not zero), and the stmt occurred at line
+ LINENO in file FILENAME. */
+
+void
+tree_code_if_start (tree exp, unsigned char* filename, int lineno)
+{
+ tree cond_exp;
+ cond_exp = build (NE_EXPR,
+ TREE_TYPE (exp),
+ exp,
+ build1 (CONVERT_EXPR, TREE_TYPE (exp), integer_zero_node));
+ emit_line_note ((const char *)filename, lineno); /* Output the line number information. */
+ expand_start_cond (cond_exp, /* Exit-able if non zero. */ 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 (unsigned char* filename, int lineno)
+{
+ emit_line_note ((const char *)filename, lineno); /* Output the line number information. */
+ expand_start_else ();
+}
+
+/* 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 (unsigned char* filename, int lineno)
+{
+ emit_line_note ((const char *)filename, lineno); /* Output the line number information. */
+ expand_end_cond ();
+}
+
+/* Create a function. The prototype name is NAME, storage class is
+ STORAGE_CLASS, type of return variable is RET_TYPE, parameter lists
+ is PARMS, returns decl for this function. */
+
+tree
+tree_code_create_function_prototype (unsigned char* chars,
+ unsigned int storage_class,
+ unsigned int ret_type,
+ struct tree_parameter_list* parms,
+ unsigned char* filename,
+ int lineno)
+{
+
+ tree id;
+ struct tree_parameter_list* parm;
+ tree type_list = NULL_TREE;
+ tree type_node;
+ tree fn_type;
+ tree fn_decl;
+
+ /* Build the type. */
+ id = get_identifier ((const char*)chars);
+ for (parm = parms; parm; parm = parm->next)
+ {
+ type_node = get_type_for_numeric_type (parm->type);
+ type_list = tree_cons (NULL_TREE, type_node, type_list);
+ }
+ /* Last parm if null indicates fixed length list (as opposed to
+ printf style va_* list). */
+ type_list = tree_cons (NULL_TREE, void_type_node, type_list);
+ /* The back end needs them in reverse order. */
+ type_list = nreverse (type_list);
+
+ type_node = get_type_for_numeric_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. */
+ DECL_SOURCE_FILE (fn_decl) = (const char *)filename;
+ /* if (lineno > 1000000)
+ ; */ /* Probably the line # is rubbish because someone forgot to set
+ the line number - and unfortunately impossible line #s are used as
+ magic flags at various times. The longest known function for
+ example is about 550,000 lines (it was written in COBOL). */
+ DECL_SOURCE_LINE (fn_decl) = lineno;
+
+ 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;
+ switch (storage_class)
+ {
+ case STATIC_STORAGE:
+ TREE_PUBLIC (fn_decl) = 0;
+ break;
+
+ case EXTERNAL_DEFINITION_STORAGE:
+ TREE_PUBLIC (fn_decl) = 1;
+ TREE_STATIC (fn_decl) = 0;
+ DECL_EXTERNAL (fn_decl) = 0;
+ break;
+
+ case EXTERNAL_REFERENCE_STORAGE:
+ TREE_PUBLIC (fn_decl) = 0;
+ DECL_EXTERNAL (fn_decl) = 1;
+ break;
+
+
+ case AUTOMATIC_STORAGE:
+ default:
+ abort ();
+ }
+
+ /* Process declaration of function defined elsewhere. */
+ rest_of_decl_compilation (fn_decl, NULL, 1, 0);
+
+ return fn_decl;
+}
+
+
+/* Output code for start of function; the decl of the function is in
+ PREV_SAVED (as created by tree_code_create_function_prototype),
+ the function is at line number LINENO in file FILENAME. The
+ parameter details are in the lists PARMS. Returns nothing. */
+void
+tree_code_create_function_initial (tree prev_saved,
+ unsigned char* filename,
+ int lineno,
+ struct tree_parameter_list* parms)
+{
+ tree fn_decl;
+ tree param_decl;
+ tree next_param;
+ tree first_param;
+ tree parm_decl;
+ tree parm_list;
+ tree resultdecl;
+ struct tree_parameter_list* this_parm;
+ struct tree_parameter_list* parm;
+
+ fn_decl = prev_saved;
+ if (!fn_decl)
+ abort ();
+
+ /* Output message if not -quiet. */
+ announce_function (fn_decl);
+
+ /* This has something to do with forcing output also. */
+ pushdecl (fn_decl);
+
+ /* Set current function for error msgs etc. */
+ current_function_decl = fn_decl;
+ DECL_INITIAL (fn_decl) = error_mark_node;
+
+ DECL_SOURCE_FILE (fn_decl) = (const char *)filename;
+ DECL_SOURCE_LINE (fn_decl) = lineno;
+
+ /* 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;
+ DECL_SOURCE_FILE (resultdecl) = (const char *)filename;
+ DECL_SOURCE_LINE (resultdecl) = lineno;
+ /* Work out the size. ??? is this needed. */
+ layout_decl (DECL_RESULT (fn_decl), 0);
+
+ /* Make the argument variable decls. */
+ parm_list = NULL_TREE;
+ for (parm = parms; parm; parm = parm->next)
+ {
+ parm_decl = build_decl (PARM_DECL, get_identifier ((const char*) (parm->variable_name)),
+ get_type_for_numeric_type (parm->type));
+
+ /* Some languages have different nominal and real types. */
+ DECL_ARG_TYPE (parm_decl) = TREE_TYPE (parm_decl);
+ if (!DECL_ARG_TYPE (parm_decl))
+ abort ();
+ if (!fn_decl)
+ abort ();
+ DECL_CONTEXT (parm_decl) = fn_decl;
+ DECL_SOURCE_FILE (parm_decl) = (const char *)filename;
+ DECL_SOURCE_LINE (parm_decl) = lineno;
+ parm_list = chainon (parm_decl, parm_list);
+ }
+
+ /* Back into reverse order as the back end likes them. */
+ parm_list = nreverse (parm_list);
+
+ DECL_ARGUMENTS (fn_decl) = parm_list;
+
+ /* Save the decls for use when the args are referred to. */
+ for (param_decl = DECL_ARGUMENTS (fn_decl),
+ this_parm = parms;
+ param_decl;
+ param_decl = TREE_CHAIN (param_decl),
+ this_parm = this_parm->next)
+ {
+ if (!this_parm)
+ abort (); /* Too few. */
+ *this_parm->where_to_put_var_tree = param_decl;
+ }
+ 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, NULL);
+
+ /* Use filename/lineno from above. */
+ init_function_start (fn_decl, (const char *)filename, lineno);
+
+ /* 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. */
+
+ (*lang_hooks.decls.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. */
+
+ (*lang_hooks.decls.pushlevel) (0);
+
+ /* Create rtl for the start of a new scope. */
+
+ expand_start_bindings (0);
+
+ emit_line_note ((const char *)filename, lineno); /* Output the line number information. */
+}
+
+/* Wrapup a function contained in file FILENAME, ending at line LINENO. */
+void
+tree_code_create_function_wrapup (unsigned char* filename,
+ int lineno)
+{
+ tree block;
+ tree fn_decl;
+
+ fn_decl = current_function_decl;
+
+ emit_line_note ((const char *)filename, lineno); /* Output the line number information. */
+
+ /* Get completely built level from debugger symbol table. */
+
+ block = (*lang_hooks.decls.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 ((const char *)filename, lineno, 0);
+
+ /* Pop the level. */
+
+ block = (*lang_hooks.decls.poplevel) (1, 0, 1);
+
+ /* And attach it to the function. */
+
+ DECL_INITIAL (fn_decl) = block;
+
+ /* Emit rtl for end of scope. */
+
+ expand_end_bindings (block, 0, 1);
+
+ /* Call optimization and convert optimized rtl to assembly code. */
+
+ rest_of_compilation (fn_decl);
+
+ /* We are not inside of any scope now. */
+
+ current_function_decl = NULL_TREE;
+}
+
+/*
+ Create a variable.
+
+ The storage class is STORAGE_CLASS (eg LOCAL).
+ The name is CHARS/LENGTH.
+ The type is EXPRESSION_TYPE (eg UNSIGNED_TYPE).
+ The init tree is INIT.
+*/
+
+tree
+tree_code_create_variable (unsigned int storage_class,
+ unsigned char* chars,
+ unsigned int length,
+ unsigned int expression_type,
+ tree init,
+ unsigned char* filename,
+ int lineno)
+{
+ tree var_type;
+ tree var_id;
+ tree var_decl;
+
+ /* 1. Build the type. */
+ var_type = get_type_for_numeric_type (expression_type);
+
+ /* 2. Build the name. */
+ if (chars[length] != 0)
+ abort (); /* Should be null terminated. */
+
+ var_id = get_identifier ((const char*)chars);
+
+ /* 3. Build the decl and set up init. */
+ var_decl = build_decl (VAR_DECL, var_id, var_type);
+
+ /* 3a. Initialization. */
+ if (init)
+ DECL_INITIAL (var_decl) = 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. */
+
+ DECL_CONTEXT (var_decl) = current_function_decl;
+
+ DECL_SOURCE_FILE (var_decl) = (const char *)filename;
+ DECL_SOURCE_LINE (var_decl) = lineno;
+
+ /* Set the storage mode and whether only visible in the same file. */
+ switch (storage_class)
+ {
+ case STATIC_STORAGE:
+ TREE_STATIC (var_decl) = 1;
+ TREE_PUBLIC (var_decl) = 0;
+ break;
+
+ case AUTOMATIC_STORAGE:
+ TREE_STATIC (var_decl) = 0;
+ TREE_PUBLIC (var_decl) = 0;
+ break;
+
+ case EXTERNAL_DEFINITION_STORAGE:
+ TREE_STATIC (var_decl) = 0;
+ TREE_PUBLIC (var_decl) = 1;
+ break;
+
+ case EXTERNAL_REFERENCE_STORAGE:
+ DECL_EXTERNAL (var_decl) = 1;
+ TREE_PUBLIC (var_decl) = 0;
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* This should really only be set if the variable is used. */
+ TREE_USED (var_decl) = 1;
+
+ /* Expand declaration and initial value if any. */
+
+ if (TREE_STATIC (var_decl))
+ rest_of_decl_compilation (var_decl, 0, 0, 0);
+ else
+ {
+ expand_decl (var_decl);
+ if (DECL_INITIAL (var_decl))
+ expand_decl_init (var_decl);
+ }
+
+ return pushdecl (copy_node (var_decl));
+
+}
+
+
+/* Generate code for return statement. Type is in TYPE, expression
+ is in EXP if present. */
+
+void
+tree_code_generate_return (tree type, tree exp)
+{
+ tree setret;
+ tree param;
+
+ for (param = DECL_ARGUMENTS (current_function_decl);
+ param;
+ param = TREE_CHAIN (param))
+ {
+ if (DECL_CONTEXT (param) != current_function_decl)
+ abort ();
+ }
+
+ if (exp)
+ {
+ setret = build (MODIFY_EXPR, type, DECL_RESULT (current_function_decl),
+ build1 (CONVERT_EXPR, type, exp));
+ TREE_SIDE_EFFECTS (setret) = 1;
+ TREE_USED (setret) = 1;
+ expand_expr_stmt (setret);
+ }
+ expand_return (DECL_RESULT (current_function_decl));
+}
+
+/* Output the code for this expression statement CODE. */
+
+
+void
+tree_code_output_expression_statement (tree code,
+ unsigned char* filename, int lineno)
+{
+ /* Output the line number information. */
+ emit_line_note ((const char *)filename, lineno);
+ TREE_USED (code) = 1;
+ TREE_SIDE_EFFECTS (code) = 1;
+ expand_expr_stmt (code);
+}
+
+/* Return a tree for a constant integer value in the token TOK. No
+ size checking is done. */
+
+tree
+tree_code_get_integer_value (unsigned char* chars, unsigned int length)
+{
+ long long int val = 0;
+ unsigned int ix;
+ unsigned int start = 0;
+ int negative = 1;
+ switch (chars[0])
+ {
+ case (unsigned char)'-':
+ negative = -1;
+ start = 1;
+ break;
+
+ case (unsigned char)'+':
+ start = 1;
+ break;
+
+ default:
+ break;
+ }
+ for (ix = start; ix < length; ix++)
+ val = val * 10 + chars[ix] - (unsigned char)'0';
+ val = val*negative;
+ return build_int_2 (val & 0xffffffff, (val >> 32) & 0xffffffff);
+}
+
+/* Return the tree for an expresssion, type EXP_TYPE (see treetree.h)
+ with tree type TYPE and with operands1 OP1, OP2 (maybe), OP3 (maybe). */
+tree
+tree_code_get_expression (unsigned int exp_type,
+ tree type, tree op1, tree op2, tree op3 ATTRIBUTE_UNUSED)
+{
+ tree ret1;
+ int operator;
+
+ switch (exp_type)
+ {
+ case EXP_ASSIGN:
+ if (!op1 || !op2)
+ abort ();
+ operator = MODIFY_EXPR;
+ ret1 = build (operator, type,
+ op1,
+ build1 (CONVERT_EXPR, type, op2));
+
+ break;
+
+ case EXP_PLUS:
+ operator = PLUS_EXPR;
+ goto binary_expression;
+
+ case EXP_MINUS:
+ operator = MINUS_EXPR;
+ goto binary_expression;
+
+ case EXP_EQUALS:
+ operator = EQ_EXPR;
+ goto binary_expression;
+
+ /* 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));
+ break;
+
+ /* Reference to a variable. This is dead easy, just return the
+ decl for the variable. If the TYPE is different than the
+ variable type, convert it. */
+ case EXP_REFERENCE:
+ if (!op1)
+ abort ();
+ if (type == TREE_TYPE (op1))
+ ret1 = op1;
+ else
+ ret1 = 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));
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ return ret1;
+}
+
+/* Init parameter list and return empty list. */
+
+tree
+tree_code_init_parameters (void)
+{
+ return NULL_TREE;
+}
+
+/* Add a parameter EXP whose expression type is EXP_PROTO to list
+ LIST, returning the new list. */
+
+tree
+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);
+ 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 == 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;
+}
+
+/* Garbage Collection. */
+
+/* Callback to mark storage M as used always. */
+
+void
+tree_ggc_storage_always_used (void * m)
+{
+ void **mm; /* Actually M is a pointer to a pointer to the memory. */
+ mm = (void**)m;
+
+ if (*mm)
+ ggc_mark (*mm);
+}
+
+/* Following from c-lang.c. */
+
+/* Tell the c code we are not objective C. */
+
+int
+maybe_objc_comptypes (tree lhs ATTRIBUTE_UNUSED,
+ tree rhs ATTRIBUTE_UNUSED,
+ int reflexive ATTRIBUTE_UNUSED)
+{
+ return -1;
+}
+
+/* Used by c-typeck.c (build_external_ref), but only for objc. */
+
+tree
+lookup_objc_ivar (tree id ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* Dummy routines called from c code. Save copying c-decl.c, c-common.c etc. */
+
+void
+check_function_format (int *status ATTRIBUTE_UNUSED,
+ tree attrs ATTRIBUTE_UNUSED,
+ tree params ATTRIBUTE_UNUSED)
+{
+ return;
+}
+
+/* Tell the c code we are not objective C. */
+
+tree
+maybe_building_objc_message_expr ()
+{
+ return 0;
+}
+
+/* Should not be called for treelang. */
+
+tree
+build_stmt VPARAMS ((enum tree_code code ATTRIBUTE_UNUSED, ...))
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+tree
+add_stmt (tree t ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+tree
+build_return_stmt (tree expr ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* C warning, ignore. */
+
+void
+pedwarn_c99 VPARAMS ((const char *msgid ATTRIBUTE_UNUSED, ...))
+{
+ return;
+}
+
+/* Should not be called for treelang. */
+
+tree
+build_case_label (tree low_value ATTRIBUTE_UNUSED,
+ tree high_value ATTRIBUTE_UNUSED,
+ tree label_decl ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void
+emit_local_var (tree decl ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void
+expand_stmt (tree t ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+cpp_reader *
+cpp_create_reader (enum c_lang lang ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void
+cpp_post_options (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void
+cpp_preprocess_file (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+const char *
+init_c_lex (const char *filename ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void init_pragma (void);
+
+void
+init_pragma ()
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void
+cpp_finish (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+unsigned int
+cpp_errors (cpp_reader *pfile ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+tree
+handle_format_attribute (tree *node ATTRIBUTE_UNUSED,
+ tree name ATTRIBUTE_UNUSED,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+tree
+handle_format_arg_attribute (tree *node ATTRIBUTE_UNUSED,
+ tree name ATTRIBUTE_UNUSED,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+int
+cpp_handle_option (cpp_reader *pfile ATTRIBUTE_UNUSED,
+ int argc ATTRIBUTE_UNUSED,
+ char **argv ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void
+set_Wformat (int setting ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void
+maybe_objc_check_decl (tree decl ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void
+gen_aux_info_record (tree fndecl ATTRIBUTE_UNUSED,
+ int is_definition ATTRIBUTE_UNUSED,
+ int is_implicit ATTRIBUTE_UNUSED,
+ int is_prototyped ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang, but it is. */
+
+void
+c_parse_init ()
+{
+ return;
+}
+
+/* Should not be called for treelang. */
+
+void maybe_apply_pragma_weak (tree decl);
+
+void
+maybe_apply_pragma_weak (tree decl ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void
+add_decl_stmt (tree decl ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+tree
+maybe_apply_renaming_pragma (tree decl, tree asmname);
+
+/* Should not be called for treelang. */
+
+tree
+maybe_apply_renaming_pragma (tree decl ATTRIBUTE_UNUSED, tree asmname ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void
+begin_stmt_tree (tree *t ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+void
+finish_stmt_tree (tree *t ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+/* Should not be called for treelang. */
+
+int
+defer_fn (tree fn ATTRIBUTE_UNUSED)
+{
+ abort ();
+}
+
+
+/* Create the predefined scalar types of C,
+ and some nodes representing standard constants (0, 1, (void *) 0).
+ Initialize the global binding level.
+ Make definitions for built-in primitive functions. */
+
+ /* `unsigned long' is the standard type for sizeof.
+ Note that stddef.h uses `unsigned long',
+ and this must agree, even if long and int are the same size. */
+
+/* This variable keeps a table for types for each precision so that we
+ only allocate each of them once. Signed and unsigned types are
+ kept separate. */
+
+tree integer_types[itk_none] = { NULL_TREE};
+
+/* The reserved keyword table. */
+struct resword
+{
+ const char *word;
+ ENUM_BITFIELD(rid) rid : 16;
+ unsigned int disable : 16;
+};
+
+static const struct resword reswords[] =
+{
+ { "_Bool", RID_BOOL, 0 },
+ { "_Complex", RID_COMPLEX, 0 },
+ { "__FUNCTION__", RID_FUNCTION_NAME, 0 },
+ { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
+ { "__alignof", RID_ALIGNOF, 0 },
+ { "__alignof__", RID_ALIGNOF, 0 },
+ { "__asm", RID_ASM, 0 },
+ { "__asm__", RID_ASM, 0 },
+ { "__attribute", RID_ATTRIBUTE, 0 },
+ { "__attribute__", RID_ATTRIBUTE, 0 },
+ { "__bounded", RID_BOUNDED, 0 },
+ { "__bounded__", RID_BOUNDED, 0 },
+ { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
+ { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 },
+ { "__builtin_va_arg", RID_VA_ARG, 0 },
+ { "__complex", RID_COMPLEX, 0 },
+ { "__complex__", RID_COMPLEX, 0 },
+ { "__const", RID_CONST, 0 },
+ { "__const__", RID_CONST, 0 },
+ { "__extension__", RID_EXTENSION, 0 },
+ { "__func__", RID_C99_FUNCTION_NAME, 0 },
+ { "__imag", RID_IMAGPART, 0 },
+ { "__imag__", RID_IMAGPART, 0 },
+ { "__inline", RID_INLINE, 0 },
+ { "__inline__", RID_INLINE, 0 },
+ { "__label__", RID_LABEL, 0 },
+ { "__ptrbase", RID_PTRBASE, 0 },
+ { "__ptrbase__", RID_PTRBASE, 0 },
+ { "__ptrextent", RID_PTREXTENT, 0 },
+ { "__ptrextent__", RID_PTREXTENT, 0 },
+ { "__ptrvalue", RID_PTRVALUE, 0 },
+ { "__ptrvalue__", RID_PTRVALUE, 0 },
+ { "__real", RID_REALPART, 0 },
+ { "__real__", RID_REALPART, 0 },
+ { "__restrict", RID_RESTRICT, 0 },
+ { "__restrict__", RID_RESTRICT, 0 },
+ { "__signed", RID_SIGNED, 0 },
+ { "__signed__", RID_SIGNED, 0 },
+ { "__typeof", RID_TYPEOF, 0 },
+ { "__typeof__", RID_TYPEOF, 0 },
+ { "__unbounded", RID_UNBOUNDED, 0 },
+ { "__unbounded__", RID_UNBOUNDED, 0 },
+ { "__volatile", RID_VOLATILE, 0 },
+ { "__volatile__", RID_VOLATILE, 0 },
+ { "asm", RID_ASM, 0 },
+ { "auto", RID_AUTO, 0 },
+ { "break", RID_BREAK, 0 },
+ { "case", RID_CASE, 0 },
+ { "char", RID_CHAR, 0 },
+ { "const", RID_CONST, 0 },
+ { "continue", RID_CONTINUE, 0 },
+ { "default", RID_DEFAULT, 0 },
+ { "do", RID_DO, 0 },
+ { "double", RID_DOUBLE, 0 },
+ { "else", RID_ELSE, 0 },
+ { "enum", RID_ENUM, 0 },
+ { "extern", RID_EXTERN, 0 },
+ { "float", RID_FLOAT, 0 },
+ { "for", RID_FOR, 0 },
+ { "goto", RID_GOTO, 0 },
+ { "if", RID_IF, 0 },
+ { "inline", RID_INLINE, 0 },
+ { "int", RID_INT, 0 },
+ { "long", RID_LONG, 0 },
+ { "register", RID_REGISTER, 0 },
+ { "restrict", RID_RESTRICT, 0 },
+ { "return", RID_RETURN, 0 },
+ { "short", RID_SHORT, 0 },
+ { "signed", RID_SIGNED, 0 },
+ { "sizeof", RID_SIZEOF, 0 },
+ { "static", RID_STATIC, 0 },
+ { "struct", RID_STRUCT, 0 },
+ { "switch", RID_SWITCH, 0 },
+ { "typedef", RID_TYPEDEF, 0 },
+ { "typeof", RID_TYPEOF, 0 },
+ { "union", RID_UNION, 0 },
+ { "unsigned", RID_UNSIGNED, 0 },
+ { "void", RID_VOID, 0 },
+ { "volatile", RID_VOLATILE, 0 },
+ { "while", RID_WHILE, 0 },
+};
+#define N_reswords (sizeof reswords / sizeof (struct resword))
+
+/* Init enough to allow the C decl code to work, then clean up
+ afterwards. */
+
+void
+treelang_init_decl_processing ()
+{
+ unsigned int i;
+ tree id;
+
+ /* It is not necessary to register ridpointers as a GC root, because
+ all the trees it points to are permanently interned in the
+ get_identifier hash anyway. */
+ ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree));
+
+ for (i = 0; i < N_reswords; i++)
+ {
+ id = get_identifier (reswords[i].word);
+ C_RID_CODE (id) = reswords[i].rid;
+ C_IS_RESERVED_WORD (id) = 1;
+ ridpointers [(int) reswords[i].rid] = id;
+ }
+
+ c_init_decl_processing ();
+
+ /* ix86_return_pops_args takes the type of these so need to patch
+ their own type as themselves. */
+
+ for (i = 0; i < itk_none; i++)
+ {
+ if (integer_types[i])
+ TREE_TYPE (integer_types [i]) = integer_types[i];
+ }
+
+ /* Probably these ones too. */
+ TREE_TYPE (float_type_node) = float_type_node;
+ TREE_TYPE (double_type_node) = double_type_node;
+ TREE_TYPE (long_double_type_node) = long_double_type_node;
+
+}
+
+/* Save typing debug_tree all the time. Dump a tree T pretty and
+ concise. */
+
+void dt (tree t);
+
+void
+dt (tree t)
+{
+ debug_tree (t);
+}
diff --git a/gcc/treelang/treetree.h b/gcc/treelang/treetree.h
new file mode 100644
index 0000000..24b72e3
--- /dev/null
+++ b/gcc/treelang/treetree.h
@@ -0,0 +1,101 @@
+/*
+
+ TREELANG Compiler definitions for interfacing to treetree.c
+ (compiler back end interface).
+
+ Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002 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
+ 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!
+
+ ---------------------------------------------------------------------------
+
+ Written by Tim Josling 1999, 2000, 2001, based in part on other
+ parts of the GCC compiler.
+
+ */
+
+/* Parameter list passed to back end. */
+struct tree_parameter_list
+{
+ struct tree_parameter_list* next; /* Next entry. */
+ int type; /* See numeric types below. */
+ unsigned char* variable_name; /* Name. */
+ tree* where_to_put_var_tree; /* Where to save decl. */
+};
+
+tree tree_code_init_parameters (void);
+tree tree_code_add_parameter (tree list, tree proto_exp, tree exp);
+tree tree_code_get_integer_value (unsigned char *chars, unsigned int length);
+void tree_code_generate_return (tree type, tree exp);
+void tree_ggc_storage_always_used (void *m);
+tree tree_code_get_expression (unsigned int exp_type, tree type, tree op1, tree op2, tree op3);
+tree tree_code_get_numeric_type (unsigned int size1, unsigned int sign1);
+void tree_code_create_function_initial (tree prev_saved,
+ unsigned char* filename, int lineno,
+ struct tree_parameter_list* parms);
+void tree_code_create_function_wrapup (unsigned char* filename, int lineno);
+tree tree_code_create_function_prototype (unsigned char* chars,
+ unsigned int storage_class,
+ unsigned int ret_type,
+ struct tree_parameter_list* parms,
+ unsigned char* filename,
+ int lineno);
+tree tree_code_create_variable (unsigned int storage_class,
+ unsigned char* chars,
+ unsigned int length,
+ unsigned int expression_type,
+ tree init,
+ unsigned char* filename,
+ int lineno);
+void tree_code_output_expression_statement (tree code, unsigned char* filename, int lineno);
+tree get_type_for_numeric_type (unsigned int numeric_type);
+void tree_code_if_start (tree exp, unsigned char* filename, int lineno);
+void tree_code_if_else (unsigned char* filename, int lineno);
+void tree_code_if_end (unsigned char* filename, int lineno);
+tree tree_code_get_type (int type_num);
+void treelang_init_decl_processing (void);
+void treelang_finish (void);
+const char * treelang_init (const char* filename);
+int treelang_decode_option (int, char **);
+void treelang_parse_file (int debug_flag);
+void push_var_level (void);
+void pop_var_level (void);
+
+/* Storage modes. */
+#define STATIC_STORAGE 0
+#define AUTOMATIC_STORAGE 1
+#define EXTERNAL_REFERENCE_STORAGE 2
+#define EXTERNAL_DEFINITION_STORAGE 3
+
+
+/* Numeric types. */
+#define SIGNED_CHAR 1
+#define UNSIGNED_CHAR 2
+#define SIGNED_INT 3
+#define UNSIGNED_INT 4
+#define VOID_TYPE 5
+
+
+#define EXP_PLUS 0 /* Addition expression. */
+#define EXP_REFERENCE 1 /* Variable reference. */
+#define EXP_ASSIGN 2 /* Assignment. */
+#define EXP_FUNCTION_INVOCATION 3 /* Call function. */
+#define EXP_MINUS 4 /* Subtraction. */
+#define EXP_EQUALS 5 /* Equality test. */