diff options
author | Stefan Kempf <stefan@cvs.openbsd.org> | 2008-04-11 20:45:53 +0000 |
---|---|---|
committer | Stefan Kempf <stefan@cvs.openbsd.org> | 2008-04-11 20:45:53 +0000 |
commit | 0fcd3a2655c466633469fdebb7b6a7ff9b39e915 (patch) | |
tree | 167f27d01d1964f917dc5481da1bae768d6949d6 /usr.bin/pcc/ccom | |
parent | 11561d4249d0255cc9d667a9cc83b66d755d5227 (diff) |
Sync with master repo. Reminded by otto@
Diffstat (limited to 'usr.bin/pcc/ccom')
-rw-r--r-- | usr.bin/pcc/ccom/ccom.1 | 60 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/cgram.y | 247 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/gcc_compat.c | 12 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/init.c | 41 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/main.c | 14 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/optim.c | 4 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/pass1.h | 20 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/pftn.c | 582 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/scan.l | 42 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/stabs.c | 65 | ||||
-rw-r--r-- | usr.bin/pcc/ccom/trees.c | 26 |
11 files changed, 654 insertions, 459 deletions
diff --git a/usr.bin/pcc/ccom/ccom.1 b/usr.bin/pcc/ccom/ccom.1 index fee05e09a80..bc7a642b821 100644 --- a/usr.bin/pcc/ccom/ccom.1 +++ b/usr.bin/pcc/ccom/ccom.1 @@ -1,20 +1,20 @@ -.\" $OpenBSD: ccom.1,v 1.2 2007/10/20 18:23:35 otto Exp $ +.\" $OpenBSD: ccom.1,v 1.3 2008/04/11 20:45:52 stefan Exp $ ."\ .\" Copyright (c) 2007 Jeremy C. Reed <reed@reedmedia.net> -.\" Permission to use, copy, modify, and/or distribute this software for any -.\" purpose with or without fee is hereby granted, provided that the above +.\" Permission to use, copy, modify, and/or distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. -.\" -.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR AND CONTRIBUTORS DISCLAIM -.\" ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -.\" WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHOR AND -.\" CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR AND CONTRIBUTORS DISCLAIM +.\" ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHOR AND +.\" CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF .\" THIS SOFTWARE. .Dd September 14, 2007 -.Dt ccom 1 +.Dt CCOM 1 .Os .Sh NAME .Nm ccom @@ -28,14 +28,15 @@ .Op Fl Z Ar flags .Op infile .Op outfile -.Pp .Sh DESCRIPTION The .Nm utility provides a C compiler. The frontend is usually .Xr pcc 1 . -It is \fBnot\fR intended to be run directly. +It is +.Em not +intended to be run directly. .Pp .Nm reads the C source from @@ -65,23 +66,28 @@ Display version. .It Fl W Ar flags Report warnings. (Do some basic checks.) -NOTE! These are subject to change RSN! +.Em NOTE! +.Em These are subject to change RSN! .Ar flags is one or more of the following: .Bl -tag -width Ds +.It Sy error +Report all warnings as errors. .It Sy implicit Implies .Sy implicit-function-declaration and .Sy implicit-int . .It Sy implicit-function-declaration -Report if no prototype for function. +Report if no prototype was declared for a function. .It Sy implicit-int TODO .It Sy missing-prototypes TODO .It Sy strict-prototypes TODO +.It Sy W +Enable all warnings. .El .\" .It Fl X Ar flags @@ -92,7 +98,7 @@ is one or more of the following: .It Sy b Building of parse trees .It Sy d -Declarations (multiple +Declarations (using multiple .Sy d flags gives more output) .It Sy e @@ -115,23 +121,27 @@ Target-specific flag, used in machine-dependent code .\" .It Fl x Ar optimizations .Ar optimizations -is one or more of the following: +is one of the following: .\" TODO: reword this, since multiple terms don't go with one -x switch?? .Bl -tag -width deljumps .It Sy deljumps Delete redundant jumps and dead code. .It Sy ssa -Convert statements into SSA form for optimization. Not yet finished. +Convert statements into SSA form for optimization. +Not yet finished. .It Sy tailcall Currently not implemented. .It Sy temps -Setting this flag allows variables to be put into registers, for further +Setting this flag allows variables to be put into registers, for further optimization by the register allocator. .El +The +.Fl x +flag can be passed multiple times to set different options. .\" .It Fl Z Ar flags Code generator (pass2) specific debugging where -.Ar flags +.Ar flags is one or more of the following: .Bl -tag -width Ds .It Sy b @@ -155,7 +165,7 @@ Type matching in instruction generator .It Sy u Sethi-Ullman computations .It Sy x -Target-specific flag, used in machine-dependent code +Target-specific flag, used in machine-dependent code .El .El .Sh SEE ALSO @@ -165,8 +175,8 @@ Target-specific flag, used in machine-dependent code .Sh HISTORY The .Nm -compiler is based on the original Portable C Compiler by S. C. -Johnson, written in the late 70's. +compiler is based on the original Portable C Compiler by S. C. Johnson, +written in the late 70's. Even though much of the compiler has been rewritten, some of the basics still remain. About 50% of the frontend code and 80% of the backend code has been @@ -174,7 +184,7 @@ rewritten. Most is written by Anders Magnusson, with the exception of the data-flow analysis part and the SSA conversion code which is written by Peter A Jonsson, and the Mips port that were written as -part of a project by undergraduate students at Lulea University of +part of a project by undergraduate students at Lulea University of Technology. .Pp This product includes software developed or owned by Caldera diff --git a/usr.bin/pcc/ccom/cgram.y b/usr.bin/pcc/ccom/cgram.y index 79c1a3963e7..2af2844b3aa 100644 --- a/usr.bin/pcc/ccom/cgram.y +++ b/usr.bin/pcc/ccom/cgram.y @@ -1,4 +1,4 @@ -/* $OpenBSD: cgram.y,v 1.8 2008/01/12 17:26:16 ragge Exp $ */ +/* $OpenBSD: cgram.y,v 1.9 2008/04/11 20:45:52 stefan Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). @@ -147,7 +147,9 @@ static int fun_inline; /* Reading an inline function */ int oldstyle; /* Current function being defined */ int noretype; static struct symtab *xnf; -extern int enummer; +extern int enummer, tvaloff; +extern struct rstack *rpole; +static int ctval; static NODE *bdty(int op, ...); static void fend(void); @@ -161,9 +163,14 @@ static void adddef(void); static void savebc(void); static void swstart(int, TWORD); static void genswitch(int, TWORD, struct swents **, int); -static NODE * structref(NODE *p, int f, char *name); +static NODE *structref(NODE *p, int f, char *name); static char *mkpstr(char *str); static struct symtab *clbrace(NODE *); +static NODE *cmop(NODE *l, NODE *r); +static NODE *xcmop(NODE *out, NODE *in, NODE *str); +static void mkxasm(char *str, NODE *p); +static NODE *xasmop(char *str, NODE *p); + /* * State for saving current switch state (when nested switches). @@ -198,7 +205,7 @@ struct savbc { declaration_specifiers pointer direct_abstract_declarator specifier_qualifier_list merge_specifiers nocon_e identifier_list arg_param_list arg_declaration arg_dcl_list - designator_list designator + designator_list designator xasm oplist oper cnstr %type <strp> string wstring C_STRING C_WSTRING %type <rp> str_head %type <symp> xnfdeclarator clbrace enum_head @@ -328,6 +335,9 @@ type_qualifier_list: direct_declarator: C_NAME { $$ = bdty(NAME, $1); } | '(' declarator ')' { $$ = $2; } | direct_declarator '[' nocon_e ']' { + $3 = optim($3); + if (blevel == 0 && !nncon($3)) + uerror("array size not constant"); if (!ISINTEGER($3->n_type)) werror("array size is not an integer"); else if ($3->n_op == ICON && $3->n_lval < 0) { @@ -337,32 +347,43 @@ direct_declarator: C_NAME { $$ = bdty(NAME, $1); } $$ = block(LB, $1, $3, INT, 0, MKSUE(INT)); } | direct_declarator '[' ']' { $$ = bdty(LB, $1, 0); } - | direct_declarator '(' notype parameter_type_list ')' { + | direct_declarator '(' fundcl parameter_type_list ')' { + if (blevel-- > 1) + symclear(blevel); $$ = bdty(CALL, $1, $4); } - | direct_declarator '(' notype identifier_list ')' { + | direct_declarator '(' fundcl identifier_list ')' { + if (blevel-- > 1) + symclear(blevel); $$ = bdty(CALL, $1, $4); if (blevel != 0) uerror("function declaration in bad context"); oldstyle = 1; } - | direct_declarator '(' ')' { $$ = bdty(UCALL, $1); } + | direct_declarator '(' ')' { + ctval = tvaloff; + $$ = bdty(UCALL, $1); + } ; -notype: { /* extern int notype, doproto; notype = 0; doproto=1; printf("notype\n"); */ } +fundcl: { if (++blevel == 1) argoff = ARGINIT; ctval = tvaloff; } ; -identifier_list: C_NAME { $$ = bdty(NAME, $1); $$->n_type = FARG; } +identifier_list: C_NAME { + $$ = mkty(FARG, NULL, MKSUE(INT)); + $$->n_sp = lookup($1, 0); + defid($$, PARAM); + } | identifier_list ',' C_NAME { - $$ = bdty(NAME, $3); - $$->n_type = FARG; + $$ = mkty(FARG, NULL, MKSUE(INT)); + $$->n_sp = lookup($3, 0); + defid($$, PARAM); $$ = block(CM, $1, $$, 0, 0, 0); } ; /* * Returns as parameter_list, but can add an additional ELLIPSIS node. - * Calls revert() to get the parameter list in the forward order. */ parameter_type_list: parameter_list { $$ = $1; } @@ -388,8 +409,18 @@ parameter_list: parameter_declaration { $$ = $1; } */ parameter_declaration: declaration_specifiers declarator { + if ($1->n_lval == AUTO || $1->n_lval == TYPEDEF || + $1->n_lval == EXTERN || $1->n_lval == STATIC) + uerror("illegal parameter class"); $$ = tymerge($1, $2); + if (blevel == 1) { + $$->n_sp = lookup((char *)$$->n_sp, 0);/* XXX */ + if (ISFTN($$->n_type)) + $$->n_type = INCREF($$->n_type); + defid($$, PARAM); + } nfree($1); + } | declaration_specifiers abstract_declarator { $$ = tymerge($1, $2); @@ -418,14 +449,14 @@ direct_abstract_declarator: $$ = bdty(LB, $1, $3); } | '(' ')' { $$ = bdty(UCALL, bdty(NAME, NULL)); } - | '(' notype parameter_type_list ')' { - $$ = bdty(CALL, bdty(NAME, NULL), $3); + | '(' parameter_type_list ')' { + $$ = bdty(CALL, bdty(NAME, NULL), $2); } | direct_abstract_declarator '(' ')' { $$ = bdty(UCALL, $1); } - | direct_abstract_declarator '(' notype parameter_type_list ')' { - $$ = bdty(CALL, $1, $4); + | direct_abstract_declarator '(' parameter_type_list ')' { + $$ = bdty(CALL, $1, $3); } ; @@ -496,14 +527,15 @@ moe_list: moe ; moe: C_NAME { moedef($1); } + | C_TYPENAME { moedef($1); } | C_NAME '=' con_e { enummer = $3; moedef($1); } + | C_TYPENAME '=' con_e { enummer = $3; moedef($1); } ; struct_dcl: str_head '{' struct_dcl_list '}' empty { $$ = dclstruct($1); } | C_STRUCT C_NAME { $$ = rstruct($2,$1); } - | C_STRUCT C_TYPENAME { $$ = rstruct($2,$1); } | str_head '{' '}' { #ifndef GCC_COMPAT werror("gcc extension"); @@ -518,7 +550,6 @@ empty: { /* Get yacc read the next token before reducing */ } str_head: C_STRUCT { $$ = bstruct(NULL, $1); } | C_STRUCT C_NAME { $$ = bstruct($2,$1); } - | C_STRUCT C_TYPENAME { $$ = bstruct($2,$1); } ; struct_dcl_list: struct_declaration @@ -549,30 +580,21 @@ struct_declarator_list: struct_declarator: declarator { tymerge($<nodep>0, $1); - $1->n_sp = getsymtab((char *)$1->n_sp, SMOSNAME); /* XXX */ - defid($1, $<nodep>0->n_lval); + soumemb($1, (char *)$1->n_sp, + $<nodep>0->n_lval); /* XXX */ nfree($1); } | ':' con_e { - if (!(instruct&INSTRUCT)) - uerror( "field outside of structure" ); - if ($2 < 0 || $2 >= FIELD) { - uerror("illegal field size"); + if (fldchk($2)) $2 = 1; - } falloc(NULL, $2, -1, $<nodep>0); } | declarator ':' con_e { - if (!(instruct&INSTRUCT)) - uerror( "field outside of structure" ); - if( $3<0 || $3 >= FIELD ){ - uerror( "illegal field size" ); + if (fldchk($3)) $3 = 1; - } if ($1->n_op == NAME) { tymerge($<nodep>0, $1); - $1->n_sp = getsymtab((char *)$1->n_sp,SMOSNAME); - defid($1, FIELD|$3); + soumemb($1, (char *)$1->n_sp, FIELD | $3); nfree($1); } else uerror("illegal declarator"); @@ -632,7 +654,11 @@ designator: '[' con_e ']' { } $$ = bdty(LB, NULL, $2); } - | C_STROP C_NAME { $$ = bdty(NAME, $2); } + | C_STROP C_NAME { + if ($1 != DOT) + uerror("invalid designator"); + $$ = bdty(NAME, $2); + } ; optcomma : /* VOID */ @@ -696,7 +722,7 @@ begin: '{' { } ; -statement: e ';' { ecomp( $1 ); } +statement: e ';' { ecomp( $1 ); symclear(blevel); } | compoundstmt | ifprefix statement { plabel($1); reached = 1; } | ifelprefix statement { @@ -799,8 +825,26 @@ statement: e ';' { ecomp( $1 ); } ; asmstatement: C_ASM '(' string ')' { send_passt(IP_ASM, mkpstr($3)); } + | C_ASM '(' string xasm ')' { mkxasm($3, $4); } + ; + +xasm: ':' oplist { $$ = xcmop($2, NIL, NIL); } + | ':' oplist ':' oplist { $$ = xcmop($2, $4, NIL); } + | ':' oplist ':' oplist ':' cnstr { $$ = xcmop($2, $4, $6); } + ; + +oplist: /* nothing */ { $$ = NIL; } + | oper { $$ = $1; } ; +oper: string '(' e ')' { $$ = xasmop($1, $3); } + | oper ',' string '(' e ')' { $$ = cmop($1, xasmop($3, $5)); } + ; + +cnstr: string { $$ = xasmop($1, bcon(0)); } + | cnstr ',' string { $$ = cmop($1, xasmop($3, bcon(0))); } + ; + label: C_NAME ':' { deflabel($1); reached = 1; } | C_CASE e ':' { addcase($2); reached = 1; } | C_DEFAULT ':' { reached = 1; adddef(); flostat |= FDEF; } @@ -861,7 +905,23 @@ forprefix: C_FOR '(' .e ';' .e ';' { else flostat |= FLOOP; } + | C_FOR '(' incblev declaration .e ';' { + blevel--; + savebc(); + contlab = getlab(); + brklab = getlab(); + plabel( $$ = getlab()); + reached = 1; + if ($5) + cbranch(buildtree(NOT, $5, NIL), bcon(brklab)); + else + flostat |= FLOOP; + } ; + +incblev: { blevel++; } + ; + switchpart: C_SWITCH '(' e ')' { NODE *p; int num; @@ -887,14 +947,14 @@ switchpart: C_SWITCH '(' e ')' { } ; /* EXPRESSIONS */ -con_e: { $<intval>$=instruct; instruct=0; } e %prec ',' { - $$ = icons( $2 ); - instruct=$<intval>1; +con_e: { $<rp>$ = rpole; rpole = NULL; } e %prec ',' { + $$ = icons($2); + rpole = $<rp>1; } ; -nocon_e: { $<intval>$=instruct; instruct=0; } e %prec ',' { - instruct=$<intval>1; +nocon_e: { $<rp>$ = rpole; rpole = NULL; } e %prec ',' { + rpole = $<rp>1; $$ = $2; } ; @@ -979,7 +1039,7 @@ term: term C_INCOP { $$ = buildtree( $2, $1, bcon(1) ); } | C_SIZEOF '(' cast_type ')' %prec C_SIZEOF { $$ = doszof($3); } - | '(' cast_type ')' clbrace init_list '}' { + | '(' cast_type ')' clbrace init_list optcomma '}' { endinit(); spname = $4; $$ = buildtree(NAME, NIL, NIL); @@ -1294,6 +1354,8 @@ init_declarator(NODE *tn, NODE *p, int assign) if (assign) { defid(typ, class); typ->n_sp->sflags |= SASG; + if (typ->n_sp->sflags & SDYNARRAY) + uerror("can't initialize dynamic arrays"); lcommdel(typ->n_sp); } else { nidcl(typ, class); @@ -1315,10 +1377,18 @@ fundef(NODE *tp, NODE *p) { extern int prolab; struct symtab *s; + NODE *q = p; int class = tp->n_lval, oclass; char *c; - /* Enter function args before they are clobbered in tymerge() */ + while (q->n_op == UMUL) + q = q->n_left; + if (q->n_op != CALL && q->n_op != UCALL) { + uerror("invalid function definition"); + p = bdty(UCALL, p); + } + + /* Save function args before they are clobbered in tymerge() */ /* Typecheck against prototype will be done in defid(). */ ftnarg(p); @@ -1344,8 +1414,8 @@ fundef(NODE *tp, NODE *p) prolab = getlab(); c = cftnsp->soname; send_passt(IP_PROLOG, -1, -1, c, cftnsp->stype, - cftnsp->sclass == EXTDEF, prolab); - blevel = 1; + cftnsp->sclass == EXTDEF, prolab, ctval); + blevel++; #ifdef STABS if (gflag) stabs_func(s); @@ -1409,9 +1479,10 @@ static char * mkpstr(char *str) { char *s, *os; - int v, l = strlen(str)+1; + int v, l = strlen(str)+3; /* \t + \n + \0 */ os = s = isinlining ? permalloc(l) : tmpalloc(l); + *s++ = '\t'; for (; *str; ) { if (*str++ == '\\') v = esccon(&str); @@ -1419,6 +1490,7 @@ mkpstr(char *str) v = str[-1]; *s++ = v; } + *s++ = '\n'; *s = 0; return os; } @@ -1445,3 +1517,90 @@ clbrace(NODE *p) beginit(sp); return sp; } + +/* Support for extended assembler a' la' gcc style follows below */ + +static NODE * +cmop(NODE *l, NODE *r) +{ + return block(CM, l, r, INT, 0, MKSUE(INT)); +} + +static NODE * +voidcon(void) +{ + return block(ICON, NIL, NIL, STRTY, 0, MKSUE(VOID)); +} + +static NODE * +xmrg(NODE *out, NODE *in) +{ + NODE *p = in; + + if (p->n_op == XARG) { + in = cmop(out, p); + } else { + while (p->n_left->n_op == CM) + p = p->n_left; + p->n_left = cmop(out, p->n_left); + } + return in; +} + +/* + * Put together in and out node lists in one list, and balance it with + * the constraints on the right side of a CM node. + */ +static NODE * +xcmop(NODE *out, NODE *in, NODE *str) +{ + NODE *p, *q; + + if (out) { + /* D out-list sanity check */ + for (p = out; p->n_op == CM; p = p->n_left) { + q = p->n_right; + if (q->n_name[0] != '=') + uerror("output missing ="); + } + if (p->n_name[0] != '=') + uerror("output missing ="); + if (in == NIL) + p = out; + else + p = xmrg(out, in); + } else if (in) { + p = in; + } else + p = voidcon(); + + if (str == NIL) + str = voidcon(); + return cmop(p, str); +} + +/* + * Generate a XARG node based on a string and an expression. + */ +static NODE * +xasmop(char *str, NODE *p) +{ + + p = block(XARG, p, NIL, INT, 0, MKSUE(INT)); + p->n_name = str; + return p; +} + +/* + * Generate a XASM node based on a string and an expression. + */ +static void +mkxasm(char *str, NODE *p) +{ + NODE *q; + + q = block(XASM, p->n_left, p->n_right, INT, 0, MKSUE(INT)); + q->n_name = str; + nfree(p); + ecomp(q); +} diff --git a/usr.bin/pcc/ccom/gcc_compat.c b/usr.bin/pcc/ccom/gcc_compat.c index 4148cd4ead4..1f8920623e6 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.4 2008/01/12 17:26:16 ragge Exp $ */ +/* $OpenBSD: gcc_compat.c,v 1.5 2008/04/11 20:45:52 stefan Exp $ */ /* * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -50,6 +50,7 @@ static struct kw { { "__const", NULL, 0 }, { "__asm__", NULL, C_ASM }, { "__inline__", NULL, C_FUNSPEC }, + { "__thread", NULL, 0 }, { NULL, NULL, 0 }, }; @@ -63,12 +64,15 @@ gcc_init() } +#define TS "\n#pragma tls\n# %d\n" +#define TLLEN sizeof(TS)+10 /* * See if a string matches a gcc keyword. */ int gcc_keyword(char *str, NODE **n) { + char tlbuf[TLLEN], *tw; struct kw *kwp; int i; @@ -86,6 +90,12 @@ gcc_keyword(char *str, NODE **n) case 3: /* __const */ *n = block(QUALIFIER, NIL, NIL, CON, 0, 0); return C_QUALIFIER; + case 6: /* __thread */ + snprintf(tlbuf, TLLEN, TS, lineno); + tw = &tlbuf[strlen(tlbuf)]; + while (tw > tlbuf) + cunput(*--tw); + return -1; } cerror("gcc_keyword"); return 0; diff --git a/usr.bin/pcc/ccom/init.c b/usr.bin/pcc/ccom/init.c index 8e800c84cb9..f4ced795f23 100644 --- a/usr.bin/pcc/ccom/init.c +++ b/usr.bin/pcc/ccom/init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init.c,v 1.6 2008/01/12 17:26:16 ragge Exp $ */ +/* $OpenBSD: init.c,v 1.7 2008/04/11 20:45:52 stefan Exp $ */ /* * Copyright (c) 2004, 2007 Anders Magnusson (ragge@ludd.ltu.se). @@ -118,8 +118,8 @@ int idebug; */ static struct instk { struct instk *in_prev; /* linked list */ - struct symtab **in_xp; /* member in structure initializations */ - struct symtab *in_sym; /* stab index */ + struct symtab *in_lnk; /* member in structure initializations */ + struct symtab *in_sym; /* symtab index */ union dimfun *in_df; /* dimenston of array */ TWORD in_t; /* type for this level */ int in_n; /* number of arrays seen so far */ @@ -231,7 +231,7 @@ beginit(struct symtab *sp) curll = ll = getll(); /* at least first entry in list */ /* first element */ - is->in_xp = ISSOU(sp->stype) ? sp->ssue->suelem : NULL; + is->in_lnk = ISSOU(sp->stype) ? sp->ssue->sylnk : NULL; is->in_n = 0; is->in_t = sp->stype; is->in_sym = sp; @@ -279,22 +279,22 @@ stkpush(void) is->in_n = 0; if (pstk == NULL) { /* stack empty */ - is->in_xp = ISSOU(sp->stype) ? sp->ssue->suelem : NULL; + is->in_lnk = ISSOU(sp->stype) ? sp->ssue->sylnk : NULL; is->in_t = sp->stype; is->in_sym = sp; is->in_df = sp->sdf; } else if (ISSOU(t)) { - sq = *pstk->in_xp; + sq = pstk->in_lnk; if (sq == NULL) { uerror("excess of initializing elements"); } else { - is->in_xp = ISSOU(sq->stype) ? sq->ssue->suelem : 0; + is->in_lnk = ISSOU(sq->stype) ? sq->ssue->sylnk : 0; is->in_t = sq->stype; is->in_sym = sq; is->in_df = sq->sdf; } } else if (ISARY(t)) { - is->in_xp = ISSOU(DECREF(t)) ? pstk->in_sym->ssue->suelem : 0; + is->in_lnk = ISSOU(DECREF(t)) ? pstk->in_sym->ssue->sylnk : 0; is->in_t = DECREF(t); is->in_sym = sp; if (pstk->in_df->ddim && pstk->in_n >= pstk->in_df->ddim) { @@ -329,9 +329,9 @@ stkpop(void) printf("stkpop\n"); #endif for (; pstk; pstk = pstk->in_prev) { - if (pstk->in_t == STRTY && pstk->in_xp[0] != NULL) { - pstk->in_xp++; - if (*pstk->in_xp != NULL) + if (pstk->in_t == STRTY && pstk->in_lnk != NULL) { + pstk->in_lnk = pstk->in_lnk->snext; + if (pstk->in_lnk != NULL) break; } if (ISSOU(pstk->in_t) && pstk->in_fl) @@ -716,8 +716,9 @@ irbrace() if (ISARY(pstk->in_t)) pstk->in_n = pstk->in_df->ddim; else if (pstk->in_t == STRTY) { - while (pstk->in_xp[0] != NULL && pstk->in_xp[1] != NULL) - pstk->in_xp++; + while (pstk->in_lnk != NULL && + pstk->in_lnk->snext != NULL) + pstk->in_lnk = pstk->in_lnk->snext; } stkpop(); return; @@ -751,11 +752,11 @@ mkstack(NODE *p) break; case NAME: - if (pstk->in_xp) { - for (; pstk->in_xp[0]; pstk->in_xp++) - if (pstk->in_xp[0]->sname == (char *)p->n_sp) + if (pstk->in_lnk) { + for (; pstk->in_lnk; pstk->in_lnk = pstk->in_lnk->snext) + if (pstk->in_lnk->sname == (char *)p->n_sp) break; - if (pstk->in_xp[0] == NULL) + if (pstk->in_lnk == NULL) uerror("member missing"); } else { uerror("not a struct/union"); @@ -783,7 +784,7 @@ desinit(NODE *p) pstk = pstk->in_prev; /* Empty stack */ if (ISSOU(pstk->in_t)) - pstk->in_xp = pstk->in_sym->ssue->suelem; + pstk->in_lnk = pstk->in_sym->ssue->sylnk; mkstack(p); /* Setup for assignment */ @@ -889,8 +890,8 @@ prtstk(struct instk *in) if (in->in_fl) printf("{ "); printf("soff=%d ", in->in_sym->soffset); if (in->in_t == STRTY) { - if (in->in_xp && in->in_xp[0]) - printf("curel %s ", in->in_xp[0]->sname); + if (in->in_lnk) + printf("curel %s ", in->in_lnk->sname); else printf("END struct"); } diff --git a/usr.bin/pcc/ccom/main.c b/usr.bin/pcc/ccom/main.c index cd3604cc12c..de88379c9e8 100644 --- a/usr.bin/pcc/ccom/main.c +++ b/usr.bin/pcc/ccom/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.4 2007/12/09 18:50:01 ragge Exp $ */ +/* $OpenBSD: main.c,v 1.5 2008/04/11 20:45:52 stefan Exp $ */ /* * Copyright (c) 2002 Anders Magnusson. All rights reserved. @@ -34,7 +34,7 @@ #include "pass1.h" #include "pass2.h" -int sflag, nflag, oflag, kflag; +int sflag, nflag, oflag, kflag, pflag; int lflag, odebug, rdebug, s2debug, udebug, x2debug; #if !defined(MULTIPASS) || defined(PASST) int iTflag, oTflag; @@ -92,6 +92,10 @@ Wflags(char *str) Wimplicit_int = Wimplicit_function_declaration = 1; return; } + if (strcmp(str, "error") == 0) { + warniserr = 1; + return; + } all = strcmp(str, "W") == 0; for (i = 0; flagstr[i].n; i++) if (all || strcmp(flagstr[i].n, str) == 0) { @@ -112,7 +116,7 @@ main(int argc, char *argv[]) prgname = argv[0]; - while ((ch = getopt(argc, argv, "VlwX:Z:W:sOT:gx:kvm:")) != -1) + while ((ch = getopt(argc, argv, "OT:VW:X:Z:gklm:psvwx:")) != -1) switch (ch) { #if !defined(MULTIPASS) || defined(PASS1) case 'X': @@ -202,6 +206,10 @@ main(int argc, char *argv[]) gflag = 1; break; + case 'p': /* Profiling */ + pflag = 1; + break; + case 's': /* Statistics */ ++sflag; break; diff --git a/usr.bin/pcc/ccom/optim.c b/usr.bin/pcc/ccom/optim.c index e4b48144cd5..6ae9991a6c4 100644 --- a/usr.bin/pcc/ccom/optim.c +++ b/usr.bin/pcc/ccom/optim.c @@ -1,4 +1,4 @@ -/* $OpenBSD: optim.c,v 1.2 2007/11/18 17:39:55 ragge Exp $ */ +/* $OpenBSD: optim.c,v 1.3 2008/04/11 20:45:52 stefan Exp $ */ /* * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. * @@ -43,8 +43,6 @@ # define LO(p) p->n_left->n_op # define LV(p) p->n_left->n_lval -static int nncon(NODE *); - int oflag = 0; /* remove left node */ diff --git a/usr.bin/pcc/ccom/pass1.h b/usr.bin/pcc/ccom/pass1.h index aa9bb3758b9..960e0f40de1 100644 --- a/usr.bin/pcc/ccom/pass1.h +++ b/usr.bin/pcc/ccom/pass1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pass1.h,v 1.8 2008/01/12 17:26:16 ragge Exp $ */ +/* $OpenBSD: pass1.h,v 1.9 2008/04/11 20:45:52 stefan Exp $ */ /* * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. * @@ -90,6 +90,9 @@ extern char *scnames(int); #define SINLINE 00400 #define STNODE 01000 #define SASG 04000 +#define SLOCAL1 010000 +#define SLOCAL2 020000 +#define SLOCAL3 040000 /* alignment of initialized quantities */ #ifndef AL_INIT @@ -116,7 +119,7 @@ union dimfun { */ struct suedef { int suesize; /* Size of the struct */ - struct symtab **suelem;/* points to the list of elements */ + struct symtab *sylnk; /* the list of elements */ int suealign; /* Alignment of this struct */ }; @@ -206,12 +209,6 @@ extern int pragma_packed, pragma_aligned; extern char *pragma_renamed; /* - * Flags used in structures/unions - */ -#define INSTRUCT 02 -#define INUNION 04 - -/* * Flags used in the (elementary) flow analysis ... */ #define FBRK 02 @@ -256,6 +253,7 @@ OFFSZ tsize(TWORD, union dimfun *, struct suedef *), NODE * typenode(NODE *new); void spalloc(NODE *, NODE *, OFFSZ); char *exname(char *); +extern struct rstack *rpole; int oalloc(struct symtab *p, int *poff); void deflabel(char *); @@ -278,6 +276,7 @@ char *addname(char *); char *newstring(char *, int len); void symclear(int level); struct symtab *hide(struct symtab *p); +void soumemb(NODE *, char *, int); int talign(unsigned int, struct suedef *); void bfcode(struct symtab **, int); int chkftn(union arglist *, union arglist *); @@ -305,7 +304,6 @@ void endinit(void); void ilbrace(void); void irbrace(void); void scalinit(NODE *p); -int ftoint(NODE *, CONSZ **); void p1print(char *fmt, ...); char *copst(int); int cdope(int); @@ -321,6 +319,10 @@ int mypragma(char **); void fixdef(struct symtab *); int cqual(TWORD t, TWORD q); void defloc(struct symtab *); +int fldchk(int sz); +int nncon(NODE *); +void cunput(char c); + #ifdef GCC_COMPAT void gcc_init(void); diff --git a/usr.bin/pcc/ccom/pftn.c b/usr.bin/pcc/ccom/pftn.c index f70636f73d7..55d2925688e 100644 --- a/usr.bin/pcc/ccom/pftn.c +++ b/usr.bin/pcc/ccom/pftn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pftn.c,v 1.12 2008/01/12 17:26:16 ragge Exp $ */ +/* $OpenBSD: pftn.c,v 1.13 2008/04/11 20:45:52 stefan Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -73,18 +73,16 @@ struct symtab *spname; struct symtab *cftnsp; -static int strunem; /* currently parsed member type */ int arglistcnt, dimfuncnt; /* statistics */ int symtabcnt, suedefcnt; /* statistics */ int autooff, /* the next unused automatic offset */ maxautooff, /* highest used automatic offset in function */ - argoff, /* the next unused argument offset */ - strucoff; /* the next structure offset position */ + argoff; /* the next unused argument offset */ int retlab = NOLAB; /* return label for subroutine */ int brklab; int contlab; int flostat; -int instruct, blevel; +int blevel; int reached, prolab; struct params; @@ -99,12 +97,11 @@ struct params; */ struct rstack { struct rstack *rnext; - int rinstruct; - int rclass; - int rstrucoff; - struct params *rlparam; + int rsou; + int rstr; struct symtab *rsym; -}; + struct symtab *rb; +} *rpole; /* * Linked list for parameter (and struct elements) declaration. @@ -120,6 +117,7 @@ static int nparams; static NODE *arrstk[10]; static int arrstkp; static int intcompare; +static NODE *parlink; void fixtype(NODE *p, int class); int fixclass(int class, TWORD type); @@ -187,14 +185,13 @@ defid(NODE *q, int class) if (blevel == 1) { switch (class) { default: - if (!(class&FIELD)) + if (!(class&FIELD) && !ISFTN(type)) uerror("declared argument %s missing", p->sname ); case MOS: - case STNAME: case MOU: - case UNAME: case TYPEDEF: + case PARAM: ; } } @@ -242,9 +239,7 @@ defid(NODE *q, int class) #endif /* check that redeclarations are to the same structure */ - if ((temp == STRTY || temp == UNIONTY) && - p->ssue != q->n_sue && - class != STNAME && class != UNAME) { + if ((temp == STRTY || temp == UNIONTY) && p->ssue != q->n_sue) { goto mismatch; } @@ -255,15 +250,9 @@ defid(NODE *q, int class) printf(" previous class: %s\n", scnames(scl)); #endif - if (class&FIELD) { - /* redefinition */ - if (!falloc(p, class&FLDSIZ, 1, NIL)) { - /* successful allocation */ - ssave(p); - return; - } - /* blew it: resume at end of switch... */ - } else switch(class) { + if (class & FIELD) + return; + switch(class) { case EXTERN: switch( scl ){ @@ -312,15 +301,7 @@ defid(NODE *q, int class) case MOU: case MOS: - if (scl == class) { - if (oalloc(p, &strucoff)) - break; - if (class == MOU) - strucoff = 0; - ssave(p); - return; - } - break; + return; case EXTDEF: switch (scl) { @@ -333,16 +314,10 @@ defid(NODE *q, int class) } break; - case STNAME: - case UNAME: - if (scl != class) - break; - if (p->ssue->suesize == 0) - return; /* previous entry just a mention */ - break; - case AUTO: case REGISTER: + if (blevel == slev) + goto redec; ; /* mismatch.. */ } @@ -354,12 +329,12 @@ defid(NODE *q, int class) if (blevel == slev || class == EXTERN || class == FORTRAN || class == UFORTRAN) { if (ISSTR(class) && !ISSTR(p->sclass)) { - uerror("redeclaration of %s", p->sname); +redec: uerror("redeclaration of %s", p->sname); return; } } if (blevel == 0) - uerror("redeclaration of %s", p->sname); + goto redec; q->n_sp = p = hide(p); enter: /* make a new entry */ @@ -373,27 +348,9 @@ defid(NODE *q, int class) p->sclass = class; p->slevel = blevel; p->soffset = NOOFFSET; - if (class == STNAME || class == UNAME) { - p->ssue = permalloc(sizeof(struct suedef)); - suedefcnt++; - p->ssue->suesize = 0; - p->ssue->suelem = NULL; - p->ssue->suealign = ALSTRUCT; - } else { - if (q->n_sue == NULL) - cerror("q->n_sue == NULL"); - p->ssue = q->n_sue; -#if 0 - switch (BTYPE(type)) { - case STRTY: - case UNIONTY: - p->ssue = q->n_sue; - break; - default: - p->ssue = MKSUE(BTYPE(type)); - } -#endif - } + if (q->n_sue == NULL) + cerror("q->n_sue == NULL"); + p->ssue = q->n_sue; /* copy dimensions */ p->sdf = q->n_df; @@ -404,7 +361,6 @@ defid(NODE *q, int class) /* allocate offsets */ if (class&FIELD) { (void) falloc(p, class&FLDSIZ, 0, NIL); /* new entry */ - ssave(p); } else switch (class) { case REGISTER: @@ -416,6 +372,18 @@ defid(NODE *q, int class) else oalloc(p, &autooff); break; + case PARAM: + if (ISARY(p->stype)) { + /* remove array type on parameters before oalloc */ + p->stype += (PTR-ARY); + p->sdf++; + } + if (arrstkp) + dynalloc(p, &argoff); + else + oalloc(p, &argoff); + break; + case STATIC: case EXTDEF: case EXTERN: @@ -429,10 +397,9 @@ defid(NODE *q, int class) case MOU: case MOS: - oalloc(p, &strucoff); + oalloc(p, &rpole->rstr); if (class == MOU) - strucoff = 0; - ssave(p); + rpole->rstr = 0; break; } @@ -458,13 +425,10 @@ ssave(struct symtab *sym) p->next = NULL; p->sym = sym; - if (lparam == NULL) { - p->prev = (struct params *)&lpole; + if ((p->prev = lparam) == NULL) lpole = p; - } else { + else lparam->next = p; - p->prev = lparam; - } lparam = p; } @@ -476,6 +440,7 @@ ftnend() { extern struct savbc *savbc; extern struct swdef *swpole; + extern int tvaloff; char *c; if (retlab != NOLAB && nerrors == 0) { /* inside a real function */ @@ -484,7 +449,7 @@ ftnend() c = cftnsp->soname; SETOFF(maxautooff, ALCHAR); send_passt(IP_EPILOG, 0, maxautooff/SZCHAR, c, - cftnsp->stype, cftnsp->sclass == EXTDEF, retlab); + cftnsp->stype, cftnsp->sclass == EXTDEF, retlab, tvaloff); } tcheck(); @@ -510,6 +475,10 @@ ftnend() tmpfree(); /* Release memory resources */ } +static struct symtab nulsym = { + { NULL, 0, 0, 0, 0 }, "null", "null", INT, 0, NULL, NULL +}; + void dclargs() { @@ -517,15 +486,12 @@ dclargs() union arglist *al, *al2, *alb; struct params *a; struct symtab *p, **parr = NULL; /* XXX gcc */ - char *c; int i; - argoff = ARGINIT; - /* * Deal with fun(void) properly. */ - if (nparams == 1 && lparam->sym->stype == VOID) + if (nparams == 1 && lparam->sym && lparam->sym->stype == VOID) goto done; /* @@ -536,11 +502,13 @@ dclargs() parr = tmpalloc(sizeof(struct symtab *) * nparams); if (nparams) - for (a = lparam, i = 0; a != NULL && a != (struct params *)&lpole; - a = a->prev) { - + for (a = lparam, i = 0; a != NULL; a = a->prev) { p = a->sym; parr[i++] = p; + if (p == NULL) { + uerror("parameter %d name missing", i); + p = &nulsym; /* empty symtab */ + } if (p->stype == FARG) { p->stype = INT; p->ssue = MKSUE(INT); @@ -552,8 +520,6 @@ dclargs() werror("function declared as argument"); p->stype = INCREF(p->stype); } - /* always set aside space, even for register arguments */ - oalloc(p, &argoff); #ifdef STABS if (gflag) stabs_newsym(p); @@ -579,59 +545,47 @@ dclargs() if (chkftn(al, alb)) uerror("function doesn't match prototype"); intcompare = 0; + + } + + if (oldstyle && nparams) { + /* Must recalculate offset for oldstyle args here */ + argoff = ARGINIT; + for (i = 0; i < nparams; i++) { + parr[i]->soffset = NOOFFSET; + oalloc(parr[i], &argoff); + } } + done: cendarg(); - c = cftnsp->soname; -#if 0 - prolab = getlab(); - send_passt(IP_PROLOG, -1, -1, c, cftnsp->stype, - cftnsp->sclass == EXTDEF, prolab); -#endif + plabel(prolab); /* after prolog, used in optimization */ retlab = getlab(); bfcode(parr, nparams); plabel(getlab()); /* used when spilling */ + if (parlink) + ecomp(parlink); + parlink = NIL; lparam = NULL; nparams = 0; + symclear(1); /* In case of function pointer args */ } /* - * reference to a structure or union, with no definition + * Struct/union/enum symtab construction. */ -NODE * -rstruct(char *tag, int soru) +static void +defstr(struct symtab *sp, int class) { - struct symtab *p; - NODE *q; - - p = (struct symtab *)lookup(tag, STAGNAME); - switch (p->stype) { - - case UNDEF: - def: - q = block(NAME, NIL, NIL, 0, 0, 0); - q->n_sp = p; - q->n_type = (soru&INSTRUCT) ? STRTY : - ((soru&INUNION) ? UNIONTY : 0); - defid(q, (soru&INSTRUCT) ? STNAME : - ((soru&INUNION) ? UNAME : 0)); - nfree(q); - break; - - case STRTY: - if (soru & INSTRUCT) - break; - goto def; - - case UNIONTY: - if (soru & INUNION) - break; - goto def; - - } - q = mkty(p->stype, 0, p->ssue); - q->n_sue = p->ssue; - return q; + sp->ssue = permalloc(sizeof(struct suedef)); + sp->ssue->suesize = 0; + sp->ssue->sylnk = NULL; + sp->ssue->suealign = 0; + sp->sclass = class; + if (class == STNAME) + sp->stype = STRTY; + else if (class == UNAME) + sp->stype = UNIONTY; } /* @@ -643,23 +597,26 @@ deftag(char *name, int class) { struct symtab *sp; - sp = lookup(name, STAGNAME); - if (sp->ssue == NULL) - sp->ssue = permalloc(sizeof(struct suedef)); - if (sp->sclass == SNULL) { + if ((sp = lookup(name, STAGNAME))->ssue == NULL) { /* New tag */ - sp->sclass = class; - } else if (sp->slevel < blevel) { - /* declared at different block level, hide it */ - sp = hide(sp); - sp->sclass = class; - } else if (sp->sclass != class) { - /* redeclaration of tag */ + defstr(sp, class); + } else if (sp->sclass != class) uerror("tag %s redeclared", name); - } return sp; } +/* + * reference to a structure or union, with no definition + */ +NODE * +rstruct(char *tag, int soru) +{ + struct symtab *sp; + + sp = deftag(tag, soru); + return mkty(sp->stype, 0, sp->ssue); +} + static int enumlow, enumhigh; int enummer; @@ -701,8 +658,12 @@ enumhd(char *name) return NULL; sp = deftag(name, ENAME); - if (sp->stype != UNDEF) /* enum type already declared */ - uerror("%s redeclared", name); + if (sp->stype != UNDEF) { + if (sp->slevel == blevel) + uerror("%s redeclared", name); + sp = hide(sp); + defstr(sp, ENAME); + } return sp; } @@ -759,39 +720,28 @@ struct rstack * bstruct(char *name, int soru) { struct rstack *r; - struct symtab *s; - NODE *q; + struct symtab *sp; - if (name != NULL) - s = lookup(name, STAGNAME); - else - s = NULL; + if (name != NULL) { + sp = deftag(name, soru); + if (sp->ssue->suealign != 0) { + if (sp->slevel < blevel) { + sp = hide(sp); + defstr(sp, soru); + } else + uerror("%s redeclared", name); + } + sp->ssue->suealign = ALSTRUCT; + } else + sp = NULL; r = tmpalloc(sizeof(struct rstack)); - r->rinstruct = instruct; - r->rclass = strunem; - r->rstrucoff = strucoff; - - strucoff = 0; - instruct = soru; - q = block(NAME, NIL, NIL, 0, 0, 0); - q->n_sp = s; - if (instruct==INSTRUCT) { - strunem = MOS; - q->n_type = STRTY; - if (s != NULL) - defid(q, STNAME); - } else if(instruct == INUNION) { - strunem = MOU; - q->n_type = UNIONTY; - if (s != NULL) - defid(q, UNAME); - } else { - cerror("bstruct"); - } - r->rsym = q->n_sp; - r->rlparam = lparam; - nfree(q); + r->rsou = soru; + r->rstr = 0; + r->rsym = sp; + r->rb = NULL; + r->rnext = rpole; + rpole = r; return r; } @@ -803,12 +753,10 @@ NODE * dclstruct(struct rstack *r) { NODE *n; - struct params *l, *m; struct suedef *sue; - struct symtab *p; + struct symtab *sp; int al, sa, sz, coff; TWORD temp; - int i, high, low; if (r->rsym == NULL) { sue = permalloc(sizeof(struct suedef)); @@ -817,65 +765,49 @@ dclstruct(struct rstack *r) sue->suealign = ALSTRUCT; } else sue = r->rsym->ssue; + if (sue->suealign == 0) /* suealign == 0 is undeclared struct */ + sue->suealign = ALSTRUCT; #ifdef PCC_DEBUG if (ddebug) printf("dclstruct(%s)\n", r->rsym ? r->rsym->sname : "??"); #endif - temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:0); - instruct = r->rinstruct; - strunem = r->rclass; + temp = r->rsou == STNAME ? STRTY : UNIONTY; al = ALSTRUCT; - high = low = 0; - - if ((l = r->rlparam) == NULL) - l = lpole; - else - l = l->next; - - /* memory for the element array must be allocated first */ - for (m = l, i = 1; m != NULL; m = m->next) - i++; - sue->suelem = permalloc(sizeof(struct symtab *) * i); - coff = 0; if (pragma_packed || pragma_aligned) - strucoff = 0; /* must recount it */ - - for (i = 0; l != NULL; l = l->next) { - sue->suelem[i++] = p = l->sym; + rpole->rstr = 0; /* must recount it */ - if (p == NULL) - cerror("gummy structure member"); - sa = talign(p->stype, p->ssue); - if (p->sclass & FIELD) - sz = p->sclass&FLDSIZ; + sue->sylnk = r->rb; + for (sp = r->rb; sp; sp = sp->snext) { + sa = talign(sp->stype, sp->ssue); + if (sp->sclass & FIELD) + sz = sp->sclass&FLDSIZ; else - sz = tsize(p->stype, p->sdf, p->ssue); + sz = tsize(sp->stype, sp->sdf, sp->ssue); if (pragma_packed || pragma_aligned) { /* XXX check pack/align sizes */ - p->soffset = coff; + sp->soffset = coff; if (pragma_aligned) coff += ALLDOUBLE; else coff += sz; - strucoff = coff; + rpole->rstr = coff; } - if (sz > strucoff) - strucoff = sz; /* for use with unions */ + if (sz > rpole->rstr) + rpole->rstr = sz; /* for use with unions */ /* * set al, the alignment, to the lcm of the alignments * of the members. */ SETOFF(al, sa); } - sue->suelem[i] = NULL; - SETOFF(strucoff, al); + SETOFF(rpole->rstr, al); - sue->suesize = strucoff; + sue->suesize = rpole->rstr; sue->suealign = al; pragma_packed = pragma_aligned = 0; @@ -887,25 +819,47 @@ dclstruct(struct rstack *r) #ifdef PCC_DEBUG if (ddebug>1) { - int i; - - printf("\tsize %d align %d elem %p\n", - sue->suesize, sue->suealign, sue->suelem); - for (i = 0; sue->suelem[i] != NULL; ++i) { - printf("\tmember %s(%p)\n", - sue->suelem[i]->sname, sue->suelem[i]); + printf("\tsize %d align %d link %p\n", + sue->suesize, sue->suealign, sue->sylnk); + for (sp = sue->sylnk; sp != NULL; sp = sp->snext) { + printf("\tmember %s(%p)\n", sp->sname, sp); } } #endif - strucoff = r->rstrucoff; - if ((lparam = r->rlparam) != NULL) - lparam->next = NULL; + rpole = r->rnext; n = mkty(temp, 0, sue); return n; } /* + * Add a new member to the current struct or union being declared. + */ +void +soumemb(NODE *n, char *name, int class) +{ + struct symtab *sp, *lsp; + + if (rpole == NULL) + cerror("soumemb"); + + lsp = NULL; + for (sp = rpole->rb; sp != NULL; lsp = sp, sp = sp->snext) + if (sp->sname == name) + uerror("redeclaration of %s", name); + + sp = getsymtab(name, SMOSNAME); + if (rpole->rb == NULL) + rpole->rb = sp; + else + lsp->snext = sp; + n->n_sp = sp; + defid(n, class); +} + + + +/* * error printing routine in parser */ void yyerror(char *s); @@ -930,74 +884,44 @@ void ftnarg(NODE *p) { NODE *q; - struct symtab *s; #ifdef PCC_DEBUG if (ddebug > 2) printf("ftnarg(%p)\n", p); #endif /* - * Enter argument onto param stack. - * Do not declare parameters until later (in dclargs); - * the function must be declared first. - * put it on the param stack in reverse order, due to the - * nature of the stack it will be reclaimed correct. + * Push argument symtab entries onto param stack in reverse order, + * due to the nature of the stack it will be reclaimed correct. */ for (; p->n_op != NAME; p = p->n_left) { - if (p->n_op == (UCALL) && p->n_left->n_op == NAME) + if (p->n_op == UCALL && p->n_left->n_op == NAME) return; /* Nothing to enter */ if (p->n_op == CALL && p->n_left->n_op == NAME) break; } p = p->n_right; - blevel = 1; - while (p->n_op == CM) { q = p->n_right; if (q->n_op != ELLIPSIS) { - s = lookup((char *)q->n_sp, 0); - if (s->stype != UNDEF) { - if (s->slevel > 0) - uerror("parameter '%s' redefined", - s->sname); - s = hide(s); - } - s->soffset = NOOFFSET; - s->sclass = PARAM; - s->stype = q->n_type; - s->sdf = q->n_df; - s->ssue = q->n_sue; - ssave(s); + ssave(q->n_sp); nparams++; #ifdef PCC_DEBUG if (ddebug > 2) printf(" saving sym %s (%p) from (%p)\n", - s->sname, s, q); + q->n_sp->sname, q->n_sp, q); #endif } p = p->n_left; } - s = lookup((char *)p->n_sp, 0); - if (s->stype != UNDEF) { - if (s->slevel > 0) - uerror("parameter '%s' redefined", s->sname); - s = hide(s); - } - s->soffset = NOOFFSET; - s->sclass = PARAM; - s->stype = p->n_type; - s->sdf = p->n_df; - s->ssue = p->n_sue; - ssave(s); + ssave(p->n_sp); if (p->n_type != VOID) nparams++; - blevel = 0; #ifdef PCC_DEBUG if (ddebug > 2) printf(" saving sym %s (%p) from (%p)\n", - s->sname, s, p); + nparams ? p->n_sp->sname : "<noname>", p->n_sp, p); #endif } @@ -1103,7 +1027,7 @@ tsize(TWORD ty, union dimfun *d, struct suedef *sue) return(SZINT); } } else { - if (sue->suelem == NULL) + if (sue->suealign == 0) uerror("unknown structure/union/enum"); } @@ -1221,7 +1145,7 @@ oalloc(struct symtab *p, int *poff ) } else #endif if (p->sclass == PARAM && (p->stype == CHAR || p->stype == UCHAR || - p->stype == SHORT || p->stype == USHORT)) { + p->stype == SHORT || p->stype == USHORT || p->stype == BOOL)) { off = upoff(SZINT, ALINT, &noff); #ifndef RTOLBYTES off = noff - tsz; @@ -1243,7 +1167,24 @@ oalloc(struct symtab *p, int *poff ) } /* - * Allocate space on the stack for dynamic arrays. + * Delay emission of code generated in argument headers. + */ +static void +edelay(NODE *p) +{ + if (blevel == 1) { + /* Delay until after declarations */ + if (parlink == NULL) + parlink = p; + else + parlink = block(COMOP, parlink, p, 0, 0, 0); + } else + ecomp(p); +} + +/* + * Allocate space on the stack for dynamic arrays (or at least keep track + * of the index). * Strategy is as follows: * - first entry is a pointer to the dynamic datatype. * - if it's a one-dimensional array this will be the only entry used. @@ -1258,41 +1199,66 @@ dynalloc(struct symtab *p, int *poff) union dimfun *df; NODE *n, *nn, *tn, *pol; TWORD t; - int i, no; + int astkp, no; /* - * The pointer to the array is stored in a TEMP node, which number - * is in the soffset field; + * The pointer to the array is not necessarily stored in a + * TEMP node, but if it is, its number is in the soffset field; */ t = p->stype; - 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 = regno(tn); + astkp = 0; + if (ISARY(t) && blevel == 1) { + /* must take care of side effects of dynamic arg arrays */ + if (p->sdf->ddim < 0) { + /* first-level array will be indexed correct */ + edelay(arrstk[astkp++]); + } + p->sdf++; + p->stype += (PTR-ARY); + t = p->stype; + } + if (ISARY(t)) { + 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 = regno(tn); + } else { + oalloc(p, poff); + tn = NIL; + } df = p->sdf; pol = NIL; - for (i = 0; ISARY(t); t = DECREF(t), df++) { - if (df->ddim >= 0) + for (; t > BTMASK; t = DECREF(t)) { + if (!ISARY(t)) continue; - n = arrstk[i++]; - nn = tempnode(0, INT, 0, MKSUE(INT)); - no = regno(nn); - ecomp(buildtree(ASSIGN, nn, n)); /* Save size */ + if (df->ddim < 0) { + n = arrstk[astkp++]; + nn = tempnode(0, INT, 0, MKSUE(INT)); + no = regno(nn); + edelay(buildtree(ASSIGN, nn, n)); + + df->ddim = -no; + n = tempnode(no, INT, 0, MKSUE(INT)); + } else + n = bcon(df->ddim); - df->ddim = -no; - n = tempnode(no, INT, 0, MKSUE(INT)); - if (pol == NIL) - pol = n; - else - pol = buildtree(MUL, pol, n); + pol = (pol == NIL ? n : buildtree(MUL, pol, n)); + df++; } /* Create stack gap */ - if (pol == NIL) - uerror("aggregate dynamic array not allowed"); - else - spalloc(tn, pol, tsize(t, 0, p->ssue)); + if (blevel == 1) { + if (tn) + tfree(tn); + if (pol) + tfree(pol); + } else { + if (pol == NIL) + uerror("aggregate dynamic array not allowed"); + if (tn) + spalloc(tn, pol, tsize(t, 0, p->ssue)); + } arrstkp = 0; } @@ -1343,24 +1309,24 @@ falloc(struct symtab *p, int w, int new, NODE *pty) } if( w == 0 ){ /* align only */ - SETOFF( strucoff, al ); + SETOFF( rpole->rstr, al ); if( new >= 0 ) uerror( "zero size field"); return(0); } - if( strucoff%al + w > sz ) SETOFF( strucoff, al ); + if( rpole->rstr%al + w > sz ) SETOFF( rpole->rstr, al ); if( new < 0 ) { - strucoff += w; /* we know it will fit */ + rpole->rstr += w; /* we know it will fit */ return(0); } /* establish the field */ if( new == 1 ) { /* previous definition */ - if( p->soffset != strucoff || p->sclass != (FIELD|w) ) return(1); + if( p->soffset != rpole->rstr || p->sclass != (FIELD|w) ) return(1); } - p->soffset = strucoff; - strucoff += w; + p->soffset = rpole->rstr; + rpole->rstr += w; p->stype = type; fldty( p ); return(0); @@ -1382,7 +1348,7 @@ nidcl(NODE *p, int class) if (class == SNULL) { if (blevel > 1) class = AUTO; - else if (blevel != 0 || instruct) + else if (blevel != 0 || rpole) cerror( "nidcl error" ); else /* blevel = 0 */ commflag = 1, class = EXTERN; @@ -1498,8 +1464,8 @@ typenode(NODE *p) type = class = qual = sig = uns = 0; saved = NIL; - if (strunem != 0) - class = strunem; + if (rpole != NULL) + class = rpole->rsou == STNAME ? MOS : MOU; for (q = p; p; p = p->n_left) { switch (p->n_op) { @@ -2376,7 +2342,7 @@ fixtype(NODE *p, int class) } /* detect function arguments, watching out for structure declarations */ - if (instruct && ISFTN(type)) { + if (rpole && ISFTN(type)) { uerror("function illegal in structure or union"); type = INCREF(type); } @@ -2404,10 +2370,8 @@ fixclass(int class, TWORD type) { /* first, fix null class */ if (class == SNULL) { - if (instruct&INSTRUCT) - class = MOS; - else if (instruct&INUNION) - class = MOU; + if (rpole) + class = rpole->rsou == STNAME ? MOS : MOU; else if (blevel == 0) class = EXTDEF; else @@ -2433,24 +2397,23 @@ fixclass(int class, TWORD type) } } - if( class&FIELD ){ - if( !(instruct&INSTRUCT) ) uerror( "illegal use of field" ); - return( class ); - } - - switch( class ){ + if (class & FIELD) { + if (rpole && rpole->rsou != STNAME) + uerror("illegal use of field"); + return(class); + } - case MOU: - if( !(instruct&INUNION) ) uerror( "illegal MOU class" ); - return( class ); + switch (class) { case MOS: - if( !(instruct&INSTRUCT) ) uerror( "illegal MOS class" ); - return( class ); + case MOU: + if (rpole == NULL) + uerror("illegal member class"); + return(class); case REGISTER: if (blevel == 0) - uerror( "illegal register declaration" ); + uerror("illegal register declaration"); if (blevel == 1) return(PARAM); else @@ -2472,13 +2435,12 @@ fixclass(int class, TWORD type) uerror( "fortran function has wrong type" ); } } - case STNAME: - case UNAME: case EXTERN: case STATIC: case EXTDEF: case TYPEDEF: case USTATIC: + case PARAM: return( class ); default: @@ -2543,6 +2505,18 @@ getsymtab(char *name, int flags) return s; } +int +fldchk(int sz) +{ + if (rpole->rsou != STNAME) + uerror("field outside of structure"); + if (sz < 0 || sz >= FIELD) { + uerror("illegal field size"); + return 1; + } + return 0; +} + #ifdef PCC_DEBUG static char * ccnames[] = { /* names of storage classes */ diff --git a/usr.bin/pcc/ccom/scan.l b/usr.bin/pcc/ccom/scan.l index 4e349815a0f..32dd7857a7e 100644 --- a/usr.bin/pcc/ccom/scan.l +++ b/usr.bin/pcc/ccom/scan.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: scan.l,v 1.4 2008/01/12 17:26:16 ragge Exp $ */ +/* $OpenBSD: scan.l,v 1.5 2008/04/11 20:45:52 stefan Exp $ */ /* * Copyright (c) 2002 Anders Magnusson. All rights reserved. @@ -58,7 +58,7 @@ int notype, parbal; #define CPP_HASH 4 #ifdef STABS -#define STABS_LINE(x) if (gflag && blevel) stabs_line(x) +#define STABS_LINE(x) if (gflag && blevel > 1) stabs_line(x) #else #define STABS_LINE(x) #endif @@ -125,10 +125,10 @@ extern void yyset_lineno (int); notype=1; return(C_TYPE); } "sizeof" { return(C_SIZEOF); } "static" { yylval.intval = STATIC; return(C_CLASS); } -"struct" { yylval.intval = INSTRUCT; notype=1; return(C_STRUCT); } +"struct" { yylval.intval = STNAME; notype=1; return(C_STRUCT); } "switch" { return(C_SWITCH); } "typedef" { yylval.intval = TYPEDEF; return(C_CLASS); } -"union" { yylval.intval = INUNION; notype=1; return(C_STRUCT); } +"union" { yylval.intval = UNAME; notype=1; return(C_STRUCT); } "unsigned" { yylval.nodep = mkty((TWORD)UNSIGNED, 0, MKSUE(UNSIGNED)); notype=1; return(C_TYPE); } "void" { yylval.nodep = mkty((TWORD)VOID, 0, MKSUE(VOID)); @@ -138,22 +138,22 @@ extern void yyset_lineno (int); return(C_QUALIFIER); } "while" { return(C_WHILE); } -{L}({L}|{D})* { struct symtab *s; - int i; +{L}({L}|{D})* { struct symtab *s; + int i = 0; - yylval.strp = addname(yytext); + yylval.strp = addname(yytext); #ifdef GCC_COMPAT - if ((i = gcc_keyword(yylval.strp, - &yylval.nodep)) != 0) - return i; + if ((i = gcc_keyword(yylval.strp, &yylval.nodep)) > 0) + return i; #endif - if (!notype) { - s = lookup(yylval.strp, SNOCREAT); - if (s && s->sclass == TYPEDEF) - return notype=1, C_TYPENAME; - } - return(C_NAME); + if (i == 0) { + if (notype) + return(C_NAME); + s = lookup(yylval.strp, SNOCREAT); + return s && s->sclass == TYPEDEF ? + notype=1, C_TYPENAME : C_NAME; } + } 0[xX]{H}+{IS}? { yylval.nodep = cvtdig(16); return(C_ICON); } 0{D}+{IS}? { yylval.nodep = cvtdig(8); return(C_ICON); } @@ -204,7 +204,7 @@ L?\"(\\.|[^\\"])*\" { "!=" { yylval.intval = NE; return(C_EQUOP); } ";" { notype = 0; return(';'); } ("{"|"<%") { notype = 0; return('{'); } -("}"|"%>") { return('}'); } +("}"|"%>") { if (rpole) notype = 1; return('}'); } "," { if (parbal) notype = 0; return(','); } ":" { return(':'); } "=" { return('='); } @@ -446,6 +446,8 @@ control(int t) lineno = val - 1; while (*wr && *wr != '\"') wr++; + if (*wr == 0) + return; if (*wr++ != '\"') goto bad; eptr = wr; @@ -510,3 +512,9 @@ pragma() else bad: werror("unknown pragma"); } + +void +cunput(char c) +{ + unput(c); +} diff --git a/usr.bin/pcc/ccom/stabs.c b/usr.bin/pcc/ccom/stabs.c index 8fe84a5b035..78765545eff 100644 --- a/usr.bin/pcc/ccom/stabs.c +++ b/usr.bin/pcc/ccom/stabs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: stabs.c,v 1.6 2008/01/12 17:26:16 ragge Exp $ */ +/* $OpenBSD: stabs.c,v 1.7 2008/04/11 20:45:52 stefan Exp $ */ /* * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). @@ -121,7 +121,7 @@ stabs_init() ptype("double", ADDTYPE(DOUBLE)->num, INTNUM, 8, 0); ptype("long double", ADDTYPE(LDOUBLE)->num, INTNUM, 12, 0); st = ADDTYPE(VOID); - cprint(savestabs, ".stabs \"void:t%d=r%d\",%d,0,0,0\n", + cprint(savestabs, "\t.stabs \"void:t%d=r%d\",%d,0,0,0\n", st->num, st->num, N_LSYM); } @@ -132,7 +132,7 @@ stabs_init() void ptype(char *name, int num, int inhnum, long long min, long long max) { - cprint(savestabs, ".stabs \"%s:t%d=r%d;%lld;%lld;\",%d,0,0,0", + cprint(savestabs, "\t.stabs \"%s:t%d=r%d;%lld;%lld;\",%d,0,0,0\n", name, num, inhnum, min, max, N_LSYM); } @@ -196,11 +196,11 @@ void stabs_line(int line) { #ifdef STAB_LINE_ABSOLUTE - cprint(savestabs, ".stabn %d,0,%d," STABLBL, N_SLINE, line, stablbl); + cprint(savestabs, "\t.stabn %d,0,%d," STABLBL "\n", N_SLINE, line, stablbl); #else - cprint(savestabs, ".stabn %d,0,%d," STABLBL "-%s", N_SLINE, line, stablbl, exname(curfun)); + cprint(savestabs, "\t.stabn %d,0,%d," STABLBL "-%s\n", N_SLINE, line, stablbl, exname(curfun)); #endif - cprint(1, STABLBL ":", stablbl++); + cprint(1, STABLBL ":\n", stablbl++); } /* @@ -210,12 +210,12 @@ void stabs_lbrac(int blklvl) { #ifdef STAB_LINE_ABSOLUTE - cprint(savestabs, ".stabn %d,0,%d," STABLBL, N_LBRAC, blklvl, stablbl); + cprint(savestabs, "\t.stabn %d,0,%d," STABLBL "\n", N_LBRAC, blklvl, stablbl); #else - cprint(savestabs, ".stabn %d,0,%d," STABLBL "-%s", + cprint(savestabs, "\t.stabn %d,0,%d," STABLBL "-%s\n", N_LBRAC, blklvl, stablbl, exname(curfun)); #endif - cprint(1, STABLBL ":", stablbl++); + cprint(1, STABLBL ":\n", stablbl++); } /* @@ -225,13 +225,13 @@ void stabs_rbrac(int blklvl) { #ifdef STAB_LINE_ABSOLUTE - cprint(savestabs, ".stabn %d,0,%d," STABLBL "\n", + cprint(savestabs, "\t.stabn %d,0,%d," STABLBL "\n", N_RBRAC, blklvl, stablbl); #else - cprint(savestabs, ".stabn %d,0,%d," STABLBL "-%s\n", + cprint(savestabs, "\t.stabn %d,0,%d," STABLBL "-%s\n", N_RBRAC, blklvl, stablbl, exname(curfun)); #endif - cprint(1, STABLBL ":", stablbl++); + cprint(1, STABLBL ":\n", stablbl++); } /* @@ -244,9 +244,9 @@ stabs_file(char *fname) if (mainfile == NULL) mainfile = fname; /* first call */ - cprint(savestabs, ".stabs \"%s\",%d,0,0," STABLBL, + cprint(savestabs, "\t.stabs \"%s\",%d,0,0," STABLBL "\n", fname, fname == mainfile ? N_SO : N_SOL, stablbl); - cprint(savestabs, STABLBL ":", stablbl++); + cprint(savestabs, STABLBL ":\n", stablbl++); } /* @@ -259,7 +259,7 @@ stabs_func(struct symtab *s) curfun = s->soname; printtype(s, str, sizeof(str)); - cprint(savestabs, ".stabs \"%s:%c%s\",%d,0,%d,%s", + cprint(savestabs, "\t.stabs \"%s:%c%s\",%d,0,%d,%s\n", curfun, s->sclass == STATIC ? 'f' : 'F', str, N_FUN, BIT2BYTE(s->ssue->suesize), exname(curfun)); } @@ -330,32 +330,32 @@ stabs_newsym(struct symtab *s) printtype(s, ostr, sizeof(ostr)); switch (s->sclass) { case PARAM: - cprint(savestabs, ".stabs \"%s:p%s\",%d,0,%d,%d", sname, ostr, + cprint(savestabs, "\t.stabs \"%s:p%s\",%d,0,%d,%d\n", sname, ostr, N_PSYM, suesize, BIT2BYTE(s->soffset)); break; case AUTO: - cprint(savestabs, ".stabs \"%s:%s\",%d,0,%d,%d", sname, ostr, + cprint(savestabs, "\t.stabs \"%s:%s\",%d,0,%d,%d\n", sname, ostr, N_LSYM, suesize, BIT2BYTE(s->soffset)); break; case STATIC: if (blevel) - cprint(savestabs, ".stabs \"%s:V%s\",%d,0,%d," LABFMT, sname, ostr, + cprint(savestabs, "\t.stabs \"%s:V%s\",%d,0,%d," LABFMT "\n", sname, ostr, N_LCSYM, suesize, s->soffset); else - cprint(savestabs, ".stabs \"%s:S%s\",%d,0,%d,%s", sname, ostr, + cprint(savestabs, "\t.stabs \"%s:S%s\",%d,0,%d,%s\n", sname, ostr, N_LCSYM, suesize, exname(sname)); break; case EXTERN: case EXTDEF: - cprint(savestabs, ".stabs \"%s:G%s\",%d,0,%d,0", sname, ostr, + cprint(savestabs, "\t.stabs \"%s:G%s\",%d,0,%d,0\n", sname, ostr, N_GSYM, suesize); break; case REGISTER: - cprint(savestabs, ".stabs \"%s:r%s\",%d,0,%d,%d", sname, ostr, + cprint(savestabs, "\t.stabs \"%s:r%s\",%d,0,%d,%d\n", sname, ostr, N_RSYM, 1, s->soffset); break; @@ -377,9 +377,15 @@ stabs_struct(struct symtab *p, struct suedef *sue) { } +static struct foo { + struct foo *next; + char *str; +} *foopole; + void cprint(int p2, char *fmt, ...) { + extern int inftn; va_list ap; char *str; @@ -387,12 +393,19 @@ cprint(int p2, char *fmt, ...) if (p2) { str = tmpvsprintf(fmt, ap); str = newstring(str, strlen(str)); /* XXX - for inlines */ - send_passt(IP_ASM, str); - } else { - putchar('\t'); + if (inftn == 0) { + struct foo *w = tmpalloc(sizeof(struct foo)); + w->str = str; + w->next = foopole; + foopole = w; + } else { + while (foopole) + send_passt(IP_ASM, foopole->str), + foopole = foopole->next; + send_passt(IP_ASM, str); + } + } else vprintf(fmt, ap); - putchar('\n'); - } va_end(ap); } diff --git a/usr.bin/pcc/ccom/trees.c b/usr.bin/pcc/ccom/trees.c index 70fa2caefe6..e7bd9a87f8a 100644 --- a/usr.bin/pcc/ccom/trees.c +++ b/usr.bin/pcc/ccom/trees.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trees.c,v 1.13 2008/01/12 17:26:16 ragge Exp $ */ +/* $OpenBSD: trees.c,v 1.14 2008/04/11 20:45:52 stefan Exp $ */ /* * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). * All rights reserved. @@ -76,6 +76,7 @@ static int opact(NODE *p); static int moditype(TWORD); static NODE *strargs(NODE *); static void rmcops(NODE *p); +int inftn; /* currently between epilog/prolog */ /* some special actions, used in finding the type of nodes */ # define NCVT 01 @@ -115,7 +116,6 @@ buildtree(int o, NODE *l, NODE *r) struct symtab *sp = NULL; /* XXX gcc */ NODE *lr, *ll; char *name; - struct symtab **elem; #ifdef PCC_DEBUG if (bdebug) { @@ -245,6 +245,8 @@ runtime: if (actions & LVAL) { /* check left descendent */ if (notlval(p->n_left)) { uerror("lvalue required"); + nfree(p); + return l; #ifdef notyet } else { if ((l->n_type > BTMASK && ISCON(l->n_qual)) || @@ -350,16 +352,15 @@ runtime: break; } - if ((elem = l->n_sue->suelem) == NULL) + if ((sp = l->n_sue->sylnk) == NULL) uerror("undefined struct or union"); name = r->n_name; - for (; *elem != NULL; elem++) { - sp = *elem; + for (; sp != NULL; sp = sp->snext) { if (sp->sname == name) break; } - if (*elem == NULL) + if (sp == NULL) uerror("member '%s' not declared", name); r->n_sp = sp; @@ -1591,6 +1592,8 @@ eprint(NODE *p, int down, int *a, int *b) ty = coptype( p->n_op ); printf("%p) %s, ", p, copst(p->n_op)); + if (p->n_op == XARG || p->n_op == XASM) + printf("id '%s', ", p->n_name); if (ty == LTYPE) { printf(CONFMT, p->n_lval); printf(", %d, ", (p->n_op != NAME && p->n_op != ICON) ? @@ -2058,6 +2061,10 @@ p2tree(NODE *p) printf("\t%d\t\n", talign(STRTY, p->n_left->n_sue)); break; + case XARG: + case XASM: + break; + default: printf( "\n" ); } @@ -2125,6 +2132,10 @@ p2tree(NODE *p) p->n_stalign = talign(STRTY,p->n_left->n_sue)/SZCHAR; break; + case XARG: + case XASM: + break; + default: p->n_name = ""; } @@ -2220,6 +2231,7 @@ send_passt(int type, ...) defloc(cftnsp); /* FALLTHROUGH */ case IP_PROLOG: + inftn = type == IP_PROLOG ? 1 : 0; ipp = (struct interpass_prolog *)ip; ipp->ipp_regs = va_arg(ap, int); ipp->ipp_autos = va_arg(ap, int); @@ -2227,7 +2239,7 @@ send_passt(int type, ...) ipp->ipp_type = va_arg(ap, TWORD); ipp->ipp_vis = va_arg(ap, int); ip->ip_lbl = va_arg(ap, int); - ipp->ip_tmpnum = tvaloff; + ipp->ip_tmpnum = va_arg(ap, int); ipp->ip_lblnum = crslab; if (type == IP_PROLOG) ipp->ip_lblnum--; |