This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

treelang patch part 5 of 6


+ 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 -c -r -p -N -X treelang.diff.excl cvs/gcc/gcc/treelang/treetree.c
cvscopy/gcc/gcc/treelang/treetree.c
*** cvs/gcc/gcc/treelang/treetree.c     Thu Jan  1 10:00:00 1970
--- cvscopy/gcc/gcc/treelang/treetree.c Sun May  5 10:18:41 2002
***************
*** 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, ...))




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]