OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/gnu-src/gcc-4.2.2/gcc/treelang
    from Rev 38 to Rev 154
    Reverse comparison

Rev 38 → Rev 154

/treetree.c
0,0 → 1,1272
/* TREELANG Compiler interface to GCC's middle end (treetree.c)
Called by the parser.
 
If you want a working example of how to write a front end to GCC,
you are in the right place.
 
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
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.
 
Updated to function-at-a-time by James A. Morrison, 2004.
 
-----------------------------------------------------------------------
 
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 3, 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; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>.
 
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. */
 
/* GCC headers. */
 
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "tree-dump.h"
#include "tree-iterator.h"
#include "tree-gimple.h"
#include "function.h"
#include "flags.h"
#include "output.h"
#include "ggc.h"
#include "toplev.h"
#include "varray.h"
#include "langhooks-def.h"
#include "langhooks.h"
#include "target.h"
 
#include "cgraph.h"
 
#include "treelang.h"
#include "treetree.h"
#include "opts.h"
 
extern int option_main;
extern char **file_names;
 
/* Types expected by gcc's garbage collector.
These types exist to allow language front-ends to
add extra information in gcc's parse tree data structure.
But the treelang front end doesn't use them -- it has
its own parse tree data structure.
We define them here only to satisfy gcc's garbage collector. */
 
/* Language-specific identifier information. */
 
struct lang_identifier GTY(())
{
struct tree_identifier common;
};
 
/* Language-specific tree node information. */
 
union lang_tree_node
GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE")))
{
union tree_node GTY ((tag ("0"),
desc ("tree_node_structure (&%h)")))
generic;
struct lang_identifier GTY ((tag ("1"))) identifier;
};
 
/* Language-specific type information. */
 
struct lang_type GTY(())
{
char junk; /* dummy field to ensure struct is not empty */
};
 
/* Language-specific declaration information. */
 
struct lang_decl GTY(())
{
char junk; /* dummy field to ensure struct is not empty */
};
 
struct language_function GTY(())
{
char junk; /* dummy field to ensure struct is not empty */
};
 
static bool tree_mark_addressable (tree exp);
static tree tree_lang_type_for_size (unsigned precision, int unsignedp);
static tree tree_lang_type_for_mode (enum machine_mode mode, int unsignedp);
static tree tree_lang_unsigned_type (tree type_node);
static tree tree_lang_signed_type (tree type_node);
static tree tree_lang_signed_or_unsigned_type (int unsignedp, tree type);
 
/* Functions to keep track of the current scope. */
static void pushlevel (int ignore);
static tree poplevel (int keep, int reverse, int functionbody);
static tree pushdecl (tree decl);
static tree* getstmtlist (void);
 
/* Langhooks. */
static tree builtin_function (const char *name, tree type, int function_code,
enum built_in_class class,
const char *library_name,
tree attrs);
extern const struct attribute_spec treelang_attribute_table[];
static tree getdecls (void);
static int global_bindings_p (void);
static void insert_block (tree);
 
static void tree_push_type_decl (tree id, tree type_node);
static void treelang_expand_function (tree fndecl);
 
/* The front end language hooks (addresses of code for this front
end). These are not really very language-dependent, i.e.
treelang, C, Mercury, etc. can all use almost the same definitions. */
 
#undef LANG_HOOKS_MARK_ADDRESSABLE
#define LANG_HOOKS_MARK_ADDRESSABLE tree_mark_addressable
#undef LANG_HOOKS_SIGNED_TYPE
#define LANG_HOOKS_SIGNED_TYPE tree_lang_signed_type
#undef LANG_HOOKS_UNSIGNED_TYPE
#define LANG_HOOKS_UNSIGNED_TYPE tree_lang_unsigned_type
#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE tree_lang_signed_or_unsigned_type
#undef LANG_HOOKS_TYPE_FOR_MODE
#define LANG_HOOKS_TYPE_FOR_MODE tree_lang_type_for_mode
#undef LANG_HOOKS_TYPE_FOR_SIZE
#define LANG_HOOKS_TYPE_FOR_SIZE tree_lang_type_for_size
#undef LANG_HOOKS_PARSE_FILE
#define LANG_HOOKS_PARSE_FILE treelang_parse_file
#undef LANG_HOOKS_ATTRIBUTE_TABLE
#define LANG_HOOKS_ATTRIBUTE_TABLE treelang_attribute_table
 
#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION treelang_expand_function
 
/* #undef LANG_HOOKS_TYPES_COMPATIBLE_P
#define LANG_HOOKS_TYPES_COMPATIBLE_P hook_bool_tree_tree_true
*/
/* Hook routines and data unique to treelang. */
 
#undef LANG_HOOKS_INIT
#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_INIT_OPTIONS
#define LANG_HOOKS_INIT_OPTIONS treelang_init_options
#undef LANG_HOOKS_HANDLE_OPTION
#define LANG_HOOKS_HANDLE_OPTION treelang_handle_option
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
/* Tree code type/name/code tables. */
 
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
 
const enum tree_code_class tree_code_type[] = {
#include "tree.def"
tcc_exceptional
};
#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 = SIZEOF_INT * HOST_BITS_PER_CHAR;
 
unsigned int tree_code_char_size = HOST_BITS_PER_CHAR;
 
/* 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:
gcc_unreachable ();
}
}
 
/* 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, location_t loc)
{
tree cond_exp, cond;
cond_exp = fold_build2 (NE_EXPR, boolean_type_node, exp,
build_int_cst (TREE_TYPE (exp), 0));
SET_EXPR_LOCATION (cond_exp, loc);
cond = build3 (COND_EXPR, void_type_node, cond_exp, NULL_TREE,
NULL_TREE);
SET_EXPR_LOCATION (cond, loc);
append_to_statement_list_force (cond, getstmtlist ());
pushlevel (0);
}
 
/* Output the code for the else of an if statement. The else occurred
at line LINENO in file FILENAME. */
 
void
tree_code_if_else (location_t loc ATTRIBUTE_UNUSED)
{
tree stmts = *getstmtlist ();
tree block = poplevel (1, 0, 0);
if (BLOCK_VARS (block))
{
tree bindexpr = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
stmts, block);
stmts = alloc_stmt_list ();
append_to_statement_list (bindexpr, &stmts);
}
 
TREE_OPERAND (STATEMENT_LIST_TAIL (*getstmtlist ())->stmt, 1) = stmts;
pushlevel (0);
}
 
/* Output the code for the end_if an if statement. The end_if (final brace)
occurred at line LINENO in file FILENAME. */
 
void
tree_code_if_end (location_t loc ATTRIBUTE_UNUSED)
{
tree stmts = *getstmtlist ();
tree block = poplevel (1, 0, 0);
if (BLOCK_VARS (block))
{
tree bindexpr = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
stmts, block);
stmts = alloc_stmt_list ();
append_to_statement_list (bindexpr, &stmts);
}
 
TREE_OPERAND (STATEMENT_LIST_TAIL (*getstmtlist ())->stmt, 2) = stmts;
}
 
/* Create a function. The prototype name is NAME, storage class is
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 prod_token_parm_item* parms,
location_t loc)
{
 
tree id;
struct prod_token_parm_item* parm;
tree type_list = NULL_TREE;
tree type_node;
tree fn_type;
tree fn_decl;
tree parm_list = NULL_TREE;
 
/* Build the type. */
id = get_identifier ((const char*)chars);
for (parm = parms; parm; parm = parm->tp.par.next)
{
gcc_assert (parm->category == parameter_category);
type_node = tree_code_get_type (parm->type);
type_list = tree_cons (NULL_TREE, type_node, type_list);
}
/* Last parm if void indicates fixed length list (as opposed to
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 = tree_code_get_type (ret_type);
fn_type = build_function_type (type_node, type_list);
 
id = get_identifier ((const char*)chars);
fn_decl = build_decl (FUNCTION_DECL, id, fn_type);
 
/* Nested functions not supported here. */
DECL_CONTEXT (fn_decl) = NULL_TREE;
DECL_SOURCE_LOCATION (fn_decl) = loc;
 
TREE_PUBLIC (fn_decl) = 0;
DECL_EXTERNAL (fn_decl) = 0;
TREE_STATIC (fn_decl) = 0;
switch (storage_class)
{
case STATIC_STORAGE:
break;
 
case EXTERNAL_DEFINITION_STORAGE:
TREE_PUBLIC (fn_decl) = 1;
break;
 
case EXTERNAL_REFERENCE_STORAGE:
DECL_EXTERNAL (fn_decl) = 1;
break;
 
case AUTOMATIC_STORAGE:
default:
gcc_unreachable ();
}
 
/* Make the argument variable decls. */
for (parm = parms; parm; parm = parm->tp.par.next)
{
tree parm_decl = build_decl (PARM_DECL, get_identifier
((const char*) (parm->tp.par.variable_name)),
tree_code_get_type (parm->type));
 
/* Some languages have different nominal and real types. */
DECL_ARG_TYPE (parm_decl) = TREE_TYPE (parm_decl);
gcc_assert (DECL_ARG_TYPE (parm_decl));
gcc_assert (fn_decl);
DECL_CONTEXT (parm_decl) = fn_decl;
DECL_SOURCE_LOCATION (parm_decl) = loc;
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 (parm = parms; parm_list;
parm_list = TREE_CHAIN (parm_list),
parm = parm->tp.par.next)
{
gcc_assert (parm); /* Too few. */
*parm->tp.par.where_to_put_var_tree = parm_list;
}
gcc_assert (!parm); /* Too many. */
 
/* Process declaration of function defined elsewhere. */
rest_of_decl_compilation (fn_decl, 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,
location_t loc)
{
tree fn_decl;
tree resultdecl;
 
fn_decl = prev_saved;
gcc_assert (fn_decl);
 
/* 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_LOCATION (fn_decl) = loc;
 
/* Create a DECL for the functions result. */
resultdecl =
build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (TREE_TYPE (fn_decl)));
DECL_CONTEXT (resultdecl) = fn_decl;
DECL_ARTIFICIAL (resultdecl) = 1;
DECL_IGNORED_P (resultdecl) = 1;
DECL_SOURCE_LOCATION (resultdecl) = loc;
DECL_RESULT (fn_decl) = resultdecl;
 
/* Create a new level at the start of the function. */
 
pushlevel (0);
 
TREE_STATIC (fn_decl) = 1;
}
 
/* Wrapup a function contained in file FILENAME, ending at line LINENO. */
void
tree_code_create_function_wrapup (location_t loc)
{
tree block;
tree fn_decl;
tree stmts = *getstmtlist ();
 
fn_decl = current_function_decl;
 
/* Pop the level. */
 
block = poplevel (1, 0, 1);
 
/* And attach it to the function. */
 
DECL_SAVED_TREE (fn_decl) = build3 (BIND_EXPR, void_type_node,
BLOCK_VARS (block),
stmts, block);
 
allocate_struct_function (fn_decl);
cfun->function_end_locus = loc;
 
/* Dump the original tree to a file. */
dump_function (TDI_original, fn_decl);
 
/* Convert current function to GIMPLE for the middle end. */
gimplify_function_tree (fn_decl);
dump_function (TDI_generic, fn_decl);
 
/* We are not inside of any scope now. */
current_function_decl = NULL_TREE;
cfun = NULL;
 
/* Pass the current function off to the middle end. */
(void)cgraph_node (fn_decl);
cgraph_finalize_function (fn_decl, false);
}
 
/* 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,
location_t loc)
{
tree var_type;
tree var_id;
tree var_decl;
 
/* 1. Build the type. */
var_type = tree_code_get_type (expression_type);
 
/* 2. Build the name. */
gcc_assert (chars[length] == 0); /* 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) = fold_convert (var_type, init);
else
DECL_INITIAL (var_decl) = NULL_TREE;
 
gcc_assert (TYPE_SIZE (var_type) != 0); /* Did not calculate size. */
 
DECL_CONTEXT (var_decl) = current_function_decl;
 
DECL_SOURCE_LOCATION (var_decl) = loc;
 
DECL_EXTERNAL (var_decl) = 0;
TREE_PUBLIC (var_decl) = 0;
TREE_STATIC (var_decl) = 0;
/* Set the storage mode and whether only visible in the same file. */
switch (storage_class)
{
case STATIC_STORAGE:
TREE_STATIC (var_decl) = 1;
break;
 
case AUTOMATIC_STORAGE:
break;
 
case EXTERNAL_DEFINITION_STORAGE:
TREE_PUBLIC (var_decl) = 1;
break;
 
case EXTERNAL_REFERENCE_STORAGE:
DECL_EXTERNAL (var_decl) = 1;
break;
 
default:
gcc_unreachable ();
}
 
TYPE_NAME (TREE_TYPE (var_decl)) = TYPE_NAME (var_type);
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;
#ifdef ENABLE_CHECKING
tree param;
 
for (param = DECL_ARGUMENTS (current_function_decl);
param;
param = TREE_CHAIN (param))
gcc_assert (DECL_CONTEXT (param) == current_function_decl);
#endif
 
if (exp && TREE_TYPE (TREE_TYPE (current_function_decl)) != void_type_node)
{
setret = fold_build2 (MODIFY_EXPR, type,
DECL_RESULT (current_function_decl),
fold_convert (type, exp));
TREE_SIDE_EFFECTS (setret) = 1;
TREE_USED (setret) = 1;
setret = build1 (RETURN_EXPR, type, setret);
/* Use EXPR_LOCUS so we don't lose any information about the file we
are compiling. */
SET_EXPR_LOCUS (setret, EXPR_LOCUS (exp));
}
else
setret = build1 (RETURN_EXPR, type, NULL_TREE);
 
append_to_statement_list_force (setret, getstmtlist ());
}
 
 
/* Output the code for this expression statement CODE. */
 
void
tree_code_output_expression_statement (tree code, location_t loc)
{
/* Output the line number information. */
SET_EXPR_LOCATION (code, loc);
TREE_USED (code) = 1;
TREE_SIDE_EFFECTS (code) = 1;
/* put CODE into the code list. */
append_to_statement_list_force (code, getstmtlist ());
}
 
/* Return a tree for a constant integer value in the token TOK. No
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_cst_wide (start == 1 ?
integer_type_node : unsigned_type_node,
val & 0xffffffff, (val >> 32) & 0xffffffff);
}
 
/* Return the tree for an expression, 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,
location_t loc)
{
tree ret1;
int operator;
 
switch (exp_type)
{
case EXP_ASSIGN:
gcc_assert (op1 && op2);
operator = MODIFY_EXPR;
ret1 = fold_build2 (operator, void_type_node, op1,
fold_convert (TREE_TYPE (op1), 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:
gcc_assert (op1 && op2);
ret1 = fold_build2 (operator, type,
fold_convert (type, op1),
fold_convert (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. However, to keep accurate location
information we wrap it in a NOP_EXPR is is easily stripped. */
case EXP_REFERENCE:
gcc_assert (op1);
TREE_USED (op1) = 1;
if (type == TREE_TYPE (op1))
ret1 = build1 (NOP_EXPR, type, op1);
else
ret1 = fold_convert (type, op1);
break;
 
case EXP_FUNCTION_INVOCATION:
gcc_assert (op1);
gcc_assert(TREE_TYPE (TREE_TYPE (op1)) == type);
TREE_USED (op1) = 1;
ret1 = build_function_call_expr(op1, op2);
break;
 
default:
gcc_unreachable ();
}
 
/* Declarations already have a location and constants can be shared so they
shouldn't a location set on them. */
if (! DECL_P (ret1) && ! TREE_CONSTANT (ret1))
SET_EXPR_LOCATION (ret1, loc);
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,
fold_convert (TREE_TYPE (proto_exp),
exp), NULL_TREE);
if (!list)
return new_exp;
return chainon (new_exp, list);
}
 
/* Get a stringpool entry for a string S of length L. This is needed
because the GTY routines don't mark strings, forcing you to put
them into stringpool, which is never freed. */
 
const char*
get_string (const char *s, size_t l)
{
tree t;
t = get_identifier_with_length (s, l);
return IDENTIFIER_POINTER(t);
}
/* Save typing debug_tree all the time. Dump a tree T pretty and
concise. */
 
void dt (tree t);
 
void
dt (tree t)
{
debug_tree (t);
}
 
/* Routines Expected by gcc: */
 
/* These are used to build types for various sizes. The code below
is a simplified version of that of GNAT. */
 
#ifndef MAX_BITS_PER_WORD
#define MAX_BITS_PER_WORD BITS_PER_WORD
#endif
 
/* This variable keeps a table for types for each precision so that we only
allocate each of them once. Signed and unsigned types are kept separate. */
static GTY(()) tree signed_and_unsigned_types[MAX_BITS_PER_WORD + 1][2];
 
/* Mark EXP saying that we need to be able to take the
address of it; it should not be allocated in a register.
Value is 1 if successful.
This implementation was copied from c-decl.c. */
 
static bool
tree_mark_addressable (tree exp)
{
register tree x = exp;
while (1)
switch (TREE_CODE (x))
{
case COMPONENT_REF:
case ADDR_EXPR:
case ARRAY_REF:
case REALPART_EXPR:
case IMAGPART_EXPR:
x = TREE_OPERAND (x, 0);
break;
case CONSTRUCTOR:
TREE_ADDRESSABLE (x) = 1;
return 1;
 
case VAR_DECL:
case CONST_DECL:
case PARM_DECL:
case RESULT_DECL:
if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
&& DECL_NONLOCAL (x))
{
if (TREE_PUBLIC (x))
{
error ("Global register variable %qD used in nested function.",
x);
return 0;
}
pedwarn ("Register variable %qD used in nested function.", x);
}
else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
{
if (TREE_PUBLIC (x))
{
error ("Address of global register variable %qD requested.",
x);
return 0;
}
 
pedwarn ("Address of register variable %qD requested.", x);
}
 
/* drops in */
case FUNCTION_DECL:
TREE_ADDRESSABLE (x) = 1;
 
default:
return 1;
}
}
/* Return an integer type with the number of bits of precision given by
PRECISION. UNSIGNEDP is nonzero if the type is unsigned; otherwise
it is a signed type. */
static tree
tree_lang_type_for_size (unsigned precision, int unsignedp)
{
tree t;
 
if (precision <= MAX_BITS_PER_WORD
&& signed_and_unsigned_types[precision][unsignedp] != 0)
return signed_and_unsigned_types[precision][unsignedp];
 
if (unsignedp)
t = signed_and_unsigned_types[precision][1]
= make_unsigned_type (precision);
else
t = signed_and_unsigned_types[precision][0]
= make_signed_type (precision);
return t;
}
 
/* Return a data type that has machine mode MODE. UNSIGNEDP selects
an unsigned type; otherwise a signed type is returned. */
 
static tree
tree_lang_type_for_mode (enum machine_mode mode, int unsignedp)
{
if (SCALAR_INT_MODE_P (mode))
return tree_lang_type_for_size (GET_MODE_BITSIZE (mode), unsignedp);
else
return NULL_TREE;
}
 
/* Return the unsigned version of a TYPE_NODE, a scalar type. */
 
static tree
tree_lang_unsigned_type (tree type_node)
{
return tree_lang_type_for_size (TYPE_PRECISION (type_node), 1);
}
 
/* Return the signed version of a TYPE_NODE, a scalar type. */
 
static tree
tree_lang_signed_type (tree type_node)
{
return tree_lang_type_for_size (TYPE_PRECISION (type_node), 0);
}
 
/* Return a type the same as TYPE except unsigned or signed according to
UNSIGNEDP. */
 
static tree
tree_lang_signed_or_unsigned_type (int unsignedp, tree type)
{
if (! INTEGRAL_TYPE_P (type) || TYPE_UNSIGNED (type) == unsignedp)
return type;
else
return tree_lang_type_for_size (TYPE_PRECISION (type), unsignedp);
}
/* These functions and variables deal with binding contours. We only
need these functions for the list of PARM_DECLs, but we leave the
functions more general; these are a simplified version of the
functions from GNAT. */
 
/* For each binding contour we allocate a binding_level structure which records
the entities defined or declared in that contour. Contours include:
 
the global one
one for each subprogram definition
one for each compound statement (declare block)
 
Binding contours are used to create GCC tree BLOCK nodes. */
 
struct binding_level
{
/* A chain of ..._DECL nodes for all variables, constants, functions,
parameters and type declarations. These ..._DECL nodes are chained
through the TREE_CHAIN field. Note that these ..._DECL nodes are stored
in the reverse of the order supplied to be compatible with the
back-end. */
tree names;
/* For each level (except the global one), a chain of BLOCK nodes for all
the levels that were entered and exited one level down from this one. */
tree blocks;
 
tree stmts;
/* The binding level containing this one (the enclosing binding level). */
struct binding_level *level_chain;
};
 
/* The binding level currently in effect. */
static struct binding_level *current_binding_level = NULL;
 
/* The outermost binding level. This binding level is created when the
compiler is started and it will exist through the entire compilation. */
static struct binding_level *global_binding_level;
 
/* Binding level structures are initialized by copying this one. */
static struct binding_level clear_binding_level = {NULL, NULL, NULL, NULL };
/* Return non-zero if we are currently in the global binding level. */
 
static int
global_bindings_p (void)
{
return current_binding_level == global_binding_level ? -1 : 0;
}
 
 
/* Return the list of declarations in the current level. Note that this list
is in reverse order (it has to be so for back-end compatibility). */
 
static tree
getdecls (void)
{
return current_binding_level->names;
}
 
/* Return a STATMENT_LIST for the current block. */
 
static tree*
getstmtlist (void)
{
return &current_binding_level->stmts;
}
 
/* Enter a new binding level. The input parameter is ignored, but has to be
specified for back-end compatibility. */
 
static void
pushlevel (int ignore ATTRIBUTE_UNUSED)
{
struct binding_level *newlevel = XNEW (struct binding_level);
 
*newlevel = clear_binding_level;
 
/* Add this level to the front of the chain (stack) of levels that are
active. */
newlevel->level_chain = current_binding_level;
current_binding_level = newlevel;
current_binding_level->stmts = alloc_stmt_list ();
}
 
/* Exit a binding level.
Pop the level off, and restore the state of the identifier-decl mappings
that were in effect when this level was entered.
 
If KEEP is nonzero, this level had explicit declarations, so
and create a "block" (a BLOCK node) for the level
to record its declarations and subblocks for symbol table output.
 
If FUNCTIONBODY is nonzero, this level is the body of a function,
so create a block as if KEEP were set and also clear out all
label names.
 
If REVERSE is nonzero, reverse the order of decls before putting
them into the BLOCK. */
 
static tree
poplevel (int keep, int reverse, int functionbody)
{
/* Points to a BLOCK tree node. This is the BLOCK node constructed for the
binding level that we are about to exit and which is returned by this
routine. */
tree block_node = NULL_TREE;
tree decl_chain;
tree subblock_chain = current_binding_level->blocks;
tree subblock_node;
 
/* Reverse the list of *_DECL nodes if desired. Note that the ..._DECL
nodes chained through the `names' field of current_binding_level are in
reverse order except for PARM_DECL node, which are explicitly stored in
the right order. */
decl_chain = (reverse) ? nreverse (current_binding_level->names)
: current_binding_level->names;
 
/* If there were any declarations in the current binding level, or if this
binding level is a function body, or if there are any nested blocks then
create a BLOCK node to record them for the life of this function. */
if (keep || functionbody)
block_node = build_block (keep ? decl_chain : 0, subblock_chain, 0, 0);
 
/* Record the BLOCK node just built as the subblock its enclosing scope. */
for (subblock_node = subblock_chain; subblock_node;
subblock_node = TREE_CHAIN (subblock_node))
BLOCK_SUPERCONTEXT (subblock_node) = block_node;
 
/* Clear out the meanings of the local variables of this level. */
 
for (subblock_node = decl_chain; subblock_node;
subblock_node = TREE_CHAIN (subblock_node))
if (DECL_NAME (subblock_node) != 0)
/* If the identifier was used or addressed via a local extern decl,
don't forget that fact. */
if (DECL_EXTERNAL (subblock_node))
{
if (TREE_USED (subblock_node))
TREE_USED (DECL_NAME (subblock_node)) = 1;
}
 
/* Pop the current level. */
current_binding_level = current_binding_level->level_chain;
 
if (functionbody)
{
/* This is the top level block of a function. */
DECL_INITIAL (current_function_decl) = block_node;
}
else if (block_node)
{
current_binding_level->blocks
= chainon (current_binding_level->blocks, block_node);
}
 
/* If we did not make a block for the level just exited, any blocks made for
inner levels (since they cannot be recorded as subblocks in that level)
must be carried forward so they will later become subblocks of something
else. */
else if (subblock_chain)
current_binding_level->blocks
= chainon (current_binding_level->blocks, subblock_chain);
if (block_node)
TREE_USED (block_node) = 1;
 
return block_node;
}
/* Insert BLOCK at the end of the list of subblocks of the
current binding level. This is used when a BIND_EXPR is expanded,
to handle the BLOCK node inside the BIND_EXPR. */
 
static void
insert_block (tree block)
{
TREE_USED (block) = 1;
current_binding_level->blocks
= chainon (current_binding_level->blocks, block);
}
 
 
/* Records a ..._DECL node DECL as belonging to the current lexical scope.
Returns the ..._DECL node. */
 
tree
pushdecl (tree decl)
{
/* External objects aren't nested, other objects may be. */
if ((DECL_EXTERNAL (decl)) || (decl==current_function_decl))
DECL_CONTEXT (decl) = 0;
else
DECL_CONTEXT (decl) = current_function_decl;
 
/* Put the declaration on the list. The list of declarations is in reverse
order. The list will be reversed later if necessary. This needs to be
this way for compatibility with the back-end. */
 
TREE_CHAIN (decl) = current_binding_level->names;
current_binding_level->names = decl;
 
/* For the declaration of a type, set its name if it is not already set. */
 
if (TREE_CODE (decl) == TYPE_DECL
&& TYPE_NAME (TREE_TYPE (decl)) == 0)
TYPE_NAME (TREE_TYPE (decl)) = DECL_NAME (decl);
 
/* Put automatic variables into the intermediate representation. */
if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)
&& !TREE_STATIC (decl) && !TREE_PUBLIC (decl))
tree_code_output_expression_statement (build1 (DECL_EXPR, void_type_node,
decl),
DECL_SOURCE_LOCATION (decl));
return decl;
}
 
static void
tree_push_type_decl(tree id, tree type_node)
{
tree decl = build_decl (TYPE_DECL, id, type_node);
TYPE_NAME (type_node) = id;
pushdecl (decl);
}
 
#define NULL_BINDING_LEVEL (struct binding_level *) NULL
 
/* Create the predefined scalar types of C,
and some nodes representing standard constants (0, 1, (void *) 0).
Initialize the global binding level.
Make definitions for built-in primitive functions. */
 
void
treelang_init_decl_processing (void)
{
current_function_decl = NULL;
current_binding_level = NULL_BINDING_LEVEL;
pushlevel (0); /* make the binding_level structure for global names */
global_binding_level = current_binding_level;
 
build_common_tree_nodes (flag_signed_char, false);
 
/* set standard type names */
 
/* Define `int' and `char' last so that they are not overwritten. */
tree_push_type_decl (NULL_TREE, intQI_type_node);
tree_push_type_decl (NULL_TREE, intHI_type_node);
tree_push_type_decl (NULL_TREE, intSI_type_node);
tree_push_type_decl (NULL_TREE, intDI_type_node);
#if HOST_BITS_PER_WIDE_INT >= 64
tree_push_type_decl (NULL_TREE, intTI_type_node);
#endif
tree_push_type_decl (NULL_TREE, unsigned_intQI_type_node);
tree_push_type_decl (NULL_TREE, unsigned_intHI_type_node);
tree_push_type_decl (NULL_TREE, unsigned_intSI_type_node);
tree_push_type_decl (NULL_TREE, unsigned_intDI_type_node);
#if HOST_BITS_PER_WIDE_INT >= 64
tree_push_type_decl (NULL_TREE, unsigned_intTI_type_node);
#endif
 
tree_push_type_decl (get_identifier ("int"), integer_type_node);
tree_push_type_decl (get_identifier ("char"), char_type_node);
tree_push_type_decl (get_identifier ("long int"),
long_integer_type_node);
tree_push_type_decl (get_identifier ("unsigned int"),
unsigned_type_node);
tree_push_type_decl (get_identifier ("long unsigned int"),
long_unsigned_type_node);
tree_push_type_decl (get_identifier ("long long int"),
long_long_integer_type_node);
tree_push_type_decl (get_identifier ("long long unsigned int"),
long_long_unsigned_type_node);
tree_push_type_decl (get_identifier ("short int"),
short_integer_type_node);
tree_push_type_decl (get_identifier ("short unsigned int"),
short_unsigned_type_node);
tree_push_type_decl (get_identifier ("signed char"),
signed_char_type_node);
tree_push_type_decl (get_identifier ("unsigned char"),
unsigned_char_type_node);
size_type_node = make_unsigned_type (POINTER_SIZE);
tree_push_type_decl (get_identifier ("size_t"), size_type_node);
set_sizetype (size_type_node);
 
build_common_tree_nodes_2 (/* short_double= */ 0);
 
tree_push_type_decl (get_identifier ("float"), float_type_node);
tree_push_type_decl (get_identifier ("double"), double_type_node);
tree_push_type_decl (get_identifier ("long double"), long_double_type_node);
tree_push_type_decl (get_identifier ("void"), void_type_node);
 
build_common_builtin_nodes ();
(*targetm.init_builtins) ();
 
pedantic_lvalues = pedantic;
}
 
static tree
handle_attribute (tree *node, tree name, tree ARG_UNUSED (args),
int ARG_UNUSED (flags), bool *no_add_attrs)
{
if (TREE_CODE (*node) == FUNCTION_DECL)
{
if (strcmp (IDENTIFIER_POINTER (name), "const") == 0)
TREE_READONLY (*node) = 1;
if (strcmp (IDENTIFIER_POINTER (name), "nothrow") == 0)
TREE_NOTHROW (*node) = 1;
}
else
{
warning (OPT_Wattributes, "%qD attribute ignored", name);
*no_add_attrs = true;
}
 
return NULL_TREE;
}
 
const struct attribute_spec treelang_attribute_table[] =
{
{ "const", 0, 0, true, false, false, handle_attribute },
{ "nothrow", 0, 0, true, false, false, handle_attribute },
{ NULL, 0, 0, false, false, false, NULL },
};
 
/* Return a definition for a builtin function named NAME and whose data type
is TYPE. TYPE should be a function type with argument types.
FUNCTION_CODE tells later passes how to compile calls to this function.
See tree.h for its possible values.
 
If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
the name to be called if we can't opencode the function. If
ATTRS is nonzero, use that for the function's attribute list.
 
copied from gcc/c-decl.c
*/
 
static tree
builtin_function (const char *name, tree type, int function_code,
enum built_in_class class, const char *library_name,
tree attrs)
{
tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
if (library_name)
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
pushdecl (decl);
DECL_BUILT_IN_CLASS (decl) = class;
DECL_FUNCTION_CODE (decl) = function_code;
 
/* Possibly apply some default attributes to this built-in function. */
if (attrs)
decl_attributes (&decl, attrs, ATTR_FLAG_BUILT_IN);
else
decl_attributes (&decl, NULL_TREE, 0);
 
return decl;
}
 
/* Treelang expand function langhook. */
 
static void
treelang_expand_function (tree fndecl)
{
/* We have nothing special to do while expanding functions for treelang. */
tree_rest_of_compilation (fndecl);
}
 
#include "debug.h" /* for debug_hooks, needed by gt-treelang-treetree.h */
#include "gt-treelang-treetree.h"
/parse.y
0,0 → 1,988
/* -*- c -*- emacs mode c */
/* TREELANG Compiler parser.
 
---------------------------------------------------------------------
 
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
Free Software Foundation, Inc.
 
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, 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; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>.
 
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
 
---------------------------------------------------------------------
 
Written by Tim Josling 1999-2001, based in part on other parts of
the GCC compiler. */
 
/* Grammar Conflicts
*****************
There are no conflicts in this grammar. Please keep it that way. */
 
%{
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "timevar.h"
#include "tree.h"
 
#include "treelang.h"
#include "treetree.h"
#include "toplev.h"
 
#define YYDEBUG 1
#define YYPRINT(file, type, value) print_token (file, type, value)
#define YYERROR_VERBOSE YES
 
/* My yylex routine used to intercept calls to flex generated code, to
record lex time. */
int yylex (void);
static inline int my_yylex (void);
 
/* Call lex, but ensure time is charged to TV_LEX. */
static inline int
my_yylex (void)
{
int res;
timevar_push (TV_LEX);
res = yylex ();
timevar_pop (TV_LEX);
return res;
}
#define yylex my_yylex
 
extern int option_parser_trace;
 
/* Local prototypes. */
static void yyerror (const char *error_message);
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 struct prod_token_parm_item *make_plus_expression
(struct prod_token_parm_item *tok, struct prod_token_parm_item *op1,
struct prod_token_parm_item *op2, int type_code, int prod_code);
static void set_storage (struct prod_token_parm_item *prod);
 
/* File global variables. */
static struct prod_token_parm_item *current_function = NULL;
%}
 
/* Not %raw - seems to have bugs. */
%token_table
 
/* Punctuation. */
%token RIGHT_BRACE
%token LEFT_BRACE
%token RIGHT_SQUARE_BRACKET
%token LEFT_SQUARE_BRACKET
%token RIGHT_PARENTHESIS
%token LEFT_PARENTHESIS
%token SEMICOLON
%token ASTERISK
%token COMMA
%right EQUALS
%right ASSIGN
%left tl_PLUS
%left tl_MINUS
 
/* Literals. */
%token INTEGER
 
/* Keywords. */
%token IF
%token ELSE
%token tl_RETURN
%token CHAR
%token INT
%token UNSIGNED
%token VOID
%token TYPEDEF
%token NAME
%token STATIC
%token AUTOMATIC
%token EXTERNAL_DEFINITION
%token EXTERNAL_REFERENCE
 
/* Tokens not passed to parser. */
%token WHITESPACE
%token COMMENT
 
/* Pseudo tokens - productions. */
%token PROD_VARIABLE_NAME
%token PROD_TYPE_NAME
%token PROD_FUNCTION_NAME
%token PROD_INTEGER_CONSTANT
%token PROD_PLUS_EXPRESSION
%token PROD_MINUS_EXPRESSION
%token PROD_ASSIGN_EXPRESSION
%token PROD_VARIABLE_REFERENCE_EXPRESSION
%token PROD_PARAMETER
%token PROD_FUNCTION_INVOCATION
%expect 0
%%
 
file:
/* Nil. */ {
/* Nothing to do. */
}
|declarations {
/* Nothing to do. */
}
;
 
 
declarations:
declaration {
/* Nothing to do. */
}
| declarations declaration {
/* Nothing to do. */
}
;
 
declaration:
variable_def {
/* Nothing to do. */
}
|function_prototype {
/* Nothing to do. */
}
|function {
/* Nothing to do. */
}
;
 
variable_def:
storage typename NAME init_opt SEMICOLON {
struct 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))
{
YYERROR;
}
STORAGE_CLASS_TOKEN (prod) = $1;
set_storage (prod);
 
if (VAR_INIT (prod))
{
gcc_assert (((struct prod_token_parm_item *)
VAR_INIT (prod))->tp.pro.code);
if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
{
error("%Hexternal reference variable %q.*s has an initial value",
&tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
YYERROR;
VAR_INIT (prod) = NULL;
}
 
}
 
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,
tok->tp.tok.location);
gcc_assert (prod->tp.pro.code);
}
;
 
storage:
STATIC
|AUTOMATIC
|EXTERNAL_DEFINITION
|EXTERNAL_REFERENCE
;
 
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))
{
YYERROR;
}
prod2 = make_production (PROD_PARAMETER, tok);
VARIABLE (prod2) = prod;
$$ = prod2;
}
;
 
function_prototype:
storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLON {
struct prod_token_parm_item *tok;
struct prod_token_parm_item *prod;
struct prod_token_parm_item *type;
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;
set_storage (prod);
switch (STORAGE_CLASS (prod))
{
case STATIC_STORAGE:
case EXTERNAL_DEFINITION_STORAGE:
case EXTERNAL_REFERENCE_STORAGE:
break;
 
case AUTOMATIC_STORAGE:
error ("%Hfunction %q.*s cannot be automatic",
&tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
YYERROR;
break;
 
default:
gcc_unreachable ();
}
type = EXPRESSION_TYPE (prod);
/* Create a parameter list in a non-front end specific format. */
for (first_parms = NULL, last_parms = NULL, this_parm = PARAMETERS (prod);
this_parm;
this_parm = this_parm->tp.pro.next)
{
gcc_assert (this_parm->category == production_category);
this_parm_var = VARIABLE (this_parm);
 
gcc_assert (this_parm_var);
gcc_assert (this_parm_var->category == production_category);
gcc_assert (this_parm_var->tp.pro.main_token);
 
this_parms = my_malloc (sizeof (struct prod_token_parm_item));
 
this_parms->tp.par.variable_name =
this_parm_var->tp.pro.main_token->tp.tok.chars;
this_parms->category = parameter_category;
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
{
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, tok->tp.tok.location);
 
#ifdef ENABLE_CHECKING
/* Check all the parameters have code. */
for (this_parm = PARAMETERS (prod);
this_parm;
this_parm = this_parm->tp.pro.next)
{
gcc_assert ((struct prod_token_parm_item *)VARIABLE (this_parm));
gcc_assert (((struct prod_token_parm_item *)
VARIABLE (this_parm))->tp.pro.code);
}
#endif
}
;
 
function:
NAME LEFT_BRACE {
struct prod_token_parm_item *proto;
struct prod_token_parm_item search_prod;
struct prod_token_parm_item *tok;
tok = $1;
SYMBOL_TABLE_NAME ((&search_prod)) = tok;
search_prod.category = token_category;
current_function = proto = lookup_tree_name (&search_prod);
if (!proto)
{
error ("%Hno prototype found for %q.*s", &tok->tp.tok.location,
tok->tp.tok.length, tok->tp.tok.chars);
YYERROR;
}
 
gcc_assert (proto->tp.pro.code);
 
tree_code_create_function_initial (proto->tp.pro.code, tok->tp.tok.location);
}
 
variable_defs_opt statements_opt RIGHT_BRACE {
struct prod_token_parm_item *tok;
tok = $1;
tree_code_create_function_wrapup (tok->tp.tok.location);
current_function = NULL;
}
;
 
variable_defs_opt:
/* Nil. */ {
$$ = 0;
}
|variable_defs {
$$ = $1;
}
;
 
statements_opt:
/* Nil. */ {
$$ = 0;
}
|statements {
$$ = $1;
}
;
 
variable_defs:
variable_def {
/* Nothing to do. */
}
|variable_defs variable_def {
/* Nothing to do. */
}
;
 
typename:
INT {
struct 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;
}
;
 
parameters_opt:
/* Nothing to do. */ {
$$ = 0;
}
| parameters {
$$ = $1;
}
;
 
parameters:
parameter {
/* Nothing to do. */
$$ = $1;
}
|parameters COMMA parameter {
struct prod_token_parm_item *prod1;
prod1 = $3;
prod1->tp.pro.next = $1; /* Insert in reverse order. */
$$ = prod1;
}
;
 
statements:
statement {
/* Nothing to do. */
}
|statements statement {
/* Nothing to do. */
}
;
 
statement:
expression SEMICOLON {
struct prod_token_parm_item *exp;
exp = $1;
tree_code_output_expression_statement (exp->tp.pro.code,
exp->tp.pro.main_token->tp.tok.location);
}
|return SEMICOLON {
/* Nothing to do. */
}
|if_statement {
/* Nothing to do. */
}
;
 
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, tok->tp.tok.location);
}
LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
/* Just let the statements flow. */
}
ELSE {
struct prod_token_parm_item *tok;
tok = $1;
tree_code_if_else (tok->tp.tok.location);
}
LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
struct prod_token_parm_item *tok;
tok = $1;
tree_code_if_end (tok->tp.tok.location);
}
;
 
 
return:
tl_RETURN expression_opt {
struct prod_token_parm_item *type_prod;
struct prod_token_parm_item *ret_tok = $1;
struct prod_token_parm_item *exp = $2;
 
type_prod = EXPRESSION_TYPE (current_function);
if (NUMERIC_TYPE (type_prod) == VOID_TYPE)
if (exp == NULL)
tree_code_generate_return (type_prod->tp.pro.code, NULL);
else
{
warning (0, "%Hredundant expression in return",
&ret_tok->tp.tok.location);
tree_code_generate_return (type_prod->tp.pro.code, NULL);
}
else
if (exp == NULL)
error ("%Hexpression missing in return", &ret_tok->tp.tok.location);
else
{
/* Check same type. */
if (check_type_match (NUMERIC_TYPE (type_prod), exp))
{
gcc_assert (type_prod->tp.pro.code);
gcc_assert (exp->tp.pro.code);
 
/* Generate the code. */
tree_code_generate_return (type_prod->tp.pro.code,
exp->tp.pro.code);
}
}
}
;
 
expression_opt:
/* Nil. */ {
$$ = 0;
}
|expression {
struct prod_token_parm_item *exp;
exp = $1;
gcc_assert (exp->tp.pro.code);
 
$$ = $1;
}
;
 
expression:
INTEGER {
$$ = make_integer_constant ($1);
}
|variable_ref {
$$ = $1;
}
|expression tl_PLUS expression {
struct prod_token_parm_item *tok = $2;
struct prod_token_parm_item *op1 = $1;
struct prod_token_parm_item *op2 = $3;
int type_code = get_common_type (op1, op2);
if (!type_code)
YYERROR;
$$ = make_plus_expression (tok, op1, op2, type_code, EXP_PLUS);
}
|expression tl_MINUS expression %prec tl_PLUS {
struct prod_token_parm_item *tok = $2;
struct prod_token_parm_item *op1 = $1;
struct prod_token_parm_item *op2 = $3;
int type_code = get_common_type (op1, op2);
if (!type_code)
YYERROR;
$$ = make_plus_expression (tok, op1, op2, type_code, EXP_MINUS);
}
|expression EQUALS expression {
struct prod_token_parm_item *tok = $2;
struct prod_token_parm_item *op1 = $1;
struct prod_token_parm_item *op2 = $3;
int type_code = NUMERIC_TYPE (op1);
if (!type_code)
YYERROR;
$$ = make_plus_expression
(tok, op1, op2, type_code, EXP_EQUALS);
}
|variable_ref ASSIGN expression {
struct prod_token_parm_item *tok = $2;
struct prod_token_parm_item *op1 = $1;
struct prod_token_parm_item *op2 = $3;
int type_code = NUMERIC_TYPE (op1);
if (!type_code)
YYERROR;
$$ = make_plus_expression
(tok, op1, op2, type_code, EXP_ASSIGN);
}
|function_invocation {
$$ = $1;
}
;
 
function_invocation:
NAME LEFT_PARENTHESIS expressions_with_commas_opt 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;
tree type;
 
tok = $1;
prod = make_production (PROD_FUNCTION_INVOCATION, tok);
SYMBOL_TABLE_NAME (prod) = tok;
PARAMETERS (prod) = reverse_prod_list ($3);
SYMBOL_TABLE_NAME ((&search_prod)) = tok;
search_prod.category = token_category;
proto = lookup_tree_name (&search_prod);
if (!proto)
{
error ("%Hfunction prototype not found for %q.*s",
&tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
YYERROR;
}
EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
NUMERIC_TYPE (prod) = NUMERIC_TYPE (proto);
/* Count the expressions and ensure they match the prototype. */
for (exp_proto_count = 0, exp_proto = PARAMETERS (proto);
exp_proto; exp_proto = exp_proto->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)
{
error ("%Hexpression count mismatch %q.*s with prototype",
&tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
YYERROR;
}
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)
{
gcc_assert (exp);
gcc_assert (exp_proto);
gcc_assert (exp->tp.pro.code);
 
var = VARIABLE (exp_proto);
 
gcc_assert (var);
gcc_assert (var->tp.pro.code);
 
parms = tree_code_add_parameter (parms, var->tp.pro.code,
exp->tp.pro.code);
}
type = tree_code_get_type (NUMERIC_TYPE (prod));
prod->tp.pro.code = tree_code_get_expression (EXP_FUNCTION_INVOCATION, type,
proto->tp.pro.code,
nreverse (parms),
NULL, tok->tp.tok.location);
$$ = prod;
}
;
 
expressions_with_commas_opt:
/* Nil. */ {
$$ = 0
}
|expressions_with_commas { $$ = $1 }
;
 
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;
SYMBOL_TABLE_NAME ((&search_prod)) = tok;
search_prod.category = token_category;
symbol_table_entry = lookup_tree_name (&search_prod);
if (!symbol_table_entry)
{
error ("%Hvariable %q.*s not defined",
&tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
YYERROR;
}
 
prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
type = tree_code_get_type (NUMERIC_TYPE (prod));
if (!NUMERIC_TYPE (prod))
YYERROR;
OP1 (prod) = $1;
 
prod->tp.pro.code =
tree_code_get_expression (EXP_REFERENCE, type,
symbol_table_entry->tp.pro.code, NULL, NULL,
tok->tp.tok.location);
$$ = prod;
}
;
 
init_opt:
/* Nil. */ {
$$ = 0;
}
|init {
/* Pass the initialization value up. */
$$ = $1;
};
 
init:
ASSIGN init_element {
$$ = $2;
}
;
 
init_element:
INTEGER {
$$ = make_integer_constant ($1);
}
;
 
%%
 
/* Print a token VALUE to file FILE. Ignore TYPE which is the token
type. */
 
void
print_token (FILE *file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value)
{
struct prod_token_parm_item *tok;
unsigned int ix;
 
tok = value;
fprintf (file, "%d \"", LOCATION_LINE (tok->tp.tok.location));
for (ix = 0; ix < tok->tp.tok.length; ix++)
fprintf (file, "%c", tok->tp.tok.chars[ix]);
 
fprintf (file, "\"");
}
 
/* Output a message ERROR_MESSAGE from the parser. */
static void
yyerror (const char *error_message)
{
struct prod_token_parm_item *tok;
 
tok = yylval;
if (tok)
error ("%H%s", &tok->tp.tok.location, error_message);
else
error ("%s", error_message);
}
 
/* 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;
 
while (current)
{
gcc_assert (current->category == production_category);
 
next = current->tp.pro.next;
current->tp.pro.next = prev;
prev = current;
current = next;
}
return prev;
}
 
/* Ensure TYPE is not VOID. Use NAME as the token for the error location. */
 
static void
ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
{
if (type == VOID_TYPE)
error ("%Htype must not be void in this context",
&name->tp.tok.location);
}
 
/* Check TYPE1 and TYPE2 which are integral types. Return the lowest
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;
if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
return UNSIGNED_INT;
 
return SIGNED_INT;
}
 
/* Check type (TYPE_NUM) and expression (EXP) match. Return the 1 if
OK else 0. Must be exact match - same name unless it is an
integral type. */
 
static int
check_type_match (int type_num, struct prod_token_parm_item *exp)
{
switch (type_num)
{
case SIGNED_INT:
case UNSIGNED_INT:
case SIGNED_CHAR:
case UNSIGNED_CHAR:
switch (NUMERIC_TYPE (exp))
{
case SIGNED_INT:
case UNSIGNED_INT:
case SIGNED_CHAR:
case UNSIGNED_CHAR:
return 1;
 
case VOID_TYPE:
default:
gcc_unreachable ();
}
break;
 
case VOID_TYPE:
default:
gcc_unreachable ();
 
}
}
 
/* 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;
}
 
 
/* Build a PROD_PLUS_EXPRESSION. This is uses for PLUS, MINUS, ASSIGN
and EQUALS expressions. */
 
static struct prod_token_parm_item *
make_plus_expression (struct prod_token_parm_item *tok,
struct prod_token_parm_item *op1,
struct prod_token_parm_item *op2,
int type_code, int prod_code)
{
struct prod_token_parm_item *prod;
tree type;
 
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) = type_code;
type = tree_code_get_type (type_code);
 
gcc_assert (type);
 
OP1 (prod) = op1;
OP2 (prod) = op2;
 
prod->tp.pro.code = tree_code_get_expression (prod_code, type,
op1->tp.pro.code,
op2->tp.pro.code, NULL,
tok->tp.tok.location);
 
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)
{
case STATIC:
STORAGE_CLASS (prod) = STATIC_STORAGE;
break;
 
case AUTOMATIC:
STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
break;
 
case EXTERNAL_DEFINITION:
STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
break;
 
case EXTERNAL_REFERENCE:
STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
break;
 
default:
gcc_unreachable ();
}
}
 
/* Set parse trace. */
 
void
treelang_debug (void)
{
if (option_parser_trace)
yydebug = 1;
}
 
#ifdef __XGETTEXT__
/* Depending on the version of Bison used to compile this grammar,
it may issue generic diagnostics spelled "syntax error" or
"parse error". To prevent this from changing the translation
template randomly, we list all the variants of this particular
diagnostic here. Translators: there is no fine distinction
between diagnostics with "syntax error" in them, and diagnostics
with "parse error" in them. It's okay to give them both the same
translation. */
const char d1[] = N_("syntax error");
const char d2[] = N_("parse error");
const char d3[] = N_("syntax error; also virtual memory exhausted");
const char d4[] = N_("parse error; also virtual memory exhausted");
const char d5[] = N_("syntax error: cannot back up");
const char d6[] = N_("parse error: cannot back up");
#endif
/Make-lang.in
0,0 → 1,312
# Top level makefile fragment for TREELANG For GCC. -*- makefile -*-
 
# Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005,
# 2006, 2007 Free Software Foundation, Inc.
 
#This file is part of GCC.
 
#GCC is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 3, or (at your option)
#any later version.
 
#GCC is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
 
#You should have received a copy of the GNU General Public License
#along with GCC; see the file COPYING3. If not see
#<http://www.gnu.org/licenses/>.
 
 
# This file provides the language dependent support in the main Makefile.
# Each language makefile fragment must provide the following targets:
#
# foo.all.cross, foo.start.encap, foo.rest.encap,
# foo.install-common, foo.install-man, foo.install-info, foo.dvi, foo.pdf
# foo.html, foo.uninstall,
# foo.mostlyclean, foo.clean, foo.distclean,
# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4
#
# where `foo' is the name of the language.
#
# It should also provide rules for:
#
# - making any compiler driver (eg: gcc)
# - the compiler proper (eg: tree1)
# - define the names for selecting the language in LANGUAGES.
#
 
## note program-prefix and program-suffix options are not supported
## just program_transform_name which is a sed script to transform the
## names
 
TREELANGSED = sed
TREELANGSEDFLAGS = -n
 
GCC_EXTRAS = -B./ -B$(build_tooldir)/bin/ -isystem $(build_tooldir)/include
 
# ./xgcc is the just built compiler. See GCC_FOR_TARGET in the GCC Makefile.in.
# If this can't be found, you probably have not done a bootstrap of GCC,
# which you need to do.
 
# GCC_FOR_TREELANG = ./xgcc $(GCC_EXTRAS)
 
TREE_GENERATED = lex.c parse.c parse.h parse.output
# We need to use something other than treelang here because the directory
# is called treelang
TREE_EXES = gtreelang
 
#strict warnings for treelang
treelang-warn = $(STRICT_WARN)
# bison emits some unused static arrays (yytoknum)
treelang/parse.o-warn = -Wno-error
# flex produces 'no previous prototype' warnings
treelang/lex.o-warn = -Wno-error
 
#
# Define the names for selecting treelang in LANGUAGES.
 
.phony: treelang
 
treelang:treelang.done
 
treelang.done: gtreelang$(exeext) tree1$(exeext)
$(STAMP) treelang.done
 
# no preprocessor
 
# core compiler
tree1$(exeext): treelang/tree1.o treelang/treetree.o treelang/tree-convert.o \
treelang/lex.o treelang/parse.o \
$(BACKEND) $(LIBSDEPS) attribs.o
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
treelang/tree1.o treelang/treetree.o treelang/tree-convert.o \
treelang/lex.o treelang/parse.o \
$(BACKEND) $(LIBS) attribs.o
 
# Create the compiler driver treelang.
gtreelang$(exeext): $(GCC_OBJS) version.o prefix.o intl.o $(EXTRA_GCC_OBJS) \
$(LIBDEPS) treelang/spec.o
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ treelang/spec.o \
$(GCC_OBJS) version.o prefix.o intl.o $(EXTRA_GCC_OBJS) $(LIBS)
 
 
 
#
# Compiling object files from source files.
 
# object file makes
 
treelang/tree1.o: treelang/tree1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(FLAGS_H) toplev.h $(GGC_H) $(TREE_H) $(DIAGNOSTIC_H) treelang/treelang.h \
input.h treelang/treetree.h options.h opts.h \
treelang/treetree.h gt-treelang-tree1.h gtype-treelang.h
 
treelang/treetree.o: treelang/treetree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(FLAGS_H) output.h $(RTL_H) $(GGC_H) toplev.h \
$(VARRAY_H) $(LANGHOOKS_DEF_H) langhooks.h treelang/treelang.h input.h \
treelang/treetree.h treelang/parse.h $(TARGET_H)
 
treelang/tree-convert.o: treelang/tree-convert.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(DIAGNOSTIC_H) $(TREE_H) $(FLAGS_H) toplev.h langhooks.h $(TM_H)
 
treelang/spec.o: treelang/spec.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(DIAGNOSTIC_H) $(TREE_H) $(FLAGS_H) toplev.h langhooks.h $(TM_H)
 
treelang/parse.o: treelang/parse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(DIAGNOSTIC_H) treelang/treelang.h input.h treelang/treetree.h \
toplev.h
 
treelang/lex.o: treelang/lex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(DIAGNOSTIC_H) $(TREE_H) treelang/treelang.h input.h \
treelang/parse.h toplev.h
 
# generated files the files from lex and yacc are put into the source
# directory in case someone wants to build but does not have
# lex/yacc
 
treelang.srcextra: treelang/parse.c treelang/parse.h treelang/lex.c
-cp -p $^ $(srcdir)/treelang
 
treelang/lex.c: treelang/lex.l
-$(FLEX) $(FLEXFLAGS) -o$@ $<
 
treelang/parse.c treelang/parse.h treelang/parse.output: treelang/parse.y
-$(BISON) $(BISONFLAGS) -v --defines --output=treelang/parse.c $<
 
# -v
 
#
# Build hooks:
 
treelang.all.cross:
_error_not_here_yet - havent even thought about it - it may even work
 
treelang.start.encap:
treelang.rest.encap:
treelang.man:
treelang.srcman:
 
treelang.tags: force
cd $(srcdir)/treelang; etags -o TAGS.sub *.y *.l *.c *.h; \
etags --include TAGS.sub --include ../TAGS.sub
 
treelang.info: doc/treelang.info
 
treelang.srcinfo: doc/treelang.info
-cp -p $^ $(srcdir)/doc
 
treelang.dvi: doc/treelang.dvi
 
treelang.pdf: doc/treelang.pdf
 
TEXI_TREELANG_FILES = treelang/treelang.texi \
$(gcc_docdir)/include/gcc-common.texi \
$(gcc_docdir)/include/gpl.texi \
$(gcc_docdir)/include/fdl.texi \
$(gcc_docdir)/include/funding.texi \
gcc-vers.texi
 
doc/treelang.info: $(TEXI_TREELANG_FILES)
$(MAKEINFO) $(MAKEINFOFLAGS) -I $(gcc_docdir)/include -o $@ $<
 
doc/treelang.dvi: $(TEXI_TREELANG_FILES)
$(TEXI2DVI) -I $(abs_docdir)/include -o $@ $<
 
doc/treelang.pdf: $(TEXI_TREELANG_FILES)
$(TEXI2PDF) -I $(abs_docdir)/include -o $@ $<
 
treelang.html: $(build_htmldir)/treelang/index.html
 
$(build_htmldir)/treelang/index.html: $(TEXI_TREELANG_FILES)
$(mkinstalldirs) $(@D)
rm -f $(@D)/*
$(TEXI2HTML) -I $(gcc_docdir)/include -I $(srcdir)/treelang -o $(@D) $<
 
#
# Install hooks:
 
# Install
.phony:treelang.install.common
.phony:treelang.install
 
treelang.install treelang.install.common treelang.install-common: treelang.install.common.done
 
treelang.install.common.done: installdirs treelang.done
for name in $(TREE_EXES); \
do \
if [ -f $$name ] ; then \
name2="`echo \`basename $$name\` | sed -e '$(program_transform_name)' `"; \
rm -f $(DESTDIR)$(bindir)/$$name2$(exeext); \
echo $(INSTALL_PROGRAM) $$name$(exeext) $(DESTDIR)$(bindir)/$$name2$(exeext); \
$(INSTALL_PROGRAM) $$name$(exeext) $(DESTDIR)$(bindir)/$$name2$(exeext); \
chmod a+x $(DESTDIR)$(bindir)/$$name2$(exeext); \
fi ; \
done
$(STAMP) treelang.install.common.done
 
# We might not be able to build the info files
treelang.install-info: $(DESTDIR)$(infodir)/treelang.info
 
treelang.install-man:
 
treelang.uninstall:
for name in $(TREE_EXES); \
do \
echo $$name; \
name2="`echo $$name | sed -e '$(program_transform_name)' `"; \
echo becomes $$name2; \
echo -rm -rf $(DESTDIR)$(bindir)/$$name2$(exeext); \
rm -rf $(DESTDIR)$(bindir)/$$name2$(exeext); \
done
-rm treelang.install.common.done
 
#
# Clean hooks:
# A lot of the ancillary files are deleted by the main makefile.
# We just have to delete files specific to us.
 
treelang.mostlyclean:
for name in $(TREE_EXES); \
do \
echo deleting $$name; \
if [ -f treelang/$$name$(exeext) ] ; then \
rm -f treelang/$$name$(exeext); \
fi ; \
done
-rm -f treelang/*$(objext)
-rm -f treelang/*$(coverageexts)
-rm treelang.done
 
 
treelang.clean: treelang.mostlyclean
 
treelang.distclean: treelang.clean
-rm -f treelang/config.status
-rm -f treelang/*.output
 
treelang.maintainer-clean: treelang.distclean
for name in $(TREE_GENERATED); \
do \
if [ -f $(srcdir)/treelang/$$name ] ; then \
echo deleting $(srcdir)/treelang/$$name; \
rm -f $(srcdir)/treelang/$$name; \
fi ; \
done
-rm -R $(srcdir)/treelang/*~
 
 
#
# Stage hooks:
# The main makefile has already created stage?/treelang.
 
treelang.stage1: stage1-start
-mv treelang/*$(objext) stage1/treelang
treelang.stage2: stage2-start
-mv treelang/*$(objext) stage2/treelang
treelang.stage3: stage3-start
-mv treelang/*$(objext) stage3/treelang
treelang.stage4: stage4-start
-mv treelang/*$(objext) stage4/treelang
treelang.stageprofile: stageprofile-start
-mv treelang/*$(objext) stageprofile/treelang
treelang.stagefeedback: stagefeedback-start
-mv treelang/*$(objext) stagefeedback/treelang
#
# Maintenance hooks:
 
# test hook
 
check-treelang: treelang.check
 
TESTSUITEDIR = testsuite
 
treelang.check: $(TESTSUITEDIR)/site.exp
-mkdir testsuite/treelang
 
# these three files are empty and it seems diff has trouble generating
# patch files for new empty files as required for cvs.
# STAMP does not cut it here as I need an empty file.
-rootme=`${PWD_COMMAND}`; export rootme; \
srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
cd testsuite; \
EXPECT=${EXPECT} ; export EXPECT ; \
if [ -f $${rootme}/../expect/expect ] ; then \
TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
export TCL_LIBRARY ; fi ; \
PATH=`cd ..;${PWD_COMMAND}`:$$PATH; export PATH; \
gcc_extras="-B`cd ..;${PWD_COMMAND}` -B`cd ..;${PWD_COMMAND}`/treelang"; export gcc_extras; \
$(RUNTEST) --tool treelang $(RUNTESTFLAGS)
 
# copy the output files from the current test to source ie say the new results are OK
treelang.check.fix: force
srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ;
-cp testsuite/treelang/*.out* t
-cp testsuite/treelang/*runpgm* t
-rm -f t/*nofilename
 
#
 
config.status: treelang/config-lang.in
/tree1.c
0,0 → 1,320
/* TREELANG Compiler almost main (tree1)
Called by GCC's toplev.c
 
Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
2007 Free Software Foundation, Inc.
 
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, 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; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>.
 
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
 
---------------------------------------------------------------------------
 
Written by Tim Josling 1999, 2000, 2001, based in part on other
parts of the GCC compiler. */
 
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "flags.h"
#include "toplev.h"
#include "version.h"
 
#include "ggc.h"
#include "tree.h"
#include "cgraph.h"
#include "diagnostic.h"
 
#include "treelang.h"
#include "treetree.h"
#include "opts.h"
#include "options.h"
 
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 = "TREELANG - sample front end for GCC ";
 
/* Local prototypes. */
 
void version (void);
 
/* Global variables. */
 
extern struct cbl_tree_struct_parse_tree_top* parse_tree_top;
 
/*
Options.
*/
 
/* Trace the parser. */
unsigned int option_parser_trace = 0;
 
/* Trace the lexical analysis. */
 
unsigned int option_lexer_trace = 0;
 
/* Warning levels. */
 
/* Local variables. */
 
/* This is 1 if we have output the version string. */
 
static int version_done = 0;
 
/* Variable nesting level. */
 
static unsigned int work_nesting_level = 0;
 
/* Prepare to handle switches. */
unsigned int
treelang_init_options (unsigned int argc ATTRIBUTE_UNUSED,
const char **argv ATTRIBUTE_UNUSED)
{
return CL_Treelang;
}
 
/* Process a switch - called by opts.c. */
int
treelang_handle_option (size_t scode, const char *arg ATTRIBUTE_UNUSED,
int value)
{
enum opt_code code = (enum opt_code) scode;
 
switch (code)
{
case OPT_v:
if (!version_done)
{
fputs (language_string, stdout);
fputs (version_string, stdout);
fputs ("\n", stdout);
version_done = 1;
}
break;
 
case OPT_y:
option_lexer_trace = 1;
option_parser_trace = 1;
break;
 
case OPT_fparser_trace:
option_parser_trace = value;
break;
 
case OPT_flexer_trace:
option_lexer_trace = value;
break;
 
default:
gcc_unreachable ();
}
 
return 1;
}
 
/* Language dependent parser setup. */
 
bool
treelang_init (void)
{
#ifndef USE_MAPPED_LOCATION
input_filename = main_input_filename;
#else
linemap_add (&line_table, LC_ENTER, false, main_input_filename, 1);
#endif
 
/* This error will not happen from GCC as it will always create a
fake input file. */
if (!input_filename || input_filename[0] == ' ' || !input_filename[0])
{
if (!version_done)
{
fprintf (stderr, "No input file specified, try --help for help\n");
exit (1);
}
 
return false;
}
 
yyin = fopen (input_filename, "r");
if (!yyin)
{
fprintf (stderr, "Unable to open input file %s\n", input_filename);
exit (1);
}
 
#ifdef USE_MAPPED_LOCATION
linemap_add (&line_table, LC_RENAME, false, "<built-in>", 1);
linemap_line_start (&line_table, 0, 1);
#endif
 
/* Init decls, etc. */
treelang_init_decl_processing ();
 
return true;
}
 
/* Language dependent wrapup. */
 
void
treelang_finish (void)
{
fclose (yyin);
}
 
/* Parse a file. Debug flag doesn't seem to work. */
 
void
treelang_parse_file (int debug_flag ATTRIBUTE_UNUSED)
{
#ifdef USE_MAPPED_LOCATION
source_location s;
linemap_add (&line_table, LC_RENAME, false, main_input_filename, 1);
s = linemap_line_start (&line_table, 1, 80);
input_location = s;
#else
input_line = 1;
#endif
 
treelang_debug ();
yyparse ();
cgraph_finalize_compilation_unit ();
#ifdef USE_MAPPED_LOCATION
linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
#endif
cgraph_optimize ();
}
 
/* Allocate SIZE bytes and clear them. Not to be used for strings
which must go in stringpool. */
 
void *
my_malloc (size_t size)
{
void *mem;
mem = ggc_alloc (size);
if (!mem)
{
fprintf (stderr, "\nOut of memory\n");
abort ();
}
memset (mem, 0, size);
return mem;
}
 
/* Look up a name in PROD->SYMBOL_TABLE_NAME in the symbol table;
return the symbol table entry from the symbol table if found there,
else 0. */
 
struct 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;
 
sanity_check (prod);
tok = SYMBOL_TABLE_NAME (prod);
sanity_check (tok);
for (this = symbol_table; this; this = this->tp.pro.next)
{
sanity_check (this);
this_tok = this->tp.pro.main_token;
sanity_check (this_tok);
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, LOCATION_LINE (tok->tp.tok.location),
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, LOCATION_LINE (tok->tp.tok.location),
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);
sanity_check (prod);
if (lookup_tree_name (prod))
{
error ("%HDuplicate name %q.*s.", &tok->tp.tok.location,
tok->tp.tok.length, tok->tp.tok.chars);
return 1;
}
prod->tp.pro.next = symbol_table;
NESTING_LEVEL (prod) = work_nesting_level;
symbol_table = prod;
return 0;
}
 
/* Create a struct productions of type TYPE, main token MAIN_TOK. */
 
struct 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;
}
 
/* Abort if ITEM is not a valid structure, based on 'category'. */
 
void
sanity_check (struct prod_token_parm_item *item)
{
switch (item->category)
{
case token_category:
case production_category:
case parameter_category:
break;
default:
gcc_unreachable ();
}
}
 
/* New garbage collection regime see gty.texi. */
#include "gt-treelang-tree1.h"
/*#include "gt-treelang-treelang.h"*/
#include "gtype-treelang.h"
/lang.opt
0,0 → 1,41
; Options for the treelang front end.
; Copyright (C) 2003, 2007 Free Software Foundation, Inc.
;
; This file is part of GCC.
;
; GCC is free software; you can redistribute it and/or modify it under
; the terms of the GNU General Public License as published by the Free
; Software Foundation; either version 3, or (at your option) any later
; version.
;
; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
; WARRANTY; without even the implied warranty of MERCHANTABILITY or
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; for more details.
;
; You should have received a copy of the GNU General Public License
; along with GCC; see the file COPYING3. If not see
; <http://www.gnu.org/licenses/>.
 
; See the GCC internals manual for a description of this file's format.
 
; Please try to keep this file in ASCII collating order.
 
Language
Treelang
 
flexer-trace
Treelang
Trace lexical analysis
 
fparser-trace
Treelang
Trace the parsing process
 
v
Treelang
 
y
Treelang
 
; This comment is to ensure we retain the blank line above.
/lex.l
0,0 → 1,300
/* -*- c -*- = mode for emacs editor
 
TREELANG lexical analysis
 
---------------------------------------------------------------------
 
Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, 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; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
---------------------------------------------------------------------
Written by Tim Josling 1999-2001, based in part on other parts of
the GCC compiler. */
 
%{
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "input.h"
#include "tree.h"
 
/* Token defs. */
#include "treelang.h"
#include "parse.h"
#include "treetree.h"
#include "toplev.h"
 
extern int option_lexer_trace;
 
int yylex (void);
void update_yylval (int a);
 
static int next_tree_charno = 1;
static int lineno = 1;
static void update_lineno_charno (void);
static void dump_lex_value (int lexret);
#define SAVE_RETURN(a) {update_yylval (a); if (option_lexer_trace)\
{fprintf (stderr, "\nlexer returning"); dump_lex_value (a);} return a;}
#define NOT_RETURN(a) {update_yylval (a); if (option_lexer_trace)\
{fprintf (stderr, "\nlexer swallowing"); dump_lex_value (a);}}
#ifndef USE_MAPPED_LOCATION
#undef LINEMAP_POSITION_FOR_COLUMN
#define LINEMAP_POSITION_FOR_COLUMN(INPUT, LINETABLE, COL)
#endif
%}
 
%option nostack
%option nounput
%option noyywrap
%option pointer
%option nodefault
 
%%
 
{
/* ??? Should really allocate only what we need. */
yylval = my_malloc (sizeof (struct prod_token_parm_item));
LINEMAP_POSITION_FOR_COLUMN (input_location, &line_table,
next_tree_charno);
((struct prod_token_parm_item *)yylval)->tp.tok.location = input_location;
((struct prod_token_parm_item *)yylval)->tp.tok.charno = next_tree_charno;
}
 
[ \n\t]+ {
update_lineno_charno ();
NOT_RETURN (WHITESPACE);
}
"//".* {
/* Comment. */
update_lineno_charno ();
NOT_RETURN (COMMENT);
}
"{" {
update_lineno_charno ();
SAVE_RETURN (LEFT_BRACE);
}
"}" {
update_lineno_charno ();
SAVE_RETURN (RIGHT_BRACE);
}
"(" {
update_lineno_charno ();
SAVE_RETURN (LEFT_PARENTHESIS);
}
")" {
update_lineno_charno ();
SAVE_RETURN (RIGHT_PARENTHESIS);
}
"," {
update_lineno_charno ();
SAVE_RETURN (COMMA);
}
";" {
update_lineno_charno ();
SAVE_RETURN (SEMICOLON);
}
"+" {
update_lineno_charno ();
SAVE_RETURN (tl_PLUS);
}
"-" {
update_lineno_charno ();
SAVE_RETURN (tl_MINUS);
}
"=" {
update_lineno_charno ();
SAVE_RETURN (ASSIGN);
}
"==" {
update_lineno_charno ();
SAVE_RETURN (EQUALS);
}
[+-]?[0-9]+ {
update_lineno_charno ();
SAVE_RETURN (INTEGER);
}
"external_reference" {
update_lineno_charno ();
SAVE_RETURN (EXTERNAL_REFERENCE);
}
"external_definition" {
update_lineno_charno ();
SAVE_RETURN (EXTERNAL_DEFINITION);
}
"static" {
update_lineno_charno ();
SAVE_RETURN (STATIC);
}
"automatic" {
update_lineno_charno ();
SAVE_RETURN (AUTOMATIC);
}
"int" {
update_lineno_charno ();
SAVE_RETURN (INT);
}
"char" {
update_lineno_charno ();
SAVE_RETURN (CHAR);
}
"void" {
update_lineno_charno ();
SAVE_RETURN (VOID);
}
"unsigned" {
update_lineno_charno ();
SAVE_RETURN (UNSIGNED);
}
"return" {
update_lineno_charno ();
SAVE_RETURN (tl_RETURN);
}
"if" {
update_lineno_charno ();
SAVE_RETURN (IF);
}
"else" {
update_lineno_charno ();
SAVE_RETURN (ELSE);
}
[A-Za-z_]+[A-Za-z_0-9]* {
update_lineno_charno ();
update_yylval (NAME);
if (option_lexer_trace)
{
fprintf (stderr, "\nlexer returning");
dump_lex_value (NAME);
}
return NAME;
}
[^\n] {
update_lineno_charno ();
error ("%HUnrecognized character %qc.",
&((struct prod_token_parm_item *)yylval)->tp.tok.location,
yytext[0]);
}
 
%%
 
/*
Update line number (1-) and character number (1-). Call this
before processing the token. */
 
static void
update_lineno_charno (void)
{
/* Update the values we send to caller in case we sometimes don't
tell them about all the 'tokens' eg comments etc. */
int yyl;
LINEMAP_POSITION_FOR_COLUMN (input_location, &line_table,
next_tree_charno);
((struct prod_token_parm_item *)yylval)->tp.tok.location = input_location;
((struct prod_token_parm_item *)yylval)->tp.tok.charno = next_tree_charno;
 
for ( yyl = 0; yyl < yyleng; ++yyl )
{
if ( yytext[yyl] == '\n' )
{
#ifdef USE_MAPPED_LOCATION
source_location s = linemap_line_start (&line_table, ++lineno,
80);
input_location = s;
#else
input_line = ++lineno;
#endif
next_tree_charno = 1;
}
else
next_tree_charno++;
}
}
 
/* Fill in the fields of yylval - the value of the token. The token
type is A. */
void
update_yylval (int a)
{
struct 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 = (unsigned char*) get_string (yytext, yyleng);
}
 
/* Trace the value LEXRET and the position and token details being
returned by the lexical analyser. */
 
static void
dump_lex_value (int lexret)
{
int ix;
 
fprintf (stderr, " %d l:%d c:%d ln:%d text=", lexret,
LOCATION_LINE (((struct prod_token_parm_item *)
yylval)->tp.tok.location),
((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]);
}
fprintf (stderr, " in hex:");
for (ix = 0; ix < yyleng; ix++)
{
fprintf (stderr, " %2.2x", yytext[ix]);
}
fprintf (stderr, "\n");
}
 
/lang-specs.h
0,0 → 1,39
/* Definitions for specs for TREELANG
 
The format of the specs file is documented in gcc.c
 
Copyright (C) 1995, 96-98, 1999, 2000, 2001, 2002, 2007
Free Software Foundation, Inc.
 
This file is part of GCC.
 
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
 
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
 
/*
This is the contribution to the `default_compilers' array in GCC.c for
treelang.
This file must compile with 'traditional', so no ANSI string concatenations
*/
 
{".tree", "@treelang", NULL, 0, 0},
{".TREE", "@treelang", NULL, 0, 0},
{".tre", "@treelang", NULL, 0, 0},
{".TRE", "@treelang", NULL, 0, 0},
{"@treelang",
"%{!E:tree1 %i %(cc1_options) %{J*} %{I*}\
%{!fsyntax-only:%(invoke_as)}}", NULL , 0, 0
},
/treetree.h
0,0 → 1,66
/* TREELANG Compiler definitions for interfacing to treetree.c
(compiler back end interface).
 
Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2007 Free Software Foundation, Inc.
 
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, 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; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>.
 
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
 
---------------------------------------------------------------------------
 
Written by Tim Josling 1999, 2000, 2001, based in part on other
parts of the GCC compiler. */
 
tree tree_code_init_parameters (void);
tree tree_code_add_parameter (tree list, tree proto_exp, tree exp);
tree tree_code_get_integer_value (unsigned char *chars, unsigned int length);
void tree_code_generate_return (tree type, tree exp);
void tree_ggc_storage_always_used (void *m);
tree tree_code_get_expression (unsigned int exp_type, tree type, tree op1,
tree op2, tree op3, location_t loc);
tree tree_code_get_numeric_type (unsigned int size1, unsigned int sign1);
void tree_code_create_function_initial (tree prev_saved,
location_t loc);
void tree_code_create_function_wrapup (location_t loc);
tree tree_code_create_function_prototype (unsigned char* chars,
unsigned int storage_class,
unsigned int ret_type,
struct prod_token_parm_item* parms,
location_t loc);
tree tree_code_create_variable (unsigned int storage_class,
unsigned char* chars,
unsigned int length,
unsigned int expression_type,
tree init,
location_t loc);
void tree_code_output_expression_statement (tree code,
location_t loc);
void tree_code_if_start (tree exp, location_t loc);
void tree_code_if_else (location_t loc);
void tree_code_if_end (location_t loc);
tree tree_code_get_type (int type_num);
void treelang_init_decl_processing (void);
void treelang_finish (void);
bool treelang_init (void);
unsigned int treelang_init_options (unsigned int, const char **);
int treelang_handle_option (size_t scode, const char *arg, int value);
void treelang_parse_file (int debug_flag);
void push_var_level (void);
void pop_var_level (void);
const char* get_string (const char *s, size_t l);
/ChangeLog
0,0 → 1,1098
2007-10-07 Release Manager
 
* GCC 4.2.2 released.
 
2007-08-29 Nick Clifton <nickc@redhat.com>
 
* parse.y: Change copyright header to refer to version 3 of the
GNU General Public License and to point readers at the COPYING3
file and the FSF's license web page.
* lex.l: Likewise.
* lang.opt: Likewise.
* lang-specs.h: Likewise.
* treelang.h: Likewise.
* config-lang.in: Likewise.
* tree-convert.c: Likewise.
* treetree.c: Likewise.
* tree1.c: Likewise.
* Make-lang.in: Likewise.
* treetree.h: Likewise.
* spec.c: Likewise.
2007-07-19 Release Manager
 
* GCC 4.2.1 released.
 
2007-05-13 Release Manager
 
* GCC 4.2.0 released.
 
2007-02-26 Brooks Moses <brooks.moses@codesourcery.com>
 
* treelang.texi: Standardize title page, remove version number
from copyright page.
 
2006-10-10 Brooks Moses <bmoses@stanford.edu>
 
* Make-lang.in: Added "treelang.pdf" target support.
 
2006-07-28 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
 
* Make-lang.in: Use $(HEADER_H) instead of header.h in dependencies.
 
2006-06-17 Karl Berry <karl@gnu.org>
 
* treelang.texi (@dircategory): Use "Software development"
instead of "Programming", following the Free Software Directory.
 
2006-06-06 Mike Stump <mrs@apple.com>
 
* Make-lang.in: Rename to gcc_htmldir to build_htmldir to avoid
installing during build.
 
2006-05-23 Carlos O'Donell <carlos@codesourcery.com>
 
* Make-lang.in: Rename htmldir to gcc_htmldir.
 
2006-05-16 H.J. Lu <hongjiu.lu@intel.com>
 
PR driver/26885
* Make-lang.in (gtreelang$(exeext)): Replace gcc.o with
$(GCC_OBJS).
 
2006-05-14 H.J. Lu <hongjiu.lu@intel.com>
 
* Make-lang.in (treelang/treetree.o): Add dependency on
$(TARGET_H).
 
2006-04-22 Matthias Klose <doko@debian.org>
 
* Make-lang.in (treelang.check): Don't set and pass TRANSFORM.
 
2006-03-29 Carlos O'Donell <caros@codesourcery.com>
 
* Make-lang.in: Rename docdir to gcc_docdir.
 
 
 
* Make-lang.in (.phony): Remove TREELANG.
(TREELANG): Remove.
 
2006-01-21 Joseph S. Myers <joseph@codesourcery.com>
 
* spec.c (lang_specific_driver): Update copyright notice date.
 
 
 
* spec.c (lang_specific_spec_functions): Remove.
 
 
 
* Make-lang.in (treelang.distdir): Remove.
 
 
 
* Make-lang.in (treelang.all.build, treelang.install-normal): Remove.
 
 
 
* Make-lang.in: Remove all dependencies on s-gtype.
 
2005-12-05 Richard Guenther <rguenther@suse.de>
 
* treetree.c (tree_code_if_start, tree_code_create_variable,
tree_code_generate_return, tree_code_get_expression,
tree_code_add_parameter): Use fold_convert where appropriate.
 
2005-11-07 James A. Morrison <phython@gcc.gnu.org>
 
PR treelang/24066
* treetree.c (LANG_HOOKS_ATTRIBUTE_TABLE): Set to
treelang_attribute_table.
(handle_attribute): New function.
(treelang_attribute_table): New attribute table.
 
2005-09-23 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
 
* parse.y : Changed pointer declaration from "type* var" to "type *var"
Removed trailing space. Wrap long lines.
 
2005-09-23 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
 
* parse.y : Fixed two compile warnings in "error" and "warning"
invocations. Removed trailing periods in messages. Decapitalized the
first word of each.
 
2005-08-07 James A. Morrison <phython@gcc.gnu.org>
 
* tree-convert.c (convert): Use fold_build1 instead of
fold (build1.
 
2005-08-06 James A. Morrison <phython@gcc.gnu.org>
 
PR treelang/23072
* Make-lang.in: Remove old testing cruft.
 
2005-06-25 Kelley Cook <kcook@gcc.gnu.org>
 
* all files: Update FSF address in copyright headers.
 
2005-06-15 James A. Morrison <phython@gcc.gnu.org>
 
* parse.y (function_invocation): Reverse parameter list.
* treetree.c (tree_code_get_expression): Don't reverse parameter list.
 
2005-06-12 Rafael ?vila de Esp?ndola <rafael.espindola@gmail.com>
 
* treetree.c (tree_code_get_expression): Call build_function_call_expr
to build function calls.
 
2005-05-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
 
* treelang/lex.l, treelang/parse.y: Don't include errors.h and
include toplev.h.
* treelang/Make-lang.in: Updates dependencies.
 
2005-05-02 Andrew Pinski <pinskia@physics.uc.edu>
 
PR treelang/21345
* parse.y (parameters_opt): Add semicolon at the end.
 
2005-04-29 Tom Tromey <tromey@redhat.com>
 
* treetree.c (poplevel): Updated for change to build_block.
 
2005-04-23 DJ Delorie <dj@redhat.com>
 
* parse.y: Adjust warning() callers.
 
2005-04-11 Richard Sandiford <rsandifo@redhat.com>
 
* lang.opt: Refer to the GCC internals documentation instead of c.opt.
 
2005-04-01 Andrew Pinski <pinskia@physics.uc.edu>
 
PR treelang/20604
* lang-spec.c: Simplify @treelang to what the other
languages do.
 
2005-04-01 Kazu Hirata <kazu@cs.umass.edu>
 
* treelang/treelang.texi: Fix typos.
* treelang/treetree.c: Fix comment typos.
 
2005-03-23 Joseph S. Myers <joseph@codesourcery.com>
 
* treetree.c (LANG_HOOKS_TRUTHVALUE_CONVERSION,
tree_lang_truthvalue_conversion): Remove.
* tree-convert.c: Don't call truthvalue_conversion.
 
2005-03-22 James A. Morrison <phython@gcc.gnu.org>
 
* treetree.c (tree_code_if_start): Use fold_buildN.
(tree_code_create_variable): Likewise.
(tree_code_generate_return): Likewise.
(tree_code_get_expression): Likewise.
(tree_code_add_parameter): Likewise.
 
2005-03-22 James A. Morrison <phython@gcc.gnu.org>
 
* treelang.h (struct parameter_part): Skip WHERE_TO_PUT_VAR_TREE
during GC.
 
2005-03-15 Zack Weinberg <zack@codesourcery.com>
 
* Make-lang.in (TEXI_TREELANG_FILES): Add gcc-vers.texi.
 
2005-03-06 James A. Morrison <phython@gcc.gnu.org>
 
PR other/20326
* Make-lang.in (gtreelang, treelang/spec.o): New targets.
* spec.c: New file.
 
2005-02-27 Kazu Hirata <kazu@cs.umass.edu>
 
* treelang.texi: Fix a typo.
 
2005-02-26 James A. Morrison <phython@gcc.gnu.org>
 
* parse.y (function_invocation, variable-ref, make_plus_expression):
Pass location to tree_code_get_expression.
* treetree.c (tree_code_generate_return): Set EXPR_LOCUS on retval.
(tree_code_get_expression): Wrap variable references in NOP_EXPRs and
set EXPR_LOCATION on ret1.
* treetree.h (tree_code_get_expression): Take the location of the
expression as an argument.
 
2005-02-26 James A. Morrison <phython@gcc.gnu.org>
 
* treelang.texi: Treelang does have warnings.
* treetree.c (tree_code_create_function_prototype): Don't set
TREE_USED and set TREE_PUBLIC, DECL_EXTERNAL, and TREE_STATIC
as few times as needed on the function declaration.
(tree_code_create_function_initial): Don't set TREE_USED,
TREE_ADDRESSABLE, but set TREE_STATIC on the function declaration.
(tree_code_create_variable): Don't set TREE_USED on VAR_DECL.
(tree_code_get_expression): Set TREE_USED for variable references
and function calls.
 
2005-02-26 James A. Morrison <phython@gcc.gnu.org>
 
* parse.y: Do comparisons as the type of the first expression.
* treetree.c (tree_code_get_integer_value): Build integer constants
with the proper type.
 
2005-02-26 James A. Morrison <phython@gcc.gnu.org>
 
* Make-lang.in: Remove commented out code.
* lang-specs.h: Always pass -dumpbase to tree1.
 
2005-02-25 James A. Morrrison <phython@gcc.gnu.org>
 
* treelang.texi: Remove extra contribution notice.
Split up some run-on sentences. Document function parameters
as optional. Indicate automatic variables can now be at any scope.
Mention literals are only signed if they are preceded by a unary
plus or minus. Clarify interoperability with C.
 
2005-02-25 James A. Morrison <phython@gcc.gnu.org>
 
* treelang.texi: Fix whitespacing.
 
2005-02-24 James A. Morrison <phython@gcc.gnu.org>
 
PR other/19896
* treetree.c (tree_code_create_variable): Initialize DECL_EXTERNAL,
TREE_PUBLIC, and TREE_STATIC for var_decl to zero. Don't call
rest_of_decl_compilation on static variables.
(pushdecl): Put DECL_EXPRs into the current BIND_EXPR for automatic
variables.
 
2005-02-24 James A. Morrison <phython@gcc.gnu.org>
 
PR other/19897
* parse.y: (function_prototype): Accept EXTERNAL_REFERENCE_STORAGE.
Move function parameters check from ...
(function): ...Here. Update call to tree_code_create_function_initial.
(function_invocation): Use expressions_with_commas_opt instead of
expressions_with_commas.
(expressions_with_commas_opt): New rule.
* treetree.c (tree_code_create_function_prototype): Create PARM_DECLs
for function parameters.
(tree_code_create_function_initial): Remove PARMS parameter.
Don't create PARM_DECLs for function parameters.
* treetree.h (tree_code_create_function_initial): Remove PARMS
parameter.
 
2005-02-23 Kazu Hirata <kazu@cs.umass.edu>
 
* parse.y: Update copyright.
 
2005-02-13 James A. Morrison <phython@gcc.gnu.org>
 
* treetree.c (tree_lang_type_for_mode): Return NULL_TREE for all non
scalar integer types.
 
2005-02-09 Richard Henderson <rth@redhat.com>
 
* treetree.c (treelang_init_decl_processing): Call
build_common_builtin_nodes.
 
2005-02-06 Joseph S. Myers <joseph@codesourcery.com>
 
* treelang.texi: Don't use local treelang version number. Don't
give last update date.
 
2005-02-01 James A. Morrison <phython@gcc.gnu.org>
 
* lex.l: Undef LINEMAP_POSITION_FOR_COLUMN before defining it.
 
2005-02-01 James A. Morrison <phython@gcc.gnu.org>
 
* parse.y: Reformat comments.
* treetree.c: Likewise.
* treetree.h: Likewise.
 
2004-10-24 James A. Morrison <phython@gcc.gnu.org>
 
* treetree.c (tree_code_generate_return): Wrap param declaration in
ENABLE_CHECKING.
 
2004-10-05 Zack Weinberg <zack@codesourcery.com>
 
* parse.y: Add list of diagnostic messages to insulate
translation template from version of yacc/bison used to
compile the grammar.
 
2004-10-02 James A. Morrison <phython@gcc.gnu.org>
 
PR other/17762
* lex.l: Include input.h and errors.h
(lineno): New variable.
(LINEMAP_POSITION_FOR_COLUMN): Define as noop when USE_MAPPED_LOCATION
is not defined.
Set column position with LINEMAP_POSITION_FOR_COLUMN.
Use error instead of fprintf.
Set input_location with the value returned by linemap_start_line when
USE_MAPPED_LOCATION is defined.
(dump_lex_value): Use LOCATION_LINE.
* parse.y: Include errors.h.
Use error and warning instead of fprintf.
(return): Move exp to rule scope and always set to $2. Test against
exp instead of $2.
(init): Set $$ to $2.
(print_token): Use LOCATION_LINE.
* tree1.c (treelang_init): Call treelang_init_decl_processing last.
Call linemap_add to set input_filename when USE_MAPPED_LOCATION is
defined.
(treelang_parse_file): Always start at line one.
Rename input_filename to main_input_filename when USE_MAPPED_LOCATION is
defined.
Leave main_input_filename when done parsing the input.
(insert_tree_name): Use error instead of fprintf.
* treetree.c (tree_code_get_expression): Wrap long line.
(tree_mark_addressable): Use %qD to print out DECLs.
 
2004-10-02 James A. Morrison <phython@gcc.gnu.org>
 
* parse.y: Use gcc_assert and gcc_unreachable instead of abort.
* tree1.c: Likewise.
* treetree.c: Likewise.
 
2004-10-02 James A. Morrison <phython@gcc.gnu.org>
 
* lex.l: Remove random whitespace.
* parse.y: Reformat copyright notice. Indent declarations.
Wrap long lines, unwrap short lines.
* tree1.c: Reformat copyright notice. Wrap long lines.
Remove random whitespace.
(lookup_tree_name): Use LOCATION_LINE.
* treetree.c: Reformat copyright notice. Wrap long lines.
Remove random whitespace.
 
2004-10-01 James A. Morrison <phython@gcc.gnu.org>
 
* parse.y (ELSE): Set tok to $1.
* treelang.texi: Wrap comments in @r{}. Indent example comments.
Use gcc when refering to the command line or website. Update function
definition.
 
2004-10-01 Jan Hubicka <jh@suse.cz>
 
* treetree.c (treeland_expand_function): Update call of
tree_rest_of_compilation.
 
2004-09-17 Jeffrey D. Oldham <oldham@codesourcery.com>
Zack Weinberg <zack@codesourcery.com>
 
* treetree.c: Update for new tree-class enumeration constants.
 
2004-09-15 Zack Weinberg <zack@codesourcery.com>
 
* Make-lang.in (treelang-warn): Set to $(STRICT_WARN).
 
2004-08-26 Nathan Sidwell <nathan@codesourcery.com>
 
* treetree.c (tree_code_get_integer_value): Fix build_int_cst call.
 
2004-08-24 Nathan Sidwell <nathan@codesourcery.com>
 
* treelang/treetree.c (treelang_init_decl_processing): Adjust
build_common_tree_nodes call.
 
2004-08-14 Nathan Sidwell <nathan@codesourcery.com>
 
* treetree.c (tree_code_get_integer_value): Use build_int_cst.
 
2004-07-31 James A. Morrison <phython@gcc.gnu.org>
 
* Make-lang.in (TREE_BE_LIBS): Remove.
(tree1): Depend on BACKEND and LIBDEPS. Use BACKEND and LIBS instead
of TREE_BE_LIBS.
* parse.y: Add variable_defs_opt before statements_opt.
Use tree_code_get_type instead of get_type_for_numeric_type.
Reformat long lines.
(parameters_opt): New rule.
(function_prototype): Use parameters_opt.
(return): Remove calls to print_token in error cases. Use VOID_TYPE.
(check_type_match): Use VOID_TYPE.
* lex.l (update_lineno_charno): Ensure INPUT_LINE starts at 1.
* tree1.c: Include version.h and cgraph.h
(treelang_parse_file): Call cgraph_finalize_compilation_unit and
cgraph_optimize.
* treelang.h (item): Remove extraneous GTY.
* treetree.h (get_type_for_numeric_type): Remove.
* treetree.c: Include tree-dump.h, tree-iterator.h, tree-gimple.h,
function.h, and cgraph.h. Don't include rtl.h
(keep_level_p): Remove.
(tree_push_atomic_type_decl): Remove.
(get_type_for_numeric_type): Remove.
(tree_code_get_numeric_type): Remove.
(global_bindings_p): Make static.
(getdecls): Likewise.
(insert_block): Likewise.
(tree_code_if_start): Create a COND_EXPR and add it to the tree
instead of creating rtl.
(tree_code_if_else): Create a BIND_EXPR if any variables were created
in the if statement.
(tree_code_end_if): Likewise.
(tree_code_create_function_prototype): Use tree_code_get_type.
Don't use SET_DECL_ASSEMBLER_NAME.
(tree_code_create_function_initial): Set DECL_ARTIFICIAL and
DECL_IGNORING_P on RESULT_DECL. Use tree_code_get_type. Don't call
layout_decl on RESULT_DECL. Don't call rtl expand functions.
(tree_code_create_function_wrapup): Don't call rtl expand functions.
Create a BIND_EXPR for each function. Dump original and gimplified
copies of the function tree. Gimplify function.
(tree_code_create_variable): Use tree_code_get_type. Don't call
layout_decl or expand_decl. Fold CONVERT_EXPRs.
(tree_code_generate_return): Fold CONVERT_EXPRs and MODIFY_EXPRs.
Add RETURN_EXPR to the current statement list. Don't call rtl expand
functions.
(tree_code_output_expression_statement): Append CODE to current
statement list.
(tree_code_get_expression): Fold expressions. Build a pointer to
a FUNCTION_TYPE intead of the called functions return type.
(struct binding_level): Add statement list STMTS.
(getstmtlist): New Function.
(pushlevel): Make static. Allocate an empty statement list.
(poplevel): Make static. Don't clear BLOCK_NODE's BLOCK_VARS.
Don't use DECL_ASSEMBLER_NAME.
(tree_push_type_decl): Set TYPE_NAME of TYPE_NODE to ID.
(treelang_init_decl_processing): Define basic types after unused types.
Don't call tree_push_atomic_type_decl.
(builtin_function): Don't call make_decl_rtl.
(treelang_expand_function). New Function.
 
2004-07-11 Joseph S. Myers <jsm@polyomino.org.uk>
 
* treetree.c (set_block): Remove.
(struct binding_level): Remove block_created_by_back_end.
(clear_binding_level): Likewise.
(tree_code_create_function_initial,
tree_code_create_function_wrapup): Call pushlevel and poplevel
directly rather than through hooks.
(poplevel): Don't handle block_created_by_back_end.
 
2004-04-07 Richard Henderson <rth@redhat.com>
 
* treetree.c (tree_mark_addressable): Don't put_var_into_stack.
 
2004-03-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
 
* treetree.c (tree_lang_signed_or_unsigned_type): Use TYPE_UNSIGNED,
not TREE_UNSIGNED.
 
2004-03-21 Joseph S. Myers <jsm@polyomino.org.uk>
 
* treelang.texi: Update link to "G++ and GCC".
 
2004-02-20 Richard Henderson <rth@redhat.com>
 
* Make-lang.in (treelang-warn): Add -Wno-variadic-macros.
 
2004-01-30 Kelley Cook <kcook@gcc.gnu.org>
 
* Make-lang.in (doc/treelang.dvi): Use $(abs_docdir).
 
2004-01-20 Kelley Cook <kcook@gcc.gnu.org>
 
* Make-lang.in: Replace $(docdir) with doc.
(treelang.info, treelang.srcinfo): New rules.
(treelang.man, treelang.man): Dummy entries.
 
2004-01-15 Kelley Cook <kcook@gcc.gnu.org>
 
* Make-lang.in (TREE_GENERATED): Delete reference to $(parsedir).
(treelang/parse.o, treelang/lex.o): Look for sources in build
directory. Use implicit rule.
(treelang/parse.c, treelang/parse.h treelang/lex.c): Always build in
doc directory.
(treelang.srcextra): Copy above back to source directory if requested.
 
2004-01-07 Zack Weinberg <zack@codesourcery.com>
 
* parse.y (yyerror): Mark the definition static.
 
2003-12-04 James A. Morrison <ja2morri@uwaterloo.ca>
 
* lex.l: Add \t as a whitespace character.
* treelang.texi (Lexical Syntax): Document a tab as whitespace.
 
* treelang.texi (What is GNU Treelang?): Fix a typo.
(Lexical Syntax): Create an itemize list of keywords. Add commas to
paragraph defining names.
 
2003-11-26 Jason Merrill <jason@redhat.com>
 
* Make-lang.in (treelang.tags): Create TAGS.sub files in each
directory and TAGS files that include them for each front end.
 
2003-11-21 Kelley Cook <kcook@gcc.gnu.org>
 
* .cvsignore: Delete.
 
2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
 
* Make-lang.in (treelang.extraclean): Delete.
 
2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
 
* Make-lang.in: Remove obsolete comment.
 
2003-11-03 Kelley Cook <kcook@gcc.gnu.org>
 
* Make-lang.in (dvi): Move targets to $(docobjdir).
(treelang.dvi): Simplify rule and adjust target.
(treelang.info): Simplify rule.
(parse.o): Correct dependencies.
(TREE_EXE): Delete doubled suffix append.
 
2003-10-21 Kelley Cook <kcook@gcc.gnu.org>
 
* Make-lang.in (treelang.o): Depend on $(parsedir)/treelang/parse.h.
(lex.o): Likewise.
 
2003-10-21 Kelley Cook <kcook@gcc.gnu.org>
 
* Make-lang.in (parse.o): Honor $(parsedir).
(lex.o): Likewise.
(lex.c): Likewise
(parse.c, parse.h): Likewise.
($(docobjdir)/treelang.info): Replace $(srcdir)/doc with $(docdir).
(dvi): Likewise.
 
2003-10-20 Mark Mitchell <mark@codesourcery.com>
 
* Make-lang.in ($(docobjdir)/treelang/treelang.info): Depend on
stmp-docobjdir.
 
* Make-lang.in (info): Use docobjdir.
($(srcdir)/treelang/treelang.info): Replace with ...
($(docobjdir)/treelang/treelang.info): ... this.
(install-info): New target.
 
2003-10-12 Andreas Jaeger <aj@suse.de>
 
* Make-lang.in (treelang.install-info): Remove reference to
treelang.info.
(treelang.): Removed.
 
2003-10-06 Mark Mitchell <mark@codesourcery.com>
 
* Make-lang.in (treelang.info): Replace with ...
(info): ... this.
* Make-lang.in (treelang.dvi): Replace with ...
(dvi): ... this.
 
2003-09-21 Richard Henderson <rth@redhat.com>
 
* treetree.c: Revert.
 
2003-09-21 Richard Henderson <rth@redhat.com>
 
* treetree.c: Update for DECL_SOURCE_LOCATION rename and
change to const.
 
2003-07-28 Andreas Jaeger <aj@suse.de>
 
* treetree.c: Convert remaining K&R prototypes to ISO C90.
* tree1.c: Likewise.
* parse.y: Likewise.
* tree-convert.c: Likewise.
 
2003-07-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
 
* treetree.c: Remove unnecessary casts.
 
2003-07-15 Neil Booth <neil@daikokuya.co.uk>
 
* lang-options.h: Remove.
* lang.opt: Document some options. Remove --help.
* tree1.c (treelang_handle_option): Remove OPT__help case.
 
2003-07-12 Andreas Jaeger <aj@suse.de>
 
* Make-lang.in (treelang/tree-convert.o): Depend on TM_H.
 
2003-07-10 Neil Booth <neil@daikokuya.co.uk>
 
* Make-lang.in: Update.
* tree1.c: Don't include c-common.h.
(c_language): Remove.
 
2003-07-10 Fergus Henderson <fjh@cs.mu.oz.au>
Steven Bosscher <steven@gcc.gnu.org>
 
* tree-convert.c: New file.
* treetree.c: Don't include c-tree.h. Include target.h.
(struct lang_identifier, union lang_tree_node, struct lang_type,
struct lang_function): New, minimal language-specific datastructs.
(tree_lang_truthvalue_conversion, tree_mark_addressable,
tree_lang_type_for_size, tree_lang_type_for_mode,
tree_lang_unsigned_type, tree_lang_signed_type,
tree_lang_signed_or_unsigned): New functions.
(LANG_HOOKS_*): Don't use C front end langhooks. Use new functions.
(pushlevel, poplevel, global_bindings_p, insert_block, set_block,
pushdecl, getdecls, kept_level_p, tree_push_type_decl,
tree_push_atomic_type_decl): New functions.
(struct resword, struct reswords): Remove.
* Make-lang.in: Update. Don't depend on C front end objects.
* config-lang.in: Likewise.
 
2003-07-07 Nathan Sidwell <nathan@codesourcery.com>
 
* treelang/treetree.c (tree_code_if_start, tree_code_if_else,
tree_code_if_end, tree_code_create_function_initial,
tree_code_create_function_wrapup, tree_code_generate_return,
tree_code_output_expression_statement): Adjust emit_line_note
calls.
 
2003-07-04 H.J. Lu <hongjiu.lu@intel.com>
 
* Make-lang.in: Replace PWD with PWD_COMMAND.
 
2003-07-02 Neil Booth <neil@daikokuya.co.uk>
 
* tree1.c (treelang_init_options): Update prototype.
* treelang.h (treelang_init_options): Update prototype.
 
2003-07-01 Neil Booth <neil@daikokuya.co.uk>
 
* Make-lang.in: Update.
* tree1.c: Include c-common.h. Define c_language.
 
2003-06-20 Nathan Sidwell <nathan@codesourcery.com>
 
* treetree.c (tree_code_create_function_wrapup): Adjust
expand_function_end call.
 
2003-06-18 Nathan Sidwell <nathan@codesourcery.com>
 
* treetree.c (build_stmt): Remove VPARAMS.
(pedwarn_c99): Likewise.
 
2003-06-15 Neil Booth <neil@daikokuya.co.uk>
 
* lang.opt: Declare Treelang. Update.
* tree1.c (treelang_init_options): Update.
 
2003-06-14 Nathan Sidwell <nathan@codesourcery.com>
 
* treetree.c (tree_code_create_function_initial): Adjust
init_function_start call.
 
2003-06-14 Neil Booth <neil@daikokuya.co.uk>
 
* Make-lang.in: Update to use options.c and options.h.
* tree1.c: Include options.h not t-options.h.
(treelang_init_options): New.
(treelang_handle_option): Abort on unrecognized switch.
* treetree.c (LANG_HOOKS_INIT_OPTIONS): Override.
* treetree.h (treelang_init_options): New.
 
2003-06-12 Andreas Jaeger <aj@suse.de>
 
* treetree.c: Remove cl_options-count and cl_options.
 
2003-06-11 Neil Booth <neil@daikokuya.co.uk>
 
* Make-lang.in: Update for option handling.
* lang.opt: New.
* tree1.c: Include opts.h and t-options.h.
(treelang_decode_option): Remove.
(treelang_handle_option): New.
* treetree.c (LANG_HOOKS_DECODE_OPTION): Remove.
(LANG_HOOKS_HANDLE_OPTION): Override.
* treetree.h (treelang_decode_option): Remove.
(treelang_handle_option): New.
 
2003-06-08 Andreas Jaeger <aj@suse.de>
 
* Make-lang.in: Update.
* treetree.c: Include opts.h. Define cl_options_count and cl_options.
 
2003-06-08 Tim Josling <tej@melbpc.org.au>
 
* treetree.c (c_lex): Add fake routine to satisfy RS6000 backend.
 
2003-06-05 Jan Hubicka <jh@suse.cz>
 
* Make-lang.in: Add support for stageprofile and stagefeedback
 
2003-05-21 Nathan Sidwell <nathan@codesourcery.com>
 
* treetree.c (reswords): Remove __bounded__, __unbounded__.
 
2003-05-09 Tim Josling <tej@melbpc.org.au>
 
* Make-lang.in (TREE_BE_LIBS): Add C_TARGET_OBJS to object files
to link (needed by some front ends such as PPC).
 
* treetree.c (tree_code_create_function_initial): Fix long line.
Initialize tree_code_int_size and tree_code_char_size to
meaningful values.
(tree_code_get_numeric_type): Add check that size1 parameter is
valid.
 
* parse.y: Fix extra long lines in prototypes.
 
* treelang.h: Fix extra long lines in macro definitions.
 
2003-05-07 Zack Weinberg <zack@codesourcery.com>
 
* Make-lang.in: Set -Wno-error for treelang/lex.o.
 
2003-05-06 Nathan Sidwell <nathan@codesourcery.com>
 
* Make-lang.in (treelang/tree1.o): Depends on input.h
(treelang/treetree.o, treelang/parse.o, treelang/lex.o): Likewise.
* treelang.h: #include input.h.
(in_fname): Remove.
(struct token_part): Remove lineno, add location.
* lex.l (next_tree_lineno): Remove.
(update_lineno_charno): Adjust.
(dump_lex_value): Adjust.
* parse.y (variable_def, function_prototype, function, statement,
if_statement, return, function_invocation, variable_ref): Adjust.
(print_token, yyerror, ensure_not_void): Adjust.
tree1.c (in_fname): Remove.
(treelang_init): Setup input_location.
(lookup_tree_name): Adjust.
(insert_tree_name): Adjust.
* treetree.c (tree_code_if_start): Replace filename and lineno
parms with loc. Adjust.
(tree_code_if_else, tree_code_if_end,
tree_code_create_function_prototype,
tree_code_create_function_initial,
tree_code_create_function_wrapup, tree_code_create_variable,
tree_code_output_expression_statement): Likewise.
* treetree.h (tree_code_if_start): Replace filename and lineno
parms with loc.
(tree_code_if_else, tree_code_if_end,
tree_code_create_function_prototype,
tree_code_create_function_initial,
tree_code_create_function_wrapup, tree_code_create_variable,
tree_code_output_expression_statement): Likewise.
 
2003-05-01 Nathan Sidwell <nathan@codesourcery.com>
 
* tree1.c (treelang_init): Rename lineno to input_line.
 
2003-04-30 Steven Bosscher <steven@gcc.gnu.org>
 
* parse.y (make_plus_expression): New function.
(expression production): Use make_plus_expression for PLUS,
MINUS, ASSIGN and EQUALS.
* tree1.c (treelang_decode_option): Don't fall through to
options that start with a different character when an option
was not recognized.
 
2003-04-30 Nathan Sidwell <nathan@codesourcery.com>
 
* Make-lang.in (parse.c): Reorder bison arguments for POSIXLY_CORRECT.
* treetree.c: Do not #include parse.h.
 
2003-03-21 Andreas Jaeger <aj@suse.de>
 
* treetree.c (cpp_create_reader): Follow prototype change in
cpplib.h.
 
2003-03-17 Andreas Jaeger <aj@suse.de>
 
* Make-lang.in (treelang.tags): Remove duplicate entry.
 
2003-03-15 Andreas Jaeger <aj@suse.de>
 
* treetree.c (cpp_handle_option): Remove.
 
2003-03-13 Andreas Jaeger <aj@suse.de>
 
* Make-lang.in (tree1$(exeext)): Fix previous patch.
 
2003-03-12 Andreas Jaeger <aj@suse.de>
 
* Make-lang.in (tree1$(exeext)): Add c-cppbuiltin.o.
 
2003-03-08 Neil Booth <neil@daikokuya.co.uk>
 
* tree1.c (in_fname): Fix type.
(treelang_init): Update prototype and use of in_fname.
* treelang.h (in_fname): Fix type.
* treetree.c (tree_code_if_start, tree_code_if_else,
tree_code_if_end, tree_code_create_function_prototype,
tree_code_create_function_initial, tree_code_create_funciton_wrapup,
tree_code_create_variable, tree_code_output_expression_statement)
: Fix prototypes and use of filenames.
* treetree.h: Similarly.
 
2003-03-05 Andreas Jaeger <aj@suse.de>
 
* treetree.c (init_c_lex): Follow change to c-common.h.
 
2003-03-04 Tom Tromey <tromey@redhat.com>
 
* Make-lang.in (treelang.tags): New target.
 
2003-03-01 Tim Josling <tej@melbpc.org.au>
 
Name clashes with rtl.h fixed.
 
* lex.l: Tokens PLUS, MINUS, RETURN changed to tl_PLUS tl_MINUS
tl_RETURN.
 
* parse.y: Ditto.
 
2003-02-24 Tim Josling <tej@melbpc.org.au>
 
* parse.y (my_yylex): New - ensure lexer time is charged to
TV_LEX.
(yylex): redefine as invocation of my_yylex which then calls
flex-generated yylex.
(timevar.h): include.
 
2003-02-23 Tim Josling <tej@melbpc.org.au>
 
Fix garbage collection, add more error checking, force GC always.
 
* Make-lang.in (treelang/tree1.o): Depend on treelang/treetree.h
(treelang/treetree.o): Depend on treelang/parse.h
 
* lex.l: include "treetree.h"
 
* lex.l (update_yylval): Allocate string using get_string so GC
works.
 
* parse.y (function_prototype): Set category correctly so GC works.
(function): Set category in search so checking works.
(function_invocation): Ditto.
(variable_ref): Ditto.
 
* tree1.c (lookup_tree_name): Call sanity_check for passed
production and associated token and for symbol table entries.
 
* tree1.c (sanity_check): New, basic check that struct is valid.
 
* treelang.h: Prototype for sanity_check.
 
2003-01-27 Tim Josling <tej@melbpc.org.au>
 
* treetree.c (treelang_init_decl_processing): Change memory
allocation to use GC.
 
2003-02-04 Joseph S. Myers <jsm@polyomino.org.uk>
 
* treelang.texi: Update to GFDL 1.2.
 
2003-01-26 Michael Matz <matz@suse.de>
 
* Make-lang.in (treelang/parse.o-warn): Define as -Wno-error.
 
2003-01-14 Andreas Jaeger <aj@suse.de>
 
* Make-lang.in (treelang.install-info): Depend only on info files
if BUILD_INFO is set. Fix install rules.
(treelang.): New.
 
2003-01-09 Christian Cornelssen <ccorn@cs.tu-berlin.de>
 
* Make-lang.in (treelang.install.common.done,
treelang.install-info, treelang.uninstall): Prepend
$(DESTDIR) to destination paths in all (un)installation
commands.
 
2002-12-28 Joseph S. Myers <jsm@polyomino.org.uk>
 
* treelang.texi: Use @copying.
 
2002-12-23 Joseph S. Myers <jsm@polyomino.org.uk>
 
* treelang.texi: Include gcc-common.texi.
* Make-lang.in ($(srcdir)/treelang/treelang.info, treelang.dvi):
Depend on gcc-common.texi. Add other missing dependencies.
(treelang.dvi): Use texi2dvi.
 
2002-12-22 Joseph S. Myers <jsm@polyomino.org.uk>
 
* treelang.texi: Use @ifnottex instead of @ifinfo.
 
2002-11-30 Zack Weinberg <zack@codesourcery.com>
 
* lex.l: Move "%{" below copyright notice; get rid of "/*"
embedded in comment. Do not #undef IN_GCC; do not include
stdio.h, memory.h, or ansidecl.h; do not include config.h twice.
Do include coretypes.h and tm.h.
* parse.y: Do not #undef IN_GCC, provide bogus definitions of tree
and rtx typedefs, or include stdio.h, stdlib.h, string.h, or
ansidecl.h. Do include coretypes.h and tm.h.
* tree1.c: Do not include ansidecl.h, stdlib.h, unistd.h, ctype.h,
stdarg.h, string.h, or stdio.h. Do include coretypes.h and tm.h.
* treetree.c: Do not include stdlib.h, unistd.h, safe-ctype.h,
errno.h. stdarg.h, limits.h, string.h, fcntl.h, getopt.h. stdio.h,
or ansidecl.h. Do include coretypes.h and tm.h.
* Make-lang.in: Update dependencies.
 
2002-09-09 Tim Josling <tej@melbpc.org.au>
 
* treetree.c (objc_is_id): New.
 
2002-08-16 Tim Josling <tej@melbpc.org.au>
 
Remove variables and functions now defined elsewhere.
 
* treetree.c (maybe_objc_comptypes): Remove.
(warn_format, warn_format_y2k, warn_format_extra_args,
warn_format_nonliteral, warn_format_security,
warn_format_zero_length): Remove.
(maybe_building_objc_message_expr): Remove.
(cpp_post_options): Remove.
(maybe_objc_check_decl): Remove.
(integer_types): Remove.
 
 
2002-08-13 Neil Booth <neil@daikokuya.co.uk>
 
* treelang.c: Remove cpp_post_options.
 
2002-08-13 Tim Josling <tej@melbpc.org.au>
 
* parse.y: Provide dummy definition of rtx for use by config.h.
* Make-lang.in (treetree.o): Remove dependency on non-existent
gt-treelang-treelang.h.
(gt-treelang-treelang.h): Remove.
 
2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
 
* treelang/Make-lang.in (treelang.mostlyclean): Remove coverage files.
 
2002-07-11 Tim Josling <tej@melbpc.org.au>
 
Remove front end hard coding from gengtype.c.
 
* config-lang.in (gtfiles): Add files needed for this front
end.
 
2002-07-09 Tim Josling <tej@melbpc.org.au>
 
Support new attributes regime (Fix for PR c++/7099).
 
* treetree.c (handle_format_attribute): Return NULL_TREE instead
of aborting.
(top level): Define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES as the standard C routines.
 
2002-06-21 Andreas Jaeger <aj@suse.de>
 
* Make-lang.in (treelang/tree1.o, treelang/treetree.o,
treelang/parse.o, treelang/lex.o): Add dependency on $(CONFIG_H).
 
2002-06-19 Paolo Bonzini <bonzini@gnu.org>
 
* lex.l (yyparse) Return AUTOMATIC for 'automatic' token rather
than STATIC.
 
2002-06-10 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 garbage 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-05-19 Tim Josling <tej@melbpc.org.au>
 
* treetree.c (warn_format_zero_length): Add.
 
2002-05-14 Tim Josling <tej@melbpc.org.au>
 
* Make-lang.in: Fix build for .info files, add target for manpages.
A bug report and a suggested patch came from Magnus Fromreide
<magfr@lysator.liu.se>.
 
2002-05-16 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
 
* Make-lang.in: Allow for PWDCMD to override hardcoded pwd.
 
2002-05-11 Tim Josling <tej@melbpc.org.au>
 
* treetree.c: (cpp_define) Add.
(cpp_get_callbacks) Add.
 
2002-05-07 Tim Josling <tej@melbpc.org.au>
 
* treetree.c: (cpp_get_options) Add.
 
2002-05-06 Tim Josling <tej@melbpc.org.au>
 
* .cvsignore: Add.
 
2002-05-05 Tim Josling <tej@melbpc.org.au>
 
* Updated for gcc3.2 experimental. Major changes throughout.
 
2002-03-31 Tim Josling <tej@melbpc.org.au>
 
* Make-lang.in: Changes so build and check work more reliably
 
2001-07-30 Tim Josling <tej@melbpc.org.au>
 
* root.texi: remove
* treelang.texi: updates based on feedback
 
2001-06-11 Tim Josling <tej@melbpc.org.au>
 
* all (all) Revamp code to conform to GCC coding standards, fix
typos in texi files.
 
2001-05-11 Tim Josling <tej@melbpc.org.au>
 
Create the new language.
/treelang.h
0,0 → 1,156
/*
 
TREELANG Compiler common definitions (treelang.h)
 
Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
2007 Free Software Foundation, Inc.
 
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, 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; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>.
 
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
 
---------------------------------------------------------------------------
 
Written by Tim Josling 1999, 2000, 2001, based in part on other
parts of the GCC compiler.
 
*/
 
#include "input.h"
 
/* Parse structure type. */
enum category_enum
{ /* These values less likely to be there by chance unlike 0/1,
make checks more meaningful */
token_category = 111,
production_category = 222,
parameter_category = 333
};
 
/* Input file FILE. */
extern FILE* yyin;
 
/* Forward references to satisfy mutually recursive definitions. */
struct token_part;
struct production_part;
struct prod_token_parm_item;
typedef struct prod_token_parm_item item;
 
/* A token from the input file. */
 
struct token_part GTY(())
{
location_t location;
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. */
/* Numeric type used in type definitions and expressions. */
#define NUMERIC_TYPE(a) a->tp.pro.info[1]
#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. */
/* Function parameters linked via struct tree_parameter_list. */
#define FIRST_PARMS(a) (a->tp.pro.sub[3])
#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;
unsigned int flag5:1;
unsigned int flag6:1;
unsigned int flag7:1;
 
};
 
/* 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 ((skip)) 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);
 
void sanity_check (struct prod_token_parm_item *item);
/treelang.texi
0,0 → 1,1305
\input texinfo @c -*-texinfo-*-
 
@c NOTE THIS IS NOT A GOOD EXAMPLE OF HOW TO DO A MANUAL. FIXME!!!
@c NOTE THIS IS NOT A GOOD EXAMPLE OF HOW TO DO A MANUAL. FIXME!!!
 
 
@c %**start of header
@setfilename treelang.info
 
@include gcc-common.texi
 
@set copyrights-treelang 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005
 
@set email-general gcc@@gcc.gnu.org
@set email-bugs gcc-bugs@@gcc.gnu.org or bug-gcc@@gnu.org
@set email-patches gcc-patches@@gcc.gnu.org
@set path-treelang gcc/gcc/treelang
 
@set which-treelang GCC-@value{version-GCC}
@set which-GCC GCC
 
@set email-josling tej@@melbpc.org.au
@set www-josling http://www.geocities.com/timjosling
 
@c This tells @include'd files that they're part of the overall TREELANG doc
@c set. (They might be part of a higher-level doc set too.)
@set DOC-TREELANG
 
@c @setfilename usetreelang.info
@c @setfilename maintaintreelang.info
@c To produce the full manual, use the "treelang.info" setfilename, and
@c make sure the following do NOT begin with '@c' (and the @clear lines DO)
@set INTERNALS
@set USING
@c To produce a user-only manual, use the "usetreelang.info" setfilename, and
@c make sure the following does NOT begin with '@c':
@c @clear INTERNALS
@c To produce a maintainer-only manual, use the "maintaintreelang.info" setfilename,
@c and make sure the following does NOT begin with '@c':
@c @clear USING
 
@ifset INTERNALS
@ifset USING
@settitle Using and Maintaining GNU Treelang
@end ifset
@end ifset
@c seems reasonable to assume at least one of INTERNALS or USING is set...
@ifclear INTERNALS
@settitle Using GNU Treelang
@end ifclear
@ifclear USING
@settitle Maintaining GNU Treelang
@end ifclear
@c then again, have some fun
@ifclear INTERNALS
@ifclear USING
@settitle Doing Very Little at all with GNU Treelang
@end ifclear
@end ifclear
 
@syncodeindex fn cp
@syncodeindex vr cp
@c %**end of header
 
@c Cause even numbered pages to be printed on the left hand side of
@c the page and odd numbered pages to be printed on the right hand
@c side of the page. Using this, you can print on both sides of a
@c sheet of paper and have the text on the same part of the sheet.
 
@c The text on right hand pages is pushed towards the right hand
@c margin and the text on left hand pages is pushed toward the left
@c hand margin.
@c (To provide the reverse effect, set bindingoffset to -0.75in.)
 
@c @tex
@c \global\bindingoffset=0.75in
@c \global\normaloffset =0.75in
@c @end tex
 
@copying
Copyright @copyright{} @value{copyrights-treelang} Free Software Foundation, Inc.
 
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with the
Invariant Sections being ``GNU General Public License'', the Front-Cover
texts being (a) (see below), and with the Back-Cover Texts being (b)
(see below). A copy of the license is included in the section entitled
``GNU Free Documentation License''.
 
(a) The FSF's Front-Cover Text is:
 
A GNU Manual
 
(b) The FSF's Back-Cover Text is:
 
You have freedom to copy and modify this GNU Manual, like GNU
software. Copies published by the Free Software Foundation raise
funds for GNU development.
@end copying
 
@ifnottex
@dircategory Software development
@direntry
* treelang: (treelang). The GNU Treelang compiler.
@end direntry
@ifset INTERNALS
@ifset USING
This file documents the use and the internals of the GNU Treelang
(@code{treelang}) compiler. At the moment this manual is not
incorporated into the main GCC manual as it is incomplete. It
corresponds to the @value{which-treelang} version of @code{treelang}.
@end ifset
@end ifset
@ifclear USING
This file documents the internals of the GNU Treelang (@code{treelang}) compiler.
It corresponds to the @value{which-treelang} version of @code{treelang}.
@end ifclear
@ifclear INTERNALS
This file documents the use of the GNU Treelang (@code{treelang}) compiler.
It corresponds to the @value{which-treelang} version of @code{treelang}.
@end ifclear
 
Published by the Free Software Foundation
51 Franklin Street, Fifth Floor
Boston, MA 02110-1301 USA
 
@insertcopying
@end ifnottex
 
@setchapternewpage odd
@c @finalout
@titlepage
@ifset INTERNALS
@ifset USING
@title Using and Maintaining GNU Treelang
@end ifset
@end ifset
@ifclear INTERNALS
@title Using GNU Treelang
@end ifclear
@ifclear USING
@title Maintaining GNU Treelang
@end ifclear
@versionsubtitle
@author Tim Josling
@page
@vskip 0pt plus 1filll
Published by the Free Software Foundation @*
51 Franklin Street, Fifth Floor@*
Boston, MA 02110-1301, USA@*
@c Last printed ??ber, 19??.@*
@c Printed copies are available for $? each.@*
@c ISBN ???
@sp 1
@insertcopying
@end titlepage
@page
 
@ifnottex
 
@node Top, Copying,, (dir)
@top Introduction
@cindex Introduction
 
@ifset INTERNALS
@ifset USING
This manual documents how to run, install and maintain @code{treelang}.
It also documents the features and incompatibilities in the @value{which-treelang}
version of @code{treelang}.
@end ifset
@end ifset
 
@ifclear INTERNALS
This manual documents how to run and install @code{treelang}.
It also documents the features and incompatibilities in the @value{which-treelang}
version of @code{treelang}.
@end ifclear
@ifclear USING
This manual documents how to maintain @code{treelang}.
It also documents the features and incompatibilities in the @value{which-treelang}
version of @code{treelang}.
@end ifclear
 
@end ifnottex
 
@menu
* Copying::
* Contributors::
* GNU Free Documentation License::
* Funding::
* Getting Started::
* What is GNU Treelang?::
* Lexical Syntax::
* Parsing Syntax::
* Compiler Overview::
* TREELANG and GCC::
* Compiler::
* Other Languages::
* treelang internals::
* Open Questions::
* Bugs::
* Service::
* Projects::
* Index::
 
@detailmenu
--- The Detailed Node Listing ---
 
Other Languages
 
* Interoperating with C and C++::
 
treelang internals
 
* treelang files::
* treelang compiler interfaces::
* Hints and tips::
 
treelang compiler interfaces
 
* treelang driver::
* treelang main compiler::
 
treelang main compiler
 
* Interfacing to toplev.c::
* Interfacing to the garbage collection::
* Interfacing to the code generation code. ::
 
Reporting Bugs
 
* Sending Patches::
 
@end detailmenu
@end menu
 
@include gpl.texi
 
@include fdl.texi
 
@node Contributors
 
@unnumbered Contributors to GNU Treelang
@cindex contributors
@cindex credits
 
Treelang was based on 'toy' by Richard Kenner, and also uses code from
the GCC core code tree. Tim Josling first created the language and
documentation, based on the GCC Fortran compiler's documentation
framework. Treelang was updated to use the TreeSSA infrastructure by
James A. Morrison.
 
@itemize @bullet
@item
The packaging and compiler portions of GNU Treelang are based largely
on the GCC compiler.
@xref{Contributors,,Contributors to GCC,GCC,Using and Maintaining GCC},
for more information.
 
@item
There is no specific run-time library for treelang, other than the
standard C runtime.
 
@item
It would have been difficult to build treelang without access to Joachim
Nadler's guide to writing a front end to GCC (written in German). A
translation of this document into English is available via the
CobolForGCC project or via the documentation links from the GCC home
page @uref{http://gcc.gnu.org}.
@end itemize
 
@include funding.texi
 
@node Getting Started
@chapter Getting Started
@cindex getting started
@cindex new users
@cindex newbies
@cindex beginners
 
Treelang is a sample language, useful only to help people understand how
to implement a new language front end to GCC. It is not a useful
language in itself other than as an example or basis for building a new
language. Therefore only language developers are likely to have an
interest in it.
 
This manual assumes familiarity with GCC, which you can obtain by using
it and by reading the manuals @samp{Using the GNU Compiler Collection (GCC)}
and @samp{GNU Compiler Collection (GCC) Internals}.
 
To install treelang, follow the GCC installation instructions,
taking care to ensure you specify treelang in the configure step by adding
treelang to the list of languages specified by @option{--enable-languages},
e.g.@: @samp{--enable-languages=all,treelang}.
 
If you're generally curious about the future of
@code{treelang}, see @ref{Projects}.
If you're curious about its past,
see @ref{Contributors}.
 
To see a few of the questions maintainers of @code{treelang} have,
and that you might be able to answer,
see @ref{Open Questions}.
 
@ifset USING
@node What is GNU Treelang?, Lexical Syntax, Getting Started, Top
@chapter What is GNU Treelang?
@cindex concepts, basic
@cindex basic concepts
 
GNU Treelang, or @code{treelang}, is designed initially as a free
replacement for, or alternative to, the 'toy' language, but which is
amenable to inclusion within the GCC source tree.
 
@code{treelang} is largely a cut down version of C, designed to showcase
the features of the GCC code generation back end. Only those features
that are directly supported by the GCC code generation back end are
implemented. Features are implemented in a manner which is easiest and
clearest to implement. Not all or even most code generation back end
features are implemented. The intention is to add features incrementally
until most features of the GCC back end are implemented in treelang.
 
The main features missing are structures, arrays and pointers.
 
A sample program follows:
 
@smallexample
// @r{function prototypes}
// @r{function 'add' taking two ints and returning an int}
external_definition int add(int arg1, int arg2);
external_definition int subtract(int arg3, int arg4);
external_definition int first_nonzero(int arg5, int arg6);
external_definition int double_plus_one(int arg7);
 
// @r{function definition}
add
@{
// @r{return the sum of arg1 and arg2}
return arg1 + arg2;
@}
 
subtract
@{
return arg3 - arg4;
@}
 
double_plus_one
@{
// @r{aaa is a variable, of type integer and allocated at the start of}
// @r{the function}
automatic int aaa;
// @r{set aaa to the value returned from add, when passed arg7 and arg7 as}
// @r{the two parameters}
aaa=add(arg7, arg7);
aaa=add(aaa, aaa);
aaa=subtract(subtract(aaa, arg7), arg7) + 1;
return aaa;
@}
 
first_nonzero
@{
// @r{C-like if statement}
if (arg5)
@{
return arg5;
@}
else
@{
@}
return arg6;
@}
@end smallexample
 
@node Lexical Syntax, Parsing Syntax, What is GNU Treelang?, Top
@chapter Lexical Syntax
@cindex Lexical Syntax
 
Treelang programs consist of whitespace, comments, keywords and names.
@itemize @bullet
 
@item
Whitespace consists of the space character, a tab, and the end of line
character. Line terminations are as defined by the
standard C library. Whitespace is ignored except within comments,
and where it separates parts of the program. In the example below, A and
B are two separate names separated by whitespace.
 
@smallexample
A B
@end smallexample
 
@item
Comments consist of @samp{//} followed by any characters up to the end
of the line. C style comments (/* */) are not supported. For example,
the assignment below is followed by a not very helpful comment.
 
@smallexample
x = 1; // @r{Set X to 1}
@end smallexample
 
@item
Keywords consist of any of the following reserved words or symbols:
 
@itemize @bullet
@item @{
used to start the statements in a function
@item @}
used to end the statements in a function
@item (
start list of function arguments, or to change the precedence of operators in
an expression
@item )
end list or prioritized operators in expression
@item ,
used to separate parameters in a function prototype or in a function call
@item ;
used to end a statement
@item +
addition, or unary plus for signed literals
@item -
subtraction, or unary minus for signed literals
@item =
assignment
@item ==
equality test
@item if
begin IF statement
@item else
begin 'else' portion of IF statement
@item static
indicate variable is permanent, or function has file scope only
@item automatic
indicate that variable is allocated for the life of the current scope
@item external_reference
indicate that variable or function is defined in another file
@item external_definition
indicate that variable or function is to be accessible from other files
@item int
variable is an integer (same as C int)
@item char
variable is a character (same as C char)
@item unsigned
variable is unsigned. If this is not present, the variable is signed
@item return
start function return statement
@item void
used as function type to indicate function returns nothing
@end itemize
 
 
@item
Names consist of any letter or "_" followed by any number of letters,
numbers, or "_". "$" is not allowed in a name. All names must be globally
unique, i.e. may not be used twice in any context, and must
not be a keyword. Names and keywords are case sensitive. For example:
 
@smallexample
a A _a a_ IF_X
@end smallexample
 
are all different names.
 
@end itemize
 
@node Parsing Syntax, Compiler Overview, Lexical Syntax, Top
@chapter Parsing Syntax
@cindex Parsing Syntax
 
Declarations are built up from the lexical elements described above. A
file may contain one of more declarations.
 
@itemize @bullet
 
@item
declaration: variable declaration OR function prototype OR function declaration
 
@item
Function Prototype: storage type NAME ( optional_parameter_list )
 
@smallexample
static int add (int a, int b)
@end smallexample
 
@item
variable_declaration: storage type NAME initial;
 
Example:
 
@smallexample
int temp1 = 1;
@end smallexample
 
A variable declaration can be outside a function, or at the start of a
function.
 
@item
storage: automatic OR static OR external_reference OR external_definition
 
This defines the scope, duration and visibility of a function or variable
 
@enumerate 1
 
@item
automatic: This means a variable is allocated at start of the current scope and
released when the current scope is exited. This can only be used for variables
within functions. It cannot be used for functions.
 
@item
static: This means a variable is allocated at start of program and
remains allocated until the program as a whole ends. For a function, it
means that the function is only visible within the current file.
 
@item
external_definition: For a variable, which must be defined outside a
function, it means that the variable is visible from other files. For a
function, it means that the function is visible from another file.
 
@item
external_reference: For a variable, which must be defined outside a
function, it means that the variable is defined in another file. For a
function, it means that the function is defined in another file.
 
@end enumerate
 
@item
type: int OR unsigned int OR char OR unsigned char OR void
 
This defines the data type of a variable or the return type of a function.
 
@enumerate a
 
@item
int: The variable is a signed integer. The function returns a signed integer.
 
@item
unsigned int: The variable is an unsigned integer. The function returns an unsigned integer.
 
@item
char: The variable is a signed character. The function returns a signed character.
 
@item
unsigned char: The variable is an unsigned character. The function returns an unsigned character.
 
@end enumerate
 
@item
parameter_list OR parameter [, parameter]...
 
@item
parameter: variable_declaration ,
 
The variable declarations must not have initializations.
 
@item
initial: = value
 
@item
value: integer_constant
 
Values without a unary plus or minus are considered to be unsigned.
@smallexample
e.g.@: 1 +2 -3
@end smallexample
 
@item
function_declaration: name @{ variable_declarations statements @}
 
A function consists of the function name then the declarations (if any)
and statements (if any) within one pair of braces.
 
The details of the function arguments come from the function
prototype. The function prototype must precede the function declaration
in the file.
 
@item
statement: if_statement OR expression_statement OR return_statement
 
@item
if_statement: if ( expression ) @{ variable_declarations statements @}
else @{ variable_declarations statements @}
 
The first lot of statements is executed if the expression is
nonzero. Otherwise the second lot of statements is executed. Either
list of statements may be empty, but both sets of braces and the else must be present.
 
@smallexample
if (a==b)
@{
// @r{nothing}
@}
else
@{
a=b;
@}
@end smallexample
 
@item
expression_statement: expression;
 
The expression is executed, including any side effects.
 
@item
return_statement: return expression_opt;
 
Returns from the function. If the function is void, the expression must
be absent, and if the function is not void the expression must be
present.
 
@item
expression: variable OR integer_constant OR expression + expression
OR expression - expression OR expression == expression OR ( expression )
OR variable = expression OR function_call
 
An expression can be a constant or a variable reference or a
function_call. Expressions can be combined as a sum of two expressions
or the difference of two expressions, or an equality test of two
expressions. An assignment is also an expression. Expressions and operator
precedence work as in C.
 
@item
function_call: function_name ( optional_comma_separated_expressions )
 
This invokes the function, passing to it the values of the expressions
as actual parameters.
 
@end itemize
 
@cindex compilers
@node Compiler Overview, TREELANG and GCC, Parsing Syntax, Top
@chapter Compiler Overview
treelang is run as part of the GCC compiler.
 
@itemize @bullet
@cindex source code
@cindex file, source
@cindex code, source
@cindex source file
@item
It reads a user's program, stored in a file and containing instructions
written in the appropriate language (Treelang, C, and so on). This file
contains @dfn{source code}.
 
@cindex translation of user programs
@cindex machine code
@cindex code, machine
@cindex mistakes
@item
It translates the user's program into instructions a computer can carry
out more quickly than it takes to translate the instructions in the
first place. These instructions are called @dfn{machine code}---code
designed to be efficiently translated and processed by a machine such as
a computer. Humans usually aren't as good writing machine code as they
are at writing Treelang or C, because it is easy to make tiny mistakes
writing machine code. When writing Treelang or C, it is easy to make
big mistakes. But you can only make one mistake, because the compiler
stops after it finds any problem.
 
@cindex debugger
@cindex bugs, finding
@cindex @code{gdb}, command
@cindex commands, @code{gdb}
@item
It provides information in the generated machine code
that can make it easier to find bugs in the program
(using a debugging tool, called a @dfn{debugger},
such as @code{gdb}).
 
@cindex libraries
@cindex linking
@cindex @code{ld} command
@cindex commands, @code{ld}
@item
It locates and gathers machine code already generated to perform actions
requested by statements in the user's program. This machine code is
organized into @dfn{libraries} and is located and gathered during the
@dfn{link} phase of the compilation process. (Linking often is thought
of as a separate step, because it can be directly invoked via the
@code{ld} command. However, the @code{gcc} command, as with most
compiler commands, automatically performs the linking step by calling on
@code{ld} directly, unless asked to not do so by the user.)
 
@cindex language, incorrect use of
@cindex incorrect use of language
@item
It attempts to diagnose cases where the user's program contains
incorrect usages of the language. The @dfn{diagnostics} produced by the
compiler indicate the problem and the location in the user's source file
where the problem was first noticed. The user can use this information
to locate and fix the problem.
 
The compiler stops after the first error. There are no plans to fix
this, ever, as it would vastly complicate the implementation of treelang
to little or no benefit.
 
@cindex diagnostics, incorrect
@cindex incorrect diagnostics
@cindex error messages, incorrect
@cindex incorrect error messages
(Sometimes an incorrect usage of the language leads to a situation where
the compiler can not make any sense of what it reads---while a human
might be able to---and thus ends up complaining about an incorrect
``problem'' it encounters that, in fact, reflects a misunderstanding of
the programmer's intention.)
 
@cindex warnings
@cindex questionable instructions
@item
There are a few warnings in treelang. For example an unused static function
generate a warnings when -Wunused-function is specified, similarly an unused
static variable generates a warning when -Wunused-variable are specified.
The only treelang specific warning is a warning when an expression is in a
return statement for functions that return void.
@end itemize
 
@cindex components of treelang
@cindex @code{treelang}, components of
@code{treelang} consists of several components:
 
@cindex @code{gcc}, command
@cindex commands, @code{gcc}
@itemize @bullet
@item
A modified version of the @code{gcc} command, which also might be
installed as the system's @code{cc} command.
(In many cases, @code{cc} refers to the
system's ``native'' C compiler, which
might be a non-GNU compiler, or an older version
of @code{GCC} considered more stable or that is
used to build the operating system kernel.)
 
@cindex @code{treelang}, command
@cindex commands, @code{treelang}
@item
The @code{treelang} command itself.
 
@item
The @code{libc} run-time library. This library contains the machine
code needed to support capabilities of the Treelang language that are
not directly provided by the machine code generated by the
@code{treelang} compilation phase. This is the same library that the
main C compiler uses (libc).
 
@cindex @code{tree1}, program
@cindex programs, @code{tree1}
@cindex assembler
@cindex @code{as} command
@cindex commands, @code{as}
@cindex assembly code
@cindex code, assembly
@item
The compiler itself, is internally named @code{tree1}.
 
Note that @code{tree1} does not generate machine code directly---it
generates @dfn{assembly code} that is a more readable form
of machine code, leaving the conversion to actual machine code
to an @dfn{assembler}, usually named @code{as}.
@end itemize
 
@code{GCC} is often thought of as ``the C compiler'' only,
but it does more than that.
Based on command-line options and the names given for files
on the command line, @code{gcc} determines which actions to perform, including
preprocessing, compiling (in a variety of possible languages), assembling,
and linking.
 
@cindex driver, gcc command as
@cindex @code{gcc}, command as driver
@cindex executable file
@cindex files, executable
@cindex cc1 program
@cindex programs, cc1
@cindex preprocessor
@cindex cpp program
@cindex programs, cpp
For example, the command @samp{gcc foo.c} @dfn{drives} the file
@file{foo.c} through the preprocessor @code{cpp}, then
the C compiler (internally named
@code{cc1}), then the assembler (usually @code{as}), then the linker
(@code{ld}), producing an executable program named @file{a.out} (on
UNIX systems).
 
@cindex treelang program
@cindex programs, treelang
As another example, the command @samp{gcc foo.tree} would do much the
same as @samp{gcc foo.c}, but instead of using the C compiler named
@code{cc1}, @code{gcc} would use the treelang compiler (named
@code{tree1}). However there is no preprocessor for treelang.
 
@cindex @code{tree1}, program
@cindex programs, @code{tree1}
In a GNU Treelang installation, @code{gcc} recognizes Treelang source
files by name just like it does C and C++ source files. It knows to use
the Treelang compiler named @code{tree1}, instead of @code{cc1} or
@code{cc1plus}, to compile Treelang files. If a file's name ends in
@code{.tree} then GCC knows that the program is written in treelang. You
can also manually override the language.
 
@cindex @code{gcc}, not recognizing Treelang source
@cindex unrecognized file format
@cindex file format not recognized
Non-Treelang-related operation of @code{gcc} is generally
unaffected by installing the GNU Treelang version of @code{gcc}.
However, without the installed version of @code{gcc} being the
GNU Treelang version, @code{gcc} will not be able to compile
and link Treelang programs.
 
@cindex printing version information
@cindex version information, printing
The command @samp{gcc -v x.tree} where @samp{x.tree} is a file which
must exist but whose contents are ignored, is a quick way to display
version information for the various programs used to compile a typical
Treelang source file.
 
The @code{tree1} program represents most of what is unique to GNU
Treelang; @code{tree1} is a combination of two rather large chunks of
code.
 
@cindex GCC Back End (GBE)
@cindex GBE
@cindex @code{GCC}, back end
@cindex back end, GCC
@cindex code generator
One chunk is the so-called @dfn{GNU Back End}, or GBE,
which knows how to generate fast code for a wide variety of processors.
The same GBE is used by the C, C++, and Treelang compiler programs @code{cc1},
@code{cc1plus}, and @code{tree1}, plus others.
Often the GBE is referred to as the ``GCC back end'' or
even just ``GCC''---in this manual, the term GBE is used
whenever the distinction is important.
 
@cindex GNU Treelang Front End (TFE)
@cindex tree1
@cindex @code{treelang}, front end
@cindex front end, @code{treelang}
The other chunk of @code{tree1} is the majority of what is unique about
GNU Treelang---the code that knows how to interpret Treelang programs to
determine what they are intending to do, and then communicate that
knowledge to the GBE for actual compilation of those programs. This
chunk is called the @dfn{Treelang Front End} (TFE). The @code{cc1} and
@code{cc1plus} programs have their own front ends, for the C and C++
languages, respectively. These fronts ends are responsible for
diagnosing incorrect usage of their respective languages by the programs
the process, and are responsible for most of the warnings about
questionable constructs as well. (The GBE in principle handles
producing some warnings, like those concerning possible references to
undefined variables, but these warnings should not occur in treelang
programs as the front end is meant to pick them up first).
 
Because so much is shared among the compilers for various languages,
much of the behavior and many of the user-selectable options for these
compilers are similar.
For example, diagnostics (error messages and
warnings) are similar in appearance; command-line
options like @samp{-Wall} have generally similar effects; and the quality
of generated code (in terms of speed and size) is roughly similar
(since that work is done by the shared GBE).
 
@node TREELANG and GCC, Compiler, Compiler Overview, Top
@chapter Compile Treelang, C, or Other Programs
@cindex compiling programs
@cindex programs, compiling
 
@cindex @code{gcc}, command
@cindex commands, @code{gcc}
A GNU Treelang installation includes a modified version of the @code{gcc}
command.
 
In a non-Treelang installation, @code{gcc} recognizes C, C++,
and Objective-C source files.
 
In a GNU Treelang installation, @code{gcc} also recognizes Treelang source
files and accepts Treelang-specific command-line options, plus some
command-line options that are designed to cater to Treelang users
but apply to other languages as well.
 
@xref{G++ and GCC,,Programming Languages Supported by GCC,GCC,Using
the GNU Compiler Collection (GCC)},
for information on the way different languages are handled
by the GCC compiler (@code{gcc}).
 
You can use this, combined with the output of the @samp{gcc -v x.tree}
command to get the options applicable to treelang. Treelang programs
must end with the suffix @samp{.tree}.
 
@cindex preprocessor
 
Treelang programs are not by default run through the C
preprocessor by @code{gcc}. There is no reason why they cannot be run through the
preprocessor manually, but you would need to prevent the preprocessor
from generating #line directives, using the @samp{-P} option, otherwise
tree1 will not accept the input.
 
@node Compiler, Other Languages, TREELANG and GCC, Top
@chapter The GNU Treelang Compiler
 
The GNU Treelang compiler, @code{treelang}, supports programs written
in the GNU Treelang language.
 
@node Other Languages, treelang internals, Compiler, Top
@chapter Other Languages
 
@menu
* Interoperating with C and C++::
@end menu
 
@node Interoperating with C and C++, , Other Languages, Other Languages
@section Tools and advice for interoperating with C and C++
 
The output of treelang programs looks like C program code to the linker
and everybody else, so you should be able to freely mix treelang and C
(and C++) code, with one proviso.
 
C promotes small integer types to 'int' when used as function parameters and
return values in non-prototyped functions. Since treelang has no
non-prototyped functions, the treelang compiler does not do this.
 
@ifset INTERNALS
@node treelang internals, Open Questions, Other Languages, Top
@chapter treelang internals
 
@menu
* treelang files::
* treelang compiler interfaces::
* Hints and tips::
@end menu
 
@node treelang files, treelang compiler interfaces, treelang internals, treelang internals
@section treelang files
 
To create a compiler that integrates into GCC, you need create many
files. Some of the files are integrated into the main GCC makefile, to
build the various parts of the compiler and to run the test
suite. Others are incorporated into various GCC programs such as
@file{gcc.c}. Finally you must provide the actual programs comprising your
compiler.
 
@cindex files
 
The files are:
 
@enumerate 1
 
@item
COPYING. This is the copyright file, assuming you are going to use the
GNU General Public License. You probably need to use the GPL because if
you use the GCC back end your program and the back end are one program,
and the back end is GPLed.
 
This need not be present if the language is incorporated into the main
GCC tree, as the main GCC directory has this file.
 
@item
COPYING.LIB. This is the copyright file for those parts of your program
that are not to be covered by the GPL, but are instead to be covered by
the LGPL (Library or Lesser GPL). This license may be appropriate for
the library routines associated with your compiler. These are the
routines that are linked with the @emph{output} of the compiler. Using
the LGPL for these programs allows programs written using your compiler
to be closed source. For example LIBC is under the LGPL.
 
This need not be present if the language is incorporated into the main
GCC tree, as the main GCC directory has this file.
 
@item
ChangeLog. Record all the changes to your compiler. Use the same format
as used in treelang as it is supported by an emacs editing mode and is
part of the FSF coding standard. Normally each directory has its own
changelog. The FSF standard allows but does not require a meaningful
comment on why the changes were made, above and beyond @emph{why} they
were made. In the author's opinion it is useful to provide this
information.
 
@item
treelang.texi. The manual, written in texinfo. Your manual would have a
different file name. You need not write it in texinfo if you don't want
do, but a lot of GNU software does use texinfo.
 
@cindex Make-lang.in
@item
Make-lang.in. This file is part of the make file which in incorporated
with the GCC make file skeleton (Makefile.in in the GCC directory) to
make Makefile, as part of the configuration process.
 
Makefile in turn is the main instruction to actually build
everything. The build instructions are held in the main GCC manual and
web site so they are not repeated here.
 
There are some comments at the top which will help you understand what
you need to do.
 
There are make commands to build things, remove generated files with
various degrees of thoroughness, count the lines of code (so you know
how much progress you are making), build info and html files from the
texinfo source, run the tests etc.
 
@item
README. Just a brief informative text file saying what is in this
directory.
 
@cindex config-lang.in
@item
config-lang.in. This file is read by the configuration progress and must
be present. You specify the name of your language, the name(s) of the
compiler(s) including preprocessors you are going to build, whether any,
usually generated, files should be excluded from diffs (ie when making
diff files to send in patches). Whether the equate 'stagestuff' is used
is unknown (???).
 
@cindex lang.opt
@item
lang.opt. This file is included into @file{gcc.c}, the main GCC driver, and
tells it what options your language supports. This is also used to
display help.
 
@cindex lang-specs.h
@item
lang-specs.h. This file is also included in @file{gcc.c}. It tells
@file{gcc.c} when to call your programs and what options to send them. The
mini-language 'specs' is documented in the source of @file{gcc.c}. Do not
attempt to write a specs file from scratch - use an existing one as the base
and enhance it.
 
@item
Your texi files. Texinfo can be used to build documentation in HTML,
info, dvi and postscript formats. It is a tagged language, is documented
in its own manual, and has its own emacs mode.
 
@item
Your programs. The relationships between all the programs are explained
in the next section. You need to write or use the following programs:
 
@itemize @bullet
 
@item
lexer. This breaks the input into words and passes these to the
parser. This is @file{lex.l} in treelang, which is passed through flex, a lex
variant, to produce C code @file{lex.c}. Note there is a school of thought
that says real men hand code their own lexers. However, you may prefer to
write far less code and use flex, as was done with treelang.
 
@item
parser. This breaks the program into recognizable constructs such as
expressions, statements etc. This is @file{parse.y} in treelang, which is
passed through bison, which is a yacc variant, to produce C code
@file{parse.c}.
 
@item
back end interface. This interfaces to the code generation back end. In
treelang, this is @file{tree1.c} which mainly interfaces to @file{toplev.c} and
@file{treetree.c} which mainly interfaces to everything else. Many languages
mix up the back end interface with the parser, as in the C compiler for
example. It is a matter of taste which way to do it, but with treelang
it is separated out to make the back end interface cleaner and easier to
understand.
 
@item
header files. For function prototypes and common data items. One point
to note here is that bison can generate a header files with all the
numbers is has assigned to the keywords and symbols, and you can include
the same header in your lexer. This technique is demonstrated in
treelang.
 
@item
compiler main file. GCC comes with a file @file{toplev.c} which is a
perfectly serviceable main program for your compiler. GNU Treelang uses
@file{toplev.c} but other languages have been known to replace it with their
own main program. Again this is a matter of taste and how much code you
want to write.
 
@end itemize
 
@end enumerate
 
@node treelang compiler interfaces, Hints and tips, treelang files, treelang internals
@section treelang compiler interfaces
 
@cindex driver
@cindex toplev.c
 
@menu
* treelang driver::
* treelang main compiler::
@end menu
 
@node treelang driver, treelang main compiler, treelang compiler interfaces, treelang compiler interfaces
@subsection treelang driver
 
The GCC compiler consists of a driver, which then executes the various
compiler phases based on the instructions in the specs files.
 
Typically a program's language will be identified from its suffix
(e.g., @file{.tree}) for treelang programs.
 
The driver (@file{gcc.c}) will then drive (exec) in turn a preprocessor,
the main compiler, the assembler and the link editor. Options to GCC allow you
to override all of this. In the case of treelang programs there is no
preprocessor, and mostly these days the C preprocessor is run within the
main C compiler rather than as a separate process, apparently for reasons of speed.
 
You will be using the standard assembler and linkage editor so these are
ignored from now on.
 
You have to write your own preprocessor if you want one. This is usually
totally language specific. The main point to be aware of is to ensure
that you find some way to pass file name and line number information
through to the main compiler so that it can tell the back end this
information and so the debugger can find the right source line for each
piece of code. That is all there is to say about the preprocessor except
that the preprocessor will probably not be the slowest part of the
compiler and will probably not use the most memory so don't waste too
much time tuning it until you know you need to do so.
 
@node treelang main compiler, , treelang driver, treelang compiler interfaces
@subsection treelang main compiler
 
The main compiler for treelang consists of @file{toplev.c} from the main GCC
compiler, the parser, lexer and back end interface routines, and the
back end routines themselves, of which there are many.
 
@file{toplev.c} does a lot of work for you and you should almost certainly
use it.
 
Writing this code is the hard part of creating a compiler using GCC. The
back end interface documentation is incomplete and the interface is
complex.
 
There are three main aspects to interfacing to the other GCC code.
 
@menu
* Interfacing to toplev.c::
* Interfacing to the garbage collection::
* Interfacing to the code generation code. ::
@end menu
 
@node Interfacing to toplev.c, Interfacing to the garbage collection, treelang main compiler, treelang main compiler
@subsubsection Interfacing to toplev.c
 
In treelang this is handled mainly in tree1.c
and partly in treetree.c. Peruse toplev.c for details of what you need
to do.
 
@node Interfacing to the garbage collection, Interfacing to the code generation code. , Interfacing to toplev.c, treelang main compiler
@subsubsection Interfacing to the garbage collection
 
Interfacing to the garbage collection. In treelang this is mainly in
tree1.c.
 
Memory allocation in the compiler should be done using the ggc_alloc and
kindred routines in ggc*.*. At the end of every 'function' in your language, toplev.c calls
the garbage collection several times. The garbage collection calls mark
routines which go through the memory which is still used, telling the
garbage collection not to free it. Then all the memory not used is
freed.
 
What this means is that you need a way to hook into this marking
process. This is done by calling ggc_add_root. This provides the address
of a callback routine which will be called duing garbage collection and
which can call ggc_mark to save the storage. If storage is only
used within the parsing of a function, you do not need to provide a way
to mark it.
 
Note that you can also call ggc_mark_tree to mark any of the back end
internal 'tree' nodes. This routine will follow the branches of the
trees and mark all the subordinate structures. This is useful for
example when you have created a variable declaration that will be used
across multiple functions, or for a function declaration (from a
prototype) that may be used later on. See the next item for more on the
tree nodes.
 
@node Interfacing to the code generation code. , , Interfacing to the garbage collection, treelang main compiler
@subsubsection Interfacing to the code generation code.
 
In treelang this is done in treetree.c. A typedef called 'tree' which is
defined in tree.h and tree.def in the GCC directory and largely
implemented in tree.c and stmt.c forms the basic interface to the
compiler back end.
 
In general you call various tree routines to generate code, either
directly or through toplev.c. You build up data structures and
expressions in similar ways.
 
You can read some documentation on this which can be found via the GCC
main web page. In particular, the documentation produced by Joachim
Nadler and translated by Tim Josling can be quite useful. the C compiler
also has documentation in the main GCC manual (particularly the current
CVS version) which is useful on a lot of the details.
 
In time it is hoped to enhance this document to provide a more
comprehensive overview of this topic. The main gap is in explaining how
it all works together.
 
@node Hints and tips, , treelang compiler interfaces, treelang internals
@section Hints and tips
 
@itemize @bullet
 
@item
TAGS: Use the make ETAGS commands to create TAGS files which can be used in
emacs to jump to any symbol quickly.
 
@item
GREP: grep is also a useful way to find all uses of a symbol.
 
@item
TREE: The main routines to look at are tree.h and tree.def. You will
probably want a hardcopy of these.
 
@item
SAMPLE: look at the sample interfacing code in treetree.c. You can use
gdb to trace through the code and learn about how it all works.
 
@item
GDB: the GCC back end works well with gdb. It traps abort() and allows
you to trace back what went wrong.
 
@item
Error Checking: The compiler back end does some error and consistency
checking. Often the result of an error is just no code being
generated. You will then need to trace through and find out what is
going wrong. The rtl dump files can help here also.
 
@item
rtl dump files: The main compiler documents these files which are dumps
of the rtl (intermediate code) which is manipulated doing the code
generation process. This can provide useful clues about what is going
wrong. The rtl 'language' is documented in the main GCC manual.
 
@end itemize
 
@end ifset
 
@node Open Questions, Bugs, treelang internals, Top
@chapter Open Questions
 
If you know GCC well, please consider looking at the file treetree.c and
resolving any questions marked "???".
 
@node Bugs, Service, Open Questions, Top
@chapter Reporting Bugs
@cindex bugs
@cindex reporting bugs
 
You can report bugs to @email{@value{email-bugs}}. Please make
sure bugs are real before reporting them. Follow the guidelines in the
main GCC manual for submitting bug reports.
 
@menu
* Sending Patches::
@end menu
 
@node Sending Patches, , Bugs, Bugs
@section Sending Patches for GNU Treelang
 
If you would like to write bug fixes or improvements for the GNU
Treelang compiler, that is very helpful. Send suggested fixes to
@email{@value{email-patches}}.
 
@node Service, Projects, Bugs, Top
@chapter How To Get Help with GNU Treelang
 
If you need help installing, using or changing GNU Treelang, there are two
ways to find it:
 
@itemize @bullet
 
@item
Look in the service directory for someone who might help you for a fee.
The service directory is found in the file named @file{SERVICE} in the
GCC distribution.
 
@item
Send a message to @email{@value{email-general}}.
 
@end itemize
 
@end ifset
@ifset INTERNALS
 
@node Projects, Index, Service, Top
@chapter Projects
@cindex projects
 
If you want to contribute to @code{treelang} by doing research,
design, specification, documentation, coding, or testing,
the following information should give you some ideas.
 
Send a message to @email{@value{email-general}} if you plan to add a
feature.
 
The main requirement for treelang is to add features and to add
documentation. Features are things that the GCC back end can do but
which are not reflected in treelang. Examples include structures,
unions, pointers, arrays.
 
@end ifset
 
@node Index, , Projects, Top
@unnumbered Index
 
@printindex cp
@summarycontents
@contents
@bye
/config-lang.in
0,0 → 1,39
# Top level configure fragment for GNU C++.
# Copyright (C) 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2007
# Free Software Foundation, Inc.
 
#This file is part of GCC.
 
#GCC is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 3, or (at your option)
#any later version.
 
#GCC is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
 
#You should have received a copy of the GNU General Public License
#along with GCC; see the file COPYING3. If not see
#<http://www.gnu.org/licenses/>.
 
# Configure looks for the existence of this file to auto-config each language.
# We define several parameters used by configure:
#
# language - name of language as it would appear in $(LANGUAGES)
# compilers - value to add to $(COMPILERS)
# stagestuff - files to add to $(STAGESTUFF)
# diff_excludes - files to ignore when building diffs between two versions.
 
language="treelang"
 
compilers="tree1\$(exeext)"
 
stagestuff=
 
diff_excludes="-x lex.c -x parse.c -x parse.h"
headers=
build_by_default="no"
 
gtfiles="\$(srcdir)/treelang/tree1.c \$(srcdir)/treelang/treetree.c \$(srcdir)/treelang/treelang.h"
/spec.c
0,0 → 1,60
/* Specific flags and argument handling of the Treelang front-end.
Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
 
This file is part of GCC.
 
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
 
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
 
#include "config.h"
#include "system.h"
#include "gcc.h"
 
#include "coretypes.h"
#include "tm.h"
 
void
lang_specific_driver (int *in_argc, const char *const **in_argv,
int *in_added_libraries ATTRIBUTE_UNUSED)
{
int argc = *in_argc, i;
const char *const *argv = *in_argv;
 
for (i = 1; i < argc; ++i)
{
if (!strcmp (argv[i], "-fversion")) /* Really --version!! */
{
printf ("\
GNU Treelang (GCC %s)\n\
Copyright (C) 2006 Free Software Foundation, Inc.\n\
\n\
GNU Treelang comes with NO WARRANTY, to the extent permitted by law.\n\
You may redistribute copies of GNU Treelang\n\
under the terms of the GNU General Public License.\n\
For more information about these matters, see the file named COPYING\n\
", version_string);
exit (0);
}
}
}
 
/* Called before linking. Returns 0 on success and -1 on failure. */
int
lang_specific_pre_link (void) /* Not used for Treelang. */
{
return 0;
}
 
/* Number of extra output files that lang_specific_pre_link may generate. */
int lang_specific_extra_outfiles = 0; /* Not used for Treelang. */
/README
0,0 → 1,19
This is a sample language front end for GCC.
 
This is a replacement for 'toy' which had potential copyright issues,
but more importantly it did not exercise very much of GCC. The intent
of this language is that it should provide a cookbook of language
elements that you can use in any language front end.
 
To this end, treelang is essentially an implementation of a subset of
the GCC back end 'tree' interface in syntax.
 
Thanks to Richard Kenner, Joachim Nadler and many others for helping
me to understand enough of GCC to do this.
 
Please note, the documentation is not a good model to use for GCC
front end documentation.
 
Tim Josling
19 June 2002
 
/tree-convert.c
0,0 → 1,107
/* Language-level data type conversion for Treelang.
This is a very slightly modified copy of c-convert.c.
Copyright (C) 1987, 1988, 1991, 1998, 2002, 2003, 2007
Free Software Foundation, Inc.
 
This file is part of GCC.
 
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
 
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
 
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
 
 
/* This file contains the functions for converting C expressions
to different data types. The only entry point is `convert'.
Every language front end must have a `convert' function
but what kind of conversions it does will depend on the language. */
 
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "diagnostic.h"
#include "tree.h"
#include "flags.h"
#include "convert.h"
#include "toplev.h"
#include "langhooks.h"
 
/* Change of width--truncation and extension of integers or reals--
is represented with NOP_EXPR. Proper functioning of many things
assumes that no other conversions can be NOP_EXPRs.
 
Conversion between integer and pointer is represented with CONVERT_EXPR.
Converting integer to real uses FLOAT_EXPR
and real to integer uses FIX_TRUNC_EXPR.
 
Here is a list of all the functions that assume that widening and
narrowing is always done with a NOP_EXPR:
In convert.c, convert_to_integer.
In c-typeck.c, build_binary_op (boolean ops), and
c_common_truthvalue_conversion.
In expr.c: expand_expr, for operands of a MULT_EXPR.
In fold-const.c: fold.
In tree.c: get_narrower and get_unwidened. */
/* Create an expression whose value is that of EXPR,
converted to type TYPE. The TREE_TYPE of the value
is always TYPE. This function implements all reasonable
conversions; callers should filter out those that are
not permitted by the language being compiled. */
 
tree
convert (tree type, tree expr)
{
tree e = expr;
enum tree_code code = TREE_CODE (type);
 
if (type == TREE_TYPE (expr)
|| TREE_CODE (expr) == ERROR_MARK
|| code == ERROR_MARK || TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
return expr;
 
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
return fold_build1 (NOP_EXPR, type, expr);
if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
return error_mark_node;
if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
{
error ("void value not ignored as it ought to be");
return error_mark_node;
}
if (code == VOID_TYPE)
return build1 (CONVERT_EXPR, type, e);
if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
return fold (convert_to_integer (type, e));
if (code == BOOLEAN_TYPE)
{
tree t = expr;
/* If it returns a NOP_EXPR, we must fold it here to avoid
infinite recursion between fold () and convert (). */
if (TREE_CODE (t) == NOP_EXPR)
return fold_build1 (NOP_EXPR, type, TREE_OPERAND (t, 0));
else
return fold_build1 (NOP_EXPR, type, t);
}
if (code == POINTER_TYPE || code == REFERENCE_TYPE)
return fold (convert_to_pointer (type, e));
if (code == REAL_TYPE)
return fold (convert_to_real (type, e));
if (code == COMPLEX_TYPE)
return fold (convert_to_complex (type, e));
if (code == VECTOR_TYPE)
return fold (convert_to_vector (type, e));
 
error ("conversion to non-scalar type requested");
return error_mark_node;
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.