* src/SDCCsymt.c (sclsFromPtr),
[fw/sdcc] / src / SDCCsymt.h
index 48d3ffd34f239bc473dd9fdeb56e4f1a2ed4caa9..b12b4d3e7281a9fb481d19d5bc344c4fee745941 100644 (file)
 #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,
@@ -93,6 +99,7 @@ typedef enum
     V_STRUCT,
     V_LABEL,
     V_BIT,
+    V_BITFIELD,
     V_SBIT,
     V_DOUBLE
   }
@@ -177,18 +184,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,7 +213,6 @@ 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             */
@@ -314,12 +323,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)
@@ -356,42 +371,40 @@ 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 || \
   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_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     )
@@ -414,7 +427,10 @@ symbol;
 #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,13 +440,18 @@ 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_FLOAT(x)  (IS_SPEC(x) && x->select.s.noun == V_FLOAT)
 #define IS_ARITHMETIC(x) (IS_INTEGRAL(x) || IS_FLOAT(x))
@@ -480,12 +501,11 @@ extern sym_link *floatType;
 /* 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 *);
 sym_link *mergeSpec (sym_link *, sym_link *, char *name);
-sym_link *cloneSpec (sym_link *);
 symbol *reverseSyms (symbol *);
 sym_link *reverseLink (sym_link *);
 symbol *copySymbol (symbol *);
@@ -521,12 +541,11 @@ void processFuncArgs (symbol *);
 int isSymbolEqual (symbol *, symbol *);
 int powof2 (unsigned long);
 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);
@@ -537,6 +556,7 @@ void *findSymWithBlock (bucket **, struct symbol *, int);
 void changePointer (symbol * sym);
 void checkTypeSanity(sym_link *etype, char *name);
 sym_link *typeFromStr (char *) ;
+STORAGE_CLASS sclsFromPtr(sym_link *ptr);
 
 
 extern char *nounName(sym_link *); /* noun strings */