* device/lib/Makefile.in: remove abspath for PORTDIR, introduced in
[fw/sdcc] / src / SDCCsymt.h
index 1d54708f3f1a80ae38d87ac3fb1cba33a2d4f571..c85d1d6e10f0a65bf88c24e71ce687525aeee00e 100644 (file)
@@ -29,6 +29,7 @@
 #define SDCC_NAME_MAX  3*SDCC_SYMNAME_MAX // big enough for _<func>_<var>_etc
 #include "SDCChasht.h"
 #include "SDCCglobl.h"
+#include "dbuf.h"
 
 #define INTNO_MAX 255                   /* maximum allowed interrupt number */
 #define INTNO_UNSPEC (INTNO_MAX+1)      /* interrupt number unspecified */
@@ -66,10 +67,10 @@ enum {
 #define GPTYPE_XSTACK    0x60
 #define GPTYPE_CODE      0x80
 #else
-#define GPTYPE_FAR     (port->gp_tags.tag_far)
-#define GPTYPE_NEAR    (port->gp_tags.tag_near)
-#define GPTYPE_XSTACK  (port->gp_tags.tag_xstack)
-#define GPTYPE_CODE    (port->gp_tags.tag_code)
+#define GPTYPE_FAR      (port->gp_tags.tag_far)
+#define GPTYPE_NEAR     (port->gp_tags.tag_near)
+#define GPTYPE_XSTACK   (port->gp_tags.tag_xstack)
+#define GPTYPE_CODE     (port->gp_tags.tag_code)
 #endif
 
 #define HASHTAB_SIZE 256
@@ -136,6 +137,13 @@ typedef enum
   }
 STORAGE_CLASS;
 
+#define TYPE_TARGET_CHAR  TYPE_BYTE
+#define TYPE_TARGET_INT   TYPE_WORD
+#define TYPE_TARGET_LONG  TYPE_DWORD
+#define TYPE_TARGET_UCHAR TYPE_UBYTE
+#define TYPE_TARGET_UINT  TYPE_UWORD
+#define TYPE_TARGET_ULONG TYPE_UDWORD
+
 /* specifier is the last in the type-chain */
 typedef struct specifier
   {
@@ -148,27 +156,30 @@ typedef struct specifier
     unsigned b_signed:1;                /* just for sanity checks only*/
     unsigned b_static:1;                /* 1=static keyword found     */
     unsigned b_extern:1;                /* 1=extern found             */
+    unsigned b_inline:1;                /* inline function requested  */
     unsigned b_absadr:1;                /* absolute address specfied  */
     unsigned b_volatile:1;              /* is marked as volatile      */
     unsigned b_const:1;                 /* is a constant              */
+    unsigned b_restrict:1;              /* is restricted              */
     unsigned b_typedef:1;               /* is typedefed               */
     unsigned b_isregparm:1;             /* is the first parameter     */
     unsigned b_isenum:1;                /* is an enumerated type      */
-    unsigned _addr;                     /* address of symbol          */
-    unsigned _stack;                    /* stack offset for stacked v */
+    unsigned b_bitUnnamed:1;            /* is an unnamed bit-field    */
     unsigned _bitStart;                 /* bit start position         */
     int _bitLength;                     /* bit length                 */
+    unsigned _addr;                     /* address of symbol          */
+    unsigned _stack;                    /* stack offset for stacked v */
     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 value  */
-        double      v_float;            /*          floating point constant value */
-        TYPE_UDWORD v_fixed16x16;       /* 4 bytes: fixed floating point constant value */
-        struct symbol *v_enum;          /* ptr to enum_list if enum==1            */
+        TYPE_TARGET_INT   v_int;        /* 2 bytes: int and char values           */
+        char             *v_char;       /*          character string              */
+        TYPE_TARGET_UINT  v_uint;       /* 2 bytes: unsigned int const value      */
+        TYPE_TARGET_LONG  v_long;       /* 4 bytes: long constant value           */
+        TYPE_TARGET_ULONG v_ulong;      /* 4 bytes: unsigned long constant value  */
+        double            v_float;      /*          floating point constant value */
+        TYPE_TARGET_ULONG v_fixed16x16; /* 4 bytes: fixed floating point constant value */
+        struct symbol    *v_enum;       /* ptr to enum_list if enum==1            */
       }
     const_val;
     struct structdef *v_struct;         /* structure pointer      */
@@ -198,6 +209,7 @@ typedef struct declarator
                                         /* always 0 for flexible arrays */
     unsigned ptr_const:1;               /* pointer is constant        */
     unsigned ptr_volatile:1;            /* pointer is volatile        */
+    unsigned ptr_restrict:1;            /* pointer is resticted       */
     struct sym_link *tspec;             /* pointer type specifier     */
   }
 declarator;
@@ -206,7 +218,7 @@ typedef enum {
   DECLARATOR=1,
   SPECIFIER
 } SYM_LINK_CLASS;
-#define DECLSPEC2TXT(select) (select==DECLARATOR?"DECLARATOR":select==SPECIFIER?"SPECIFIER":"UNKNOW")
+#define DECLSPEC2TXT(select) (select==DECLARATOR?"DECLARATOR":select==SPECIFIER?"SPECIFIER":"UNKNOWN")
 
 typedef struct sym_link
   {
@@ -236,6 +248,7 @@ typedef struct sym_link
       unsigned critical:1;              /* critical function          */
       unsigned intrtn:1;                /* this is an interrupt routine */
       unsigned rbank:1;                 /* seperate register bank     */
+      unsigned inlinereq:1;             /* inlining requested         */
       unsigned intno;                   /* 1=Interrupt svc routine    */
       short    regbank;                 /* register bank 2b used      */
       unsigned builtin;                 /* is a builtin function      */
@@ -258,7 +271,7 @@ typedef struct symbol
     int key;
     unsigned flexArrayLength;           /* if the symbol specifies a struct
     with a "flexible array member", then the additional length in bytes for
-    the "fam" is stored here. Because the lenght can be different from symbol
+    the "fam" is stored here. Because the length can be different from symbol
     to symbol AND v_struct isn't copied in copyLinkChain(), it's located here
     in the symbol and not in v_struct or the declarator */
     unsigned implicit:1;                /* implicit flag                     */
@@ -273,8 +286,9 @@ typedef struct symbol
     unsigned isinvariant:1;             /* is a loop invariant  */
     unsigned cdef:1;                    /* compiler defined symbol */
     unsigned addrtaken:1;               /* address of the symbol was taken */
-    unsigned isreqv:1;                  /* is the register quivalent of a symbol */
+    unsigned isreqv:1;                  /* is the register equivalent of a symbol */
     unsigned udChked:1;                 /* use def checking has been already done */
+    unsigned generated:1;               /* code generated (function symbols only) */
 
     /* following flags are used by the backend
        for code generation and can be changed
@@ -316,7 +330,7 @@ typedef struct symbol
     struct iCode *fuse;                 /* furthest use */
     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 *prereqv;             /* symbol before register equiv. substitution */
     struct symbol *psbase;              /* if pseudo symbol, the symbol it is based on */
     union
       {
@@ -324,7 +338,8 @@ typedef struct symbol
         struct set *itmpStack;          /* symbols spilt @ this stack location */
       }
     usl;
-    short bitVar;                       /* this is a bit variable    */
+    char bitVar;                        /* if bitVar != 0: this is a bit variable, bitVar is the size in bits */
+    char bitUnnamed:1;                  /* unnamed bit variable */
     unsigned offset;                    /* offset from top if struct */
 
     int lineDef;                        /* defined line number        */
@@ -343,6 +358,7 @@ typedef struct symbol
     int used;                           /* no. of times this was used */
     int recvSize;                       /* size of first argument  */
     struct bitVect *clashes;            /* overlaps with what other symbols */
+    struct ast * funcTree;              /* function body ast if inlined */
   }
 symbol;
 
@@ -353,10 +369,14 @@ extern sym_link *validateLink(sym_link  *l,
                                const char       *file,
                                unsigned         line);
 /* Easy Access Macros */
+#define IS_OP_RUONLY(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->ruonly)
+#define IS_OP_ACCUSE(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->accuse)
+
 #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_PTR_RESTRICT(l) validateLink(l, "DCL_PTR_RESTRICT", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_restrict
 #define DCL_TSPEC(l) validateLink(l, "DCL_TSPEC", #l, DECLARATOR, __FILE__, __LINE__)->select.d.tspec
 
 #define FUNC_DEBUG //assert(IS_FUNC(x));
@@ -376,6 +396,8 @@ extern sym_link *validateLink(sym_link  *l,
 #define FUNC_INTNO(x) (x->funcAttrs.intno)
 #define FUNC_REGBANK(x) (x->funcAttrs.regbank)
 #define FUNC_HASSTACKPARM(x) (x->funcAttrs.hasStackParms)
+#define FUNC_ISINLINE(x) (x->funcAttrs.inlinereq)
+#define IFFUNC_ISINLINE(x) (IS_FUNC(x) && FUNC_ISINLINE(x))
 
 #define FUNC_ISREENT(x) (x->funcAttrs.reent)
 #define IFFUNC_ISREENT(x) (IS_FUNC(x) && FUNC_ISREENT(x))
@@ -421,6 +443,7 @@ extern sym_link *validateLink(sym_link  *l,
 #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
+#define SPEC_BUNNAMED(x) validateLink(x, "SPEC_BLEN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_bitUnnamed
 
 /* Sleaze: SPEC_ISR_SAVED_BANKS is only used on
  * function type symbols, which obviously cannot
@@ -430,10 +453,12 @@ extern sym_link *validateLink(sym_link  *l,
 #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.b_volatile
 #define SPEC_CONST(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_const
+#define SPEC_RESTRICT(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_restrict
 #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.b_typedef
 #define SPEC_REGPARM(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_isregparm
 #define SPEC_ARGREG(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.argreg
+#define SPEC_INLINE(x) validateLink(x, "SPEC_INLINE", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_inline
 
 /* type check macros */
 #define IS_DECL(x)   ( x && x->class == DECLARATOR      )
@@ -449,6 +474,7 @@ extern sym_link *validateLink(sym_link  *l,
                                      DCL_TYPE(x) == CPOINTER   ||    \
                                      DCL_TYPE(x) == UPOINTER  ))
 #define IS_PTR_CONST(x) (IS_PTR(x) && DCL_PTR_CONST(x))
+#define IS_PTR_RESTRICT(x) (IS_PTR(x) && DCL_PTR_RESTRICT(x))
 #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)
@@ -466,6 +492,7 @@ extern sym_link *validateLink(sym_link  *l,
 #define IS_REGISTER(x)  (IS_SPEC(x) && SPEC_SCLS(x) == S_REGISTER)
 #define IS_RENT(x)   (IS_SPEC(x) && x->select.s._reent )
 #define IS_STATIC(x) (IS_SPEC(x) && SPEC_STAT(x))
+#define IS_INLINE(x) (IS_SPEC(x) && SPEC_INLINE(x))
 #define IS_INT(x)    (IS_SPEC(x) && x->select.s.noun == V_INT)
 #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)
@@ -481,7 +508,7 @@ extern sym_link *validateLink(sym_link  *l,
                                        x->select.s.noun == V_SBIT ))
 #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_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 ))
@@ -525,8 +552,8 @@ extern symbol *__fps16x16_lteq;
 extern symbol *__fps16x16_gt;
 extern symbol *__fps16x16_gteq;
 
-/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
-extern symbol *__muldiv[3][3][2];
+/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED/BOTH */
+extern symbol *__muldiv[3][3][4];
 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
 extern sym_link *__multypes[3][2];
 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
@@ -556,6 +583,7 @@ typedef enum
   RESULT_TYPE_INT,
   RESULT_TYPE_OTHER,    /* operands will be promoted to int */
   RESULT_TYPE_IFX,
+  RESULT_TYPE_GPTR,     /* operands will be promoted to generic ptr */
 } RESULT_TYPE;
 
 /* forward definitions for the symbol table related functions */
@@ -601,7 +629,8 @@ sym_link *computeType (sym_link *, sym_link *, RESULT_TYPE, int);
 void processFuncPtrArgs (sym_link *);
 void processFuncArgs (symbol *);
 int isSymbolEqual (symbol *, symbol *);
-int powof2 (TYPE_UDWORD);
+int powof2 (TYPE_TARGET_ULONG);
+void dbuf_printTypeChain (sym_link *, struct dbuf_s *);
 void printTypeChain (sym_link *, FILE *);
 void printTypeChainRaw (sym_link *, FILE *);
 void initCSupport ();