summaryrefslogtreecommitdiff
path: root/bcc/type.c
diff options
context:
space:
mode:
Diffstat (limited to 'bcc/type.c')
-rw-r--r--bcc/type.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/bcc/type.c b/bcc/type.c
new file mode 100644
index 0000000..4852c9d
--- /dev/null
+++ b/bcc/type.c
@@ -0,0 +1,203 @@
+/* type.c - type and storage-class routines for bcc */
+
+/* Copyright (C) 1992 Bruce Evans */
+
+#include "const.h"
+#include "types.h"
+#include "align.h"
+#include "gencode.h" /* s.b. switches.h */
+#include "sc.h"
+#include "scan.h"
+#include "table.h"
+
+#undef EXTERN
+#define EXTERN
+#include "type.h"
+
+PUBLIC uoffset_t ctypesize = 1;
+PUBLIC uoffset_t dtypesize = 8;
+PUBLIC uoffset_t ftypesize = 0;
+PUBLIC uoffset_t itypesize = 2;
+PUBLIC uoffset_t ptypesize = 2;
+PUBLIC uoffset_t stypesize = 2;
+
+PRIVATE char skey0;
+PRIVATE char skey1;
+
+PUBLIC struct typestruct *addstruct(structname)
+char *structname;
+{
+ unsigned namelength;
+ struct symstruct *symptr;
+ struct typestruct *structype;
+
+ (structype = newtype())->constructor = STRUCTU;
+ structype->alignmask = ctype->alignmask;
+ if (++skey1 == 0)
+ {
+ ++skey1; /* must be nonzero or key string would end */
+ ++skey0; /* will never reach 'A' to be an identifier */
+ }
+ structype->structkey[0] = skey0;
+ structype->structkey[1] = skey1;
+ if (*structname != 0)
+ {
+ symptr = addlorg(structname, structype);
+ symptr->storage = 0;
+ symptr->flags = STRUCTNAME;
+ if (charptr + (namelength = strlen(structname)) >= chartop)
+ growheap(namelength + 1);
+#ifdef TS
+++ts_n_structname;
+ts_s_structname += namelength + 1;
+#endif
+ structype->tname = strcpy(charptr, structname);
+ charptr += namelength + 1;
+ }
+ return structype;
+}
+
+PUBLIC struct typestruct *iscalartotype(scalar)
+scalar_pt scalar;
+{
+ if (scalar & LONG)
+ {
+ if (scalar & UNSIGNED)
+ return ultype;
+ return ltype;
+ }
+ if (scalar & UNSIGNED)
+ return uitype;
+ return itype;
+}
+
+PUBLIC struct typestruct *newtype()
+{
+ register struct typestruct *type;
+
+ type = qmalloc(sizeof *type);
+#ifdef TS
+++ts_n_type;
+ts_s_type += sizeof *type;
+#endif
+ type->typesize = /* (uoffset_t) */
+ type->scalar = /* (scalar_t) */
+ type->constructor = /* (constr_t) */
+ type->structkey[0] = 0;
+ type->nexttype =
+ type->prevtype =
+ type->sidetype = NULL;
+ type->listtype = NULL;
+ type->tname = "";
+ return type;
+}
+
+PUBLIC void outntypechar(type)
+struct typestruct *type;
+{
+ outnbyte(*type->tname);
+}
+
+PUBLIC struct typestruct *pointype(type)
+struct typestruct *type;
+{
+ return prefix(POINTER, ptypesize, type);
+}
+
+PUBLIC struct typestruct *prefix(constructor, size, type)
+constr_pt constructor;
+uoffset_t size;
+struct typestruct *type;
+{
+ register struct typestruct *searchtype;
+
+ for (searchtype = type->prevtype; searchtype != NULL;
+ searchtype = searchtype->sidetype)
+ if (searchtype->constructor == (constr_t) constructor &&
+ searchtype->typesize == size)
+ return searchtype;
+ switch ((searchtype = newtype())->constructor = constructor)
+ {
+ case ARRAY:
+ searchtype->alignmask = type->alignmask;
+ break;
+ case FUNCTION:
+ searchtype->alignmask = ~(uoffset_t) 0;
+ break;
+ case POINTER:
+ searchtype->alignmask = ~(ptypesize - 1) | alignmask;
+ break;
+ case STRUCTU:
+ bugerror("prefixing structure/union");
+ searchtype->alignmask = alignmask;
+ break;
+ }
+ searchtype->typesize = size;
+ searchtype->nexttype = type;
+ searchtype->sidetype = type->prevtype;
+ return type->prevtype = searchtype;
+}
+
+PUBLIC struct typestruct *promote(type)
+struct typestruct *type;
+{
+ scalar_t scalar;
+
+ if ((scalar = type->scalar) & (CHAR | SHORT))
+ {
+ if (scalar & UNSIGNED)
+ return uitype;
+ return itype;
+ }
+ if (scalar & FLOAT)
+ return dtype;
+ if (type->constructor & ARRAY)
+ return pointype(type->nexttype);
+ if (type->constructor & FUNCTION)
+ return pointype(type);
+ return type;
+}
+
+PUBLIC struct typestruct *tounsigned(type)
+struct typestruct *type;
+{
+ switch (type->scalar & ~(UNSIGNED | DLONG))
+ {
+ case CHAR:
+ return uctype;
+ case SHORT:
+ return ustype;
+ case INT:
+ return uitype;
+ case LONG:
+ return ultype;
+ default:
+ error("unsigned only applies to integral types");
+ return type;
+ }
+}
+
+PUBLIC void typeinit()
+{
+#ifdef I8088
+ if (i386_32)
+ {
+ uitype->typesize =
+ itype->typesize =
+ ptypesize =
+ itypesize = 4;
+ dtype->alignmask =
+ fltype->alignmask =
+ uitype->alignmask =
+ ltype->alignmask =
+ ultype->alignmask =
+ itype->alignmask = ~(uoffset_t) (4 - 1);
+ ltype->scalar = LONG; /* not DLONG */
+ ultype->scalar = UNSIGNED | LONG;
+ }
+#endif
+ fitype = prefix(FUNCTION, ftypesize, itype);
+ pctype = pointype(ctype);
+ skey0 = 1;
+ vtype->constructor = VOID;
+}