X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.h;h=4e3340dbe81dd59b997d165ee0b02e0d6fd3ae30;hb=1e1c6a588fe0a45598443b59686c6f6cd0f84cca;hp=f1cc4de749906ba38440b2af1caa9a0186eebb2a;hpb=b25efb9a75e0bb7fb74196af0c77fabaf1760fc5;p=fw%2Fsdcc diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index f1cc4de7..4e3340db 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -30,6 +30,11 @@ #include "SDCChasht.h" #include "SDCCglobl.h" +#define INTNO_MAX 255 /* maximum allowed interrupt number */ +#define INTNO_UNSPEC (INTNO_MAX+1) /* interrupt number unspecified */ + +#define BITVAR_PAD -1 + enum { TYPEOF_INT=1, TYPEOF_SHORT, @@ -37,6 +42,7 @@ enum { TYPEOF_LONG, TYPEOF_FLOAT, TYPEOF_BIT, + TYPEOF_BITFIELD, TYPEOF_SBIT, TYPEOF_SFR, TYPEOF_VOID, @@ -52,13 +58,11 @@ enum { TYPEOF_EEPPOINTER }; -// values for first byte of generic pointer. -#define GPTYPE_NEAR 0 -#define GPTYPE_FAR 1 -#define GPTYPE_CODE 2 -#define GPTYPE_XSTACK 3 -#define GPTYPE_GPTR 4 // Never used? -#define GPTYPE_IDATA 5 +// values for first byte (or 3 most significant bits) of generic pointer. +#define GPTYPE_FAR 0x00 +#define GPTYPE_NEAR 0x40 +#define GPTYPE_XSTACK 0x60 +#define GPTYPE_CODE 0x80 #define HASHTAB_SIZE 256 @@ -80,6 +84,7 @@ typedef struct structdef unsigned char level; /* Nesting level */ struct symbol *fields; /* pointer to fields */ unsigned size; /* sizeof the table in bytes */ + int type; /* STRUCT or UNION */ } structdef; @@ -93,6 +98,7 @@ typedef enum V_STRUCT, V_LABEL, V_BIT, + V_BITFIELD, V_SBIT, V_DOUBLE } @@ -144,13 +150,13 @@ typedef struct specifier int argreg; /* reg no for regparm */ union { /* Values if constant or enum */ - TYPE_WORD v_int; /* 2 bytes: int and char values */ - char *v_char; /* character string */ - TYPE_UWORD v_uint; /* 2 bytes: unsigned int const value */ - TYPE_DWORD v_long; /* 4 bytes: long constant value */ - TYPE_UDWORD v_ulong; /* 4 bytes: unsigned long constant val */ + TYPE_WORD v_int; /* 2 bytes: int and char values */ + char *v_char; /* character string */ + TYPE_UWORD v_uint; /* 2 bytes: unsigned int const value */ + TYPE_DWORD v_long; /* 4 bytes: long constant value */ + TYPE_UDWORD v_ulong; /* 4 bytes: unsigned long constant value */ double v_float; /* floating point constant value */ - struct symbol *v_enum; /* ptr 2 enum_list if enum==1 */ + struct symbol *v_enum; /* ptr to enum_list if enum==1 */ } const_val; struct structdef *v_struct; /* structure pointer */ @@ -177,18 +183,21 @@ typedef struct declarator { DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */ unsigned int num_elem; /* # of elems if type==array */ - short ptr_const:1; /* pointer is constant */ - short ptr_volatile:1; /* pointer is volatile */ + unsigned ptr_const:1; /* pointer is constant */ + unsigned ptr_volatile:1; /* pointer is volatile */ struct sym_link *tspec; /* pointer type specifier */ } declarator; -#define DECLARATOR 0 -#define SPECIFIER 1 +typedef enum { + DECLARATOR=1, + SPECIFIER +} SYM_LINK_CLASS; +#define DECLSPEC2TXT(select) (select==DECLARATOR?"DECLARATOR":select==SPECIFIER?"SPECIFIER":"UNKNOW") typedef struct sym_link { - unsigned class:1; /* DECLARATOR or SPECIFIER */ + SYM_LINK_CLASS class; /* DECLARATOR or SPECIFIER */ unsigned tdef:1; /* current link created by */ /* typedef if this flag is set */ union @@ -203,18 +212,19 @@ typedef struct sym_link unsigned hasVargs:1; /* functions has varargs */ unsigned calleeSaves:1; /* functions uses callee save */ unsigned hasbody:1; /* function body defined */ - //unsigned ret:1; /* return statement for a function */ unsigned hasFcall:1; /* does it call other functions */ unsigned reent:1; /* function is reentrant */ unsigned naked:1; /* naked function */ + unsigned shadowregs:1; /* function uses shadow registers (pic16 port) */ + unsigned wparam:1; /* first byte of arguments is passed via WREG (pic16 port) */ unsigned nonbanked:1; /* function has the nonbanked attribute */ unsigned banked:1; /* function has the banked attribute */ unsigned critical:1; /* critical function */ - unsigned intrtn:1; /* this is an interrupt routin */ + unsigned intrtn:1; /* this is an interrupt routine */ unsigned rbank:1; /* seperate register bank */ unsigned intno; /* 1=Interrupt svc routine */ - unsigned regbank; /* register bank 2b used */ + short regbank; /* register bank 2b used */ unsigned builtin; /* is a builtin function */ unsigned javaNative; /* is a JavaNative Function (TININative ONLY) */ unsigned overlay; /* force parameters & locals into overlay segment */ @@ -269,7 +279,7 @@ typedef struct symbol unsigned noSpilLoc:1; /* cannot be assigned a spil location */ unsigned isstrlit; /* is a string literal and it's usage count */ unsigned accuse; /* can be left in the accumulator - On the Z80 accuse is devided into + On the Z80 accuse is divided into ACCUSE_A and ACCUSE_HL as the idea is quite similar. */ @@ -285,8 +295,10 @@ typedef struct symbol struct regs *regs[4]; /* can have at the most 4 registers */ struct asmop *aop; /* asmoperand for this symbol */ struct iCode *fuse; /* furthest use */ - struct iCode *rematiCode; /* rematerialse with which instruction */ + struct iCode *rematiCode; /* rematerialise with which instruction */ struct operand *reqv; /* register equivalent of a local variable */ + struct symbol *prereqv; /* symbol before register equiv. substituion */ + struct symbol *psbase; /* if pseudo symbol, the symbol it is based on */ union { struct symbol *spillLoc; /* register spil location */ @@ -297,9 +309,10 @@ typedef struct symbol unsigned offset; /* offset from top if struct */ int lineDef; /* defined line number */ + char *fileDef; /* defined filename */ int lastLine; /* for functions the last line */ - struct sym_link *type; /* 1st link to declator chain */ - struct sym_link *etype; /* last link to declarator chn */ + struct sym_link *type; /* 1st link to declarator chain */ + struct sym_link *etype; /* last link to declarator chain */ struct symbol *next; /* crosslink to next symbol */ struct symbol *localof; /* local variable of which function */ struct initList *ival; /* ptr to initializer if any */ @@ -314,12 +327,18 @@ typedef struct symbol } symbol; +extern sym_link *validateLink(sym_link *l, + const char *macro, + const char *args, + const char select, + const char *file, + unsigned line); /* Easy Access Macros */ -#define DCL_TYPE(l) l->select.d.dcl_type -#define DCL_ELEM(l) l->select.d.num_elem -#define DCL_PTR_CONST(l) l->select.d.ptr_const -#define DCL_PTR_VOLATILE(l) l->select.d.ptr_volatile -#define DCL_TSPEC(l) l->select.d.tspec +#define DCL_TYPE(l) validateLink(l, "DCL_TYPE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.dcl_type +#define DCL_ELEM(l) validateLink(l, "DCL_ELEM", #l, DECLARATOR, __FILE__, __LINE__)->select.d.num_elem +#define DCL_PTR_CONST(l) validateLink(l, "DCL_PTR_CONST", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_const +#define DCL_PTR_VOLATILE(l) validateLink(l, "DCL_PTR_VOLATILE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_volatile +#define DCL_TSPEC(l) validateLink(l, "DCL_TSPEC", #l, DECLARATOR, __FILE__, __LINE__)->select.d.tspec #define FUNC_DEBUG //assert(IS_FUNC(x)); #define FUNC_HASVARARGS(x) (x->funcAttrs.hasVargs) @@ -341,6 +360,10 @@ symbol; #define FUNC_ISREENT(x) (x->funcAttrs.reent) #define IFFUNC_ISREENT(x) (IS_FUNC(x) && FUNC_ISREENT(x)) +#define FUNC_ISSHADOWREGS(x) (x->funcAttrs.shadowregs) +#define IFFUNC_ISSHADOWREGS(x) (IS_FUNC(x) && FUNC_ISSHADOWREGS(x)) +#define FUNC_ISWPARAM(x) (x->funcAttrs.wparam) +#define IFFUNC_ISWPARAM(x) (IS_FUNC(x) && FUNC_ISWPARAM(x)) #define FUNC_ISNAKED(x) (x->funcAttrs.naked) #define IFFUNC_ISNAKED(x) (IS_FUNC(x) && FUNC_ISNAKED(x)) #define FUNC_NONBANKED(x) (x->funcAttrs.nonbanked) @@ -356,42 +379,42 @@ symbol; #define FUNC_ISOVERLAY(x) (x->funcAttrs.overlay) #define IFFUNC_ISOVERLAY(x) (IS_FUNC(x) && FUNC_ISOVERLAY(x)) - -// jwk: I am not sure about this #define IFFUNC_ISBANKEDCALL(x) (!IFFUNC_NONBANKED(x) && \ - (options.model == MODEL_LARGE || \ - options.model == MODEL_MEDIUM || \ + (options.model == MODEL_HUGE || \ + ((options.model == MODEL_LARGE || options.model == MODEL_MEDIUM) && \ + (TARGET_IS_Z80 || TARGET_IS_GBZ80)) || \ IFFUNC_BANKED(x))) -#define SPEC_NOUN(x) x->select.s.noun -#define SPEC_LONG(x) x->select.s._long -#define SPEC_USIGN(x) x->select.s._unsigned -#define SPEC_SCLS(x) x->select.s.sclass -#define SPEC_ENUM(x) x->select.s._isenum -#define SPEC_OCLS(x) x->select.s.oclass -#define SPEC_STAT(x) x->select.s._static -#define SPEC_EXTR(x) x->select.s._extern -#define SPEC_CODE(x) x->select.s._codesg -#define SPEC_ABSA(x) x->select.s._absadr -#define SPEC_BANK(x) x->select.s._regbank -#define SPEC_ADDR(x) x->select.s._addr -#define SPEC_STAK(x) x->select.s._stack -#define SPEC_CVAL(x) x->select.s.const_val -#define SPEC_BSTR(x) x->select.s._bitStart -#define SPEC_BLEN(x) x->select.s._bitLength +#define SPEC_NOUN(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.noun +#define SPEC_LONG(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s._long +#define SPEC_SHORT(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s._short +#define SPEC_USIGN(x) validateLink(x, "SPEC_USIGN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._unsigned +#define SPEC_SCLS(x) validateLink(x, "SPEC_SCLS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.sclass +#define SPEC_ENUM(x) validateLink(x, "SPEC_ENUM", #x, SPECIFIER, __FILE__, __LINE__)->select.s._isenum +#define SPEC_OCLS(x) validateLink(x, "SPEC_OCLS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.oclass +#define SPEC_STAT(x) validateLink(x, "SPEC_STAT", #x, SPECIFIER, __FILE__, __LINE__)->select.s._static +#define SPEC_EXTR(x) validateLink(x, "SPEC_EXTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._extern +#define SPEC_CODE(x) validateLink(x, "SPEC_CODE", #x, SPECIFIER, __FILE__, __LINE__)->select.s._codesg +#define SPEC_ABSA(x) validateLink(x, "SPEC_ABSA", #x, SPECIFIER, __FILE__, __LINE__)->select.s._absadr +#define SPEC_BANK(x) validateLink(x, "SPEC_BANK", #x, SPECIFIER, __FILE__, __LINE__)->select.s._regbank +#define SPEC_ADDR(x) validateLink(x, "SPEC_ADDR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._addr +#define SPEC_STAK(x) validateLink(x, "SPEC_STAK", #x, SPECIFIER, __FILE__, __LINE__)->select.s._stack +#define SPEC_CVAL(x) validateLink(x, "SPEC_CVAL", #x, SPECIFIER, __FILE__, __LINE__)->select.s.const_val +#define SPEC_BSTR(x) validateLink(x, "SPEC_BSTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart +#define SPEC_BLEN(x) validateLink(x, "SPEC_BLEN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitLength /* Sleaze: SPEC_ISR_SAVED_BANKS is only used on * function type symbols, which obviously cannot * be of BIT type. Therefore, we recycle the * _bitStart field instead of defining a new field. */ -#define SPEC_ISR_SAVED_BANKS(x) x->select.s._bitStart -#define SPEC_VOLATILE(x) x->select.s._volatile -#define SPEC_CONST(x) x->select.s._const -#define SPEC_STRUCT(x) x->select.s.v_struct -#define SPEC_TYPEDEF(x) x->select.s._typedef -#define SPEC_REGPARM(x) x->select.s._isregparm -#define SPEC_ARGREG(x) x->select.s.argreg +#define SPEC_ISR_SAVED_BANKS(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart +#define SPEC_VOLATILE(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._volatile +#define SPEC_CONST(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._const +#define SPEC_STRUCT(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.v_struct +#define SPEC_TYPEDEF(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._typedef +#define SPEC_REGPARM(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._isregparm +#define SPEC_ARGREG(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.argreg /* type check macros */ #define IS_DECL(x) ( x && x->class == DECLARATOR ) @@ -410,11 +433,15 @@ symbol; #define IS_FARPTR(x) (IS_DECL(x) && DCL_TYPE(x) == FPOINTER) #define IS_CODEPTR(x) (IS_DECL(x) && DCL_TYPE(x) == CPOINTER) #define IS_GENPTR(x) (IS_DECL(x) && DCL_TYPE(x) == GPOINTER) +#define IS_FUNCPTR(x) (IS_DECL(x) && (DCL_TYPE(x) == CPOINTER || DCL_TYPE(x) == GPOINTER) && IS_FUNC(x->next)) #define IS_FUNC(x) (IS_DECL(x) && DCL_TYPE(x) == FUNCTION) #define IS_LONG(x) (IS_SPEC(x) && x->select.s._long) #define IS_UNSIGNED(x) (IS_SPEC(x) && x->select.s._unsigned) #define IS_TYPEDEF(x)(IS_SPEC(x) && x->select.s._typedef) -#define IS_CONSTANT(x) (IS_SPEC(x) && ( x->select.s._const == 1)) +#define IS_CONSTANT(x) (!x ? 0 : \ + IS_SPEC(x) ? \ + x->select.s._const : \ + x->select.d.ptr_const) #define IS_STRUCT(x) (IS_SPEC(x) && x->select.s.noun == V_STRUCT) #define IS_ABSOLUTE(x) (IS_SPEC(x) && x->select.s._absadr ) #define IS_REGISTER(x) (IS_SPEC(x) && SPEC_SCLS(x) == S_REGISTER) @@ -424,14 +451,21 @@ symbol; #define IS_VOID(x) (IS_SPEC(x) && x->select.s.noun == V_VOID) #define IS_CHAR(x) (IS_SPEC(x) && x->select.s.noun == V_CHAR) #define IS_EXTERN(x) (IS_SPEC(x) && x->select.s._extern) -#define IS_VOLATILE(x) (IS_SPEC(x) && x->select.s._volatile ) +#define IS_VOLATILE(x) (!x ? 0 : \ + IS_SPEC(x) ? \ + x->select.s._volatile : \ + x->select.d.ptr_volatile) #define IS_INTEGRAL(x) (IS_SPEC(x) && (x->select.s.noun == V_INT || \ x->select.s.noun == V_CHAR || \ + x->select.s.noun == V_BITFIELD || \ x->select.s.noun == V_BIT || \ x->select.s.noun == V_SBIT )) -#define IS_BITFIELD(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT)) -#define IS_BITVAR(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT || \ +#define IS_BITFIELD(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD)) +#define IS_BITVAR(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD || \ + x->select.s.noun == V_BIT || \ x->select.s.noun == V_SBIT )) +#define IS_BIT(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT || \ + x->select.s.noun == V_SBIT )) #define IS_FLOAT(x) (IS_SPEC(x) && x->select.s.noun == V_FLOAT) #define IS_ARITHMETIC(x) (IS_INTEGRAL(x) || IS_FLOAT(x)) #define IS_AGGREGATE(x) (IS_ARRAY(x) || IS_STRUCT(x)) @@ -439,6 +473,9 @@ symbol; #define IS_CODE(x) (IS_SPEC(x) && SPEC_SCLS(x) == S_CODE) #define IS_REGPARM(x) (IS_SPEC(x) && SPEC_REGPARM(x)) +/* symbol check macros */ +#define IS_AUTO(x) (x->level && !IS_STATIC(x->etype) && !IS_EXTERN(x->etype)) + /* forward declaration for the global vars */ extern bucket *SymbolTab[]; extern bucket *StructTab[]; @@ -477,10 +514,20 @@ extern sym_link *floatType; #include "SDCCval.h" +typedef enum +{ + RESULT_TYPE_NONE = 0, /* operands will be promoted to int */ + RESULT_TYPE_BIT, + RESULT_TYPE_CHAR, + RESULT_TYPE_INT, + RESULT_TYPE_OTHER, /* operands will be promoted to int */ + RESULT_TYPE_IFX, +} RESULT_TYPE; + /* forward definitions for the symbol table related functions */ void initSymt (); symbol *newSymbol (char *, int); -sym_link *newLink (); +sym_link *newLink (SYM_LINK_CLASS); sym_link *newFloatLink (); structdef *newStruct (char *); void addDecl (symbol *, int, sym_link *); @@ -503,29 +550,30 @@ value *checkStructIval (symbol *, value *); value *checkArrayIval (sym_link *, value *); value *checkIval (sym_link *, value *); unsigned int getSize (sym_link *); +unsigned int getAllocSize (sym_link *); unsigned int bitsForType (sym_link *); sym_link *newIntLink (); sym_link *newCharLink (); sym_link *newLongLink (); int compareType (sym_link *, sym_link *); +int compareTypeExact (sym_link *, sym_link *, int); int checkFunction (symbol *, symbol *); void cleanUpLevel (bucket **, int); void cleanUpBlock (bucket **, int); int funcInChain (sym_link *); -void addSymChain (symbol *); +void addSymChain (symbol **); sym_link *structElemType (sym_link *, value *); symbol *getStructElement (structdef *, symbol *); -sym_link *computeType (sym_link *, sym_link *); +sym_link *computeType (sym_link *, sym_link *, RESULT_TYPE, int); void processFuncArgs (symbol *); int isSymbolEqual (symbol *, symbol *); -int powof2 (unsigned long); +int powof2 (TYPE_UDWORD); void printTypeChain (sym_link *, FILE *); +void printTypeChainRaw (sym_link *, FILE *); void initCSupport (); void initBuiltIns (); void pointerTypes (sym_link *, sym_link *); -void cdbTypeInfo (sym_link *, FILE *); -void cdbSymbol (symbol *, FILE *, int, int); -void cdbStructBlock (int, FILE *); +void cdbStructBlock (int); void initHashT (); bucket *newBucket (); void addSym (bucket **, void *, char *, int, int, int checkType); @@ -533,9 +581,12 @@ void deleteSym (bucket **, void *, char *); void *findSym (bucket **, void *, const char *); void *findSymWithLevel (bucket **, struct symbol *); void *findSymWithBlock (bucket **, struct symbol *, int); -void changePointer (symbol * sym); +void changePointer (sym_link * p); void checkTypeSanity(sym_link *etype, char *name); sym_link *typeFromStr (char *) ; +STORAGE_CLASS sclsFromPtr(sym_link *ptr); +sym_link *newEnumType (symbol *); +void promoteAnonStructs (int, structdef *); extern char *nounName(sym_link *); /* noun strings */