⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccsym.c

📁 KCC , a good c compiler, write by Ken Harrenstien
💻 C
📖 第 1 页 / 共 5 页
字号:
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 + -