diff options
author | Anders Magnusson <ragge@cvs.openbsd.org> | 2008-01-12 17:26:17 +0000 |
---|---|---|
committer | Anders Magnusson <ragge@cvs.openbsd.org> | 2008-01-12 17:26:17 +0000 |
commit | 2a38ae248a7a74080d79e5a0646acb024f68f80b (patch) | |
tree | 436697f771daf51850328fcaa23bda048e5c79ba | |
parent | 5435eef5c2fd45c7b516422cd37370bbb1a13f68 (diff) |
Large update from master repo:
> Pragma not position dependent
> Accept declarations anywhere in the C code.
> Just typing "a;" is not allowed anymore when declaring variables.
> Change to new initializer handling.
> Use symtab entry, not name to identify inline functions.
> Remove "suse" symtab element and replace it with output name.
> Print out strings directly, do not store them until end.
> Make prtdcon() target dependent to allow for float constants in code.
-rw-r--r-- | usr.bin/pcc/ccom/cgram.y | 107 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/gcc_compat.c | 40 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/init.c | 37 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/inline.c | 35 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/pass1.h | 46 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/pftn.c | 252 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/scan.l | 80 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/stabs.c | 12 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/trees.c | 91 |
9 files changed, 229 insertions, 471 deletions
diff --git a/usr.bin/pcc/ccom/cgram.y b/usr.bin/pcc/ccom/cgram.y index b914b1c4612..79c1a3963e7 100644 --- a/usr.bin/pcc/ccom/cgram.y +++ b/usr.bin/pcc/ccom/cgram.y @@ -1,4 +1,4 @@ -/* $OpenBSD: cgram.y,v 1.7 2007/11/25 10:27:35 stefan Exp $ */ +/* $OpenBSD: cgram.y,v 1.8 2008/01/12 17:26:16 ragge Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). @@ -116,13 +116,7 @@ %token C_QUALIFIER %token C_FUNSPEC %token C_ASM - -/* - * These tokens are only used for pragmas; let yacc handle syntax check. - */ -%token PRAG_PACKED -%token PRAG_ALIGNED -%token PRAG_RENAMED +%token NOMATCH /* * Precedence @@ -154,10 +148,6 @@ int oldstyle; /* Current function being defined */ int noretype; static struct symtab *xnf; extern int enummer; -#ifdef GCC_COMPAT -char *renname; /* for renaming of variables */ -#endif - static NODE *bdty(int op, ...); static void fend(void); @@ -200,7 +190,7 @@ struct savbc { %start ext_def_list %type <intval> con_e ifelprefix ifprefix whprefix forprefix doprefix switchpart - type_qualifier_list str_attr + type_qualifier_list %type <nodep> e .e term enum_dcl struct_dcl cast_type funct_idn declarator direct_declarator elist type_specifier merge_attribs parameter_declaration abstract_declarator initializer @@ -209,13 +199,12 @@ struct savbc { specifier_qualifier_list merge_specifiers nocon_e identifier_list arg_param_list arg_declaration arg_dcl_list designator_list designator -%type <strp> string wstring C_STRING C_WSTRING PRAG_RENAMED +%type <strp> string wstring C_STRING C_WSTRING %type <rp> str_head %type <symp> xnfdeclarator clbrace enum_head %type <intval> C_CLASS C_STRUCT C_RELOP C_DIVOP C_SHIFTOP C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP - PRAG_PACKED PRAG_ALIGNED %type <nodep> C_TYPE C_QUALIFIER C_ICON C_FCON %type <strp> C_NAME C_TYPENAME @@ -339,6 +328,12 @@ type_qualifier_list: direct_declarator: C_NAME { $$ = bdty(NAME, $1); } | '(' declarator ')' { $$ = $2; } | direct_declarator '[' nocon_e ']' { + if (!ISINTEGER($3->n_type)) + werror("array size is not an integer"); + else if ($3->n_op == ICON && $3->n_lval < 0) { + uerror("array size must be non-negative"); + $3->n_lval = 1; + } $$ = block(LB, $1, $3, INT, 0, MKSUE(INT)); } | direct_declarator '[' ']' { $$ = bdty(LB, $1, 0); } @@ -456,18 +451,18 @@ arg_param_list: declarator { olddecl(tymerge($<nodep>0, $1)); } /* * Declarations in beginning of blocks. */ -declaration_list: declaration - | declaration_list declaration +block_item_list: block_item + | block_item_list block_item + ; + +block_item: declaration + | statement ; /* * Here starts the old YACC code. */ -stmt_list: stmt_list statement - | { bccode(); } - ; - /* * Variables are declared in init_declarator. */ @@ -504,8 +499,8 @@ moe: C_NAME { moedef($1); } | C_NAME '=' con_e { enummer = $3; moedef($1); } ; -struct_dcl: str_head '{' struct_dcl_list '}' str_attr { - $$ = dclstruct($1, $5); +struct_dcl: str_head '{' struct_dcl_list '}' empty { + $$ = dclstruct($1); } | C_STRUCT C_NAME { $$ = rstruct($2,$1); } | C_STRUCT C_TYPENAME { $$ = rstruct($2,$1); } @@ -513,13 +508,12 @@ struct_dcl: str_head '{' struct_dcl_list '}' str_attr { #ifndef GCC_COMPAT werror("gcc extension"); #endif - $$ = dclstruct($1, 0); + $$ = dclstruct($1); } ; -str_attr: { $$ = 0; /* nothing */ } - | PRAG_PACKED { $$ = PRAG_PACKED; } - | PRAG_ALIGNED { $$ = PRAG_ALIGNED; } +empty: { /* Get yacc read the next token before reducing */ } + | NOMATCH ; str_head: C_STRUCT { $$ = bstruct(NULL, $1); } @@ -594,13 +588,9 @@ xnfdeclarator: declarator { $$ = xnf = init_declarator($<nodep>0, $1, 1); } * Returns nothing. */ init_declarator: declarator { init_declarator($<nodep>0, $1, 0); } - | declarator PRAG_RENAMED { - renname = $2; /* XXX ugly */ - init_declarator($<nodep>0, $1, 0); - } | declarator C_ASM '(' string ')' { #ifdef GCC_COMPAT - renname = $4; + pragma_renamed = newstring($4, strlen($4)); init_declarator($<nodep>0, $1, 0); #else werror("gcc extension"); @@ -635,7 +625,13 @@ designator_list: designator { $$ = $1; } | designator_list designator { $$ = $2; $$->n_left = $1; } ; -designator: '[' con_e ']' { $$ = bdty(LB, NULL, $2); } +designator: '[' con_e ']' { + if ($2 < 0) { + uerror("designator must be non-negative"); + $2 = 0; + } + $$ = bdty(LB, NULL, $2); + } | C_STROP C_NAME { $$ = bdty(NAME, $2); } ; @@ -648,7 +644,7 @@ ibrace: '{' { ilbrace(); } /* STATEMENTS */ -compoundstmt: begin declaration_list stmt_list '}' { +compoundstmt: begin block_item_list '}' { #ifdef STABS if (gflag && blevel > 2) stabs_rbrac(blevel); @@ -662,7 +658,7 @@ compoundstmt: begin declaration_list stmt_list '}' { autooff = savctx->contlab; savctx = savctx->next; } - | begin stmt_list '}' { + | begin '}' { #ifdef STABS if (gflag && blevel > 2) stabs_rbrac(blevel); @@ -696,6 +692,7 @@ begin: '{' { bc->contlab = autooff; bc->next = savctx; savctx = bc; + bccode(); } ; @@ -882,7 +879,7 @@ switchpart: C_SWITCH '(' e ')' { t = $3->n_type; } p = tempnode(0, t, 0, MKSUE(t)); - num = p->n_lval; + num = regno(p); ecomp(buildtree(ASSIGN, p, $3)); branch( $$ = getlab()); swstart(num, t); @@ -997,27 +994,16 @@ term: term C_INCOP { $$ = buildtree( $2, $1, bcon(1) ); } | term C_STROP C_TYPENAME { $$ = structref($1, $2, $3); } | C_NAME { spname = lookup($1, 0); - /* recognize identifiers in initializations */ - if (blevel==0 && spname->stype == UNDEF) { - register NODE *q; - werror("undeclared initializer name %s", - spname->sname); - q = block(NAME, NIL, NIL, INT, 0, MKSUE(INT)); - q->n_sp = spname; - defid(q, EXTERN); - nfree(q); - } if (spname->sflags & SINLINE) - inline_ref($1); + inline_ref(spname); $$ = buildtree(NAME, NIL, NIL); - spname->suse = -lineno; if (spname->sflags & SDYNARRAY) $$ = buildtree(UMUL, $$, NIL); } | C_ICON { $$ = $1; } | C_FCON { $$ = $1; } - | string { $$ = strend($1); /* get string contents */ } - | wstring { $$ = wstrend($1); } + | string { $$ = strend(0, $1); /* get string contents */ } + | wstring { $$ = strend('L', $1); } | '(' e ')' { $$=$2; } ; @@ -1070,10 +1056,9 @@ funct_idn: C_NAME '(' { nfree(q); } if (s->sflags & SINLINE) - inline_ref($1); + inline_ref(s); spname = s; $$ = buildtree(NAME, NIL, NIL); - s->suse = -lineno; } | term '(' ; @@ -1089,6 +1074,7 @@ static NODE * bdty(int op, ...) { va_list ap; + int val; register NODE *q; va_start(ap, op); @@ -1108,7 +1094,9 @@ bdty(int op, ...) case LB: q->n_left = va_arg(ap, NODE *); - q->n_right = bcon(va_arg(ap, int)); + if ((val = va_arg(ap, int)) < 0) + uerror("array size must be non-negative"); + q->n_right = bcon(val < 0 ? 1 : val); break; case NAME: @@ -1279,9 +1267,7 @@ genswitch(int num, TWORD type, struct swents **p, int n) for (i = 1; i <= n; ++i) { /* already in 1 */ r = tempnode(num, type, 0, MKSUE(type)); - q = block(ICON, NIL, NIL, type, 0, MKSUE(type)); - q->n_sp = NULL; - q->n_lval = p[i]->sval; + q = xbcon(p[i]->sval, NULL, type); r = buildtree(NE, r, clocal(q)); cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab)); } @@ -1305,7 +1291,6 @@ init_declarator(NODE *tn, NODE *p, int assign) typ->n_sp->sflags |= SINLINE; if (ISFTN(typ->n_type) == 0) { - setloc1(DATA); if (assign) { defid(typ, class); typ->n_sp->sflags |= SASG; @@ -1333,7 +1318,6 @@ fundef(NODE *tp, NODE *p) int class = tp->n_lval, oclass; char *c; - setloc1(PROG); /* Enter function args before they are clobbered in tymerge() */ /* Typecheck against prototype will be done in defid(). */ ftnarg(p); @@ -1350,7 +1334,7 @@ fundef(NODE *tp, NODE *p) /* Unreferenced, store it for (eventual) later use */ /* Ignore it if it not declared static */ s->sflags |= SINLINE; - inline_start(s->sname); + inline_start(s); } if (class == EXTERN) class = SNULL; /* same result */ @@ -1358,10 +1342,7 @@ fundef(NODE *tp, NODE *p) cftnsp = s; defid(p, class); prolab = getlab(); - c = cftnsp->sname; -#ifdef GCC_COMPAT - c = gcc_findname(cftnsp); -#endif + c = cftnsp->soname; send_passt(IP_PROLOG, -1, -1, c, cftnsp->stype, cftnsp->sclass == EXTDEF, prolab); blevel = 1; diff --git a/usr.bin/pcc/ccom/gcc_compat.c b/usr.bin/pcc/ccom/gcc_compat.c index 477b467a466..4148cd4ead4 100644 --- a/usr.bin/pcc/ccom/gcc_compat.c +++ b/usr.bin/pcc/ccom/gcc_compat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gcc_compat.c,v 1.3 2007/10/20 18:24:11 otto Exp $ */ +/* $OpenBSD: gcc_compat.c,v 1.4 2008/01/12 17:26:16 ragge Exp $ */ /* * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -90,42 +90,4 @@ gcc_keyword(char *str, NODE **n) cerror("gcc_keyword"); return 0; } - -static struct ren { - struct ren *next; - char *old, *new; -} *renp; -/* - * Save a name for later renaming of a variable. - */ -void -gcc_rename(struct symtab *sp, char *newname) -{ - struct ren *ren = permalloc(sizeof(struct ren)); - - sp->sflags |= SRENAME; - ren->old = sp->sname; - ren->new = newstring(newname, strlen(newname)+1); - ren->next = renp; - renp = ren; -} - -/* - * Get a renamed variable. - */ -char * -gcc_findname(struct symtab *sp) -{ - struct ren *w; - - if ((sp->sflags & SRENAME) == 0) - return sp->sname; - - for (w = renp; w; w = w->next) { - if (w->old == sp->sname) - return w->new; - } - cerror("gcc_findname %s", sp->sname); - return NULL; -} #endif diff --git a/usr.bin/pcc/ccom/init.c b/usr.bin/pcc/ccom/init.c index ee85a716e32..8e800c84cb9 100644 --- a/usr.bin/pcc/ccom/init.c +++ b/usr.bin/pcc/ccom/init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init.c,v 1.5 2007/12/22 22:56:31 stefan Exp $ */ +/* $OpenBSD: init.c,v 1.6 2008/01/12 17:26:16 ragge Exp $ */ /* * Copyright (c) 2004, 2007 Anders Magnusson (ragge@ludd.ltu.se). @@ -448,31 +448,6 @@ nsetval(CONSZ off, int fsz, NODE *p) } /* - * Align data and set correct location. - */ -static void -setscl(struct symtab *sp) -{ - int ro = DATA; - - if (BTYPE(sp->stype) == sp->stype && sp->squal & (CON >> TSHIFT)) - ro = RDATA; - else if (ISPTR(sp->stype) && ISCON(sp->squal)) - ro = RDATA; - /* XXX - readonly pointers */ - setloc1(ro); - defalign(talign(sp->stype, sp->ssue)); - if (sp->sclass == EXTDEF || - (sp->sclass == STATIC && sp->slevel == 0)) { - defnam(sp); - } else { - if (sp->soffset == NOOFFSET) - cerror("setscl"); - deflab1(sp->soffset); - } -} - -/* * take care of generating a value for the initializer p * inoff has the current offset (last bit written) * in the current word being generated @@ -567,14 +542,13 @@ insbf(OFFSZ off, int fsz, int val) spname = csym; p = buildtree(ADDROF, buildtree(NAME, NIL, NIL), NIL); - r = block(ICON, NIL, NIL, typ, 0, MKSUE(typ)); sym.stype = typ; sym.squal = 0; sym.sdf = 0; sym.ssue = MKSUE(typ); sym.soffset = off; sym.sclass = typ == INT ? FIELD | fsz : MOU; - r->n_sp = &sym; + r = xbcon(0, &sym, typ); p = block(STREF, p, r, INT, 0, MKSUE(INT)); ecode(buildtree(ASSIGN, stref(p), bcon(val))); } @@ -621,7 +595,7 @@ endinit(void) #endif if (csym->sclass != AUTO) - setscl(csym); + defloc(csym); /* Calculate total block size */ if (ISARY(csym->stype) && csym->sdf->ddim == 0) { @@ -660,14 +634,13 @@ endinit(void) p = buildtree(ADDROF, buildtree(NAME, NIL, NIL), NIL); n = il->n; - r = block(ICON, NIL, NIL, INT, 0, MKSUE(INT)); sym.stype = n->n_type; sym.squal = n->n_qual; sym.sdf = n->n_df; sym.ssue = n->n_sue; sym.soffset = ll->begsz + il->off; sym.sclass = fsz < 0 ? FIELD | -fsz : 0; - r->n_sp = &sym; + r = xbcon(0, &sym, INT); p = block(STREF, p, r, INT, 0, MKSUE(INT)); ecode(buildtree(ASSIGN, stref(p), il->n)); if (fsz < 0) @@ -954,7 +927,7 @@ simpleinit(struct symtab *sp, NODE *p) case EXTDEF: spname = sp; p = optim(buildtree(ASSIGN, buildtree(NAME, NIL, NIL), p)); - setscl(sp); + defloc(sp); ninval(0, p->n_right->n_sue->suesize, p->n_right); tfree(p); break; diff --git a/usr.bin/pcc/ccom/inline.c b/usr.bin/pcc/ccom/inline.c index c9d0a829e58..1f463a0a136 100644 --- a/usr.bin/pcc/ccom/inline.c +++ b/usr.bin/pcc/ccom/inline.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inline.c,v 1.1 2007/10/07 17:58:51 otto Exp $ */ +/* $OpenBSD: inline.c,v 1.2 2008/01/12 17:26:16 ragge Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -36,7 +36,7 @@ */ static struct istat { struct istat *ilink; - char *name; + struct symtab *sp; int type; #define NOTYETR 0 /* saved but not yet referenced */ #define NOTYETW 1 /* saved and referenced but not yet written out */ @@ -60,11 +60,11 @@ tcnt(NODE *p) } static struct istat * -findfun(char *name) +findfun(struct symtab *sp) { struct istat *is = ipole; while (is) { - if (is->name == name) + if (is->sp == sp) return is; is = is->ilink; } @@ -72,16 +72,16 @@ findfun(char *name) } static void -refnode(char *str) +refnode(struct symtab *sp) { struct interpass *ip; if (sdebug) - printf("refnode(%s)\n", str); + printf("refnode(%s)\n", sp->sname); ip = permalloc(sizeof(*ip)); ip->type = IP_REF; - ip->ip_name = str; + ip->ip_name = (char *)sp; inline_addarg(ip); } @@ -97,21 +97,21 @@ inline_addarg(struct interpass *ip) * Called to setup for inlining of a new function. */ void -inline_start(char *name) +inline_start(struct symtab *sp) { struct istat *is; if (sdebug) - printf("inline_start(\"%s\")\n", name); + printf("inline_start(\"%s\")\n", sp->sname); if (isinlining) cerror("already inlining function"); - if ((is = findfun(name)) == 0) { + if ((is = findfun(sp)) == 0) { is = ialloc(); is->ilink = ipole; ipole = is; - is->name = name; + is->sp = sp; is->type = NOTYETR; } else { if (is->type != NOTYETD) @@ -138,17 +138,17 @@ inline_end() * The function may not be defined when inline_ref() is called. */ void -inline_ref(char *name) +inline_ref(struct symtab *sp) { struct istat *w = ipole; if (sdebug) - printf("inline_ref(\"%s\")\n", name); + printf("inline_ref(\"%s\")\n", sp->sname); if (isinlining) { - refnode(name); + refnode(sp); } else { while (w != NULL) { - if (w->name == name) { + if (w->sp == sp) { if (w->type == NOTYETR) w->type = NOTYETW; return; /* setup for writeout */ @@ -159,7 +159,7 @@ inline_ref(char *name) w = ialloc(); w->ilink = ipole; ipole = w; - w->name = name; + w->sp = sp; w->type = NOTYETD; } } @@ -175,7 +175,7 @@ puto(struct istat *w) nip = DLIST_NEXT(ip, qelem); DLIST_REMOVE(ip, qelem); if (ip->type == IP_REF) - inline_ref(ip->ip_name); + inline_ref((struct symtab *)ip->ip_name); else pass2_compile(ip); ip = nip; @@ -197,6 +197,7 @@ inline_prtout() recovernodes++; while (w != NULL) { if (w->type == NOTYETW) { + defloc(w->sp); puto(w); w->type = WRITTEN; gotone++; diff --git a/usr.bin/pcc/ccom/pass1.h b/usr.bin/pcc/ccom/pass1.h index e782f2ddeaf..aa9bb3758b9 100644 --- a/usr.bin/pcc/ccom/pass1.h +++ b/usr.bin/pcc/ccom/pass1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pass1.h,v 1.7 2008/01/07 21:04:47 stefan Exp $ */ +/* $OpenBSD: pass1.h,v 1.8 2008/01/12 17:26:16 ragge Exp $ */ /* * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. * @@ -89,15 +89,8 @@ extern char *scnames(int); #define SDYNARRAY 00200 #define SINLINE 00400 #define STNODE 01000 -#ifdef GCC_COMPAT -#define SRENAME 02000 /* Node is renamed */ -#endif #define SASG 04000 -#ifndef FIXDEF -#define FIXDEF(p) -#endif - /* alignment of initialized quantities */ #ifndef AL_INIT #define AL_INIT ALINT @@ -153,12 +146,12 @@ struct symtab_hdr { struct symtab { struct symtab_hdr hdr; - char *sname; + char *sname; /* Symbol name */ + char *soname; /* Written-out name */ TWORD stype; /* type word */ TWORD squal; /* qualifier word */ union dimfun *sdf; /* ptr to the dimension/prototype array */ struct suedef *ssue; /* ptr to the definition table */ - int suse; /* line number of last use of the variable */ }; #define snext hdr.h_next @@ -190,7 +183,6 @@ extern char *ftitle; extern struct symtab *cftnsp; extern int autooff, maxautooff, argoff, strucoff; extern int brkflag; -extern int lastloc; extern OFFSZ inoff; @@ -209,6 +201,10 @@ extern int contlab; extern int flostat; extern int retlab; +/* pragma globals */ +extern int pragma_packed, pragma_aligned; +extern char *pragma_renamed; + /* * Flags used in structures/unions */ @@ -232,13 +228,13 @@ extern NODE *buildtree(int, NODE *l, NODE *r), *mkty(unsigned, union dimfun *, struct suedef *), *rstruct(char *, int), - *dclstruct(struct rstack *, int), - *strend(char *), - *wstrend(char *), + *dclstruct(struct rstack *), + *strend(int gtype, char *), *tymerge(NODE *typ, NODE *idp), *stref(NODE *), *offcon(OFFSZ, TWORD, union dimfun *, struct suedef *), *bcon(int), + *xbcon(CONSZ, struct symtab *, TWORD), *bpsize(NODE *), *convert(NODE *, int), *pconvert(NODE *), @@ -252,7 +248,6 @@ extern NODE *optim(NODE *), *clocal(NODE *), *ccopy(NODE *), - *btsize(TWORD, union dimfun *, struct suedef *), *tempnode(int, TWORD type, union dimfun *df, struct suedef *sue), *doacall(NODE *f, NODE *a); NODE *intprom(NODE *); @@ -264,14 +259,12 @@ char *exname(char *); int oalloc(struct symtab *p, int *poff); void deflabel(char *); -void deflab1(int); -void setloc1(int); void gotolabel(char *); unsigned int esccon(char **sptr); -void inline_start(char *name); +void inline_start(struct symtab *sp); void inline_end(void); void inline_addarg(struct interpass *); -void inline_ref(char *); +void inline_ref(struct symtab *sp); void inline_prtout(void); void ftnarg(NODE *); struct rstack *bstruct(char *, int); @@ -284,7 +277,6 @@ char *addstring(char *); char *addname(char *); char *newstring(char *, int len); void symclear(int level); -void schedremove(struct symtab *p); struct symtab *hide(struct symtab *p); int talign(unsigned int, struct suedef *); void bfcode(struct symtab **, int); @@ -292,16 +284,14 @@ int chkftn(union arglist *, union arglist *); void branch(int); void cbranch(NODE *p, NODE *q); void extdec(struct symtab *); -void commdec(struct symtab *); -void lcommdec(struct symtab *); +void defzero(struct symtab *); int falloc(struct symtab *p, int w, int new, NODE *pty); TWORD ctype(TWORD); void ninval(CONSZ off, int fsz, NODE *); void infld(CONSZ off, int fsz, CONSZ); void zbits(CONSZ off, int fsz); -void indata(CONSZ, int); -void instring(char *); -void defnam(struct symtab *); +void instring(struct symtab *sp); +void inwstring(struct symtab *sp); void plabel(int lab); void bjobcode(void); void ejobcode(int); @@ -327,12 +317,14 @@ struct symtab *enumhd(char *); NODE *enumdcl(struct symtab *); NODE *enumref(char *); CONSZ icons(NODE *); +int mypragma(char **); +void fixdef(struct symtab *); +int cqual(TWORD t, TWORD q); +void defloc(struct symtab *); #ifdef GCC_COMPAT void gcc_init(void); int gcc_keyword(char *, NODE **); -void gcc_rename(struct symtab *sp, char *newname); -char *gcc_findname(struct symtab *sp); #endif #ifdef STABS diff --git a/usr.bin/pcc/ccom/pftn.c b/usr.bin/pcc/ccom/pftn.c index 739aae17069..f70636f73d7 100644 --- a/usr.bin/pcc/ccom/pftn.c +++ b/usr.bin/pcc/ccom/pftn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pftn.c,v 1.11 2007/12/25 14:00:45 stefan Exp $ */ +/* $OpenBSD: pftn.c,v 1.12 2008/01/12 17:26:16 ragge Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -95,15 +95,6 @@ struct params; r = argcast(r, t, d, s); *p = *r; nfree(r); /* - * Info stored for delaying string printouts. - */ -struct strsched { - struct strsched *next; - int locctr; - struct symtab *sym; -} *strpole; - -/* * Linked list stack while reading in structs. */ struct rstack { @@ -137,7 +128,6 @@ static void dynalloc(struct symtab *p, int *poff); void inforce(OFFSZ n); void vfdalign(int n); static void ssave(struct symtab *); -static void strprint(void); static void alprint(union arglist *al, int in); static void lcommadd(struct symtab *sp); @@ -383,7 +373,6 @@ defid(NODE *q, int class) p->sclass = class; p->slevel = blevel; p->soffset = NOOFFSET; - p->suse = lineno; if (class == STNAME || class == UNAME) { p->ssue = permalloc(sizeof(struct suedef)); suedefcnt++; @@ -429,32 +418,15 @@ defid(NODE *q, int class) break; case STATIC: case EXTDEF: - p->soffset = getlab(); -#ifdef GCC_COMPAT - { extern char *renname; - if (renname) - gcc_rename(p, renname); - renname = NULL; - } -#endif - break; - case EXTERN: case UFORTRAN: case FORTRAN: p->soffset = getlab(); -#ifdef notdef - /* Cannot reset level here. What does the standard say??? */ - p->slevel = 0; -#endif -#ifdef GCC_COMPAT - { extern char *renname; - if (renname) - gcc_rename(p, renname); - renname = NULL; - } -#endif + if (pragma_renamed) + p->soname = pragma_renamed; + pragma_renamed = NULL; break; + case MOU: case MOS: oalloc(p, &strucoff); @@ -469,12 +441,12 @@ defid(NODE *q, int class) stabs_newsym(p); #endif + fixdef(p); /* Leave last word to target */ #ifdef PCC_DEBUG if (ddebug) printf( " sdf, ssue, offset: %p, %p, %d\n", p->sdf, p->ssue, p->soffset); #endif - } void @@ -509,10 +481,7 @@ ftnend() if (retlab != NOLAB && nerrors == 0) { /* inside a real function */ plabel(retlab); efcode(); /* struct return handled here */ - c = cftnsp->sname; -#ifdef GCC_COMPAT - c = gcc_findname(cftnsp); -#endif + c = cftnsp->soname; SETOFF(maxautooff, ALCHAR); send_passt(IP_EPILOG, 0, maxautooff/SZCHAR, c, cftnsp->stype, cftnsp->sclass == EXTDEF, retlab); @@ -538,8 +507,6 @@ ftnend() inline_end(); inline_prtout(); - strprint(); - tmpfree(); /* Release memory resources */ } @@ -614,10 +581,7 @@ dclargs() intcompare = 0; } done: cendarg(); - c = cftnsp->sname; -#ifdef GCC_COMPAT - c = gcc_findname(cftnsp); -#endif + c = cftnsp->soname; #if 0 prolab = getlab(); send_passt(IP_PROLOG, -1, -1, c, cftnsp->stype, @@ -836,7 +800,7 @@ bstruct(char *name, int soru) * Called after a struct is declared to restore the environment. */ NODE * -dclstruct(struct rstack *r, int pa) +dclstruct(struct rstack *r) { NODE *n; struct params *l, *m; @@ -876,7 +840,7 @@ dclstruct(struct rstack *r, int pa) sue->suelem = permalloc(sizeof(struct symtab *) * i); coff = 0; - if (pa == PRAG_PACKED || pa == PRAG_ALIGNED) + if (pragma_packed || pragma_aligned) strucoff = 0; /* must recount it */ for (i = 0; l != NULL; l = l->next) { @@ -890,9 +854,10 @@ dclstruct(struct rstack *r, int pa) else sz = tsize(p->stype, p->sdf, p->ssue); - if (pa == PRAG_PACKED || pa == PRAG_ALIGNED) { + if (pragma_packed || pragma_aligned) { + /* XXX check pack/align sizes */ p->soffset = coff; - if (pa == PRAG_ALIGNED) + if (pragma_aligned) coff += ALLDOUBLE; else coff += sz; @@ -913,6 +878,8 @@ dclstruct(struct rstack *r, int pa) sue->suesize = strucoff; sue->suealign = al; + pragma_packed = pragma_aligned = 0; + #ifdef STABS if (gflag) stabs_struct(r->rsym, sue); @@ -1144,147 +1111,59 @@ tsize(TWORD ty, union dimfun *d, struct suedef *sue) } /* - * Write last part of wide string. - * Do not bother to save wide strings. - */ -NODE * -wstrend(char *str) -{ - struct symtab *sp = getsymtab(str, SSTRING|STEMP); - struct strsched *sc = tmpalloc(sizeof(struct strsched)); - NODE *p = block(NAME, NIL, NIL, WCHAR_TYPE+ARY, - tmpalloc(sizeof(union dimfun)), MKSUE(WCHAR_TYPE)); - int i; - char *c; - - sp->sclass = ILABEL; - sp->soffset = getlab(); - sp->stype = WCHAR_TYPE+ARY; - - sc = tmpalloc(sizeof(struct strsched)); - sc->locctr = STRNG; - sc->sym = sp; - sc->next = strpole; - strpole = sc; - - /* length calculation, used only for sizeof */ - for (i = 0, c = str; *c; ) { - if (*c++ == '\\') - (void)esccon(&c); - i++; - } - p->n_df->ddim = (i+1) * ((MKSUE(WCHAR_TYPE))->suesize/SZCHAR); - p->n_sp = sp; - return(clocal(p)); -} - -/* - * Write last part of string. + * Save string (and print it out). If wide == 'L' then wide string. */ NODE * -strend(char *str) +strend(int wide, char *str) { -// extern int maystr; - struct symtab *s; + struct symtab *sp; NODE *p; - int i; - char *c; /* If an identical string is already emitted, just forget this one */ - str = addstring(str); /* enter string in string table */ - s = lookup(str, SSTRING); /* check for existance */ - - if (s->soffset == 0 /* && maystr == 0 */) { /* No string */ - struct strsched *sc; - s->sclass = ILABEL; - - /* - * Delay printout of this string until after the current - * function, or the end of the statement. - */ - sc = tmpalloc(sizeof(struct strsched)); - sc->locctr = STRNG; - sc->sym = s; - sc->next = strpole; - strpole = sc; - s->soffset = getlab(); + if (wide == 'L') { + /* Do not save wide strings, at least not now */ + sp = getsymtab(str, SSTRING|STEMP); + } else { + str = addstring(str); /* enter string in string table */ + sp = lookup(str, SSTRING); /* check for existance */ } - p = block(NAME, NIL, NIL, CHAR+ARY, - tmpalloc(sizeof(union dimfun)), MKSUE(CHAR)); -#ifdef CHAR_UNSIGNED - p->n_type = UCHAR+ARY; - p->n_sue = MKSUE(UCHAR); -#endif - /* length calculation, used only for sizeof */ - for (i = 0, c = str; *c; ) { - if (*c++ == '\\') - (void)esccon(&c); - i++; - } - p->n_df->ddim = i+1; - p->n_sp = s; - return(clocal(p)); -} + if (sp->soffset == 0) { /* No string */ + char *wr; + int i; -/* - * Print out new strings, before temp memory is cleared. - */ -void -strprint() -{ - char *wr; - int i, val, isw; - NODE *p = bcon(0); - - while (strpole != NULL) { - setloc1(STRNG); - deflab1(strpole->sym->soffset); - isw = strpole->sym->stype == WCHAR_TYPE+ARY; - - i = 0; - wr = strpole->sym->sname; - while (*wr != 0) { - if (*wr++ == '\\') - val = esccon(&wr); - else - val = (unsigned char)wr[-1]; - if (isw) { - p->n_lval = val; - p->n_type = WCHAR_TYPE; - ninval(i*(WCHAR_TYPE/SZCHAR), - (MKSUE(WCHAR_TYPE))->suesize, p); - } else - bycode(val, i); - i++; - } - if (isw) { - p->n_lval = 0; - ninval(i*(WCHAR_TYPE/SZCHAR), - (MKSUE(WCHAR_TYPE))->suesize, p); + sp->sclass = STATIC; + sp->slevel = 1; + sp->soffset = getlab(); + sp->squal = (CON >> TSHIFT); + sp->sdf = permalloc(sizeof(union dimfun)); + if (wide == 'L') { + sp->stype = WCHAR_TYPE+ARY; + sp->ssue = MKSUE(WCHAR_TYPE); } else { - bycode(0, i++); - bycode(-1, i); +#ifdef CHAR_UNSIGNED + sp->stype = UCHAR+ARY; + sp->ssue = MKSUE(UCHAR); +#else + sp->stype = CHAR+ARY; + sp->ssue = MKSUE(CHAR); +#endif } - strpole = strpole->next; + for (wr = sp->sname, i = 1; *wr; i++) + if (*wr++ == '\\') + (void)esccon(&wr); + + sp->sdf->ddim = i; + if (wide == 'L') + inwstring(sp); + else + instring(sp); } - nfree(p); -} -#if 0 -/* - * simulate byte v appearing in a list of integer values - */ -void -putbyte(int v) -{ - NODE *p; - p = bcon(v); - incode( p, SZCHAR ); - tfree( p ); -// gotscal(); + p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->ssue); + p->n_sp = sp; + return(clocal(p)); } -#endif /* * update the offset pointed to by poff; return the @@ -1323,7 +1202,7 @@ oalloc(struct symtab *p, int *poff ) (p->stype < STRTY || ISPTR(p->stype)) && !ISVOL((p->squal << TSHIFT)) && cisreg(p->stype)) { NODE *tn = tempnode(0, p->stype, p->sdf, p->ssue); - p->soffset = tn->n_lval; + p->soffset = regno(tn); p->sflags |= STNODE; nfree(tn); return 0; @@ -1389,7 +1268,7 @@ dynalloc(struct symtab *p, int *poff) p->sflags |= (STNODE|SDYNARRAY); p->stype = INCREF(p->stype); /* Make this an indirect pointer */ tn = tempnode(0, p->stype, p->sdf, p->ssue); - p->soffset = tn->n_lval; + p->soffset = regno(tn); df = p->sdf; @@ -1399,7 +1278,7 @@ dynalloc(struct symtab *p, int *poff) continue; n = arrstk[i++]; nn = tempnode(0, INT, 0, MKSUE(INT)); - no = nn->n_lval; + no = regno(nn); ecomp(buildtree(ASSIGN, nn, n)); /* Save size */ df->ddim = -no; @@ -1534,7 +1413,7 @@ nidcl(NODE *p, int class) if (blevel == 0) lcommadd(p->n_sp); else - lcommdec(p->n_sp); + defzero(p->n_sp); break; } } @@ -1594,12 +1473,8 @@ lcommprint(void) struct lcd *lc; SLIST_FOREACH(lc, &lhead, next) { - if (lc->sp != NULL) { - if (lc->sp->sclass == STATIC) - lcommdec(lc->sp); - else - commdec(lc->sp); - } + if (lc->sp != NULL) + defzero(lc->sp); } } @@ -2012,7 +1887,7 @@ builtin_alloca(NODE *f, NODE *a) return bcon(0); } t = tempnode(0, VOID|PTR, 0, MKSUE(INT) /* XXX */); - u = tempnode(t->n_lval, VOID|PTR, 0, MKSUE(INT) /* XXX */); + u = tempnode(regno(t), VOID|PTR, 0, MKSUE(INT) /* XXX */); spalloc(t, a, SZCHAR); tfree(f); return u; @@ -2072,7 +1947,7 @@ builtin_va_arg(NODE *f, NODE *a) /* create a copy to a temp node of current ap */ p = tcopy(a->n_left); q = tempnode(0, p->n_type, p->n_df, p->n_sue); - nodnum = q->n_lval; + nodnum = regno(q); rv = buildtree(ASSIGN, q, p); r = a->n_right; @@ -2655,7 +2530,7 @@ getsymtab(char *name, int flags) s = permalloc(sizeof(struct symtab)); symtabcnt++; } - s->sname = name; + s->sname = s->soname = name; s->snext = NULL; s->stype = UNDEF; s->squal = 0; @@ -2665,7 +2540,6 @@ getsymtab(char *name, int flags) s->slevel = blevel; s->sdf = NULL; s->ssue = NULL; - s->suse = 0; return s; } diff --git a/usr.bin/pcc/ccom/scan.l b/usr.bin/pcc/ccom/scan.l index 7e774a0f502..4e349815a0f 100644 --- a/usr.bin/pcc/ccom/scan.l +++ b/usr.bin/pcc/ccom/scan.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: scan.l,v 1.3 2007/10/20 18:24:11 otto Exp $ */ +/* $OpenBSD: scan.l,v 1.4 2008/01/12 17:26:16 ragge Exp $ */ /* * Copyright (c) 2002 Anders Magnusson. All rights reserved. @@ -48,7 +48,7 @@ IS (u|U|l|L)* static NODE *cvtdig(int radix); static NODE *charcon(void); static void control(int); -static int pragma(void); +static void pragma(void); static NODE *floatcon(void); static NODE *fhexcon(void); int notype, parbal; @@ -226,7 +226,7 @@ L?\"(\\.|[^\\"])*\" { "^" { return('^'); } "|" { return('|'); } "?" { return('?'); } -^#pragma[ \t].* { int rv; if ((rv = pragma())) return rv; } +^#pragma[ \t].* { pragma(); } ^#ident[ \t].* { control(CPP_IDENT); } ^#line[ \t].* { control(CPP_LINE); } ^#.* { control(CPP_HASH); } @@ -388,8 +388,7 @@ cvtdig(int radix) ntype = UNSIGNED; } ntype = ctype(ntype); - p = block(ICON, NIL, NIL, ntype, 0, MKSUE(ntype)); - p->n_lval = v; + p = xbcon(v, NULL, ntype); ASGLVAL(p->n_slval, v); return p; @@ -466,51 +465,48 @@ bad: werror("%s: illegal control", yytext); } -static char * -nextkw(char **ptr) +/* + * split a pragma string in parts. + */ +static char ** +splitup(char *str) { - char *rc; - - while (**ptr == ' ' || **ptr == '\t') - (*ptr)++; - if (**ptr == 0) - return 0; - rc = *ptr; - while (**ptr && **ptr != ' ' && **ptr != '\t') - (*ptr)++; - if (**ptr != 0) { - **ptr = 0; - (*ptr)++; - } - return rc; + char *s, **ary; + int i; + + /* count ws. at least needed array size, add 2 to terminate */ + for (i = 2, s = str; *s; s++) + if (*s == ' ' || *s == '\t') + i++; + ary = tmpalloc(sizeof(char *)*i); + for (i = 0, s = strtok(str, " \t"); s; s = strtok(NULL, " \t")) + ary[i++] = s; + ary[i] = NULL; + return ary; } +int pragma_packed, pragma_aligned; +char *pragma_renamed; + /* * got a full pragma line. Split it up here. */ -static int +static void pragma() { - int rv; - char *c, *ptr = yytext; + char **ary; - rv = 0; - ptr += strlen("#pragma"); - if ((c = nextkw(&ptr)) == NULL) + ary = splitup(yytext); + if (ary[1] == NULL) goto bad; - if (strcmp(c, "packed") == 0) { - rv = PRAG_PACKED; - } else if (strcmp(c, "aligned") == 0) { - rv = PRAG_ALIGNED; - } else if (strcmp(c, "rename") == 0) { - if ((c = nextkw(&ptr)) == NULL) - goto bad; - /* XXX may loose memory if blevel > 0 */ - yylval.strp = newstring(c, strlen(c)); - rv = PRAG_RENAMED; - } -bad: - if (rv == 0) - werror("unknown pragma"); - return rv; + if (strcmp(ary[1], "packed") == 0) { + pragma_packed = ary[2] ? atoi(ary[2]) : 1; + } else if (strcmp(ary[1], "aligned") == 0) { + pragma_aligned = ary[2] ? atoi(ary[2]) : 1; + } else if (strcmp(ary[1], "rename") == 0) { + pragma_renamed = newstring(ary[2], strlen(ary[2])); + } else if (mypragma(ary)) + return; + else +bad: werror("unknown pragma"); } diff --git a/usr.bin/pcc/ccom/stabs.c b/usr.bin/pcc/ccom/stabs.c index d3ac046342f..8fe84a5b035 100644 --- a/usr.bin/pcc/ccom/stabs.c +++ b/usr.bin/pcc/ccom/stabs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: stabs.c,v 1.5 2007/12/16 19:20:45 ragge Exp $ */ +/* $OpenBSD: stabs.c,v 1.6 2008/01/12 17:26:16 ragge Exp $ */ /* * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). @@ -257,10 +257,7 @@ stabs_func(struct symtab *s) { char str[MAXPSTR]; - curfun = s->sname; -#ifdef GCC_COMPAT - curfun = gcc_findname(cftnsp); -#endif + curfun = s->soname; printtype(s, str, sizeof(str)); cprint(savestabs, ".stabs \"%s:%c%s\",%d,0,%d,%s", curfun, s->sclass == STATIC ? 'f' : 'F', str, @@ -323,10 +320,7 @@ stabs_newsym(struct symtab *s) s->sclass == TYPEDEF || (s->sclass & FIELD)) return; /* XXX - fix structs */ - sname = s->sname; -#ifdef GCC_COMPAT - sname = gcc_findname(s); -#endif + sname = s->soname; suesize = BIT2BYTE(s->ssue->suesize); if (suesize > 32767) suesize = 32767; diff --git a/usr.bin/pcc/ccom/trees.c b/usr.bin/pcc/ccom/trees.c index 09f71974633..70fa2caefe6 100644 --- a/usr.bin/pcc/ccom/trees.c +++ b/usr.bin/pcc/ccom/trees.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trees.c,v 1.12 2007/12/22 22:56:31 stefan Exp $ */ +/* $OpenBSD: trees.c,v 1.13 2008/01/12 17:26:16 ragge Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -77,8 +77,6 @@ static int moditype(TWORD); static NODE *strargs(NODE *); static void rmcops(NODE *p); -int lastloc = -1; - /* some special actions, used in finding the type of nodes */ # define NCVT 01 # define PUN 02 @@ -303,7 +301,7 @@ runtime: p->n_type = sp->stype; p->n_sue = sp->ssue; p->n_df = sp->sdf; - p->n_lval = sp->soffset; + p->n_rval = sp->soffset; break; } @@ -909,12 +907,18 @@ notlval(p) register NODE *p; { NODE * bcon(int i) { - register NODE *p; + return xbcon(i, NULL, INT); +} - p = block(ICON, NIL, NIL, INT, 0, MKSUE(INT)); - p->n_lval = i; - p->n_sp = NULL; - return(clocal(p)); +NODE * +xbcon(CONSZ val, struct symtab *sp, TWORD type) +{ + NODE *p; + + p = block(ICON, NIL, NIL, type, 0, MKSUE(type)); + p->n_lval = val; + p->n_sp = sp; + return clocal(p); } NODE * @@ -1523,7 +1527,7 @@ moditype(TWORD ty) } } -int tvaloff = 100; +int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100; /* * Returns a TEMP node with temp number nr. @@ -1535,7 +1539,7 @@ tempnode(int nr, TWORD type, union dimfun *df, struct suedef *sue) NODE *r; r = block(TEMP, NIL, NIL, type, df, sue); - r->n_lval = nr ? nr : tvaloff; + regno(r) = nr ? nr : tvaloff; tvaloff += szty(type); return r; } @@ -1597,30 +1601,6 @@ eprint(NODE *p, int down, int *a, int *b) } # endif -void -prtdcon(NODE *p) -{ - int o = p->n_op, i; - - if (o != FCON) - return; - - /* Write float constants to memory */ - /* Should be volontary per architecture */ - - setloc1(RDATA); - defalign(p->n_type == FLOAT ? ALFLOAT : p->n_type == DOUBLE ? - ALDOUBLE : ALLDOUBLE ); - deflab1(i = getlab()); - ninval(0, btdims[p->n_type].suesize, p); - p->n_op = NAME; - p->n_lval = 0; - p->n_sp = tmpalloc(sizeof(struct symtab_hdr)); - p->n_sp->sclass = ILABEL; - p->n_sp->soffset = i; - p->n_sp->sflags = 0; -} - extern int negrel[]; /* @@ -1836,7 +1816,7 @@ again: q = p->n_right->n_left; if (type != VOID) { r = tempnode(0, q->n_type, q->n_df, q->n_sue); - tval = r->n_lval; + tval = regno(r); q = buildtree(ASSIGN, r, q); } rmcops(q); @@ -1883,7 +1863,7 @@ again: *r = *p; andorbr(r, -1, lbl = getlab()); q = tempnode(0, p->n_type, p->n_df, p->n_sue); - tval = q->n_lval; + tval = regno(q); r = tempnode(tval, p->n_type, p->n_df, p->n_sue); ecode(buildtree(ASSIGN, q, bcon(1))); branch(lbl2 = getlab()); @@ -1965,7 +1945,7 @@ delasgop(NODE *p) if (has_se(l)) { q = tempnode(0, ll->n_type, ll->n_df, ll->n_sue); - tval = q->n_lval; + tval = regno(q); r = tempnode(tval, ll->n_type, ll->n_df,ll->n_sue); l->n_left = q; /* Now the left side of node p has no side effects. */ @@ -2014,7 +1994,6 @@ ecomp(NODE *p) p = optim(p); rmcops(p); p = delasgop(p); - setloc1(PROG); if (p->n_op == ICON && p->n_type == VOID) tfree(p); else @@ -2059,7 +2038,7 @@ p2tree(NODE *p) q->sclass == ILABEL) { printf(LABFMT, q->soffset); } else - printf("%s\n", exname(q->sname)); + printf("%s\n", exname(q->soname)); } else printf("\n"); break; @@ -2117,11 +2096,7 @@ p2tree(NODE *p) snprintf(cp, 32, LABFMT, n); p->n_name = cp; } else { -#ifdef GCC_COMPAT - p->n_name = gcc_findname(q); -#else - p->n_name = q->sname; -#endif + p->n_name = q->soname; } } else p->n_name = ""; @@ -2179,7 +2154,7 @@ delvoid(NODE *p) *q = *p; q->n_type = BOOL_TYPE; r = tempnode(0, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE)); - val = r->n_lval; + val = regno(r); s = tempnode(val, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE)); *p = *s; q = buildtree(ASSIGN, r, q); @@ -2202,7 +2177,6 @@ ecode(NODE *p) p = optim(p); p = delasgop(p); - walkf(p, prtdcon); walkf(p, delvoid); #ifdef PCC_DEBUG if (xdebug) { @@ -2239,12 +2213,13 @@ send_passt(int type, ...) ip->lineno = lineno; switch (type) { case IP_NODE: - setloc1(PROG); ip->ip_node = va_arg(ap, NODE *); break; case IP_EPILOG: + if (!isinlining) + defloc(cftnsp); + /* FALLTHROUGH */ case IP_PROLOG: - setloc1(PROG); ipp = (struct interpass_prolog *)ip; ipp->ipp_regs = va_arg(ap, int); ipp->ipp_autos = va_arg(ap, int); @@ -2264,7 +2239,7 @@ send_passt(int type, ...) if (blevel == 0) { /* outside function */ printf("\t%s\n", va_arg(ap, char *)); va_end(ap); - lastloc = -1; + defloc(NULL); return; } ip->ip_asm = va_arg(ap, char *); @@ -2277,8 +2252,6 @@ send_passt(int type, ...) inline_addarg(ip); else pass2_compile(ip); - if (type == IP_EPILOG) - lastloc = PROG; } char * @@ -2396,7 +2369,6 @@ ccopy(NODE *p) void plabel(int label) { - setloc1(PROG); reached = 1; /* Will this always be correct? */ send_passt(IP_DEFLAB, label); } @@ -2415,3 +2387,16 @@ intprom(NODE *n) } return n; } + +/* + * Return CON/VOL/0, whichever are active for the current type. + */ +int +cqual(TWORD t, TWORD q) +{ + while (ISARY(t)) + t = DECREF(t), q = DECQAL(q); + if (t <= BTMASK) + q <<= TSHIFT; + return q & (CON|VOL); +} |