From 425decdf7e9284d15aa726e3ae96b9942fb0e3ea Mon Sep 17 00:00:00 2001 From: IronClawTrem Date: Sun, 16 Feb 2020 03:40:06 +0000 Subject: create tremded branch --- src/tools/lcc/cpp/cpp.c | 621 +++++++++--------- src/tools/lcc/cpp/include.c | 268 ++++---- src/tools/lcc/cpp/unix.c | 215 +++--- src/tools/lcc/etc/bytecode.c | 2 +- src/tools/lcc/etc/lcc.c | 1465 ++++++++++++++++++++++------------------- src/tools/lcc/lburg/gram.c | 72 +- src/tools/lcc/lburg/gram.y | 1 + src/tools/lcc/src/dag.c | 1494 +++++++++++++++++++++++------------------- 8 files changed, 2224 insertions(+), 1914 deletions(-) (limited to 'src/tools/lcc') diff --git a/src/tools/lcc/cpp/cpp.c b/src/tools/lcc/cpp/cpp.c index 5c0cfd7..c379a72 100644 --- a/src/tools/lcc/cpp/cpp.c +++ b/src/tools/lcc/cpp/cpp.c @@ -1,326 +1,339 @@ +#include "cpp.h" +#include #include #include #include #include -#include -#include "cpp.h" char rcsid[] = "cpp.c - faked rcsid"; -#define OUTS 16384 -char outbuf[OUTS]; -char *outbufp = outbuf; -Source *cursource; -int nerrs; -struct token nltoken = { NL, 0, 0, 0, 1, (uchar*)"\n" }; -char *curtime; -int incdepth; -int ifdepth; -int ifsatisfied[NIF]; -int skipping; - - -int -main(int argc, char **argv) +#define OUTS 16384 +char outbuf[OUTS]; +char *outbufp = outbuf; +Source *cursource; +int nerrs; +struct token nltoken = {NL, 0, 0, 0, 1, (uchar *)"\n"}; +char *curtime; +int incdepth; +int ifdepth; +int ifsatisfied[NIF]; +int skipping; + +int main(int argc, char **argv) { - Tokenrow tr; - time_t t; - char ebuf[BUFSIZ]; - - setbuf(stderr, ebuf); - t = time(NULL); - curtime = ctime(&t); - maketokenrow(3, &tr); - expandlex(); - setup(argc, argv); - fixlex(); - iniths(); - genline(); - process(&tr); - flushout(); - fflush(stderr); - exit(nerrs > 0); - return 0; + Tokenrow tr; + time_t t; + char ebuf[BUFSIZ]; + + setbuf(stderr, ebuf); + t = time(NULL); + curtime = ctime(&t); + maketokenrow(3, &tr); + expandlex(); + setup(argc, argv); + fixlex(); + iniths(); + genline(); + process(&tr); + flushout(); + fflush(stderr); + exit(nerrs > 0); + return 0; } -void -process(Tokenrow *trp) +void process(Tokenrow *trp) { - int anymacros = 0; - - for (;;) { - if (trp->tp >= trp->lp) { - trp->tp = trp->lp = trp->bp; - outbufp = outbuf; - anymacros |= gettokens(trp, 1); - trp->tp = trp->bp; - } - if (trp->tp->type == END) { - if (--incdepth>=0) { - if (cursource->ifdepth) - error(ERROR, - "Unterminated conditional in #include"); - unsetsource(); - cursource->line += cursource->lineinc; - trp->tp = trp->lp; - genline(); - continue; - } - if (ifdepth) - error(ERROR, "Unterminated #if/#ifdef/#ifndef"); - break; - } - if (trp->tp->type==SHARP) { - trp->tp += 1; - control(trp); - } else if (!skipping && anymacros) - expandrow(trp, NULL); - if (skipping) - setempty(trp); - puttokens(trp); - anymacros = 0; - cursource->line += cursource->lineinc; - if (cursource->lineinc>1) { - genline(); - } - } + int anymacros = 0; + + for (;;) + { + if (trp->tp >= trp->lp) + { + trp->tp = trp->lp = trp->bp; + outbufp = outbuf; + anymacros |= gettokens(trp, 1); + trp->tp = trp->bp; + } + if (trp->tp->type == END) + { + if (--incdepth >= 0) + { + if (cursource->ifdepth) + error(ERROR, "Unterminated conditional in #include"); + unsetsource(); + cursource->line += cursource->lineinc; + trp->tp = trp->lp; + genline(); + continue; + } + if (ifdepth) + error(ERROR, "Unterminated #if/#ifdef/#ifndef"); + break; + } + if (trp->tp->type == SHARP) + { + trp->tp += 1; + control(trp); + } + else if (!skipping && anymacros) + expandrow(trp, NULL); + if (skipping) + setempty(trp); + puttokens(trp); + anymacros = 0; + cursource->line += cursource->lineinc; + if (cursource->lineinc > 1) + { + genline(); + } + } } - -void -control(Tokenrow *trp) -{ - Nlist *np; - Token *tp; - - tp = trp->tp; - if (tp->type!=NAME) { - if (tp->type==NUMBER) - goto kline; - if (tp->type != NL) - error(ERROR, "Unidentifiable control line"); - return; /* else empty line */ - } - if ((np = lookup(tp, 0))==NULL || ((np->flag&ISKW)==0 && !skipping)) { - error(WARNING, "Unknown preprocessor control %t", tp); - return; - } - if (skipping) { - switch (np->val) { - case KENDIF: - if (--ifdepthifdepth; - setempty(trp); - return; - - case KIFDEF: - case KIFNDEF: - case KIF: - if (++ifdepth >= NIF) - error(FATAL, "#if too deeply nested"); - ++cursource->ifdepth; - return; - - case KELIF: - case KELSE: - if (ifdepth<=skipping) - break; - return; - - default: - return; - } - } - switch (np->val) { - case KDEFINE: - dodefine(trp); - break; - - case KUNDEF: - tp += 1; - if (tp->type!=NAME || trp->lp - trp->bp != 4) { - error(ERROR, "Syntax error in #undef"); - break; - } - if ((np = lookup(tp, 0)) != NULL) - np->flag &= ~ISDEFINED; - break; - - case KPRAGMA: - return; - - case KIFDEF: - case KIFNDEF: - case KIF: - if (++ifdepth >= NIF) - error(FATAL, "#if too deeply nested"); - ++cursource->ifdepth; - ifsatisfied[ifdepth] = 0; - if (eval(trp, np->val)) - ifsatisfied[ifdepth] = 1; - else - skipping = ifdepth; - break; - case KELIF: - if (ifdepth==0) { - error(ERROR, "#elif with no #if"); - return; - } - if (ifsatisfied[ifdepth]==2) - error(ERROR, "#elif after #else"); - if (eval(trp, np->val)) { - if (ifsatisfied[ifdepth]) - skipping = ifdepth; - else { - skipping = 0; - ifsatisfied[ifdepth] = 1; - } - } else - skipping = ifdepth; - break; - - case KELSE: - if (ifdepth==0 || cursource->ifdepth==0) { - error(ERROR, "#else with no #if"); - return; - } - if (ifsatisfied[ifdepth]==2) - error(ERROR, "#else after #else"); - if (trp->lp - trp->bp != 3) - error(ERROR, "Syntax error in #else"); - skipping = ifsatisfied[ifdepth]? ifdepth: 0; - ifsatisfied[ifdepth] = 2; - break; - - case KENDIF: - if (ifdepth==0 || cursource->ifdepth==0) { - error(ERROR, "#endif with no #if"); - return; - } - --ifdepth; - --cursource->ifdepth; - if (trp->lp - trp->bp != 3) - error(WARNING, "Syntax error in #endif"); - break; - - case KWARNING: - trp->tp = tp+1; - error(WARNING, "#warning directive: %r", trp); - break; - - case KERROR: - trp->tp = tp+1; - error(ERROR, "#error directive: %r", trp); - break; - - case KLINE: - trp->tp = tp+1; - expandrow(trp, ""); - tp = trp->bp+2; - kline: - if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3lp - || ((tp+3==trp->lp && ((tp+1)->type!=STRING))||*(tp+1)->t=='L')){ - error(ERROR, "Syntax error in #line"); - return; - } - cursource->line = atol((char*)tp->t)-1; - if (cursource->line<0 || cursource->line>=32768) - error(WARNING, "#line specifies number out of range"); - tp = tp+1; - if (tp+1lp) - cursource->filename=(char*)newstring(tp->t+1,tp->len-2,0); - return; - - case KDEFINED: - error(ERROR, "Bad syntax for control line"); - break; - - case KINCLUDE: - doinclude(trp); - trp->lp = trp->bp; - return; - - case KEVAL: - eval(trp, np->val); - break; - - default: - error(ERROR, "Preprocessor control `%t' not yet implemented", tp); - break; - } - setempty(trp); +void control(Tokenrow *trp) +{ + Nlist *np; + Token *tp; + + tp = trp->tp; + if (tp->type != NAME) + { + if (tp->type == NUMBER) + goto kline; + if (tp->type != NL) + error(ERROR, "Unidentifiable control line"); + return; /* else empty line */ + } + if ((np = lookup(tp, 0)) == NULL || ((np->flag & ISKW) == 0 && !skipping)) + { + error(WARNING, "Unknown preprocessor control %t", tp); + return; + } + if (skipping) + { + switch (np->val) + { + case KENDIF: + if (--ifdepth < skipping) + skipping = 0; + --cursource->ifdepth; + setempty(trp); + return; + + case KIFDEF: + case KIFNDEF: + case KIF: + if (++ifdepth >= NIF) + error(FATAL, "#if too deeply nested"); + ++cursource->ifdepth; + return; + + case KELIF: + case KELSE: + if (ifdepth <= skipping) + break; + return; + + default: + return; + } + } + switch (np->val) + { + case KDEFINE: + dodefine(trp); + break; + + case KUNDEF: + tp += 1; + if (tp->type != NAME || trp->lp - trp->bp != 4) + { + error(ERROR, "Syntax error in #undef"); + break; + } + if ((np = lookup(tp, 0)) != NULL) + np->flag &= ~ISDEFINED; + break; + + case KPRAGMA: + return; + + case KIFDEF: + case KIFNDEF: + case KIF: + if (++ifdepth >= NIF) + error(FATAL, "#if too deeply nested"); + ++cursource->ifdepth; + ifsatisfied[ifdepth] = 0; + if (eval(trp, np->val)) + ifsatisfied[ifdepth] = 1; + else + skipping = ifdepth; + break; + + case KELIF: + if (ifdepth == 0) + { + error(ERROR, "#elif with no #if"); + return; + } + if (ifsatisfied[ifdepth] == 2) + error(ERROR, "#elif after #else"); + if (eval(trp, np->val)) + { + if (ifsatisfied[ifdepth]) + skipping = ifdepth; + else + { + skipping = 0; + ifsatisfied[ifdepth] = 1; + } + } + else + skipping = ifdepth; + break; + + case KELSE: + if (ifdepth == 0 || cursource->ifdepth == 0) + { + error(ERROR, "#else with no #if"); + return; + } + if (ifsatisfied[ifdepth] == 2) + error(ERROR, "#else after #else"); + if (trp->lp - trp->bp != 3) + error(ERROR, "Syntax error in #else"); + skipping = ifsatisfied[ifdepth] ? ifdepth : 0; + ifsatisfied[ifdepth] = 2; + break; + + case KENDIF: + if (ifdepth == 0 || cursource->ifdepth == 0) + { + error(ERROR, "#endif with no #if"); + return; + } + --ifdepth; + --cursource->ifdepth; + if (trp->lp - trp->bp != 3) + error(WARNING, "Syntax error in #endif"); + break; + + case KWARNING: + trp->tp = tp + 1; + error(WARNING, "#warning directive: %r", trp); + break; + + case KERROR: + trp->tp = tp + 1; + error(ERROR, "#error directive: %r", trp); + break; + + case KLINE: + trp->tp = tp + 1; + expandrow(trp, ""); + tp = trp->bp + 2; + kline: + if (tp + 1 >= trp->lp || tp->type != NUMBER || tp + 3 < trp->lp || + ((tp + 3 == trp->lp && ((tp + 1)->type != STRING)) || *(tp + 1)->t == 'L')) + { + error(ERROR, "Syntax error in #line"); + return; + } + cursource->line = atol((char *)tp->t) - 1; + if (cursource->line < 0 || cursource->line >= 32768) + error(WARNING, "#line specifies number out of range"); + tp = tp + 1; + if (tp + 1 < trp->lp) + cursource->filename = (char *)newstring(tp->t + 1, tp->len - 2, 0); + return; + + case KDEFINED: + error(ERROR, "Bad syntax for control line"); + break; + + case KINCLUDE: + doinclude(trp); + trp->lp = trp->bp; + return; + + case KEVAL: + eval(trp, np->val); + break; + + default: + error(ERROR, "Preprocessor control `%t' not yet implemented", tp); + break; + } + setempty(trp); } -void * -domalloc(int size) +void *domalloc(int size) { - void *p = malloc(size); + void *p = malloc(size); - if (p==NULL) - error(FATAL, "Out of memory from malloc"); - return p; + if (p == NULL) + error(FATAL, "Out of memory from malloc"); + return p; } -void -dofree(void *p) -{ - free(p); -} +void dofree(void *p) { free(p); } -void -error(enum errtype type, char *string, ...) +void error(enum errtype type, char *string, ...) { - va_list ap; - char *cp, *ep; - Token *tp; - Tokenrow *trp; - Source *s; - int i; - - fprintf(stderr, "cpp: "); - for (s=cursource; s; s=s->next) - if (*s->filename) - fprintf(stderr, "%s:%d ", s->filename, s->line); - va_start(ap, string); - for (ep=string; *ep; ep++) { - if (*ep=='%') { - switch (*++ep) { - - case 's': - cp = va_arg(ap, char *); - fprintf(stderr, "%s", cp); - break; - case 'd': - i = va_arg(ap, int); - fprintf(stderr, "%d", i); - break; - case 't': - tp = va_arg(ap, Token *); - fprintf(stderr, "%.*s", tp->len, tp->t); - break; - - case 'r': - trp = va_arg(ap, Tokenrow *); - for (tp=trp->tp; tplp&&tp->type!=NL; tp++) { - if (tp>trp->tp && tp->wslen) - fputc(' ', stderr); - fprintf(stderr, "%.*s", tp->len, tp->t); - } - break; - - default: - fputc(*ep, stderr); - break; - } - } else - fputc(*ep, stderr); - } - va_end(ap); - fputc('\n', stderr); - if (type==FATAL) - exit(1); - if (type!=WARNING) - nerrs = 1; - fflush(stderr); + va_list ap; + char *cp, *ep; + Token *tp; + Tokenrow *trp; + Source *s; + int i; + + fprintf(stderr, "cpp: "); + for (s = cursource; s; s = s->next) + if (*s->filename) + fprintf(stderr, "%s:%d ", s->filename, s->line); + va_start(ap, string); + for (ep = string; *ep; ep++) + { + if (*ep == '%') + { + switch (*++ep) + { + case 's': + cp = va_arg(ap, char *); + fprintf(stderr, "%s", cp); + break; + case 'd': + i = va_arg(ap, int); + fprintf(stderr, "%d", i); + break; + case 't': + tp = va_arg(ap, Token *); + fprintf(stderr, "%.*s", tp->len, tp->t); + break; + + case 'r': + trp = va_arg(ap, Tokenrow *); + for (tp = trp->tp; tp < trp->lp && tp->type != NL; tp++) + { + if (tp > trp->tp && tp->wslen) + fputc(' ', stderr); + fprintf(stderr, "%.*s", tp->len, tp->t); + } + break; + + default: + fputc(*ep, stderr); + break; + } + } + else + fputc(*ep, stderr); + } + va_end(ap); + fputc('\n', stderr); + if (type == FATAL) + exit(1); + if (type != WARNING) + nerrs = 1; + fflush(stderr); } diff --git a/src/tools/lcc/cpp/include.c b/src/tools/lcc/cpp/include.c index 5ecd8b3..778cea2 100644 --- a/src/tools/lcc/cpp/include.c +++ b/src/tools/lcc/cpp/include.c @@ -3,151 +3,171 @@ #include #include "cpp.h" -Includelist includelist[NINCLUDE]; +Includelist includelist[NINCLUDE]; -extern char *objname; +extern char *objname; -void appendDirToIncludeList( char *dir ) +void appendDirToIncludeList(char *dir) { - int i; - char *fqdir; + int i; + char *fqdir; - fqdir = (char *)newstring( (uchar *)includelist[NINCLUDE-1].file, 256, 0 ); - strcat( fqdir, "/" ); - strcat( fqdir, dir ); + fqdir = (char *)newstring((uchar *)includelist[NINCLUDE - 1].file, 256, 0); + strcat(fqdir, "/"); + strcat(fqdir, dir); - //avoid adding it more than once - for (i=NINCLUDE-2; i>=0; i--) { - if (includelist[i].file && - !strcmp (includelist[i].file, fqdir)) { - return; - } - } + // avoid adding it more than once + for (i = NINCLUDE - 2; i >= 0; i--) + { + if (includelist[i].file && !strcmp(includelist[i].file, fqdir)) + { + return; + } + } - for (i=NINCLUDE-2; i>=0; i--) { - if (includelist[i].file==NULL) { - includelist[i].always = 1; - includelist[i].file = fqdir; - break; - } - } - if (i<0) - error(FATAL, "Too many -I directives"); + for (i = NINCLUDE - 2; i >= 0; i--) + { + if (includelist[i].file == NULL) + { + includelist[i].always = 1; + includelist[i].file = fqdir; + break; + } + } + if (i < 0) + error(FATAL, "Too many -I directives"); } -void -doinclude(Tokenrow *trp) +void doinclude(Tokenrow *trp) { - char fname[256], iname[256]; - Includelist *ip; - int angled, len, fd, i; + char fname[256], iname[256]; + Includelist *ip; + int angled, len, fd, i; - trp->tp += 1; - if (trp->tp>=trp->lp) - goto syntax; - if (trp->tp->type!=STRING && trp->tp->type!=LT) { - len = trp->tp - trp->bp; - expandrow(trp, ""); - trp->tp = trp->bp+len; - } - if (trp->tp->type==STRING) { - len = trp->tp->len-2; - if (len > sizeof(fname) - 1) - len = sizeof(fname) - 1; - strncpy(fname, (char*)trp->tp->t+1, len); - angled = 0; - } else if (trp->tp->type==LT) { - len = 0; - trp->tp++; - while (trp->tp->type!=GT) { - if (trp->tp>trp->lp || len+trp->tp->len+2 >= sizeof(fname)) - goto syntax; - strncpy(fname+len, (char*)trp->tp->t, trp->tp->len); - len += trp->tp->len; - trp->tp++; - } - angled = 1; - } else - goto syntax; - trp->tp += 2; - if (trp->tp < trp->lp || len==0) - goto syntax; - fname[len] = '\0'; + trp->tp += 1; + if (trp->tp >= trp->lp) + goto syntax; + if (trp->tp->type != STRING && trp->tp->type != LT) + { + len = trp->tp - trp->bp; + expandrow(trp, ""); + trp->tp = trp->bp + len; + } + if (trp->tp->type == STRING) + { + len = trp->tp->len - 2; + if (len > sizeof(fname) - 1) + len = sizeof(fname) - 1; + strncpy(fname, (char *)trp->tp->t + 1, len); + angled = 0; + } + else if (trp->tp->type == LT) + { + len = 0; + trp->tp++; + while (trp->tp->type != GT) + { + if (trp->tp > trp->lp || len + trp->tp->len + 2 >= sizeof(fname)) + goto syntax; + strncpy(fname + len, (char *)trp->tp->t, trp->tp->len); + len += trp->tp->len; + trp->tp++; + } + angled = 1; + } + else + goto syntax; + trp->tp += 2; + if (trp->tp < trp->lp || len == 0) + goto syntax; + fname[len] = '\0'; - appendDirToIncludeList( basepath( fname ) ); + appendDirToIncludeList(basepath(fname)); - if (fname[0]=='/') { - fd = open(fname, 0); - strcpy(iname, fname); - } else for (fd = -1,i=NINCLUDE-1; i>=0; i--) { - ip = &includelist[i]; - if (ip->file==NULL || ip->deleted || (angled && ip->always==0)) - continue; - if (strlen(fname)+strlen(ip->file)+2 > sizeof(iname)) - continue; - strcpy(iname, ip->file); - strcat(iname, "/"); - strcat(iname, fname); - if ((fd = open(iname, 0)) >= 0) - break; - } - if ( Mflag>1 || (!angled&&Mflag==1) ) { - write(1,objname,strlen(objname)); - write(1,iname,strlen(iname)); - write(1,"\n",1); - } - if (fd >= 0) { - if (++incdepth > 10) - error(FATAL, "#include too deeply nested"); - setsource((char*)newstring((uchar*)iname, strlen(iname), 0), fd, NULL); - genline(); - } else { - trp->tp = trp->bp+2; - error(ERROR, "Could not find include file %r", trp); - } - return; + if (fname[0] == '/') + { + fd = open(fname, 0); + strcpy(iname, fname); + } + else + for (fd = -1, i = NINCLUDE - 1; i >= 0; i--) + { + ip = &includelist[i]; + if (ip->file == NULL || ip->deleted || (angled && ip->always == 0)) + continue; + if (strlen(fname) + strlen(ip->file) + 2 > sizeof(iname)) + continue; + strcpy(iname, ip->file); + strcat(iname, "/"); + strcat(iname, fname); + if ((fd = open(iname, 0)) >= 0) + break; + } + if (Mflag > 1 || (!angled && Mflag == 1)) + { + write(1, objname, strlen(objname)); + write(1, iname, strlen(iname)); + write(1, "\n", 1); + } + if (fd >= 0) + { + if (++incdepth > 10) + error(FATAL, "#include too deeply nested"); + setsource((char *)newstring((uchar *)iname, strlen(iname), 0), fd, NULL); + genline(); + } + else + { + trp->tp = trp->bp + 2; + error(ERROR, "Could not find include file %r", trp); + } + return; syntax: - error(ERROR, "Syntax error in #include"); + error(ERROR, "Syntax error in #include"); } /* * Generate a line directive for cursource */ -void -genline(void) +void genline(void) { - static Token ta = { UNCLASS }; - static Tokenrow tr = { &ta, &ta, &ta+1, 1 }; - uchar *p; + static Token ta = {UNCLASS}; + static Tokenrow tr = {&ta, &ta, &ta + 1, 1}; + uchar *p; - ta.t = p = (uchar*)outbufp; - strcpy((char*)p, "#line "); - p += sizeof("#line ")-1; - p = (uchar*)outnum((char*)p, cursource->line); - *p++ = ' '; *p++ = '"'; - if (cursource->filename[0]!='/' && wd[0]) { - strcpy((char*)p, wd); - p += strlen(wd); - *p++ = '/'; - } - strcpy((char*)p, cursource->filename); - p += strlen((char*)p); - *p++ = '"'; *p++ = '\n'; - ta.len = (char*)p-outbufp; - outbufp = (char*)p; - tr.tp = tr.bp; - puttokens(&tr); + ta.t = p = (uchar *)outbufp; + strcpy((char *)p, "#line "); + p += sizeof("#line ") - 1; + p = (uchar *)outnum((char *)p, cursource->line); + *p++ = ' '; + *p++ = '"'; + if (cursource->filename[0] != '/' && wd[0]) + { + strcpy((char *)p, wd); + p += strlen(wd); + *p++ = '/'; + } + strcpy((char *)p, cursource->filename); + p += strlen((char *)p); + *p++ = '"'; + *p++ = '\n'; + ta.len = (char *)p - outbufp; + outbufp = (char *)p; + tr.tp = tr.bp; + puttokens(&tr); } -void -setobjname(char *f) +void setobjname(char *f) { - int n = strlen(f); - objname = (char*)domalloc(n+5); - strcpy(objname,f); - if(objname[n-2]=='.'){ - strcpy(objname+n-1,"$O: "); - }else{ - strcpy(objname+n,"$O: "); - } + int n = strlen(f); + objname = (char *)domalloc(n + 5); + strcpy(objname, f); + if (objname[n - 2] == '.') + { + strcpy(objname + n - 1, "$O: "); + } + else + { + strcpy(objname + n, "$O: "); + } } diff --git a/src/tools/lcc/cpp/unix.c b/src/tools/lcc/cpp/unix.c index ff1496a..ee975aa 100644 --- a/src/tools/lcc/cpp/unix.c +++ b/src/tools/lcc/cpp/unix.c @@ -1,134 +1,141 @@ -#include #include +#include #include #include #include #include "cpp.h" -extern int lcc_getopt(int, char *const *, const char *); -extern char *optarg, rcsid[]; -extern int optind; -int verbose; -int Mflag; /* only print active include files */ -char *objname; /* "src.$O: " */ -int Cplusplus = 1; +extern int lcc_getopt(int, char *const *, const char *); +extern char *optarg, rcsid[]; +extern int optind; +int verbose; +int Mflag; /* only print active include files */ +char *objname; /* "src.$O: " */ +int Cplusplus = 1; -void -setup(int argc, char **argv) +void setup(int argc, char **argv) { - int c, fd, i; - char *fp, *dp; - Tokenrow tr; - extern void setup_kwtab(void); - uchar *includeDirs[ NINCLUDE ] = { 0 }; - int numIncludeDirs = 0; + int c, fd, i; + char *fp, *dp; + Tokenrow tr; + extern void setup_kwtab(void); + uchar *includeDirs[NINCLUDE] = {0}; + int numIncludeDirs = 0; - setup_kwtab(); - while ((c = lcc_getopt(argc, argv, "MNOVv+I:D:U:F:lg")) != -1) - switch (c) { - case 'N': - for (i=0; i", -1, optarg); - maketokenrow(3, &tr); - gettokens(&tr, 1); - doadefine(&tr, c); - unsetsource(); - break; - case 'M': - Mflag++; - break; - case 'v': - fprintf(stderr, "%s %s\n", argv[0], rcsid); - break; - case 'V': - verbose++; - break; - case '+': - Cplusplus++; - break; - default: - break; - } - dp = "."; - fp = ""; - fd = 0; - if (optind", -1, optarg); + maketokenrow(3, &tr); + gettokens(&tr, 1); + doadefine(&tr, c); + unsetsource(); + break; + case 'M': + Mflag++; + break; + case 'v': + fprintf(stderr, "%s %s\n", argv[0], rcsid); + break; + case 'V': + verbose++; + break; + case '+': + Cplusplus++; + break; + default: + break; + } + dp = "."; + fp = ""; + fd = 0; + if (optind < argc) + { + dp = basepath(argv[optind]); + fp = (char *)newstring((uchar *)argv[optind], strlen(argv[optind]), 0); + if ((fd = open(fp, 0)) <= 0) + error(FATAL, "Can't open input file %s", fp); + } + if (optind + 1 < argc) + { + int fdo; #ifdef WIN32 - fdo = creat(argv[optind+1], _S_IREAD | _S_IWRITE); + fdo = creat(argv[optind + 1], _S_IREAD | _S_IWRITE); #else - fdo = creat(argv[optind+1], 0666); + fdo = creat(argv[optind + 1], 0666); #endif - if (fdo<0) - error(FATAL, "Can't open output file %s", argv[optind+1]); - dup2(fdo, 1); - } - if(Mflag) - setobjname(fp); - includelist[NINCLUDE-1].always = 0; - includelist[NINCLUDE-1].file = dp; + if (fdo < 0) + error(FATAL, "Can't open output file %s", argv[optind + 1]); + dup2(fdo, 1); + } + if (Mflag) + setobjname(fp); + includelist[NINCLUDE - 1].always = 0; + includelist[NINCLUDE - 1].file = dp; - for( i = 0; i < numIncludeDirs; i++ ) - appendDirToIncludeList( (char *)includeDirs[ i ] ); + for (i = 0; i < numIncludeDirs; i++) + appendDirToIncludeList((char *)includeDirs[i]); - setsource(fp, fd, NULL); + setsource(fp, fd, NULL); } - -char *basepath( char *fname ) +char *basepath(char *fname) { - char *dp = "."; - char *p; - if ((p = strrchr(fname, '/')) != NULL) { - int dlen = p - fname; - dp = (char*)newstring((uchar*)fname, dlen+1, 0); - dp[dlen] = '\0'; - } + char *dp = "."; + char *p; + if ((p = strrchr(fname, '/')) != NULL) + { + int dlen = p - fname; + dp = (char *)newstring((uchar *)fname, dlen + 1, 0); + dp[dlen] = '\0'; + } - return dp; + return dp; } /* memmove is defined here because some vendors don't provide it at all and others do a terrible job (like calling malloc) */ // -- ouch, that hurts -- ln -#ifndef __APPLE__ /* always use the system memmove() on Mac OS X. --ryan. */ +/* always use the system memmove() on Mac OS X. --ryan. */ +#if !defined(__APPLE__) && !defined(_MSC_VER) #ifdef memmove #undef memmove #endif -void * -memmove(void *dp, const void *sp, size_t n) +void *memmove(void *dp, const void *sp, size_t n) { - unsigned char *cdp, *csp; + unsigned char *cdp, *csp; - if (n<=0) - return dp; - cdp = dp; - csp = (unsigned char *)sp; - if (cdp < csp) { - do { - *cdp++ = *csp++; - } while (--n); - } else { - cdp += n; - csp += n; - do { - *--cdp = *--csp; - } while (--n); - } - return dp; + if (n <= 0) + return dp; + cdp = dp; + csp = (unsigned char *)sp; + if (cdp < csp) + { + do + { + *cdp++ = *csp++; + } while (--n); + } + else + { + cdp += n; + csp += n; + do + { + *--cdp = *--csp; + } while (--n); + } + return dp; } #endif diff --git a/src/tools/lcc/etc/bytecode.c b/src/tools/lcc/etc/bytecode.c index a5855de..1bbee64 100644 --- a/src/tools/lcc/etc/bytecode.c +++ b/src/tools/lcc/etc/bytecode.c @@ -2,7 +2,7 @@ #include #include -#include "../../../qcommon/q_platform.h" +#include "qcommon/q_platform.h" #ifdef _WIN32 #define BINEXT ".exe" diff --git a/src/tools/lcc/etc/lcc.c b/src/tools/lcc/etc/lcc.c index aa3e789..9ebc47f 100644 --- a/src/tools/lcc/etc/lcc.c +++ b/src/tools/lcc/etc/lcc.c @@ -4,16 +4,16 @@ */ static char rcsid[] = "Id: dummy rcsid"; -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include #ifdef WIN32 -#include /* getpid() */ #include /* access() */ +#include /* getpid() */ #else #include #endif @@ -23,13 +23,13 @@ static char rcsid[] = "Id: dummy rcsid"; #endif typedef struct list *List; -struct list { /* circular list nodes: */ - char *str; /* option or file name */ - List link; /* next list element */ +struct list { /* circular list nodes: */ + char *str; /* option or file name */ + List link; /* next list element */ }; static void *alloc(int); -static List append(char *,List); +static List append(char *, List); extern char *basename(char *); static int callsys(char *[]); extern char *concat(char *, char *); @@ -57,228 +57,258 @@ extern char *tempname(char *); extern int getpid(void); #endif -extern char *cpp[], *include[], *com[], *as[],*ld[], inputs[], *suffixes[]; +extern char *cpp[], *include[], *com[], *as[], *ld[], inputs[], *suffixes[]; extern int option(char *); -static int errcnt; /* number of errors */ -static int Eflag; /* -E specified */ -static int Sflag = 1; /* -S specified */ //for Q3 we always generate asm -static int cflag; /* -c specified */ -static int verbose; /* incremented for each -v */ -static List llist[2]; /* loader files, flags */ -static List alist; /* assembler flags */ -static List clist; /* compiler flags */ -static List plist; /* preprocessor flags */ -static List ilist; /* list of additional includes from LCCINPUTS */ -static List rmlist; /* list of files to remove */ -static char *outfile; /* ld output file or -[cS] object file */ -static int ac; /* argument count */ -static char **av; /* argument vector */ -char *tempdir = TEMPDIR; /* directory for temporary files */ +static int errcnt; /* number of errors */ +static int Eflag; /* -E specified */ +static int Sflag = 1; /* -S specified */ // for Q3 we always generate asm +static int cflag; /* -c specified */ +static int verbose; /* incremented for each -v */ +static List llist[2]; /* loader files, flags */ +static List alist; /* assembler flags */ +static List clist; /* compiler flags */ +static List plist; /* preprocessor flags */ +static List ilist; /* list of additional includes from LCCINPUTS */ +static List rmlist; /* list of files to remove */ +static char *outfile; /* ld output file or -[cS] object file */ +static int ac; /* argument count */ +static char **av; /* argument vector */ +char *tempdir = TEMPDIR; /* directory for temporary files */ static char *progname; -static List lccinputs; /* list of input directories */ +static List lccinputs; /* list of input directories */ -extern void UpdatePaths( const char *lccBinary ); +extern void UpdatePaths(const char *lccBinary); -int main(int argc, char *argv[]) { - int i, j, nf; +int main(int argc, char *argv[]) +{ + int i, j, nf; - progname = argv[0]; + progname = argv[0]; - UpdatePaths( progname ); + UpdatePaths(progname); - ac = argc + 50; - av = alloc(ac*sizeof(char *)); - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, interrupt); - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, interrupt); + ac = argc + 50; + av = alloc(ac * sizeof(char *)); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, interrupt); + if (signal(SIGTERM, SIG_IGN) != SIG_IGN) + signal(SIGTERM, interrupt); #ifdef SIGHUP - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) - signal(SIGHUP, interrupt); + if (signal(SIGHUP, SIG_IGN) != SIG_IGN) + signal(SIGHUP, interrupt); #endif - if (getenv("TMP")) - tempdir = getenv("TMP"); - else if (getenv("TEMP")) - tempdir = getenv("TEMP"); - else if (getenv("TMPDIR")) - tempdir = getenv("TMPDIR"); - assert(tempdir); - i = strlen(tempdir); - for (; (i > 0 && tempdir[i-1] == '/') || tempdir[i-1] == '\\'; i--) - tempdir[i-1] = '\0'; - if (argc <= 1) { - help(); - exit(0); - } - plist = append("-D__LCC__", 0); - initinputs(); - if (getenv("LCCDIR")) - option(stringf("-lccdir=%s", getenv("LCCDIR"))); - for (nf = 0, i = j = 1; i < argc; i++) { - if (strcmp(argv[i], "-o") == 0) { - if (++i < argc) { - if (suffix(argv[i], suffixes, 2) >= 0) { - error("-o would overwrite %s", argv[i]); - exit(8); - } - outfile = argv[i]; - continue; - } else { - error("unrecognized option `%s'", argv[i-1]); - exit(8); - } - } else if (strcmp(argv[i], "-target") == 0) { - if (argv[i+1] && *argv[i+1] != '-') - i++; - continue; - } else if (*argv[i] == '-' && argv[i][1] != 'l') { - opt(argv[i]); - continue; - } else if (*argv[i] != '-' && suffix(argv[i], suffixes, 3) >= 0) - nf++; - argv[j++] = argv[i]; - } - if ((cflag || Sflag) && outfile && nf != 1) { - fprintf(stderr, "%s: -o %s ignored\n", progname, outfile); - outfile = 0; - } - argv[j] = 0; - for (i = 0; include[i]; i++) - plist = append(include[i], plist); - if (ilist) { - List b = ilist; - do { - b = b->link; - plist = append(b->str, plist); - } while (b != ilist); - } - ilist = 0; - for (i = 1; argv[i]; i++) - if (*argv[i] == '-') - opt(argv[i]); - else { - char *name = exists(argv[i]); - if (name) { - if (strcmp(name, argv[i]) != 0 - || (nf > 1 && suffix(name, suffixes, 3) >= 0)) - fprintf(stderr, "%s:\n", name); - filename(name, 0); - } else - error("can't find `%s'", argv[i]); - } - if (errcnt == 0 && !Eflag && !Sflag && !cflag && llist[1]) { - compose(ld, llist[0], llist[1], - append(outfile ? outfile : concat("a", first(suffixes[4])), 0)); - if (callsys(av)) - errcnt++; - } - rm(rmlist); - return errcnt ? EXIT_FAILURE : EXIT_SUCCESS; + if (getenv("TMP")) + tempdir = getenv("TMP"); + else if (getenv("TEMP")) + tempdir = getenv("TEMP"); + else if (getenv("TMPDIR")) + tempdir = getenv("TMPDIR"); + assert(tempdir); + i = strlen(tempdir); + for (; (i > 0 && tempdir[i - 1] == '/') || tempdir[i - 1] == '\\'; i--) + tempdir[i - 1] = '\0'; + if (argc <= 1) + { + help(); + exit(0); + } + plist = append("-D__LCC__", 0); + initinputs(); + if (getenv("LCCDIR")) + option(stringf("-lccdir=%s", getenv("LCCDIR"))); + for (nf = 0, i = j = 1; i < argc; i++) + { + if (strcmp(argv[i], "-o") == 0) + { + if (++i < argc) + { + if (suffix(argv[i], suffixes, 2) >= 0) + { + error("-o would overwrite %s", argv[i]); + exit(8); + } + outfile = argv[i]; + continue; + } + else + { + error("unrecognized option `%s'", argv[i - 1]); + exit(8); + } + } + else if (strcmp(argv[i], "-target") == 0) + { + if (argv[i + 1] && *argv[i + 1] != '-') + i++; + continue; + } + else if (*argv[i] == '-' && argv[i][1] != 'l') + { + opt(argv[i]); + continue; + } + else if (*argv[i] != '-' && suffix(argv[i], suffixes, 3) >= 0) + nf++; + argv[j++] = argv[i]; + } + if ((cflag || Sflag) && outfile && nf != 1) + { + fprintf(stderr, "%s: -o %s ignored\n", progname, outfile); + outfile = 0; + } + argv[j] = 0; + for (i = 0; include[i]; i++) + plist = append(include[i], plist); + if (ilist) + { + List b = ilist; + do + { + b = b->link; + plist = append(b->str, plist); + } while (b != ilist); + } + ilist = 0; + for (i = 1; argv[i]; i++) + if (*argv[i] == '-') + opt(argv[i]); + else + { + char *name = exists(argv[i]); + if (name) + { + if (strcmp(name, argv[i]) != 0 || (nf > 1 && suffix(name, suffixes, 3) >= 0)) + fprintf(stderr, "%s:\n", name); + filename(name, 0); + } + else + error("can't find `%s'", argv[i]); + } + if (errcnt == 0 && !Eflag && !Sflag && !cflag && llist[1]) + { + compose(ld, llist[0], llist[1], append(outfile ? outfile : concat("a", first(suffixes[4])), 0)); + if (callsys(av)) + errcnt++; + } + rm(rmlist); + return errcnt ? EXIT_FAILURE : EXIT_SUCCESS; } /* alloc - allocate n bytes or die */ -static void *alloc(int n) { - static char *avail, *limit; - - n = (n + sizeof(char *) - 1)&~(sizeof(char *) - 1); - if (n >= limit - avail) { - avail = malloc(n + 4*1024); - assert(avail); - limit = avail + n + 4*1024; - } - avail += n; - return avail - n; +static void *alloc(int n) +{ + static char *avail, *limit; + + n = (n + sizeof(char *) - 1) & ~(sizeof(char *) - 1); + if (n >= limit - avail) + { + avail = malloc(n + 4 * 1024); + assert(avail); + limit = avail + n + 4 * 1024; + } + avail += n; + return avail - n; } -/* append - append a node with string str onto list, return new list */ -static List append(char *str, List list) { - List p = alloc(sizeof *p); - - p->str = str; - if (list) { - p->link = list->link; - list->link = p; - } else - p->link = p; - return p; +/* append - append a node with string str onto list, return new list */ +static List append(char *str, List list) +{ + List p = alloc(sizeof *p); + + p->str = str; + if (list) + { + p->link = list->link; + list->link = p; + } + else + p->link = p; + return p; } /* basename - return base name for name, e.g. /usr/drh/foo.c => foo */ -char *basename(char *name) { - char *s, *b, *t = 0; - - for (b = s = name; *s; s++) - if (*s == '/' || *s == '\\') { - b = s + 1; - t = 0; - } else if (*s == '.') - t = s; - s = strsave(b); - if (t) - s[t-b] = 0; - return s; +char *basename(char *name) +{ + char *s, *b, *t = 0; + + for (b = s = name; *s; s++) + if (*s == '/' || *s == '\\') + { + b = s + 1; + t = 0; + } + else if (*s == '.') + t = s; + s = strsave(b); + if (t) + s[t - b] = 0; + return s; } #ifdef WIN32 #include -static char *escapeDoubleQuotes(const char *string) { - int stringLength = strlen(string); - int bufferSize = stringLength + 1; - int i, j; - char *newString; +static char *escapeDoubleQuotes(const char *string) +{ + int stringLength = strlen(string); + int bufferSize = stringLength + 1; + int i, j; + char *newString; - if (string == NULL) - return NULL; + if (string == NULL) + return NULL; - for (i = 0; i < stringLength; i++) { - if (string[i] == '"') - bufferSize++; - } + for (i = 0; i < stringLength; i++) + { + if (string[i] == '"') + bufferSize++; + } - newString = (char*)malloc(bufferSize); + newString = (char *)malloc(bufferSize); - if (newString == NULL) - return NULL; + if (newString == NULL) + return NULL; - for (i = 0, j = 0; i < stringLength; i++) { - if (string[i] == '"') - newString[j++] = '\\'; + for (i = 0, j = 0; i < stringLength; i++) + { + if (string[i] == '"') + newString[j++] = '\\'; - newString[j++] = string[i]; - } + newString[j++] = string[i]; + } - newString[j] = '\0'; + newString[j] = '\0'; - return newString; + return newString; } -static int spawn(const char *cmdname, char **argv) { - int argc = 0; - char **newArgv = argv; - int i; - intptr_t exitStatus; +static int spawn(const char *cmdname, char **argv) +{ + int argc = 0; + char **newArgv = argv; + int i; + intptr_t exitStatus; - // _spawnvp removes double quotes from arguments, so we - // have to escape them manually - while (*newArgv++ != NULL) - argc++; + // _spawnvp removes double quotes from arguments, so we + // have to escape them manually + while (*newArgv++ != NULL) + argc++; - newArgv = (char **)malloc(sizeof(char*) * (argc + 1)); + newArgv = (char **)malloc(sizeof(char *) * (argc + 1)); - for (i = 0; i < argc; i++) - newArgv[i] = escapeDoubleQuotes(argv[i]); + for (i = 0; i < argc; i++) + newArgv[i] = escapeDoubleQuotes(argv[i]); - newArgv[argc] = NULL; + newArgv[argc] = NULL; - exitStatus = _spawnvp(_P_WAIT, cmdname, (const char *const *)newArgv); + exitStatus = _spawnvp(_P_WAIT, cmdname, (const char *const *)newArgv); - for (i = 0; i < argc; i++) - free(newArgv[i]); + for (i = 0; i < argc; i++) + free(newArgv[i]); - free(newArgv); - return exitStatus; + free(newArgv); + return exitStatus; } #else @@ -289,569 +319,628 @@ extern int fork(void); #endif extern int wait(int *); -static int spawn(const char *cmdname, char **argv) { - int pid, n, status; - - switch (pid = fork()) { - case -1: - fprintf(stderr, "%s: no more processes\n", progname); - return 100; - case 0: - // TTimo removing hardcoded paths, searching in $PATH - execvp(cmdname, argv); - fprintf(stderr, "%s: ", progname); - perror(cmdname); - fflush(stdout); - exit(100); - } - while ((n = wait(&status)) != pid && n != -1) - ; - if (n == -1) - status = -1; - if (status&0377) { - fprintf(stderr, "%s: fatal error in %s\n", progname, cmdname); - status |= 0400; - } - return (status>>8)&0377; +static int spawn(const char *cmdname, char **argv) +{ + int pid, n, status; + + switch (pid = fork()) + { + case -1: + fprintf(stderr, "%s: no more processes\n", progname); + return 100; + case 0: + // TTimo removing hardcoded paths, searching in $PATH + execvp(cmdname, argv); + fprintf(stderr, "%s: ", progname); + perror(cmdname); + fflush(stdout); + exit(100); + } + while ((n = wait(&status)) != pid && n != -1) + ; + if (n == -1) + status = -1; + if (status & 0377) + { + fprintf(stderr, "%s: fatal error in %s\n", progname, cmdname); + status |= 0400; + } + return (status >> 8) & 0377; } #endif /* callsys - execute the command described by av[0...], return status */ -static int callsys(char **av) { - int i, status = 0; - static char **argv; - static int argc; - char *executable; - - for (i = 0; av[i] != NULL; i++) - ; - if (i + 1 > argc) { - argc = i + 1; - if (argv == NULL) - argv = malloc(argc*sizeof *argv); - else - argv = realloc(argv, argc*sizeof *argv); - assert(argv); - } - for (i = 0; status == 0 && av[i] != NULL; ) { - int j = 0; - char *s = NULL; - for ( ; av[i] != NULL && (s = strchr(av[i], '\n')) == NULL; i++) - argv[j++] = av[i]; - if (s != NULL) { - if (s > av[i]) - argv[j++] = stringf("%.*s", s - av[i], av[i]); - if (s[1] != '\0') - av[i] = s + 1; - else - i++; - } - argv[j] = NULL; - executable = strsave( argv[0] ); - argv[0] = stringf( "\"%s\"", argv[0] ); - if (verbose > 0) { - int k; - fprintf(stderr, "%s", argv[0]); - for (k = 1; argv[k] != NULL; k++) - fprintf(stderr, " %s", argv[k]); - fprintf(stderr, "\n"); - } - if (verbose < 2) - status = spawn(executable, argv); - if (status == -1) { - fprintf(stderr, "%s: ", progname); - perror(argv[0]); - } - } - return status; +static int callsys(char **av) +{ + int i, status = 0; + static char **argv; + static int argc; + char *executable; + + for (i = 0; av[i] != NULL; i++) + ; + if (i + 1 > argc) + { + argc = i + 1; + if (argv == NULL) + argv = malloc(argc * sizeof *argv); + else + argv = realloc(argv, argc * sizeof *argv); + assert(argv); + } + for (i = 0; status == 0 && av[i] != NULL;) + { + int j = 0; + char *s = NULL; + for (; av[i] != NULL && (s = strchr(av[i], '\n')) == NULL; i++) + argv[j++] = av[i]; + if (s != NULL) + { + if (s > av[i]) + argv[j++] = stringf("%.*s", s - av[i], av[i]); + if (s[1] != '\0') + av[i] = s + 1; + else + i++; + } + argv[j] = NULL; + executable = strsave(argv[0]); + argv[0] = stringf("\"%s\"", argv[0]); + if (verbose > 0) + { + int k; + fprintf(stderr, "%s", argv[0]); + for (k = 1; argv[k] != NULL; k++) + fprintf(stderr, " %s", argv[k]); + fprintf(stderr, "\n"); + } + if (verbose < 2) + status = spawn(executable, argv); + if (status == -1) + { + fprintf(stderr, "%s: ", progname); + perror(argv[0]); + } + } + return status; } /* concat - return concatenation of strings s1 and s2 */ -char *concat(char *s1, char *s2) { - int n = strlen(s1); - char *s = alloc(n + strlen(s2) + 1); - - strcpy(s, s1); - strcpy(s + n, s2); - return s; +char *concat(char *s1, char *s2) +{ + int n = strlen(s1); + char *s = alloc(n + strlen(s2) + 1); + + strcpy(s, s1); + strcpy(s + n, s2); + return s; } /* compile - compile src into dst, return status */ -static int compile(char *src, char *dst) { - compose(com, clist, append(src, 0), append(dst, 0)); - return callsys(av); +static int compile(char *src, char *dst) +{ + compose(com, clist, append(src, 0), append(dst, 0)); + return callsys(av); } /* compose - compose cmd into av substituting a, b, c for $1, $2, $3, resp. */ -static void compose(char *cmd[], List a, List b, List c) { - int i, j; - List lists[3]; - - lists[0] = a; - lists[1] = b; - lists[2] = c; - for (i = j = 0; cmd[i]; i++) { - char *s = strchr(cmd[i], '$'); - if (s && isdigit(s[1])) { - int k = s[1] - '0'; - assert(k >=1 && k <= 3); - if ((b = lists[k-1])) { - b = b->link; - av[j] = alloc(strlen(cmd[i]) + strlen(b->str) - 1); - strncpy(av[j], cmd[i], s - cmd[i]); - av[j][s-cmd[i]] = '\0'; - strcat(av[j], b->str); - strcat(av[j++], s + 2); - while (b != lists[k-1]) { - b = b->link; - assert(j < ac); - av[j++] = b->str; - }; - } - } else if (*cmd[i]) { - assert(j < ac); - av[j++] = cmd[i]; - } - } - av[j] = NULL; +static void compose(char *cmd[], List a, List b, List c) +{ + int i, j; + List lists[3]; + + lists[0] = a; + lists[1] = b; + lists[2] = c; + for (i = j = 0; cmd[i]; i++) + { + char *s = strchr(cmd[i], '$'); + if (s && isdigit(s[1])) + { + int k = s[1] - '0'; + assert(k >= 1 && k <= 3); + if ((b = lists[k - 1])) + { + b = b->link; + av[j] = alloc(strlen(cmd[i]) + strlen(b->str) - 1); + strncpy(av[j], cmd[i], s - cmd[i]); + av[j][s - cmd[i]] = '\0'; + strcat(av[j], b->str); + strcat(av[j++], s + 2); + while (b != lists[k - 1]) + { + b = b->link; + assert(j < ac); + av[j++] = b->str; + }; + } + } + else if (*cmd[i]) + { + assert(j < ac); + av[j++] = cmd[i]; + } + } + av[j] = NULL; } /* error - issue error msg according to fmt, bump error count */ -static void error(char *fmt, char *msg) { - fprintf(stderr, "%s: ", progname); - fprintf(stderr, fmt, msg); - fprintf(stderr, "\n"); - errcnt++; +static void error(char *fmt, char *msg) +{ + fprintf(stderr, "%s: ", progname); + fprintf(stderr, fmt, msg); + fprintf(stderr, "\n"); + errcnt++; } /* exists - if `name' readable return its path name or return null */ -static char *exists(char *name) { - List b; - - if ( (name[0] == '/' || name[0] == '\\' || name[2] == ':') - && access(name, 4) == 0) - return name; - if (!(name[0] == '/' || name[0] == '\\' || name[2] == ':') - && (b = lccinputs)) - do { - b = b->link; - if (b->str[0]) { - char buf[1024]; - sprintf(buf, "%s/%s", b->str, name); - if (access(buf, 4) == 0) - return strsave(buf); - } else if (access(name, 4) == 0) - return name; - } while (b != lccinputs); - if (verbose > 1) - return name; - return 0; +static char *exists(char *name) +{ + List b; + + if ((name[0] == '/' || name[0] == '\\' || name[2] == ':') && access(name, 4) == 0) + return name; + if (!(name[0] == '/' || name[0] == '\\' || name[2] == ':') && (b = lccinputs)) + do + { + b = b->link; + if (b->str[0]) + { + char buf[1024]; + sprintf(buf, "%s/%s", b->str, name); + if (access(buf, 4) == 0) + return strsave(buf); + } + else if (access(name, 4) == 0) + return name; + } while (b != lccinputs); + if (verbose > 1) + return name; + return 0; } /* first - return first component in semicolon separated list */ -static char *first(char *list) { - char *s = strchr(list, ';'); - - if (s) { - char buf[1024]; - strncpy(buf, list, s-list); - buf[s-list] = '\0'; - return strsave(buf); - } else - return list; +static char *first(char *list) +{ + char *s = strchr(list, ';'); + + if (s) + { + char buf[1024]; + strncpy(buf, list, s - list); + buf[s - list] = '\0'; + return strsave(buf); + } + else + return list; } /* filename - process file name argument `name', return status */ -static int filename(char *name, char *base) { - int status = 0; - static char *stemp, *itemp; - - if (base == 0) - base = basename(name); - switch (suffix(name, suffixes, 4)) { - case 0: /* C source files */ - compose(cpp, plist, append(name, 0), 0); - if (Eflag) { - status = callsys(av); - break; - } - if (itemp == NULL) - itemp = tempname(first(suffixes[1])); - compose(cpp, plist, append(name, 0), append(itemp, 0)); - status = callsys(av); - if (status == 0) - return filename(itemp, base); - break; - case 1: /* preprocessed source files */ - if (Eflag) - break; - if (Sflag) - status = compile(name, outfile ? outfile : concat(base, first(suffixes[2]))); - else if ((status = compile(name, stemp?stemp:(stemp=tempname(first(suffixes[2]))))) == 0) - return filename(stemp, base); - break; - case 2: /* assembly language files */ - if (Eflag) - break; - if (!Sflag) { - char *ofile; - if (cflag && outfile) - ofile = outfile; - else if (cflag) - ofile = concat(base, first(suffixes[3])); - else - ofile = tempname(first(suffixes[3])); - compose(as, alist, append(name, 0), append(ofile, 0)); - status = callsys(av); - if (!find(ofile, llist[1])) - llist[1] = append(ofile, llist[1]); - } - break; - case 3: /* object files */ - if (!find(name, llist[1])) - llist[1] = append(name, llist[1]); - break; - default: - if (Eflag) { - compose(cpp, plist, append(name, 0), 0); - status = callsys(av); - } - llist[1] = append(name, llist[1]); - break; - } - if (status) - errcnt++; - return status; +static int filename(char *name, char *base) +{ + int status = 0; + static char *stemp, *itemp; + + if (base == 0) + base = basename(name); + switch (suffix(name, suffixes, 4)) + { + case 0: /* C source files */ + compose(cpp, plist, append(name, 0), 0); + if (Eflag) + { + status = callsys(av); + break; + } + if (itemp == NULL) + itemp = tempname(first(suffixes[1])); + compose(cpp, plist, append(name, 0), append(itemp, 0)); + status = callsys(av); + if (status == 0) + return filename(itemp, base); + break; + case 1: /* preprocessed source files */ + if (Eflag) + break; + if (Sflag) + status = compile(name, outfile ? outfile : concat(base, first(suffixes[2]))); + else if ((status = compile(name, stemp ? stemp : (stemp = tempname(first(suffixes[2]))))) == 0) + return filename(stemp, base); + break; + case 2: /* assembly language files */ + if (Eflag) + break; + if (!Sflag) + { + char *ofile; + if (cflag && outfile) + ofile = outfile; + else if (cflag) + ofile = concat(base, first(suffixes[3])); + else + ofile = tempname(first(suffixes[3])); + compose(as, alist, append(name, 0), append(ofile, 0)); + status = callsys(av); + if (!find(ofile, llist[1])) + llist[1] = append(ofile, llist[1]); + } + break; + case 3: /* object files */ + if (!find(name, llist[1])) + llist[1] = append(name, llist[1]); + break; + default: + if (Eflag) + { + compose(cpp, plist, append(name, 0), 0); + status = callsys(av); + } + llist[1] = append(name, llist[1]); + break; + } + if (status) + errcnt++; + return status; } /* find - find 1st occurrence of str in list, return list node or 0 */ -static List find(char *str, List list) { - List b; - - if ((b = list)) - do { - if (strcmp(str, b->str) == 0) - return b; - } while ((b = b->link) != list); - return 0; +static List find(char *str, List list) +{ + List b; + + if ((b = list)) + do + { + if (strcmp(str, b->str) == 0) + return b; + } while ((b = b->link) != list); + return 0; } /* help - print help message */ -static void help(void) { - static char *msgs[] = { -"", " [ option | file ]...\n", -" except for -l, options are processed left-to-right before files\n", -" unrecognized options are taken to be linker options\n", -"-A warn about nonANSI usage; 2nd -A warns more\n", -"-b emit expression-level profiling code; see bprint(1)\n", +static void help(void) +{ + static char *msgs[] = {"", " [ option | file ]...\n", + " except for -l, options are processed left-to-right before files\n", + " unrecognized options are taken to be linker options\n", + "-A warn about nonANSI usage; 2nd -A warns more\n", + "-b emit expression-level profiling code; see bprint(1)\n", #ifdef sparc -"-Bstatic -Bdynamic specify static or dynamic libraries\n", + "-Bstatic -Bdynamic specify static or dynamic libraries\n", #endif -"-Bdir/ use the compiler named `dir/rcc'\n", -"-c compile only\n", -"-dn set switch statement density to `n'\n", -"-Dname -Dname=def define the preprocessor symbol `name'\n", -"-E run only the preprocessor on the named C programs and unsuffixed files\n", -"-g produce symbol table information for debuggers\n", -"-help or -? print this message\n", -"-Idir add `dir' to the beginning of the list of #include directories\n", -"-lx search library `x'\n", -"-N do not search the standard directories for #include files\n", -"-n emit code to check for dereferencing zero pointers\n", -"-O is ignored\n", -"-o file leave the output in `file'\n", -"-P print ANSI-style declarations for globals\n", -"-p -pg emit profiling code; see prof(1) and gprof(1)\n", -"-S compile to assembly language\n", + "-Bdir/ use the compiler named `dir/rcc'\n", "-c compile only\n", + "-dn set switch statement density to `n'\n", + "-Dname -Dname=def define the preprocessor symbol `name'\n", + "-E run only the preprocessor on the named C programs and unsuffixed files\n", + "-g produce symbol table information for debuggers\n", "-help or -? print this message\n", + "-Idir add `dir' to the beginning of the list of #include directories\n", "-lx search library `x'\n", + "-N do not search the standard directories for #include files\n", + "-n emit code to check for dereferencing zero pointers\n", "-O is ignored\n", + "-o file leave the output in `file'\n", "-P print ANSI-style declarations for globals\n", + "-p -pg emit profiling code; see prof(1) and gprof(1)\n", "-S compile to assembly language\n", #ifdef linux -"-static specify static libraries (default is dynamic)\n", + "-static specify static libraries (default is dynamic)\n", #endif -"-t -tname emit function tracing calls to printf or to `name'\n", -"-target name is ignored\n", -"-tempdir=dir place temporary files in `dir/'", "\n" -"-Uname undefine the preprocessor symbol `name'\n", -"-v show commands as they are executed; 2nd -v suppresses execution\n", -"-w suppress warnings\n", -"-Woarg specify system-specific `arg'\n", -"-W[pfal]arg pass `arg' to the preprocessor, compiler, assembler, or linker\n", - 0 }; - int i; - char *s; - - msgs[0] = progname; - for (i = 0; msgs[i]; i++) { - fprintf(stderr, "%s", msgs[i]); - if (strncmp("-tempdir", msgs[i], 8) == 0 && tempdir) - fprintf(stderr, "; default=%s", tempdir); - } -#define xx(v) if ((s = getenv(#v))) fprintf(stderr, #v "=%s\n", s) - xx(LCCINPUTS); - xx(LCCDIR); + "-t -tname emit function tracing calls to printf or to `name'\n", "-target name is ignored\n", + "-tempdir=dir place temporary files in `dir/'", + "\n" + "-Uname undefine the preprocessor symbol `name'\n", + "-v show commands as they are executed; 2nd -v suppresses execution\n", "-w suppress warnings\n", + "-Woarg specify system-specific `arg'\n", + "-W[pfal]arg pass `arg' to the preprocessor, compiler, assembler, or linker\n", 0}; + int i; + char *s; + + msgs[0] = progname; + for (i = 0; msgs[i]; i++) + { + fprintf(stderr, "%s", msgs[i]); + if (strncmp("-tempdir", msgs[i], 8) == 0 && tempdir) + fprintf(stderr, "; default=%s", tempdir); + } +#define xx(v) \ + if ((s = getenv(#v))) \ + fprintf(stderr, #v "=%s\n", s) + xx(LCCINPUTS); + xx(LCCDIR); #undef xx } /* initinputs - if LCCINPUTS or include is defined, use them to initialize various lists */ -static void initinputs(void) { - char *s = getenv("LCCINPUTS"); - List b; - - if (s == 0 || (s = inputs)[0] == 0) - s = "."; - if (s) { - lccinputs = path2list(s); - if ((b = lccinputs)) - do { - b = b->link; - if (strcmp(b->str, ".") != 0) { - ilist = append(concat("-I", b->str), ilist); - if (strstr(com[1], "win32") == NULL) - llist[0] = append(concat("-L", b->str), llist[0]); - } else - b->str = ""; - } while (b != lccinputs); - } +static void initinputs(void) +{ + char *s = getenv("LCCINPUTS"); + List b; + + if (s == 0 || (s = inputs)[0] == 0) + s = "."; + if (s) + { + lccinputs = path2list(s); + if ((b = lccinputs)) + do + { + b = b->link; + if (strcmp(b->str, ".") != 0) + { + ilist = append(concat("-I", b->str), ilist); + if (strstr(com[1], "win32") == NULL) + llist[0] = append(concat("-L", b->str), llist[0]); + } + else + b->str = ""; + } while (b != lccinputs); + } } /* interrupt - catch interrupt signals */ -static void interrupt(int n) { - rm(rmlist); - exit(n = 100); +static void interrupt(int n) +{ + rm(rmlist); + exit(n = 100); } /* opt - process option in arg */ -static void opt(char *arg) { - switch (arg[1]) { /* multi-character options */ - case 'W': /* -Wxarg */ - if (arg[2] && arg[3]) - switch (arg[2]) { - case 'o': - if (option(&arg[3])) - return; - break; - case 'p': - plist = append(&arg[3], plist); - return; - case 'f': - if (strcmp(&arg[3], "-C") || option("-b")) { - clist = append(&arg[3], clist); - return; - } - break; /* and fall thru */ - case 'a': - alist = append(&arg[3], alist); - return; - case 'l': - llist[0] = append(&arg[3], llist[0]); - return; - } - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - case 'd': /* -dn */ - arg[1] = 's'; - clist = append(arg, clist); - return; - case 't': /* -t -tname -tempdir=dir */ - if (strncmp(arg, "-tempdir=", 9) == 0) - tempdir = arg + 9; - else - clist = append(arg, clist); - return; - case 'p': /* -p -pg */ - if (option(arg)) - clist = append(arg, clist); - else - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - case 'D': /* -Dname -Dname=def */ - case 'U': /* -Uname */ - case 'I': /* -Idir */ - plist = append(arg, plist); - return; - case 'B': /* -Bdir -Bstatic -Bdynamic */ +static void opt(char *arg) +{ + switch (arg[1]) + { /* multi-character options */ + case 'W': /* -Wxarg */ + if (arg[2] && arg[3]) + switch (arg[2]) + { + case 'o': + if (option(&arg[3])) + return; + break; + case 'p': + plist = append(&arg[3], plist); + return; + case 'f': + if (strcmp(&arg[3], "-C") || option("-b")) + { + clist = append(&arg[3], clist); + return; + } + break; /* and fall thru */ + case 'a': + alist = append(&arg[3], alist); + return; + case 'l': + llist[0] = append(&arg[3], llist[0]); + return; + } + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + case 'd': /* -dn */ + arg[1] = 's'; + clist = append(arg, clist); + return; + case 't': /* -t -tname -tempdir=dir */ + if (strncmp(arg, "-tempdir=", 9) == 0) + tempdir = arg + 9; + else + clist = append(arg, clist); + return; + case 'p': /* -p -pg */ + if (option(arg)) + clist = append(arg, clist); + else + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + case 'D': /* -Dname -Dname=def */ + case 'U': /* -Uname */ + case 'I': /* -Idir */ + plist = append(arg, plist); + return; + case 'B': /* -Bdir -Bstatic -Bdynamic */ #ifdef sparc - if (strcmp(arg, "-Bstatic") == 0 || strcmp(arg, "-Bdynamic") == 0) - llist[1] = append(arg, llist[1]); - else -#endif - { - static char *path; - if (path) - error("-B overwrites earlier option", 0); - path = arg + 2; - if (strstr(com[1], "win32") != NULL) - com[0] = concat(replace(path, '/', '\\'), concat("rcc", first(suffixes[4]))); - else - com[0] = concat(path, "rcc"); - if (path[0] == 0) - error("missing directory in -B option", 0); - } - return; - case 'h': - if (strcmp(arg, "-help") == 0) { - static int printed = 0; - case '?': - if (!printed) - help(); - printed = 1; - return; - } + if (strcmp(arg, "-Bstatic") == 0 || strcmp(arg, "-Bdynamic") == 0) + llist[1] = append(arg, llist[1]); + else +#endif + { + static char *path; + if (path) + error("-B overwrites earlier option", 0); + path = arg + 2; + if (strstr(com[1], "win32") != NULL) + com[0] = concat(replace(path, '/', '\\'), concat("rcc", first(suffixes[4]))); + else + com[0] = concat(path, "rcc"); + if (path[0] == 0) + error("missing directory in -B option", 0); + } + return; + case 'h': + if (strcmp(arg, "-help") == 0) + { + static int printed = 0; + case '?': + if (!printed) + help(); + printed = 1; + return; + } #ifdef linux - case 's': - if (strcmp(arg,"-static") == 0) { - if (!option(arg)) - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - } -#endif - } - if (arg[2] == 0) - switch (arg[1]) { /* single-character options */ - case 'S': - Sflag++; - return; - case 'O': - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - case 'A': case 'n': case 'w': case 'P': - clist = append(arg, clist); - return; - case 'g': case 'b': - if (option(arg)) - clist = append(arg[1] == 'g' ? "-g2" : arg, clist); - else - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - case 'G': - if (option(arg)) { - clist = append("-g3", clist); - llist[0] = append("-N", llist[0]); - } else - fprintf(stderr, "%s: %s ignored\n", progname, arg); - return; - case 'E': - Eflag++; - return; - case 'c': - cflag++; - return; - case 'N': - if (strcmp(basename(cpp[0]), "gcc-cpp") == 0) - plist = append("-nostdinc", plist); - include[0] = 0; - ilist = 0; - return; - case 'v': - if (verbose++ == 0) { - if (strcmp(basename(cpp[0]), "gcc-cpp") == 0) - plist = append(arg, plist); - clist = append(arg, clist); - fprintf(stderr, "%s %s\n", progname, rcsid); - } - return; - } - if (cflag || Sflag || Eflag) - fprintf(stderr, "%s: %s ignored\n", progname, arg); - else - llist[1] = append(arg, llist[1]); + case 's': + if (strcmp(arg, "-static") == 0) + { + if (!option(arg)) + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + } +#endif + } + if (arg[2] == 0) + switch (arg[1]) + { /* single-character options */ + case 'S': + Sflag++; + return; + case 'O': + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + case 'A': + case 'n': + case 'w': + case 'P': + clist = append(arg, clist); + return; + case 'g': + case 'b': + if (option(arg)) + clist = append(arg[1] == 'g' ? "-g2" : arg, clist); + else + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + case 'G': + if (option(arg)) + { + clist = append("-g3", clist); + llist[0] = append("-N", llist[0]); + } + else + fprintf(stderr, "%s: %s ignored\n", progname, arg); + return; + case 'E': + Eflag++; + return; + case 'c': + cflag++; + return; + case 'N': + if (strcmp(basename(cpp[0]), "gcc-cpp") == 0) + plist = append("-nostdinc", plist); + include[0] = 0; + ilist = 0; + return; + case 'v': + if (verbose++ == 0) + { + if (strcmp(basename(cpp[0]), "gcc-cpp") == 0) + plist = append(arg, plist); + clist = append(arg, clist); + fprintf(stderr, "%s %s\n", progname, rcsid); + } + return; + } + if (cflag || Sflag || Eflag) + fprintf(stderr, "%s: %s ignored\n", progname, arg); + else + llist[1] = append(arg, llist[1]); } /* path2list - convert a colon- or semicolon-separated list to a list */ -static List path2list(const char *path) { - List list = NULL; - char sep = ':'; - - if (path == NULL) - return NULL; - if (strchr(path, ';')) - sep = ';'; - while (*path) { - char *p, buf[512]; - if ((p = strchr(path, sep))) { - assert(p - path < sizeof buf); - strncpy(buf, path, p - path); - buf[p-path] = '\0'; - } else { - assert(strlen(path) < sizeof buf); - strcpy(buf, path); - } - if (!find(buf, list)) - list = append(strsave(buf), list); - if (p == 0) - break; - path = p + 1; - } - return list; +static List path2list(const char *path) +{ + List list = NULL; + char sep = ':'; + + if (path == NULL) + return NULL; + if (strchr(path, ';')) + sep = ';'; + while (*path) + { + char *p, buf[512]; + if ((p = strchr(path, sep))) + { + assert(p - path < sizeof buf); + strncpy(buf, path, p - path); + buf[p - path] = '\0'; + } + else + { + assert(strlen(path) < sizeof buf); + strcpy(buf, path); + } + if (!find(buf, list)) + list = append(strsave(buf), list); + if (p == 0) + break; + path = p + 1; + } + return list; } /* replace - copy str, then replace occurrences of from with to, return the copy */ -char *replace(const char *str, int from, int to) { - char *s = strsave(str), *p = s; +char *replace(const char *str, int from, int to) +{ + char *s = strsave(str), *p = s; - for ( ; (p = strchr(p, from)) != NULL; p++) - *p = to; - return s; + for (; (p = strchr(p, from)) != NULL; p++) + *p = to; + return s; } /* rm - remove files in list */ -static void rm(List list) { - if (list) { - List b = list; - if (verbose) - fprintf(stderr, "rm"); - do { - if (verbose) - fprintf(stderr, " %s", b->str); - if (verbose < 2) - remove(b->str); - } while ((b = b->link) != list); - if (verbose) - fprintf(stderr, "\n"); - } +static void rm(List list) +{ + if (list) + { + List b = list; + if (verbose) + fprintf(stderr, "rm"); + do + { + if (verbose) + fprintf(stderr, " %s", b->str); + if (verbose < 2) + remove(b->str); + } while ((b = b->link) != list); + if (verbose) + fprintf(stderr, "\n"); + } } /* strsave - return a saved copy of string str */ -char *strsave(const char *str) { - return strcpy(alloc(strlen(str)+1), str); -} +char *strsave(const char *str) { return strcpy(alloc(strlen(str) + 1), str); } /* stringf - format and return a string */ -char *stringf(const char *fmt, ...) { - char buf[1024]; - va_list ap; - - va_start(ap, fmt); - vsprintf(buf, fmt, ap); - va_end(ap); - return strsave(buf); +char *stringf(const char *fmt, ...) +{ + char buf[1024]; + va_list ap; + + va_start(ap, fmt); + vsprintf(buf, fmt, ap); + va_end(ap); + return strsave(buf); } /* suffix - if one of tails[0..n-1] holds a proper suffix of name, return its index */ -int suffix(char *name, char *tails[], int n) { - int i, len = strlen(name); - - for (i = 0; i < n; i++) { - char *s = tails[i], *t; - for ( ; (t = strchr(s, ';')); s = t + 1) { - int m = t - s; - if (len > m && strncmp(&name[len-m], s, m) == 0) - return i; - } - if (*s) { - int m = strlen(s); - if (len > m && strncmp(&name[len-m], s, m) == 0) - return i; - } - } - return -1; +int suffix(char *name, char *tails[], int n) +{ + int i, len = strlen(name); + + for (i = 0; i < n; i++) + { + char *s = tails[i], *t; + for (; (t = strchr(s, ';')); s = t + 1) + { + int m = t - s; + if (len > m && strncmp(&name[len - m], s, m) == 0) + return i; + } + if (*s) + { + int m = strlen(s); + if (len > m && strncmp(&name[len - m], s, m) == 0) + return i; + } + } + return -1; } /* tempname - generate a temporary file name in tempdir with given suffix */ -char *tempname(char *suffix) { - static int n; - char *name = stringf("%s/lcc%d%d%s", tempdir, getpid(), n++, suffix); - - if (strstr(com[1], "win32") != NULL) - name = replace(name, '/', '\\'); - rmlist = append(name, rmlist); - return name; +char *tempname(char *suffix) +{ + static int n; + char *name = stringf("%s/lcc%d%d%s", tempdir, getpid(), n++, suffix); + + if (strstr(com[1], "win32") != NULL) + name = replace(name, '/', '\\'); + rmlist = append(name, rmlist); + return name; } diff --git a/src/tools/lcc/lburg/gram.c b/src/tools/lcc/lburg/gram.c index f6ee9f9..94fd3b3 100644 --- a/src/tools/lcc/lburg/gram.c +++ b/src/tools/lcc/lburg/gram.c @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.0.2. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.4" +#define YYBISON_VERSION "3.0.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -62,11 +62,11 @@ /* Copy the first part of user declarations. */ -#line 1 "src/tools/lcc/lburg/gram.y" /* yacc.c:339 */ +#line 1 "code/tools/lcc/lburg/gram.y" /* yacc.c:339 */ #include #include "lburg.h" -static char rcsid[] = "$Id: gram.y 145 2001-10-17 21:53:10Z timo $"; +//static char rcsid[] = "$Id: gram.y 145 2001-10-17 21:53:10Z timo $"; /*lint -e616 -e527 -e652 -esym(552,yynerrs) -esym(563,yynewstate,yyerrlab) */ static int yylineno = 0; @@ -122,10 +122,10 @@ extern int yydebug; /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - +typedef union YYSTYPE YYSTYPE; union YYSTYPE { -#line 8 "src/tools/lcc/lburg/gram.y" /* yacc.c:355 */ +#line 8 "code/tools/lcc/lburg/gram.y" /* yacc.c:355 */ int n; char *string; @@ -133,8 +133,6 @@ union YYSTYPE #line 135 "y.tab.c" /* yacc.c:355 */ }; - -typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif @@ -143,12 +141,13 @@ typedef union YYSTYPE YYSTYPE; extern YYSTYPE yylval; int yyparse (void); +int yylex(void); /* Copy the second part of user declarations. */ -#line 152 "y.tab.c" /* yacc.c:358 */ +#line 150 "y.tab.c" /* yacc.c:358 */ #ifdef short # undef short @@ -1236,82 +1235,82 @@ yyreduce: switch (yyn) { case 2: -#line 22 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 22 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { yylineno = 0; } -#line 1242 "y.tab.c" /* yacc.c:1646 */ +#line 1240 "y.tab.c" /* yacc.c:1646 */ break; case 3: -#line 23 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 23 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { yylineno = 0; } -#line 1248 "y.tab.c" /* yacc.c:1646 */ +#line 1246 "y.tab.c" /* yacc.c:1646 */ break; case 7: -#line 31 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 31 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { if (nonterm((yyvsp[-1].string))->number != 1) yyerror("redeclaration of the start symbol\n"); } -#line 1257 "y.tab.c" /* yacc.c:1646 */ +#line 1255 "y.tab.c" /* yacc.c:1646 */ break; case 9: -#line 36 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 36 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { yyerrok; } -#line 1263 "y.tab.c" /* yacc.c:1646 */ +#line 1261 "y.tab.c" /* yacc.c:1646 */ break; case 11: -#line 40 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 40 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { term((yyvsp[-2].string), (yyvsp[0].n)); } -#line 1269 "y.tab.c" /* yacc.c:1646 */ +#line 1267 "y.tab.c" /* yacc.c:1646 */ break; case 13: -#line 44 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 44 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { rule((yyvsp[-5].string), (yyvsp[-3].tree), (yyvsp[-2].string), (yyvsp[-1].string)); } -#line 1275 "y.tab.c" /* yacc.c:1646 */ +#line 1273 "y.tab.c" /* yacc.c:1646 */ break; case 15: -#line 46 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 46 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { yyerrok; } -#line 1281 "y.tab.c" /* yacc.c:1646 */ +#line 1279 "y.tab.c" /* yacc.c:1646 */ break; case 16: -#line 49 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 49 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { nonterm((yyval.string) = (yyvsp[0].string)); } -#line 1287 "y.tab.c" /* yacc.c:1646 */ +#line 1285 "y.tab.c" /* yacc.c:1646 */ break; case 17: -#line 52 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 52 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { (yyval.tree) = tree((yyvsp[0].string), 0, 0); } -#line 1293 "y.tab.c" /* yacc.c:1646 */ +#line 1291 "y.tab.c" /* yacc.c:1646 */ break; case 18: -#line 53 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 53 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { (yyval.tree) = tree((yyvsp[-3].string), (yyvsp[-1].tree), 0); } -#line 1299 "y.tab.c" /* yacc.c:1646 */ +#line 1297 "y.tab.c" /* yacc.c:1646 */ break; case 19: -#line 54 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 54 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { (yyval.tree) = tree((yyvsp[-5].string), (yyvsp[-3].tree), (yyvsp[-1].tree)); } -#line 1305 "y.tab.c" /* yacc.c:1646 */ +#line 1303 "y.tab.c" /* yacc.c:1646 */ break; case 20: -#line 57 "src/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ +#line 57 "code/tools/lcc/lburg/gram.y" /* yacc.c:1646 */ { if (*(yyvsp[0].string) == 0) (yyval.string) = "0"; } -#line 1311 "y.tab.c" /* yacc.c:1646 */ +#line 1309 "y.tab.c" /* yacc.c:1646 */ break; -#line 1315 "y.tab.c" /* yacc.c:1646 */ +#line 1313 "y.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1539,7 +1538,7 @@ yyreturn: #endif return yyresult; } -#line 59 "src/tools/lcc/lburg/gram.y" /* yacc.c:1906 */ +#line 59 "code/tools/lcc/lburg/gram.y" /* yacc.c:1906 */ #include #include @@ -1683,4 +1682,5 @@ void yywarn(char *fmt, ...) { fprintf(stderr, "line %d: ", yylineno); fprintf(stderr, "warning: "); vfprintf(stderr, fmt, ap); + va_end(ap); } diff --git a/src/tools/lcc/lburg/gram.y b/src/tools/lcc/lburg/gram.y index 1ecd8a9..c0a9c94 100644 --- a/src/tools/lcc/lburg/gram.y +++ b/src/tools/lcc/lburg/gram.y @@ -199,4 +199,5 @@ void yywarn(char *fmt, ...) { fprintf(stderr, "line %d: ", yylineno); fprintf(stderr, "warning: "); vfprintf(stderr, fmt, ap); + va_end(ap); } diff --git a/src/tools/lcc/src/dag.c b/src/tools/lcc/src/dag.c index 420cbe7..ad0ea1c 100644 --- a/src/tools/lcc/src/dag.c +++ b/src/tools/lcc/src/dag.c @@ -1,15 +1,13 @@ #include "c.h" - -#define iscall(op) (generic(op) == CALL \ - || (IR->mulops_calls \ - && (generic(op)==DIV||generic(op)==MOD||generic(op)==MUL) \ - && ( optype(op)==U || optype(op)==I))) +#define iscall(op) \ + (generic(op) == CALL || (IR->mulops_calls && (generic(op) == DIV || generic(op) == MOD || generic(op) == MUL) && \ + (optype(op) == U || optype(op) == I))) static Node forest; static struct dag { - struct node node; - struct dag *hlink; -} *buckets[16]; + struct node node; + struct dag *hlink; +} * buckets[16]; int nodecount; static Tree firstarg; int assignargs = 1; @@ -35,702 +33,884 @@ static void typestab(Symbol, void *); static Node undag(Node); static Node visit(Node, int); static void unlist(void); -void walk(Tree tp, int tlab, int flab) { - listnodes(tp, tlab, flab); - if (forest) { - Node list = forest->link; - forest->link = NULL; - if (!IR->wants_dag) - list = undag(list); - code(Gen)->u.forest = list; - forest = NULL; - } - reset(); - deallocate(STMT); +void walk(Tree tp, int tlab, int flab) +{ + listnodes(tp, tlab, flab); + if (forest) + { + Node list = forest->link; + forest->link = NULL; + if (!IR->wants_dag) list = undag(list); + code(Gen)->u.forest = list; + forest = NULL; + } + reset(); + deallocate(STMT); } -static Node node(int op, Node l, Node r, Symbol sym) { - int i; - struct dag *p; +static Node node(int op, Node l, Node r, Symbol sym) +{ + int i; + struct dag *p; - i = (opindex(op)^((unsigned long)sym>>2))&(NELEMS(buckets)-1); - for (p = buckets[i]; p; p = p->hlink) - if (p->node.op == op && p->node.syms[0] == sym - && p->node.kids[0] == l && p->node.kids[1] == r) - return &p->node; - p = dagnode(op, l, r, sym); - p->hlink = buckets[i]; - buckets[i] = p; - ++nodecount; - return &p->node; + i = (opindex(op) ^ ((unsigned long)sym >> 2)) & (NELEMS(buckets) - 1); + for (p = buckets[i]; p; p = p->hlink) + if (p->node.op == op && p->node.syms[0] == sym && p->node.kids[0] == l && p->node.kids[1] == r) return &p->node; + p = dagnode(op, l, r, sym); + p->hlink = buckets[i]; + buckets[i] = p; + ++nodecount; + return &p->node; } -static struct dag *dagnode(int op, Node l, Node r, Symbol sym) { - struct dag *p; - NEW0(p, FUNC); - p->node.op = op; - if ((p->node.kids[0] = l) != NULL) - ++l->count; - if ((p->node.kids[1] = r) != NULL) - ++r->count; - p->node.syms[0] = sym; - return p; +static Node constnode(int op, Symbol sym) +{ + struct dag *p; + p = dagnode(op, NULL, NULL, sym); + ++nodecount; + return &p->node; } -Node newnode(int op, Node l, Node r, Symbol sym) { - return &dagnode(op, l, r, sym)->node; + +static struct dag *dagnode(int op, Node l, Node r, Symbol sym) +{ + struct dag *p; + + NEW0(p, FUNC); + p->node.op = op; + if ((p->node.kids[0] = l) != NULL) ++l->count; + if ((p->node.kids[1] = r) != NULL) ++r->count; + p->node.syms[0] = sym; + return p; } -static void kill(Symbol p) { - int i; - struct dag **q; +Node newnode(int op, Node l, Node r, Symbol sym) { return &dagnode(op, l, r, sym)->node; } +static void kill(Symbol p) +{ + int i; + struct dag **q; - for (i = 0; i < NELEMS(buckets); i++) - for (q = &buckets[i]; *q; ) - if (generic((*q)->node.op) == INDIR && - (!isaddrop((*q)->node.kids[0]->op) - || (*q)->node.kids[0]->syms[0] == p)) { - *q = (*q)->hlink; - --nodecount; - } else - q = &(*q)->hlink; + for (i = 0; i < NELEMS(buckets); i++) + for (q = &buckets[i]; *q;) + if (generic((*q)->node.op) == INDIR && + (!isaddrop((*q)->node.kids[0]->op) || (*q)->node.kids[0]->syms[0] == p)) + { + *q = (*q)->hlink; + --nodecount; + } + else + q = &(*q)->hlink; } -static void reset(void) { - if (nodecount > 0) - memset(buckets, 0, sizeof buckets); - nodecount = 0; +static void reset(void) +{ + if (nodecount > 0) memset(buckets, 0, sizeof buckets); + nodecount = 0; } -Node listnodes(Tree tp, int tlab, int flab) { - Node p = NULL, l, r; - int op; +Node listnodes(Tree tp, int tlab, int flab) +{ + Node p = NULL, l, r; + int op; - assert(tlab || flab || (tlab == 0 && flab == 0)); - if (tp == NULL) - return NULL; - if (tp->node) - return tp->node; - op = tp->op + sizeop(tp->type->size); - switch (generic(tp->op)) { - case AND: { if (depth++ == 0) reset(); - if (flab) { - listnodes(tp->kids[0], 0, flab); - listnodes(tp->kids[1], 0, flab); - } else { - listnodes(tp->kids[0], 0, flab = genlabel(1)); - listnodes(tp->kids[1], tlab, 0); - labelnode(flab); - } - depth--; } break; - case OR: { if (depth++ == 0) - reset(); - if (tlab) { - listnodes(tp->kids[0], tlab, 0); - listnodes(tp->kids[1], tlab, 0); - } else { - tlab = genlabel(1); - listnodes(tp->kids[0], tlab, 0); - listnodes(tp->kids[1], 0, flab); - labelnode(tlab); - } - depth--; - } break; - case NOT: { return listnodes(tp->kids[0], flab, tlab); } - case COND: { Tree q = tp->kids[1]; - assert(tlab == 0 && flab == 0); - if (tp->u.sym) - addlocal(tp->u.sym); - flab = genlabel(2); - listnodes(tp->kids[0], 0, flab); - assert(q && q->op == RIGHT); - reset(); - listnodes(q->kids[0], 0, 0); - if (forest->op == LABEL+V) { - equatelab(forest->syms[0], findlabel(flab + 1)); - unlist(); - } - list(jump(flab + 1)); - labelnode(flab); - listnodes(q->kids[1], 0, 0); - if (forest->op == LABEL+V) { - equatelab(forest->syms[0], findlabel(flab + 1)); - unlist(); - } - labelnode(flab + 1); + assert(tlab || flab || (tlab == 0 && flab == 0)); + if (tp == NULL) return NULL; + if (tp->node) return tp->node; + op = tp->op + sizeop(tp->type->size); + switch (generic(tp->op)) + { + case AND: + { + if (depth++ == 0) reset(); + if (flab) + { + listnodes(tp->kids[0], 0, flab); + listnodes(tp->kids[1], 0, flab); + } + else + { + listnodes(tp->kids[0], 0, flab = genlabel(1)); + listnodes(tp->kids[1], tlab, 0); + labelnode(flab); + } + depth--; + } + break; + case OR: + { + if (depth++ == 0) reset(); + if (tlab) + { + listnodes(tp->kids[0], tlab, 0); + listnodes(tp->kids[1], tlab, 0); + } + else + { + tlab = genlabel(1); + listnodes(tp->kids[0], tlab, 0); + listnodes(tp->kids[1], 0, flab); + labelnode(tlab); + } + depth--; + } + break; + case NOT: + { + return listnodes(tp->kids[0], flab, tlab); + } + case COND: + { + Tree q = tp->kids[1]; + assert(tlab == 0 && flab == 0); + if (tp->u.sym) addlocal(tp->u.sym); + flab = genlabel(2); + listnodes(tp->kids[0], 0, flab); + assert(q && q->op == RIGHT); + reset(); + listnodes(q->kids[0], 0, 0); + if (forest->op == LABEL + V) + { + equatelab(forest->syms[0], findlabel(flab + 1)); + unlist(); + } + list(jump(flab + 1)); + labelnode(flab); + listnodes(q->kids[1], 0, 0); + if (forest->op == LABEL + V) + { + equatelab(forest->syms[0], findlabel(flab + 1)); + unlist(); + } + labelnode(flab + 1); - if (tp->u.sym) - p = listnodes(idtree(tp->u.sym), 0, 0); } break; - case CNST: { Type ty = unqual(tp->type); - assert(ty->u.sym); - if (tlab || flab) { - assert(ty == inttype); - if (tlab && tp->u.v.i != 0) - list(jump(tlab)); - else if (flab && tp->u.v.i == 0) - list(jump(flab)); - } - else if (ty->u.sym->addressed) - p = listnodes(cvtconst(tp), 0, 0); - else - p = node(op, NULL, NULL, constant(ty, tp->u.v)); } break; - case RIGHT: { if ( tp->kids[0] && tp->kids[1] - && generic(tp->kids[1]->op) == ASGN - && ((generic(tp->kids[0]->op) == INDIR - && tp->kids[0]->kids[0] == tp->kids[1]->kids[0]) - || (tp->kids[0]->op == FIELD - && tp->kids[0] == tp->kids[1]->kids[0]))) { - assert(tlab == 0 && flab == 0); - if (generic(tp->kids[0]->op) == INDIR) { - p = listnodes(tp->kids[0], 0, 0); - list(p); - listnodes(tp->kids[1], 0, 0); - } - else { - assert(generic(tp->kids[0]->kids[0]->op) == INDIR); - list(listnodes(tp->kids[0]->kids[0], 0, 0)); - p = listnodes(tp->kids[0], 0, 0); - listnodes(tp->kids[1], 0, 0); - } - } else if (tp->kids[1]) { - listnodes(tp->kids[0], 0, 0); - p = listnodes(tp->kids[1], tlab, flab); - } else - p = listnodes(tp->kids[0], tlab, flab); } break; - case JUMP: { assert(tlab == 0 && flab == 0); - assert(tp->u.sym == 0); - assert(tp->kids[0]); - l = listnodes(tp->kids[0], 0, 0); - list(newnode(JUMP+V, l, NULL, NULL)); - reset(); } break; - case CALL: { Tree save = firstarg; - firstarg = NULL; - assert(tlab == 0 && flab == 0); - if (tp->op == CALL+B && !IR->wants_callb) { - Tree arg0 = tree(ARG+P, tp->kids[1]->type, - tp->kids[1], NULL); - if (IR->left_to_right) - firstarg = arg0; - l = listnodes(tp->kids[0], 0, 0); - if (!IR->left_to_right || firstarg) { - firstarg = NULL; - listnodes(arg0, 0, 0); - } - p = newnode(CALL+V, l, NULL, NULL); - } else { - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - p = newnode(tp->op == CALL+B ? tp->op : op, l, r, NULL); - } - NEW0(p->syms[0], FUNC); - assert(isptr(tp->kids[0]->type)); - assert(isfunc(tp->kids[0]->type->type)); - p->syms[0]->type = tp->kids[0]->type->type; - list(p); - reset(); - cfunc->u.f.ncalls++; - firstarg = save; - } break; - case ARG: { assert(tlab == 0 && flab == 0); - if (IR->left_to_right) - listnodes(tp->kids[1], 0, 0); - if (firstarg) { - Tree arg = firstarg; - firstarg = NULL; - listnodes(arg, 0, 0); - } - l = listnodes(tp->kids[0], 0, 0); - list(newnode(tp->op == ARG+B ? tp->op : op, l, NULL, NULL)); - forest->syms[0] = intconst(tp->type->size); - forest->syms[1] = intconst(tp->type->align); - if (!IR->left_to_right) - listnodes(tp->kids[1], 0, 0); } break; - case EQ: case NE: case GT: case GE: case LE: - case LT: { assert(tp->u.sym == 0); - assert(errcnt || tlab || flab); - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - assert(errcnt || opkind(l->op) == opkind(r->op)); - assert(errcnt || optype(op) == optype(l->op)); - if (tlab) - assert(flab == 0), - list(newnode(generic(tp->op) + opkind(l->op), l, r, findlabel(tlab))); - else if (flab) { - switch (generic(tp->op)) { - case EQ: op = NE; break; - case NE: op = EQ; break; - case GT: op = LE; break; - case LT: op = GE; break; - case GE: op = LT; break; - case LE: op = GT; break; - default: assert(0); - } - list(newnode(op + opkind(l->op), l, r, findlabel(flab))); - } - if (forest && forest->syms[0]) - forest->syms[0]->ref++; } break; - case ASGN: { assert(tlab == 0 && flab == 0); - if (tp->kids[0]->op == FIELD) { - Tree x = tp->kids[0]->kids[0]; - Field f = tp->kids[0]->u.field; - assert(generic(x->op) == INDIR); - reset(); - l = listnodes(lvalue(x), 0, 0); - if (fieldsize(f) < 8*f->type->size) { - unsigned int fmask = fieldmask(f); - unsigned int mask = fmask<kids[1]; - if ((q->op == CNST+I && q->u.v.i == 0) - || (q->op == CNST+U && q->u.v.u == 0)) - q = bittree(BAND, x, cnsttree(unsignedtype, (unsigned long)~mask)); - else if ((q->op == CNST+I && (q->u.v.i&fmask) == fmask) - || (q->op == CNST+U && (q->u.v.u&fmask) == fmask)) - q = bittree(BOR, x, cnsttree(unsignedtype, (unsigned long)mask)); - else { - listnodes(q, 0, 0); - q = bittree(BOR, - bittree(BAND, rvalue(lvalue(x)), - cnsttree(unsignedtype, (unsigned long)~mask)), - bittree(BAND, shtree(LSH, cast(q, unsignedtype), - cnsttree(unsignedtype, (unsigned long)fieldright(f))), - cnsttree(unsignedtype, (unsigned long)mask))); - } - r = listnodes(q, 0, 0); - op = ASGN + ttob(q->type); - } else { - r = listnodes(tp->kids[1], 0, 0); - op = ASGN + ttob(tp->kids[1]->type); - } - } else { - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - } - list(newnode(tp->op == ASGN+B ? tp->op : op, l, r, NULL)); - forest->syms[0] = intconst(tp->kids[1]->type->size); - forest->syms[1] = intconst(tp->kids[1]->type->align); - if (isaddrop(tp->kids[0]->op) - && !tp->kids[0]->u.sym->computed) - kill(tp->kids[0]->u.sym); - else - reset(); - p = listnodes(tp->kids[1], 0, 0); } break; - case BOR: case BAND: case BXOR: - case ADD: case SUB: case RSH: - case LSH: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - p = node(op, l, r, NULL); } break; - case DIV: case MUL: - case MOD: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - p = node(op, l, r, NULL); - if (IR->mulops_calls && isint(tp->type)) { - list(p); - cfunc->u.f.ncalls++; - } } break; - case RET: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - list(newnode(op, l, NULL, NULL)); } break; - case CVF: case CVI: case CVP: - case CVU: { assert(tlab == 0 && flab == 0); - assert(optype(tp->kids[0]->op) != optype(tp->op) || tp->kids[0]->type->size != tp->type->size); - l = listnodes(tp->kids[0], 0, 0); - p = node(op, l, NULL, intconst(tp->kids[0]->type->size)); - } break; - case BCOM: - case NEG: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - p = node(op, l, NULL, NULL); } break; - case INDIR: { Type ty = tp->kids[0]->type; - assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - if (isptr(ty)) - ty = unqual(ty)->type; - if (isvolatile(ty) - || (isstruct(ty) && unqual(ty)->u.sym->u.s.vfields)) - p = newnode(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL); - else - p = node(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL); } break; - case FIELD: { Tree q = tp->kids[0]; - if (tp->type == inttype) { - long n = fieldleft(tp->u.field); - q = shtree(RSH, - shtree(LSH, q, cnsttree(inttype, n)), - cnsttree(inttype, n + fieldright(tp->u.field))); - } else if (fieldsize(tp->u.field) < 8*tp->u.field->type->size) - q = bittree(BAND, - shtree(RSH, q, cnsttree(inttype, (long)fieldright(tp->u.field))), - cnsttree(unsignedtype, (unsigned long)fieldmask(tp->u.field))); - assert(tlab == 0 && flab == 0); - p = listnodes(q, 0, 0); } break; - case ADDRG: - case ADDRF: { assert(tlab == 0 && flab == 0); - p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym); - } break; - case ADDRL: { assert(tlab == 0 && flab == 0); - if (tp->u.sym->temporary) - addlocal(tp->u.sym); - p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym); } break; - default:assert(0); - } - tp->node = p; - return p; + if (tp->u.sym) p = listnodes(idtree(tp->u.sym), 0, 0); + } + break; + case CNST: + { + Type ty = unqual(tp->type); + assert(ty->u.sym); + if (tlab || flab) + { + assert(ty == inttype); + if (tlab && tp->u.v.i != 0) + list(jump(tlab)); + else if (flab && tp->u.v.i == 0) + list(jump(flab)); + } + else if (ty->u.sym->addressed) + p = listnodes(cvtconst(tp), 0, 0); + else + /* always generate new node for constants */ + if (isscalar(ty)) + p = constnode(op, constant(ty, tp->u.v)); + else + p = node(op, NULL, NULL, constant(ty, tp->u.v)); + } + break; + case RIGHT: + { + if (tp->kids[0] && tp->kids[1] && generic(tp->kids[1]->op) == ASGN && + ((generic(tp->kids[0]->op) == INDIR && tp->kids[0]->kids[0] == tp->kids[1]->kids[0]) || + (tp->kids[0]->op == FIELD && tp->kids[0] == tp->kids[1]->kids[0]))) + { + assert(tlab == 0 && flab == 0); + if (generic(tp->kids[0]->op) == INDIR) + { + p = listnodes(tp->kids[0], 0, 0); + list(p); + listnodes(tp->kids[1], 0, 0); + } + else + { + assert(generic(tp->kids[0]->kids[0]->op) == INDIR); + list(listnodes(tp->kids[0]->kids[0], 0, 0)); + p = listnodes(tp->kids[0], 0, 0); + listnodes(tp->kids[1], 0, 0); + } + } + else if (tp->kids[1]) + { + listnodes(tp->kids[0], 0, 0); + p = listnodes(tp->kids[1], tlab, flab); + } + else + p = listnodes(tp->kids[0], tlab, flab); + } + break; + case JUMP: + { + assert(tlab == 0 && flab == 0); + assert(tp->u.sym == 0); + assert(tp->kids[0]); + l = listnodes(tp->kids[0], 0, 0); + list(newnode(JUMP + V, l, NULL, NULL)); + reset(); + } + break; + case CALL: + { + Tree save = firstarg; + firstarg = NULL; + assert(tlab == 0 && flab == 0); + if (tp->op == CALL + B && !IR->wants_callb) + { + Tree arg0 = tree(ARG + P, tp->kids[1]->type, tp->kids[1], NULL); + if (IR->left_to_right) firstarg = arg0; + l = listnodes(tp->kids[0], 0, 0); + if (!IR->left_to_right || firstarg) + { + firstarg = NULL; + listnodes(arg0, 0, 0); + } + p = newnode(CALL + V, l, NULL, NULL); + } + else + { + l = listnodes(tp->kids[0], 0, 0); + r = listnodes(tp->kids[1], 0, 0); + p = newnode(tp->op == CALL + B ? tp->op : op, l, r, NULL); + } + NEW0(p->syms[0], FUNC); + assert(isptr(tp->kids[0]->type)); + assert(isfunc(tp->kids[0]->type->type)); + p->syms[0]->type = tp->kids[0]->type->type; + list(p); + reset(); + cfunc->u.f.ncalls++; + firstarg = save; + } + break; + case ARG: + { + assert(tlab == 0 && flab == 0); + if (IR->left_to_right) listnodes(tp->kids[1], 0, 0); + if (firstarg) + { + Tree arg = firstarg; + firstarg = NULL; + listnodes(arg, 0, 0); + } + l = listnodes(tp->kids[0], 0, 0); + list(newnode(tp->op == ARG + B ? tp->op : op, l, NULL, NULL)); + forest->syms[0] = intconst(tp->type->size); + forest->syms[1] = intconst(tp->type->align); + if (!IR->left_to_right) listnodes(tp->kids[1], 0, 0); + } + break; + case EQ: + case NE: + case GT: + case GE: + case LE: + case LT: + { + assert(tp->u.sym == 0); + assert(errcnt || tlab || flab); + l = listnodes(tp->kids[0], 0, 0); + r = listnodes(tp->kids[1], 0, 0); + assert(errcnt || opkind(l->op) == opkind(r->op)); + assert(errcnt || optype(op) == optype(l->op)); + if (tlab) + assert(flab == 0), list(newnode(generic(tp->op) + opkind(l->op), l, r, findlabel(tlab))); + else if (flab) + { + switch (generic(tp->op)) + { + case EQ: + op = NE; + break; + case NE: + op = EQ; + break; + case GT: + op = LE; + break; + case LT: + op = GE; + break; + case GE: + op = LT; + break; + case LE: + op = GT; + break; + default: + assert(0); + } + list(newnode(op + opkind(l->op), l, r, findlabel(flab))); + } + if (forest && forest->syms[0]) forest->syms[0]->ref++; + } + break; + case ASGN: + { + assert(tlab == 0 && flab == 0); + if (tp->kids[0]->op == FIELD) + { + Tree x = tp->kids[0]->kids[0]; + Field f = tp->kids[0]->u.field; + assert(generic(x->op) == INDIR); + reset(); + l = listnodes(lvalue(x), 0, 0); + if (fieldsize(f) < 8 * f->type->size) + { + unsigned int fmask = fieldmask(f); + unsigned int mask = fmask << fieldright(f); + Tree q = tp->kids[1]; + if ((q->op == CNST + I && q->u.v.i == 0) || (q->op == CNST + U && q->u.v.u == 0)) + q = bittree(BAND, x, cnsttree(unsignedtype, (unsigned long)~mask)); + else if ((q->op == CNST + I && (q->u.v.i & fmask) == fmask) || + (q->op == CNST + U && (q->u.v.u & fmask) == fmask)) + q = bittree(BOR, x, cnsttree(unsignedtype, (unsigned long)mask)); + else + { + listnodes(q, 0, 0); + q = bittree(BOR, bittree(BAND, rvalue(lvalue(x)), cnsttree(unsignedtype, (unsigned long)~mask)), + bittree(BAND, shtree(LSH, cast(q, unsignedtype), + cnsttree(unsignedtype, (unsigned long)fieldright(f))), + cnsttree(unsignedtype, (unsigned long)mask))); + } + r = listnodes(q, 0, 0); + op = ASGN + ttob(q->type); + } + else + { + r = listnodes(tp->kids[1], 0, 0); + op = ASGN + ttob(tp->kids[1]->type); + } + } + else + { + l = listnodes(tp->kids[0], 0, 0); + r = listnodes(tp->kids[1], 0, 0); + } + list(newnode(tp->op == ASGN + B ? tp->op : op, l, r, NULL)); + forest->syms[0] = intconst(tp->kids[1]->type->size); + forest->syms[1] = intconst(tp->kids[1]->type->align); + if (isaddrop(tp->kids[0]->op) && !tp->kids[0]->u.sym->computed) + kill(tp->kids[0]->u.sym); + else + reset(); + p = listnodes(tp->kids[1], 0, 0); + } + break; + case BOR: + case BAND: + case BXOR: + case ADD: + case SUB: + case RSH: + case LSH: + { + assert(tlab == 0 && flab == 0); + l = listnodes(tp->kids[0], 0, 0); + r = listnodes(tp->kids[1], 0, 0); + p = node(op, l, r, NULL); + } + break; + case DIV: + case MUL: + case MOD: + { + assert(tlab == 0 && flab == 0); + l = listnodes(tp->kids[0], 0, 0); + r = listnodes(tp->kids[1], 0, 0); + p = node(op, l, r, NULL); + if (IR->mulops_calls && isint(tp->type)) + { + list(p); + cfunc->u.f.ncalls++; + } + } + break; + case RET: + { + assert(tlab == 0 && flab == 0); + l = listnodes(tp->kids[0], 0, 0); + list(newnode(op, l, NULL, NULL)); + } + break; + case CVF: + case CVI: + case CVP: + case CVU: + { + assert(tlab == 0 && flab == 0); + assert(optype(tp->kids[0]->op) != optype(tp->op) || tp->kids[0]->type->size != tp->type->size); + l = listnodes(tp->kids[0], 0, 0); + p = node(op, l, NULL, intconst(tp->kids[0]->type->size)); + } + break; + case BCOM: + case NEG: + { + assert(tlab == 0 && flab == 0); + l = listnodes(tp->kids[0], 0, 0); + p = node(op, l, NULL, NULL); + } + break; + case INDIR: + { + Type ty = tp->kids[0]->type; + assert(tlab == 0 && flab == 0); + l = listnodes(tp->kids[0], 0, 0); + if (isptr(ty)) ty = unqual(ty)->type; + if (isvolatile(ty) || (isstruct(ty) && unqual(ty)->u.sym->u.s.vfields)) + p = newnode(tp->op == INDIR + B ? tp->op : op, l, NULL, NULL); + else + p = node(tp->op == INDIR + B ? tp->op : op, l, NULL, NULL); + } + break; + case FIELD: + { + Tree q = tp->kids[0]; + if (tp->type == inttype) + { + long n = fieldleft(tp->u.field); + q = shtree(RSH, shtree(LSH, q, cnsttree(inttype, n)), cnsttree(inttype, n + fieldright(tp->u.field))); + } + else if (fieldsize(tp->u.field) < 8 * tp->u.field->type->size) + q = bittree(BAND, shtree(RSH, q, cnsttree(inttype, (long)fieldright(tp->u.field))), + cnsttree(unsignedtype, (unsigned long)fieldmask(tp->u.field))); + assert(tlab == 0 && flab == 0); + p = listnodes(q, 0, 0); + } + break; + case ADDRG: + case ADDRF: + { + assert(tlab == 0 && flab == 0); + p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym); + } + break; + case ADDRL: + { + assert(tlab == 0 && flab == 0); + if (tp->u.sym->temporary) addlocal(tp->u.sym); + p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym); + } + break; + default: + assert(0); + } + tp->node = p; + return p; } -static void list(Node p) { - if (p && p->link == NULL) { - if (forest) { - p->link = forest->link; - forest->link = p; - } else - p->link = p; - forest = p; - } +static void list(Node p) +{ + if (p && p->link == NULL) + { + if (forest) + { + p->link = forest->link; + forest->link = p; + } + else + p->link = p; + forest = p; + } } -static void labelnode(int lab) { - assert(lab); - if (forest && forest->op == LABEL+V) - equatelab(findlabel(lab), forest->syms[0]); - else - list(newnode(LABEL+V, NULL, NULL, findlabel(lab))); - reset(); +static void labelnode(int lab) +{ + assert(lab); + if (forest && forest->op == LABEL + V) + equatelab(findlabel(lab), forest->syms[0]); + else + list(newnode(LABEL + V, NULL, NULL, findlabel(lab))); + reset(); } -static void unlist(void) { - Node p; +static void unlist(void) +{ + Node p; - assert(forest); - assert(forest != forest->link); - p = forest->link; - while (p->link != forest) - p = p->link; - p->link = forest->link; - forest = p; + assert(forest); + assert(forest != forest->link); + p = forest->link; + while (p->link != forest) p = p->link; + p->link = forest->link; + forest = p; } -Tree cvtconst(Tree p) { - Symbol q = constant(p->type, p->u.v); - Tree e; +Tree cvtconst(Tree p) +{ + Symbol q = constant(p->type, p->u.v); + Tree e; - if (q->u.c.loc == NULL) - q->u.c.loc = genident(STATIC, p->type, GLOBAL); - if (isarray(p->type)) { - e = simplify(ADDRG, atop(p->type), NULL, NULL); - e->u.sym = q->u.c.loc; - } else - e = idtree(q->u.c.loc); - return e; + if (q->u.c.loc == NULL) q->u.c.loc = genident(STATIC, p->type, GLOBAL); + if (isarray(p->type)) + { + e = simplify(ADDRG, atop(p->type), NULL, NULL); + e->u.sym = q->u.c.loc; + } + else + e = idtree(q->u.c.loc); + return e; } -void gencode(Symbol caller[], Symbol callee[]) { - Code cp; - Coordinate save; +void gencode(Symbol caller[], Symbol callee[]) +{ + Code cp; + Coordinate save; - if (prunetemps == -1) - prunetemps = !IR->wants_dag; - save = src; - if (assignargs) { - int i; - Symbol p, q; - cp = codehead.next->next; - codelist = codehead.next; - for (i = 0; (p = callee[i]) != NULL - && (q = caller[i]) != NULL; i++) - if (p->sclass != q->sclass || p->type != q->type) - walk(asgn(p, idtree(q)), 0, 0); - codelist->next = cp; - cp->prev = codelist; - } - if (glevel && IR->stabsym) { - int i; - Symbol p, q; - for (i = 0; (p = callee[i]) != NULL - && (q = caller[i]) != NULL; i++) { - (*IR->stabsym)(p); - if (p->sclass != q->sclass || p->type != q->type) - (*IR->stabsym)(q); - } - swtoseg(CODE); - } - cp = codehead.next; - for ( ; errcnt <= 0 && cp; cp = cp->next) - switch (cp->kind) { - case Address: (*IR->address)(cp->u.addr.sym, cp->u.addr.base, - cp->u.addr.offset); break; - case Blockbeg: { - Symbol *p = cp->u.block.locals; - (*IR->blockbeg)(&cp->u.block.x); - for ( ; *p; p++) - if ((*p)->ref != 0.0) - (*IR->local)(*p); - else if (glevel) (*IR->local)(*p); - } - break; - case Blockend: (*IR->blockend)(&cp->u.begin->u.block.x); break; - case Defpoint: src = cp->u.point.src; break; - case Gen: case Jump: - case Label: if (prunetemps) - cp->u.forest = prune(cp->u.forest); - fixup(cp->u.forest); - cp->u.forest = (*IR->gen)(cp->u.forest); break; - case Local: (*IR->local)(cp->u.var); break; - case Switch: break; - default: assert(0); - } - src = save; + if (prunetemps == -1) prunetemps = !IR->wants_dag; + save = src; + if (assignargs) + { + int i; + Symbol p, q; + cp = codehead.next->next; + codelist = codehead.next; + for (i = 0; (p = callee[i]) != NULL && (q = caller[i]) != NULL; i++) + if (p->sclass != q->sclass || p->type != q->type) walk(asgn(p, idtree(q)), 0, 0); + codelist->next = cp; + cp->prev = codelist; + } + if (glevel && IR->stabsym) + { + int i; + Symbol p, q; + for (i = 0; (p = callee[i]) != NULL && (q = caller[i]) != NULL; i++) + { + (*IR->stabsym)(p); + if (p->sclass != q->sclass || p->type != q->type) (*IR->stabsym)(q); + } + swtoseg(CODE); + } + cp = codehead.next; + for (; errcnt <= 0 && cp; cp = cp->next) switch (cp->kind) + { + case Address: + (*IR->address)(cp->u.addr.sym, cp->u.addr.base, cp->u.addr.offset); + break; + case Blockbeg: + { + Symbol *p = cp->u.block.locals; + (*IR->blockbeg)(&cp->u.block.x); + for (; *p; p++) + if ((*p)->ref != 0.0) + (*IR->local)(*p); + else if (glevel) + (*IR->local)(*p); + } + break; + case Blockend: + (*IR->blockend)(&cp->u.begin->u.block.x); + break; + case Defpoint: + src = cp->u.point.src; + break; + case Gen: + case Jump: + case Label: + if (prunetemps) cp->u.forest = prune(cp->u.forest); + fixup(cp->u.forest); + cp->u.forest = (*IR->gen)(cp->u.forest); + break; + case Local: + (*IR->local)(cp->u.var); + break; + case Switch: + break; + default: + assert(0); + } + src = save; } -static void fixup(Node p) { - for ( ; p; p = p->link) - switch (generic(p->op)) { - case JUMP: - if (specific(p->kids[0]->op) == ADDRG+P) - p->kids[0]->syms[0] = - equated(p->kids[0]->syms[0]); - break; - case LABEL: assert(p->syms[0] == equated(p->syms[0])); break; - case EQ: case GE: case GT: case LE: case LT: case NE: - assert(p->syms[0]); - p->syms[0] = equated(p->syms[0]); - } +static void fixup(Node p) +{ + for (; p; p = p->link) switch (generic(p->op)) + { + case JUMP: + if (specific(p->kids[0]->op) == ADDRG + P) p->kids[0]->syms[0] = equated(p->kids[0]->syms[0]); + break; + case LABEL: + assert(p->syms[0] == equated(p->syms[0])); + break; + case EQ: + case GE: + case GT: + case LE: + case LT: + case NE: + assert(p->syms[0]); + p->syms[0] = equated(p->syms[0]); + } } -static Symbol equated(Symbol p) { - { Symbol q; for (q = p->u.l.equatedto; q; q = q->u.l.equatedto) assert(p != q); } - while (p->u.l.equatedto) - p = p->u.l.equatedto; - return p; +static Symbol equated(Symbol p) +{ + { + Symbol q; + for (q = p->u.l.equatedto; q; q = q->u.l.equatedto) assert(p != q); + } + while (p->u.l.equatedto) p = p->u.l.equatedto; + return p; } -void emitcode(void) { - Code cp; - Coordinate save; +void emitcode(void) +{ + Code cp; + Coordinate save; - save = src; - cp = codehead.next; - for ( ; errcnt <= 0 && cp; cp = cp->next) - switch (cp->kind) { - case Address: break; - case Blockbeg: if (glevel && IR->stabblock) { - (*IR->stabblock)('{', cp->u.block.level - LOCAL, cp->u.block.locals); - swtoseg(CODE); - } - break; - case Blockend: if (glevel && IR->stabblock) { - Code bp = cp->u.begin; - foreach(bp->u.block.identifiers, bp->u.block.level, typestab, NULL); - foreach(bp->u.block.types, bp->u.block.level, typestab, NULL); - (*IR->stabblock)('}', bp->u.block.level - LOCAL, bp->u.block.locals); - swtoseg(CODE); - } - break; - case Defpoint: src = cp->u.point.src; - if (glevel > 0 && IR->stabline) { - (*IR->stabline)(&cp->u.point.src); swtoseg(CODE); } break; - case Gen: case Jump: - case Label: if (cp->u.forest) - (*IR->emit)(cp->u.forest); break; - case Local: if (glevel && IR->stabsym) { - (*IR->stabsym)(cp->u.var); - swtoseg(CODE); - } break; - case Switch: { int i; - defglobal(cp->u.swtch.table, LIT); - (*IR->defaddress)(equated(cp->u.swtch.labels[0])); - for (i = 1; i < cp->u.swtch.size; i++) { - long k = cp->u.swtch.values[i-1]; - while (++k < cp->u.swtch.values[i]) - assert(k < LONG_MAX), - (*IR->defaddress)(equated(cp->u.swtch.deflab)); - (*IR->defaddress)(equated(cp->u.swtch.labels[i])); - } - swtoseg(CODE); - } break; - default: assert(0); - } - src = save; + save = src; + cp = codehead.next; + for (; errcnt <= 0 && cp; cp = cp->next) switch (cp->kind) + { + case Address: + break; + case Blockbeg: + if (glevel && IR->stabblock) + { + (*IR->stabblock)('{', cp->u.block.level - LOCAL, cp->u.block.locals); + swtoseg(CODE); + } + break; + case Blockend: + if (glevel && IR->stabblock) + { + Code bp = cp->u.begin; + foreach (bp->u.block.identifiers, bp->u.block.level, typestab, NULL) + ; + foreach (bp->u.block.types, bp->u.block.level, typestab, NULL) + ; + (*IR->stabblock)('}', bp->u.block.level - LOCAL, bp->u.block.locals); + swtoseg(CODE); + } + break; + case Defpoint: + src = cp->u.point.src; + if (glevel > 0 && IR->stabline) + { + (*IR->stabline)(&cp->u.point.src); + swtoseg(CODE); + } + break; + case Gen: + case Jump: + case Label: + if (cp->u.forest) (*IR->emit)(cp->u.forest); + break; + case Local: + if (glevel && IR->stabsym) + { + (*IR->stabsym)(cp->u.var); + swtoseg(CODE); + } + break; + case Switch: + { + int i; + defglobal(cp->u.swtch.table, LIT); + (*IR->defaddress)(equated(cp->u.swtch.labels[0])); + for (i = 1; i < cp->u.swtch.size; i++) + { + long k = cp->u.swtch.values[i - 1]; + while (++k < cp->u.swtch.values[i]) + assert(k < LONG_MAX), (*IR->defaddress)(equated(cp->u.swtch.deflab)); + (*IR->defaddress)(equated(cp->u.swtch.labels[i])); + } + swtoseg(CODE); + } + break; + default: + assert(0); + } + src = save; } -static Node undag(Node forest) { - Node p; +static Node undag(Node forest) +{ + Node p; - tail = &forest; - for (p = forest; p; p = p->link) - if (generic(p->op) == INDIR) { - assert(p->count >= 1); - visit(p, 1); - if (p->syms[2]) { - assert(p->syms[2]->u.t.cse); - p->syms[2]->u.t.cse = NULL; - addlocal(p->syms[2]); - } - } else if (iscall(p->op) && p->count >= 1) - visit(p, 1); - else { - assert(p->count == 0), - visit(p, 1); - *tail = p; - tail = &p->link; - } - *tail = NULL; - return forest; + tail = &forest; + for (p = forest; p; p = p->link) + if (generic(p->op) == INDIR) + { + assert(p->count >= 1); + visit(p, 1); + if (p->syms[2]) + { + assert(p->syms[2]->u.t.cse); + p->syms[2]->u.t.cse = NULL; + addlocal(p->syms[2]); + } + } + else if (iscall(p->op) && p->count >= 1) + visit(p, 1); + else + { + assert(p->count == 0), visit(p, 1); + *tail = p; + tail = &p->link; + } + *tail = NULL; + return forest; } -static Node replace(Node p) { - if (p && ( generic(p->op) == INDIR - && generic(p->kids[0]->op) == ADDRL - && p->kids[0]->syms[0]->temporary - && p->kids[0]->syms[0]->u.t.replace)) { - p = p->kids[0]->syms[0]->u.t.cse; - if (generic(p->op) == INDIR && isaddrop(p->kids[0]->op)) - p = newnode(p->op, newnode(p->kids[0]->op, NULL, NULL, - p->kids[0]->syms[0]), NULL, NULL); - else if (generic(p->op) == ADDRG) - p = newnode(p->op, NULL, NULL, p->syms[0]); - else - assert(0); - p->count = 1; - } else if (p) { - p->kids[0] = replace(p->kids[0]); - p->kids[1] = replace(p->kids[1]); - } - return p; +static Node replace(Node p) +{ + if (p && (generic(p->op) == INDIR && generic(p->kids[0]->op) == ADDRL && p->kids[0]->syms[0]->temporary && + p->kids[0]->syms[0]->u.t.replace)) + { + p = p->kids[0]->syms[0]->u.t.cse; + if (generic(p->op) == INDIR && isaddrop(p->kids[0]->op)) + p = newnode(p->op, newnode(p->kids[0]->op, NULL, NULL, p->kids[0]->syms[0]), NULL, NULL); + else if (generic(p->op) == ADDRG) + p = newnode(p->op, NULL, NULL, p->syms[0]); + else + assert(0); + p->count = 1; + } + else if (p) + { + p->kids[0] = replace(p->kids[0]); + p->kids[1] = replace(p->kids[1]); + } + return p; } -static Node prune(Node forest) { - Node p, *tail = &forest; - int count = 0; +static Node prune(Node forest) +{ + Node p, *tail = &forest; + int count = 0; - for (p = forest; p; p = p->link) { - if (count > 0) { - p->kids[0] = replace(p->kids[0]); - p->kids[1] = replace(p->kids[1]); - } - if (( generic(p->op) == ASGN - && generic(p->kids[0]->op) == ADDRL - && p->kids[0]->syms[0]->temporary - && p->kids[0]->syms[0]->u.t.cse == p->kids[1])) { - Symbol tmp = p->kids[0]->syms[0]; - if (!tmp->defined) - (*IR->local)(tmp); - tmp->defined = 1; - if (( generic(p->kids[1]->op) == INDIR - && isaddrop(p->kids[1]->kids[0]->op) - && p->kids[1]->kids[0]->syms[0]->sclass == REGISTER) - || (( generic(p->kids[1]->op) == INDIR - && isaddrop(p->kids[1]->kids[0]->op)) && tmp->sclass == AUTO) - || (generic(p->kids[1]->op) == ADDRG && tmp->sclass == AUTO)) { - tmp->u.t.replace = 1; - count++; - continue; /* and omit the assignment */ - } - } - /* keep the assignment and other roots */ - *tail = p; - tail = &(*tail)->link; - } - assert(*tail == NULL); - return forest; + for (p = forest; p; p = p->link) + { + if (count > 0) + { + p->kids[0] = replace(p->kids[0]); + p->kids[1] = replace(p->kids[1]); + } + if ((generic(p->op) == ASGN && generic(p->kids[0]->op) == ADDRL && p->kids[0]->syms[0]->temporary && + p->kids[0]->syms[0]->u.t.cse == p->kids[1])) + { + Symbol tmp = p->kids[0]->syms[0]; + if (!tmp->defined) (*IR->local)(tmp); + tmp->defined = 1; + if ((generic(p->kids[1]->op) == INDIR && isaddrop(p->kids[1]->kids[0]->op) && + p->kids[1]->kids[0]->syms[0]->sclass == REGISTER) || + ((generic(p->kids[1]->op) == INDIR && isaddrop(p->kids[1]->kids[0]->op)) && tmp->sclass == AUTO) || + (generic(p->kids[1]->op) == ADDRG && tmp->sclass == AUTO)) + { + tmp->u.t.replace = 1; + count++; + continue; /* and omit the assignment */ + } + } + /* keep the assignment and other roots */ + *tail = p; + tail = &(*tail)->link; + } + assert(*tail == NULL); + return forest; } -static Node visit(Node p, int listed) { - if (p) { - if (p->syms[2]) - p = tmpnode(p); - else if ((p->count <= 1 && !iscall(p->op)) - || (p->count == 0 && iscall(p->op))) { - p->kids[0] = visit(p->kids[0], 0); - p->kids[1] = visit(p->kids[1], 0); - } +static Node visit(Node p, int listed) +{ + if (p) + { + if (p->syms[2]) + p = tmpnode(p); + else if ((p->count <= 1 && !iscall(p->op)) || (p->count == 0 && iscall(p->op))) + { + p->kids[0] = visit(p->kids[0], 0); + p->kids[1] = visit(p->kids[1], 0); + } - else if (specific(p->op) == ADDRL+P || specific(p->op) == ADDRF+P) { - assert(!listed); - p = newnode(p->op, NULL, NULL, p->syms[0]); - p->count = 1; - } - else if (p->op == INDIR+B) { - p = newnode(p->op, p->kids[0], NULL, NULL); - p->count = 1; - p->kids[0] = visit(p->kids[0], 0); - p->kids[1] = visit(p->kids[1], 0); - } - else { - p->kids[0] = visit(p->kids[0], 0); - p->kids[1] = visit(p->kids[1], 0); - p->syms[2] = temporary(REGISTER, btot(p->op, opsize(p->op))); - assert(!p->syms[2]->defined); - p->syms[2]->ref = 1; - p->syms[2]->u.t.cse = p; + else if (specific(p->op) == ADDRL + P || specific(p->op) == ADDRF + P) + { + assert(!listed); + p = newnode(p->op, NULL, NULL, p->syms[0]); + p->count = 1; + } + else if (p->op == INDIR + B) + { + p = newnode(p->op, p->kids[0], NULL, NULL); + p->count = 1; + p->kids[0] = visit(p->kids[0], 0); + p->kids[1] = visit(p->kids[1], 0); + } + else + { + p->kids[0] = visit(p->kids[0], 0); + p->kids[1] = visit(p->kids[1], 0); + p->syms[2] = temporary(REGISTER, btot(p->op, opsize(p->op))); + assert(!p->syms[2]->defined); + p->syms[2]->ref = 1; + p->syms[2]->u.t.cse = p; - *tail = asgnnode(p->syms[2], p); - tail = &(*tail)->link; - if (!listed) - p = tmpnode(p); - }; - } - return p; + *tail = asgnnode(p->syms[2], p); + tail = &(*tail)->link; + if (!listed) p = tmpnode(p); + }; + } + return p; } -static Node tmpnode(Node p) { - Symbol tmp = p->syms[2]; +static Node tmpnode(Node p) +{ + Symbol tmp = p->syms[2]; - assert(tmp); - if (--p->count == 0) - p->syms[2] = NULL; - p = newnode(INDIR + ttob(tmp->type), - newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), NULL, NULL); - p->count = 1; - return p; + assert(tmp); + if (--p->count == 0) p->syms[2] = NULL; + p = newnode(INDIR + ttob(tmp->type), newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), NULL, NULL); + p->count = 1; + return p; } -static Node asgnnode(Symbol tmp, Node p) { - p = newnode(ASGN + ttob(tmp->type), - newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), p, NULL); - p->syms[0] = intconst(tmp->type->size); - p->syms[1] = intconst(tmp->type->align); - return p; +static Node asgnnode(Symbol tmp, Node p) +{ + p = newnode(ASGN + ttob(tmp->type), newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), p, NULL); + p->syms[0] = intconst(tmp->type->size); + p->syms[1] = intconst(tmp->type->align); + return p; } /* printdag - print dag p on fd, or the node list if p == 0 */ -void printdag(Node p, int fd) { - FILE *f = fd == 1 ? stdout : stderr; +void printdag(Node p, int fd) +{ + FILE *f = fd == 1 ? stdout : stderr; - printed(0); - if (p == 0) { - if ((p = forest) != NULL) - do { - p = p->link; - printdag1(p, fd, 0); - } while (p != forest); - } else if (*printed(nodeid((Tree)p))) - fprint(f, "node'%d printed above\n", nodeid((Tree)p)); - else - printdag1(p, fd, 0); + printed(0); + if (p == 0) + { + if ((p = forest) != NULL) do + { + p = p->link; + printdag1(p, fd, 0); + } while (p != forest); + } + else if (*printed(nodeid((Tree)p))) + fprint(f, "node'%d printed above\n", nodeid((Tree)p)); + else + printdag1(p, fd, 0); } /* printdag1 - recursively print dag p */ -static void printdag1(Node p, int fd, int lev) { - int id, i; +static void printdag1(Node p, int fd, int lev) +{ + int id, i; - if (p == 0 || *printed(id = nodeid((Tree)p))) - return; - *printed(id) = 1; - for (i = 0; i < NELEMS(p->kids); i++) - printdag1(p->kids[i], fd, lev + 1); - printnode(p, fd, lev); + if (p == 0 || *printed(id = nodeid((Tree)p))) return; + *printed(id) = 1; + for (i = 0; i < NELEMS(p->kids); i++) printdag1(p->kids[i], fd, lev + 1); + printnode(p, fd, lev); } /* printnode - print fields of dag p */ -static void printnode(Node p, int fd, int lev) { - if (p) { - FILE *f = fd == 1 ? stdout : stderr; - int i, id = nodeid((Tree)p); - fprint(f, "%c%d%s", lev == 0 ? '\'' : '#', id, - &" "[id < 10 ? 0 : id < 100 ? 1 : 2]); - fprint(f, "%s count=%d", opname(p->op), p->count); - for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++) - fprint(f, " #%d", nodeid((Tree)p->kids[i])); - if (generic(p->op) == CALL && p->syms[0] && p->syms[0]->type) - fprint(f, " {%t}", p->syms[0]->type); - else - for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++) - if (p->syms[i]->name) - fprint(f, " %s", p->syms[i]->name); - else - fprint(f, " %p", p->syms[i]); - fprint(f, "\n"); - } +static void printnode(Node p, int fd, int lev) +{ + if (p) + { + FILE *f = fd == 1 ? stdout : stderr; + int i, id = nodeid((Tree)p); + fprint(f, "%c%d%s", lev == 0 ? '\'' : '#', id, &" "[id < 10 ? 0 : id < 100 ? 1 : 2]); + fprint(f, "%s count=%d", opname(p->op), p->count); + for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++) fprint(f, " #%d", nodeid((Tree)p->kids[i])); + if (generic(p->op) == CALL && p->syms[0] && p->syms[0]->type) + fprint(f, " {%t}", p->syms[0]->type); + else + for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++) + if (p->syms[i]->name) + fprint(f, " %s", p->syms[i]->name); + else + fprint(f, " %p", p->syms[i]); + fprint(f, "\n"); + } } /* typestab - emit stab entries for p */ -static void typestab(Symbol p, void *cl) { - if (!isfunc(p->type) && (p->sclass == EXTERN || p->sclass == STATIC) && IR->stabsym) - (*IR->stabsym)(p); - else if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype) - (*IR->stabtype)(p); +static void typestab(Symbol p, void *cl) +{ + if (!isfunc(p->type) && (p->sclass == EXTERN || p->sclass == STATIC) && IR->stabsym) + (*IR->stabsym)(p); + else if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype) + (*IR->stabtype)(p); } - -- cgit