/* 
 * $Id: C-front.h,v 1.3 2002/02/20 06:32:45 m-hirano Exp $
 * $RWC_Release: Omni-1.6 $
 * $RWC_Copyright:
 *  Omni Compiler Software Version 1.5-1.6
 *  Copyright (C) 2002 PC Cluster Consortium
 *  
 *  This software is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License version
 *  2.1 published by the Free Software Foundation.
 *  
 *  Omni Compiler Software Version 1.0-1.4
 *  Copyright (C) 1999, 2000, 2001.
 *   Tsukuba Research Center, Real World Computing Partnership, Japan.
 *  
 *  Please check the Copyright and License information in the files named
 *  COPYRIGHT and LICENSE under the top  directory of the Omni Compiler
 *  Software release kit.
 *  
 *  
 *  $
 */
/* 
 * K&R C language frontend 
 */
#include "exc_platform.h"

#define USE_PRAGMA
#define USE_TEA_PRAGMA
#define INT_IS_LONG /* for 32bit machine ? */

#define TRUE	1
#define FALSE 	0

#include "C-exprcode.h"
#include "C-expr.h"
#include "C-datatype.h"
#include "C-ident.h"
#include "C-pragma.h"

/* maximum nest level for compound statment */
#define MAX_NEST_LEVEL 	100

#define FILE_NAME_LEN 	125
#define MAX_N_FILES 	128
extern int n_files;
extern char *file_names[];
#define FILE_NAME(id) file_names[id]

extern lineno_info *current_line;

extern char *source_file_name, *output_file_name, *outX_file_name;
extern FILE *source_file, *output_file, *out_X_file;

/* debug flag(in C-main.c) */
extern int debug_flag;
extern int debug_flag2;
extern int debug_X_flag;
extern int debug_X_flag2;
extern int debug_expr_flag;
extern FILE *debug_fp;

extern int no_omp_flag;
#ifdef USE_OPENGR_PRAGMA
extern int no_ogr_flag;
#endif /* USE_OPENGR_PRAGMA */
extern int array_arg_flag;

#define EXPV_IS_POINTER(v)	IS_POINTER(EXPV_TYPE(v))
#define EXPV_IS_INTEGRAL(v)	IS_INTEGRAL(EXPV_TYPE(v))
#define EXPV_IS_ARITHMETIC(v)	IS_ARITHMETIC(EXPV_TYPE(v))
#define EXPV_IS_SCALAR(v)	IS_SCALAR(EXPV_TYPE(v))
#define EXPV_IS_STRUCT(v)	IS_STRUCT(EXPV_TYPE(v))
#define EXPV_IS_UNION(v)	IS_UNION(EXPV_TYPE(v))
#define EXPV_IS_ENUM(v)		IS_ENUM(EXPV_TYPE(v))
#define EXPV_IS_ZERO(v)	\
 ((EXPV_CODE(v) == INT_CONSTANT || EXPV_CODE(v) == LONG_CONSTANT)\
  && EXPV_INT_VALUE(v) == 0)
#define EXPV_IS_ONE(v)	\
 ((EXPV_CODE(v) == INT_CONSTANT || EXPV_CODE(v) == LONG_CONSTANT)\
   && EXPV_INT_VALUE(v) == 1)
#define EXPV_IS_MINUS_ONE(v)	\
 ((EXPV_CODE(v) == INT_CONSTANT || EXPV_CODE(v) == LONG_CONSTANT)\
    && EXPV_INT_VALUE(v) == -1)
#define EXPV_IS_ZERO_FLOAT(v)	\
  (EXPV_CODE(v) == FLOAT_CONSTANT && EXPV_FLOAT_VALUE(v) == 0.0)
#define EXPV_IS_ONE_FLOAT(v)	\
  (EXPV_CODE(v) == FLOAT_CONSTANT && EXPV_FLOAT_VALUE(v) == 1.0)
#define EXPV_IS_FUNCTION(v)	IS_FUNCTION(EXPV_TYPE(v))
#define EXPV_IS_ARRAY(v)	IS_ARRAY(EXPV_TYPE(v))

/* nexted block information */
extern int current_level;
extern ID id_lists[];
extern expv decl_lists[];

#define PUSH_ENV	id_lists[++current_level] = NULL; \
                        decl_lists[current_level] = list0(LIST)
#define POP_ENV		current_level--
#define CURRENT_ID_LIST	id_lists[current_level]
#define CURRENT_DECL_LIST decl_lists[current_level]
#define GLOBAL_ID_LIST 	id_lists[0]
#define GLOBAL_DECL_LIST decl_lists[0]

/* "break" and "continue" scopes */
#define MAX_BREAK_LEVEL 	50
#define MAX_CONT_LEVEL 		50
#define MAX_SWITCH_LEVEL	50

extern ID switch_labels[];
extern int break_level;
extern int continue_level;
extern int switch_level;
extern TYPE_DESC return_type;

#define ROUND(x,y)	(((x)+(y)-1)/(y))*(y)
#define MAX(x,y)	((x)>(y)? (x):(y))
#define MIN(x,y)	((x)<(y)? (x):(y))

extern expr constant_1;
extern TYPE_DESC default_data_type;
extern TYPE_DESC default_func_type;
extern TYPE_DESC int_type, long_type, unsigned_int_type, float_type;
extern TYPE_DESC void_pointer_type;	/* pointer to any, void * */
extern TYPE_DESC string_type, longlong_type;

extern expv expv_constant_0, expv_constant_1, expv_constant_m1;
extern expv expv_float_0;

extern int enum_type_size, enum_type_align;
extern int pointer_type_size, pointer_type_align;
extern int alignment_double;

/* flags */
extern int X_flag;
extern TYPE_DESC type_list, type_list_tail;

/* for C++ */
#define CXX_ATTR_PUBLIC 0
#define CXX_ATTR_PRIVATE 1
#define CXX_ATTR_PROTECTED 2
#define CXX_EXTERN_C_BEGIN 3
#define CXX_EXTERN_C_END 4
#define CXX_EXTERN_CXX_BEGIN 5
#define CXX_EXTERN_CXX_END 6

/* prototypes */
extern lineno_info *	new_line_info _ANSI_ARGS_((int fid, int ln));
extern expr	pragma_name_value _ANSI_ARGS_((SYMBOL sp));
extern void	string_to_integer _ANSI_ARGS_((long int *p,long int *hp,char *cp, int radix));

extern char *	strip_dir _ANSI_ARGS_((char *));
extern void	compile_function _ANSI_ARGS_((expr x));
extern void	initialize_compile _ANSI_ARGS_((void));
extern void	compile_external_declaration _ANSI_ARGS_((expr x));
extern void	compile_type_definition _ANSI_ARGS_((expr type_spec, expr decl_list));
extern TYPE_DESC	compile_decl_type_spec _ANSI_ARGS_((expr x));
void		compile_declaration _ANSI_ARGS_((expr , STORAGE_CLASS));
extern void	compile_enum_elements _ANSI_ARGS_((TYPE_DESC tp, expr elem_list));
extern void	compile_struct_declaration _ANSI_ARGS_((TYPE_DESC tp,expr decl_list));
extern TYPE_DESC	compile_declarator_type _ANSI_ARGS_((expr decl, TYPE_DESC tp));
extern TYPE_DESC	combine_basic_type _ANSI_ARGS_((expr x, TYPE_DESC tp));
extern TYPE_DESC	combine_type_qual _ANSI_ARGS_((expr x, TYPE_DESC tp));

extern TYPE_DESC	pointer_type _ANSI_ARGS_((TYPE_DESC tp));
extern TYPE_DESC	func_type _ANSI_ARGS_((TYPE_DESC tp));
extern TYPE_DESC	duplicate_type _ANSI_ARGS_((TYPE_DESC tp));
extern ID	lookup_ident _ANSI_ARGS_((expr name));
extern ID	define_ident _ANSI_ARGS_((expr name, STORAGE_CLASS class, TYPE_DESC tp));

extern void	check_type_combination _ANSI_ARGS_((TYPE_DESC tp, expr name));
extern void	align_offset _ANSI_ARGS_((TYPE_DESC tp, int *offset));
extern int	is_integral_type _ANSI_ARGS_((TYPE_DESC tp));
extern int	is_unsigned_type _ANSI_ARGS_((TYPE_DESC tp));
extern int	is_float_type _ANSI_ARGS_((TYPE_DESC tp));
extern int	type_equal _ANSI_ARGS_((TYPE_DESC tp, TYPE_DESC tq));
extern int	is_compatible_type _ANSI_ARGS_((TYPE_DESC tp,TYPE_DESC tq));
extern void	null_ansi_param _ANSI_ARGS_((TYPE_DESC  type));
extern void	move_id_last _ANSI_ARGS_((TYPE_DESC  type, expr  decl));

extern void	print_type_name _ANSI_ARGS_((TYPE_DESC tp, FILE *fp));
extern void	print_type _ANSI_ARGS_((TYPE_DESC tp, FILE *fp));
extern void	print_ID _ANSI_ARGS_((ID id, FILE *fp));
extern void	dump_id_list _ANSI_ARGS_((int lev));
extern void	print_id_list _ANSI_ARGS_((char *msg,ID id_list,FILE *fp));

extern expv	compile_init_assignment _ANSI_ARGS_((TYPE_DESC tp, expr init, int must_const));
extern expv	compile_compound_statement _ANSI_ARGS_((expr x));
extern expv	compile_statement _ANSI_ARGS_((expr x));
extern expv	compile_expression _ANSI_ARGS_((expr x));
extern int	expv_is_constant _ANSI_ARGS_((expv v));
extern int	expv_is_addr _ANSI_ARGS_((expv v));


extern expv	compile_logical_expression _ANSI_ARGS_((expr x));
extern expv	eval_expression _ANSI_ARGS_((expr x));
extern expv	compile_lvalue_expression _ANSI_ARGS_((expr x));
extern expv	expv_type_conversion _ANSI_ARGS_((TYPE_DESC tp, expv v));

extern expv	expv_reduce _ANSI_ARGS_((expv v));

extern int	check_assignment_type _ANSI_ARGS_((TYPE_DESC tp,expv v, expr x, char *msg));
extern TYPE_DESC	arithmetic_operator_type _ANSI_ARGS_((expv v1, expv v2));
extern TYPE_DESC	integral_operator_type _ANSI_ARGS_((expv v1, expv v2));

extern expr	compile_pragma_line _ANSI_ARGS_((expr x));

extern int	basic_type_size _ANSI_ARGS_((BASIC_DATA_TYPE type));
extern int	basic_type_align _ANSI_ARGS_((BASIC_DATA_TYPE type));

extern void	input_X_file _ANSI_ARGS_((void));

extern void	X_output _ANSI_ARGS_((expv v, FILE *fp));
extern void	X_output2 _ANSI_ARGS_((expv v, FILE *fp, int l));
extern void 	expr_print _ANSI_ARGS_((expr x, FILE *fp));
extern void 	expr_print_msg _ANSI_ARGS_((char *msg,expr x, FILE *fp));
extern void	debug_collect_type_dummy _ANSI_ARGS_((expv ex));
extern void	collect_types _ANSI_ARGS_((void));
extern void	debug_output_X_type _ANSI_ARGS_((void));
extern void	output_X_file _ANSI_ARGS_((void));
extern void	decompile_file _ANSI_ARGS_((void));

extern char *	storage_class_name _ANSI_ARGS_((STORAGE_CLASS class));
extern char *	basic_type_name _ANSI_ARGS_((BASIC_DATA_TYPE type));

extern char *	xmalloc _ANSI_ARGS_((int size));

extern int	get_file_id _ANSI_ARGS_((char *file));

extern void	initialize_lex _ANSI_ARGS_((void));

extern void	define_pragma_name _ANSI_ARGS_((SYMBOL s, expr x));

extern void	error EXC_VARARGS(char *, fmt);
extern void	fatal EXC_VARARGS(char *, fmt);
extern void	warning EXC_VARARGS(char *, fmt);
extern void	error_at_node EXC_VARARGS(expr, x);
extern void	warning_at_node EXC_VARARGS(expr, x);

extern longlong	longlong_add _ANSI_ARGS_((longlong ll1, longlong ll2));
extern longlong	longlong_uminus _ANSI_ARGS_((longlong ll));
extern longlong	longlong_sub _ANSI_ARGS_((longlong ll1, longlong ll2));
extern longlong	longlong_lshift _ANSI_ARGS_((longlong ll, int i));
extern longlong longlong_rshift _ANSI_ARGS_((longlong ll, int i));
extern longlong	longlong_and _ANSI_ARGS_((longlong ll1, longlong ll2));
extern longlong	longlong_or _ANSI_ARGS_((longlong ll1, longlong ll2));
extern longlong	longlong_xor _ANSI_ARGS_((longlong ll1, longlong ll2));
extern longlong	longlong_not _ANSI_ARGS_((longlong ll));

extern SYMBOL	find_symbol _ANSI_ARGS_((char *name));

extern expr	list0 _ANSI_ARGS_((enum expr_code code));
extern expr	list1 _ANSI_ARGS_((enum expr_code code, expr x1));
extern expr	list2 _ANSI_ARGS_((enum expr_code code, expr x1, expr x2));
extern expr	list3 _ANSI_ARGS_((enum expr_code code, expr x1, expr x2, expr x3));
extern expr	list4 _ANSI_ARGS_((enum expr_code code, expr x1, expr x2, expr x3, expr x4));

extern expr	elist0 _ANSI_ARGS_((lineno_info *lineno, enum expr_code code));
extern expr	elist1 _ANSI_ARGS_((lineno_info *lineno, enum expr_code code, expr x1));
extern expr	elist2 _ANSI_ARGS_((lineno_info *lineno, enum expr_code code, expr x1, expr x2));
extern expr	elist3 _ANSI_ARGS_((lineno_info *lineno, enum expr_code code, expr x1, expr x2, expr x3));
extern expr	elist4 _ANSI_ARGS_((lineno_info *lineno, enum expr_code code,
				    expr x1, expr x2, expr x3, expr x4));

extern expr	list_put_last _ANSI_ARGS_((expr lx, expr x));

extern struct list_node *	cons_list _ANSI_ARGS_((expr x, struct list_node *l));

extern expr	make_enode _ANSI_ARGS_((enum expr_code code, void *v));
extern expr	make_char_enode _ANSI_ARGS_((enum expr_code code, int v));
extern expr	make_float_enode _ANSI_ARGS_((double d));
extern expr	make_longlong_enode _ANSI_ARGS_((int l, int h));

extern expv	expv_cons _ANSI_ARGS_((enum expr_code code, TYPE_DESC tp, expv left, expv right));

extern expv	expv_sym_term _ANSI_ARGS_((enum expr_code code, TYPE_DESC tp, SYMBOL name));
extern expv	expv_int_term _ANSI_ARGS_((enum expr_code code, TYPE_DESC tp, int i));
extern expv	expv_long_term _ANSI_ARGS_((enum expr_code code, TYPE_DESC tp, long i));
extern expv	expv_any_term _ANSI_ARGS_((enum expr_code code, void *p));

extern expv	expv_str_term _ANSI_ARGS_((TYPE_DESC tp, char *str));
extern expv	expv_float_term _ANSI_ARGS_((TYPE_DESC tp, double d));
extern expv	expv_longlong_term _ANSI_ARGS_((TYPE_DESC tp, longlong ll));

extern expv	expv_retype _ANSI_ARGS_((TYPE_DESC tp, expv v));

extern expr	parse_pragma _ANSI_ARGS_((char *line,enum pragma_syntax *ret));
extern void	pg_get_token _ANSI_ARGS_((void));
extern expr	pg_parse_expr _ANSI_ARGS_((void));
extern expr	pg_parse_ident _ANSI_ARGS_((void));

extern enum pragma_syntax	parse_OMP_pragma _ANSI_ARGS_((void));

extern ID	new_ident_desc _ANSI_ARGS_((SYMBOL sp));

extern expv	compile_OMP_pragma _ANSI_ARGS_((enum OMP_pragma pragma, expr x));

extern expr	parse_TEA_pragma _ANSI_ARGS_((enum pragma_syntax *ret));
extern expv	compile_TEA_pragma _ANSI_ARGS_((enum TEA_pragma pragma, expr x));

extern TYPE_DESC 	new_type_desc _ANSI_ARGS_((enum expr_code code));

extern ID *	expv_members_list _ANSI_ARGS_((TYPE_DESC tp));
extern expv *	expv_moe_list _ANSI_ARGS_((TYPE_DESC tp));
extern expr 	gen_IDENT _ANSI_ARGS_((char *));

extern void	extern_C_begin _ANSI_ARGS_((void));
extern void	extern_C_end _ANSI_ARGS_((void));

#ifdef USE_OPENGR_PRAGMA
extern void	init_OGR_pragma _ANSI_ARGS_((void));
extern expr	parse_OGR_pragma _ANSI_ARGS_((enum pragma_syntax *ret));
extern expv	compile_OGR_pragma _ANSI_ARGS_((enum OGR_pragma pragma, expr x));
#endif /* USE_OPENGR_PRAGMA */

#if SIZEOF_UNSIGNED_LONG > SIZEOF_UNSIGNED_INT
#define SCANNER_READ_L_AS_LL
#endif /* SIZEOF_UNSIGNED_LONG > SIZEOF_UNSIGNED_INT */
