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

📄 ccsym.c

📁 KCC , a good c compiler, write by Ken Harrenstien
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (!isvowel(*sp) && *sp != '_')
	    --i, *++cp = *sp;
	}

    *++cp = 0;

    if (!smapmatch(ms = sixbit(sym6)))
	{
	s->Smaplab = ms;
	return;
	}

    /* Sigh sigh, fall into step 3 -- add digits on end */

    if (i > 0)		/* Fill out rest of name with '0's */
	{
	while (--i >= 0)
	    *++cp = '0';

	*++cp = 0;
	}

    for (;;)
	{
	if (!smapmatch(ms = sixbit(sym6)))
	    {
	    s->Smaplab = ms;
	    return;
	    }

	/* Increment number again */

	cp = &sym6[5];

	for (;;)
	    {
	    if (!isdigit(*cp))
		{
		*cp = '1';
		break;
		}
	    else if (*cp != '9')
		{
		++(*cp);
		break;
		}

	    *cp = '0';		/* Wrap from 9 to 0 */
	    --cp;		/* and carry to prev digit */
	    }
	}
    }

/* LABEL MANAGEMENT CODE */

static int maxlabel;		/* Current highest-numbered label */
static SYMBOL *fllist = NULL;	/* Free label list */
static SYMBOL *flprev = NULL;	/* queue of almost-free labels */
#if DEBUG_KCC	/* 8/91 shrink KCC */
static int nlabels = 0;		/* # labels allocated */
#endif

/* LABINIT - Initialize label stuff.
**	Called by SYMINIT at start of compilation for each file.
*/
static void
labinit()
{
    maxlabel = 0;		/* Reset internal label numbering to 0 */
    cleanlabs();		/* Ensure no queued labels */
	/* Note that "fllist" is left alone in case it contains free labels,
	** which will save us the bother of allocating them.
	*/
}

/*
** Get a new label to play with.
**
** The argument should be nonzero if the label will be emitted after all
** uses of it, rather than before.  If it is zero, the label is emitted.
*/

SYMBOL *
newlabel()
{
    SYMBOL *lab;

    /* find a free label */
    if ((lab = fllist) != NULL)		/* If have one already free, */
	fllist = fllist->Snext;		/* remove it from freelist */
    /* KAR-8/91, Changed to calloc() call to ensure memory is zeroed */
    else if ((lab = (SYMBOL *) calloc(1, sizeof (*lab))) == NULL)/*make new */
	efatal("Out of memory for labels");
#if DEBUG_KCC	/* 8/91 shrink KCC */
    else
	nlabels++;			/* Bump # of labels allocated */
#endif

    /* fill it out */
    lab->Sclass = SC_ILABEL;		/* this is an internal label */
    sprintf(lab->Sname, "$%d", ++maxlabel); /* give it a name */
    lab->Svalue = 0;			/* no uses yet */
    return lab;
}

/* REFLABEL - Reference or dereference a label.
**
** The second argument is how much to add to the reference count.
** The label may be NULL or not a SC_ILABEL; in that case nothing happens.
*/
void
reflabel(lab, count)
SYMBOL * lab;
{
    if (lab != NULL && lab->Sclass == SC_ILABEL)
	lab->Svalue += count;
}

/* FREELABEL - release a label
**
** Unfortunately we can't know when the last instance in the peephole
** buffer has been emitted, at least until we flush the whole thing out.
** So we keep explicitly freed labels on another list and only transfer
** them after we have emitted a new label (and thus called flushcode()).
**
** This list chains through sprev rather than snext to keep things simple.
*/
void
freelabel(lab)
SYMBOL *lab;
{
    lab->Sprev = flprev;		/* chain old freelist onto it */
    flprev = lab;			/* it is now head of freelist */
}

/* CLEANLABS() - actually free up all "almost-free" labels.
*/

void
cleanlabs()
{
    while (flprev != NULL)	/* peephole buffer is now empty */
	{
	realfreelabel(flprev);	/* so free the list of labels queued */
	flprev = flprev->Sprev;	/* by freelabel() */
	}				/* (nb sprev unchanged by realfree) */
}

/* REALFREELABEL - Really free a label.
**
** This should be called after the last possible reference to the label.
** It will be called automatically on emission of forward labels.
** Note sprev must not be changed (see cleanlabs()).
*/
static void
realfreelabel(lab)
SYMBOL *lab;
{
    lab->Snext = fllist;		/* chain old freelist onto it */
    fllist = lab;			/* it is now head of freelist */
}

#if DEBUG_KCC		/* 5/91 KCC size */
/* SYMDUMP - Dump symbol table info to debugging output.
*/
#if __STDC__
static void shoffset(INT);
#else
static void shoffset();
#endif

extern FILE *fsym;
void
symdump(table, name)
SYMBOL *table;
char *name;
{
    int u;
    char *str, *c, tmpstr[50];
    SYMBOL *s;

    fprintf(fsym, "\n-- Symbols for %s --\n\n", name);
    for (s = table; s != NULL; s = s->Snext)
	{
	switch (u=s->Sclass)
	    {
	    case SC_UNDEF:
		str = "undefined";
		break;
	    case SC_RW:
		str = "reserved word";
		break;
	    case SC_MACRO:
		str = "macro";
		break;
	    case SC_TAG:
		str = "structure tag";
		break;
	    case SC_UTAG:
		str = "undef structure tag";
		break;
	    case SC_TYPEDEF:
		str = "typedef";
		break;
	    case SC_XEXTREF:
		str = "ex-extern-ref";
		break;
	    case SC_EXTREF:
		str = "extern-ref";
		break;
	    case SC_EXTDEF:
		str = "extern-def";
		break;
	    case SC_EXLINK:
		str = "extern-tntdef";
		break;
	    case SC_INTREF:
		str = "intern-ref";
		break;
	    case SC_INTDEF:
		str = "intern-def";
		break;
	    case SC_INLINK:
		str = "intern-tntdef";
		break;
	    case SC_ISTATIC:
		str = "local-static";
		break;
	    case SC_ARG:
		str = "argument";
		break;
	    case SC_RARG:
		str = "register-arg";
		break;
	    case SC_REGISTER:
		str = "register";
		break;
	    case SC_MEMBER:
		str = "struct member";
		break;
	    case SC_AUTO:
		str = "auto";
		break;
	    case SC_RAUTO:
		str = "register-auto";
		break;
	    case SC_LABEL:
		str = "goto label";
		break;
	    case SC_ENUM:
		str = "enumerated type";
		break;
	    case SC_ULABEL:
		str = "undefined goto label";
		break;
	    default:
		sprintf(tmpstr, "ILLEGAL symbol class %d", u);
		str = tmpstr;
	    }
	c = s->Sname;
	fprintf(fsym, "%-10s: %s", c, str);
	if (s->Sflags)
	    fprintf(fsym," (%lo)", (INT) s->Sflags);
	fprintf(fsym,", refs %d", (int) s->Srefs);
	if (u != SC_MACRO && u != SC_TAG && s->Stype)
	    {
	    fprintf(fsym, ", type %d", s->Stype-types);
	    if (s->Stype->Tspec == TS_STRUCT
		|| s->Stype->Tspec == TS_UNION)	/* struct or union? */
		fprintf(fsym, ", struct %s", s->Stype->Tsmtag->Sname+1);
	    fprintf(fsym, ", tsize %ld", (INT) sizetype(s->Stype));
	    }
	switch (u)
	    {
	    case SC_RAUTO:
		fprintf (fsym, ", register %d", s->Sreg);
		break;

	    case SC_AUTO:
		fprintf (fsym, ", offset %ld", (INT) s->Svalue + 1);
		break;

	    case SC_RARG:
		fprintf (fsym, ", register %d", s->Sreg);
		break;
	    case SC_ARG:
		fprintf (fsym, ", offset %ld", (INT) - s->Svalue);
		break;

	    case SC_ENUM:
	    case SC_TAG:
		fprintf(fsym, ", value %ld", (INT) s->Svalue);
		break;

	    case SC_EXTDEF:
	    case SC_INTDEF:
		if (s->Stype->Tspec == TS_FUNCT && s->Shproto)
		    fprintf(fsym, ", Shproto %d", s->Shproto - types);
		break;

	    case SC_MEMBER:
		shoffset(s->Svalue);
		break;

	    case SC_MACRO:
		fprintf(fsym, ", nargs %d, parlen %d, len %d=",
			    (int) s->Smacnpar, (int) s->Smacparlen, (int) s->Smaclen);
		if (!s->Smacptr)
		    fputs("NULL", fsym);
		else
		    {
		    int i = s->Smaclen;
		    char *cp = s->Smacptr;
		    putc('"', fsym);
		    while (--i >= 0)
			putc(*cp++, fsym);
		    putc('"', fsym);
		    }
		break;
	    }
	putc ('\n', fsym);
	}
}

static void
shoffset(off)
INT off;
{
    if (off >= 0)
	fprintf(fsym, ", offset %ld", (INT) off);
    else
	{
	unsigned INT o = -off;			/* negate */
	fprintf(fsym, ", offset %lu, width %lu, bit offset %lu",
		      o >> 12, o & 077, 36 - ((o & 07700) >> 6) - (o & 077));
	}
}
#endif

#if 0	/* debug stuff */
shohash()
{
    int n;
    SYMBOL *s;
    for(n=0; n < MAXHSH; n++)
	if(s = htable[n])
	    {
	    printf("Hash %o:", n);
	    do
		printf(" %o=%s", s, s->Sname);
	    while (s = s->Snhash)
		;
	    printf("\n");
	    }
}
#endif

static int maxtype = 0;	/* maximum types used */

/* TYPEINIT - Initialize things for support of C types.
** Mainly initializes the type table with the supported basic types.
*/
static void
typeinit()
{
    int i;

    /* First a crock to ensure "char" byte size selection has effect */
    typbsiztab[TS_CHAR] = typbsiztab[TS_UCHAR] = tgcsize;

    maxtype = 0;
    for (i = 0 ; i < MAXTYPE ; i++)
	ttable[i] = NULL;	/* Clear hash table */
    for (i = 0; i < TS_MAX; i++)
	if (i == TS_VOID || typsiztab[i] != 0)
	    typeptr[i] = findtype(i, (TYPE *)NULL);
	else
	    typeptr[i] = NULL;

    /* Machine-dependent... clobber table so some types are equivalent */
    /* Someday clean this up and make it table-driven also */
    chartype = uchartype;	/* Say plain "char" is "unsigned char" */
    deftype = inttype;		/* Default type is "int" */
    strcontype = findtype(TS_PTR, chartype);	/* Type of string constant */
    voidptrtype = findtype(TS_PTR, voidtype);	/* (void *) */
    siztype = (clevel >= CLEV_ANSI) ? uinttype	/* Std C wants unsigned, ugh */
				: inttype;
    ptrdifftype = inttype;			/* What ptrdiff_t is */
}


/* NOTE on the various "type finding" routines below:
**	Much of KCC relies on being able to compare types simply by
** comparing the pointers to TYPE nodes.  This, and the desire to share
** type definitions, means that all type declarations must first look for
** an identical existing type, and only create a new type if no existing
** definition matches.
**	In order to do this most efficiently, we indulge in non-portable
** type punning for the arguments to these routines.  Specifically, the
** values of the two unions in the TYPE structure are declared below as
** being (int) and (TYPE *) but may in fact contain other things.
**	This is a deliberate but reasonable sacrifice of clumsy theoretical
** portability in return for speed.
*/

/* FINDTYPE - Find or create an unqualified type.
**	Note CCDECL's tagspec() calls this with a symbol (tag) pointer instead
**	of a type pointer.
*/
TYPE *
findtype(tsp, subt)
TYPE *subt;
{
    return findctype(tsp,
		    typbsiztab[tsp],	/* Use default flags and  # bits */
		    typsiztab[tsp],		/* Use default size in words */
		    subt);
}

#if 0	/* 5/91 KCC size */
/* FINDSZTYPE - Same, but use specified Tsize instead of default.
*/
TYPE *
findsztype(tsp, siz, subt)
int tsp;
INT siz;
TYPE *subt;
{
    return findctype(tsp,
		    typbsiztab[tsp],	/* Use default flags and  # bits */
		    siz,			/* Use specified size in words */
		    subt);
}
#endif

/* FINDUTYPE - Find or create the unqualified version of a given type.
*/
TYPE *
findutype(t)
TYPE *t;
{
    return !(t->Tflag&(TF_QUALS|TF_SIQUALS)) ? t /* No prob if no quals */
	: findctype(t->Tspec, t->Tflag&(~(TF_QUALS|TF_SIQUALS)),
					t->Tsize, t->Tsubt);
}

/* FINDQTYPE - Find or create the qualified version of a given type.
**	The given qualifier flags are added into any that already exist.
*/
TYPE *
findqtype(t, quals)
TYPE *t;
INT quals;
{
    return findctype(t->Tspec, t->Tflag|(quals & TF_QUALS),
			t->Tsize, t->Tsubt);
}

/* FINDFTYPE - Find or create a function type.
**	Tspec is always set to TS_FUNCT and flags to 0.
**	The two arguments are the return type and prototype list pointer.
*/
TYPE *
findftype(rtyp, plist)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -