fixes to get treelang working with gengtype.c and PCH

Tim Josling tej@melbpc.org.au
Sat Jun 8 20:40:00 GMT 2002


This requires a fix to gengtype.c which has languages hard coded in three places, for which I need approval plelease. Also changes to the treelang directory, for which I do not.

Rather than have to manually patch gengtype.c this file every week I also added cobol to the list of languages in gengtype.c.

A more permanent solution to this is desirable. The gengtype.c documentation also needs some work.

One side benefit of this change is that the treelang productions and tokens are all in one big union as in the rest of GCC.

I have withdrawn the documentation changes I previously submitted.

Tim Josling
-------------- next part --------------
diff -c -p -r -N -X treelang.diff.excl cvs.copy/gcc/gcc/ChangeLog cvs/gcc/gcc/ChangeLog
*** cvs.copy/gcc/gcc/ChangeLog	Sat Jun  8 06:58:25 2002
--- cvs/gcc/gcc/ChangeLog	Sun Jun  9 12:06:22 2002
***************
*** 1,3 ****
--- 1,11 ----
+ 2002-06-09  Tim Josling  <tej@melbpc.org.au>
+ 
+ 	* gengtype.c (unnamed enum containing BASE_FILE_*): Add languages
+ 	TREELANG and COBOL.
+ 	(lang_names): Add treelang and cobol.
+ 	(get_file_basename): Add code to support treelang and cobol as
+ 	4th and 5th users of c-common.c.
+ 
  2002-06-07  Akim Demaille  <akim@epita.fr>
  
  	* gengtype-yacc.y (optionseqopt): Add the ending `;' to the action.
diff -c -p -r -N -X treelang.diff.excl cvs.copy/gcc/gcc/treelang/ChangeLog cvs/gcc/gcc/treelang/ChangeLog
*** cvs.copy/gcc/gcc/treelang/ChangeLog	Wed Jun  5 11:53:27 2002
--- cvs/gcc/gcc/treelang/ChangeLog	Sun Jun  9 09:54:51 2002
***************
*** 1,3 ****
--- 1,59 ----
+ 2002-06-09  Tim Josling  <tej@melbpc.org.au>
+ 
+         Cleanup 
+ 
+ 	* Make-lang.in (check-treelang). Add. Remove direct dependency of
+ 	'check' on 'treelang.check' as redundant.
+ 	
+ 	PCH Garbage collection regime (gengtypes.c) phase 1.
+ 	
+ 	* Make-lang.in (treelang/tree1.o). Depend on gt-treelang-tree1.h
+ 	gt-treelang-treelang.h gtype-treelang.h.
+ 	(gt-treelang-tree1.h) Depend on s-gtype.
+ 	(gt-treelang-treelang.h) Depend on s-gtype.
+ 	(gtype-treelang.h) Depend on s-gtype.
+ 
+ 	* config-lang.in (gtfiles): Define. 
+ 
+ 	* lex.l (main): Remove '#if 0' dead code.
+ 	(main): Move undef of IN_GCC so define of tree typedef works.
+ 	(all): Replace token and production by prod_token_parm_item.
+ 	
+ 	* parse.y
+ 	(all): Replace token and production by prod_token_parm_item.
+ 
+ 	* tree1.c (main): Remove include of "output.h".
+ 	(symbol_table): Add GTY details.
+ 	(symbol_table_ggc): Remove.
+ 	(treelang_init): Remove root definitions for garage collection.
+ 	(mark_production_used): Remove.
+ 	(mark_token_used): Remove.
+ 	(main, at end): include generated garage collection routines.
+ 
+ 	* treelang.h (category_enum ): Add parameter_category.
+ 	(all): Replace token and production and parameters by union
+ 	prod_token_parm_item containing production_part, token_part,
+ 	parameter_part.
+ 	(STATIC_STORAGE AUTOMATIC_STORAGE EXTERNAL_REFERENCE_STORAGE
+ 	EXTERNAL_DEFINITION_STORAGE SIGNED_CHAR UNSIGNED_CHAR SIGNED_INT
+ 	UNSIGNED_INT VOID_TYPE EXP_PLUS EXP_REFERENCE EXP_ASSIGN
+ 	EXP_FUNCTION_INVOCATION EXP_MINUS EXP_EQUALS): Move here from
+ 	treetree.h.
+ 
+ 	* treetree.c
+ 	(tm_p.h): Do not include.
+ 	(ansidecl.h): Move include after config.h.
+ 	(treelang.h): Include it.
+ 	(ADDROOT): Remove.
+ 	(all): Replace token, production and parameter by prod_token_parm_item.
+ 	(tree_parameter_list): Move to treelang.h as part of
+ 	prod_token_parm_item.
+ 	(STATIC_STORAGE AUTOMATIC_STORAGE EXTERNAL_REFERENCE_STORAGE
+ 	EXTERNAL_DEFINITION_STORAGE SIGNED_CHAR UNSIGNED_CHAR SIGNED_INT
+ 	UNSIGNED_INT VOID_TYPE EXP_PLUS EXP_REFERENCE EXP_ASSIGN
+ 	EXP_FUNCTION_INVOCATION EXP_MINUS EXP_EQUALS): Move from here to
+ 	treelang.h.
+ 
  2002-06-05  Tim Josling  <tej@melbpc.org.au>
  
  	* treetree.c (cpp_assert): Add.
diff -c -p -r -N -X treelang.diff.excl cvs.copy/gcc/gcc/gengtype.c cvs/gcc/gcc/gengtype.c
*** cvs.copy/gcc/gcc/gengtype.c	Sat Jun  8 06:58:35 2002
--- cvs/gcc/gcc/gengtype.c	Sat Jun  8 21:57:49 2002
*************** FILE * header_file;
*** 501,510 ****
  enum {
    BASE_FILE_C,
    BASE_FILE_OBJC,
!   BASE_FILE_CPLUSPLUS
  };
  static const char *lang_names[] = {
!   "c", "objc", "cp", "f", "ada", "java"
  };
  #define NUM_BASE_FILES (sizeof (lang_names) / sizeof (lang_names[0]))
  FILE *base_files[NUM_BASE_FILES];
--- 501,512 ----
  enum {
    BASE_FILE_C,
    BASE_FILE_OBJC,
!   BASE_FILE_CPLUSPLUS,
!   BASE_FILE_TREELANG,
!   BASE_FILE_COBOL
  };
  static const char *lang_names[] = {
!   "c", "objc", "cp", "treelang", "cobol", "f", "ada", "java"
  };
  #define NUM_BASE_FILES (sizeof (lang_names) / sizeof (lang_names[0]))
  FILE *base_files[NUM_BASE_FILES];
*************** get_file_basename (f)
*** 609,614 ****
--- 611,620 ----
      basename -= 5;
    else if (startswith (basename - f, basename-5, "objc/"))
      basename -= 5;
+   else if (startswith (basename - f, basename-9, "treelang/"))
+     basename -= 9;
+   else if (startswith (basename - f, basename-5, "cobol/"))
+     basename -= 6;
  
    return basename;
  }
*************** get_base_file_bitmap (input_file)
*** 644,649 ****
--- 650,658 ----
  	   || strcmp (basename, "c-decl.c") == 0
  	   || strcmp (basename, "c-objc-common.c") == 0)
      return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC;
+   else if (startswith (len, basename, "c-common.c"))
+     return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC| 1 << BASE_FILE_CPLUSPLUS
+       |  1 << BASE_FILE_TREELANG | 1 << BASE_FILE_COBOL;
    else if (startswith (len, basename, "c-"))
      return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC | 1 << BASE_FILE_CPLUSPLUS;
    else
diff -c -p -r -N -X treelang.diff.excl cvs.copy/gcc/gcc/treelang/Make-lang.in cvs/gcc/gcc/treelang/Make-lang.in
*** cvs.copy/gcc/gcc/treelang/Make-lang.in	Sun May 19 07:30:28 2002
--- cvs/gcc/gcc/treelang/Make-lang.in	Sun Jun  9 06:57:57 2002
*************** tree1$(exeext): treelang/tree1.o treelan
*** 90,96 ****
  
  # 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
--- 90,97 ----
  
  # object file makes
  
! treelang/tree1.o: $(srcdir)/treelang/tree1.c $(srcdir)/treelang/treelang.h $(srcdir)/treelang/parse.h\
! 	gt-treelang-tree1.h gt-treelang-treelang.h gtype-treelang.h
  	$(CC) -o $@ -c $(ALL_CFLAGS) $(INCLUDES) $< 
  
  treelang/treetree.o: $(srcdir)/treelang/treetree.c $(srcdir)/treelang/treetree.h
*************** $(srcdir)/treelang/parse.c $(srcdir)/tre
*** 114,119 ****
--- 115,122 ----
  	--output=$(srcdir)/treelang/parse.c --defines
  # -v
  
+ gt-treelang-tree1.h gt-treelang-treelang.h gtype-treelang.h : s-gtype; @true
+ 
  #
  # Build hooks:
  
*************** treelang.distdir:
*** 246,252 ****
  # test hook
  # the other languages are hard coded in the main makefile.in - that seems to be wrong 
  
! check: treelang.check
  
  TESTSUITEDIR = testsuite
  
--- 249,255 ----
  # test hook
  # the other languages are hard coded in the main makefile.in - that seems to be wrong 
  
! check-treelang: treelang.check
  
  TESTSUITEDIR = testsuite
  
diff -c -p -r -N -X treelang.diff.excl cvs.copy/gcc/gcc/treelang/config-lang.in cvs/gcc/gcc/treelang/config-lang.in
*** cvs.copy/gcc/gcc/treelang/config-lang.in	Sun May  5 14:24:18 2002
--- cvs/gcc/gcc/treelang/config-lang.in	Sat Jun  8 19:20:21 2002
*************** stagestuff=
*** 35,37 ****
--- 35,40 ----
  diff_excludes="-x lex.c -x parse.c -x parse.h"
  headers=
  build_by_default="no"
+ 
+ gtfiles="\$(srcdir)/treelang/tree1.c \$(srcdir)/treelang/treelang.h"
+ 
diff -c -p -r -N -X treelang.diff.excl cvs.copy/gcc/gcc/treelang/lex.l cvs/gcc/gcc/treelang/lex.l
*** cvs.copy/gcc/gcc/treelang/lex.l	Sun May  5 14:24:18 2002
--- cvs/gcc/gcc/treelang/lex.l	Sat Jun  8 20:38:46 2002
***************
*** 33,54 ****
   
  */
  
- /* 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"
--- 33,50 ----
   
  */
  
  #include <stdio.h>
  #include <memory.h>
  #include "ansidecl.h"
  #include "config.h"
  #include "system.h"
+ 
+ /* Avoid poisoned malloc problem.  */
+ #undef IN_GCC
+ 
+ #include "config.h"
  #include "diagnostic.h"
+ #include "tree.h"
  
  /* Token defs.  */
  #include "treelang.h"
*************** static void dump_lex_value (int lexret);
*** 81,89 ****
  %%
  
   { 
!    yylval = my_malloc (sizeof (struct token));
!    ((struct token*)yylval)->lineno = next_tree_lineno;
!    ((struct token*)yylval)->charno = next_tree_charno;
   }
  
  [ \n]+ {
--- 77,86 ----
  %%
  
   { 
!    /* Should really allocate only what we need. lll;.  */
!    yylval = my_malloc (sizeof (struct prod_token_parm_item));
!    ((struct prod_token_parm_item *)yylval)->tp.tok.lineno = next_tree_lineno;
!    ((struct prod_token_parm_item *)yylval)->tp.tok.charno = next_tree_charno;
   }
  
  [ \n]+ {
*************** static void dump_lex_value (int lexret);
*** 221,228 ****
  [^\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++;
  }
  
--- 218,225 ----
  [^\n]  {
    update_lineno_charno ();
    fprintf (stderr, "%s:%i:%i: Unrecognized character %c\n", in_fname, 
!            ((struct prod_token_parm_item *)yylval)->tp.tok.lineno, 
!            ((struct prod_token_parm_item *)yylval)->tp.tok.charno, yytext[0]);
    errorcount++;
  }
  
*************** update_lineno_charno (void)
*** 238,245 ****
     /* 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' ) 
--- 235,242 ----
     /* 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 prod_token_parm_item *)yylval)->tp.tok.lineno = next_tree_lineno;
!    ((struct prod_token_parm_item *)yylval)->tp.tok.charno = next_tree_charno;
     for ( yyl = 0; yyl < yyleng; ++yyl ) 
        {
           if ( yytext[yyl] == '\n' ) 
*************** update_lineno_charno (void)
*** 257,272 ****
  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
--- 254,269 ----
  void 
  update_yylval (int a)
  {
!   struct prod_token_parm_item * tok;
    tok=yylval;
    
    tok->category = token_category;
    tok->type = a;
!   tok->tp.tok.length = yyleng;
    /* Have to copy yytext as it is just a ptr into the buffer at the
       moment.  */
!   tok->tp.tok.chars = my_malloc (yyleng + 1);
!   memcpy (tok->tp.tok.chars, yytext, yyleng);
  }
  
  /* Trace the value LEXRET and the position and token details being
*************** dump_lex_value (int lexret) 
*** 277,285 ****
  {
    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]);
--- 274,282 ----
  {
    int ix;
    fprintf (stderr, " %d l:%d c:%d ln:%d text=", lexret,
!          ((struct prod_token_parm_item *) yylval)->tp.tok.lineno,
!          ((struct prod_token_parm_item *) yylval)->tp.tok.charno,
!          ((struct prod_token_parm_item *) yylval)->tp.tok.length);
    for (ix = 0; ix < yyleng; ix++) 
      {
        fprintf (stderr, "%c", yytext[ix]);
diff -c -p -r -N -X treelang.diff.excl cvs.copy/gcc/gcc/treelang/parse.y cvs/gcc/gcc/treelang/parse.y
*** cvs.copy/gcc/gcc/treelang/parse.y	Sun May  5 14:24:18 2002
--- cvs/gcc/gcc/treelang/parse.y	Sat Jun  8 20:46:36 2002
*************** static void yyerror (const char *error_m
*** 71,86 ****
  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;
  
  %}
  
--- 71,86 ----
  int yylex (void);
  int yyparse (void);
  void print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value);
! static struct prod_token_parm_item *reverse_prod_list (struct prod_token_parm_item *old_first);
! static void ensure_not_void (unsigned int type, struct prod_token_parm_item* name);
! static int check_type_match (int type_num, struct prod_token_parm_item *exp);
! static int get_common_type (struct prod_token_parm_item *type1, struct prod_token_parm_item *type2);
! static struct prod_token_parm_item *make_integer_constant (struct prod_token_parm_item* value);
! static void set_storage (struct prod_token_parm_item *prod);
  
  /* File global variables.  */
  
! static struct prod_token_parm_item *current_function=NULL;
  
  %}
  
*************** variable_def {
*** 171,184 ****
  
  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))
      {
--- 171,184 ----
  
  variable_def:
  storage typename NAME init_opt SEMICOLON {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *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 prod_token_parm_item*)EXPRESSION_TYPE (prod)));
    ensure_not_void (NUMERIC_TYPE (prod), tok);
    if (insert_tree_name (prod))
      {
*************** storage typename NAME init_opt SEMICOLON
*** 189,214 ****
  
    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 ();
  }
  ;
--- 189,214 ----
  
    if (VAR_INIT (prod))
      {
!       if (! ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.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->tp.tok.lineno, tok->tp.tok.charno);
          print_token (stderr, 0, tok);
          errorcount++;
          YYERROR;
        }
      }
!   prod->tp.pro.code = tree_code_create_variable
      (STORAGE_CLASS (prod), 
!      ((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.chars,
!      ((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.length,
       NUMERIC_TYPE (prod),
!      VAR_INIT (prod)? ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code:NULL,
       in_fname,
!      tok->tp.tok.lineno);
!   if (!prod->tp.pro.code) 
      abort ();
  }
  ;
*************** STATIC
*** 222,235 ****
  
  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))
      {
--- 222,235 ----
  
  parameter:
  typename NAME {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
!   struct prod_token_parm_item *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 prod_token_parm_item*)EXPRESSION_TYPE (prod)));
    ensure_not_void (NUMERIC_TYPE (prod), tok);
    if (insert_tree_name (prod))
      {
*************** typename NAME {
*** 243,261 ****
  
  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;
--- 243,261 ----
  
  function_prototype:
  storage typename NAME LEFT_PARENTHESIS parameters RIGHT_PARENTHESIS SEMICOLON {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
!   struct prod_token_parm_item *type;
!   struct prod_token_parm_item* first_parms;
!   struct prod_token_parm_item* last_parms;
!   struct prod_token_parm_item* this_parms;
!   struct prod_token_parm_item *this_parm;
!   struct prod_token_parm_item *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 prod_token_parm_item*)EXPRESSION_TYPE (prod)));
    PARAMETERS (prod) = reverse_prod_list ($5); 
    insert_tree_name (prod);
    STORAGE_CLASS_TOKEN (prod) = $1;
*************** storage typename NAME LEFT_PARENTHESIS p
*** 268,274 ****
        
      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;
--- 268,274 ----
        
      case AUTOMATIC_STORAGE:
        fprintf (stderr, "%s:%i:%i: A function cannot be automatic\n", in_fname, 
!               tok->tp.tok.lineno, tok->tp.tok.charno);
        print_token (stderr, 0, tok);
        errorcount++;
        YYERROR;
*************** storage typename NAME LEFT_PARENTHESIS p
*** 281,287 ****
    /* 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 ();
--- 281,287 ----
    /* 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->tp.pro.next)
      {
        if (this_parm->category != production_category)
          abort ();
*************** storage typename NAME LEFT_PARENTHESIS p
*** 290,303 ****
          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
--- 290,303 ----
          abort ();
        if (this_parm_var->category != production_category)
          abort ();
!       this_parms = my_malloc (sizeof (struct prod_token_parm_item));
!       if (!this_parm_var->tp.pro.main_token)
          abort ();
!       this_parms->tp.par.variable_name = this_parm_var->tp.pro.main_token->tp.tok.chars;
!       this_parms->type = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (this_parm_var)));
        if (last_parms)
          {
!           last_parms->tp.par.next = this_parms;
            last_parms = this_parms;
          }
        else
*************** storage typename NAME LEFT_PARENTHESIS p
*** 305,359 ****
            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;
  }
  ;
--- 305,360 ----
            first_parms = this_parms;
            last_parms = this_parms;
          }
!       this_parms->tp.par.where_to_put_var_tree = 
!         & (( (struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code);
      }
    FIRST_PARMS (prod) = first_parms;
  
!   prod->tp.pro.code = tree_code_create_function_prototype
!     (tok->tp.tok.chars, STORAGE_CLASS (prod), NUMERIC_TYPE (type),
!      first_parms, in_fname, tok->tp.tok.lineno);
  
  }
  ;
  
  function:
  NAME LEFT_BRACE {
!   struct prod_token_parm_item *proto;
!   struct prod_token_parm_item search_prod;
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *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->tp.tok.lineno, tok->tp.tok.charno);
        print_token (stderr, 0, tok);
        errorcount++;
        YYERROR;
      }
!   if (!proto->tp.pro.code)
      abort ();
    tree_code_create_function_initial
!     (proto->tp.pro.code, in_fname, tok->tp.tok.lineno,
       FIRST_PARMS (current_function));
  
    /* Check all the parameters have code.  */
    for (this_parm = PARAMETERS (proto);
         this_parm;
!        this_parm = this_parm->tp.pro.next)
      {
!       if (! (struct prod_token_parm_item*)VARIABLE (this_parm))
          abort ();
!       if (! (( (struct prod_token_parm_item*)VARIABLE (this_parm))->tp.pro.code))
          abort ();
      }
  }
  variable_defs_opt statements_opt RIGHT_BRACE {
!   struct prod_token_parm_item* tok;
    tok = $1;
!   tree_code_create_function_wrapup (in_fname, tok->tp.tok.lineno);
    current_function = NULL;
  }
  ;
*************** variable_def {
*** 387,434 ****
  
  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;
  }
  ;
--- 388,435 ----
  
  typename:
  INT {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
    tok = $1;
    prod = make_production (PROD_TYPE_NAME, tok);
    NUMERIC_TYPE (prod) = SIGNED_INT;
!   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
    $$ = prod;
  }
  |UNSIGNED INT {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
    tok = $1;
    prod = make_production (PROD_TYPE_NAME, tok);
    NUMERIC_TYPE (prod) = UNSIGNED_INT;
!   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
    $$ = prod;
  }
  |CHAR {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
    tok = $1;
    prod = make_production (PROD_TYPE_NAME, tok);
    NUMERIC_TYPE (prod) = SIGNED_CHAR;
!   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
    $$ = prod;
  }
  |UNSIGNED CHAR {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
    tok = $1;
    prod = make_production (PROD_TYPE_NAME, tok);
    NUMERIC_TYPE (prod) = UNSIGNED_CHAR;
!   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
    $$ = prod;
  }
  |VOID {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
    tok = $1;
    prod = make_production (PROD_TYPE_NAME, tok);
    NUMERIC_TYPE (prod) = VOID_TYPE;
!   prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
    $$ = prod;
  }
  ;
*************** parameter {
*** 439,447 ****
    $$ = $1;
  }
  |parameters COMMA parameter {
!   struct production *prod1;
    prod1 = $3;
!   prod1->next = $1; /* Insert in reverse order.  */
    $$ = prod1;
  }
  ;
--- 440,448 ----
    $$ = $1;
  }
  |parameters COMMA parameter {
!   struct prod_token_parm_item *prod1;
    prod1 = $3;
!   prod1->tp.pro.next = $1; /* Insert in reverse order.  */
    $$ = prod1;
  }
  ;
*************** statement {
*** 457,465 ****
  
  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.  */
--- 458,466 ----
  
  statement:
  expression SEMICOLON {
!   struct prod_token_parm_item *exp;
    exp = $1;
!   tree_code_output_expression_statement (exp->tp.pro.code, in_fname, exp->tp.pro.main_token->tp.tok.lineno);
  }
  |return SEMICOLON {
    /* Nothing to do.  */
*************** expression SEMICOLON {
*** 471,537 ****
  
  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);
            }
        }
  }
--- 472,538 ----
  
  if_statement:
  IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *exp;
    tok = $1;
    exp = $3;
!   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
!   tree_code_if_start (exp->tp.pro.code, in_fname, tok->tp.tok.lineno);
  }
  LEFT_BRACE statements_opt RIGHT_BRACE {
    /* Just let the statements flow.  */
  }
  ELSE {
!   struct prod_token_parm_item* tok;
    tok = $1;
!   tree_code_if_else (in_fname, tok->tp.tok.lineno);
  }
  LEFT_BRACE statements_opt RIGHT_BRACE {
!   struct prod_token_parm_item* tok;
    tok = $12;
!   tree_code_if_end (in_fname, tok->tp.tok.lineno);
  }
  ;
  
  
  return:
  RETURN expression_opt {
!   struct prod_token_parm_item *type_prod;
!   struct prod_token_parm_item* 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->tp.pro.code, NULL);
      else
        {
          fprintf (stderr, "%s:%i:%i: Redundant expression in return\n", in_fname, 
!                 ret_tok->tp.tok.lineno, ret_tok->tp.tok.charno);
          print_token (stderr, 0, ret_tok);
          errorcount++;
!         tree_code_generate_return (type_prod->tp.pro.code, NULL);
        }
    else
      if ($2 == NULL)
        {
          fprintf (stderr, "%s:%i:%i: Expression missing in return\n", in_fname, 
!                 ret_tok->tp.tok.lineno, ret_tok->tp.tok.charno); 
          print_token (stderr, 0, ret_tok);
          errorcount++;
        }
      else
        {
!         struct prod_token_parm_item *exp;
          exp = $2;
          /* Check same type.  */
          if (check_type_match (NUMERIC_TYPE (type_prod), $2))
            {
!             if (!type_prod->tp.pro.code)
                abort ();
!             if (!exp->tp.pro.code)
                abort ();
              /* Generate the code. */
!             tree_code_generate_return (type_prod->tp.pro.code, exp->tp.pro.code);
            }
        }
  }
*************** expression_opt:
*** 542,550 ****
    $$ = 0;
  }
  |expression {
!   struct production *exp;
    exp = $1;
!   if (!exp->code)
      abort ();
    
    $$ = $1;
--- 543,551 ----
    $$ = 0;
  }
  |expression {
!   struct prod_token_parm_item *exp;
    exp = $1;
!   if (!exp->tp.pro.code)
      abort ();
    
    $$ = $1;
*************** INTEGER {
*** 559,575 ****
    $$ = $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))
--- 560,576 ----
    $$ = $1;
  }
  |expression PLUS expression {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
!   struct prod_token_parm_item *op1;
!   struct prod_token_parm_item *op2;
    tree type;
    
    op1 = $1;
    op2 = $3;
    tok = $2;
!   ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
!   ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
    prod = make_production (PROD_PLUS_EXPRESSION, tok);
    NUMERIC_TYPE (prod) = get_common_type (op1, op2);
    if (!NUMERIC_TYPE (prod))
*************** INTEGER {
*** 582,603 ****
        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);
--- 583,604 ----
        OP1 (prod) = $1;
        OP2 (prod) = $3;
        
!       prod->tp.pro.code = tree_code_get_expression
!         (EXP_PLUS, type, op1->tp.pro.code, op2->tp.pro.code, NULL);
      }
    $$ = prod;
  }
  |expression MINUS expression %prec PLUS {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
!   struct prod_token_parm_item *op1;
!   struct prod_token_parm_item *op2;
    tree type;
    
    op1 = $1;
    op2 = $3;
!   ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
!   ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
    tok = $2;
    prod = make_production (PROD_PLUS_EXPRESSION, tok);
    NUMERIC_TYPE (prod) = get_common_type (op1, op2);
*************** INTEGER {
*** 611,632 ****
        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;
--- 612,633 ----
        OP1 (prod) = $1;
        OP2 (prod) = $3;
        
!       prod->tp.pro.code = tree_code_get_expression (EXP_MINUS, 
!                                           type, op1->tp.pro.code, op2->tp.pro.code, NULL);
      }
    $$ = prod;
  }
  |expression EQUALS expression {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
!   struct prod_token_parm_item *op1;
!   struct prod_token_parm_item *op2;
    tree type;
    
    op1 = $1;
    op2 = $3;
!   ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
!   ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
    tok = $2;
    prod = make_production (PROD_PLUS_EXPRESSION, tok);
    NUMERIC_TYPE (prod) = SIGNED_INT;
*************** INTEGER {
*** 640,661 ****
        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))
--- 641,662 ----
        OP1 (prod) = $1;
        OP2 (prod) = $3;
        
!       prod->tp.pro.code = tree_code_get_expression (EXP_EQUALS, 
!                                           type, op1->tp.pro.code, op2->tp.pro.code, NULL);
      }
    $$ = prod;
  }
  |variable_ref ASSIGN expression {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
!   struct prod_token_parm_item *op1;
!   struct prod_token_parm_item *op2;
    tree type;
    
    op1 = $1;
    op2 = $3;
    tok = $2;
!   ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
    prod = make_production (PROD_ASSIGN_EXPRESSION, tok);
    NUMERIC_TYPE (prod) = NUMERIC_TYPE (op1);
    if (!NUMERIC_TYPE (prod))
*************** INTEGER {
*** 667,674 ****
          abort ();
        OP1 (prod) = $1;
        OP2 (prod) = $3;
!       prod->code = tree_code_get_expression (EXP_ASSIGN, 
!                                           type, op1->code, op2->code, NULL);
      }
    $$ = prod;
  }
--- 668,675 ----
          abort ();
        OP1 (prod) = $1;
        OP2 (prod) = $3;
!       prod->tp.pro.code = tree_code_get_expression (EXP_ASSIGN, 
!                                           type, op1->tp.pro.code, op2->tp.pro.code, NULL);
      }
    $$ = prod;
  }
*************** INTEGER {
*** 679,691 ****
  
  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;
--- 680,692 ----
  
  function_invocation:
  NAME LEFT_PARENTHESIS expressions_with_commas RIGHT_PARENTHESIS {
!   struct prod_token_parm_item *prod;
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item search_prod;
!   struct prod_token_parm_item *proto;
!   struct prod_token_parm_item *exp;
!   struct prod_token_parm_item *exp_proto;
!   struct prod_token_parm_item *var;
    int exp_proto_count;
    int exp_count;
    tree parms;
*************** NAME LEFT_PARENTHESIS expressions_with_c
*** 700,706 ****
    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;
--- 701,707 ----
    if (!proto)
      {
        fprintf (stderr, "%s:%i:%i: Function prototype not found\n", in_fname, 
!               tok->tp.tok.lineno, tok->tp.tok.charno);
        print_token (stderr, 0, tok);
        errorcount++;
        YYERROR;
*************** NAME LEFT_PARENTHESIS expressions_with_c
*** 709,724 ****
    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;
--- 710,725 ----
    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->tp.pro.next)
      exp_proto_count++;
  
!   for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->tp.pro.next)
      exp_count++;
  
    if (exp_count !=  exp_proto_count)
      {
        fprintf (stderr, "%s:%i:%i: expression count mismatch with prototype\n", in_fname, 
!               tok->tp.tok.lineno, tok->tp.tok.charno);
        print_token (stderr, 0, tok);
        errorcount++;
        YYERROR;
*************** NAME LEFT_PARENTHESIS expressions_with_c
*** 726,775 ****
    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;
--- 727,776 ----
    parms = tree_code_init_parameters ();
    for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
         exp_proto;
!        exp = exp->tp.pro.next, exp_proto = exp_proto->tp.pro.next)
    {
      if (!exp)
        abort ();
      if (!exp_proto)
        abort ();
!     if (!exp->tp.pro.code)
        abort ();
      var = VARIABLE (exp_proto);
      if (!var)
        abort ();
!     if (!var->tp.pro.code)
        abort ();
!     parms = tree_code_add_parameter (parms, var->tp.pro.code, exp->tp.pro.code);
    }
    type = get_type_for_numeric_type (NUMERIC_TYPE (prod));
!   prod->tp.pro.code = tree_code_get_expression
!     (EXP_FUNCTION_INVOCATION, type, proto->tp.pro.code, parms, NULL);
    $$ = prod;
  }
  ;
  
  expressions_with_commas:
  expression {
!   struct prod_token_parm_item *exp;
    exp = $1;
!   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
    $$ = $1;
  }
  |expressions_with_commas COMMA expression {
!   struct prod_token_parm_item *exp;
    exp = $3;
!   ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
!   exp->tp.pro.next = $1; /* Reverse order.  */
    $$ = exp;
  }
  ;
  
  variable_ref:
  NAME {
!   struct prod_token_parm_item search_prod;
!   struct prod_token_parm_item *prod;
!   struct prod_token_parm_item *symbol_table_entry;
!   struct prod_token_parm_item* tok;
    tree type;
  
    tok = $1;
*************** NAME {
*** 778,784 ****
    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;
--- 779,785 ----
    if (!symbol_table_entry)
      {
        fprintf (stderr, "%s:%i:%i: Variable referred to but not defined\n", in_fname, 
!               tok->tp.tok.lineno, tok->tp.tok.charno);
        print_token (stderr, 0, tok);
        errorcount++;
        YYERROR;
*************** NAME {
*** 791,798 ****
      YYERROR;
    OP1 (prod) = $1;
    
!   prod->code = tree_code_get_expression (EXP_REFERENCE, type, 
!                                       symbol_table_entry->code, NULL, NULL);
    $$ = prod;
  }
  ;
--- 792,799 ----
      YYERROR;
    OP1 (prod) = $1;
    
!   prod->tp.pro.code = tree_code_get_expression (EXP_REFERENCE, type, 
!                                       symbol_table_entry->tp.pro.code, NULL, NULL);
    $$ = prod;
  }
  ;
*************** INTEGER {
*** 824,836 ****
  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, "\"");
  }
  
--- 825,837 ----
  void
  print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value) 
  {
!   struct prod_token_parm_item *tok;
    unsigned int  ix;
  
    tok  =  value;
!   fprintf (file, "%d \"", tok->tp.tok.lineno);
!   for (ix  =  0; ix < tok->tp.tok.length; ix++)
!     fprintf (file, "%c", tok->tp.tok.chars[ix]);
    fprintf (file, "\"");
  }
  
*************** print_token (FILE * file, unsigned int t
*** 838,849 ****
  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
--- 839,850 ----
  void
  yyerror (const char *error_message)
  {
!   struct prod_token_parm_item *tok;
    
    tok = yylval;
    if (tok)
      {
!       fprintf (stderr, "%s:%i:%i: %s\n", in_fname, tok->tp.tok.lineno, tok->tp.tok.charno, error_message);
        print_token (stderr, 0, tok);
      }
    else
*************** yyerror (const char *error_message)
*** 856,867 ****
  /* 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;
--- 857,868 ----
  /* Reverse the order of a token list, linked by parse_next, old first
     token is OLD_FIRST.  */
  
! static struct prod_token_parm_item*
! reverse_prod_list (struct prod_token_parm_item *old_first)
  {
!   struct prod_token_parm_item *current;
!   struct prod_token_parm_item *next;
!   struct prod_token_parm_item *prev = NULL;
    
    current = old_first;
    prev = NULL;
*************** reverse_prod_list (struct production *ol
*** 870,877 ****
      {
        if (current->category != production_category)
          abort ();
!       next = current->next;
!       current->next = prev;
        prev = current;
        current = next; 
      }
--- 871,878 ----
      {
        if (current->category != production_category)
          abort ();
!       next = current->tp.pro.next;
!       current->tp.pro.next = prev;
        prev = current;
        current = next; 
      }
*************** reverse_prod_list (struct production *ol
*** 881,892 ****
  /* 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++;
      }
--- 882,893 ----
  /* Ensure TYPE is not VOID. Use NAME as the token for the error location.  */
  
  static void
! ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
  {
    if (type == VOID)
      {
        fprintf (stderr, "%s:%i:%i: Type must not be void in this context\n", in_fname, 
!               name->tp.tok.lineno, name->tp.tok.charno);
        print_token (stderr, 0, name);
        errorcount++;
      }
*************** ensure_not_void (unsigned int type, stru
*** 896,902 ****
     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;
--- 897,903 ----
     common type (min is signed int).  */
  
  static int 
! get_common_type (struct prod_token_parm_item *type1, struct prod_token_parm_item *type2)
  {
    if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
      return UNSIGNED_INT;
*************** get_common_type (struct production *type
*** 911,917 ****
     integral type.  */
  
  static int 
! check_type_match (int type_num, struct production *exp)
  {
    switch (type_num)
      {
--- 912,918 ----
     integral type.  */
  
  static int 
! check_type_match (int type_num, struct prod_token_parm_item *exp)
  {
    switch (type_num)
      {
*************** check_type_match (int type_num, struct p
*** 946,972 ****
  
  /* 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)
      {
--- 947,973 ----
  
  /* Make a production for an integer constant VALUE.  */
  
! static struct prod_token_parm_item *
! make_integer_constant (struct prod_token_parm_item* value)
  {
!   struct prod_token_parm_item* tok;
!   struct prod_token_parm_item *prod;
    tok = value;
    prod = make_production (PROD_INTEGER_CONSTANT, tok);
!   if ((tok->tp.tok.chars[0] == (unsigned char)'-')|| (tok->tp.tok.chars[0] == (unsigned char)'+'))
      NUMERIC_TYPE (prod) = SIGNED_INT;
    else
      NUMERIC_TYPE (prod) = UNSIGNED_INT;
!   prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars, tok->tp.tok.length);
    return prod;
  }
  
  /* Set STORAGE_CLASS in PROD according to CLASS_TOKEN.  */
  
  static void
! set_storage (struct prod_token_parm_item *prod)
  {
!   struct prod_token_parm_item* stg_class;
    stg_class = STORAGE_CLASS_TOKEN (prod);
    switch (stg_class->type)
      {
diff -c -p -r -N -X treelang.diff.excl cvs.copy/gcc/gcc/treelang/tree1.c cvs/gcc/gcc/treelang/tree1.c
*** cvs.copy/gcc/gcc/treelang/tree1.c	Sun May  5 14:24:18 2002
--- cvs/gcc/gcc/treelang/tree1.c	Sun Jun  9 09:37:49 2002
***************
*** 35,41 ****
  #include "system.h"
  #include "ansidecl.h"
  #include "flags.h"
- #include "output.h"
  #include "toplev.h"
  
  #include "ggc.h"
--- 35,40 ----
***************
*** 55,61 ****
  extern int yyparse (void);
  /* Linked list of symbols - all must be unique in treelang.  */
  
! struct production *symbol_table = NULL;
  
  /* Language for usage for messages.  */
  
--- 54,60 ----
  extern int yyparse (void);
  /* Linked list of symbols - all must be unique in treelang.  */
  
! static GTY(()) struct prod_token_parm_item *symbol_table = NULL;
  
  /* Language for usage for messages.  */
  
*************** const char *const language_string = "TRE
*** 65,73 ****
  
  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;
--- 64,69 ----
*************** treelang_decode_option (num_options_left
*** 191,208 ****
  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 = "";
--- 187,192 ----
*************** treelang_parse_file (int debug_flag ATTR
*** 250,307 ****
    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 *
--- 234,239 ----
*************** my_malloc (size_t size)
*** 322,366 ****
     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;
--- 254,299 ----
     return the symbol table entry from the symbol table if found there,
     else 0.  */
  
! struct prod_token_parm_item*
! lookup_tree_name (struct prod_token_parm_item *prod)
  {
!   struct prod_token_parm_item *this;
!   struct prod_token_parm_item *this_tok;
!   struct prod_token_parm_item *tok;
    tok = SYMBOL_TABLE_NAME (prod);
!   for (this = symbol_table; this; this = this->tp.pro.next)
      {
!       this_tok = this->tp.pro.main_token;
!       if (tok->tp.tok.length != this_tok->tp.tok.length) 
          continue;
!       if (memcmp (tok->tp.tok.chars, this_tok->tp.tok.chars, this_tok->tp.tok.length))
          continue;
        if (option_parser_trace)
!         fprintf (stderr, "Found symbol %s (%i:%i) as %i \n", tok->tp.tok.chars, 
!                 tok->tp.tok.lineno, tok->tp.tok.charno, NUMERIC_TYPE (this));
        return this;
      }
    if (option_parser_trace)
!     fprintf (stderr, "Not found symbol %s (%i:%i) as %i \n", tok->tp.tok.chars, 
!             tok->tp.tok.lineno, tok->tp.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 prod_token_parm_item *prod)
  {
!   struct prod_token_parm_item *tok;
    tok = SYMBOL_TABLE_NAME (prod);
    if (lookup_tree_name (prod))
      {
!       fprintf (stderr, "%s:%i:%i duplicate name %s\n", in_fname, tok->tp.tok.lineno, 
!                tok->tp.tok.charno, tok->tp.tok.chars);
        errorcount++;
        return 1;
      }
!   prod->tp.pro.next = symbol_table;
    NESTING_LEVEL (prod) = work_nesting_level;
    symbol_table = prod;
    return 0;
*************** insert_tree_name (struct production *pro
*** 368,382 ****
  
  /* 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;
  } 
  
  
--- 301,319 ----
  
  /* Create a struct productions of type TYPE, main token MAIN_TOK.  */
  
! struct prod_token_parm_item *
! make_production (int type, struct prod_token_parm_item *main_tok)
  {
!   struct prod_token_parm_item *prod;
!   prod = my_malloc (sizeof (struct prod_token_parm_item));
    prod->category = production_category;
    prod->type = type;
!   prod->tp.pro.main_token = main_tok;
    return prod;
  } 
  
  
+ /* New garbage collection regime see gty.texi.  */
+ #include "gt-treelang-tree1.h"
+ /*#include "gt-treelang-treelang.h"*/
+ #include "gtype-treelang.h"
diff -c -p -r -N -X treelang.diff.excl cvs.copy/gcc/gcc/treelang/treelang.h cvs/gcc/gcc/treelang/treelang.h
*** cvs.copy/gcc/gcc/treelang/treelang.h	Sun May  5 14:24:18 2002
--- cvs/gcc/gcc/treelang/treelang.h	Sat Jun  8 20:40:39 2002
*************** enum category_enum 
*** 35,98 ****
  { /* 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;
--- 35,91 ----
  { /* These values less likely to be there by chance unlike 0/1,
        make checks more meaningful */
    token_category = 111,
!   production_category = 222,
!   parameter_category = 333
  };
  
  /* Input file name and FILE.  */
  extern unsigned char* in_fname;
  extern FILE* yyin;
  
! /* Forward references to satisfy mutually recursive definitions.  */
! struct token_part;
! struct production_part;
! struct prod_token_parm_item;
! typedef struct GTY(()) prod_token_parm_item item;
  
! /* A token from the input file.  */
! 
! struct token_part GTY(())
  {
    unsigned int lineno;
    unsigned int charno;
    unsigned int length; /* The value.  */
    unsigned char* chars;
  };
  
! /* Definitions for fields in production.  */
! #define NESTING_LEVEL(a) a->tp.pro.info[0]  /* Level used for variable definitions.  */
! #define NUMERIC_TYPE(a)  a->tp.pro.info[1]  /* Numeric type used in type definitions and expressions.  */
  #define SUB_COUNT 5
! #define SYMBOL_TABLE_NAME(a) (a->tp.pro.sub[0]) /* Name token.  */
! #define EXPRESSION_TYPE(a) (a->tp.pro.sub[1]) /* Type identifier.  */
! #define OP1(a) (a->tp.pro.sub[2]) /* Exp operand1.  */
! #define PARAMETERS(a) (a->tp.pro.sub[2]) /* Function parameters.  */
! #define VARIABLE(a) (a->tp.pro.sub[2]) /* Parameter variable ptr.  */
! #define VAR_INIT(a) (a->tp.pro.sub[2]) /* Variable init.  */
! #define OP2(a) (a->tp.pro.sub[3]) /* Exp operand2.  */
! #define FIRST_PARMS(a) (a->tp.pro.sub[3]) /* Function parameters linked via struct tree_parameter_list.  */
! #define OP3(a) (a->tp.pro.sub[4]) /* Exp operand3.  */
! #define STORAGE_CLASS_TOKEN(a) (a->tp.pro.sub[4]) /* Storage class token.  */
! #define STORAGE_CLASS(a) a->tp.pro.flag1 /* Values in treetree.h.  */
  
! struct production_part GTY(())
! {
!   struct prod_token_parm_item *main_token; /* Main token for error msgs; variable name token.  */
  
!   unsigned int info[2]; /* Extra information.  */
  
!   struct prod_token_parm_item *sub[SUB_COUNT]; /* Sub productions or tokens.  */
!   tree code; /* Back end hook for this item.  */
!   struct prod_token_parm_item *next; /* Next in chains of various types.  */
  
    unsigned int flag1:2;
    unsigned int flag2:1;
    unsigned int flag3:1;
    unsigned int flag4:1;
*************** struct production
*** 102,116 ****
  
  };
  
  /* 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);
  
--- 95,152 ----
  
  };
  
+ /* 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
+ 
+ /* Expression types.  */
+ #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.  */
+ 
+ /* Parameter list passed to back end.  */
+ struct parameter_part GTY(())
+ {
+   struct prod_token_parm_item *next; /* Next entry.  */
+   unsigned char* variable_name; /* Name. */
+   tree * GTY ((length ("1"))) where_to_put_var_tree; /* Where to save decl.  */
+ };
+ 
+ /* A production or a token.  */
+ struct prod_token_parm_item GTY(())
+ {
+   enum category_enum category; /* Token or production. */
+   unsigned int type; /* Token or production type.  */
+   union t_or_p
+   {
+     struct token_part GTY((tag ("token_category"))) tok;
+     struct production_part GTY((tag ("production_category"))) pro;
+     struct parameter_part GTY((tag ("parameter_category"))) par;
+   } GTY((desc ("((item *)&%1)->category"))) tp;
+ };
+ 
+ 
  /* 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 prod_token_parm_item *prod);
! struct prod_token_parm_item *lookup_tree_name (struct prod_token_parm_item *prod);
! struct prod_token_parm_item *make_production (int type, struct prod_token_parm_item *main_tok);
! void mark_production_used (struct prod_token_parm_item *pp);
! void mark_token_used (struct prod_token_parm_item *tt);
  void treelang_debug (void);
  
diff -c -p -r -N -X treelang.diff.excl cvs.copy/gcc/gcc/treelang/treetree.c cvs/gcc/gcc/treelang/treetree.c
*** cvs.copy/gcc/gcc/treelang/treetree.c	Wed Jun  5 11:53:04 2002
--- cvs/gcc/gcc/treelang/treetree.c	Sun Jun  9 09:49:46 2002
***************
*** 70,90 ****
  
  /* GCC headers.  */
  
- #include "ansidecl.h"
  #include "config.h"
  #include "system.h"
  #include "tree.h"
  #include "flags.h"
  #include "output.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;
--- 70,90 ----
  
  /* GCC headers.  */
  
  #include "config.h"
+ #include "ansidecl.h"
  #include "system.h"
  #include "tree.h"
  #include "flags.h"
  #include "output.h"
  #include "c-tree.h"
  #include "rtl.h"
  #include "ggc.h"
  #include "toplev.h"
  #include "varray.h"
  #include "langhooks-def.h"
  #include "langhooks.h"
  
+ #include "treelang.h"
  #include "treetree.h"
  
  extern int option_main;
*************** const char *const tree_code_name[] = {
*** 163,176 ****
  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 
--- 163,168 ----
*************** tree 
*** 242,254 ****
  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;
--- 234,246 ----
  tree_code_create_function_prototype (unsigned char* chars,
                                      unsigned int storage_class,
                                      unsigned int ret_type,
!                                     struct prod_token_parm_item* parms,
                                      unsigned char* filename,
                                      int lineno)
  {
  
    tree id;
!   struct prod_token_parm_item* parm;
    tree type_list = NULL_TREE;
    tree type_node;
    tree fn_type;
*************** tree_code_create_function_prototype (uns
*** 256,262 ****
  
    /* 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);
--- 248,254 ----
  
    /* Build the type.  */
    id = get_identifier ((const char*)chars);
!   for (parm = parms; parm; parm = parm->tp.par.next)
      {
        type_node = get_type_for_numeric_type (parm->type);
        type_list = tree_cons (NULL_TREE, type_node, type_list);
*************** void 
*** 328,334 ****
  tree_code_create_function_initial (tree prev_saved, 
                                    unsigned char* filename,
                                    int lineno,
!                                   struct tree_parameter_list* parms)
  {
    tree fn_decl;
    tree param_decl;
--- 320,326 ----
  tree_code_create_function_initial (tree prev_saved, 
                                    unsigned char* filename,
                                    int lineno,
!                                   struct prod_token_parm_item* parms)
  {
    tree fn_decl;
    tree param_decl;
*************** tree_code_create_function_initial (tree 
*** 337,344 ****
    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)
--- 329,336 ----
    tree parm_decl;
    tree parm_list;
    tree resultdecl;
!   struct prod_token_parm_item* this_parm; 
!   struct prod_token_parm_item* parm;
  
    fn_decl = prev_saved;
    if (!fn_decl)
*************** tree_code_create_function_initial (tree 
*** 368,377 ****
  
    /* 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);
--- 360,370 ----
  
    /* Make the argument variable decls.  */
    parm_list = NULL_TREE;
!   for (parm = parms; parm; parm = parm->tp.par.next)
      {
!       parm_decl = build_decl (PARM_DECL, get_identifier 
!                               ((const char*) (parm->tp.par.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);
*************** tree_code_create_function_initial (tree 
*** 395,405 ****
           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.  */
--- 388,398 ----
           this_parm = parms;
         param_decl;
         param_decl = TREE_CHAIN (param_decl),
!          this_parm = this_parm->tp.par.next)
      {
        if (!this_parm)
          abort (); /* Too few.  */
!       *this_parm->tp.par.where_to_put_var_tree = param_decl;
      }
    if (this_parm)
      abort (); /* Too many.  */
diff -c -p -r -N -X treelang.diff.excl cvs.copy/gcc/gcc/treelang/treetree.h cvs/gcc/gcc/treelang/treetree.h
*** cvs.copy/gcc/gcc/treelang/treetree.h	Sun May  5 14:24:18 2002
--- cvs/gcc/gcc/treelang/treetree.h	Sat Jun  8 20:41:19 2002
***************
*** 31,45 ****
  
   */
  
- /* 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);
--- 31,36 ----
*************** tree tree_code_get_expression (unsigned 
*** 49,60 ****
  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,
--- 40,51 ----
  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 prod_token_parm_item* 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 prod_token_parm_item* parms,                                 
                                           unsigned char* filename,
                                           int lineno);
  tree tree_code_create_variable (unsigned int storage_class,
*************** void treelang_parse_file (int debug_flag
*** 78,101 ****
  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.  */
--- 69,73 ----


More information about the Gcc-patches mailing list