/* 
   Copyright 1994-2003 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 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  

   You may contact the author at:

   mailto::camille@bluegrass.net

   or by snail mail at:

   David Lindauer
   850 Washburn Ave Apt 99
   Louisville, KY 40222
*/
/*      compiler header file    */

#define TRUE 1
#define FALSE 0


/* declaration flags */
#define DF_INT 1
#define DF_ABS 2
#define DF_CONST 4
#define DF_VOL 8
#define DF_FUNCPARMS 16
#define DF_GLOBAL 32
#define DF_AUTOREG 64
#define DF_PRIVATE 128
#define DF_PROTECTED 256
#define DF_PUBLIC 512
#define DF_INTRINS 1024
#define DF_LOADDS 2048
#define DF_FAR 4096
#define DF_FORCEREG 8192
#define DF_RESTRICT 16384

#define UF_DEFINED 1
#define UF_USED	2
#define UF_ASSIGNED 4
#define UF_CANASSIGN 8
#define UF_ALTERED 16

#define GF_ASSIGN 1
#define GF_CONTINUABLE 2
#define GF_CONTINUE 4
#define GF_GOTO 8
#define GF_DEF 16
#define GF_BREAK 32
#define GF_RETURN 64
#define GF_UNREACH 128
#define GF_NOPROTO 256
#define GF_AND 512
#define GF_SUPERAND 1024
#define GF_INLOOP 2048
#define GF_INFUNCPARMS 4096
#define GF_BREAKABLE 8192
#define GF_INIF 16384

#ifdef CPLUSPLUS
#define BM_PRIVATE 0
#define BM_PROTECTED 1
#define BM_PUBLIC 2

#define PF_PRIVATE 0x20000
#define PF_PROTECTED 1
#define PF_PUBLIC 2
#define PF_VIRTUAL 4
#define PF_PURE 8
#define PF_INLINE 16
#define PF_STATIC 32
#define PF_CONSTRUCTOR 64
#define PF_DESTRUCTOR 128
#define PF_PARENTPRIVATE 256
#define PF_PARENTPROTECTED 512
#define PF_PARENTPUBLIC 1024
#define PF_FRIEND 2048
#define PF_NODEF 4096
#define PF_HASCONS 8192
#define PF_HASDEST 16384
#define PF_UNREACHABLE 0x8000
#define PF_MEMBER 0x10000
#define PF_HEADERFUNC 0x20000
#define PF_OPERATOR   0x40000
#define PF_INSTANTIATED 0x80000
#define PF_INHERITED 0x100000
#define PF_DUMDEST 0x200000
#define PF_TEMPCONSALREADY 0x400000
#define PF_TEMPCONSREFALREADY 0x800000

#define CI_CONSTRUCTOR 0
#define CI_DESTRUCTOR 1
#define CI_NEW 2
#define CI_DELETE 3
#define CI_NEWA 41
#define CI_DELETEA 42

#endif

/* keywords and symbols */
enum e_sym {
/* first comes all the C++ overloadable operators */
/* be sure to change expectlist if you insert things */
	kw_new,kw_delete,plus, minus, star, divide, lshift, rshift, 
	modop, eq, neq, 
   lt, leq, gt, geq, assign, lassign, asplus, asminus, astimes, asdivide, 
	asmodop, aslshift, asrshift, asand, asor, asxor, autoinc, autodec, 
        openbr, openpa, pointstar, pointsto, lor, land, not, 
	or, and, uparrow, compl,
/* then generic stuff that isn't overloadable or is internal */
        id, cconst, iconst, lconst, iuconst, luconst, llconst,lluconst,
        sconst, lsconst, fconst, lrconst, rconst, 
	hook, colon, begin, end, dot, dostar, closebr, closepa, ellipse,
   comma, semicolon, hash, classsel, classselstar, dotstar, 
/* Finally tokens for keywords */
	kw_int, kw_void, kw_char, kw_float, kw_double, kw_struct, kw_union,
        kw_long, kw_short, kw_unsigned, kw_signed, kw_auto, kw_extern,
        kw_register, kw_typedef, kw_static, kw_goto, kw_return,
        kw_sizeof, kw_break, kw_continue, kw_if, kw_else, kw_for,
        kw_do, kw_while, kw_switch, kw_case, kw_default, kw_enum, kw_volatile,
	kw_const, kw_phitext, kw__trap, kw__interrupt, kw__abs, kw__genword,
   kw___func__, kw__Complex, kw_restrict, kw__Imaginary,
/* C++ */
	kw_public, kw_private, kw_protected, kw_class, kw_friend,
   kw_namespace, kw_using, kw_this, kw_operator, kw_inline, kw_virtual,
	kw_try,kw_throw,kw_catch, kw_template, kw_bool, kw_true, kw_false,
   kw_wchar_t,
/* extended */
	kw__pascal, kw__stdcall, kw__cdecl, kw__intrinsic, kw_asm, 
	kw__loadds, kw__far, kw_asmreg,kw_asminst, kw__indirect, kw__export,
	kw__import,
/* These next are generic register names */	
	kw_D0,kw_D1,kw_D2,kw_D3,kw_D4,kw_D5,kw_D6,kw_D7,
	kw_D8,kw_D9,kw_DA,kw_DB,kw_DC,kw_DD,kw_DE,kw_DF,
	kw_A0,kw_A1,kw_A2,kw_A3,kw_A4,kw_A5,kw_A6,kw_A7,
	kw_A8,kw_A9,kw_AA,kw_AB,kw_AC,kw_AD,kw_AE,kw_AF,
	kw_F0,kw_F1,kw_F2,kw_F3,kw_F4,kw_F5,kw_F6,kw_F7,
	kw_F8,kw_F9,kw_FA,kw_FB,kw_FC,kw_FD,kw_FE,kw_FF,
	eol, eof };

#ifdef CPLUSPLUS
/* Definitions for C++ overloaded operators */
#define IT_THRESHOLD 2
#define IT_OV_THRESHOLD 2
enum overloadop { ov_ctr, ov_dtr, ov_new, ov_delete, 
		ov_add, ov_sub, ov_mul, ov_div, ov_shl, ov_shr,
		ov_mod, ov_equ, ov_neq, ov_lt, ov_le, ov_gt, ov_ge,
		ov_asn, ov_aasadd, ov_assub, ov_asmul, ov_asdiv,
		ov_asmod, ov_asshl, ov_asshr, ov_asand, ov_asor,
		ov_asxor, ov_autoinc, ov_autodec, ov_ind, ov_arg, 
      ov_pstar, ov_arr,ov_lor, ov_land, ov_not, ov_or, ov_and, ov_xor, ov_cpl,
      // must come after everything else
      ov_newa=CI_NEWA, ov_deletea=CI_DELETEA,
} ;
#endif

/* storage classes */
enum e_sc {
        sc_static, sc_auto, sc_global, sc_external, sc_type, sc_defunc, 
        sc_friendlist, sc_const,
        sc_member, sc_classmember, sc_label, sc_ulabel, sc_argument, sc_memberreg, sc_autoreg,
	sc_externalfunc,sc_abs, sc_namespace, sc_temp };

/* basic types */
enum e_bt {
	/* This first two lines MUST be ordered for the 
	 * lostconv stuff to work
	 */
        bt_bool, bt_char, bt_unsignedchar, bt_enum,bt_short,bt_unsignedshort,
   bt_int, bt_unsigned, bt_long, bt_unsignedlong, bt_longlong, bt_unsignedlonglong,
   bt_float, bt_double, bt_longdouble, bt_fimaginary, bt_rimaginary, bt_lrimaginary,
   bt_fcomplex, bt_rcomplex, bt_lrcomplex, bt_untyped,
	bt_pointer,bt_ref,bt_void,bt_struct, bt_union, bt_func, bt_class, bt_iclass,
	bt_ifunc, bt_matchall, bt_matchnone, bt_ellipse, bt_bitfield, bt_memberptr,
	bt_defunc, bt_cond, bt_member };

struct slit {
        struct slit     *next;
        int             label;		/* label to use */
	int		len;
        char            *str;		/* string to dump */
	char		type;		/* ascii/phitext or wide */
        };
struct stab {
	struct sym *head, *tail;
};
typedef struct _vlist {
   struct _vlist *next ;
   struct sym *entry ;
   int negofs ;
} VLIST ;

struct _classlist ;

/* symbols */
struct sym {
        struct sym      *next;			/* next symbol (local tabs only) */
        char            *name;			/* symbol name */
        enum e_sc	storage_class;		/* storage class */
#ifdef ICODE
        struct _imode_ *imaddress ;
        struct _imode_ *imvalue ;
        struct _imode_ *imind ;
#endif
	int		extflag:1;		/* if external, was it used */
	int		absflag:1;		/* the _abs keyword was used */
	int		intflag:1;		/* the _interrupt keyword was used */
	int		indecltable:1;		/* global already in dump table */
	int		pascaldefn:1;		/* function: pascal type */
	int		isstdcall:1;		/* function: stdcall type */
	int		inreg:1;  		/* function var is in reg, no stack space needed */
	int		funcparm:1;		/* function var is a param and has space allocated */
	int 		staticlabel:1;		/* Var is a static declared in a function */
	int		loadds:1;		/* to load data seg (limited) */
	int		farproc:1;		/* this procedure should be terminated with retf */
	int		indirect:1 ;		/* This procedure is to be called indirectly. */
	int		exportable:1;		/* Export the symbol (for win32 dll) */
	int		importable:1;		/* Import the symbol (for win32 dll) */
   int      calleenearret:1;   /* true if callee provided a place for the return value */
   int      hasproto:1;      /* C language prototype was encountered */
   int      hasunnamed:1;     /* structure has unnamed substructs */
   int      isunnamed:1;      /* substructure is unnamed */
#ifdef ICODE
   int      iglobal:1 ;       /* if a temp variable has gone global */
   int      ipointerindx ;    /* pointer index for pointer opts */
#endif
   char     **oldstyle  ;      /* pointer to a names list if an old style function arg */
	int		linkid;			/* ID to use for linkage purposes (binary output) */
   int      offset;        /* address offset of data in the given seg */   
	ENODE *		defalt;			/* Default for function params */
						/* Also name for CPP overload lists */
	char *		alias;			/* alias.  Filled in right before end */
	char *		importfile ;		/* import name */
	char 		*memberptrname;		/* name to use for address of member pointer, or 0 if none */
	struct sym      *parentclass;		/* the sym of the class which holds this member item */
   struct sym      *originalparentclass; /* sym of its original parent (used for friend matching in inheritance)*/
   struct sym *mainsym ;     /* pointer to the global version of a copied symbol */
	struct sym	*enumlist ;		/* pointer to a list of enumeration values, or link in chain */
                              /* also used for namespace data pointer */
	/* these fields depend on storage_class */
        union   {
                long            i;		/* int val */
                unsigned long   u;		/* nsigned val */
                long double          f;		/* float val */
                char            *s;		/* string val */
#ifdef CPLUSPLUS
		struct cdat {
			int		i;	/* int val = member offset */
			int		size; /* duplicates the type entry */
         int             vtabindex;      /* which vtab entry this symbol is */
         int      vtaboffs; /* offset to the vtab for this symbol */
			long		cppflags;  /* flags */
         struct _classlist  *baseclass; /* Parent class list */
         struct _classlist  *enclosedclass ; /* list of enclosed classes */
/*         struct stab    overlist; overload table */
			struct stab 	memberptrs; /* pointers to members */
			struct ifunc	*inlinefunc; /* inline functions-> to statement */
         ENODE       *consbuild; /* constructor build tree */
			ENODE		*defalt; /* Default for function params */
						/* Also name for CPP overload lists */
         ENODE    *eofdest ;  /* destructor tree for end of function */
			struct sym 	*gdeclare ;		/* pointer to the global version of static class members */
                        } classdata;
#endif
                }
                        value;
	/* Type declarations */
        struct typ {
                enum e_bt		       type;	/* the type */
                char            val_flag;       /* set if is an array */
       		char		uflags;			/* Track usage */
		char		bits;		/* -1 for not a bit val, else bit field len */
		char		startbit;	/* start of bit field */	
                long            size;		/* total size of type */
		int		cflags;		/* C & C++ flags */
                struct typ      *btp;		/* pointer to next type (pointers & arrays */
		struct sym	*sp;		/* pointer to a symbol which describes the type */
		/* local symbol tables */
		struct sym *tdef;		/* Pointer to a typedef entry */
		struct stab lst;	 	/* Symbol table for structs & functions */
      int      *typeindex ; /* type index for debugger */
      struct sym *enumlist ; /* enumeration list for enums */
      struct typ *reclone ; /* clone list for things that have been cloned before the full declaration came into effect (circular) */
      int      alignment ;    /* alignment pref for this structure/class/union   */
                }
                        *tp;
	struct decldata {
			struct decldata *link;
         enum { dd_byte,dd_word,dd_long,dd_longlong,dd_float,dd_double,
                dd_ldouble, dd_fcomplex, dd_rcomplex, dd_lrcomplex,
                dd_pcname, dd_dataname, dd_storage, dd_label
			     } mode;
			union {
            LLONG_TYPE i;
            long double f[2];
				struct sym *sp;
			} val;		
			long offset;
	} *init;
};

#define SYM     struct sym
#define TYP     struct typ
#define TABLE   struct stab

#define MAX_STRLEN      4100
#define MAX_STLP1       4101

/* struct for preprocessor if tracking */
typedef struct ifstruct {
		struct ifstruct *link;		/* link */
		short iflevel;			
		short elsetaken;
} IFSTRUCT;
		
/* #define tracking */
typedef struct {
		char *string;
		short argcount;
		char **args;
} DEFSTRUCT;

/* used for #pragma aux */
typedef struct _auxlist {
		struct _auxlist *link;
		char *name;
		char *alias;
} AUXLIST;
/* error list */
struct errl {
		struct errl *link;
		short errornumber;
		void *data;
};

/* used for error skimming */
#define BALANCE struct balance
#define BAL_PAREN   0
#define BAL_BRACKET 0
#define ERRORS struct errl

struct balance {
		struct balance *back;
		short type;
		short count;
};

/* Global symbol table is a hash table */
#define HASHTABLESIZE 1023

typedef struct _hashrec_ {
   struct _hashrec_ *link;	/* Link to next element in list */
   char *key;	/* Full key */
} HASHREC;

typedef struct {
	char *word;
	short atype;
	short amode;
	struct _opcode *data ;
} ASMNAME;
typedef struct kwblk {
				struct kwblk *next;
        char            *word;
        short		stype;
	enum { KW_CPLUSPLUS=1,KW_INLINEASM=2,KW_NONANSI=4 } flags;
   ASMNAME     *data;        } KEYWORDS;
typedef struct intrinsblk {
				struct intrinsblk *next;
        char            *word;
        short		val;
        } INTRINSICS;

typedef struct {
	char *word;
   short regtype;
	char regnum;
	char size;
} ASMREG;

/* we use C++ name spaces for the gsyms, but it is transparent if C++
 * is not enabled
 */
#define HASHTABLESIZE 1023
typedef struct _namespace {
	int hashsize;
   int autouse ;
   SYM *nsp ;
   HASHREC **table ;
} NAMESPACE;

typedef struct ifunc {
	SNODE *stmt;
	TABLE syms;
} INLINEFUNC ;

typedef struct _filelist {
	struct _filelist *link ;
	char *data ;
	int hascode ;
} FILELIST ;

typedef struct _classlist {
   struct _classlist *link ;
   SYM *data ;
   int offset ;                     /* offset to this subclass */
   int      vtabsize;               /* size of vtab */
   struct sym      *vtabsp;    /* vtab name for classes */
   LIST            *vtablist;      /* list of vtab entries for the subclass */
   int   isvtab ;                /* this baseclass has a vtab */
   int   vtaboffs ;              /* offset into the actual vtab of this base */
} CLASSLIST ;


#include "cc.p"