#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "output.h"
#include "rtl.h"
#include "ggc.h"
#include "toplev.h"
#include "varray.h"
#include "langhooks-def.h"
#include "langhooks.h"
#include "target.h"
#include "treelang.h"
#include "treetree.h"
#include "opts.h"
extern int option_main;
extern char **file_names;
struct lang_identifier GTY(())
{
struct tree_identifier common;
};
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;
};
struct lang_type GTY(())
{
char junk;
};
struct lang_decl GTY(())
{
char junk;
};
struct language_function GTY(())
{
char junk;
};
static tree tree_lang_truthvalue_conversion (tree expr);
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);
void pushlevel (int ignore);
tree poplevel (int keep, int reverse, int functionbody);
int global_bindings_p (void);
void insert_block (tree block);
void set_block (tree block);
tree pushdecl (tree decl);
tree getdecls (void);
int kept_level_p (void);
static void tree_push_type_decl (tree id, tree type_node);
static void tree_push_atomic_type_decl (tree id, tree type_node);
#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
#define LANG_HOOKS_TRUTHVALUE_CONVERSION tree_lang_truthvalue_conversion
#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_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;
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
const char tree_code_type[] = {
#include "tree.def"
'x'
};
#undef DEFTREECODE
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
const unsigned char tree_code_length[] = {
#include "tree.def"
0
};
#undef DEFTREECODE
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
const char *const tree_code_name[] = {
#include "tree.def"
"@@dummy"
};
#undef DEFTREECODE
unsigned int tree_code_int_size = SIZEOF_INT * HOST_BITS_PER_CHAR;
unsigned int tree_code_char_size = HOST_BITS_PER_CHAR;
tree
tree_code_get_type (int type_num)
{
switch (type_num)
{
case SIGNED_CHAR:
return signed_char_type_node;
case UNSIGNED_CHAR:
return unsigned_char_type_node;
case SIGNED_INT:
return integer_type_node;
case UNSIGNED_INT:
return unsigned_type_node;
case VOID_TYPE:
return void_type_node;
default:
abort ();
}
}
void
tree_code_if_start (tree exp, location_t loc)
{
tree cond_exp;
cond_exp = build (NE_EXPR,
TREE_TYPE (exp),
exp,
build1 (CONVERT_EXPR, TREE_TYPE (exp), integer_zero_node));
emit_line_note (loc);
expand_start_cond (cond_exp, 0);
}
void
tree_code_if_else (location_t loc)
{
emit_line_note (loc);
expand_start_else ();
}
void
tree_code_if_end (location_t loc)
{
emit_line_note (loc);
expand_end_cond ();
}
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;
id = get_identifier ((const char*)chars);
for (parm = parms; parm; parm = parm->tp.par.next)
{
if (parm->category != parameter_category)
abort ();
type_node = get_type_for_numeric_type (parm->type);
type_list = tree_cons (NULL_TREE, type_node, type_list);
}
type_list = tree_cons (NULL_TREE, void_type_node, type_list);
type_list = nreverse (type_list);
type_node = get_type_for_numeric_type (ret_type);
fn_type = build_function_type (type_node, type_list);
id = get_identifier ((const char*)chars);
fn_decl = build_decl (FUNCTION_DECL, id, fn_type);
DECL_CONTEXT (fn_decl) = NULL_TREE;
DECL_SOURCE_LOCATION (fn_decl) = loc;
TREE_USED (fn_decl) = 1;
SET_DECL_ASSEMBLER_NAME (fn_decl, DECL_NAME (fn_decl));
TREE_PUBLIC (fn_decl) = 0;
DECL_EXTERNAL (fn_decl) = 0;
TREE_STATIC (fn_decl) = 0;
switch (storage_class)
{
case STATIC_STORAGE:
TREE_PUBLIC (fn_decl) = 0;
break;
case EXTERNAL_DEFINITION_STORAGE:
TREE_PUBLIC (fn_decl) = 1;
TREE_STATIC (fn_decl) = 0;
DECL_EXTERNAL (fn_decl) = 0;
break;
case EXTERNAL_REFERENCE_STORAGE:
TREE_PUBLIC (fn_decl) = 0;
DECL_EXTERNAL (fn_decl) = 1;
break;
case AUTOMATIC_STORAGE:
default:
abort ();
}
rest_of_decl_compilation (fn_decl, NULL, 1, 0);
return fn_decl;
}
void
tree_code_create_function_initial (tree prev_saved,
location_t loc,
struct prod_token_parm_item* parms)
{
tree fn_decl;
tree param_decl;
tree next_param;
tree first_param;
tree parm_decl;
tree parm_list;
tree resultdecl;
struct prod_token_parm_item* this_parm;
struct prod_token_parm_item* parm;
fn_decl = prev_saved;
if (!fn_decl)
abort ();
announce_function (fn_decl);
pushdecl (fn_decl);
current_function_decl = fn_decl;
DECL_INITIAL (fn_decl) = error_mark_node;
DECL_SOURCE_LOCATION (fn_decl) = loc;
resultdecl = DECL_RESULT (fn_decl)
= build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (TREE_TYPE (fn_decl)));
DECL_CONTEXT (DECL_RESULT (fn_decl)) = fn_decl;
DECL_SOURCE_LOCATION (resultdecl) = loc;
layout_decl (DECL_RESULT (fn_decl), 0);
parm_list = NULL_TREE;
for (parm = parms; parm; parm = parm->tp.par.next)
{
parm_decl = build_decl (PARM_DECL, get_identifier
((const char*) (parm->tp.par.variable_name)),
get_type_for_numeric_type (parm->type));
DECL_ARG_TYPE (parm_decl) = TREE_TYPE (parm_decl);
if (!DECL_ARG_TYPE (parm_decl))
abort ();
if (!fn_decl)
abort ();
DECL_CONTEXT (parm_decl) = fn_decl;
DECL_SOURCE_LOCATION (parm_decl) = loc;
parm_list = chainon (parm_decl, parm_list);
}
parm_list = nreverse (parm_list);
DECL_ARGUMENTS (fn_decl) = parm_list;
for (param_decl = DECL_ARGUMENTS (fn_decl),
this_parm = parms;
param_decl;
param_decl = TREE_CHAIN (param_decl),
this_parm = this_parm->tp.par.next)
{
if (!this_parm)
abort ();
*this_parm->tp.par.where_to_put_var_tree = param_decl;
}
if (this_parm)
abort ();
make_decl_rtl (fn_decl, NULL);
init_function_start (fn_decl);
expand_function_start (fn_decl, 0);
(*lang_hooks.decls.pushlevel) (0);
expand_start_bindings (2);
for (first_param = param_decl = nreverse (DECL_ARGUMENTS (fn_decl));
param_decl;
param_decl = next_param)
{
next_param = TREE_CHAIN (param_decl);
TREE_CHAIN (param_decl) = NULL;
pushdecl (param_decl);
if (DECL_CONTEXT (param_decl) != current_function_decl)
abort ();
}
DECL_ARGUMENTS (fn_decl) = getdecls ();
TREE_ADDRESSABLE (fn_decl) = 1;
TREE_USED (fn_decl) = 1;
(*lang_hooks.decls.pushlevel) (0);
expand_start_bindings (0);
emit_line_note (loc);
}
void
tree_code_create_function_wrapup (location_t loc)
{
tree block;
tree fn_decl;
fn_decl = current_function_decl;
emit_line_note (loc);
block = (*lang_hooks.decls.poplevel) (1, 0, 0);
expand_end_bindings (block, 0, 1);
expand_function_end ();
block = (*lang_hooks.decls.poplevel) (1, 0, 1);
DECL_INITIAL (fn_decl) = block;
expand_end_bindings (block, 0, 1);
rest_of_compilation (fn_decl);
current_function_decl = NULL_TREE;
}
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;
var_type = get_type_for_numeric_type (expression_type);
if (chars[length] != 0)
abort ();
var_id = get_identifier ((const char*)chars);
var_decl = build_decl (VAR_DECL, var_id, var_type);
if (init)
DECL_INITIAL (var_decl) = build1 (CONVERT_EXPR, var_type, init);
else
DECL_INITIAL (var_decl) = NULL_TREE;
layout_decl (var_decl, 0);
if (TYPE_SIZE (var_type) == 0)
abort ();
DECL_CONTEXT (var_decl) = current_function_decl;
DECL_SOURCE_LOCATION (var_decl) = loc;
switch (storage_class)
{
case STATIC_STORAGE:
TREE_STATIC (var_decl) = 1;
TREE_PUBLIC (var_decl) = 0;
break;
case AUTOMATIC_STORAGE:
TREE_STATIC (var_decl) = 0;
TREE_PUBLIC (var_decl) = 0;
break;
case EXTERNAL_DEFINITION_STORAGE:
TREE_STATIC (var_decl) = 0;
TREE_PUBLIC (var_decl) = 1;
break;
case EXTERNAL_REFERENCE_STORAGE:
DECL_EXTERNAL (var_decl) = 1;
TREE_PUBLIC (var_decl) = 0;
break;
default:
abort ();
}
TREE_USED (var_decl) = 1;
if (TREE_STATIC (var_decl))
rest_of_decl_compilation (var_decl, 0, 0, 0);
else
{
expand_decl (var_decl);
if (DECL_INITIAL (var_decl))
expand_decl_init (var_decl);
}
return pushdecl (copy_node (var_decl));
}
void
tree_code_generate_return (tree type, tree exp)
{
tree setret;
tree param;
for (param = DECL_ARGUMENTS (current_function_decl);
param;
param = TREE_CHAIN (param))
{
if (DECL_CONTEXT (param) != current_function_decl)
abort ();
}
if (exp)
{
setret = build (MODIFY_EXPR, type, DECL_RESULT (current_function_decl),
build1 (CONVERT_EXPR, type, exp));
TREE_SIDE_EFFECTS (setret) = 1;
TREE_USED (setret) = 1;
expand_expr_stmt (setret);
}
expand_return (DECL_RESULT (current_function_decl));
}
void
tree_code_output_expression_statement (tree code, location_t loc)
{
emit_line_note (loc);
TREE_USED (code) = 1;
TREE_SIDE_EFFECTS (code) = 1;
expand_expr_stmt (code);
}
tree
tree_code_get_integer_value (unsigned char* chars, unsigned int length)
{
long long int val = 0;
unsigned int ix;
unsigned int start = 0;
int negative = 1;
switch (chars[0])
{
case (unsigned char)'-':
negative = -1;
start = 1;
break;
case (unsigned char)'+':
start = 1;
break;
default:
break;
}
for (ix = start; ix < length; ix++)
val = val * 10 + chars[ix] - (unsigned char)'0';
val = val*negative;
return build_int_2 (val & 0xffffffff, (val >> 32) & 0xffffffff);
}
tree
tree_code_get_expression (unsigned int exp_type,
tree type, tree op1, tree op2,
tree op3 ATTRIBUTE_UNUSED)
{
tree ret1;
int operator;
switch (exp_type)
{
case EXP_ASSIGN:
if (!op1 || !op2)
abort ();
operator = MODIFY_EXPR;
ret1 = build (operator, type,
op1,
build1 (CONVERT_EXPR, type, op2));
break;
case EXP_PLUS:
operator = PLUS_EXPR;
goto binary_expression;
case EXP_MINUS:
operator = MINUS_EXPR;
goto binary_expression;
case EXP_EQUALS:
operator = EQ_EXPR;
goto binary_expression;
binary_expression:
if (!op1 || !op2)
abort ();
ret1 = build (operator, type,
build1 (CONVERT_EXPR, type, op1),
build1 (CONVERT_EXPR, type, op2));
break;
case EXP_REFERENCE:
if (!op1)
abort ();
if (type == TREE_TYPE (op1))
ret1 = op1;
else
ret1 = build1 (CONVERT_EXPR, type, op1);
break;
case EXP_FUNCTION_INVOCATION:
if (!op1 || !op2)
abort ();
{
tree fun_ptr;
fun_ptr = build1 (ADDR_EXPR, build_pointer_type (type), op1);
ret1 = build (CALL_EXPR, type, fun_ptr, nreverse (op2));
}
break;
default:
abort ();
}
return ret1;
}
tree
tree_code_init_parameters (void)
{
return NULL_TREE;
}
tree
tree_code_add_parameter (tree list, tree proto_exp, tree exp)
{
tree new_exp;
new_exp = tree_cons (NULL_TREE,
build1 (CONVERT_EXPR, TREE_TYPE (proto_exp), exp),
NULL_TREE);
if (!list)
return new_exp;
return chainon (new_exp, list);
}
tree
get_type_for_numeric_type (unsigned int numeric_type)
{
int size1;
int sign1;
switch (numeric_type)
{
case VOID_TYPE:
return void_type_node;
case SIGNED_INT:
size1 = tree_code_int_size;
sign1 = 1;
break;
case UNSIGNED_INT:
size1 = tree_code_int_size;
sign1 = 0;
break;
case SIGNED_CHAR:
size1 = tree_code_char_size;
sign1 = 1;
break;
case UNSIGNED_CHAR:
size1 = tree_code_char_size;
sign1 = 0;
break;
default:
abort ();
}
return tree_code_get_numeric_type (size1, sign1);
}
tree
tree_code_get_numeric_type (unsigned int size1, unsigned int sign1)
{
tree ret1;
if (!size1)
abort ();
if (size1 == tree_code_int_size)
{
if (sign1)
ret1 = integer_type_node;
else
ret1 = unsigned_type_node;
}
else
if (size1 == tree_code_char_size)
{
if (sign1)
ret1 = signed_char_type_node;
else
ret1 = unsigned_char_type_node;
}
else
abort ();
return ret1;
}
const char*
get_string (const char *s, size_t l)
{
tree t;
t = get_identifier_with_length (s, l);
return IDENTIFIER_POINTER(t);
}
void dt (tree t);
void
dt (tree t)
{
debug_tree (t);
}
#ifndef MAX_BITS_PER_WORD
#define MAX_BITS_PER_WORD BITS_PER_WORD
#endif
static GTY(()) tree signed_and_unsigned_types[MAX_BITS_PER_WORD + 1][2];
static tree
tree_lang_truthvalue_conversion (tree expr)
{
return expr;
}
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 `%s' used in nested function",
IDENTIFIER_POINTER (DECL_NAME (x)));
return 0;
}
pedwarn ("register variable `%s' used in nested function",
IDENTIFIER_POINTER (DECL_NAME (x)));
}
else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
{
if (TREE_PUBLIC (x))
{
error ("address of global register variable `%s' requested",
IDENTIFIER_POINTER (DECL_NAME (x)));
return 0;
}
pedwarn ("address of register variable `%s' requested",
IDENTIFIER_POINTER (DECL_NAME (x)));
}
put_var_into_stack (x, true);
case FUNCTION_DECL:
TREE_ADDRESSABLE (x) = 1;
default:
return 1;
}
}
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;
}
static tree
tree_lang_type_for_mode (enum machine_mode mode, int unsignedp)
{
return tree_lang_type_for_size (GET_MODE_BITSIZE (mode), unsignedp);
}
static tree
tree_lang_unsigned_type (tree type_node)
{
return tree_lang_type_for_size (TYPE_PRECISION (type_node), 1);
}
static tree
tree_lang_signed_type (tree type_node)
{
return tree_lang_type_for_size (TYPE_PRECISION (type_node), 0);
}
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);
}
struct binding_level
{
tree names;
tree blocks;
tree block_created_by_back_end;
struct binding_level *level_chain;
};
static struct binding_level *current_binding_level = NULL;
static struct binding_level *global_binding_level;
static struct binding_level clear_binding_level = {NULL, NULL, NULL, NULL};
int
global_bindings_p (void)
{
return current_binding_level == global_binding_level ? -1 : 0;
}
tree
getdecls (void)
{
return current_binding_level->names;
}
int
kept_level_p (void)
{
return (current_binding_level->names != 0);
}
void
pushlevel (int ignore ATTRIBUTE_UNUSED)
{
struct binding_level *newlevel = xmalloc (sizeof (struct binding_level));
*newlevel = clear_binding_level;
newlevel->level_chain = current_binding_level;
current_binding_level = newlevel;
}
tree
poplevel (int keep, int reverse, int functionbody)
{
tree block_node = NULL_TREE;
tree decl_chain;
tree subblock_chain = current_binding_level->blocks;
tree subblock_node;
tree block_created_by_back_end;
decl_chain = (reverse) ? nreverse (current_binding_level->names)
: current_binding_level->names;
block_created_by_back_end = current_binding_level->block_created_by_back_end;
if (block_created_by_back_end != 0)
{
block_node = block_created_by_back_end;
if ((keep || functionbody) && (decl_chain || subblock_chain))
abort ();
}
else if (keep || functionbody)
block_node = build_block (keep ? decl_chain : 0, 0, subblock_chain, 0, 0);
for (subblock_node = subblock_chain; subblock_node;
subblock_node = TREE_CHAIN (subblock_node))
BLOCK_SUPERCONTEXT (subblock_node) = block_node;
for (subblock_node = decl_chain; subblock_node;
subblock_node = TREE_CHAIN (subblock_node))
if (DECL_NAME (subblock_node) != 0)
if (DECL_EXTERNAL (subblock_node))
{
if (TREE_USED (subblock_node))
TREE_USED (DECL_NAME (subblock_node)) = 1;
if (TREE_ADDRESSABLE (subblock_node))
TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (subblock_node)) = 1;
}
current_binding_level = current_binding_level->level_chain;
if (functionbody)
{
DECL_INITIAL (current_function_decl) = block_node;
BLOCK_VARS (block_node) = 0;
}
else if (block_node)
{
if (block_created_by_back_end == NULL)
current_binding_level->blocks
= chainon (current_binding_level->blocks, block_node);
}
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;
}
void
insert_block (tree block)
{
TREE_USED (block) = 1;
current_binding_level->blocks
= chainon (current_binding_level->blocks, block);
}
void
set_block (tree block)
{
current_binding_level->block_created_by_back_end = block;
}
tree
pushdecl (tree decl)
{
if ((DECL_EXTERNAL (decl)) || (decl==current_function_decl))
DECL_CONTEXT (decl) = 0;
else
DECL_CONTEXT (decl) = current_function_decl;
TREE_CHAIN (decl) = current_binding_level->names;
current_binding_level->names = decl;
if (TREE_CODE (decl) == TYPE_DECL
&& TYPE_NAME (TREE_TYPE (decl)) == 0)
TYPE_NAME (TREE_TYPE (decl)) = DECL_NAME (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) = decl;
TYPE_STUB_DECL (type_node) = decl;
pushdecl (decl);
}
static void
tree_push_atomic_type_decl(tree id, tree type_node)
{
TREE_TYPE (type_node) = type_node;
tree_push_type_decl (id, type_node);
}
#define NULL_BINDING_LEVEL (struct binding_level *) NULL
void
treelang_init_decl_processing (void)
{
current_function_decl = NULL;
current_binding_level = NULL_BINDING_LEVEL;
pushlevel (0);
global_binding_level = current_binding_level;
build_common_tree_nodes (flag_signed_char);
tree_push_atomic_type_decl (get_identifier ("int"), integer_type_node);
tree_push_atomic_type_decl (get_identifier ("char"), char_type_node);
tree_push_atomic_type_decl (get_identifier ("long int"),
long_integer_type_node);
tree_push_atomic_type_decl (get_identifier ("unsigned int"),
unsigned_type_node);
tree_push_atomic_type_decl (get_identifier ("long unsigned int"),
long_unsigned_type_node);
tree_push_atomic_type_decl (get_identifier ("long long int"),
long_long_integer_type_node);
tree_push_atomic_type_decl (get_identifier ("long long unsigned int"),
long_long_unsigned_type_node);
tree_push_atomic_type_decl (get_identifier ("short int"),
short_integer_type_node);
tree_push_atomic_type_decl (get_identifier ("short unsigned int"),
short_unsigned_type_node);
tree_push_atomic_type_decl (get_identifier ("signed char"),
signed_char_type_node);
tree_push_atomic_type_decl (get_identifier ("unsigned char"),
unsigned_char_type_node);
tree_push_atomic_type_decl (NULL_TREE, intQI_type_node);
tree_push_atomic_type_decl (NULL_TREE, intHI_type_node);
tree_push_atomic_type_decl (NULL_TREE, intSI_type_node);
tree_push_atomic_type_decl (NULL_TREE, intDI_type_node);
#if HOST_BITS_PER_WIDE_INT >= 64
tree_push_atomic_type_decl (NULL_TREE, intTI_type_node);
#endif
tree_push_atomic_type_decl (NULL_TREE, unsigned_intQI_type_node);
tree_push_atomic_type_decl (NULL_TREE, unsigned_intHI_type_node);
tree_push_atomic_type_decl (NULL_TREE, unsigned_intSI_type_node);
tree_push_atomic_type_decl (NULL_TREE, unsigned_intDI_type_node);
#if HOST_BITS_PER_WIDE_INT >= 64
tree_push_atomic_type_decl (NULL_TREE, unsigned_intTI_type_node);
#endif
size_type_node = make_unsigned_type (POINTER_SIZE);
tree_push_atomic_type_decl (get_identifier ("size_t"), size_type_node);
set_sizetype (size_type_node);
build_common_tree_nodes_2 ( 0);
tree_push_atomic_type_decl (get_identifier ("float"), float_type_node);
tree_push_atomic_type_decl (get_identifier ("double"), double_type_node);
tree_push_atomic_type_decl (get_identifier ("long double"), long_double_type_node);
tree_push_atomic_type_decl (get_identifier ("void"), void_type_node);
(*targetm.init_builtins) ();
pedantic_lvalues = pedantic;
}
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));
make_decl_rtl (decl, NULL);
pushdecl (decl);
DECL_BUILT_IN_CLASS (decl) = class;
DECL_FUNCTION_CODE (decl) = function_code;
if (attrs)
decl_attributes (&decl, attrs, ATTR_FLAG_BUILT_IN);
else
decl_attributes (&decl, NULL_TREE, 0);
return decl;
}
#include "debug.h"
#include "gt-treelang-treetree.h"