summaryrefslogtreecommitdiff
path: root/usr.bin/pcc/ccom
diff options
context:
space:
mode:
authorStefan Kempf <stefan@cvs.openbsd.org>2008-04-11 20:45:53 +0000
committerStefan Kempf <stefan@cvs.openbsd.org>2008-04-11 20:45:53 +0000
commit0fcd3a2655c466633469fdebb7b6a7ff9b39e915 (patch)
tree167f27d01d1964f917dc5481da1bae768d6949d6 /usr.bin/pcc/ccom
parent11561d4249d0255cc9d667a9cc83b66d755d5227 (diff)
Sync with master repo. Reminded by otto@
Diffstat (limited to 'usr.bin/pcc/ccom')
-rw-r--r--usr.bin/pcc/ccom/ccom.160
-rw-r--r--usr.bin/pcc/ccom/cgram.y247
-rw-r--r--usr.bin/pcc/ccom/gcc_compat.c12
-rw-r--r--usr.bin/pcc/ccom/init.c41
-rw-r--r--usr.bin/pcc/ccom/main.c14
-rw-r--r--usr.bin/pcc/ccom/optim.c4
-rw-r--r--usr.bin/pcc/ccom/pass1.h20
-rw-r--r--usr.bin/pcc/ccom/pftn.c582
-rw-r--r--usr.bin/pcc/ccom/scan.l42
-rw-r--r--usr.bin/pcc/ccom/stabs.c65
-rw-r--r--usr.bin/pcc/ccom/trees.c26
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--;