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 ¤t_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; |
} |