📄 ccsym.c
字号:
TYPE *rtyp, *plist;
{
return findctype(TS_FUNCT, 0, /* Always function, no qualifiers */
(unsigned INT) plist, /* Param list - note type punning! */
rtyp); /* Return type */
}
/* FINDPTYPE - Find or create a prototype-list "type".
** Important thing to note is that only the unqualified version of
** the original type is used.
*/
TYPE *
findptype(tsp, plist, t)
TYPE *plist, *t;
{
return findctype(tsp, 0, /* Never any flags or qualifiers */
(unsigned INT) plist, /* Param list - note type punning! */
((!t || !(t->Tflag&(TF_CONST|TF_VOLATILE))) /* Parameter type */
? t /* Type is OK as is */
: findctype(t->Tspec, /* Ugh, use unqualified version */
(t->Tflag & (~(TF_CONST|TF_VOLATILE))),
t->Tsize,
t->Tsubt)));
}
/* FINDCTYPE - Main routine to find or create a type.
** Permits full specification of all type info; this is the only
** routine that allows setting the type-qualifier flags.
*/
TYPE *
findctype(tsp, flags, siz, subt)
int tsp;
INT flags;
unsigned INT siz;
TYPE *subt;
{
TYPE *t;
int hash;
flags |= tfltab[tsp]; /* Ensure usual flags are added in */
/* Hash up attributes of this type and look up in table */
hash = (int) ((((unsigned INT) subt) + (tsp * 43) + (siz * 101)) %
THASHSIZE);
for (t = ttable[hash]; t != NULL; t = t->Tnhash)
if (t->Tspec == tsp && t->Tflag == flags
&& t->Tsize == siz && t->Tsubt == subt)
return t; /* Found identical existing type! */
/* Not found, have to make up a new one */
#if !DEBUG_KCC /* 9/91 shrink KCC */
if (abs (debcsi) == KCC_DBG_SDBG || abs (debcsi) == KCC_DBG_FDBG)
#endif /* 2/92 fixes KCCDBG */
{
if (!maxtype)
{
types = (TYPE *) calloc (MAXTYPE, sizeof(TYPE));
if (types == NULL)
jerr("Out of memory for types table\n");
}
t = &types[maxtype];
}
#if !DEBUG_KCC
else
{
t = (TYPE *) calloc (1, sizeof(TYPE));
if (t == NULL)
jerr("Out of memory for types table\n");
}
#endif
if (++maxtype >= MAXTYPE)
efatal("Type table overflow");
t->Tspec = tsp; /* Store type specifications */
t->Tflag = flags;
t->Tsize = siz;
t->Tsubt = subt;
t->Tnhash = ttable[hash]; /* link old types with same hash */
ttable[hash] = t; /* add this one in to hash table */
return t;
}
/* CMPTYPE - Compare two types for compatibility
*/
int
cmptype(t1, t2)
TYPE *t1, *t2;
{
return (t1 == t2 || tcomposite(t1, t2));
}
/* CMPUTYPE - Compare two types "unqualifiedly", i.e. ignore const/volatile.
** This is different from normal type compat checking because the
** top type's qualifiers must be ignored.
*/
int
cmputype(t, u)
TYPE *t, *u;
{
if (t == u)
return 1;
if (t->Tspec == u->Tspec
&& (t->Tflag&(~TF_QUALS)) == (u->Tflag&(~TF_QUALS)))
{
switch (t->Tspec)
{
case TS_FUNCT:
return tcomposite(t, u) != NULL;
case TS_ARRAY:
/* If both arrays have sizes, the size must be identical.
** The element types must be compatible.
*/
if (t->Tsize && u->Tsize && (t->Tsize != u->Tsize))
break;
/* Sizes OK, fall thru to check element type */
case TS_PTR:
return (t->Tsubt == u->Tsubt || tcomposite(t->Tsubt, u->Tsubt));
case TS_STRUCT:
case TS_UNION:
return t->Tsmtag == u->Tsmtag;
default:
return 1;
}
}
return 0;
}
/* TCOMPOSITE - Return the composite type for two types, or NULL if
** they are not compatible types.
** Whenever possible, just the "best" of the two is returned, rather
** than constructing a new type.
*/
TYPE *
tcomposite(t1, t2)
TYPE *t1, *t2;
{
TYPE *t;
if (t1 == t2)
return t1; /* Quick check */
if (t1->Tflag != t2->Tflag /* Must have same qualifiers */
|| t1->Tspec != t2->Tspec) /* and same top-level type */
return NULL;
/* Types have same qualifiers and same top-level type, so their
** size or subtype must be different. For some things, that's OK.
*/
switch (t1->Tspec)
{
case TS_ARRAY: /* For array types, */
/* If both arrays have sizes, the size must be identical.
** The element types must always be compatible.
*/
if (t1->Tsize && t2->Tsize && t1->Tsize != t2->Tsize)
break; /* Different sizes, fail */
if (t1->Tsubt != t2->Tsubt) /* must have same element types */
{
if ((t = tcomposite(t1->Tsubt, t2->Tsubt)) != NULL)
return findctype(TS_ARRAY, t1->Tflag,
(t1->Tsize ? t1->Tsize : t2->Tsize), t);
break;
}
return (t1->Tsize ? t1 : t2); /* Won! Return whichever has size */
case TS_PTR: /* For pointer, subtypes must be compatible */
if ((t = tcomposite(t1->Tsubt, t2->Tsubt)) != NULL)
return findctype(TS_PTR, t1->Tflag, t1->Tsize, t);
break;
case TS_FUNCT: /* For function, hairier */
if (t1->Tsubt == t2->Tsubt) /* Check for quick win */
{
if (!t1->Tproto)
return t2; /* Same return type, so use */
if (!t2->Tproto)
return t1; /* whichever has a proto */
t = t1->Tsubt; /* Diff protos, sigh */
}
else if ((t = tcomposite(t1->Tsubt, t2->Tsubt)) == NULL)
break; /* Return types not compatible */
/* Have new return type in t, now determine new prototype in t2 */
if (!t1->Tproto)
t2 = t2->Tproto;
else if (!t2->Tproto)
t2 = t1->Tproto;
else if ((t2 = tcomproto(t1->Tproto, t2->Tproto)) == NULL)
break; /* Prototypes not compatible */
return findftype(t, t2); /* Win! */
default:
; /* do nothing */
}
return NULL;
}
/* TCOMPROTO - Build composite prototype
** Returns NULL if couldn't.
*/
static TYPE *
tcomproto(t1, t2)
TYPE *t1, *t2;
{
TYPE *t;
if (t1 == t2)
return t1; /* Win if same -- TS_PARVOID, TS_PARINF */
if (t1->Tspec != t2->Tspec || t1->Tspec != TS_PARAM)
return NULL; /* Mismatch of (void) or ,...) */
/* OK, have real parameter, build composite type for it */
if ((t = tcomposite(t1->Tsubt, t2->Tsubt)) == NULL)
return NULL; /* Param types not compatible */
if (t1->Tproto && t2->Tproto) /* More params? */
{
if ((t2 = tcomproto(t1->Tproto, t2->Tproto)) == NULL)
return NULL; /* Remaining params not compatible */
}
else if (!t1->Tproto && !t2->Tproto) /* No more params? */
{
t2 = NULL; /* Terminated OK! */
}
else
return NULL; /* Mismatch of # params! */
/* Here, have all the parts needed for new composite prototype. */
return findptype(TS_PARAM, t2, t);
}
/* SIZETYPE - Find size of type, in words.
** Note this is words, not bytes such as "sizeof" evaluates to!
** The only "funny" value is that for "char" which is simply 1 (no smaller
** value can be represented). This requires interpreting the size specially
** when the type is char (see sizeptobj below for an example).
*/
INT
sizetype(TYPE *t)
{
INT s;
if (t == NULL) /* izlist => izer0/1 does this, why? */
{
int_error("sizetype: null type"); /* Flush later if never hit */
return 0;
}
/* calculate factor for array dimensions */
s = 1; /* nothing multiplied in yet */
while (t->Tspec == TS_ARRAY) /* array has to multiply out ranges */
{
s *= t->Tsize; /* so multiply it in with rest */
t = t->Tsubt; /* and go to next in chain */
}
/* Multiply that by size of base type */
if (tisbyte(t)) /* Bytes are special case, round up. */
{
if (!tbitsize(t))
return 0; /* Check for TS_VOID (0-size byte) */
return (s + (TGSIZ_WORD/tbitsize(t)) - 1) / (TGSIZ_WORD/tbitsize(t));
}
switch (t->Tspec)
{
case TS_STRUCT:
case TS_UNION: /* If structure or union, */
if (t->Tsmtag->Sclass != SC_TAG) /* make sure it's defined */
/* Otherwise must be SC_UTAG (undefined) and size is unknown */
error("Structure %S undefined, size unknown",
t->Tsmtag); /* Complain */
break;
case TS_PTR: /* Temporary check installed when changing to
** new type-size scheme, take out if never hit
** and just use default.
*/
if (t->Tsize != (unsigned int) typsiztab[TS_PTR])
{
int_error("bad pointer size: %d", (int) t->Tsize);
return s * typsiztab[TS_PTR];
} /* Drop thru to normal case */
break;
default:
; /* do nothing */
}
return s * t->Tsize; /* return final number of words */
}
/* SIZEPTOBJ - Find size of object that a pointer points to.
** This helps determine how much to increment/decrement pointers by.
** The return value is funny, however. If the pointer is a normal word
** pointer then the "size" is size in words. If the pointer is a byte
** pointer then its "size" is expressed in terms of bytes.
*/
INT
sizeptobj(t)
TYPE *t;
{
return (tisbytepointer(t) /* If byte pointer, handle specially */
? sizearray(t->Tsubt) /* Bytes: either 1 or # elements */
: sizetype(t->Tsubt)); /* Words: use # words */
}
/* SIZEARRAY - returns number of elements in array (1 if not an array).
** This has nothing to do with the size or type of the elements.
** This is used to find the # of bytes in a byte array.
*/
INT
sizearray(t)
register TYPE *t;
{
register INT s = 1;
while (t->Tspec == TS_ARRAY)
{
s *= t->Tsize; /* Multiply size for each index */
t = t->Tsubt; /* of the array structure. */
}
return s;
}
/* ARYERR - Auxiliary for errors invoked by several following rtns */
static void
aryerr(s)
char *s;
{
int_error("%s: array of null", s);
}
/* ELEMBSIZE - Returns size in bits of an element (in an array, or pointed to)
** Value is zero if element is not a scalar object.
** In particular, TS_VOID is zero even though it pretends to be a "byte".
*/
int
elembsize(t)
TYPE *t;
{
if (t->Tspec != TS_PTR && t->Tspec != TS_ARRAY)
return 0;
while ((t = t->Tsubt) != NULL)
if (t->Tspec != TS_ARRAY)
{
if (tisstruct(t))
return TGSIZ_WORD;
return (tisscalar(t) ? (int)tbitsize(t) : 0);
}
aryerr("elembsize");
return 0;
}
#if 0 /* 5/91 KCC size */
/* TISPURE - Return true if type can be considered completely "pure";
** that is, it is completely const-qualified and there are no
** volatile qualifiers.
*/
int
tispure(t)
TYPE *t;
{
while (t->Tspec == TS_ARRAY)
t = t->Tsubt; /* Get to bottom of array */
return (!tisanyvolat(t) && tisconst(t));
}
#endif
/* TISCHARPOINTER - Return true if pointer representation for this type
** is a pointer to some kind of char.
** TISBYTEPOINTER - Likewise for bytes.
*/
int
tischarpointer(t)
TYPE *t;
{
if (t->Tspec != TS_PTR && t->Tspec != TS_ARRAY)
return 0;
while ((t = t->Tsubt) != NULL)
if (t->Tspec != TS_ARRAY)
return(tischar(t));
aryerr("tischarpointer");
return 0;
}
int
tisbytepointer(t)
TYPE *t;
{
if (t->Tspec != TS_PTR && t->Tspec != TS_ARRAY)
return 0;
while ((t = t->Tsubt) != NULL)
if (t->Tspec != TS_ARRAY)
return(tisbyte(t));
aryerr("tisbytepointer");
return 0;
}
/* TISCHARARRAY - Return true if type is "array of char".
** This works for either signed or unsigned chars.
** TISBYTEARRAY - Similar, true if elements are "bytes" (smaller than words).
*/
int
tischararray(t)
TYPE *t;
{
if (t->Tspec != TS_ARRAY)
return 0;
while ((t = t->Tsubt) != NULL)
if (t->Tspec != TS_ARRAY)
return(tischar(t));
aryerr("tischararray");
return 0;
}
int
tisbytearray(t)
TYPE *t;
{
if (t->Tspec != TS_ARRAY)
return 0;
while ((t = t->Tsubt) != NULL)
if (t->Tspec != TS_ARRAY)
return tisbyte(t);
aryerr("tisbytearray");
return 0;
}
#if DEBUG_KCC /* 5/91 KCC size */
/* TYPEDUMP - Dump type table info to debugging file
*/
static struct typflg
{
INT flag;
int flchar;
char *flstr;
}
tflagtb[] = {
TF_CONST, 'C', "Const-qualified",
TF_VOLATILE, 'V', "Volatile-qualified",
TF_INTEG, 'i', "Integral",
TF_FLOAT, 'f', "Floating-point",
TF_SCALAR, 's', "Scalar",
TF_UNSIGN, 'u', "Unsigned",
TF_CHAR, 'c', "Char",
TF_BITF, 'b', "Bitfield",
TF_BYTE, 'B', "Byte (non-word)",
TF_STRUCT, 'S', "Struct or Union",
TF_SICONST, 'n', "S/U contains a const",
TF_SIVOLAT, 'v', "S/U contains a volatile",
0, 0, 0,
};
void
typedump()
{
int u, size, idx;
char *str;
TYPE *t;
SYMBOL *sm;
char flagstr[30],
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -