diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2007-10-07 17:58:53 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2007-10-07 17:58:53 +0000 |
commit | 14b353bdf99a61b29314822d06fff3f7250019ac (patch) | |
tree | cfb9b82ab66c64756933986a1d66b0b133819ab4 /usr.bin/pcc/cc | |
parent | 71267fa7f73e6e874cf9cb489551cb44ead37aba (diff) |
reorg pcc tree; requested by and ok deraadt@; ok ragge@
Diffstat (limited to 'usr.bin/pcc/cc')
45 files changed, 17 insertions, 13313 deletions
diff --git a/usr.bin/pcc/cc/Makefile b/usr.bin/pcc/cc/Makefile index dda4affea45..2626ba970ae 100644 --- a/usr.bin/pcc/cc/Makefile +++ b/usr.bin/pcc/cc/Makefile @@ -1,7 +1,16 @@ -# $OpenBSD: Makefile,v 1.2 2007/09/15 21:48:06 ray Exp $ +# $OpenBSD: Makefile,v 1.3 2007/10/07 17:58:50 otto Exp $ # -# Makefile for top-level of pcc/cc. +# Makefile for the cc part of pcc. # -SUBDIR=cc ccom cpp +PROG= cc +PREFIX= /usr/local +BINDIR= ${PREFIX}/bin +MANDIR= ${PREFIX}/man/man +TARGOS= openbsd +TARGMACH= x86 -.include <bsd.subdir.mk> +CFLAGS+= -DLIBEXECDIR=\"${PREFIX}/libexec\" +CPPFLAGS+= -I${.CURDIR}/.. +CPPFLAGS+= -DDEFMACH=\"${TARGMACH}\" + +.include <bsd.prog.mk> diff --git a/usr.bin/pcc/cc/cc/cc.1 b/usr.bin/pcc/cc/cc.1 index be1d0e88169..e8ec6394f2e 100644 --- a/usr.bin/pcc/cc/cc/cc.1 +++ b/usr.bin/pcc/cc/cc.1 @@ -1,6 +1,6 @@ -.\" $Id: cc.1,v 1.5 2007/10/03 08:05:03 otto Exp $ +.\" $Id: cc.1,v 1.1 2007/10/07 17:58:50 otto Exp $ .\" $NetBSD$ -.\" $OpenBSD: cc.1,v 1.5 2007/10/03 08:05:03 otto Exp $ +.\" $OpenBSD: cc.1,v 1.1 2007/10/07 17:58:50 otto Exp $ ."\ .\" Copyright (c) 2007 Jeremy C. Reed <reed@reedmedia.net> .\" diff --git a/usr.bin/pcc/cc/cc/cc.c b/usr.bin/pcc/cc/cc.c index 9318b9cb16a..f931b8b9ee8 100644 --- a/usr.bin/pcc/cc/cc/cc.c +++ b/usr.bin/pcc/cc/cc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cc.c,v 1.18 2007/10/04 07:05:01 gilles Exp $ */ +/* $OpenBSD: cc.c,v 1.1 2007/10/07 17:58:50 otto Exp $ */ /* * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. * @@ -61,7 +61,7 @@ #include <libgen.h> #include <errno.h> -#include "../../config.h" +#include "../config.h" #include "ccconfig.h" /* C command */ diff --git a/usr.bin/pcc/cc/cc/Makefile b/usr.bin/pcc/cc/cc/Makefile deleted file mode 100644 index 5d708a88b80..00000000000 --- a/usr.bin/pcc/cc/cc/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# $OpenBSD: Makefile,v 1.5 2007/09/19 15:21:07 todd Exp $ -# -# Makefile for the cc part of pcc. -# -PROG= cc -PREFIX= /usr/local -BINDIR= ${PREFIX}/bin -MANDIR= ${PREFIX}/man/man -TARGOS= openbsd -TARGMACH= x86 - -CFLAGS+= -DLIBEXECDIR=\"${PREFIX}/libexec\" -CPPFLAGS+= -I${.CURDIR}/../.. -I${.CURDIR}/../../os/${TARGOS} -CPPFLAGS+= -DDEFMACH=\"${TARGMACH}\" - -.include <bsd.prog.mk> diff --git a/usr.bin/pcc/cc/ccom/Makefile b/usr.bin/pcc/cc/ccom/Makefile deleted file mode 100644 index d5dd831b8ff..00000000000 --- a/usr.bin/pcc/cc/ccom/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $OpenBSD: Makefile,v 1.9 2007/09/19 15:21:07 todd Exp $ -# -# Makefile for the ccom part of pcc. -# - -SUBDIR+= x86 -#SUBDIR+= vax - -.include <bsd.subdir.mk> diff --git a/usr.bin/pcc/cc/ccom/Makefile.inc b/usr.bin/pcc/cc/ccom/Makefile.inc deleted file mode 100644 index 6d329262345..00000000000 --- a/usr.bin/pcc/cc/ccom/Makefile.inc +++ /dev/null @@ -1,45 +0,0 @@ -# $OpenBSD: Makefile.inc,v 1.1 2007/09/19 15:21:07 todd Exp $ -# -# Makefile for the ccom part of pcc. -# - -PROG= ccom_${TARGMACH} -MAN= ccom.1 - -PREFIX= /usr/local -BINDIR= ${PREFIX}/libexec -MANDIR= ${PREFIX}/man/man -TARGOS= openbsd -CLEANFILES= external.h external.c mkext - -CFLAGS+= -DPCC_DEBUG -DGCC_COMPAT -CFLAGS+= -Wall -Wmissing-prototypes -Wstrict-prototypes -Werror -CFLAGS+= -DLIBEXECDIR=\"${PREFIX}/libexec\" -CPPFLAGS+= -I. -I${.CURDIR}/.. -I${.CURDIR} -I${.CURDIR}/../../../mip -CPPFLAGS+= -I${.CURDIR}/../../../arch/${TARGMACH} -CPPFLAGS+= -I${.CURDIR}/../../../os/${TARGOS} - -.PATH: ${.CURDIR}/../../../arch/${TARGMACH} -.PATH: ${.CURDIR}/../../../mip -.PATH: ${.CURDIR}/.. - -SRCS=optim.c pftn.c scan.l trees.c cgram.y inline.c symtabs.c \ - gcc_compat.c init.c local.c code.c stabs.c match.c reader.c optim2.c \ - regs.c local2.c order.c table.c common.c main.c external.c - -cgram.c: cgram.y - $(YACC) $(YFLAGS) -d $< - mv y.tab.c cgram.c - mv y.tab.h cgram.h - -mkext: mkext.c table.c common.c - $(CC) $(CPPFLAGS) $(CFLAGS) -DMKEXT -o mkext \ - ${.CURDIR}/../../../mip/mkext.c \ - ${.CURDIR}/../../../arch/${TARGMACH}/table.c \ - ${.CURDIR}/../../../mip/common.c - -external.h external.c: mkext - ./mkext - -cleandepend: - rm -f .depend ${.CURDIR}/tags cgram.h diff --git a/usr.bin/pcc/cc/ccom/ccom.1 b/usr.bin/pcc/cc/ccom/ccom.1 deleted file mode 100644 index ec9a26b63f5..00000000000 --- a/usr.bin/pcc/cc/ccom/ccom.1 +++ /dev/null @@ -1,167 +0,0 @@ -.\" $Id: ccom.1,v 1.4 2007/10/03 08:05:04 otto Exp $ -.\" $NetBSD$ -.\" $OpenBSD: ccom.1,v 1.4 2007/10/03 08:05:04 otto 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 -.\" 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 -.\" THIS SOFTWARE. -.Dd September 14, 2007 -.Dt ccom 1 -.Os -.Sh NAME -.Nm ccom -.Nd C compiler -.Sh SYNOPSIS -.Nm -.Op Fl gs -.Op Fl W Ar flags -.Op Fl X Ar flags -.Op Fl x Ar optimizations -.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. -.Pp -.Nm -reads the C source from -.Ar infile -or standard input and writes the assembler source -to -.Ar outfile -or to standard output. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl g -Enable debugging. -.\" built into binary, explain stabs? -.It Fl s -Print statistics to standard error when complete. -This includes: -name table entries, name string size, permanent allocated memory, -temporary allocated memory, lost memory, argument list unions, -dimension/function unions, struct/union/enum blocks, inline node count, -inline control blocks, and permanent symtab entries. -.\" TODO: explain units for above? -.It Fl v -Display version. -.It Fl W Ar flags -Report warnings. -(Do some basic checks.) -NOTE! These are subject to change RSN! -.Ar flags -is one or more of the following: -.Bl -tag -width Ds -.It Sy implicit -Implies -.Sy implicit-function-declaration -and -.Sy implicit-int . -.It Sy implicit-function-declaration -Report if no prototype for function. -.It Sy implicit-int -TODO -.It Sy missing-prototypes -TODO -.It Sy strict-prototypes -TODO -.El -.\" -.It Fl X Ar flags -C specific debugging where -.Ar flags -is one or more of the following: -.Bl -tag -width Ds -.It Sy b -Building of parse trees -.It Sy d -Declarations (multiple -.Sy d -flags gives more output) -.It Sy e -Pass1 trees at exit -.It Sy i -Initializations -.It Sy t -Type conversions -.It Sy x -Target-specific flag, used in machine-dependent code -.El -.\" -.It Fl x Ar optimizations -.Ar optimizations -is one or more 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. -.It Sy tailcall -Currently not implemented. -.It Sy temps -Setting this flag allows variables to be put into registers, for further -optimization by the register allocator. -.El -.\" -.It Fl Z Ar flags -Code generator (pass2) specific debugging where -.Ar flags -is one or more of the following: -.Bl -tag -width Ds -.It Sy e -Trees when entering pass2 -.It Sy f -Instruction matcher, may provide much output -.It Sy o -Instruction generator -.It Sy r -Register allocator -.It Sy s -Shape matching in instruction generator -.It Sy t -Type matching in instruction generator -.It Sy u -Sethi-Ullman computations -.It Sy x -Target-specific flag, used in machine-dependent code -.El -.El -.Sh SEE ALSO -.Xr as 1 , -.Xr cpp 1 , -.Xr pcc 1 -.Sh HISTORY -The -.Nm -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 -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 -Technology. -.Pp -This product includes software developed or owned by Caldera -International, Inc. diff --git a/usr.bin/pcc/cc/ccom/cgram.y b/usr.bin/pcc/cc/ccom/cgram.y deleted file mode 100644 index afbfe033b07..00000000000 --- a/usr.bin/pcc/cc/ccom/cgram.y +++ /dev/null @@ -1,1403 +0,0 @@ -/* $OpenBSD: cgram.y,v 1.3 2007/10/01 18:51:57 otto Exp $ */ - -/* - * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code and documentation must retain the above - * copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of other - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Comments for this grammar file. Ragge 021123 - * - * ANSI support required rewrite of the function header and declaration - * rules almost totally. - * - * The lex/yacc shared keywords are now split from the keywords used - * in the rest of the compiler, to simplify use of other frontends. - */ - -/* - * At last count, there were 3 shift/reduce and no reduce/reduce conflicts - * Two was funct_idn and the third was "dangling else". - */ - -/* - * Token used in C lex/yacc communications. - */ -%token C_WSTRING /* a wide string constant */ -%token C_STRING /* a string constant */ -%token C_ICON /* an integer constant */ -%token C_FCON /* a floating point constant */ -%token C_NAME /* an identifier */ -%token C_TYPENAME /* a typedef'd name */ -%token C_ANDAND /* && */ -%token C_OROR /* || */ -%token C_GOTO /* unconditional goto */ -%token C_RETURN /* return from function */ -%token C_TYPE /* a type */ -%token C_CLASS /* a storage class */ -%token C_ASOP /* assignment ops */ -%token C_RELOP /* <=, <, >=, > */ -%token C_EQUOP /* ==, != */ -%token C_DIVOP /* /, % */ -%token C_SHIFTOP /* <<, >> */ -%token C_INCOP /* ++, -- */ -%token C_UNOP /* !, ~ */ -%token C_STROP /* ., -> */ -%token C_STRUCT -%token C_IF -%token C_ELSE -%token C_SWITCH -%token C_BREAK -%token C_CONTINUE -%token C_WHILE -%token C_DO -%token C_FOR -%token C_DEFAULT -%token C_CASE -%token C_SIZEOF -%token C_ENUM -%token C_ELLIPSIS -%token C_QUALIFIER -%token C_FUNSPEC -%token C_ASM - -/* - * Precedence - */ -%left ',' -%right '=' C_ASOP -%right '?' ':' -%left C_OROR -%left C_ANDAND -%left '|' -%left '^' -%left '&' -%left C_EQUOP -%left C_RELOP -%left C_SHIFTOP -%left '+' '-' -%left '*' C_DIVOP -%right C_UNOP -%right C_INCOP C_SIZEOF -%left '[' '(' C_STROP -%{ -# include "pass1.h" -# include <stdarg.h> -# include <string.h> - -static int fun_inline; /* Reading an inline function */ -int oldstyle; /* Current function being defined */ -int noretype; -static struct symtab *xnf; -#ifdef GCC_COMPAT -char *renname; /* for renaming of variables */ -#endif - - -static NODE *bdty(int op, ...); -static void fend(void); -static void fundef(NODE *tp, NODE *p); -static void olddecl(NODE *p); -static struct symtab *init_declarator(NODE *tn, NODE *p, int assign); -static void resetbc(int mask); -static void swend(void); -static void addcase(NODE *p); -static void adddef(void); -static void savebc(void); -static void swstart(int); -static NODE * structref(NODE *p, int f, char *name); -static char *mkpstr(char *str); -static struct symtab *clbrace(NODE *); - -/* - * State for saving current switch state (when nested switches). - */ -struct savbc { - struct savbc *next; - int brklab; - int contlab; - int flostat; - int swx; -} *savbc, *savctx; - -%} - -%union { - int intval; - NODE *nodep; - struct symtab *symp; - struct rstack *rp; - char *strp; -} - - /* define types */ -%start ext_def_list - -%type <intval> con_e ifelprefix ifprefix whprefix forprefix doprefix switchpart - type_qualifier_list -%type <nodep> e .e term enum_dcl struct_dcl cast_type funct_idn declarator - direct_declarator elist type_specifier merge_attribs - parameter_declaration abstract_declarator initializer - parameter_type_list parameter_list addrlbl - 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 -%type <strp> string wstring C_STRING C_WSTRING -%type <rp> enum_head str_head -%type <symp> xnfdeclarator clbrace - -%type <intval> C_CLASS C_STRUCT C_RELOP C_DIVOP C_SHIFTOP - C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP -%type <nodep> C_TYPE C_QUALIFIER C_ICON C_FCON -%type <strp> C_NAME C_TYPENAME - -%% - -ext_def_list: ext_def_list external_def - | { ftnend(); } - ; - -external_def: function_definition { blevel = 0; } - | declaration { blevel = 0; symclear(0); } - | asmstatement ';' - | ';' - | error { blevel = 0; } - ; - -function_definition: - /* Ansi (or K&R header without parameter types) */ - declaration_specifiers declarator { - fundef($1, $2); - } compoundstmt { fend(); } - /* Same as above but without declaring function type */ - | declarator { - noretype = 1; - fundef(mkty(INT, 0, MKSUE(INT)), $1); - } compoundstmt { fend(); noretype = 0; } - /* K&R function without type declaration */ - | declarator { - noretype = 1; - if (oldstyle == 0) - uerror("bad declaration in ansi function"); - fundef(mkty(INT, 0, MKSUE(INT)), $1); - } arg_dcl_list compoundstmt { fend(); noretype = 0; } - /* K&R function with type declaration */ - | declaration_specifiers declarator { - if (oldstyle == 0) - uerror("bad declaration in ansi function"); - fundef($1, $2); - } arg_dcl_list compoundstmt { fend(); } - ; - -/* - * Returns a node pointer or NULL, if no types at all given. - * Type trees are checked for correctness and merged into one - * type node in typenode(). - */ -declaration_specifiers: - merge_attribs { $$ = typenode($1); } - ; - -merge_attribs: C_CLASS { $$ = block(CLASS, NIL, NIL, $1, 0, 0); } - | C_CLASS merge_attribs { $$ = block(CLASS, $2, NIL, $1,0,0);} - | type_specifier { $$ = $1; } - | type_specifier merge_attribs { $1->n_left = $2; $$ = $1; } - | C_QUALIFIER { $$ = $1; } - | C_QUALIFIER merge_attribs { $1->n_left = $2; $$ = $1; } - | function_specifiers { $$ = NIL; } - | function_specifiers merge_attribs { $$ = $2; } - ; - -function_specifiers: - C_FUNSPEC { - if (fun_inline) - uerror("too many inline"); - fun_inline = 1; - } - ; - -type_specifier: C_TYPE { $$ = $1; } - | C_TYPENAME { - struct symtab *sp = lookup($1, 0); - $$ = mkty(sp->stype, sp->sdf, sp->ssue); - $$->n_sp = sp; - } - | struct_dcl { $$ = $1; } - | enum_dcl { $$ = $1; } - ; - -/* - * Adds a pointer list to front of the declarators. - * Note the UMUL right node pointer usage. - */ -declarator: pointer direct_declarator { - $$ = $1; $1->n_right->n_left = $2; - } - | direct_declarator { $$ = $1; } - ; - -/* - * Return an UMUL node type linked list of indirections. - */ -pointer: '*' { $$ = bdty(UMUL, NIL); $$->n_right = $$; } - | '*' type_qualifier_list { - $$ = bdty(UMUL, NIL); - $$->n_qual = $2; - $$->n_right = $$; - } - | '*' pointer { - $$ = bdty(UMUL, $2); - $$->n_right = $2->n_right; - } - | '*' type_qualifier_list pointer { - $$ = bdty(UMUL, $3); - $$->n_qual = $2; - $$->n_right = $3->n_right; - } - ; - -type_qualifier_list: - C_QUALIFIER { $$ = $1->n_type; nfree($1); } - | type_qualifier_list C_QUALIFIER { - $$ = $1 | $2->n_type; nfree($2); - } - ; - -/* - * Sets up a function declarator. The call node will have its parameters - * connected to its right node pointer. - */ -direct_declarator: C_NAME { $$ = bdty(NAME, $1); } - | '(' declarator ')' { $$ = $2; } - | direct_declarator '[' nocon_e ']' { - $$ = block(LB, $1, $3, INT, 0, MKSUE(INT)); - } - | direct_declarator '[' ']' { $$ = bdty(LB, $1, 0); } - | direct_declarator '(' notype parameter_type_list ')' { - $$ = bdty(CALL, $1, $4); - } - | direct_declarator '(' notype identifier_list ')' { - $$ = bdty(CALL, $1, $4); - if (blevel != 0) - uerror("function declaration in bad context"); - oldstyle = 1; - } - | direct_declarator '(' ')' { $$ = bdty(UCALL, $1); } - ; - -notype: { /* extern int notype, doproto; notype = 0; doproto=1; printf("notype\n"); */ } - ; - -identifier_list: C_NAME { $$ = bdty(NAME, $1); $$->n_type = FARG; } - | identifier_list ',' C_NAME { - $$ = bdty(NAME, $3); - $$->n_type = FARG; - $$ = 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; } - | parameter_list ',' C_ELLIPSIS { - $$ = block(CM, $1, block(ELLIPSIS, NIL, NIL, 0, 0, 0), - 0, 0, 0); - } - ; - -/* - * Returns a linked lists of nodes of op CM with parameters on - * its right and additional CM nodes of its left pointer. - * No CM nodes if only one parameter. - */ -parameter_list: parameter_declaration { $$ = $1; } - | parameter_list ',' parameter_declaration { - $$ = block(CM, $1, $3, 0, 0, 0); - } - ; - -/* - * Returns a node pointer to the declaration. - */ -parameter_declaration: - declaration_specifiers declarator { - $$ = tymerge($1, $2); - nfree($1); - } - | declaration_specifiers abstract_declarator { - $$ = tymerge($1, $2); - nfree($1); - } - | declaration_specifiers { - $$ = tymerge($1, bdty(NAME, NULL)); - nfree($1); - } - ; - -abstract_declarator: - pointer { $$ = $1; $1->n_right->n_left = bdty(NAME, NULL); } - | direct_abstract_declarator { $$ = $1; } - | pointer direct_abstract_declarator { - $$ = $1; $1->n_right->n_left = $2; - } - ; - -direct_abstract_declarator: - '(' abstract_declarator ')' { $$ = $2; } - | '[' ']' { $$ = bdty(LB, bdty(NAME, NULL), 0); } - | '[' con_e ']' { $$ = bdty(LB, bdty(NAME, NULL), $2); } - | direct_abstract_declarator '[' ']' { $$ = bdty(LB, $1, 0); } - | direct_abstract_declarator '[' con_e ']' { - $$ = bdty(LB, $1, $3); - } - | '(' ')' { $$ = bdty(UCALL, bdty(NAME, NULL)); } - | '(' notype parameter_type_list ')' { - $$ = bdty(CALL, bdty(NAME, NULL), $3); - } - | direct_abstract_declarator '(' ')' { - $$ = bdty(UCALL, $1); - } - | direct_abstract_declarator '(' notype parameter_type_list ')' { - $$ = bdty(CALL, $1, $4); - } - ; - -/* - * K&R arg declaration, between ) and { - */ -arg_dcl_list: arg_declaration - | arg_dcl_list arg_declaration - ; - - -arg_declaration: declaration_specifiers arg_param_list ';' { - nfree($1); - } - ; - -arg_param_list: declarator { olddecl(tymerge($<nodep>0, $1)); } - | arg_param_list ',' declarator { - olddecl(tymerge($<nodep>0, $3)); - } - ; - -/* - * Declarations in beginning of blocks. - */ -declaration_list: declaration - | declaration_list declaration - ; - -/* - * Here starts the old YACC code. - */ - -stmt_list: stmt_list statement - | { bccode(); } - ; - -/* - * Variables are declared in init_declarator. - */ -declaration: declaration_specifiers ';' { nfree($1); goto inl; } - | declaration_specifiers init_declarator_list ';' { - nfree($1); - inl: - fun_inline = 0; - } - ; - -/* - * Normal declaration of variables. curtype contains the current type node. - * Returns nothing, variables are declared in init_declarator. - */ -init_declarator_list: - init_declarator - | init_declarator_list ',' { $<nodep>$ = $<nodep>0; } init_declarator - ; - -enum_dcl: enum_head '{' moe_list optcomma '}' { $$ = dclstruct($1); } - | C_ENUM C_NAME { $$ = rstruct($2,0); } - | C_ENUM C_TYPENAME { $$ = rstruct($2,0); } - ; - -enum_head: C_ENUM { $$ = bstruct(NULL,0); } - | C_ENUM C_NAME { $$ = bstruct($2,0); } - | C_ENUM C_TYPENAME { $$ = bstruct($2,0); } - ; - -moe_list: moe - | moe_list ',' moe - ; - -moe: C_NAME { moedef( $1 ); } - | C_NAME '=' con_e { strucoff = $3; moedef( $1 ); } - ; - -struct_dcl: str_head '{' struct_dcl_list '}' { $$ = dclstruct($1); } - | C_STRUCT C_NAME { $$ = rstruct($2,$1); } - | C_STRUCT C_TYPENAME { $$ = rstruct($2,$1); } - | str_head '{' '}' { -#ifndef GCC_COMPAT - werror("gcc extension"); -#endif - $$ = dclstruct($1); - } - ; - -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 - | struct_dcl_list struct_declaration - ; - -struct_declaration: - specifier_qualifier_list struct_declarator_list ';' { - nfree($1); - } - ; - -specifier_qualifier_list: - merge_specifiers { $$ = typenode($1); } - ; - -merge_specifiers: type_specifier merge_specifiers { $1->n_left = $2;$$ = $1; } - | type_specifier { $$ = $1; } - | C_QUALIFIER merge_specifiers { $1->n_left = $2; $$ = $1; } - | C_QUALIFIER { $$ = $1; } - ; - -struct_declarator_list: - struct_declarator { } - | struct_declarator_list ',' { $<nodep>$=$<nodep>0; } - struct_declarator { } - ; - -struct_declarator: declarator { - tymerge($<nodep>0, $1); - $1->n_sp = getsymtab((char *)$1->n_sp, SMOSNAME); /* XXX */ - defid($1, $<nodep>0->n_lval); - nfree($1); - } - | ':' con_e { - if (!(instruct&INSTRUCT)) - uerror( "field outside of structure" ); - 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" ); - $3 = 1; - } - if ($1->n_op == NAME) { - tymerge($<nodep>0, $1); - $1->n_sp = getsymtab((char *)$1->n_sp,SMOSNAME); - defid($1, FIELD|$3); - nfree($1); - } else - uerror("illegal declarator"); - } - ; - - /* always preceeded by attributes */ -xnfdeclarator: declarator { $$ = xnf = init_declarator($<nodep>0, $1, 1); } - ; - -/* - * Handles declarations and assignments. - * Returns nothing. - */ -init_declarator: declarator { init_declarator($<nodep>0, $1, 0); } - | declarator C_ASM '(' string ')' { -#ifdef GCC_COMPAT - renname = $4; - init_declarator($<nodep>0, $1, 0); -#else - werror("gcc extension"); - init_declarator($<nodep>0, $1, 0); -#endif - } - | xnfdeclarator '=' e { simpleinit($1, $3); xnf = NULL; } - | xnfdeclarator '=' begbr init_list optcomma '}' { - endinit(); - xnf = NULL; - } - | xnfdeclarator '=' addrlbl { simpleinit($1, $3); xnf = NULL; } - ; - -begbr: '{' { beginit($<symp>-1); } - ; - -initializer: e %prec ',' { $$ = $1; } - | addrlbl { $$ = $1; } - | ibrace init_list optcomma '}' { $$ = NULL; } - ; - -init_list: designation initializer { asginit($2); } - | init_list ',' designation initializer { asginit($4); } - ; - -designation: designator_list '=' { desinit($1); } - | { /* empty */ } - ; - -designator_list: designator { $$ = $1; } - | designator_list designator { $$ = $2; $$->n_left = $1; } - ; - -designator: '[' con_e ']' { $$ = bdty(LB, NULL, $2); } - | C_STROP C_NAME { $$ = bdty(NAME, $2); } - ; - -optcomma : /* VOID */ - | ',' - ; - -ibrace: '{' { ilbrace(); } - ; - -/* STATEMENTS */ - -compoundstmt: begin declaration_list stmt_list '}' { -#ifdef STABS - if (gflag && blevel > 2) - stabs_rbrac(blevel); -#endif - --blevel; - if( blevel == 1 ) - blevel = 0; - symclear(blevel); /* Clean ut the symbol table */ - if (autooff > maxautooff) - maxautooff = autooff; - autooff = savctx->contlab; - savctx = savctx->next; - } - | begin stmt_list '}' { -#ifdef STABS - if (gflag && blevel > 2) - stabs_rbrac(blevel); -#endif - --blevel; - if( blevel == 1 ) - blevel = 0; - symclear(blevel); /* Clean ut the symbol table */ - if (autooff > maxautooff) - maxautooff = autooff; - autooff = savctx->contlab; - savctx = savctx->next; - } - ; - -begin: '{' { - struct savbc *bc = tmpalloc(sizeof(struct savbc)); - if (blevel == 1) { -#ifdef STABS - if (gflag) - stabs_line(lineno); -#endif - dclargs(); - } -#ifdef STABS - if (gflag && blevel > 1) - stabs_lbrac(blevel+1); -#endif - ++blevel; - oldstyle = 0; - bc->contlab = autooff; - bc->next = savctx; - savctx = bc; - } - ; - -statement: e ';' { ecomp( $1 ); } - | compoundstmt - | ifprefix statement { plabel($1); reached = 1; } - | ifelprefix statement { - if ($1 != NOLAB) { - plabel( $1); - reached = 1; - } - } - | whprefix statement { - branch(contlab); - plabel( brklab ); - if( (flostat&FBRK) || !(flostat&FLOOP)) - reached = 1; - else - reached = 0; - resetbc(0); - } - | doprefix statement C_WHILE '(' e ')' ';' { - plabel(contlab); - if (flostat & FCONT) - reached = 1; - if (reached) - cbranch($5, bcon($1)); - else - tfree($5); - plabel( brklab); - reached = 1; - resetbc(0); - } - | forprefix .e ')' statement - { plabel( contlab ); - if( flostat&FCONT ) reached = 1; - if( $2 ) ecomp( $2 ); - branch($1); - plabel( brklab ); - if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1; - else reached = 0; - resetbc(0); - } - | switchpart statement - { if( reached ) branch( brklab ); - plabel( $1 ); - swend(); - plabel( brklab); - if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1; - resetbc(FCONT); - } - | C_BREAK ';' { - if (brklab == NOLAB) - uerror("illegal break"); - else if (reached) - branch(brklab); - flostat |= FBRK; - reached = 0; - } - | C_CONTINUE ';' { - if (contlab == NOLAB) - uerror("illegal continue"); - else - branch(contlab); - flostat |= FCONT; - goto rch; - } - | C_RETURN ';' { - branch(retlab); - if (cftnsp->stype != VOID && noretype && - cftnsp->stype != VOID+FTN) - uerror("return value required"); - rch: - if (!reached) - werror( "statement is not reached"); - reached = 0; - } - | C_RETURN e ';' { - register NODE *temp; - - spname = cftnsp; - temp = buildtree( NAME, NIL, NIL ); - temp->n_type = DECREF(temp->n_type); - temp = buildtree(RETURN, temp, $2); - - if (temp->n_type == VOID) - ecomp(temp->n_right); - else - ecomp(buildtree(FORCE, temp->n_right, NIL)); - nfree(temp->n_left); - nfree(temp); - branch(retlab); - reached = 0; - } - | C_GOTO C_NAME ';' { gotolabel($2); goto rch; } - | C_GOTO '*' e ';' { - ecomp(block(GOTO, $3, NIL, INT, 0, 0)); - } - | asmstatement ';' - | ';' - | error ';' - | error '}' - | label statement - ; - -asmstatement: C_ASM '(' string ')' { send_passt(IP_ASM, mkpstr($3)); } - ; - -label: C_NAME ':' { deflabel($1); reached = 1; } - | C_CASE e ':' { addcase($2); reached = 1; } - | C_DEFAULT ':' { reached = 1; adddef(); flostat |= FDEF; } - ; - -doprefix: C_DO { - savebc(); - if (!reached) - werror("loop not entered at top"); - brklab = getlab(); - contlab = getlab(); - plabel( $$ = getlab()); - reached = 1; - } - ; -ifprefix: C_IF '(' e ')' { - cbranch(buildtree(NOT, $3, NIL), bcon($$ = getlab())); - reached = 1; - } - ; -ifelprefix: ifprefix statement C_ELSE { - if (reached) - branch($$ = getlab()); - else - $$ = NOLAB; - plabel( $1); - reached = 1; - } - ; - -whprefix: C_WHILE '(' e ')' { - savebc(); - if (!reached) - werror("loop not entered at top"); - if ($3->n_op == ICON && $3->n_lval != 0) - flostat = FLOOP; - plabel( contlab = getlab()); - reached = 1; - brklab = getlab(); - if (flostat == FLOOP) - tfree($3); - else - cbranch(buildtree(NOT, $3, NIL), bcon(brklab)); - } - ; -forprefix: C_FOR '(' .e ';' .e ';' { - if ($3) - ecomp($3); - else if (!reached) - werror("loop not entered at top"); - savebc(); - contlab = getlab(); - brklab = getlab(); - plabel( $$ = getlab()); - reached = 1; - if ($5) - cbranch(buildtree(NOT, $5, NIL), bcon(brklab)); - else - flostat |= FLOOP; - } - ; -switchpart: C_SWITCH '(' e ')' { - NODE *p; - int num; - - savebc(); - brklab = getlab(); - if ($3->n_type != INT) { - /* must cast to integer */ - p = block(NAME, NIL, NIL, INT, 0, MKSUE(INT)); - p = buildtree(CAST, p, $3); - $3 = p->n_right; - nfree(p->n_left); - nfree(p); - } -// ecomp( buildtree( FORCE, $3, NIL ) ); - p = tempnode(0, INT, 0, MKSUE(INT)); - num = p->n_lval; - ecomp(buildtree(ASSIGN, p, $3)); - branch( $$ = getlab()); - swstart(num); - reached = 0; - } - ; -/* EXPRESSIONS */ -con_e: { $<intval>$=instruct; instruct=0; } e %prec ',' { - $$ = icons( $2 ); - instruct=$<intval>1; - } - ; - -nocon_e: { $<intval>$=instruct; instruct=0; } e %prec ',' { - instruct=$<intval>1; - $$ = $2; - } - ; - -.e: e - | { $$=0; } - ; - -elist: e %prec ',' - | elist ',' e { $$ = buildtree(CM, $1, $3); } - | elist ',' cast_type { /* hack for stdarg */ - $3->n_op = TYPE; - $$ = buildtree(CM, $1, $3); - } - ; - -/* - * Precedence order of operators. - */ -e: e ',' e { $$ = buildtree(COMOP, $1, $3); } - | e '=' e { $$ = buildtree(ASSIGN, $1, $3); } - | e C_ASOP e { $$ = buildtree($2, $1, $3); } - | e '?' e ':' e { - $$=buildtree(QUEST, $1, buildtree(COLON, $3, $5)); - } - | e C_OROR e { $$ = buildtree($2, $1, $3); } - | e C_ANDAND e { $$ = buildtree($2, $1, $3); } - | e '|' e { $$ = buildtree(OR, $1, $3); } - | e '^' e { $$ = buildtree(ER, $1, $3); } - | e '&' e { $$ = buildtree(AND, $1, $3); } - | e C_EQUOP e { $$ = buildtree($2, $1, $3); } - | e C_RELOP e { $$ = buildtree($2, $1, $3); } - | e C_SHIFTOP e { $$ = buildtree($2, $1, $3); } - | e '+' e { $$ = buildtree(PLUS, $1, $3); } - | e '-' e { $$ = buildtree(MINUS, $1, $3); } - | e C_DIVOP e { $$ = buildtree($2, $1, $3); } - | e '*' e { $$ = buildtree(MUL, $1, $3); } - | e '=' addrlbl { $$ = buildtree(ASSIGN, $1, $3); } - | term - ; - -addrlbl: C_ANDAND C_NAME { -#ifdef GCC_COMPAT - struct symtab *s = lookup($2, SLBLNAME); - if (s->soffset == 0) - s->soffset = -getlab(); - spname = s; - $$ = buildtree(ADDROF, buildtree(NAME, NIL, NIL), NIL); -#else - uerror("gcc extension"); -#endif - } - ; - -term: term C_INCOP { $$ = buildtree( $2, $1, bcon(1) ); } - | '*' term { $$ = buildtree(UMUL, $2, NIL); } - | '&' term { - if( ISFTN($2->n_type) || ISARY($2->n_type) ){ -#ifdef notdef - werror( "& before array or function: ignored" ); -#endif - $$ = $2; - } else - $$ = buildtree(ADDROF, $2, NIL); - } - | '-' term { $$ = buildtree(UMINUS, $2, NIL ); } - | '+' term { $$ = $2; } - | C_UNOP term { $$ = buildtree( $1, $2, NIL ); } - | C_INCOP term { - $$ = buildtree($1 == INCR ? PLUSEQ : MINUSEQ, - $2, bcon(1)); - } - | C_SIZEOF term { $$ = doszof($2); } - | '(' cast_type ')' term %prec C_INCOP { - $$ = buildtree(CAST, $2, $4); - nfree($$->n_left); - nfree($$); - $$ = $$->n_right; - } - | C_SIZEOF '(' cast_type ')' %prec C_SIZEOF { - $$ = doszof($3); - } - | '(' cast_type ')' clbrace init_list '}' { - endinit(); - spname = $4; - $$ = buildtree(NAME, NIL, NIL); - } - | term '[' e ']' { - $$ = buildtree( UMUL, - buildtree( PLUS, $1, $3 ), NIL ); - } - | funct_idn ')' { $$ = doacall($1, NIL); } - | funct_idn elist ')' { $$ = doacall($1, $2); } - | term C_STROP C_NAME { $$ = structref($1, $2, $3); } - | term C_STROP C_TYPENAME { $$ = structref($1, $2, $3); } - | C_NAME { - spname = lookup($1, 0); - /* recognize identifiers in initializations */ - if (blevel==0 && spname->stype == UNDEF) { - register NODE *q; - werror("undeclared initializer name %s", - spname->sname); - q = block(NAME, NIL, NIL, INT, 0, MKSUE(INT)); - q->n_sp = spname; - defid(q, EXTERN); - nfree(q); - } - if (spname->sflags & SINLINE) - inline_ref($1); - $$ = buildtree(NAME, NIL, NIL); - spname->suse = -lineno; - if (spname->sflags & SDYNARRAY) - $$ = buildtree(UMUL, $$, NIL); - } - | C_ICON { $$ = $1; } - | C_FCON { $$ = $1; } - | string { $$ = strend($1); /* get string contents */ } - | wstring { $$ = wstrend($1); } - | '(' e ')' { $$=$2; } - ; - -clbrace: '{' { $$ = clbrace($<nodep>-1); } - ; - -string: C_STRING { - int len = strlen($1) + 1; - $$ = tmpalloc(len); - strlcpy($$, $1, len); - } - | string C_STRING { - int len = strlen($1) + strlen($2) + 1; - $$ = tmpalloc(len); - strlcpy($$, $1, len); - strlcat($$, $2, len); - } - ; - -wstring: C_WSTRING { - int len = strlen($1) + 1; - $$ = tmpalloc(len); - strlcpy($$, $1, len); - } - | string C_WSTRING { - int len = strlen($1) + strlen($2) + 1; - $$ = tmpalloc(len); - strlcpy($$, $1, len); - strlcat($$, $2, len); - } - ; - -cast_type: specifier_qualifier_list { - $$ = tymerge($1, bdty(NAME, NULL)); - nfree($1); - } - | specifier_qualifier_list abstract_declarator { - $$ = tymerge($1, $2); - nfree($1); - } - ; - -funct_idn: C_NAME '(' { - struct symtab *s = lookup($1, 0); - if (s->stype == UNDEF) { - register NODE *q; - q = block(NAME, NIL, NIL, FTN|INT, 0, MKSUE(INT)); - q->n_sp = s; - defid(q, EXTERN); - nfree(q); - } - if (s->sflags & SINLINE) - inline_ref($1); - spname = s; - $$ = buildtree(NAME, NIL, NIL); - s->suse = -lineno; - } - | term '(' - ; -%% - -NODE * -mkty(TWORD t, union dimfun *d, struct suedef *sue) -{ - return block(TYPE, NIL, NIL, t, d, sue); -} - -static NODE * -bdty(int op, ...) -{ - va_list ap; - register NODE *q; - - va_start(ap, op); - q = block(op, NIL, NIL, INT, 0, MKSUE(INT)); - - switch (op) { - case UMUL: - case UCALL: - q->n_left = va_arg(ap, NODE *); - q->n_rval = 0; - break; - - case CALL: - q->n_left = va_arg(ap, NODE *); - q->n_right = va_arg(ap, NODE *); - break; - - case LB: - q->n_left = va_arg(ap, NODE *); - q->n_right = bcon(va_arg(ap, int)); - break; - - case NAME: - q->n_sp = va_arg(ap, struct symtab *); /* XXX survive tymerge */ - break; - - default: - cerror("bad bdty"); - } - va_end(ap); - - return q; -} - -static void -savebc(void) -{ - struct savbc *bc = tmpalloc(sizeof(struct savbc)); - - bc->brklab = brklab; - bc->contlab = contlab; - bc->flostat = flostat; - bc->next = savbc; - savbc = bc; - flostat = 0; -} - -static void -resetbc(int mask) -{ - flostat = savbc->flostat | (flostat&mask); - contlab = savbc->contlab; - brklab = savbc->brklab; - savbc = savbc->next; -} - -struct swdef { - struct swdef *next; /* Next in list */ - int deflbl; /* Label for "default" */ - struct swents *ents; /* Linked sorted list of case entries */ - int nents; /* # of entries in list */ - int num; /* Node value will end up in */ -} *swpole; - -/* - * add case to switch - */ -static void -addcase(NODE *p) -{ - struct swents *w, *sw = tmpalloc(sizeof(struct swents)); - - p = optim(p); /* change enum to ints */ - if (p->n_op != ICON || p->n_sp != NULL) { - uerror( "non-constant case expression"); - return; - } - if (swpole == NULL) { - uerror("case not in switch"); - return; - } - - sw->sval = p->n_lval; - plabel( sw->slab = getlab()); - w = swpole->ents; - if (swpole->ents == NULL) { - sw->next = NULL; - swpole->ents = sw; - } else if (swpole->ents->next == NULL) { - if (swpole->ents->sval == sw->sval) { - uerror("duplicate case in switch"); - } else if (swpole->ents->sval < sw->sval) { - sw->next = NULL; - swpole->ents->next = sw; - } else { - sw->next = swpole->ents; - swpole->ents = sw; - } - } else { - while (w->next->next != NULL && w->next->sval < sw->sval) { - w = w->next; - } - if (w->next->sval == sw->sval) { - uerror("duplicate case in switch"); - } else if (w->next->sval > sw->sval) { - sw->next = w->next; - w->next = sw; - } else { - sw->next = NULL; - w->next->next = sw; - } - } - swpole->nents++; - tfree(p); -} - -/* - * add default case to switch - */ -static void -adddef(void) -{ - if (swpole == NULL) - uerror("default not inside switch"); - else if (swpole->deflbl != 0) - uerror("duplicate default in switch"); - else - plabel( swpole->deflbl = getlab()); -} - -static void -swstart(int num) -{ - struct swdef *sw = tmpalloc(sizeof(struct swdef)); - - sw->deflbl = sw->nents = 0; - sw->ents = NULL; - sw->next = swpole; - sw->num = num; - swpole = sw; -} - -/* - * end a switch block - */ -static void -swend(void) -{ - struct swents *sw, **swp; - int i; - - sw = tmpalloc(sizeof(struct swents)); - swp = tmpalloc(sizeof(struct swents *) * (swpole->nents+1)); - - sw->slab = swpole->deflbl; - swp[0] = sw; - - for (i = 1; i <= swpole->nents; i++) { - swp[i] = swpole->ents; - swpole->ents = swpole->ents->next; - } - genswitch(swpole->num, swp, swpole->nents); - - swpole = swpole->next; -} - -/* - * Declare a variable or prototype. - */ -static struct symtab * -init_declarator(NODE *tn, NODE *p, int assign) -{ - int class = tn->n_lval; - NODE *typ; - - typ = tymerge(tn, p); - typ->n_sp = lookup((char *)typ->n_sp, 0); /* XXX */ - - if (fun_inline && ISFTN(typ->n_type)) - typ->n_sp->sflags |= SINLINE; - - if (ISFTN(typ->n_type) == 0) { - setloc1(DATA); - if (assign) { - defid(typ, class); - typ->n_sp->sflags |= SASG; - lcommdel(typ->n_sp); - } else { - nidcl(typ, class); - } - } else { - if (assign) - uerror("cannot initialise function"); - defid(typ, uclass(class)); - } - nfree(p); - return typ->n_sp; -} - -/* - * Declare a function. - */ -static void -fundef(NODE *tp, NODE *p) -{ - extern int prolab; - struct symtab *s; - int class = tp->n_lval, oclass; - char *c; - - setloc1(PROG); - /* Enter function args before they are clobbered in tymerge() */ - /* Typecheck against prototype will be done in defid(). */ - ftnarg(p); - - tymerge(tp, p); - s = p->n_sp = lookup((char *)p->n_sp, 0); /* XXX */ - - oclass = s->sclass; - if (class == STATIC && oclass == EXTERN) - werror("%s was first declared extern, then static", s->sname); - - if ((oclass == SNULL || oclass == USTATIC) && - class == STATIC && fun_inline) { - /* Unreferenced, store it for (eventual) later use */ - /* Ignore it if it not declared static */ - s->sflags |= SINLINE; - inline_start(s->sname); - } - if (class == EXTERN) - class = SNULL; /* same result */ - - cftnsp = s; - defid(p, class); - prolab = getlab(); - c = cftnsp->sname; -#ifdef GCC_COMPAT - c = gcc_findname(cftnsp); -#endif - send_passt(IP_PROLOG, -1, -1, c, cftnsp->stype, - cftnsp->sclass == EXTDEF, prolab); - blevel = 1; -#ifdef STABS - if (gflag) - stabs_func(s); -#endif - nfree(tp); - nfree(p); - -} - -static void -fend(void) -{ - if (blevel) - cerror("function level error"); - ftnend(); - fun_inline = 0; - cftnsp = NULL; -} - -static NODE * -structref(NODE *p, int f, char *name) -{ - NODE *r; - - if (f == DOT) - p = buildtree(ADDROF, p, NIL); - r = block(NAME, NIL, NIL, INT, 0, MKSUE(INT)); - r->n_name = name; - return buildtree(STREF, p, r); -} - -static void -olddecl(NODE *p) -{ - struct symtab *s; - - s = lookup((char *)p->n_sp, 0); - if (s->slevel != 1 || s->stype == UNDEF) - uerror("parameter '%s' not defined", s->sname); - else if (s->stype != FARG) - uerror("parameter '%s' redefined", s->sname); - s->stype = p->n_type; - s->sdf = p->n_df; - s->ssue = p->n_sue; - nfree(p); -} - -void -branch(int lbl) -{ - int r = reached++; - ecomp(block(GOTO, bcon(lbl), NIL, INT, 0, 0)); - reached = r; -} - -/* - * Create a printable string based on an encoded string. - */ -static char * -mkpstr(char *str) -{ - char *s, *os; - int v, l = strlen(str)+1; - - os = s = isinlining ? permalloc(l) : tmpalloc(l); - for (; *str; ) { - if (*str++ == '\\') - v = esccon(&str); - else - v = str[-1]; - *s++ = v; - } - *s = 0; - return os; -} - -static struct symtab * -clbrace(NODE *p) -{ - struct symtab *sp; - - if (blevel == 0 && xnf != NULL) - cerror("no level0 compound literals"); - - sp = getsymtab("cl", STEMP); - sp->stype = p->n_type; - sp->squal = p->n_qual; - sp->sdf = p->n_df; - sp->ssue = p->n_sue; - sp->sclass = blevel ? AUTO : STATIC; - if (!ISARY(sp->stype) || sp->sdf->ddim != 0) { - sp->soffset = NOOFFSET; - oalloc(sp, &autooff); - } - tfree(p); - beginit(sp); - return sp; -} diff --git a/usr.bin/pcc/cc/ccom/gcc_compat.c b/usr.bin/pcc/cc/ccom/gcc_compat.c deleted file mode 100644 index 29a8cfabdd9..00000000000 --- a/usr.bin/pcc/cc/ccom/gcc_compat.c +++ /dev/null @@ -1,126 +0,0 @@ -/* $OpenBSD: gcc_compat.c,v 1.2 2007/09/15 22:04:38 ray Exp $ */ -/* - * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Routines to support some of the gcc extensions to C. - */ -#ifdef GCC_COMPAT - -#include "pass1.h" -#include "cgram.h" - -#include <string.h> - -static struct kw { - char *name, *ptr; - int rv; -} kw[] = { - { "__asm", NULL, C_ASM }, - { "__signed", NULL, 0 }, - { "__inline", NULL, C_FUNSPEC }, - { "__const", NULL, 0 }, - { "__asm__", NULL, C_ASM }, - { NULL, NULL, 0 }, -}; - -void -gcc_init() -{ - struct kw *kwp; - - for (kwp = kw; kwp->name; kwp++) - kwp->ptr = addname(kwp->name); - -} - -/* - * See if a string matches a gcc keyword. - */ -int -gcc_keyword(char *str, NODE **n) -{ - struct kw *kwp; - int i; - - for (i = 0, kwp = kw; kwp->name; kwp++, i++) - if (str == kwp->ptr) - break; - if (kwp->name == NULL) - return 0; - if (kwp->rv) - return kwp->rv; - switch (i) { - case 1: /* __signed */ - *n = mkty((TWORD)SIGNED, 0, MKSUE(SIGNED)); - return C_TYPE; - case 3: /* __const */ - *n = block(QUALIFIER, NIL, NIL, CON, 0, 0); - return C_QUALIFIER; - } - cerror("gcc_keyword"); - return 0; -} - -static struct ren { - struct ren *next; - char *old, *new; -} *renp; -/* - * Save a name for later renaming of a variable. - */ -void -gcc_rename(struct symtab *sp, char *newname) -{ - struct ren *ren = permalloc(sizeof(struct ren)); - - sp->sflags |= SRENAME; - ren->old = sp->sname; - ren->new = newstring(newname, strlen(newname)+1); - ren->next = renp; - renp = ren; -} - -/* - * Get a renamed variable. - */ -char * -gcc_findname(struct symtab *sp) -{ - struct ren *w; - - if ((sp->sflags & SRENAME) == 0) - return exname(sp->sname); - - for (w = renp; w; w = w->next) { - if (w->old == sp->sname) - return exname(w->new); - } - cerror("gcc_findname %s", sp->sname); - return NULL; -} -#endif diff --git a/usr.bin/pcc/cc/ccom/init.c b/usr.bin/pcc/cc/ccom/init.c deleted file mode 100644 index ec721195479..00000000000 --- a/usr.bin/pcc/cc/ccom/init.c +++ /dev/null @@ -1,968 +0,0 @@ -/* $OpenBSD: init.c,v 1.9 2007/10/05 12:48:29 otto Exp $ */ - -/* - * Copyright (c) 2004, 2007 Anders Magnusson (ragge@ludd.ltu.se). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code and documentation must retain the above - * copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of other - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "pass1.h" -#include <string.h> - -/* - * Four machine-dependent routines may be called during initialization: - * - * instring(char *str) - Print out a string. - * zbits(OFFSZ, int) - sets int bits of zero at position OFFSZ. - * infld(CONSZ off, int fsz, CONSZ val) - * - sets the bitfield val starting at off and size fsz. - * inval(CONSZ off, int fsz, NODE *) - * - prints an integer constant which may have - * a label associated with it, located at off and - * size fsz. - * - * Initialization may be of different kind: - * - Initialization at compile-time, all values are constants and laid - * out in memory. Static or extern variables outside functions. - * - Initialization at run-time, written to their values as code. - * - * Currently run-time-initialized variables are only initialized by using - * move instructions. An optimization might be to detect that it is - * initialized with constants and therefore copied from readonly memory. - */ - -/* - * The base element(s) of an initialized variable is kept in a linked - * list, allocated while initialized. - * - * When a scalar is found, entries are popped of the instk until it's - * possible to find an entry for a new scalar; then onstk() is called - * to get the correct type and size of that scalar. - * - * If a right brace is found, pop the stack until a matching left brace - * were found while filling the elements with zeros. This left brace is - * also marking where the current level is for designated initializations. - * - * Position entries are increased when traversing back down into the stack. - */ - -/* - * Good-to-know entries from symtab: - * soffset - # of bits from beginning of this structure. - */ - -/* - * TO FIX: - * - Alignment of structs on like i386 char members. - */ - -int idebug; - -/* - * Struct used in array initialisation. - */ -static struct instk { - struct instk *in_prev; /* linked list */ - struct symtab **in_xp; /* member in structure initializations */ - struct symtab *in_sym; /* stab index */ - union dimfun *in_df; /* dimenston of array */ - TWORD in_t; /* type for this level */ - int in_n; /* number of arrays seen so far */ - int in_fl; /* flag which says if this level is controlled by {} */ -} *pstk, pbase; - -static struct symtab *csym; - -#define ISSOU(ty) (ty == STRTY || ty == UNIONTY) - -#ifdef PCC_DEBUG -static void prtstk(struct instk *in); -#endif - -/* - * Linked lists for initializations. - */ -struct ilist { - struct ilist *next; - CONSZ off; /* bit offset of this entry */ - int fsz; /* bit size of this entry */ - NODE *n; /* node containing this data info */ -}; - -struct llist { - SLIST_ENTRY(llist) next; - CONSZ begsz; /* bit offset of this entry */ - struct ilist *il; -} *curll; -static SLIST_HEAD(, llist) lpole; -static CONSZ basesz; -static int numents; /* # of array entries allocated */ - -static struct ilist * -getil(struct ilist *next, CONSZ b, int sz, NODE *n) -{ - struct ilist *il = tmpalloc(sizeof(struct ilist)); - - il->off = b; - il->fsz = sz; - il->n = n; - il->next = next; - return il; -} - -/* - * Allocate a new struct defining a block of initializers appended to the - * end of the llist. Return that entry. - */ -static struct llist * -getll(void) -{ - struct llist *ll; - - ll = tmpalloc(sizeof(struct llist)); - ll->begsz = numents * basesz; - ll->il = NULL; - SLIST_INSERT_LAST(&lpole, ll, next); - numents++; - return ll; -} - -/* - * Return structure containing off bitnumber. - * Allocate more entries, if needed. - */ -static struct llist * -setll(OFFSZ off) -{ - struct llist *ll = NULL; - - /* Ensure that we have enough entries */ - while (off >= basesz * numents) - ll = getll(); - - if (ll != NULL && ll->begsz <= off && ll->begsz + basesz > off) - return ll; - - SLIST_FOREACH(ll, &lpole, next) - if (ll->begsz <= off && ll->begsz + basesz > off) - break; - return ll; /* ``cannot fail'' */ -} - -/* - * beginning of initialization; allocate space to store initialized data. - * remember storage class for writeout in endinit(). - * p is the newly declarated type. - */ -void -beginit(struct symtab *sp) -{ - struct instk *is = &pbase; - struct llist *ll; - -#ifdef PCC_DEBUG - if (idebug) - printf("beginit(), sclass %s\n", scnames(sp->sclass)); -#endif - - csym = sp; - - numents = 0; /* no entries in array list */ - if (ISARY(sp->stype)) - basesz = tsize(DECREF(sp->stype), sp->sdf+1, sp->ssue); - else - basesz = tsize(DECREF(sp->stype), sp->sdf, sp->ssue); - SLIST_INIT(&lpole); - curll = ll = getll(); /* at least first entry in list */ - - /* first element */ - is->in_xp = ISSOU(sp->stype) ? sp->ssue->suelem : NULL; - is->in_n = 0; - is->in_t = sp->stype; - is->in_sym = sp; - is->in_df = sp->sdf; - is->in_fl = 0; - is->in_prev = NULL; - pstk = is; -} - -/* - * Push a new entry on the initializer stack. - * The new entry will be "decremented" to the new sub-type of the previous - * entry when called. - * Popping of entries is done elsewhere. - */ -static void -stkpush(void) -{ - struct instk *is; - struct symtab *sq, *sp; - TWORD t; - - if (pstk == NULL) { - sp = csym; - t = 0; - } else { - t = pstk->in_t; - sp = pstk->in_sym; - } - -#ifdef PCC_DEBUG - if (idebug) { - printf("stkpush: '%s' %s ", sp->sname, scnames(sp->sclass)); - tprint(stdout, t, 0); - printf("\n"); - } -#endif - - /* - * Figure out what the next initializer will be, and push it on - * the stack. If this is an array, just decrement type, if it - * is a struct or union, extract the next element. - */ - is = tmpalloc(sizeof(struct instk)); - is->in_fl = 0; - is->in_n = 0; - if (pstk == NULL) { - /* stack empty */ - is->in_xp = ISSOU(sp->stype) ? sp->ssue->suelem : NULL; - is->in_t = sp->stype; - is->in_sym = sp; - is->in_df = sp->sdf; - } else if (ISSOU(t)) { - sq = *pstk->in_xp; - if (sq == NULL) { - uerror("excess of initializing elements"); - } else { - is->in_xp = ISSOU(sq->stype) ? sq->ssue->suelem : 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_t = DECREF(t); - is->in_sym = sp; - if (pstk->in_df->ddim && pstk->in_n >= pstk->in_df->ddim) { - werror("excess of initializing elements"); - pstk->in_n--; - } - if (ISARY(is->in_t)) - is->in_df = pstk->in_df+1; - } else - uerror("too many left braces"); - is->in_prev = pstk; - pstk = is; - -#ifdef PCC_DEBUG - if (idebug) { - printf(" newtype "); - tprint(stdout, is->in_t, 0); - printf("\n"); - } -#endif -} - -/* - * pop down to either next level that can handle a new initializer or - * to the next braced level. - */ -static void -stkpop(void) -{ -#ifdef PCC_DEBUG - if (idebug) - 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) - break; - } - if (ISSOU(pstk->in_t) && pstk->in_fl) - break; /* need } */ - if (ISARY(pstk->in_t)) { - pstk->in_n++; - if (pstk->in_fl) - break; - if (pstk->in_df->ddim == 0 || - pstk->in_n < pstk->in_df->ddim) - break; /* ger more elements */ - } - } -#ifdef PCC_DEBUG - if (idebug > 1) - prtstk(pstk); -#endif -} - -/* - * Count how many elements an array may consist of. - */ -static int -acalc(struct instk *is, int n) -{ - if (is == NULL || !ISARY(is->in_t)) - return 0; - return acalc(is->in_prev, n * is->in_df->ddim) + n * is->in_n; -} - -/* - * Find current bit offset of the top element on the stack from - * the beginning of the aggregate. - */ -static CONSZ -findoff(void) -{ - struct instk *is; - OFFSZ off; - -#ifdef PCC_DEBUG - if (ISARY(pstk->in_t) || ISSOU(pstk->in_t)) - cerror("findoff on bad type"); -#endif - - /* - * Offset calculations. If: - * - previous type is STRTY, soffset has in-struct offset. - * - this type is ARY, offset is ninit*stsize. - */ - for (off = 0, is = pstk; is; is = is->in_prev) { - if (is->in_prev && is->in_prev->in_t == STRTY) - off += is->in_sym->soffset; - if (ISARY(is->in_t)) { - /* suesize is the basic type, so adjust */ - TWORD t = is->in_t; - OFFSZ o; - while (ISARY(t)) - t = DECREF(t); - o = ISPTR(t) ? SZPOINT(t) : is->in_sym->ssue->suesize; - off += o * acalc(is, 1); - while (is->in_prev && ISARY(is->in_prev->in_t)) { - if (is->in_prev->in_prev && - is->in_prev->in_prev->in_t == STRTY) - off += is->in_sym->soffset; - is = is->in_prev; - } - } - } - if (idebug>1) { - printf("findoff: off %lld\n", off); - prtstk(pstk); - } - return off; -} - -/* - * Insert the node p with size fsz at position off. - * Bit fields are already dealt with, so a node of correct type - * with correct alignment and correct bit offset is given. - */ -static void -nsetval(CONSZ off, int fsz, NODE *p) -{ - struct llist *ll; - struct ilist *il; - - if (idebug>1) - printf("setval: off %lld fsz %d p %p\n", off, fsz, p); - - if (fsz == 0) - return; - - ll = setll(off); - off -= ll->begsz; - if (ll->il == NULL) { - ll->il = getil(NULL, off, fsz, p); - } else { - il = ll->il; - if (il->off > off) { - ll->il = getil(ll->il, off, fsz, p); - } else { - for (il = ll->il; il->next; il = il->next) - if (il->off <= off && il->next->off > off) - break; - if (il->off == off) { - /* replace */ - nfree(il->n); - il->n = p; - } else - il->next = getil(il->next, off, fsz, p); - } - } -} - -/* - * Align data and set correct location. - */ -static void -setscl(struct symtab *sp) -{ - setloc1((sp->squal << TSHIFT) & CON ? RDATA : DATA); - defalign(talign(sp->stype, sp->ssue)); - if (sp->sclass == EXTDEF || - (sp->sclass == STATIC && sp->slevel == 0)) { - defnam(sp); - } else { - if (sp->soffset == NOOFFSET) - cerror("setscl"); - deflab1(sp->soffset); - } -} - -/* - * take care of generating a value for the initializer p - * inoff has the current offset (last bit written) - * in the current word being generated - */ -void -scalinit(NODE *p) -{ - CONSZ woff; - NODE *q; - int fsz; - -#ifdef PCC_DEBUG - if (idebug > 2) { - printf("scalinit(%p)\n", p); - fwalk(p, eprint, 0); - prtstk(pstk); - } -#endif - - if (nerrors) - return; - - p = optim(p); - - if (csym->sclass != AUTO && p->n_op != ICON && - p->n_op != FCON && p->n_op != NAME) - cerror("scalinit not leaf"); - - /* Out of elements? */ - if (pstk == NULL) { - uerror("excess of initializing elements"); - return; - } - - /* - * Get to the simple type if needed. - */ - while (ISSOU(pstk->in_t) || ISARY(pstk->in_t)) - stkpush(); - - /* let buildtree do typechecking (and casting) */ - q = block(NAME, NIL,NIL, pstk->in_t, pstk->in_sym->sdf, - pstk->in_sym->ssue); - p = buildtree(ASSIGN, q, p); - nfree(p->n_left); - q = optim(p->n_right); - nfree(p); - - /* bitfield sizes are special */ - if (pstk->in_sym->sclass & FIELD) - fsz = -(pstk->in_sym->sclass & FLDSIZ); - else - fsz = tsize(pstk->in_t, pstk->in_sym->sdf, pstk->in_sym->ssue); - woff = findoff(); - - nsetval(woff, fsz, q); - - stkpop(); -#ifdef PCC_DEBUG - if (idebug > 2) { - printf("scalinit e(%p)\n", p); - } -#endif -} - -/* - * Generate code to insert a value into a bitfield. - */ -static void -insbf(OFFSZ off, int fsz, int val) -{ - struct symtab sym; - NODE *p, *r; - TWORD typ; - -#ifdef PCC_DEBUG - if (idebug > 1) - printf("insbf: off %lld fsz %d val %d\n", off, fsz, val); -#endif - - if (fsz == 0) - return; - - /* small opt: do char instead of bf asg */ - if ((off & (ALCHAR-1)) == 0 && fsz == SZCHAR) - typ = CHAR; - else - typ = INT; - /* Fake a struct reference */ - spname = csym; - p = buildtree(ADDROF, - buildtree(NAME, NIL, NIL), NIL); - r = block(ICON, NIL, NIL, typ, 0, MKSUE(typ)); - sym.stype = typ; - sym.squal = 0; - sym.sdf = 0; - sym.ssue = MKSUE(typ); - sym.soffset = off; - sym.sclass = typ == INT ? FIELD | fsz : MOU; - r->n_sp = &sym; - p = block(STREF, p, r, INT, 0, MKSUE(INT)); - ecode(buildtree(ASSIGN, stref(p), bcon(val))); -} - -/* - * Clear a bitfield, starting at off and size fsz. - */ -static void -clearbf(OFFSZ off, OFFSZ fsz) -{ - /* Pad up to the next even initializer */ - if ((off & (ALCHAR-1)) || (fsz < SZCHAR)) { - int ba = ((off + (SZCHAR-1)) & ~(SZCHAR-1)) - off; - if (ba > fsz) - ba = fsz; - insbf(off, ba, 0); - off += ba; - fsz -= ba; - } - while (fsz >= SZCHAR) { - insbf(off, SZCHAR, 0); - off += SZCHAR; - fsz -= SZCHAR; - } - if (fsz) - insbf(off, fsz, 0); -} - -/* - * final step of initialization. - * print out init nodes and generate copy code (if needed). - */ -void -endinit(void) -{ - struct llist *ll; - struct ilist *il; - int fsz; - OFFSZ lastoff, tbit; - -#ifdef PCC_DEBUG - if (idebug) - printf("endinit()\n"); -#endif - - if (csym->sclass != AUTO) - setscl(csym); - - /* Calculate total block size */ - if (ISARY(csym->stype) && csym->sdf->ddim == 0) { - tbit = numents*basesz; /* open-ended arrays */ - csym->sdf->ddim = numents; - if (csym->sclass == AUTO) { /* Get stack space */ - csym->soffset = NOOFFSET; - oalloc(csym, &autooff); - } - } else - tbit = tsize(csym->stype, csym->sdf, csym->ssue); - - /* Traverse all entries and print'em out */ - lastoff = 0; - SLIST_FOREACH(ll, &lpole, next) { - for (il = ll->il; il; il = il->next) { -#ifdef PCC_DEBUG - if (idebug > 1) { - printf("off %lld size %d val %lld type ", - ll->begsz+il->off, il->fsz, il->n->n_lval); - tprint(stdout, il->n->n_type, 0); - printf("\n"); - } -#endif - fsz = il->fsz; - if (csym->sclass == AUTO) { - struct symtab sym; - NODE *p, *r, *n; - - if (ll->begsz + il->off > lastoff) - clearbf(lastoff, - (ll->begsz + il->off) - lastoff); - - /* Fake a struct reference */ - spname = csym; - p = buildtree(ADDROF, - buildtree(NAME, NIL, NIL), NIL); - n = il->n; - r = block(ICON, NIL, NIL, INT, 0, MKSUE(INT)); - sym.stype = n->n_type; - sym.squal = n->n_qual; - sym.sdf = n->n_df; - sym.ssue = n->n_sue; - sym.soffset = ll->begsz + il->off; - sym.sclass = fsz < 0 ? FIELD | -fsz : 0; - r->n_sp = &sym; - p = block(STREF, p, r, INT, 0, MKSUE(INT)); - ecode(buildtree(ASSIGN, stref(p), il->n)); - if (fsz < 0) - fsz = -fsz; - - } else { - if (ll->begsz + il->off > lastoff) - zbits(lastoff, - (ll->begsz + il->off) - lastoff); - if (fsz < 0) { - fsz = -fsz; - infld(il->off, fsz, il->n->n_lval); - } else - ninval(il->off, fsz, il->n); - nfree(il->n); - } - lastoff = ll->begsz + il->off + fsz; - } - } - if (csym->sclass == AUTO) { - clearbf(lastoff, tbit-lastoff); - } else - zbits(lastoff, tbit-lastoff); -} - -/* - * process an initializer's left brace - */ -void -ilbrace() -{ - -#ifdef PCC_DEBUG - if (idebug) - printf("ilbrace()\n"); -#endif - - if (pstk == NULL) - return; - - stkpush(); - pstk->in_fl = 1; /* mark lbrace */ -#ifdef PCC_DEBUG - if (idebug > 1) - prtstk(pstk); -#endif -} - -/* - * called when a '}' is seen - */ -void -irbrace() -{ -#ifdef PCC_DEBUG - if (idebug) - printf("irbrace()\n"); - if (idebug > 2) - prtstk(pstk); -#endif - - if (pstk == NULL) - return; - - /* Got right brace, search for corresponding in the stack */ - for (; pstk->in_prev != NULL; pstk = pstk->in_prev) { - if(!pstk->in_fl) - continue; - - /* we have one now */ - - pstk->in_fl = 0; /* cancel { */ - 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++; - } - stkpop(); - return; - } -} - -/* - * Create a new init stack based on given elements. - */ -static void -mkstack(NODE *p) -{ - -#ifdef PCC_DEBUG - if (idebug) - printf("mkstack: %p\n", p); -#endif - - if (p == NULL) - return; - mkstack(p->n_left); - - switch (p->n_op) { - case LB: /* Array index */ - if (p->n_right->n_op != ICON) - cerror("mkstack"); - if (!ISARY(pstk->in_t)) - uerror("array indexing non-array"); - pstk->in_n = p->n_right->n_lval; - nfree(p->n_right); - 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) - break; - if (pstk->in_xp[0] == NULL) - uerror("member missing"); - } else { - uerror("not a struct/union"); - } - break; - default: - cerror("mkstack2"); - } - nfree(p); - stkpush(); - -} - -/* - * Initialize a specific element, as per C99. - */ -void -desinit(NODE *p) -{ - int op = p->n_op; - - if (pstk == NULL) - stkpush(); /* passed end of array */ - while (pstk->in_prev && pstk->in_fl == 0) - pstk = pstk->in_prev; /* Empty stack */ - - if (ISSOU(pstk->in_t)) - pstk->in_xp = pstk->in_sym->ssue->suelem; - - mkstack(p); /* Setup for assignment */ - - /* pop one step if SOU, ilbrace will push */ - if (op == NAME) - pstk = pstk->in_prev; - -#ifdef PCC_DEBUG - if (idebug > 1) { - printf("desinit e\n"); - prtstk(pstk); - } -#endif -} - -/* - * Convert a string to an array of char/wchar for asginit. - */ -static void -strcvt(NODE *p) -{ - char *s; - int i; - - for (s = p->n_sp->sname; *s != 0; ) { - if (*s++ == '\\') { - i = esccon(&s); - } else - i = (unsigned char)s[-1]; - asginit(bcon(i)); - } - nfree(p); -} - -/* - * Do an assignment to a struct element. - */ -void -asginit(NODE *p) -{ - int g; - -#ifdef PCC_DEBUG - if (idebug) - printf("asginit %p\n", p); - if (idebug > 1 && p) - fwalk(p, eprint, 0); -#endif - - /* convert string to array of char */ - if (p && DEUNSIGN(p->n_type) == ARY+CHAR) { - /* - * ...but only if next element is ARY+CHAR, otherwise - * just fall through. - */ - - /* HACKHACKHACK */ - struct instk *is = pstk; - - if (pstk == NULL) - stkpush(); - while (ISSOU(pstk->in_t) || ISARY(pstk->in_t)) - stkpush(); - if (pstk->in_prev && - DEUNSIGN(pstk->in_prev->in_t) == ARY+CHAR) { - pstk = pstk->in_prev; - if ((g = pstk->in_fl) == 0) - pstk->in_fl = 1; /* simulate ilbrace */ - - strcvt(p); - if (g == 0) - irbrace(); - return; - } else - pstk = is; /* no array of char */ - /* END HACKHACKHACK */ - } - - if (p == NULL) { /* only end of compound stmt */ - irbrace(); - } else /* assign next element */ - scalinit(p); -} - -#ifdef PCC_DEBUG -void -prtstk(struct instk *in) -{ - int i, o = 0; - - printf("init stack:\n"); - for (; in != NULL; in = in->in_prev) { - for (i = 0; i < o; i++) - printf(" "); - printf("%p) '%s' ", in, in->in_sym->sname); - tprint(stdout, in->in_t, 0); - printf(" %s ", scnames(in->in_sym->sclass)); - if (ISARY(in->in_t) && in->in_df->ddim) - printf("arydim=%d ", in->in_df->ddim); - printf("ninit=%d ", in->in_n); - if (BTYPE(in->in_t) == STRTY || ISARY(in->in_t)) - printf("stsize=%d ", in->in_sym->ssue->suesize); - 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); - else - printf("END struct"); - } - printf("\n"); - o++; - } -} -#endif - -/* - * Do a simple initialization. - * At block 0, just print out the value, at higher levels generate - * appropriate code. - */ -void -simpleinit(struct symtab *sp, NODE *p) -{ - /* May be an initialization of an array of char by a string */ - if ((DEUNSIGN(p->n_type) == ARY+CHAR && - DEUNSIGN(sp->stype) == ARY+CHAR) || - (DEUNSIGN(p->n_type) == ARY+WCHAR_TYPE && - DEUNSIGN(sp->stype) == ARY+WCHAR_TYPE)) { - /* Handle "aaa" as { 'a', 'a', 'a' } */ - beginit(sp); - strcvt(p); - if (csym->sdf->ddim == 0) - scalinit(bcon(0)); /* Null-term arrays */ - endinit(); - return; - } - - switch (sp->sclass) { - case STATIC: - case EXTDEF: - spname = sp; - p = optim(buildtree(ASSIGN, buildtree(NAME, NIL, NIL), p)); - setscl(sp); - if (p->n_right->n_op != ICON && p->n_right->n_op != FCON) - uerror("initializer element is not a constant"); - else - ninval(0, p->n_right->n_sue->suesize, p->n_right); - tfree(p); - break; - - case AUTO: - case REGISTER: - if (ISARY(sp->stype)) - cerror("no array init"); - spname = sp; - ecomp(buildtree(ASSIGN, buildtree(NAME, NIL, NIL), p)); - break; - - default: - uerror("illegal initialization"); - } -} diff --git a/usr.bin/pcc/cc/ccom/inline.c b/usr.bin/pcc/cc/ccom/inline.c deleted file mode 100644 index 9d7b2eebc89..00000000000 --- a/usr.bin/pcc/cc/ccom/inline.c +++ /dev/null @@ -1,209 +0,0 @@ -/* $OpenBSD: inline.c,v 1.2 2007/09/15 22:04:38 ray Exp $ */ -/* - * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "pass1.h" - -#include <stdarg.h> - -/* - * ilink from ipole points to the next struct in the list of functions. - */ -static struct istat { - struct istat *ilink; - char *name; - int type; -#define NOTYETR 0 /* saved but not yet referenced */ -#define NOTYETW 1 /* saved and referenced but not yet written out */ -#define WRITTEN 2 /* is written out */ -#define NOTYETD 3 /* referenced but not yet saved */ - struct interpass shead; -} *ipole, *cifun; - -#define IP_REF (MAXIP+1) - -int isinlining, recovernodes; -int inlnodecnt, inlstatcnt; - -#define ialloc() permalloc(sizeof(struct istat)); inlstatcnt++ -#define nalloc() permalloc(sizeof(NODE)) - -static void -tcnt(NODE *p) -{ - inlnodecnt++; -} - -static struct istat * -findfun(char *name) -{ - struct istat *is = ipole; - while (is) { - if (is->name == name) - return is; - is = is->ilink; - } - return NULL; -} - -static void -refnode(char *str) -{ - struct interpass *ip; - - if (sdebug) - printf("refnode(%s)\n", str); - - ip = permalloc(sizeof(*ip)); - ip->type = IP_REF; - ip->ip_name = str; - inline_addarg(ip); -} - -void -inline_addarg(struct interpass *ip) -{ - DLIST_INSERT_BEFORE(&cifun->shead, ip, qelem); - if (ip->type == IP_NODE) - walkf(ip->ip_node, tcnt); /* Count as saved */ -} - -/* - * Called to setup for inlining of a new function. - */ -void -inline_start(char *name) -{ - struct istat *is; - - if (sdebug) - printf("inline_start(\"%s\")\n", name); - - if (isinlining) - cerror("already inlining function"); - - if ((is = findfun(name)) == 0) { - is = ialloc(); - is->ilink = ipole; - ipole = is; - is->name = name; - is->type = NOTYETR; - } else { - if (is->type != NOTYETD) - cerror("inline function already defined"); - is->type = NOTYETW; - } - DLIST_INIT(&is->shead, qelem); - cifun = is; - isinlining++; -} - -void -inline_end() -{ - if (sdebug) - printf("inline_end()\n"); - - isinlining = 0; -} - -/* - * Called when an inline function is found, to be sure that it will - * be written out. - * The function may not be defined when inline_ref() is called. - */ -void -inline_ref(char *name) -{ - struct istat *w = ipole; - - if (sdebug) - printf("inline_ref(\"%s\")\n", name); - if (isinlining) { - refnode(name); - } else { - while (w != NULL) { - if (w->name == name) { - if (w->type == NOTYETR) - w->type = NOTYETW; - return; /* setup for writeout */ - } - w = w->ilink; - } - /* function not yet defined, print out when found */ - w = ialloc(); - w->ilink = ipole; - ipole = w; - w->name = name; - w->type = NOTYETD; - } -} - -static void -puto(struct istat *w) -{ - struct interpass *ip, *nip; - - /* if -O, list will be saved again so foreach cannot be used */ - ip = DLIST_NEXT(&w->shead, qelem); - while (ip != (&w->shead)) { - nip = DLIST_NEXT(ip, qelem); - DLIST_REMOVE(ip, qelem); - if (ip->type == IP_REF) - inline_ref(ip->ip_name); - else - pass2_compile(ip); - ip = nip; - } - DLIST_INIT(&w->shead, qelem); -} - -/* - * printout functions that are referenced. - */ -void -inline_prtout() -{ - struct istat *w = ipole; - int gotone = 0; - - if (w == NULL) - return; - recovernodes++; - while (w != NULL) { - if (w->type == NOTYETW) { - puto(w); - w->type = WRITTEN; - gotone++; - } - w = w->ilink; - } - if (gotone) - inline_prtout(); - recovernodes--; -} diff --git a/usr.bin/pcc/cc/ccom/main.c b/usr.bin/pcc/cc/ccom/main.c deleted file mode 100644 index a4ae51d0e9e..00000000000 --- a/usr.bin/pcc/cc/ccom/main.c +++ /dev/null @@ -1,317 +0,0 @@ -/* $OpenBSD: main.c,v 1.4 2007/09/25 10:52:06 otto Exp $ */ - -/* - * Copyright (c) 2002 Anders Magnusson. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <unistd.h> -#include <signal.h> -#include <string.h> -#include <stdlib.h> - -#include "pass1.h" -#include "pass2.h" - -int sflag, nflag, oflag, kflag; -int lflag, odebug, rdebug, radebug, vdebug, s2debug, udebug, x2debug; -#if !defined(MULTIPASS) || defined(PASST) -int iTflag, oTflag; -#endif -int xdebug, mdebug, sdebug, gflag, c2debug, pdebug; -int Wstrict_prototypes, Wmissing_prototypes, Wimplicit_int, - Wimplicit_function_declaration; -int xssaflag, xtailcallflag, xtemps, xdeljumps; - -int e2debug, t2debug, f2debug, b2debug; - -struct suedef btdims[24]; -char *prgname; - -static void prtstats(void); - -static struct { - char *n; int *f; -} flagstr[] = { - { "strict-prototypes", &Wstrict_prototypes, }, - { "missing-prototypes", &Wmissing_prototypes, }, - { "implicit-int", &Wimplicit_int, }, - { "implicit-function-declaration", &Wimplicit_function_declaration, }, - { NULL, NULL, }, -}; - -static void -usage(void) -{ - (void)fprintf(stderr, "usage: %s [option] [infile] [outfile]...\n", - prgname); - exit(1); -} - -static void -segvcatch(int a) -{ - fprintf(stderr, "%sinternal compiler error: %s, line %d\n", - nerrors ? "" : "major ", ftitle, lineno); - fflush(stderr); - exit(1); -} - -/* - * "emulate" the gcc warning flags. - */ -static void -Wflags(char *str) -{ - int i, found = 0, all; - - if (strcmp(str, "implicit") == 0) { - Wimplicit_int = Wimplicit_function_declaration = 1; - return; - } - all = strcmp(str, "W") == 0; - for (i = 0; flagstr[i].n; i++) - if (all || strcmp(flagstr[i].n, str) == 0) { - *flagstr[i].f = 1; - found++; - } - if (found == 0) - usage(); -} - - -/* control multiple files */ -int -main(int argc, char *argv[]) -{ - - int ch; - - prgname = argv[0]; - - while ((ch = getopt(argc, argv, "VlwX:Z:W:sOT:gx:kv")) != -1) - switch (ch) { -#if !defined(MULTIPASS) || defined(PASS1) - case 'X': - while (*optarg) - switch (*optarg++) { - case 'd': ++ddebug; break; /* declarations */ - case 'i': ++idebug; break; /* initializations */ - case 'b': ++bdebug; break; - case 't': ++tdebug; break; - case 'e': ++edebug; break; /* pass1 exit */ - case 'x': ++xdebug; break; /* MD code */ - case 's': ++sdebug; break; - case 'n': ++nflag; break; - case 'o': ++oflag; break; - case 'p': ++pdebug; break; /* prototype */ - default: - fprintf(stderr, "unknown X flag '%c'\n", - optarg[-1]); - exit(1); - } -#endif - break; -#if !defined(MULTIPASS) || defined(PASST) - case 'T': - while (*optarg) - switch (*optarg++) { - case 'i': ++iTflag; break; - case 'o': ++oTflag; break; - case 'n': ++nflag; break; - default: - fprintf(stderr, "unknown T flag '%c'\n", - optarg[-1]); - exit(1); - } -#endif - break; -#if !defined(MULTIPASS) || defined(PASS2) - case 'Z': - while (*optarg) - switch (*optarg++) { - case 'f': /* instruction matching */ - ++f2debug; - break; - case 'e': /* print tree upon pass2 enter */ - ++e2debug; - break; - case 'o': ++odebug; break; - case 'r': /* register alloc/graph coloring */ - ++rdebug; - break; - case 'a': ++radebug; break; - case 'b': /* basic block and SSA building */ - ++b2debug; - break; - case 'c': /* code printout */ - ++c2debug; - break; - case 'm': ++mdebug; break; - case 'v': ++vdebug; break; - case 't': ++t2debug; break; - case 's': /* shape matching */ - ++s2debug; - break; - case 'u': /* Sethi-Ullman debugging */ - ++udebug; - break; - case 'x': ++x2debug; break; - case 'n': ++nflag; break; - default: - fprintf(stderr, "unknown Z flag '%c'\n", - optarg[-1]); - exit(1); - } -#endif - break; - - case 'k': /* PIC code */ - ++kflag; - break; - - case 'l': /* linenos */ - ++lflag; - break; - - case 'g': /* Debugging */ - gflag = 1; - break; - - case 's': /* Statistics */ - ++sflag; - break; - - case 'W': /* Enable different warnings */ - Wflags(optarg); - break; - - case 'x': /* Different optimizations */ - if (strcmp(optarg, "ssa") == 0) - xssaflag++; - else if (strcmp(optarg, "tailcall") == 0) - xtailcallflag++; - else if (strcmp(optarg, "temps") == 0) - xtemps++; - else if (strcmp(optarg, "deljumps") == 0) - xdeljumps++; - else - usage(); - break; - case 'v': - printf("ccom: %s\n", VERSSTR); - break; - - case '?': - default: - usage(); - } - argc -= optind; - argv += optind; - - if (argc != 0) { - if (freopen(argv[0], "r", stdin) == NULL) { - fprintf(stderr, "open input file '%s':", - argv[0]); - perror(NULL); - exit(1); - } - if (argc != 1) - if (freopen(argv[1], "w", stdout) == NULL) { - fprintf(stderr, "open output file '%s':", - argv[1]); - perror(NULL); - exit(1); - } - } - - mkdope(); - signal(SIGSEGV, segvcatch); - fregs = FREGS; /* number of free registers */ - lineno = 1; -#ifdef GCC_COMPAT - gcc_init(); -#endif - - /* dimension table initialization */ - - btdims[VOID].suesize = 0; - btdims[BOOL].suesize = SZBOOL; - btdims[CHAR].suesize = SZCHAR; - btdims[INT].suesize = SZINT; - btdims[FLOAT].suesize = SZFLOAT; - btdims[DOUBLE].suesize = SZDOUBLE; - btdims[LDOUBLE].suesize = SZLDOUBLE; - btdims[LONG].suesize = SZLONG; - btdims[LONGLONG].suesize = SZLONGLONG; - btdims[SHORT].suesize = SZSHORT; - btdims[UCHAR].suesize = SZCHAR; - btdims[USHORT].suesize = SZSHORT; - btdims[UNSIGNED].suesize = SZINT; - btdims[ULONG].suesize = SZLONG; - btdims[ULONGLONG].suesize = SZLONGLONG; - /* starts past any of the above */ - reached = 1; - - bjobcode(); - -#ifdef STABS - if (gflag) { - stabs_file(argc ? argv[0] : ""); - stabs_init(); - } -#endif - - (void) yyparse(); - yyaccpt(); - - ejobcode( nerrors ? 1 : 0 ); - if (!nerrors) - lcommprint(); - - if (sflag) - prtstats(); - return(nerrors?1:0); - -} - -void -prtstats(void) -{ - extern int nametabs, namestrlen, tmpallocsize, permallocsize; - extern int lostmem, arglistcnt, dimfuncnt, inlnodecnt, inlstatcnt; - extern int symtabcnt, suedefcnt; - - fprintf(stderr, "Name table entries: %d pcs\n", nametabs); - fprintf(stderr, "Name string size: %d B\n", namestrlen); - fprintf(stderr, "Permanent allocated memory: %d B\n", permallocsize); - fprintf(stderr, "Temporary allocated memory: %d B\n", tmpallocsize); - fprintf(stderr, "Lost memory: %d B\n", lostmem); - fprintf(stderr, "Argument list unions: %d pcs\n", arglistcnt); - fprintf(stderr, "Dimension/function unions: %d pcs\n", dimfuncnt); - fprintf(stderr, "Struct/union/enum blocks: %d pcs\n", suedefcnt); - fprintf(stderr, "Inline node count: %d pcs\n", inlnodecnt); - fprintf(stderr, "Inline control blocks: %d pcs\n", inlstatcnt); - fprintf(stderr, "Permanent symtab entries: %d pcs\n", symtabcnt); -} diff --git a/usr.bin/pcc/cc/ccom/optim.c b/usr.bin/pcc/cc/ccom/optim.c deleted file mode 100644 index c06a5b94671..00000000000 --- a/usr.bin/pcc/cc/ccom/optim.c +++ /dev/null @@ -1,355 +0,0 @@ -/* $OpenBSD: optim.c,v 1.2 2007/09/15 22:04:38 ray Exp $ */ -/* - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code and documentation must retain the above - * copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditionsand the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of other - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -# include "pass1.h" - -# define SWAP(p,q) {sp=p; p=q; q=sp;} -# define RCON(p) (p->n_right->n_op==ICON) -# define RO(p) p->n_right->n_op -# define RV(p) p->n_right->n_lval -# define LCON(p) (p->n_left->n_op==ICON) -# 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 */ -static NODE * -zapleft(NODE *p) -{ - NODE *q; - - q = p->n_left; - nfree(p->n_right); - nfree(p); - return q; -} - -/* - * fortran function arguments - */ -static NODE * -fortarg(NODE *p) -{ - if( p->n_op == CM ){ - p->n_left = fortarg( p->n_left ); - p->n_right = fortarg( p->n_right ); - return(p); - } - - while( ISPTR(p->n_type) ){ - p = buildtree( UMUL, p, NIL ); - } - return( optim(p) ); -} - - /* mapping relationals when the sides are reversed */ -short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT }; - -/* - * local optimizations, most of which are probably - * machine independent - */ -NODE * -optim(NODE *p) -{ - int o, ty; - NODE *sp, *q; - int i; - TWORD t; - - if( (t=BTYPE(p->n_type))==ENUMTY || t==MOETY ) econvert(p); - if( oflag ) return(p); - - ty = coptype(p->n_op); - if( ty == LTYPE ) return(p); - - if( ty == BITYPE ) p->n_right = optim(p->n_right); - p->n_left = optim(p->n_left); - - /* collect constants */ -again: o = p->n_op; - switch(o){ - - case SCONV: - case PCONV: - return( clocal(p) ); - - case FORTCALL: - p->n_right = fortarg( p->n_right ); - break; - - case ADDROF: - if (LO(p) == TEMP) - return p; - if( LO(p) != NAME ) cerror( "& error" ); - - if( !andable(p->n_left) ) return(p); - - LO(p) = ICON; - - setuleft: - /* paint over the type of the left hand side with the type of the top */ - p->n_left->n_type = p->n_type; - p->n_left->n_df = p->n_df; - p->n_left->n_sue = p->n_sue; - q = p->n_left; - nfree(p); - return q; - - case UMUL: - if( LO(p) != ICON ) break; - LO(p) = NAME; - goto setuleft; - - case RS: - if (LO(p) == RS && RCON(p->n_left) && RCON(p)) { - /* two right-shift by constants */ - RV(p) += RV(p->n_left); - p->n_left = zapleft(p->n_left); - } -#if 0 - else if (LO(p) == LS && RCON(p->n_left) && RCON(p)) { - RV(p) -= RV(p->n_left); - if (RV(p) < 0) - o = p->n_op = LS, RV(p) = -RV(p); - p->n_left = zapleft(p->n_left); - } -#endif - if (RO(p) == ICON) { - if (RV(p) < 0) { - RV(p) = -RV(p); - p->n_op = LS; - goto again; - } -#ifdef notyet /* must check for side effects, --a >> 32; */ - if (RV(p) >= tsize(p->n_type, p->n_df, p->n_sue) && - ISUNSIGNED(p->n_type)) { /* ignore signed shifts */ - /* too many shifts */ - tfree(p->n_left); - nfree(p->n_right); - p->n_op = ICON; p->n_lval = 0; p->n_sp = NULL; - } else -#endif - /* avoid larger shifts than type size */ - if (RV(p) >= p->n_sue->suesize) { - RV(p) = RV(p) % p->n_sue->suesize; - werror("shift larger than type"); - } - if (RV(p) == 0) - p = zapleft(p); - } - break; - - case LS: - if (LO(p) == LS && RCON(p->n_left) && RCON(p)) { - /* two left-shift by constants */ - RV(p) += RV(p->n_left); - p->n_left = zapleft(p->n_left); - } -#if 0 - else if (LO(p) == RS && RCON(p->n_left) && RCON(p)) { - RV(p) -= RV(p->n_left); - p->n_left = zapleft(p->n_left); - } -#endif - if (RO(p) == ICON) { - if (RV(p) < 0) { - RV(p) = -RV(p); - p->n_op = RS; - goto again; - } -#ifdef notyet /* must check for side effects */ - if (RV(p) >= tsize(p->n_type, p->n_df, p->n_sue)) { - /* too many shifts */ - tfree(p->n_left); - nfree(p->n_right); - p->n_op = ICON; p->n_lval = 0; p->n_sp = NULL; - } else -#endif - /* avoid larger shifts than type size */ - if (RV(p) >= p->n_sue->suesize) { - RV(p) = RV(p) % p->n_sue->suesize; - werror("shift larger than type"); - } - if (RV(p) == 0) - p = zapleft(p); - } - break; - - case MINUS: - if (LCON(p) && RCON(p) && p->n_left->n_sp == p->n_right->n_sp) { - /* link-time constants, but both are the same */ - /* solve it now by forgetting the symbols */ - p->n_left->n_sp = p->n_right->n_sp = NULL; - } - if( !nncon(p->n_right) ) break; - RV(p) = -RV(p); - o = p->n_op = PLUS; - - case MUL: - case PLUS: - case AND: - case OR: - case ER: - /* commutative ops; for now, just collect constants */ - /* someday, do it right */ - if( nncon(p->n_left) || ( LCON(p) && !RCON(p) ) ) - SWAP( p->n_left, p->n_right ); - /* make ops tower to the left, not the right */ - if( RO(p) == o ){ - NODE *t1, *t2, *t3; - t1 = p->n_left; - sp = p->n_right; - t2 = sp->n_left; - t3 = sp->n_right; - /* now, put together again */ - p->n_left = sp; - sp->n_left = t1; - sp->n_right = t2; - p->n_right = t3; - } - if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->n_left) && - conval(p->n_right, MINUS, p->n_left->n_right)){ - zapleft: - - q = p->n_left->n_left; - nfree(p->n_left->n_right); - nfree(p->n_left); - p->n_left = q; - } - if( RCON(p) && LO(p)==o && RCON(p->n_left) && - conval( p->n_right, o, p->n_left->n_right ) ){ - goto zapleft; - } - else if( LCON(p) && RCON(p) && conval( p->n_left, o, p->n_right ) ){ - zapright: - nfree(p->n_right); - q = makety(p->n_left, p->n_type, p->n_qual, - p->n_df, p->n_sue); - nfree(p); - return clocal(q); - } - - /* change muls to shifts */ - - if( o == MUL && nncon(p->n_right) && (i=ispow2(RV(p)))>=0){ - if( i == 0 ) { /* multiplication by 1 */ - goto zapright; - } - o = p->n_op = LS; - p->n_right->n_type = INT; - p->n_right->n_df = NULL; - RV(p) = i; - } - - /* change +'s of negative consts back to - */ - if( o==PLUS && nncon(p->n_right) && RV(p)<0 ){ - RV(p) = -RV(p); - o = p->n_op = MINUS; - } - - /* remove ops with RHS 0 */ - if ((o == PLUS || o == MINUS || o == OR || o == ER) && - nncon(p->n_right) && RV(p) == 0) { - goto zapright; - } - break; - - case DIV: - if( nncon( p->n_right ) && p->n_right->n_lval == 1 ) - goto zapright; - if (LCON(p) && RCON(p) && conval(p->n_left, DIV, p->n_right)) - goto zapright; - if (RCON(p) && ISUNSIGNED(p->n_type) && (i=ispow2(RV(p))) > 0) { - p->n_op = RS; - RV(p) = i; - q = p->n_right; - if(tsize(q->n_type, q->n_df, q->n_sue) > SZINT) - p->n_right = makety(q, INT, 0, 0, MKSUE(INT)); - - break; - } - break; - - case MOD: - if (RCON(p) && ISUNSIGNED(p->n_type) && ispow2(RV(p)) > 0) { - p->n_op = AND; - RV(p) = RV(p) -1; - break; - } - break; - - case EQ: - case NE: - case LT: - case LE: - case GT: - case GE: - case ULT: - case ULE: - case UGT: - case UGE: - if( !LCON(p) ) break; - - /* exchange operands */ - - sp = p->n_left; - p->n_left = p->n_right; - p->n_right = sp; - p->n_op = revrel[p->n_op - EQ ]; - break; - - } - - return(p); - } - -int -ispow2(CONSZ c) -{ - int i; - if( c <= 0 || (c&(c-1)) ) return(-1); - for( i=0; c>1; ++i) c >>= 1; - return(i); -} - -int -nncon( p ) NODE *p; { - /* is p a constant without a name */ - return( p->n_op == ICON && p->n_sp == NULL ); - } diff --git a/usr.bin/pcc/cc/ccom/pass1.h b/usr.bin/pcc/cc/ccom/pass1.h deleted file mode 100644 index 247fa0e3cec..00000000000 --- a/usr.bin/pcc/cc/ccom/pass1.h +++ /dev/null @@ -1,394 +0,0 @@ -/* $OpenBSD: pass1.h,v 1.2 2007/09/15 22:04:38 ray Exp $ */ -/* - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code and documentation must retain the above - * copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditionsand the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of other - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/types.h> -#include <stdarg.h> - -#include "manifest.h" - -#include "protos.h" -#include "ccconfig.h" - -/* - * Storage classes - */ -#define SNULL 0 -#define AUTO 1 -#define EXTERN 2 -#define STATIC 3 -#define REGISTER 4 -#define EXTDEF 5 -/* #define LABEL 6*/ -/* #define ULABEL 7*/ -#define MOS 8 -#define PARAM 9 -#define STNAME 10 -#define MOU 11 -#define UNAME 12 -#define TYPEDEF 13 -#define FORTRAN 14 -#define ENAME 15 -#define MOE 16 -#define UFORTRAN 17 -#define USTATIC 18 -#define ILABEL 19 - - /* field size is ORed in */ -#define FIELD 0100 -#define FLDSIZ 077 -extern char *scnames(int); - -/* - * Symbol table flags - */ -#define SNORMAL 0 -#define STAGNAME 01 -#define SLBLNAME 02 -#define SMOSNAME 03 -#define SSTRING 04 -#define NSTYPES 05 -#define SMASK 07 - -#define SSET 00010 -#define SREF 00020 -#define SNOCREAT 00040 -#define STEMP 00100 -#define SDYNARRAY 00200 -#define SINLINE 00400 -#define STNODE 01000 -#ifdef GCC_COMPAT -#define SRENAME 02000 /* Node is renamed */ -#endif -#define SASG 04000 - -#ifndef FIXDEF -#define FIXDEF(p) -#endif - - /* alignment of initialized quantities */ -#ifndef AL_INIT -#define AL_INIT ALINT -#endif - -struct rstack; -struct symtab; -union arglist; - -/* - * Dimension/prototype information. - * ddim > 0 holds the dimension of an array. - * ddim < 0 is a dynamic array and refers to a tempnode. - */ -union dimfun { - int ddim; /* Dimension of an array */ - union arglist *dfun; /* Prototype index */ -}; - -/* - * Struct/union/enum definition. - * The first element (size) is used for other types as well. - */ -struct suedef { - int suesize; /* Size of the struct */ - struct symtab **suelem;/* points to the list of elements */ - int suealign; /* Alignment of this struct */ -}; - -/* - * Argument list member info when storing prototypes. - */ -union arglist { - TWORD type; - union dimfun *df; - struct suedef *sue; -}; -#define TNULL INCREF(MOETY) /* pointer to MOETY -- impossible type */ -#define TELLIPSIS INCREF(INCREF(MOETY)) - -/* - * Symbol table definition. - * - * The symtab_hdr struct is used to save label info in NAME and ICON nodes. - */ -struct symtab_hdr { - struct symtab *h_next; /* link to other symbols in the same scope */ - int h_offset; /* offset or value */ - char h_sclass; /* storage class */ - char h_slevel; /* scope level */ - short h_sflags; /* flags, see below */ -}; - -struct symtab { - struct symtab_hdr hdr; - char *sname; - TWORD stype; /* type word */ - TWORD squal; /* qualifier word */ - union dimfun *sdf; /* ptr to the dimension/prototype array */ - struct suedef *ssue; /* ptr to the definition table */ - int suse; /* line number of last use of the variable */ -}; - -#define snext hdr.h_next -#define soffset hdr.h_offset -#define sclass hdr.h_sclass -#define slevel hdr.h_slevel -#define sflags hdr.h_sflags - -#define MKSUE(type) &btdims[type] -extern struct suedef btdims[]; - -/* - * External definitions - */ -struct swents { /* switch table */ - struct swents *next; /* Next struct in linked list */ - CONSZ sval; /* case value */ - int slab; /* associated label */ -}; -void genswitch(int, struct swents **, int); - -extern int blevel; -extern int instruct, got_type; -extern int oldstyle; - -extern int lineno, nerrors; - -extern char *ftitle; -extern struct symtab *cftnsp; -extern int autooff, maxautooff, argoff, strucoff; -extern int brkflag; -extern int lastloc; - -extern OFFSZ inoff; - -extern int reached; -extern int isinlining; - -/* tunnel to buildtree for name id's */ - -extern struct symtab *spname; - -extern int sdebug, idebug, pdebug; - -/* various labels */ -extern int brklab; -extern int contlab; -extern int flostat; -extern int retlab; - -/* - * Flags used in structures/unions - */ -#define INSTRUCT 02 -#define INUNION 04 - -/* - * Flags used in the (elementary) flow analysis ... - */ -#define FBRK 02 -#define FCONT 04 -#define FDEF 010 -#define FLOOP 020 - -/* mark an offset which is undefined */ - -#define NOOFFSET (-10201) - -/* declarations of various functions */ -extern NODE - *buildtree(int, NODE *l, NODE *r), - *mkty(unsigned, union dimfun *, struct suedef *), - *rstruct(char *, int), - *dclstruct(struct rstack *), - *strend(char *), - *wstrend(char *), - *tymerge(NODE *typ, NODE *idp), - *stref(NODE *), - *offcon(OFFSZ, TWORD, union dimfun *, struct suedef *), - *bcon(int), - *bpsize(NODE *), - *convert(NODE *, int), - *pconvert(NODE *), - *oconvert(NODE *), - *ptmatch(NODE *), - *tymatch(NODE *), - *makety(NODE *, TWORD, TWORD, union dimfun *, struct suedef *), - *block(int, NODE *, NODE *r, TWORD, union dimfun *, struct suedef *), - *doszof(NODE *), - *talloc(void), - *optim(NODE *), - *clocal(NODE *), - *ccopy(NODE *), - *btsize(TWORD, union dimfun *, struct suedef *), - *tempnode(int, TWORD type, union dimfun *df, struct suedef *sue), - *doacall(NODE *f, NODE *a); -OFFSZ tsize(TWORD, union dimfun *, struct suedef *), - psize(NODE *); -NODE * typenode(NODE *new); -void spalloc(NODE *, NODE *, OFFSZ); -char *exname(char *); - -int oalloc(struct symtab *p, int *poff); -void deflabel(char *); -void deflab1(int); -void setloc1(int); -void gotolabel(char *); -unsigned int esccon(char **sptr); -void inline_start(char *name); -void inline_end(void); -void inline_addarg(struct interpass *); -void inline_ref(char *); -void inline_prtout(void); -void ftnarg(NODE *); -struct rstack *bstruct(char *, int); -void moedef(char *); -void beginit(struct symtab *); -void simpleinit(struct symtab *, NODE *); -struct symtab *lookup(char *name, int s); -struct symtab *getsymtab(char *name, int flags); -char *addstring(char *); -char *addname(char *); -char *newstring(char *, int len); -void symclear(int level); -void schedremove(struct symtab *p); -struct symtab *hide(struct symtab *p); -int talign(unsigned int, struct suedef *); -void bfcode(struct symtab **, int); -int chkftn(union arglist *, union arglist *); -void branch(int); -void cbranch(NODE *p, NODE *q); -void extdec(struct symtab *); -void commdec(struct symtab *); -void lcommdec(struct symtab *); -int falloc(struct symtab *p, int w, int new, NODE *pty); -TWORD ctype(TWORD); -void ninval(CONSZ off, int fsz, NODE *); -void infld(CONSZ off, int fsz, CONSZ); -void zbits(CONSZ off, int fsz); -void indata(CONSZ, int); -void instring(char *); -void defnam(struct symtab *); -void plabel(int lab); -void bjobcode(void); -void ejobcode(int); -void calldec(NODE *, NODE *); -int cisreg(TWORD); -char *tmpsprintf(char *fmt, ...); -char *tmpvsprintf(char *fmt, va_list ap); -void asginit(NODE *); -void desinit(NODE *); -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); -void myp2tree(NODE *); -void lcommprint(void); -void lcommdel(struct symtab *); - -#ifdef GCC_COMPAT -void gcc_init(void); -int gcc_keyword(char *, NODE **); -void gcc_rename(struct symtab *sp, char *newname); -char *gcc_findname(struct symtab *sp); -#endif - -#ifdef STABS -void stabs_init(void); -void stabs_file(char *); -void stabs_line(int); -void stabs_rbrac(int); -void stabs_lbrac(int); -void stabs_func(struct symtab *); -void stabs_newsym(struct symtab *); -void stabs_chgsym(struct symtab *); -void stabs_struct(struct symtab *p, struct suedef *sue); -#endif - -#ifndef CHARCAST -/* to make character constants into character connstants */ -/* this is a macro to defend against cross-compilers, etc. */ -#define CHARCAST(x) (char)(x) -#endif - -/* - * C compiler first pass extra defines. - */ -#define QUALIFIER (MAXOP+1) -#define CLASS (MAXOP+2) -#define RB (MAXOP+3) -#define DOT (MAXOP+4) -#define ELLIPSIS (MAXOP+5) -#define TYPE (MAXOP+6) -#define LB (MAXOP+7) -#define COMOP (MAXOP+8) -#define QUEST (MAXOP+9) -#define COLON (MAXOP+10) -#define ANDAND (MAXOP+11) -#define OROR (MAXOP+12) -#define NOT (MAXOP+13) -#define CAST (MAXOP+14) -/* #define STRING (MAXOP+15) */ - -/* The following must be in the same order as their NOASG counterparts */ -#define PLUSEQ (MAXOP+16) -#define MINUSEQ (MAXOP+17) -#define DIVEQ (MAXOP+18) -#define MODEQ (MAXOP+19) -#define MULEQ (MAXOP+20) -#define ANDEQ (MAXOP+21) -#define OREQ (MAXOP+22) -#define EREQ (MAXOP+23) -#define LSEQ (MAXOP+24) -#define RSEQ (MAXOP+25) - -#define UNASG (-(PLUSEQ-PLUS))+ - -#define INCR (MAXOP+26) -#define DECR (MAXOP+27) -/* - * The following types are only used in pass1. - */ -#define SIGNED (MAXTYPES+1) -#define BOOL (MAXTYPES+2) - - -#define coptype(o) (cdope(o)&TYFLG) -#define clogop(o) (cdope(o)&LOGFLG) -#define casgop(o) (cdope(o)&ASGFLG) - diff --git a/usr.bin/pcc/cc/ccom/pftn.c b/usr.bin/pcc/cc/ccom/pftn.c deleted file mode 100644 index cc805df26a3..00000000000 --- a/usr.bin/pcc/cc/ccom/pftn.c +++ /dev/null @@ -1,2676 +0,0 @@ -/* $OpenBSD: pftn.c,v 1.6 2007/10/01 18:51:57 otto Exp $ */ -/* - * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code and documentation must retain the above - * copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditionsand the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of other - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Many changes from the 32V sources, among them: - * - New symbol table manager (moved to another file). - * - Prototype saving/checks. - */ - -# include "pass1.h" - -#include <string.h> /* XXX - for strcmp */ - -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 */ -int retlab = NOLAB; /* return label for subroutine */ -int brklab; -int contlab; -int flostat; -int instruct, blevel; -int reached, prolab; - -struct params; - -#define ISSTR(ty) (ty == STRTY || ty == UNIONTY || ty == ENUMTY) -#define ISSOU(ty) (ty == STRTY || ty == UNIONTY) -#define MKTY(p, t, d, s) r = talloc(); *r = *p; \ - r = argcast(r, t, d, s); *p = *r; nfree(r); - -/* - * Info stored for delaying string printouts. - */ -struct strsched { - struct strsched *next; - int locctr; - struct symtab *sym; -} *strpole; - -/* - * Linked list stack while reading in structs. - */ -struct rstack { - struct rstack *rnext; - int rinstruct; - int rclass; - int rstrucoff; - struct params *rlparam; - struct symtab *rsym; -}; - -/* - * Linked list for parameter (and struct elements) declaration. - */ -static struct params { - struct params *next, *prev; - struct symtab *sym; -} *lpole, *lparam; -static int nparams; - -/* defines used for getting things off of the initialization stack */ - -static NODE *arrstk[10]; -static int arrstkp; -static int intcompare; - -void fixtype(NODE *p, int class); -int fixclass(int class, TWORD type); -int falloc(struct symtab *p, int w, int new, NODE *pty); -static void dynalloc(struct symtab *p, int *poff); -void inforce(OFFSZ n); -void vfdalign(int n); -static void ssave(struct symtab *); -static void strprint(void); -static void alprint(union arglist *al, int in); -static void lcommadd(struct symtab *sp); - -int ddebug = 0; - -/* - * Declaration of an identifier. Handles redeclarations, hiding, - * incomplete types and forward declarations. - */ - -void -defid(NODE *q, int class) -{ - struct symtab *p; - TWORD type, qual; - TWORD stp, stq; - int scl; - union dimfun *dsym, *ddef; - int slev, temp, changed; - - if (q == NIL) - return; /* an error was detected */ - - p = q->n_sp; - -#ifdef PCC_DEBUG - if (ddebug) { - printf("defid(%s (%p), ", p->sname, p); - tprint(stdout, q->n_type, q->n_qual); - printf(", %s, (%p,%p)), level %d\n", scnames(class), - q->n_df, q->n_sue, blevel); - } -#endif - - fixtype(q, class); - - type = q->n_type; - qual = q->n_qual; - class = fixclass(class, type); - - stp = p->stype; - stq = p->squal; - slev = p->slevel; - -#ifdef PCC_DEBUG - if (ddebug) { - printf(" modified to "); - tprint(stdout, type, qual); - printf(", %s\n", scnames(class)); - printf(" previous def'n: "); - tprint(stdout, stp, stq); - printf(", %s, (%p,%p)), level %d\n", - scnames(p->sclass), p->sdf, p->ssue, slev); - } -#endif - - if (blevel == 1) { - switch (class) { - default: - if (!(class&FIELD)) - uerror("declared argument %s missing", - p->sname ); - case MOS: - case STNAME: - case MOU: - case UNAME: - case MOE: - case ENAME: - case TYPEDEF: - ; - } - } - - if (stp == UNDEF) - goto enter; /* New symbol */ - - if (type != stp) - goto mismatch; - - if (blevel > slev && (class == AUTO || class == REGISTER)) - /* new scope */ - goto mismatch; - - /* - * test (and possibly adjust) dimensions. - * also check that prototypes are correct. - */ - dsym = p->sdf; - ddef = q->n_df; - changed = 0; - for (temp = type; temp & TMASK; temp = DECREF(temp)) { - if (ISARY(temp)) { - if (dsym->ddim == 0) { - dsym->ddim = ddef->ddim; - changed = 1; - } else if (ddef->ddim != 0 && dsym->ddim!=ddef->ddim) { - goto mismatch; - } - ++dsym; - ++ddef; - } else if (ISFTN(temp)) { - /* add a late-defined prototype here */ - if (cftnsp == NULL && dsym->dfun == NULL) - dsym->dfun = ddef->dfun; - if (!oldstyle && ddef->dfun != NULL && - chkftn(dsym->dfun, ddef->dfun)) - uerror("declaration doesn't match prototype"); - dsym++, ddef++; - } - } -#ifdef STABS - if (changed && gflag) - stabs_chgsym(p); /* symbol changed */ -#endif - - /* check that redeclarations are to the same structure */ - if ((temp == STRTY || temp == UNIONTY || temp == ENUMTY) && - p->ssue != q->n_sue && - class != STNAME && class != UNAME && class != ENAME) { - goto mismatch; - } - - scl = p->sclass; - -#ifdef PCC_DEBUG - if (ddebug) - 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) { - - case EXTERN: - switch( scl ){ - case STATIC: - case USTATIC: - if( slev==0 ) return; - break; - case EXTDEF: - case EXTERN: - case FORTRAN: - case UFORTRAN: - return; - } - break; - - case STATIC: - if (scl==USTATIC || (scl==EXTERN && blevel==0)) { - p->sclass = STATIC; - return; - } - if (changed || (scl == STATIC && blevel == slev)) - return; /* identical redeclaration */ - break; - - case USTATIC: - if (scl==STATIC || scl==USTATIC) - return; - break; - - case TYPEDEF: - if (scl == class) - return; - break; - - case UFORTRAN: - if (scl == UFORTRAN || scl == FORTRAN) - return; - break; - - case FORTRAN: - if (scl == UFORTRAN) { - p->sclass = FORTRAN; - return; - } - break; - - case MOU: - case MOS: - if (scl == class) { - if (oalloc(p, &strucoff)) - break; - if (class == MOU) - strucoff = 0; - ssave(p); - return; - } - break; - - case MOE: - break; - - case EXTDEF: - switch (scl) { - case EXTERN: - p->sclass = EXTDEF; - return; - case USTATIC: - p->sclass = STATIC; - return; - } - break; - - case STNAME: - case UNAME: - case ENAME: - if (scl != class) - break; - if (p->ssue->suesize == 0) - return; /* previous entry just a mention */ - break; - - case AUTO: - case REGISTER: - ; /* mismatch.. */ - } - - mismatch: - - /* - * Only allowed for automatic variables. - */ - if (blevel == slev || class == EXTERN || class == FORTRAN || - class == UFORTRAN) { - if (ISSTR(class) && !ISSTR(p->sclass)) { - uerror("redeclaration of %s", p->sname); - return; - } - } - if (blevel == 0) - uerror("redeclaration of %s", p->sname); - q->n_sp = p = hide(p); - - enter: /* make a new entry */ - -#ifdef PCC_DEBUG - if(ddebug) - printf(" new entry made\n"); -#endif - p->stype = type; - p->squal = qual; - p->sclass = class; - p->slevel = blevel; - p->soffset = NOOFFSET; - p->suse = lineno; - if (class == STNAME || class == UNAME || class == ENAME) { - p->ssue = permalloc(sizeof(struct suedef)); - suedefcnt++; - p->ssue->suesize = 0; - p->ssue->suelem = NULL; - p->ssue->suealign = ALSTRUCT; - } else { - switch (BTYPE(type)) { - case STRTY: - case UNIONTY: - case ENUMTY: - p->ssue = q->n_sue; - break; - default: - p->ssue = MKSUE(BTYPE(type)); - } - } - - /* copy dimensions */ - p->sdf = q->n_df; - /* Do not save param info for old-style functions */ - if (ISFTN(type) && oldstyle) - p->sdf->dfun = NULL; - - /* allocate offsets */ - if (class&FIELD) { - (void) falloc(p, class&FLDSIZ, 0, NIL); /* new entry */ - ssave(p); - } else switch (class) { - - case REGISTER: - cerror("register var"); - - case AUTO: - if (arrstkp) - dynalloc(p, &autooff); - else - oalloc(p, &autooff); - break; - case STATIC: - case EXTDEF: - p->soffset = getlab(); -#ifdef GCC_COMPAT - { extern char *renname; - if (renname) - gcc_rename(p, renname); - renname = NULL; - } -#endif - break; - - case EXTERN: - case UFORTRAN: - case FORTRAN: - p->soffset = getlab(); -#ifdef notdef - /* Cannot reset level here. What does the standard say??? */ - p->slevel = 0; -#endif -#ifdef GCC_COMPAT - { extern char *renname; - if (renname) - gcc_rename(p, renname); - renname = NULL; - } -#endif - break; - case MOU: - case MOS: - oalloc(p, &strucoff); - if (class == MOU) - strucoff = 0; - ssave(p); - break; - - case MOE: - p->soffset = strucoff++; - ssave(p); - break; - - } - -#ifdef STABS - if (gflag) - stabs_newsym(p); -#endif - -#ifdef PCC_DEBUG - if (ddebug) - printf( " sdf, ssue, offset: %p, %p, %d\n", - p->sdf, p->ssue, p->soffset); -#endif - -} - -void -ssave(struct symtab *sym) -{ - struct params *p; - - p = tmpalloc(sizeof(struct params)); - p->next = NULL; - p->sym = sym; - - if (lparam == NULL) { - p->prev = (struct params *)&lpole; - lpole = p; - } else { - lparam->next = p; - p->prev = lparam; - } - lparam = p; -} - -/* - * end of function - */ -void -ftnend() -{ - extern struct savbc *savbc; - extern struct swdef *swpole; - char *c; - - if (retlab != NOLAB && nerrors == 0) { /* inside a real function */ - plabel(retlab); - efcode(); /* struct return handled here */ - c = cftnsp->sname; -#ifdef GCC_COMPAT - c = gcc_findname(cftnsp); -#endif - SETOFF(maxautooff, ALCHAR); - send_passt(IP_EPILOG, 0, maxautooff/SZCHAR, c, - cftnsp->stype, cftnsp->sclass == EXTDEF, retlab); - } - - tcheck(); - brklab = contlab = retlab = NOLAB; - flostat = 0; - if (nerrors == 0) { - if (savbc != NULL) - cerror("bcsave error"); - if (lparam != NULL) - cerror("parameter reset error"); - if (swpole != NULL) - cerror("switch error"); - } - savbc = NULL; - lparam = NULL; - maxautooff = autooff = AUTOINIT; - reached = 1; - - if (isinlining) - inline_end(); - inline_prtout(); - - strprint(); - - tmpfree(); /* Release memory resources */ -} - -void -dclargs() -{ - union dimfun *df; - 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) - goto done; - - /* - * Generate a list for bfcode(). - * Parameters were pushed in reverse order. - */ - if (nparams != 0) - parr = tmpalloc(sizeof(struct symtab *) * nparams); - - if (nparams) - for (a = lparam, i = 0; a != NULL && a != (struct params *)&lpole; - a = a->prev) { - - p = a->sym; - parr[i++] = p; - if (p->stype == FARG) { - p->stype = INT; - p->ssue = MKSUE(INT); - } - if (ISARY(p->stype)) { - p->stype += (PTR-ARY); - p->sdf++; - } else if (ISFTN(p->stype)) { - 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); -#endif - } - if (oldstyle && (df = cftnsp->sdf) && (al = df->dfun)) { - /* - * Check against prototype of oldstyle function. - */ - alb = al2 = tmpalloc(sizeof(union arglist) * nparams * 3 + 1); - for (i = 0; i < nparams; i++) { - TWORD type = parr[i]->stype; - (al2++)->type = type; - if (ISSTR(BTYPE(type))) - (al2++)->sue = parr[i]->ssue; - while (!ISFTN(type) && !ISARY(type) && type > BTMASK) - type = DECREF(type); - if (type > BTMASK) - (al2++)->df = parr[i]->sdf; - } - al2->type = TNULL; - intcompare = 1; - if (chkftn(al, alb)) - uerror("function doesn't match prototype"); - intcompare = 0; - } -done: cendarg(); - c = cftnsp->sname; -#ifdef GCC_COMPAT - c = gcc_findname(cftnsp); -#endif -#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); - if (xtemps) { - /* put arguments in temporaries */ - for (i = 0; i < nparams; i++) { - NODE *q, *r, *s; - - p = parr[i]; - if (p->stype == STRTY || p->stype == UNIONTY || - cisreg(p->stype) == 0) - continue; - spname = p; - q = buildtree(NAME, 0, 0); - r = tempnode(0, p->stype, p->sdf, p->ssue); - s = buildtree(ASSIGN, r, q); - p->soffset = r->n_lval; - p->sflags |= STNODE; - ecomp(s); - } - plabel(getlab()); /* used when spilling */ - } - lparam = NULL; - nparams = 0; -} - -/* - * reference to a structure or union, with no definition - */ -NODE * -rstruct(char *tag, int soru) -{ - 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 : ENUMTY); - defid(q, (soru&INSTRUCT) ? STNAME : - ((soru&INUNION) ? UNAME : ENAME)); - nfree(q); - break; - - case STRTY: - if (soru & INSTRUCT) - break; - goto def; - - case UNIONTY: - if (soru & INUNION) - break; - goto def; - - case ENUMTY: - if (!(soru&(INUNION|INSTRUCT))) - break; - goto def; - - } - q = mkty(p->stype, 0, p->ssue); - q->n_sue = p->ssue; - return q; -} - -void -moedef(char *name) -{ - NODE *q; - - q = block(NAME, NIL, NIL, MOETY, 0, 0); - q->n_sp = lookup(name, 0); - defid(q, MOE); - nfree(q); -} - -/* - * begining of structure or union declaration - */ -struct rstack * -bstruct(char *name, int soru) -{ - struct rstack *r; - struct symtab *s; - NODE *q; - - if (name != NULL) - s = lookup(name, STAGNAME); - else - s = 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 { /* enum */ - strunem = MOE; - q->n_type = ENUMTY; - if (s != NULL) - defid(q, ENAME); - } - r->rsym = q->n_sp; - r->rlparam = lparam; - nfree(q); - - return r; -} - -/* - * Called after a struct is declared to restore the environment. - */ -NODE * -dclstruct(struct rstack *r) -{ - NODE *n; - struct params *l, *m; - struct suedef *sue; - struct symtab *p; - int al, sa, sz; - TWORD temp; - int i, high, low; - - if (r->rsym == NULL) { - sue = permalloc(sizeof(struct suedef)); - suedefcnt++; - sue->suesize = 0; - sue->suealign = ALSTRUCT; - } else - sue = r->rsym->ssue; - -#ifdef PCC_DEBUG - if (ddebug) - printf("dclstruct(%s)\n", r->rsym ? r->rsym->sname : "??"); -#endif - temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY); - instruct = r->rinstruct; - strunem = r->rclass; - 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); - - for (i = 0; l != NULL; l = l->next) { - sue->suelem[i++] = p = l->sym; - - if (p == NULL) - cerror("gummy structure member"); - if (temp == ENUMTY) { - if (p->soffset < low) - low = p->soffset; - if (p->soffset > high) - high = p->soffset; - p->ssue = sue; - continue; - } - sa = talign(p->stype, p->ssue); - if (p->sclass & FIELD) { - sz = p->sclass&FLDSIZ; - } else { - sz = tsize(p->stype, p->sdf, p->ssue); - } - if (sz > strucoff) - strucoff = 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); - - if (temp == ENUMTY) { - TWORD ty; - -#ifdef ENUMSIZE - ty = ENUMSIZE(high,low); -#else - if ((char)high == high && (char)low == low) - ty = ctype(CHAR); - else if ((short)high == high && (short)low == low) - ty = ctype(SHORT); - else - ty = ctype(INT); -#endif - strucoff = tsize(ty, 0, MKSUE(ty)); - sue->suealign = al = talign(ty, MKSUE(ty)); - } - - sue->suesize = strucoff; - sue->suealign = al; - -#ifdef STABS - if (gflag) - stabs_struct(r->rsym, sue); -#endif - -#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]); - } - } -#endif - - strucoff = r->rstrucoff; - if ((lparam = r->rlparam) != NULL) - lparam->next = NULL; - n = mkty(temp, 0, sue); - return n; -} - -/* - * error printing routine in parser - */ -void yyerror(char *s); -void -yyerror(char *s) -{ - uerror(s); -} - -void yyaccpt(void); -void -yyaccpt(void) -{ - ftnend(); -} - -/* - * p is top of type list given to tymerge later. - * Find correct CALL node and declare parameters from there. - */ -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. - */ - for (; p->n_op != NAME; p = p->n_left) { - 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); - nparams++; -#ifdef PCC_DEBUG - if (ddebug > 2) - printf(" saving sym %s (%p) from (%p)\n", - s->sname, s, 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); - 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); -#endif -} - -/* - * compute the alignment of an object with type ty, sizeoff index s - */ -int -talign(unsigned int ty, struct suedef *sue) -{ - int i; - - if (ISPTR(ty)) - return(ALPOINT); /* shortcut */ - - if(sue == NULL && ty!=INT && ty!=CHAR && ty!=SHORT && - ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT) { - return(fldal(ty)); - } - - for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){ - switch( (ty>>i)&TMASK ){ - - case FTN: - cerror("compiler takes alignment of function"); - case PTR: - return(ALPOINT); - case ARY: - continue; - case 0: - break; - } - } - - switch( BTYPE(ty) ){ - - case UNIONTY: - case ENUMTY: - case STRTY: - return((unsigned int)sue->suealign); - case BOOL: - return (ALBOOL); - case CHAR: - case UCHAR: - return (ALCHAR); - case FLOAT: - return (ALFLOAT); - case LDOUBLE: - return (ALLDOUBLE); - case DOUBLE: - return (ALDOUBLE); - case LONGLONG: - case ULONGLONG: - return (ALLONGLONG); - case LONG: - case ULONG: - return (ALLONG); - case SHORT: - case USHORT: - return (ALSHORT); - default: - return (ALINT); - } -} - -/* compute the size associated with type ty, - * dimoff d, and sizoff s */ -/* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */ -OFFSZ -tsize(TWORD ty, union dimfun *d, struct suedef *sue) -{ - - int i; - OFFSZ mult, sz; - - mult = 1; - - for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){ - switch( (ty>>i)&TMASK ){ - - case FTN: - uerror( "cannot take size of function"); - case PTR: - return( SZPOINT(ty) * mult ); - case ARY: - mult *= d->ddim; - d++; - continue; - case 0: - break; - - } - } - - if (sue == NULL) - cerror("bad tsize sue"); - sz = sue->suesize; -#ifdef GCC_COMPAT - if (ty == VOID) - sz = SZCHAR; -#endif - if (ty != STRTY && ty != UNIONTY) { - if (sz == 0) { - uerror("unknown size"); - return(SZINT); - } - } else { - if (sue->suelem == NULL) - uerror("unknown structure/union/enum"); - } - - return((unsigned int)sz * mult); -} - -/* - * Write last part of wide string. - * Do not bother to save wide strings. - */ -NODE * -wstrend(char *str) -{ - struct symtab *sp = getsymtab(str, SSTRING|STEMP); - struct strsched *sc = tmpalloc(sizeof(struct strsched)); - NODE *p = block(NAME, NIL, NIL, WCHAR_TYPE+ARY, - tmpalloc(sizeof(union dimfun)), MKSUE(WCHAR_TYPE)); - int i; - char *c; - - sp->sclass = ILABEL; - sp->soffset = getlab(); - sp->stype = WCHAR_TYPE+ARY; - - sc = tmpalloc(sizeof(struct strsched)); - sc->locctr = STRNG; - sc->sym = sp; - sc->next = strpole; - strpole = sc; - - /* length calculation, used only for sizeof */ - for (i = 0, c = str; *c; ) { - if (*c++ == '\\') - (void)esccon(&c); - i++; - } - p->n_df->ddim = (i+1) * ((MKSUE(WCHAR_TYPE))->suesize/SZCHAR); - p->n_sp = sp; - return(p); -} - -/* - * Write last part of string. - */ -NODE * -strend(char *str) -{ -// extern int maystr; - struct symtab *s; - NODE *p; - int i; - char *c; - - /* If an identical string is already emitted, just forget this one */ - str = addstring(str); /* enter string in string table */ - s = lookup(str, SSTRING); /* check for existance */ - - if (s->soffset == 0 /* && maystr == 0 */) { /* No string */ - struct strsched *sc; - s->sclass = ILABEL; - - /* - * Delay printout of this string until after the current - * function, or the end of the statement. - */ - sc = tmpalloc(sizeof(struct strsched)); - sc->locctr = STRNG; - sc->sym = s; - sc->next = strpole; - strpole = sc; - s->soffset = getlab(); - } - - p = block(NAME, NIL, NIL, CHAR+ARY, - tmpalloc(sizeof(union dimfun)), MKSUE(CHAR)); -#ifdef CHAR_UNSIGNED - p->n_type = UCHAR+ARY; -#endif - /* length calculation, used only for sizeof */ - for (i = 0, c = str; *c; ) { - if (*c++ == '\\') - (void)esccon(&c); - i++; - } - p->n_df->ddim = i+1; - p->n_sp = s; - return(p); -} - -/* - * Print out new strings, before temp memory is cleared. - */ -void -strprint() -{ - char *wr; - int i, val, isw; - NODE *p = bcon(0); - - while (strpole != NULL) { - setloc1(STRNG); - deflab1(strpole->sym->soffset); - isw = strpole->sym->stype == WCHAR_TYPE+ARY; - - i = 0; - wr = strpole->sym->sname; - while (*wr != 0) { - if (*wr++ == '\\') - val = esccon(&wr); - else - val = (unsigned char)wr[-1]; - if (isw) { - p->n_lval = val; - p->n_type = WCHAR_TYPE; - ninval(i*(WCHAR_TYPE/SZCHAR), - (MKSUE(WCHAR_TYPE))->suesize, p); - } else - bycode(val, i); - i++; - } - if (isw) { - p->n_lval = 0; - ninval(i*(WCHAR_TYPE/SZCHAR), - (MKSUE(WCHAR_TYPE))->suesize, p); - } else { - bycode(0, i++); - bycode(-1, i); - } - strpole = strpole->next; - } - nfree(p); -} - -#if 0 -/* - * simulate byte v appearing in a list of integer values - */ -void -putbyte(int v) -{ - NODE *p; - p = bcon(v); - incode( p, SZCHAR ); - tfree( p ); -// gotscal(); -} -#endif - -/* - * update the offset pointed to by poff; return the - * offset of a value of size `size', alignment `alignment', - * given that off is increasing - */ -int -upoff(int size, int alignment, int *poff) -{ - int off; - - off = *poff; - SETOFF(off, alignment); - if (off < 0) - cerror("structure or stack overgrown"); /* wrapped */ - *poff = off+size; - return (off); -} - -/* - * allocate p with offset *poff, and update *poff - */ -int -oalloc(struct symtab *p, int *poff ) -{ - int al, off, tsz; - int noff; - - /* - * Only generate tempnodes if we are optimizing, - * and only for integers, floats or pointers, - * and not if the basic type is volatile. - */ -/* XXX OLDSTYLE */ - if (xtemps && ((p->sclass == AUTO) || (p->sclass == REGISTER)) && - (p->stype < STRTY || ISPTR(p->stype)) && - !ISVOL((p->squal << TSHIFT)) && cisreg(p->stype)) { - NODE *tn = tempnode(0, p->stype, p->sdf, p->ssue); - p->soffset = tn->n_lval; - p->sflags |= STNODE; - nfree(tn); - return 0; - } - - al = talign(p->stype, p->ssue); - noff = off = *poff; - tsz = tsize(p->stype, p->sdf, p->ssue); -#ifdef BACKAUTO - if (p->sclass == AUTO) { - noff = off + tsz; - if (noff < 0) - cerror("stack overflow"); - SETOFF(noff, al); - off = -noff; - } else -#endif - if (p->sclass == PARAM && (p->stype == CHAR || p->stype == UCHAR || - p->stype == SHORT || p->stype == USHORT)) { - off = upoff(SZINT, ALINT, &noff); -#ifndef RTOLBYTES - off = noff - tsz; -#endif - } else { - off = upoff(tsz, al, &noff); - } - - if (p->sclass != REGISTER) { - /* in case we are allocating stack space for register arguments */ - if (p->soffset == NOOFFSET) - p->soffset = off; - else if(off != p->soffset) - return(1); - } - - *poff = noff; - return(0); -} - -/* - * Allocate space on the stack for dynamic arrays. - * 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. - * - if it's a multi-dimensional array the following (numdim-1) integers - * will contain the sizes to multiply the indexes with. - * - code to write the dimension sizes this will be generated here. - * - code to allocate space on the stack will be generated here. - */ -static void -dynalloc(struct symtab *p, int *poff) -{ - union dimfun *df; - NODE *n, *nn, *tn, *pol; - TWORD t; - int i, no; - - /* - * The pointer to the array is stored in a TEMP node, which 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 = tn->n_lval; - - df = p->sdf; - - pol = NIL; - for (i = 0; ISARY(t); t = DECREF(t), df++) { - if (df->ddim >= 0) - continue; - n = arrstk[i++]; - nn = tempnode(0, INT, 0, MKSUE(INT)); - no = nn->n_lval; - ecomp(buildtree(ASSIGN, nn, n)); /* Save size */ - - df->ddim = -no; - n = tempnode(no, INT, 0, MKSUE(INT)); - if (pol == NIL) - pol = n; - else - pol = buildtree(MUL, pol, n); - } - /* Create stack gap */ - if (pol == NIL) - uerror("aggregate dynamic array not allowed"); - else - spalloc(tn, pol, tsize(t, 0, p->ssue)); - arrstkp = 0; -} - -/* - * allocate a field of width w - * new is 0 if new entry, 1 if redefinition, -1 if alignment - */ -int -falloc(struct symtab *p, int w, int new, NODE *pty) -{ - int al,sz,type; - - type = (new<0)? pty->n_type : p->stype; - - /* this must be fixed to use the current type in alignments */ - switch( new<0?pty->n_type:p->stype ){ - - case ENUMTY: { - struct suedef *sue; - sue = new < 0 ? pty->n_sue : p->ssue; - al = sue->suealign; - sz = sue->suesize; - break; - } - - case CHAR: - case UCHAR: - al = ALCHAR; - sz = SZCHAR; - break; - - case SHORT: - case USHORT: - al = ALSHORT; - sz = SZSHORT; - break; - - case INT: - case UNSIGNED: - al = ALINT; - sz = SZINT; - break; - - default: - if( new < 0 ) { - uerror( "illegal field type" ); - al = ALINT; - } else - al = fldal( p->stype ); - sz =SZINT; - } - - if( w > sz ) { - uerror( "field too big"); - w = sz; - } - - if( w == 0 ){ /* align only */ - SETOFF( strucoff, al ); - if( new >= 0 ) uerror( "zero size field"); - return(0); - } - - if( strucoff%al + w > sz ) SETOFF( strucoff, al ); - if( new < 0 ) { - strucoff += 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); - } - p->soffset = strucoff; - strucoff += w; - p->stype = type; - fldty( p ); - return(0); -} - -/* - * handle unitialized declarations assumed to be not functions: - * int a; - * extern int a; - * static int a; - */ -void -nidcl(NODE *p, int class) -{ - struct symtab *sp; - int commflag = 0; - - /* compute class */ - if (class == SNULL) { - if (blevel > 1) - class = AUTO; - else if (blevel != 0 || instruct) - cerror( "nidcl error" ); - else /* blevel = 0 */ - commflag = 1, class = EXTERN; - } - - defid(p, class); - - sp = p->n_sp; - /* check if forward decl */ - if (ISARY(sp->stype) && sp->sdf->ddim == 0) - return; - - if (sp->sflags & SASG) - return; /* already initialized */ - - switch (class) { - case EXTDEF: - /* simulate initialization by 0 */ - simpleinit(p->n_sp, bcon(0)); - break; - case EXTERN: - if (commflag) - lcommadd(p->n_sp); - else - extdec(p->n_sp); - break; - case STATIC: - if (blevel == 0) - lcommadd(p->n_sp); - else - lcommdec(p->n_sp); - break; - } -} - -struct lcd { - SLIST_ENTRY(lcd) next; - struct symtab *sp; -}; - -static SLIST_HEAD(, lcd) lhead = { NULL, &lhead.q_forw}; - -/* - * Add a local common statement to the printout list. - */ -void -lcommadd(struct symtab *sp) -{ - struct lcd *lc, *lcp; - - lcp = NULL; - SLIST_FOREACH(lc, &lhead, next) { - if (lc->sp == sp) - return; /* already exists */ - if (lc->sp == NULL && lcp == NULL) - lcp = lc; - } - if (lcp == NULL) { - lc = permalloc(sizeof(struct lcd)); - lc->sp = sp; - SLIST_INSERT_LAST(&lhead, lc, next); - } else - lcp->sp = sp; -} - -/* - * Delete a local common statement. - */ -void -lcommdel(struct symtab *sp) -{ - struct lcd *lc; - - SLIST_FOREACH(lc, &lhead, next) { - if (lc->sp == sp) { - lc->sp = NULL; - return; - } - } -} - -/* - * Print out the remaining common statements. - */ -void -lcommprint(void) -{ - struct lcd *lc; - - SLIST_FOREACH(lc, &lhead, next) { - if (lc->sp != NULL) { - if (lc->sp->sclass == STATIC) - lcommdec(lc->sp); - else - commdec(lc->sp); - } - } -} - -/* - * Merges a type tree into one type. Returns one type node with merged types - * and class stored in the su field. Frees all other nodes. - * XXX - classes in typedefs? - */ -NODE * -typenode(NODE *p) -{ - NODE *l, *sp = NULL; - int class = 0, adj, noun, sign; - TWORD qual = 0; - - adj = INT; /* INT, LONG or SHORT */ - noun = UNDEF; /* INT, CHAR or FLOAT */ - sign = 0; /* 0, SIGNED or UNSIGNED */ - - /* Remove initial QUALIFIERs */ - if (p && p->n_op == QUALIFIER) { - qual = p->n_type; - l = p->n_left; - nfree(p); - p = l; - } - - /* Handle initial classes special */ - if (p && p->n_op == CLASS) { - class = p->n_type; - l = p->n_left; - nfree(p); - p = l; - } - - /* Remove more QUALIFIERs */ - if (p && p->n_op == QUALIFIER) { - qual |= p->n_type; - l = p->n_left; - nfree(p); - p = l; - } - -ag: if (p && p->n_op == TYPE) { - if (p->n_left == NIL) { -#ifdef CHAR_UNSIGNED - if (p->n_type == CHAR) - p->n_type = UCHAR; -#endif - if (p->n_type == SIGNED) - p->n_type = INT; -uni: p->n_lval = class; - p->n_qual = qual >> TSHIFT; - return p; - } else if (p->n_left->n_op == QUALIFIER) { - qual |= p->n_left->n_type; - l = p->n_left; - p->n_left = l->n_left; - nfree(l); - goto ag; - } else if (ISSTR(p->n_type)) { - /* Save node; needed for return */ - sp = p; - p = p->n_left; - } - } - - while (p != NIL) { - if (p->n_op == QUALIFIER) { - qual |= p->n_type; - goto next; - } - if (p->n_op == CLASS) { - if (class != 0) - uerror("too many storage classes"); - class = p->n_type; - goto next; - } - if (p->n_op != TYPE) - cerror("typenode got notype %d", p->n_op); - switch (p->n_type) { - case UCHAR: - case USHORT: /* may come from typedef */ - if (sign != 0 || adj != INT) - goto bad; - noun = p->n_type; - break; - case SIGNED: - case UNSIGNED: - if (sign != 0) - goto bad; - sign = p->n_type; - break; - case LONG: - if (adj == LONG) { - adj = LONGLONG; - break; - } - /* FALLTHROUGH */ - case SHORT: - if (adj != INT) - goto bad; - adj = p->n_type; - break; - case INT: - case CHAR: - case FLOAT: - case DOUBLE: - if (noun != UNDEF) - goto bad; - noun = p->n_type; - break; - case VOID: - if (noun != UNDEF || adj != INT) - goto bad; - adj = noun = VOID; - break; - case STRTY: - case UNIONTY: - break; - default: - goto bad; - } - next: - l = p->n_left; - nfree(p); - p = l; - } - - if (sp) { - p = sp; - goto uni; - } - -#ifdef CHAR_UNSIGNED - if (noun == CHAR && sign == 0) - sign = UNSIGNED; -#endif - if (noun == UNDEF) { - noun = INT; - } else if (noun == FLOAT) { - if (sign != 0 || adj == SHORT) - goto bad; - noun = (adj == LONG ? DOUBLE : FLOAT); - } else if (noun == DOUBLE) { - if (sign != 0 || adj == SHORT) - goto bad; - noun = (adj == LONG ? LDOUBLE : DOUBLE); - } else if (noun == CHAR && adj != INT) - goto bad; - - if (adj != INT && (noun != DOUBLE && noun != LDOUBLE)) - noun = adj; - if (sign == UNSIGNED) - noun += (UNSIGNED-INT); - - p = block(TYPE, NIL, NIL, noun, 0, 0); - p->n_qual = qual >> TSHIFT; - if (strunem != 0) - class = strunem; - p->n_lval = class; - return p; - -bad: uerror("illegal type combination"); - return mkty(INT, 0, 0); -} - -struct tylnk { - struct tylnk *next; - union dimfun df; -}; - -static void tyreduce(NODE *p, struct tylnk **, int *); - -static void -tylkadd(union dimfun dim, struct tylnk **tylkp, int *ntdim) -{ - (*tylkp)->next = tmpalloc(sizeof(struct tylnk)); - *tylkp = (*tylkp)->next; - (*tylkp)->next = NULL; - (*tylkp)->df = dim; - (*ntdim)++; -} - -/* merge type typ with identifier idp */ -NODE * -tymerge(NODE *typ, NODE *idp) -{ - NODE *p; - union dimfun *j; - struct tylnk *base, tylnk, *tylkp; - unsigned int t; - int ntdim, i; - - if (typ->n_op != TYPE) - cerror("tymerge: arg 1"); - -#ifdef PCC_DEBUG - if (ddebug > 2) { - printf("tymerge(%p,%p)\n", typ, idp); - fwalk(typ, eprint, 0); - fwalk(idp, eprint, 0); - } -#endif - - idp->n_type = typ->n_type; - idp->n_qual = (typ->n_qual << TSHIFT) | idp->n_qual; /* XXX ??? */ - - tylkp = &tylnk; - tylkp->next = NULL; - ntdim = 0; - - tyreduce(idp, &tylkp, &ntdim); - idp->n_sue = typ->n_sue; - - for (t = typ->n_type, j = typ->n_df; t&TMASK; t = DECREF(t)) - if (ISARY(t) || ISFTN(t)) - tylkadd(*j++, &tylkp, &ntdim); - - if (ntdim) { - union dimfun *a = permalloc(sizeof(union dimfun) * ntdim); - dimfuncnt += ntdim; - for (i = 0, base = tylnk.next; base; base = base->next, i++) - a[i] = base->df; - idp->n_df = a; - } else - idp->n_df = NULL; - - /* now idp is a single node: fix up type */ - - idp->n_type = ctype(idp->n_type); - idp->n_qual = DECQAL(idp->n_qual); - - /* in case ctype has rewritten things */ - if ((t = BTYPE(idp->n_type)) != STRTY && t != UNIONTY && t != ENUMTY) - idp->n_sue = MKSUE(t); - - if (idp->n_op != NAME) { - for (p = idp->n_left; p->n_op != NAME; p = p->n_left) - nfree(p); - nfree(p); - idp->n_op = NAME; - } - - return(idp); -} - -/* - * Retrieve all CM-separated argument types, sizes and dimensions and - * put them in an array. - * XXX - can only check first type level, side effects? - */ -static union arglist * -arglist(NODE *n) -{ - union arglist *al; - NODE *w = n, **ap; - int num, cnt, i, j, k; - TWORD ty; - -#ifdef PCC_DEBUG - if (pdebug) { - printf("arglist %p\n", n); - fwalk(n, eprint, 0); - } -#endif - /* First: how much to allocate */ - for (num = cnt = 0, w = n; w->n_op == CM; w = w->n_left) { - cnt++; /* Number of levels */ - num++; /* At least one per step */ - if (w->n_right->n_op == ELLIPSIS) - continue; - ty = w->n_right->n_type; - if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY || - BTYPE(ty) == ENUMTY) - num++; - while (ISFTN(ty) == 0 && ISARY(ty) == 0 && ty > BTMASK) - ty = DECREF(ty); - if (ty > BTMASK) - num++; - } - cnt++; - ty = w->n_type; - if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY || - BTYPE(ty) == ENUMTY) - num++; - while (ISFTN(ty) == 0 && ISARY(ty) == 0 && ty > BTMASK) - ty = DECREF(ty); - if (ty > BTMASK) - num++; - num += 2; /* TEND + last arg type */ - - /* Second: Create list to work on */ - ap = tmpalloc(sizeof(NODE *) * cnt); - al = permalloc(sizeof(union arglist) * num); - arglistcnt += num; - - for (w = n, i = 0; w->n_op == CM; w = w->n_left) - ap[i++] = w->n_right; - ap[i] = w; - - /* Third: Create actual arg list */ - for (k = 0, j = i; j >= 0; j--) { - if (ap[j]->n_op == ELLIPSIS) { - al[k++].type = TELLIPSIS; - ap[j]->n_op = ICON; /* for tfree() */ - continue; - } - /* Convert arrays to pointers */ - if (ISARY(ap[j]->n_type)) { - ap[j]->n_type += (PTR-ARY); - ap[j]->n_df++; - } - /* Convert (silently) functions to pointers */ - if (ISFTN(ap[j]->n_type)) - ap[j]->n_type = INCREF(ap[j]->n_type); - ty = ap[j]->n_type; - al[k++].type = ty; - if (BTYPE(ty) == STRTY || BTYPE(ty) == UNIONTY || - BTYPE(ty) == ENUMTY) - al[k++].sue = ap[j]->n_sue; - while (ISFTN(ty) == 0 && ISARY(ty) == 0 && ty > BTMASK) - ty = DECREF(ty); - if (ty > BTMASK) - al[k++].df = ap[j]->n_df; - } - al[k++].type = TNULL; - if (k > num) - cerror("arglist: k%d > num%d", k, num); - tfree(n); - if (pdebug) - alprint(al, 0); - return al; -} - -/* - * build a type, and stash away dimensions, - * from a parse tree of the declaration - * the type is build top down, the dimensions bottom up - */ -void -tyreduce(NODE *p, struct tylnk **tylkp, int *ntdim) -{ - union dimfun dim; - NODE *r = NULL; - int o; - TWORD t, q; - - o = p->n_op; - if (o == NAME) - return; - - t = INCREF(p->n_type); - q = p->n_qual; - switch (o) { - case CALL: - t += (FTN-PTR); - dim.dfun = arglist(p->n_right); - break; - case UCALL: - t += (FTN-PTR); - dim.dfun = NULL; - break; - case LB: - t += (ARY-PTR); - if (p->n_right->n_op != ICON) { - r = p->n_right; - o = RB; - } else { - dim.ddim = p->n_right->n_lval; - nfree(p->n_right); -#ifdef notdef - /* XXX - check dimensions at usage time */ - if (dim.ddim == 0 && p->n_left->n_op == LB) - uerror("null dimension"); -#endif - } - break; - } - - p->n_left->n_type = t; - p->n_left->n_qual = INCQAL(q) | p->n_left->n_qual; - tyreduce(p->n_left, tylkp, ntdim); - - if (o == LB || o == (UCALL) || o == CALL) - tylkadd(dim, tylkp, ntdim); - if (o == RB) { - dim.ddim = -1; - tylkadd(dim, tylkp, ntdim); - arrstk[arrstkp++] = r; - } - - p->n_sp = p->n_left->n_sp; - p->n_type = p->n_left->n_type; - p->n_qual = p->n_left->n_qual; -} - -static NODE * -argcast(NODE *p, TWORD t, union dimfun *d, struct suedef *sue) -{ - NODE *u, *r = talloc(); - - r->n_op = NAME; - r->n_type = t; - r->n_qual = 0; /* XXX */ - r->n_df = d; - r->n_sue = sue; - - u = buildtree(CAST, r, p); - nfree(u->n_left); - r = u->n_right; - nfree(u); - return r; -} - -#ifndef NO_C_BUILTINS -/* - * replace an alloca function with direct allocation on stack. - * return a destination temp node. - */ -static NODE * -builtin_alloca(NODE *f, NODE *a) -{ - struct symtab *sp; - NODE *t, *u; - -#ifdef notyet - if (xnobuiltins) - return NULL; -#endif - sp = f->n_sp; - - if (a == NULL || a->n_op == CM) { - uerror("wrong arg count for alloca"); - return bcon(0); - } - t = tempnode(0, VOID|PTR, 0, MKSUE(INT) /* XXX */); - u = tempnode(t->n_lval, VOID|PTR, 0, MKSUE(INT) /* XXX */); - spalloc(t, a, SZCHAR); - tfree(f); - return u; -} - -#ifndef TARGET_STDARGS -static NODE * -builtin_stdarg_start(NODE *f, NODE *a) -{ - NODE *p, *q; - int sz; - - /* check num args and type */ - if (a == NULL || a->n_op != CM || a->n_left->n_op == CM || - !ISPTR(a->n_left->n_type)) - goto bad; - - /* must first deal with argument size; use int size */ - p = a->n_right; - if (p->n_type < INT) { - sz = SZINT/tsize(p->n_type, p->n_df, p->n_sue); - } else - sz = 1; - - /* do the real job */ - p = buildtree(ADDROF, p, NIL); /* address of last arg */ -#ifdef BACKAUTO - p = optim(buildtree(PLUS, p, bcon(sz))); /* add one to it (next arg) */ -#else - p = optim(buildtree(MINUS, p, bcon(sz))); /* add one to it (next arg) */ -#endif - q = block(NAME, NIL, NIL, PTR+VOID, 0, 0); /* create cast node */ - q = buildtree(CAST, q, p); /* cast to void * (for assignment) */ - p = q->n_right; - nfree(q->n_left); - nfree(q); - p = buildtree(ASSIGN, a->n_left, p); /* assign to ap */ - tfree(f); - nfree(a); - return p; -bad: - uerror("bad argument to __builtin_stdarg_start"); - return bcon(0); -} - -static NODE * -builtin_va_arg(NODE *f, NODE *a) -{ - NODE *p, *q, *r; - int sz, nodnum; - - /* check num args and type */ - if (a == NULL || a->n_op != CM || a->n_left->n_op == CM || - !ISPTR(a->n_left->n_type) || a->n_right->n_op != TYPE) - goto bad; - - /* create a copy to a temp node of current ap */ - p = tcopy(a->n_left); - q = tempnode(0, p->n_type, p->n_df, p->n_sue); - nodnum = q->n_lval; - ecomp(buildtree(ASSIGN, q, p)); /* done! */ - - r = a->n_right; - sz = tsize(r->n_type, r->n_df, r->n_sue)/SZCHAR; - /* add one to ap */ -#ifdef BACKAUTO - ecomp(buildtree(PLUSEQ, a->n_left, bcon(sz))); -#else - /* XXX fix this; wrong order */ - ecomp(buildtree(MINUSEQ, a->n_left, bcon(sz))); -#endif - - nfree(a->n_right); - nfree(a); - nfree(f); - r = tempnode(nodnum, INCREF(r->n_type), r->n_df, r->n_sue); - return buildtree(UMUL, r, NIL); -bad: - uerror("bad argument to __builtin_va_arg"); - return bcon(0); - -} - -static NODE * -builtin_va_end(NODE *f, NODE *a) -{ - tfree(f); - tfree(a); - return bcon(0); /* nothing */ -} - -static NODE * -builtin_va_copy(NODE *f, NODE *a) -{ - if (a == NULL || a->n_op != CM || a->n_left->n_op == CM) - goto bad; - tfree(f); - f = buildtree(ASSIGN, a->n_left, a->n_right); - nfree(a); - return f; - -bad: - uerror("bad argument to __builtin_va_copy"); - return bcon(0); -} -#endif /* TARGET_STDARGS */ - -static struct bitable { - char *name; - NODE *(*fun)(NODE *f, NODE *a); -} bitable[] = { - { "__builtin_alloca", builtin_alloca }, - { "__builtin_stdarg_start", builtin_stdarg_start }, - { "__builtin_va_arg", builtin_va_arg }, - { "__builtin_va_end", builtin_va_end }, - { "__builtin_va_copy", builtin_va_copy }, -#ifdef TARGET_BUILTINS - TARGET_BUILTINS -#endif -}; -#endif - -#ifdef PCC_DEBUG -/* - * Print a prototype. - */ -static void -alprint(union arglist *al, int in) -{ - int i = 0, j; - - for (; al->type != TNULL; al++) { - for (j = in; j > 0; j--) - printf(" "); - printf("arg %d: ", i++); - tprint(stdout, al->type, 0); - if (BTYPE(al->type) == STRTY || - BTYPE(al->type) == UNIONTY || BTYPE(al->type) == ENUMTY) { - al++; - printf("dim %d\n", al->df->ddim); - } - printf("\n"); - if (ISFTN(DECREF(al->type))) { - al++; - alprint(al->df->dfun, in+1); - } - } - if (in == 0) - printf("end arglist\n"); -} -#endif -/* - * Do prototype checking and add conversions before calling a function. - * Argument f is function and a is a CM-separated list of arguments. - * Returns a merged node (via buildtree() of function and arguments. - */ -NODE * -doacall(NODE *f, NODE *a) -{ - NODE *w, *r; - union arglist *al; - struct ap { - struct ap *next; - NODE *node; - } *at, *apole = NULL; - int argidx/* , hasarray = 0*/; - TWORD type, arrt; - -#ifdef PCC_DEBUG - if (ddebug) { - printf("doacall.\n"); - fwalk(f, eprint, 0); - if (a) - fwalk(a, eprint, 0); - } -#endif - - /* First let MD code do something */ - calldec(f, a); -/* XXX XXX hack */ - if ((f->n_op == CALL) && - f->n_left->n_op == ADDROF && - f->n_left->n_left->n_op == NAME && - (f->n_left->n_left->n_type & 0x7e0) == 0x4c0) - goto build; -/* XXX XXX hack */ - -#ifndef NO_C_BUILTINS - /* check for builtins. function pointers are not allowed */ - if (f->n_op == NAME && - f->n_sp->sname[0] == '_' && f->n_sp->sname[1] == '_') { - int i; - - for (i = 0; i < sizeof(bitable)/sizeof(bitable[0]); i++) { - if (strcmp(bitable[i].name, f->n_sp->sname) == 0) - return (*bitable[i].fun)(f, a); - } - } -#endif - /* - * Do some basic checks. - */ - if (f->n_df == NULL || (al = f->n_df[0].dfun) == NULL) { - if (Wimplicit_function_declaration) { - if (f->n_sp != NULL) - werror("no prototype for function '%s()'", - f->n_sp->sname); - else - werror("no prototype for function pointer"); - } - /* floats must be cast to double */ - if (a == NULL) - goto build; - for (w = a; w->n_op == CM; w = w->n_left) { - if (w->n_right->n_op == TYPE) - uerror("type is not an argument"); - if (w->n_right->n_type != FLOAT) - continue; - w->n_right = argcast(w->n_right, DOUBLE, - NULL, MKSUE(DOUBLE)); - } - if (a->n_op == TYPE) - uerror("type is not an argument"); - if (a->n_type == FLOAT) { - MKTY(a, DOUBLE, 0, 0); - } - goto build; - } - if (al->type == VOID) { - if (a != NULL) - uerror("function takes no arguments"); - goto build; /* void function */ - } else { - if (a == NULL) { - uerror("function needs arguments"); - goto build; - } - } -#ifdef PCC_DEBUG - if (pdebug) { - printf("arglist for %p\n", - f->n_sp != NULL ? f->n_sp->sname : "function pointer"); - alprint(al, 0); - } -#endif - - /* - * Create a list of pointers to the nodes given as arg. - */ - for (w = a; w->n_op == CM; w = w->n_left) { - at = tmpalloc(sizeof(struct ap)); - at->node = w->n_right; - at->next = apole; - apole = at; - } - at = tmpalloc(sizeof(struct ap)); - at->node = w; - at->next = apole; - apole = at; - - /* - * Do the typechecking by walking up the list. - */ - argidx = 1; - while (al->type != TNULL) { - if (al->type == TELLIPSIS) { - /* convert the rest of float to double */ - for (; apole; apole = apole->next) { - if (apole->node->n_type != FLOAT) - continue; - MKTY(apole->node, DOUBLE, 0, 0); - } - goto build; - } - if (apole == NULL) { - uerror("too few arguments to function"); - goto build; - } -/* al = prototyp, apole = argument till ftn */ -/* type = argumentets typ, arrt = prototypens typ */ - type = apole->node->n_type; - arrt = al->type; -#if 0 - if ((hasarray = ISARY(arrt))) - arrt += (PTR-ARY); -#endif - if (ISARY(type)) - type += (PTR-ARY); - - /* Check structs */ - if (type <= BTMASK && arrt <= BTMASK) { - if (type != arrt) { - if (ISSOU(BTYPE(type)) || ISSOU(BTYPE(arrt))) { -incomp: uerror("incompatible types for arg %d", - argidx); - } else { - MKTY(apole->node, arrt, 0, 0) - } - } else if (ISSOU(BTYPE(type))) { - if (apole->node->n_sue != al[1].sue) - goto incomp; - } - goto out; - } - - /* Hereafter its only pointers (or arrays) left */ - /* Check for struct/union intermixing with other types */ - if (((type <= BTMASK) && ISSOU(BTYPE(type))) || - ((arrt <= BTMASK) && ISSOU(BTYPE(arrt)))) - goto incomp; - - /* Check for struct/union compatibility */ - if (type == arrt) { - if (ISSOU(BTYPE(type))) { - if (apole->node->n_sue == al[1].sue) - goto out; - } else - goto out; - } - if (BTYPE(arrt) == ENUMTY && BTYPE(type) == INT && - (arrt & ~BTMASK) == (type & ~BTMASK)) - goto skip; /* XXX enumty destroyed in optim() */ - if (BTYPE(arrt) == VOID && type > BTMASK) - goto skip; /* void *f = some pointer */ - if (arrt > BTMASK && BTYPE(type) == VOID) - goto skip; /* some *f = void pointer */ - if (apole->node->n_op == ICON && apole->node->n_lval == 0) - goto skip; /* Anything assigned a zero */ - - if ((type & ~BTMASK) == (arrt & ~BTMASK)) { - /* do not complain for intermixed char/uchar */ - if ((BTYPE(type) == CHAR || BTYPE(type) == UCHAR) && - (BTYPE(arrt) == CHAR || BTYPE(arrt) == UCHAR)) - goto skip; - } - - werror("implicit conversion of argument %d due to prototype", - argidx); - -skip: if (ISSTR(BTYPE(arrt))) { - MKTY(apole->node, arrt, 0, al[1].sue) - } else { - MKTY(apole->node, arrt, 0, 0) - } - -out: al++; - if (ISSTR(BTYPE(arrt))) - al++; -#if 0 - while (arrt > BTMASK && !ISFTN(arrt)) - arrt = DECREF(arrt); - if (ISFTN(arrt) || hasarray) - al++; -#else - while (arrt > BTMASK) { - if (ISARY(arrt) || ISFTN(arrt)) { - al++; - break; - } - arrt = DECREF(arrt); - } -#endif - apole = apole->next; - argidx++; - } - if (apole != NULL) - uerror("too many arguments to function"); - -build: return buildtree(a == NIL ? UCALL : CALL, f, a); -} - -static int -chk2(TWORD type, union dimfun *dsym, union dimfun *ddef) -{ - while (type > BTMASK) { - switch (type & TMASK) { - case ARY: - /* may be declared without dimension */ - if (dsym->ddim == 0) - dsym->ddim = ddef->ddim; - if (ddef->ddim && dsym->ddim != ddef->ddim) - return 1; - dsym++, ddef++; - break; - case FTN: - /* old-style function headers with function pointers - * will most likely not have a prototype. - * This is not considered an error. */ - if (ddef->dfun == NULL) { -#ifdef notyet - werror("declaration not a prototype"); -#endif - } else if (chkftn(dsym->dfun, ddef->dfun)) - return 1; - dsym++, ddef++; - break; - } - type = DECREF(type); - } - return 0; -} - -/* - * Compare two function argument lists to see if they match. - */ -int -chkftn(union arglist *usym, union arglist *udef) -{ - TWORD t2; - int ty, tyn; - - if (usym == NULL) - return 0; - if (cftnsp != NULL && udef == NULL && usym->type == VOID) - return 0; /* foo() { function with foo(void); prototype */ - if (udef == NULL && usym->type != TNULL) - return 1; - while (usym->type != TNULL) { - if (usym->type == udef->type) - goto done; - /* - * If an old-style declaration, then all types smaller than - * int are given as int parameters. - */ - if (intcompare) { - ty = BTYPE(usym->type); - tyn = BTYPE(udef->type); - if (ty == tyn || ty != INT) - return 1; - if (tyn == CHAR || tyn == UCHAR || - tyn == SHORT || tyn == USHORT) - goto done; - return 1; - } else - return 1; - -done: ty = BTYPE(usym->type); - t2 = usym->type; - if (ISSTR(ty)) { - usym++, udef++; - if (usym->sue != udef->sue) - return 1; - } - - while (ISFTN(t2) == 0 && ISARY(t2) == 0 && t2 > BTMASK) - t2 = DECREF(t2); - if (t2 > BTMASK) { - usym++, udef++; - if (chk2(t2, usym->df, udef->df)) - return 1; - } - usym++, udef++; - } - if (usym->type != udef->type) - return 1; - return 0; -} - -void -fixtype(NODE *p, int class) -{ - unsigned int t, type; - int mod1, mod2; - /* fix up the types, and check for legality */ - - if( (type = p->n_type) == UNDEF ) return; - if ((mod2 = (type&TMASK))) { - t = DECREF(type); - while( mod1=mod2, mod2 = (t&TMASK) ){ - if( mod1 == ARY && mod2 == FTN ){ - uerror( "array of functions is illegal" ); - type = 0; - } - else if( mod1 == FTN && ( mod2 == ARY || mod2 == FTN ) ){ - uerror( "function returns illegal type" ); - type = 0; - } - t = DECREF(t); - } - } - - /* detect function arguments, watching out for structure declarations */ - if (instruct && ISFTN(type)) { - uerror("function illegal in structure or union"); - type = INCREF(type); - } - p->n_type = type; -} - -/* - * give undefined version of class - */ -int -uclass(int class) -{ - if (class == SNULL) - return(EXTERN); - else if (class == STATIC) - return(USTATIC); - else if (class == FORTRAN) - return(UFORTRAN); - else - return(class); -} - -int -fixclass(int class, TWORD type) -{ - /* first, fix null class */ - if (class == SNULL) { - if (instruct&INSTRUCT) - class = MOS; - else if (instruct&INUNION) - class = MOU; - else if (blevel == 0) - class = EXTDEF; - else - class = AUTO; - } - - /* now, do general checking */ - - if( ISFTN( type ) ){ - switch( class ) { - default: - uerror( "function has illegal storage class" ); - case AUTO: - class = EXTERN; - case EXTERN: - case EXTDEF: - case FORTRAN: - case TYPEDEF: - case STATIC: - case UFORTRAN: - case USTATIC: - ; - } - } - - if( class&FIELD ){ - if( !(instruct&INSTRUCT) ) uerror( "illegal use of field" ); - return( class ); - } - - switch( class ){ - - case MOU: - if( !(instruct&INUNION) ) uerror( "illegal MOU class" ); - return( class ); - - case MOS: - if( !(instruct&INSTRUCT) ) uerror( "illegal MOS class" ); - return( class ); - - case MOE: - if( instruct & (INSTRUCT|INUNION) ) uerror( "illegal MOE class" ); - return( class ); - - case REGISTER: - if (blevel == 0) - uerror( "illegal register declaration" ); - if (blevel == 1) - return(PARAM); - else - return(AUTO); - - case AUTO: - if( blevel < 2 ) uerror( "illegal ULABEL class" ); - return( class ); - - case UFORTRAN: - case FORTRAN: -# ifdef NOFORTRAN - NOFORTRAN; /* a condition which can regulate the FORTRAN usage */ -# endif - if( !ISFTN(type) ) uerror( "fortran declaration must apply to function" ); - else { - type = DECREF(type); - if( ISFTN(type) || ISARY(type) || ISPTR(type) ) { - uerror( "fortran function has wrong type" ); - } - } - case STNAME: - case UNAME: - case ENAME: - case EXTERN: - case STATIC: - case EXTDEF: - case TYPEDEF: - case USTATIC: - return( class ); - - default: - cerror( "illegal class: %d", class ); - /* NOTREACHED */ - - } - return 0; /* XXX */ -} - -/* - * Generates a goto statement; sets up label number etc. - */ -void -gotolabel(char *name) -{ - struct symtab *s = lookup(name, SLBLNAME); - - if (s->soffset == 0) - s->soffset = -getlab(); - branch(s->soffset < 0 ? -s->soffset : s->soffset); -} - -/* - * Sets a label for gotos. - */ -void -deflabel(char *name) -{ - struct symtab *s = lookup(name, SLBLNAME); - - if (s->soffset > 0) - uerror("label '%s' redefined", name); - if (s->soffset == 0) - s->soffset = getlab(); - if (s->soffset < 0) - s->soffset = -s->soffset; - plabel( s->soffset); -} - -struct symtab * -getsymtab(char *name, int flags) -{ - struct symtab *s; - - if (flags & STEMP) { - s = tmpalloc(sizeof(struct symtab)); - } else { - s = permalloc(sizeof(struct symtab)); - symtabcnt++; - } - s->sname = name; - s->snext = NULL; - s->stype = UNDEF; - s->squal = 0; - s->sclass = SNULL; - s->sflags = flags & SMASK; - s->soffset = 0; - s->slevel = blevel; - s->sdf = NULL; - s->ssue = NULL; - s->suse = 0; - return s; -} - -#ifdef PCC_DEBUG -static char * -ccnames[] = { /* names of storage classes */ - "SNULL", - "AUTO", - "EXTERN", - "STATIC", - "REGISTER", - "EXTDEF", - "LABEL", - "ULABEL", - "MOS", - "PARAM", - "STNAME", - "MOU", - "UNAME", - "TYPEDEF", - "FORTRAN", - "ENAME", - "MOE", - "UFORTRAN", - "USTATIC", - }; - -char * -scnames(int c) -{ - /* return the name for storage class c */ - static char buf[12]; - if( c&FIELD ){ - snprintf( buf, sizeof(buf), "FIELD[%d]", c&FLDSIZ ); - return( buf ); - } - return( ccnames[c] ); - } -#endif diff --git a/usr.bin/pcc/cc/ccom/scan.l b/usr.bin/pcc/cc/ccom/scan.l deleted file mode 100644 index 45693712a74..00000000000 --- a/usr.bin/pcc/cc/ccom/scan.l +++ /dev/null @@ -1,467 +0,0 @@ -%{ -/* $OpenBSD: scan.l,v 1.4 2007/09/20 13:39:39 otto Exp $ */ - -/* - * Copyright (c) 2002 Anders Magnusson. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -%} - - -D [0-9] -L [a-zA-Z_] -H [a-fA-F0-9] -E [Ee][+-]?{D}+ -P [Pp][+-]?{D}+ -FS (f|F|l|L) -IS (u|U|l|L)* - -%{ -#include <errno.h> -#include <string.h> -#include <stdarg.h> - -#include "pass1.h" -#include "cgram.h" - -static NODE *cvtdig(int radix); -static NODE *charcon(void); -static void control(int); -static NODE *floatcon(void); -static NODE *fhexcon(void); -int notype, parbal; - -#define CPP_PRAGMA 1 -#define CPP_IDENT 2 -#define CPP_LINE 3 -#define CPP_HASH 4 - -#ifdef STABS -#define STABS_LINE(x) if (gflag && blevel) stabs_line(x) -#else -#define STABS_LINE(x) -#endif -#if defined(FLEX_SCANNER) && YY_FLEX_SUBMINOR_VERSION >= 31 -/* Hack to avoid unneccessary warnings */ -FILE *yyget_in (void); -FILE *yyget_out (void); -int yyget_leng (void); -char *yyget_text (void); -void yyset_in (FILE * in_str ); -void yyset_out (FILE * out_str ); -int yyget_debug (void); -void yyset_debug (int bdebug ); -int yylex_destroy (void); -extern int yyget_lineno (void); -extern void yyset_lineno (int); -#endif - -%} - -%% - -"__func__" { - if (cftnsp == NULL) - uerror("__func__ outside function"); - yylval.strp = cftnsp->sname; /* XXX - not C99 */ - return(C_STRING); - } -"asm" { return(C_ASM); } -"auto" { yylval.intval = AUTO; return(C_CLASS); } -"_Bool" { yylval.nodep = mkty((TWORD)BOOL, 0, MKSUE(BOOL)); - return(C_TYPE); } -"break" { return(C_BREAK); } -"case" { return(C_CASE); } -"char" { yylval.nodep = mkty((TWORD)CHAR, 0, MKSUE(CHAR)); - notype=1; return(C_TYPE); } -"const" { yylval.nodep = - block(QUALIFIER, NIL, NIL, CON, 0, 0); - return(C_QUALIFIER); } -"continue" { return(C_CONTINUE); } -"default" { return(C_DEFAULT); } -"do" { return(C_DO); } -"double" { yylval.nodep = mkty((TWORD)DOUBLE, 0, MKSUE(DOUBLE)); - notype=1; return(C_TYPE); } -"else" { return(C_ELSE); } -"enum" { notype=1; return(C_ENUM); } -"extern" { yylval.intval = EXTERN; return(C_CLASS); } -"float" { yylval.nodep = mkty((TWORD)FLOAT, 0, MKSUE(FLOAT)); - notype=1; return(C_TYPE); } -"for" { return(C_FOR); } -"goto" { return(C_GOTO); } -"if" { return(C_IF); } -"inline" { return(C_FUNSPEC); } -"int" { yylval.nodep = mkty((TWORD)INT, 0, MKSUE(INT)); - notype=1; return(C_TYPE); } -"long" { yylval.nodep = mkty((TWORD)LONG, 0, MKSUE(LONG)); - notype=1; return(C_TYPE); } -"register" { yylval.intval = REGISTER; return(C_CLASS); } -"restrict" { ; /* just ignore */ } -"return" { return(C_RETURN); } -"short" { yylval.nodep = mkty((TWORD)SHORT, 0, MKSUE(SHORT)); - notype=1; return(C_TYPE); } -"signed" { yylval.nodep = mkty((TWORD)SIGNED, 0, MKSUE(SIGNED)); - 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); } -"switch" { return(C_SWITCH); } -"typedef" { yylval.intval = TYPEDEF; return(C_CLASS); } -"union" { yylval.intval = INUNION; 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)); - notype=1; return(C_TYPE); } -"volatile" { yylval.nodep = - block(QUALIFIER, NIL, NIL, VOL, 0, 0); - return(C_QUALIFIER); } -"while" { return(C_WHILE); } - -{L}({L}|{D})* { struct symtab *s; - int i; - - yylval.strp = addname(yytext); - if ((i = gcc_keyword(yylval.strp, - &yylval.nodep)) != 0) - return i; -// printf("str: %s notype %d parbal %d\n", yytext, notype, parbal); - if (!notype) { - s = lookup(yylval.strp, SNOCREAT); - if (s && s->sclass == TYPEDEF) - return notype=1, C_TYPENAME; - } - return(C_NAME); - } - -0[xX]{H}+{IS}? { yylval.nodep = cvtdig(16); return(C_ICON); } -0{D}+{IS}? { yylval.nodep = cvtdig(8); return(C_ICON); } -{D}+{IS}? { yylval.nodep = cvtdig(10); return(C_ICON); } -L?'(\\.|[^\\'])+' { yylval.nodep = charcon(); return(C_ICON); } - -{D}+{E}{FS}? { yylval.nodep = floatcon(); return(C_FCON); } -{D}*"."{D}+({E})?{FS}? { yylval.nodep = floatcon(); return(C_FCON); } -{D}+"."{D}*({E})?{FS}? { yylval.nodep = floatcon(); return(C_FCON); } -0[xX]{H}*"."{H}+{P}{FS}? { yylval.nodep = fhexcon(); return(C_FCON); } -0[xX]{H}+"."{P}{FS}? { yylval.nodep = fhexcon(); return(C_FCON); } -0[xX]{H}+{P}{FS}? { yylval.nodep = fhexcon(); return(C_FCON); } - -L?\"(\\.|[^\\"])*\" { - char *c = yytext; - int i = yyleng-2, rv; - - if (*c++ == 'L') { - c++, i--; - rv = C_WSTRING; - } else - rv = C_STRING; - c[i] = 0; /* last " */ - yylval.strp = c; - return rv; - } -"..." { return(C_ELLIPSIS); } -">>=" { yylval.intval = RSEQ; return(C_ASOP); } -"<<=" { yylval.intval = LSEQ; return(C_ASOP); } -"+=" { yylval.intval = PLUSEQ; return(C_ASOP); } -"-=" { yylval.intval = MINUSEQ; return(C_ASOP); } -"*=" { yylval.intval = MULEQ; return(C_ASOP); } -"/=" { yylval.intval = DIVEQ; return(C_ASOP); } -"%=" { yylval.intval = MODEQ; return(C_ASOP); } -"&=" { yylval.intval = ANDEQ; return(C_ASOP); } -"^=" { yylval.intval = EREQ; return(C_ASOP); } -"|=" { yylval.intval = OREQ; return(C_ASOP); } -">>" { yylval.intval = RS; return(C_SHIFTOP); } -"<<" { yylval.intval = LS; return(C_SHIFTOP); } -"++" { yylval.intval = INCR; return(C_INCOP); } -"--" { yylval.intval = DECR; return(C_INCOP); } -"->" { yylval.intval = STREF; return(C_STROP); } -"&&" { yylval.intval = ANDAND; return(C_ANDAND); } -"||" { yylval.intval = OROR; return(C_OROR); } -"<=" { yylval.intval = LE; return(C_RELOP); } -">=" { yylval.intval = GE; return(C_RELOP); } -"==" { yylval.intval = EQ; return(C_EQUOP); } -"!=" { yylval.intval = NE; return(C_EQUOP); } -";" { notype = 0; return(';'); } -("{"|"<%") { notype = 0; return('{'); } -("}"|"%>") { return('}'); } -"," { if (parbal) notype = 0; return(','); } -":" { return(':'); } -"=" { return('='); } -"(" { parbal++; notype = 0; return('('); } -")" { parbal--; if (parbal==0) { notype = 0; } return(')'); } -("["|"<:") { return('['); } -("]"|":>") { return(']'); } -"." { yylval.intval = DOT; return(C_STROP); } -"&" { return('&'); } -"!" { yylval.intval = NOT; return(C_UNOP); } -"~" { yylval.intval = COMPL; return(C_UNOP); } -"-" { return('-'); } -"+" { return('+'); } -"*" { if (parbal && notype == 0) notype = 1; return('*'); } -"/" { yylval.intval = DIV; return(C_DIVOP); } -"%" { yylval.intval = MOD; return(C_DIVOP); } -"<" { yylval.intval = LT; return(C_RELOP); } -">" { yylval.intval = GT; return(C_RELOP); } -"^" { return('^'); } -"|" { return('|'); } -"?" { return('?'); } -^#pragma[ \t].* { control(CPP_PRAGMA); } -^#ident[ \t].* { control(CPP_IDENT); } -^#line[ \t].* { control(CPP_LINE); } -^#.* { control(CPP_HASH); } - -[ \t\v\f] { } -"\n" { ++lineno; STABS_LINE(lineno); } -. { /* ignore bad characters */ } - -%% - -int lineno; -char *ftitle = "<stdin>"; - -int -yywrap(void) -{ - if (0) unput(0); /* quiet gcc */ - return(1); -} - -/* - * XXX floatcon() and fhexcon() should be in support libraries for - * the target floating point. - */ -static NODE * -f2(char *str) -{ - TWORD tw; - NODE *p; - double dc; - char *eptr; - - dc = strtod(str, &eptr); /* XXX - avoid strtod() */ - tw = (*eptr == 'f' || *eptr == 'F' ? FLOAT : DOUBLE); - p = block(FCON, NIL, NIL, tw, 0, MKSUE(tw)); - p->n_dcon = dc; - return p; -} - -NODE * -floatcon(void) -{ - return f2(yytext); -} - -static int -h2n(int ch) -{ - if (ch >= '0' && ch <= '9') - return ch - '0'; - if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - return ch - 'A' + 10; - -} - -NODE * -fhexcon(void) -{ - char buf[500]; - char *c = yytext; - unsigned long long num1, num2; - - /* XXX - convert it to a decimal float number and use strtod */ - c+= 2; /* skip 0x */ - for (num1 = 0; *c != '.' && *c != 'p' && *c != 'P'; c++) - num1 = (num1 << 4) | h2n(*c); - if (*c != '.' && *c != 'p' && *c != 'P') - cerror("fhexcon"); - num2 = 0; - if (*c == '.') { - c++; - for (; *c != 'p' && *c != 'P'; c++) - num2 = (num2 << 4) | h2n(*c); - } - if (*c != 'P' && *c != 'p') - cerror("fhexcon2"); - c++; - snprintf(buf, sizeof(buf), "%llu.%lluE%s", num1, num2, c); - return f2(buf); -} - -unsigned int -esccon(char **sptr) -{ - char *wr = *sptr; - unsigned int val; - - switch (*wr++) { - case 'a': val = '\a'; break; - case 'b': val = '\b'; break; - case 'f': val = '\f'; break; - case 'n': val = '\n'; break; - case 'r': val = '\r'; break; - case 't': val = '\t'; break; - case 'v': val = '\v'; break; - case '\"': val = '\"'; break; - case 'x': val = strtoul(wr, &wr, 16); break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - wr--; - val = strtoul(wr, &wr, 8); - break; - default: val = wr[-1]; - } - *sptr = wr; - return val; -} - -NODE * -cvtdig(int radix) -{ - NODE *p; - TWORD ntype; - unsigned long long v; - char *ch = yytext; - int n, numl, numu; - - if (radix == 16) - ch += 2; /* Skip 0x */ - - v = 0; - while ((*ch >= '0' && *ch <= '9') || (*ch >= 'a' && *ch <= 'f') || - (*ch >= 'A' && *ch <= 'F')) { - v *= radix; - n = *ch; - n = (n <= '9' ? n - '0' : (n > 'F' ? n - 'a' : n - 'A') + 10); - ch++; - v += n; - } - /* Parse trailing chars */ - ntype = INT; - numl = numu = 0; - for (n = 0; n < 3; n++) { - if (*ch == 0) - break; - if ((*ch == 'l' || *ch == 'L') && numl < 2) - ntype+=2, numl++; - else if ((*ch == 'u' || *ch == 'U') && numu < 1) - ntype = ENUNSIGN(ntype), numu++; - else - break; - ch++; - } - if (*ch) - uerror("constant has too many '%c'", *ch); - - if (ntype == INT) { - /* v contains a number. Get type correct */ - if (v > MAX_LONGLONG && radix != 10) - ntype = ULONGLONG; - else if (v > MAX_ULONG) - ntype = LONGLONG; - else if (v > MAX_LONG && radix != 10) - ntype = ULONG; - else if (v > MAX_UNSIGNED) - ntype = LONG; - else if (v > MAX_INT && radix != 10) - ntype = UNSIGNED; - } - ntype = ctype(ntype); - p = block(ICON, NIL, NIL, ntype, 0, MKSUE(ntype)); - p->n_lval = v; - ASGLVAL(p->n_slval, v); - - return p; -} - -/* - * Convert a character constant to an integer. - */ -NODE * -charcon(void) -{ - int lastcon = 0; - int val, i = 0; - char *pp = yytext; - - if (*pp == 'L') - pp++; - pp++; - while (*pp != '\'') { - if (*pp++ == '\\') { - val = esccon(&pp); - } else - val = pp[-1]; - makecc(val, i); - i++; - } - - if (i == 0) - uerror("empty character constant"); - if (i > (SZINT/SZCHAR) || (i>1)) - werror("too many characters in character constant"); - return bcon(lastcon); -} - -void -control(int t) -{ - char *wr = yytext; - char *eptr; - int val; - - wr++; /* Skip initial '#' */ - switch (t) { - case CPP_PRAGMA: - case CPP_IDENT: - return; /* Just skip these for now. */ - - case CPP_LINE: - wr += 4; - /* FALLTHROUGH */ - case CPP_HASH: - val = strtol(wr, &eptr, 10); - if (wr == eptr) /* Illegal string */ - goto bad; - wr = eptr; - lineno = val - 1; - while (*wr && *wr != '\"') - wr++; - if (*wr++ != '\"') - goto bad; - eptr = wr; - while (*wr && *wr != '\"') - wr++; - if (*wr != '\"') - goto bad; - *wr = 0; - ftitle = addstring(eptr); -#ifdef STABS - if (gflag) - stabs_file(ftitle); -#endif - } - return; -bad: - werror("%s: illegal control", yytext); -} diff --git a/usr.bin/pcc/cc/ccom/stabs.c b/usr.bin/pcc/cc/ccom/stabs.c deleted file mode 100644 index 19190bca8ba..00000000000 --- a/usr.bin/pcc/cc/ccom/stabs.c +++ /dev/null @@ -1,374 +0,0 @@ -/* $OpenBSD: stabs.c,v 1.2 2007/09/15 22:04:39 ray Exp $ */ - -/* - * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Simple implementation of the "stabs" debugging format. - * Not complete but at least makes it possible to set breakpoints, - * examine simple variables and do stack traces. - * Based on the stabs documentation that follows gdb. - */ - -#include "pass1.h" - -#ifdef STABS - -#include <sys/types.h> -#include <stab.h> -#include <stdarg.h> -#include <string.h> - -#define STABHASH 256 -#define INTNUM 1 /* internal number of type "int" */ -#define BIT2BYTE(x) ((x)/SZCHAR) - -#ifndef STABLBL -#error macdefs.h must define STABLBL -#endif - -/* - * Local type mapping - * Types are defined as a typeword, a dimension pointer (in the case - * of arrays) and struct/union/enum declarations. - * Function prototypes are ignored. - */ -static struct stabtype { - struct stabtype *next; /* linked list */ - TWORD type; /* pcc type number */ - union dimfun *df; /* dimension of arrays */ - struct suedef *sue; /* struct/union/enum declarations */ - int num; /* local type number */ -} *stabhash[STABHASH]; -static int ntypes; -static char *curfun; -static int stablbl = 10; - -void ptype(char *name, int num, int inhnum, long long min, long long max); -struct stabtype *addtype(TWORD, union dimfun *, struct suedef *); -struct stabtype *findtype(TWORD t, union dimfun *df, struct suedef *sue); -void printtype(struct symtab *s, char *str, int len); -void cprint(int p2, char *fmt, ...); - -#define MAXPSTR 100 - -extern int isinlining; -#define savestabs isinlining - -/* - * Output type definitions for the stab debugging format. - * Note that "int" is always internal number 1. - */ -void -stabs_init() -{ - struct stabtype *st; - -#define ADDTYPE(y) addtype(y, NULL, MKSUE(y)) - - ptype("int", ADDTYPE(INT)->num, INTNUM, MIN_INT, MAX_INT); - - st = ADDTYPE(CHAR); - ptype("char", st->num, st->num, 0, MAX_CHAR); - ptype("short", ADDTYPE(SHORT)->num, INTNUM, MIN_SHORT, MAX_SHORT); - ptype("long", ADDTYPE(LONG)->num, INTNUM, MIN_LONG, MAX_LONG); - ptype("long long", ADDTYPE(LONGLONG)->num, INTNUM, - MIN_LONGLONG, MAX_LONGLONG); - ptype("unsigned char", ADDTYPE(UCHAR)->num, INTNUM, 0, MAX_UCHAR); - ptype("unsigned short", ADDTYPE(USHORT)->num, INTNUM, 0, MAX_USHORT); - ptype("unsigned int", ADDTYPE(UNSIGNED)->num, INTNUM, 0, MAX_UNSIGNED); - ptype("unsigned long", ADDTYPE(ULONG)->num, INTNUM, 0, MAX_ULONG); - ptype("unsigned long long", ADDTYPE(ULONGLONG)->num, INTNUM, - 0, MAX_ULONGLONG); - - ptype("float", ADDTYPE(FLOAT)->num, INTNUM, 4, 0); - 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", - st->num, st->num, N_LSYM); - -} - -/* - * Print a type in stabs format - */ -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", - name, num, inhnum, min, max, N_LSYM); -} - -/* - * Add a new local type to the hash table. - * The search key is the (type, df, sue) triple. - */ -struct stabtype * -addtype(TWORD t, union dimfun *df, struct suedef *sue) -{ - struct stabtype *st; - - st = permalloc(sizeof(struct stabtype)); - st->type = t; - st->df = df; - st->sue = sue; - st->num = ++ntypes; - st->next = stabhash[t & (STABHASH-1)]; - stabhash[t & (STABHASH-1)] = st; - return st; -} - -/* - * Search for a given type and return a type pointer (or NULL). - */ -struct stabtype * -findtype(TWORD t, union dimfun *df, struct suedef *sue) -{ - struct stabtype *st; - union dimfun *dw, *dx; - TWORD tw; - - st = stabhash[t & (STABHASH-1)]; - for (; st; st = st->next) { - if (t != st->type || sue != st->sue) - continue; - /* Ok, type and sue matches, check dimensions */ - if (st->df == NULL) - return st; /* no arrays, got match */ - dw = st->df; - dx = df; - tw = t; - for (; tw > BTMASK; tw = DECREF(tw)) { - if (ISARY(tw)) { - if (dw->ddim == dx->ddim) - dw++, dx++; - else - break; - } - } - if (tw <= BTMASK) - return st; - } - return NULL; -} - -/* - * Print current line number. - */ -void -stabs_line(int line) -{ - cprint(savestabs, ".stabn %d,0,%d," STABLBL "-%s", N_SLINE, line, stablbl, curfun); - cprint(1, STABLBL ":", stablbl++); -} - -/* - * Start of block. - */ -void -stabs_lbrac(int blklvl) -{ - cprint(savestabs, ".stabn %d,0,%d," STABLBL "-%s", - N_LBRAC, blklvl, stablbl, curfun); - cprint(1, STABLBL ":", stablbl++); -} - -/* - * End of block. - */ -void -stabs_rbrac(int blklvl) -{ - cprint(savestabs, ".stabn %d,0,%d," STABLBL "-%s\n", - N_RBRAC, blklvl, stablbl, curfun); - cprint(1, STABLBL ":", stablbl++); -} - -/* - * Print current file and set mark. - */ -void -stabs_file(char *fname) -{ - static char *mainfile; - - if (mainfile == NULL) - mainfile = fname; /* first call */ - cprint(savestabs, ".stabs \"%s\",%d,0,0," STABLBL, - fname, fname == mainfile ? N_SO : N_SOL, stablbl); - cprint(savestabs, STABLBL ":", stablbl++); -} - -/* - * Print beginning of function. - */ -void -stabs_func(struct symtab *s) -{ - char str[MAXPSTR]; - - curfun = s->sname; -#ifdef GCC_COMPAT - curfun = gcc_findname(cftnsp); -#endif - printtype(s, str, sizeof(str)); - cprint(savestabs, ".stabs \"%s:%c%s\",%d,0,%d,%s", - curfun, s->sclass == STATIC ? 'f' : 'F', str, - N_FUN, BIT2BYTE(s->ssue->suesize), exname(curfun)); -} - -/* - * Print a (complex) type. - * Will also create subtypes. - * Printed string is like "20=*21=*1". - */ -void -printtype(struct symtab *s, char *ostr, int len) -{ - struct stabtype *st; - union dimfun *df = s->sdf; - struct suedef *sue = s->ssue; - TWORD t = s->stype; - int op = 0; - - /* Print out not-yet-found types */ - if (ISFTN(t)) - t = DECREF(t); - st = findtype(t, df, sue); - while (st == NULL && t > BTMASK) { - st = addtype(t, df, sue); - op+=snprintf(ostr+op, len - op, "%d=", st->num); - if (ISFTN(t)) - ostr[op++] = 'f'; - else if (ISPTR(t)) - ostr[op++] = '*'; - else if (ISARY(t)) { - op+=snprintf(ostr+op, len - op, "ar%d;0;%d;", INTNUM, df->ddim-1); - } else - cerror("printtype: notype"); - if (ISARY(t)) - df++; - t = DECREF(t); - st = findtype(t, df, sue); - if (op > MAXPSTR-10) - cerror("printtype: too difficult expression"); - } - /* print out basic type. may have to be entered in case of sue */ - snprintf(ostr+op, len - op, "%d", st == NULL ? 1 : st->num); - /* snprintf here null-terminated the string */ -} - -void -stabs_newsym(struct symtab *s) -{ - char *sname; - char ostr[MAXPSTR]; - - if (ISFTN(s->stype)) - return; /* functions are handled separate */ - - if (s->sclass == STNAME || s->sclass == UNAME || s->sclass == MOS || - s->sclass == ENAME || s->sclass == MOU || s->sclass == MOE || - s->sclass == TYPEDEF || (s->sclass & FIELD)) - return; /* XXX - fix structs */ - - sname = s->sname; -#ifdef GCC_COMPAT - sname = gcc_findname(s); -#endif - - printtype(s, ostr, sizeof(ostr)); - switch (s->sclass) { - case PARAM: - cprint(savestabs, ".stabs \"%s:p%s\",%d,0,%d,%d", sname, ostr, - N_PSYM, BIT2BYTE(s->ssue->suesize), BIT2BYTE(s->soffset)); - break; - - case AUTO: - cprint(savestabs, ".stabs \"%s:%s\",%d,0,%d,%d", sname, ostr, - N_LSYM, BIT2BYTE(s->ssue->suesize), BIT2BYTE(s->soffset)); - break; - - case STATIC: - if (blevel) - cprint(savestabs, ".stabs \"%s:V%s\",%d,0,%d," LABFMT, sname, ostr, - N_LCSYM, BIT2BYTE(s->ssue->suesize), s->soffset); - else - cprint(savestabs, ".stabs \"%s:S%s\",%d,0,%d,%s", sname, ostr, - N_LCSYM, BIT2BYTE(s->ssue->suesize), exname(sname)); - break; - - case EXTERN: - case EXTDEF: - cprint(savestabs, ".stabs \"%s:G%s\",%d,0,%d,0", sname, ostr, - N_GSYM, BIT2BYTE(s->ssue->suesize)); - break; - - case REGISTER: - cprint(savestabs, ".stabs \"%s:r%s\",%d,0,%d,%d", sname, ostr, - N_RSYM, 1, s->soffset); - break; - - default: - cerror("fix stab_newsym; class %d", s->sclass); - } -} - -void -stabs_chgsym(struct symtab *s) -{ -} - -/* - * define a struct. - */ -void -stabs_struct(struct symtab *p, struct suedef *sue) -{ -} - -void -cprint(int p2, char *fmt, ...) -{ - va_list ap; - char *str; - - va_start(ap, fmt); - if (p2) { - str = tmpvsprintf(fmt, ap); - str = newstring(str, strlen(str)); /* XXX - for inlines */ - send_passt(IP_ASM, str); - } else { - putchar('\t'); - vprintf(fmt, ap); - putchar('\n'); - } - va_end(ap); -} - -#endif diff --git a/usr.bin/pcc/cc/ccom/symtabs.c b/usr.bin/pcc/cc/ccom/symtabs.c deleted file mode 100644 index 6ef6bab9999..00000000000 --- a/usr.bin/pcc/cc/ccom/symtabs.c +++ /dev/null @@ -1,356 +0,0 @@ -/* $OpenBSD: symtabs.c,v 1.2 2007/09/15 22:04:39 ray Exp $ */ -/* - * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "pass1.h" - -/* - * These definitions are used in the patricia tree that stores - * the strings. - */ -#define LEFT_IS_LEAF 0x80000000 -#define RIGHT_IS_LEAF 0x40000000 -#define IS_LEFT_LEAF(x) (((x) & LEFT_IS_LEAF) != 0) -#define IS_RIGHT_LEAF(x) (((x) & RIGHT_IS_LEAF) != 0) -#define BITNO(x) ((x) & ~(LEFT_IS_LEAF|RIGHT_IS_LEAF)) -#define CHECKBITS 8 - -struct tree { - int bitno; - struct tree *lr[2]; -}; - -static struct tree *firstname; -int nametabs, namestrlen; -static struct tree *firststr; -int strtabs, strstrlen; -static char *symtab_add(char *key, struct tree **, int *, int *); - -#define P_BIT(key, bit) (key[bit >> 3] >> (bit & 7)) & 1 -#define getree() permalloc(sizeof(struct tree)) - -char * -addname(char *key) -{ - return symtab_add(key, &firstname, &nametabs, &namestrlen); -} - -char * -addstring(char *key) -{ - return symtab_add(key, &firststr, &strtabs, &strstrlen); -} - -/* - * Add a name to the name stack (if its non-existing), - * return its address. - * This is a simple patricia implementation. - */ -char * -symtab_add(char *key, struct tree **first, int *tabs, int *stlen) -{ - struct tree *w, *new, *last; - int cix, bit, fbit, svbit, ix, bitno, len; - char *m, *k, *sm; - - /* Count full string length */ - for (k = key, len = 0; *k; k++, len++) - ; - - switch (*tabs) { - case 0: - *first = (struct tree *)newstring(key, len); - *stlen += (len + 1); - (*tabs)++; - return (char *)*first; - - case 1: - m = (char *)*first; - svbit = 0; /* XXX why? */ - break; - - default: - w = *first; - bitno = len * CHECKBITS; - for (;;) { - bit = BITNO(w->bitno); - fbit = bit > bitno ? 0 : P_BIT(key, bit); - svbit = fbit ? IS_RIGHT_LEAF(w->bitno) : - IS_LEFT_LEAF(w->bitno); - w = w->lr[fbit]; - if (svbit) { - m = (char *)w; - break; - } - } - } - - sm = m; - k = key; - - /* Check for correct string and return */ - for (cix = 0; *m && *k && *m == *k; m++, k++, cix += CHECKBITS) - ; - if (*m == 0 && *k == 0) - return sm; - - ix = *m ^ *k; - while ((ix & 1) == 0) - ix >>= 1, cix++; - - /* Create new node */ - new = getree(); - bit = P_BIT(key, cix); - new->bitno = cix | (bit ? RIGHT_IS_LEAF : LEFT_IS_LEAF); - new->lr[bit] = (struct tree *)newstring(key, len); - *stlen += (len + 1); - - if ((*tabs)++ == 1) { - new->lr[!bit] = *first; - new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF); - *first = new; - return (char *)new->lr[bit]; - } - - - w = *first; - last = NULL; - for (;;) { - fbit = w->bitno; - bitno = BITNO(w->bitno); - if (bitno == cix) - cerror("bitno == cix"); - if (bitno > cix) - break; - svbit = P_BIT(key, bitno); - last = w; - w = w->lr[svbit]; - if (fbit & (svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF)) - break; - } - - new->lr[!bit] = w; - if (last == NULL) { - *first = new; - } else { - last->lr[svbit] = new; - last->bitno &= ~(svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF); - } - if (bitno < cix) - new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF); - return (char *)new->lr[bit]; -} - -static struct tree *sympole[NSTYPES]; -static struct symtab *tmpsyms[NSTYPES]; -int numsyms[NSTYPES]; - -/* - * Inserts a symbol into the symbol tree. - * Returns a struct symtab. - */ -struct symtab * -lookup(char *key, int ttype) -{ - struct symtab *sym; - struct tree *w, *new, *last; - int cix, bit, fbit, svbit, ix, bitno, match; - int type, uselvl; - - long code = (long)key; - type = ttype & SMASK; - uselvl = (blevel > 0 && type != SSTRING); - - /* - * The local symbols are kept in a simple linked list. - * Check this list first. - */ - if (blevel > 0) - for (sym = tmpsyms[type]; sym; sym = sym->snext) - if (sym->sname == key) - return sym; - - switch (numsyms[type]) { - case 0: - if (ttype & SNOCREAT) - return NULL; - if (uselvl) { - sym = getsymtab(key, ttype|STEMP); - sym->snext = tmpsyms[type]; - tmpsyms[type] = sym; - return sym; - } - sympole[type] = (struct tree *)getsymtab(key, ttype); - numsyms[type]++; - return (struct symtab *)sympole[type]; - - case 1: - w = (struct tree *)sympole[type]; - svbit = 0; /* XXX why? */ - break; - - default: - w = sympole[type]; - for (;;) { - bit = BITNO(w->bitno); - fbit = (code >> bit) & 1; - svbit = fbit ? IS_RIGHT_LEAF(w->bitno) : - IS_LEFT_LEAF(w->bitno); - w = w->lr[fbit]; - if (svbit) - break; - } - } - - sym = (struct symtab *)w; - match = (long)sym->sname; - - ix = code ^ match; - if (ix == 0) - return sym; - else if (ttype & SNOCREAT) - return NULL; - -#ifdef PCC_DEBUG - if (ddebug) - printf(" adding %s as %s at level %d\n", - key, uselvl ? "temp" : "perm", blevel); -#endif - - /* - * Insert into the linked list, if feasible. - */ - if (uselvl) { - sym = getsymtab(key, ttype|STEMP); - sym->snext = tmpsyms[type]; - tmpsyms[type] = sym; - return sym; - } - - /* - * Need a new node. If type is SNORMAL and inside a function - * the node must be allocated as permanent anyway. - * This could be optimized by adding a remove routine, but it - * may be more trouble than it is worth. - */ - if (ttype == (STEMP|SNORMAL)) - ttype = SNORMAL; - - for (cix = 0; (ix & 1) == 0; ix >>= 1, cix++) - ; - - new = ttype & STEMP ? tmpalloc(sizeof(struct tree)) : - permalloc(sizeof(struct tree)); - bit = (code >> cix) & 1; - new->bitno = cix | (bit ? RIGHT_IS_LEAF : LEFT_IS_LEAF); - new->lr[bit] = (struct tree *)getsymtab(key, ttype); - if (numsyms[type]++ == 1) { - new->lr[!bit] = sympole[type]; - new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF); - sympole[type] = new; - return (struct symtab *)new->lr[bit]; - } - - - w = sympole[type]; - last = NULL; - for (;;) { - fbit = w->bitno; - bitno = BITNO(w->bitno); - if (bitno == cix) - cerror("bitno == cix"); - if (bitno > cix) - break; - svbit = (code >> bitno) & 1; - last = w; - w = w->lr[svbit]; - if (fbit & (svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF)) - break; - } - - new->lr[!bit] = w; - if (last == NULL) { - sympole[type] = new; - } else { - last->lr[svbit] = new; - last->bitno &= ~(svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF); - } - if (bitno < cix) - new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF); - return (struct symtab *)new->lr[bit]; -} - -void -symclear(int level) -{ - struct symtab *s; - int i; - -#ifdef PCC_DEBUG - if (ddebug) - printf("symclear(%d)\n", level); -#endif - if (level < 1) { - for (i = 0; i < NSTYPES; i++) { - s = tmpsyms[i]; - tmpsyms[i] = 0; - if (i != SLBLNAME) - continue; - while (s != NULL) { - if (s->soffset < 0) - uerror("label '%s' undefined",s->sname); - s = s->snext; - } - } - } else { - for (i = 0; i < NSTYPES; i++) { - if (i == SLBLNAME) - continue; /* function scope */ - while (tmpsyms[i] != NULL && - tmpsyms[i]->slevel > level) { - tmpsyms[i] = tmpsyms[i]->snext; - } - } - } -} - -struct symtab * -hide(struct symtab *sym) -{ - struct symtab *new; - - new = getsymtab(sym->sname, SNORMAL|STEMP); - new->snext = tmpsyms[SNORMAL]; - tmpsyms[SNORMAL] = new; -#ifdef PCC_DEBUG - if (ddebug) - printf("\t%s hidden at level %d (%p -> %p)\n", - sym->sname, blevel, sym, new); -#endif - return new; -} diff --git a/usr.bin/pcc/cc/ccom/trees.c b/usr.bin/pcc/cc/ccom/trees.c deleted file mode 100644 index 88fd39b4a21..00000000000 --- a/usr.bin/pcc/cc/ccom/trees.c +++ /dev/null @@ -1,2466 +0,0 @@ -/* $Id: trees.c,v 1.6 2007/10/06 14:34:45 ragge Exp $ */ -/* - * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code and documentation must retain the above - * copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditionsand the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of other - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Some of the changes from 32V include: - * - Understand "void" as type. - * - Handle enums as ints everywhere. - * - Convert some C-specific ops into branches. - */ - -# include "pass1.h" -# include "pass2.h" - -# include <stdarg.h> - -static void chkpun(NODE *p); -static int chkenum(int, int, NODE *p); -static int opact(NODE *p); -static int moditype(TWORD); -static NODE *strargs(NODE *); -static void rmcops(NODE *p); - -int lastloc = -1; - -/* some special actions, used in finding the type of nodes */ -# define NCVT 01 -# define PUN 02 -# define TYPL 04 -# define TYPR 010 -# define TYMATCH 040 -# define LVAL 0100 -# define CVTO 0200 -# define CVTL 0400 -# define CVTR 01000 -# define PTMATCH 02000 -# define OTHER 04000 -# define NCVTR 010000 - -/* node conventions: - - NAME: rval>0 is stab index for external - rval<0 is -inlabel number - lval is offset in bits - ICON: lval has the value - rval has the STAB index, or - label number, - if a name whose address is in the constant - rval = NONAME means no name - REG: rval is reg. identification cookie - - */ - -int bdebug = 0; - -NODE * -buildtree(int o, NODE *l, NODE *r) -{ - NODE *p, *q; - int actions; - int opty; - struct symtab *sp = NULL; /* XXX gcc */ - NODE *lr, *ll; - char *name; - struct symtab **elem; - -#ifdef PCC_DEBUG - if (bdebug) { - printf("buildtree(%s, %p, %p)\n", copst(o), l, r); - if (l) fwalk(l, eprint, 0); - if (r) fwalk(r, eprint, 0); - } -#endif - opty = coptype(o); - - /* check for constants */ - - if( opty == UTYPE && l->n_op == ICON ){ - - switch( o ){ - - case NOT: - case UMINUS: - case COMPL: - if( conval( l, o, l ) ) return(l); - break; - } - } else if (o == NOT && l->n_op == FCON) { - l = clocal(block(SCONV, l, NIL, INT, 0, MKSUE(INT))); - } else if( o == UMINUS && l->n_op == FCON ){ - l->n_dcon = -l->n_dcon; - return(l); - - } else if( o==QUEST && l->n_op==ICON ) { - CONSZ c = l->n_lval; - nfree(l); - if (c) { - tfree(r->n_right); - l = r->n_left; - nfree(r); - return(l); - } else { - tfree(r->n_left); - l = r->n_right; - nfree(r); - return(l); - } - } else if( opty == BITYPE && l->n_op == ICON && r->n_op == ICON ){ - - switch( o ){ - - case PLUS: - case MINUS: - case MUL: - case DIV: - case MOD: - /* - * Do type propagation for simple types here. - * The constant value is correct anyway. - * Maybe this op shortcut should be removed? - */ - if (l->n_sp == NULL && r->n_sp == NULL && - l->n_type < BTMASK && r->n_type < BTMASK) { - if (l->n_type > r->n_type) - r->n_type = l->n_type; - else - l->n_type = r->n_type; - } - /* FALLTHROUGH */ - case ULT: - case UGT: - case ULE: - case UGE: - case LT: - case GT: - case LE: - case GE: - case EQ: - case NE: - case ANDAND: - case OROR: - case AND: - case OR: - case ER: - case LS: - case RS: - if( conval( l, o, r ) ) { - nfree(r); - return(l); - } - break; - } - } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) && - (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS || - o == MUL || o == DIV)) { - switch(o){ - case PLUS: - case MINUS: - case MUL: - case DIV: - if (l->n_op == ICON) - l->n_dcon = l->n_lval; - if (r->n_op == ICON) - r->n_dcon = r->n_lval; - switch (o) { - case PLUS: - l->n_dcon += r->n_dcon; break; - case MINUS: - l->n_dcon -= r->n_dcon; break; - case MUL: - l->n_dcon *= r->n_dcon; break; - case DIV: - if (r->n_dcon == 0) - uerror("division by 0."); - else - l->n_dcon /= r->n_dcon; - } - l->n_op = FCON; - l->n_type = DOUBLE; - l->n_sue = MKSUE(DOUBLE); - nfree(r); - return(l); - } - } - - /* its real; we must make a new node */ - - p = block(o, l, r, INT, 0, MKSUE(INT)); - - actions = opact(p); - - if (actions & LVAL) { /* check left descendent */ - if (notlval(p->n_left)) { - uerror("lvalue required"); -#ifdef notyet - } else { - if ((l->n_type > BTMASK && ISCON(l->n_qual)) || - (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT))) - if (blevel > 0) - uerror("lvalue is declared const"); -#endif - } - } - - if( actions & NCVTR ){ - p->n_left = pconvert( p->n_left ); - } - else if( !(actions & NCVT ) ){ - switch( opty ){ - - case BITYPE: - p->n_right = pconvert( p->n_right ); - case UTYPE: - p->n_left = pconvert( p->n_left ); - - } - } - - if ((actions&PUN) && (o!=CAST)) - chkpun(p); - - if( actions & (TYPL|TYPR) ){ - - q = (actions&TYPL) ? p->n_left : p->n_right; - - p->n_type = q->n_type; - p->n_qual = q->n_qual; - p->n_df = q->n_df; - p->n_sue = q->n_sue; - } - - if( actions & CVTL ) p = convert( p, CVTL ); - if( actions & CVTR ) p = convert( p, CVTR ); - if( actions & TYMATCH ) p = tymatch(p); - if( actions & PTMATCH ) p = ptmatch(p); - - if( actions & OTHER ){ - l = p->n_left; - r = p->n_right; - - switch(o){ - - case NAME: - sp = spname; - if (sp->sflags & STNODE) { - /* Generated for optimizer */ - p->n_op = TEMP; - p->n_type = sp->stype; - p->n_sue = sp->ssue; - p->n_df = sp->sdf; - p->n_lval = sp->soffset; - break; - } - -#ifdef GCC_COMPAT - /* Get a label name */ - if (sp->sflags == SLBLNAME) { - p->n_type = VOID; - p->n_sue = MKSUE(VOID); - p->n_lval = 0; - p->n_sp = sp; - break; - } else -#endif - if (sp->stype == UNDEF) { - uerror("%s undefined", sp->sname); - /* make p look reasonable */ - p->n_type = INT; - p->n_sue = MKSUE(INT); - p->n_df = NULL; - p->n_sp = sp; - p->n_lval = 0; - defid(p, SNULL); - break; - } - p->n_type = sp->stype; - p->n_qual = sp->squal; - p->n_df = sp->sdf; - p->n_sue = sp->ssue; - p->n_lval = 0; - p->n_sp = sp; - /* special case: MOETY is really an ICON... */ - if (p->n_type == MOETY) { - p->n_sp = NULL; - p->n_lval = sp->soffset; - p->n_df = NULL; - p->n_type = ENUMTY; - p->n_op = ICON; - } - break; - - case STREF: - /* p->x turned into *(p+offset) */ - /* rhs must be a name; check correctness */ - - /* Find member symbol struct */ - if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){ - uerror("struct or union required"); - break; - } - - if ((elem = l->n_sue->suelem) == NULL) - uerror("undefined struct or union"); - - name = r->n_name; - for (; *elem != NULL; elem++) { - sp = *elem; - if (sp->sname == name) - break; - } - if (*elem == NULL) - uerror("member '%s' not declared", name); - - r->n_sp = sp; - p = stref(p); - break; - - case UMUL: - if (l->n_op == ADDROF) { - nfree(p); - p = l->n_left; - nfree(l); - } - if( !ISPTR(l->n_type))uerror("illegal indirection"); - p->n_type = DECREF(l->n_type); - p->n_qual = DECREF(l->n_qual); - p->n_df = l->n_df; - p->n_sue = l->n_sue; - break; - - case ADDROF: - switch( l->n_op ){ - - case UMUL: - nfree(p); - p = l->n_left; - nfree(l); - case TEMP: - case NAME: - p->n_type = INCREF(l->n_type); - p->n_qual = INCQAL(l->n_qual); - p->n_df = l->n_df; - p->n_sue = l->n_sue; - break; - - case COMOP: - nfree(p); - lr = buildtree(ADDROF, l->n_right, NIL); - p = buildtree( COMOP, l->n_left, lr ); - nfree(l); - break; - - case QUEST: - lr = buildtree( ADDROF, l->n_right->n_right, NIL ); - ll = buildtree( ADDROF, l->n_right->n_left, NIL ); - nfree(p); nfree(l->n_right); - p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) ); - nfree(l); - break; - - default: - uerror("unacceptable operand of &: %d", l->n_op ); - break; - } - break; - - case LS: - case RS: /* must make type size at least int... */ - if (p->n_type == CHAR || p->n_type == SHORT) { - p->n_left = makety(l, INT, 0, 0, MKSUE(INT)); - } else if (p->n_type == UCHAR || p->n_type == USHORT) { - p->n_left = makety(l, UNSIGNED, 0, 0, - MKSUE(UNSIGNED)); - } - l = p->n_left; - p->n_type = l->n_type; - p->n_qual = l->n_qual; - p->n_df = l->n_df; - p->n_sue = l->n_sue; - - /* FALLTHROUGH */ - case LSEQ: - case RSEQ: /* ...but not for assigned types */ - if(tsize(r->n_type, r->n_df, r->n_sue) > SZINT) - p->n_right = makety(r, INT, 0, 0, MKSUE(INT)); - break; - - case RETURN: - case ASSIGN: - case CAST: - /* structure assignment */ - /* take the addresses of the two sides; then make an - * operator using STASG and - * the addresses of left and right */ - - { - struct suedef *sue; - TWORD t; - union dimfun *d; - - if (l->n_sue != r->n_sue) - uerror("assignment of different structures"); - - r = buildtree(ADDROF, r, NIL); - t = r->n_type; - d = r->n_df; - sue = r->n_sue; - - l = block(STASG, l, r, t, d, sue); - - if( o == RETURN ){ - nfree(p); - p = l; - break; - } - - p->n_op = UMUL; - p->n_left = l; - p->n_right = NIL; - break; - } - case COLON: - /* structure colon */ - - if (l->n_sue != r->n_sue) - uerror( "type clash in conditional" ); - break; - - case CALL: - p->n_right = r = strargs(p->n_right); - case UCALL: - if (!ISPTR(l->n_type)) - uerror("illegal function"); - p->n_type = DECREF(l->n_type); - if (!ISFTN(p->n_type)) - uerror("illegal function"); - p->n_type = DECREF(p->n_type); - p->n_df = l->n_df; - p->n_sue = l->n_sue; - if (l->n_op == ADDROF && l->n_left->n_op == NAME && - l->n_left->n_sp != NULL && l->n_left->n_sp != NULL && - (l->n_left->n_sp->sclass == FORTRAN || - l->n_left->n_sp->sclass == UFORTRAN)) { - p->n_op += (FORTCALL-CALL); - } - if (p->n_type == STRTY || p->n_type == UNIONTY) { - /* function returning structure */ - /* make function really return ptr to str., with * */ - - p->n_op += STCALL-CALL; - p->n_type = INCREF(p->n_type); - p = clocal(p); /* before recursing */ - p = buildtree(UMUL, p, NIL); - - } - break; - - default: - cerror( "other code %d", o ); - } - - } - - /* - * Allow (void)0 casts. - * XXX - anything on the right side must be possible to cast. - * XXX - remove void types further on. - */ - if (p->n_op == CAST && p->n_type == VOID && - p->n_right->n_op == ICON) - p->n_right->n_type = VOID; - - if (actions & CVTO) - p = oconvert(p); - p = clocal(p); - -#ifdef PCC_DEBUG - if (bdebug) { - printf("End of buildtree:\n"); - fwalk(p, eprint, 0); - } -#endif - - return(p); - - } - -/* - * Do a conditional branch. - */ -void -cbranch(NODE *p, NODE *q) -{ - p = buildtree(CBRANCH, p, q); - if (p->n_left->n_op == ICON) { - if (p->n_left->n_lval != 0) - branch(q->n_lval); /* branch always */ - tfree(p); - tfree(q); - return; - } - ecomp(p); -} - -NODE * -strargs( p ) register NODE *p; { /* rewrite structure flavored arguments */ - - if( p->n_op == CM ){ - p->n_left = strargs( p->n_left ); - p->n_right = strargs( p->n_right ); - return( p ); - } - - if( p->n_type == STRTY || p->n_type == UNIONTY ){ - p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_sue); - p->n_left = buildtree( ADDROF, p->n_left, NIL ); - p = clocal(p); - } - return( p ); -} - -/* - * apply the op o to the lval part of p; if binary, rhs is val - */ -int -conval(NODE *p, int o, NODE *q) -{ - int i, u; - CONSZ val; - U_CONSZ v1, v2; - - val = q->n_lval; - u = ISUNSIGNED(p->n_type) || ISUNSIGNED(q->n_type); - if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE); - - if (p->n_sp != NULL && q->n_sp != NULL) - return(0); - if (q->n_sp != NULL && o != PLUS) - return(0); - if (p->n_sp != NULL && o != PLUS && o != MINUS) - return(0); - v1 = p->n_lval; - v2 = q->n_lval; - switch( o ){ - - case PLUS: - p->n_lval += val; - if (p->n_sp == NULL) { - p->n_rval = q->n_rval; - p->n_type = q->n_type; - } - break; - case MINUS: - p->n_lval -= val; - break; - case MUL: - p->n_lval *= val; - break; - case DIV: - if (val == 0) - uerror("division by 0"); - else { - if (u) { - v1 /= v2; - p->n_lval = v1; - } else - p->n_lval /= val; - } - break; - case MOD: - if (val == 0) - uerror("division by 0"); - else { - if (u) { - v1 %= v2; - p->n_lval = v1; - } else - p->n_lval %= val; - } - break; - case AND: - p->n_lval &= val; - break; - case OR: - p->n_lval |= val; - break; - case ER: - p->n_lval ^= val; - break; - case LS: - i = val; - p->n_lval = p->n_lval << i; - break; - case RS: - i = val; - if (u) { - v1 = v1 >> i; - p->n_lval = v1; - } else - p->n_lval = p->n_lval >> i; - break; - - case UMINUS: - p->n_lval = - p->n_lval; - break; - case COMPL: - p->n_lval = ~p->n_lval; - break; - case NOT: - p->n_lval = !p->n_lval; - break; - case LT: - p->n_lval = p->n_lval < val; - break; - case LE: - p->n_lval = p->n_lval <= val; - break; - case GT: - p->n_lval = p->n_lval > val; - break; - case GE: - p->n_lval = p->n_lval >= val; - break; - case ULT: - p->n_lval = v1 < v2; - break; - case ULE: - p->n_lval = v1 <= v2; - break; - case UGT: - p->n_lval = v1 > v2; - break; - case UGE: - p->n_lval = v1 >= v2; - break; - case EQ: - p->n_lval = p->n_lval == val; - break; - case NE: - p->n_lval = p->n_lval != val; - break; - case ANDAND: - p->n_lval = p->n_lval && val; - break; - case OROR: - p->n_lval = p->n_lval || val; - break; - default: - return(0); - } - return(1); - } - -/* - * Checks p for the existance of a pun. This is called when the op of p - * is ASSIGN, RETURN, CAST, COLON, or relational. - * One case is when enumerations are used: this applies only to lint. - * In the other case, one operand is a pointer, the other integer type - * we check that this integer is in fact a constant zero... - * in the case of ASSIGN, any assignment of pointer to integer is illegal - * this falls out, because the LHS is never 0. - */ -void -chkpun(NODE *p) -{ - union dimfun *d1, *d2; - NODE *q; - int t1, t2; - - t1 = p->n_left->n_type; - t2 = p->n_right->n_type; - - switch (p->n_op) { - case RETURN: - /* return of void allowed but nothing else */ - if (t1 == VOID && t2 == VOID) - return; - if (t1 == VOID) { - werror("returning value from void function"); - return; - } - if (t2 == VOID) { - uerror("using void value"); - return; - } - case COLON: - if (t1 == VOID && t2 == VOID) - return; - break; - default: - if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) { - uerror("value of void expression used"); - return; - } - break; - } - - /* allow void pointer assignments in any direction */ - if (BTYPE(t1) == VOID && (t2 & TMASK)) - return; - if (BTYPE(t2) == VOID && (t1 & TMASK)) - return; - - /* check for enumerations */ - if (t1 == ENUMTY || t2 == ENUMTY) { - if (clogop(p->n_op) && p->n_op != EQ && p->n_op != NE) { - werror("comparison of enums"); - return; - } - if (chkenum(t1, t2, p)) - return; - } - - if (ISPTR(t1) || ISARY(t1)) - q = p->n_right; - else - q = p->n_left; - - if (!ISPTR(q->n_type) && !ISARY(q->n_type)) { - if (q->n_op != ICON || q->n_lval != 0) - werror("illegal combination of pointer and integer"); - } else { - d1 = p->n_left->n_df; - d2 = p->n_right->n_df; - if (t1 == t2) { - if (p->n_left->n_sue != p->n_right->n_sue) - werror("illegal structure pointer combination"); - return; - } - for (;;) { - if (ISARY(t1) || ISPTR(t1)) { - if (!ISARY(t2) && !ISPTR(t2)) - break; - if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) { - werror("illegal array size combination"); - return; - } - if (ISARY(t1)) - ++d1; - if (ISARY(t2)) - ++d2; - } else if (ISFTN(t1)) { - if (chkftn(d1->dfun, d2->dfun)) { - werror("illegal function " - "pointer combination"); - return; - } - ++d1; - ++d2; - } else if (t1 == ENUMTY || t2 == ENUMTY) { - chkenum(t1, t2, p); - return; - } else - break; - t1 = DECREF(t1); - t2 = DECREF(t2); - } - werror("illegal pointer combination"); - } -} - -static int -chkenum(int t1, int t2, NODE *p) -{ - if (t1 == ENUMTY && t2 == ENUMTY) { - if (p->n_left->n_sue != p->n_right->n_sue) - werror("enumeration type clash, operator %s", copst(p->n_op)); - return 1; - } - if ((t1 == ENUMTY && !(t2 >= CHAR && t2 <= UNSIGNED)) || - (t2 == ENUMTY && !(t1 >= CHAR && t1 <= UNSIGNED))) { - werror("illegal combination of enum and non-integer type"); - return 1; - } - return 0; -} - -NODE * -stref(NODE *p) -{ - NODE *r; - struct suedef *sue; - union dimfun *d; - TWORD t, q; - int dsc; - OFFSZ off; - struct symtab *s; - - /* make p->x */ - /* this is also used to reference automatic variables */ - - s = p->n_right->n_sp; - nfree(p->n_right); - r = p->n_left; - nfree(p); - p = pconvert(r); - - /* make p look like ptr to x */ - - if (!ISPTR(p->n_type)) - p->n_type = PTR+UNIONTY; - - t = INCREF(s->stype); - q = INCQAL(s->squal); - d = s->sdf; - sue = s->ssue; - - p = makety(p, t, q, d, sue); - - /* compute the offset to be added */ - - off = s->soffset; - dsc = s->sclass; - - if (dsc & FIELD) { /* make fields look like ints */ - off = (off/ALINT)*ALINT; - sue = MKSUE(INT); - } - if (off != 0) { - p = block(PLUS, p, offcon(off, t, d, sue), t, d, sue); - p->n_qual = q; - p = optim(p); - } - - p = buildtree(UMUL, p, NIL); - - /* if field, build field info */ - - if (dsc & FIELD) { - p = block(FLD, p, NIL, s->stype, 0, s->ssue); - p->n_qual = q; - p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%ALINT); - } - - p = clocal(p); - return p; -} - -int -notlval(p) register NODE *p; { - - /* return 0 if p an lvalue, 1 otherwise */ - - again: - - switch( p->n_op ){ - - case FLD: - p = p->n_left; - goto again; - - case NAME: - case OREG: - case UMUL: - if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1); - case TEMP: - case REG: - return(0); - - default: - return(1); - - } - - } -/* make a constant node with value i */ -NODE * -bcon(int i) -{ - register NODE *p; - - p = block(ICON, NIL, NIL, INT, 0, MKSUE(INT)); - p->n_lval = i; - p->n_sp = NULL; - return(clocal(p)); -} - -NODE * -bpsize(NODE *p) -{ - return(offcon(psize(p), p->n_type, p->n_df, p->n_sue)); -} - -/* - * p is a node of type pointer; psize returns the - * size of the thing pointed to - */ -OFFSZ -psize(NODE *p) -{ - - if (!ISPTR(p->n_type)) { - uerror("pointer required"); - return(SZINT); - } - /* note: no pointers to fields */ - return(tsize(DECREF(p->n_type), p->n_df, p->n_sue)); -} - -/* - * convert an operand of p - * f is either CVTL or CVTR - * operand has type int, and is converted by the size of the other side - * convert is called when an integer is to be added to a pointer, for - * example in arrays or structures. - */ -NODE * -convert(NODE *p, int f) -{ - union dimfun *df; - TWORD ty, ty2; - NODE *q, *r, *s, *rv; - - if (f == CVTL) { - q = p->n_left; - s = p->n_right; - } else { - q = p->n_right; - s = p->n_left; - } - ty2 = ty = DECREF(s->n_type); - while (ISARY(ty)) - ty = DECREF(ty); - - r = offcon(tsize(ty, s->n_df, s->n_sue), s->n_type, s->n_df, s->n_sue); - ty = ty2; - rv = bcon(1); - df = s->n_df; - while (ISARY(ty)) { - rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) : - tempnode(-df->ddim, INT, 0, MKSUE(INT))); - df++; - ty = DECREF(ty); - } - rv = clocal(block(PMCONV, rv, r, INT, 0, MKSUE(INT))); - rv = optim(rv); - - r = block(PMCONV, q, rv, INT, 0, MKSUE(INT)); - r = clocal(r); - /* - * Indexing is only allowed with integer arguments, so insert - * SCONV here if arg is not an integer. - * XXX - complain? - */ - if (r->n_type != INT) - r = clocal(block(SCONV, r, NIL, INT, 0, MKSUE(INT))); - if (f == CVTL) - p->n_left = r; - else - p->n_right = r; - return(p); -} - -/* - * change enums to ints, or appropriate types - */ -void -econvert( p ) register NODE *p; { - - - register TWORD ty; - - if( (ty=BTYPE(p->n_type)) == ENUMTY || ty == MOETY ) { - if (p->n_sue->suesize == SZCHAR) - ty = INT; - else if (p->n_sue->suesize == SZINT) - ty = INT; - else if (p->n_sue->suesize == SZSHORT) - ty = INT; - else if (p->n_sue->suesize == SZLONGLONG) - ty = LONGLONG; - else - ty = LONG; - ty = ctype(ty); - p->n_sue = MKSUE(ty); - MODTYPE(p->n_type,ty); - if (p->n_op == ICON && ty != LONG && ty != LONGLONG) - p->n_type = INT, p->n_sue = MKSUE(INT); - } -} - -NODE * -pconvert( p ) register NODE *p; { - - /* if p should be changed into a pointer, do so */ - - if( ISARY( p->n_type) ){ - p->n_type = DECREF( p->n_type ); - ++p->n_df; - return( buildtree( ADDROF, p, NIL ) ); - } - if( ISFTN( p->n_type) ) - return( buildtree( ADDROF, p, NIL ) ); - - return( p ); - } - -NODE * -oconvert(p) register NODE *p; { - /* convert the result itself: used for pointer and unsigned */ - - switch(p->n_op) { - - case LE: - case LT: - case GE: - case GT: - if( ISUNSIGNED(p->n_left->n_type) || ISUNSIGNED(p->n_right->n_type) ) p->n_op += (ULE-LE); - case EQ: - case NE: - return( p ); - - case MINUS: - return( clocal( block( PVCONV, - p, bpsize(p->n_left), INT, 0, MKSUE(INT)))); - } - - cerror( "illegal oconvert: %d", p->n_op ); - - return(p); - } - -/* - * makes the operands of p agree; they are - * either pointers or integers, by this time - * with MINUS, the sizes must be the same - * with COLON, the types must be the same - */ -NODE * -ptmatch(NODE *p) -{ - struct suedef *sue, *sue2; - union dimfun *d, *d2; - TWORD t1, t2, t, q1, q2, q; - int o; - - o = p->n_op; - t = t1 = p->n_left->n_type; - q = q1 = p->n_left->n_qual; - t2 = p->n_right->n_type; - q2 = p->n_right->n_qual; - d = p->n_left->n_df; - d2 = p->n_right->n_df; - sue = p->n_left->n_sue; - sue2 = p->n_right->n_sue; - - switch( o ){ - - case ASSIGN: - case RETURN: - case CAST: - { break; } - - case MINUS: - { if( psize(p->n_left) != psize(p->n_right) ){ - uerror( "illegal pointer subtraction"); - } - break; - } - case COLON: - if (t1 != t2) { - /* - * Check for void pointer types. They are allowed - * to cast to/from any pointers. - */ - if (ISPTR(t1) && ISPTR(t2) && - (BTYPE(t1) == VOID || BTYPE(t2) == VOID)) - break; - uerror("illegal types in :"); - } - break; - - default: /* must work harder: relationals or comparisons */ - - if( !ISPTR(t1) ){ - t = t2; - q = q2; - d = d2; - sue = sue2; - break; - } - if( !ISPTR(t2) ){ - break; - } - - /* both are pointers */ - if( talign(t2,sue2) < talign(t,sue) ){ - t = t2; - q = q2; - sue = sue2; - } - break; - } - - p->n_left = makety( p->n_left, t, q, d, sue ); - p->n_right = makety( p->n_right, t, q, d, sue ); - if( o!=MINUS && !clogop(o) ){ - - p->n_type = t; - p->n_qual = q; - p->n_df = d; - p->n_sue = sue; - } - - return(clocal(p)); - } - -int tdebug = 0; - -NODE * -tymatch(p) register NODE *p; { - - /* satisfy the types of various arithmetic binary ops */ - - /* rules are: - if assignment, type of LHS - if any doubles, make double - else if any float make float - else if any longlongs, make long long - else if any longs, make long - else etcetc. - if either operand is unsigned, the result is... - */ - - TWORD t1, t2, t, tu; - int o, lu, ru; - - o = p->n_op; - - t1 = p->n_left->n_type; - t2 = p->n_right->n_type; - - lu = ru = 0; - if( ISUNSIGNED(t1) ){ - lu = 1; - t1 = DEUNSIGN(t1); - } - if( ISUNSIGNED(t2) ){ - ru = 1; - t2 = DEUNSIGN(t2); - } - - if (t1 == ENUMTY || t1 == MOETY) - t1 = INT; /* XXX */ - if (t2 == ENUMTY || t2 == MOETY) - t2 = INT; /* XXX */ -#if 0 - if ((t1 == CHAR || t1 == SHORT) && o!= RETURN) - t1 = INT; - if (t2 == CHAR || t2 == SHORT) - t2 = INT; -#endif - - if (t1 == LDOUBLE || t2 == LDOUBLE) - t = LDOUBLE; - else if (t1 == DOUBLE || t2 == DOUBLE) - t = DOUBLE; - else if (t1 == FLOAT || t2 == FLOAT) - t = FLOAT; - else if (t1==LONGLONG || t2 == LONGLONG) - t = LONGLONG; - else if (t1==LONG || t2==LONG) - t = LONG; - else /* if (t1==INT || t2==INT) */ - t = INT; -#if 0 - else if (t1==SHORT || t2==SHORT) - t = SHORT; - else - t = CHAR; -#endif - - if( casgop(o) ){ - tu = p->n_left->n_type; - t = t1; - } else { - tu = ((ru|lu) && UNSIGNABLE(t))?ENUNSIGN(t):t; - } - - /* because expressions have values that are at least as wide - as INT or UNSIGNED, the only conversions needed - are those involving FLOAT/DOUBLE, and those - from LONG to INT and ULONG to UNSIGNED */ - - - if (t != t1 || (ru && !lu)) - p->n_left = makety( p->n_left, tu, 0, 0, MKSUE(tu)); - - if (t != t2 || o==CAST || (lu && !ru)) - p->n_right = makety(p->n_right, tu, 0, 0, MKSUE(tu)); - - if( casgop(o) ){ - p->n_type = p->n_left->n_type; - p->n_df = p->n_left->n_df; - p->n_sue = p->n_left->n_sue; - } - else if( !clogop(o) ){ - p->n_type = tu; - p->n_df = NULL; - p->n_sue = MKSUE(t); - } - -#ifdef PCC_DEBUG - if (tdebug) { - printf("tymatch(%p): ", p); - tprint(stdout, t1, 0); - printf(" %s ", copst(o)); - tprint(stdout, t2, 0); - printf(" => "); - tprint(stdout, tu, 0); - printf("\n"); - } -#endif - - return(p); - } - -/* - * make p into type t by inserting a conversion - */ -NODE * -makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct suedef *sue) -{ - - if (p->n_type == ENUMTY && p->n_op == ICON) - econvert(p); - if (t == p->n_type) { - p->n_df = d; - p->n_sue = sue; - p->n_qual = q; - return(p); - } - - if ((p->n_type == FLOAT || p->n_type == DOUBLE || p->n_type == LDOUBLE) - && (t == FLOAT || t == DOUBLE || t == LDOUBLE) && p->n_op == FCON) { - p->n_type = t; - p->n_qual = q; - p->n_df = d; - p->n_sue = sue; - return(p); - } - - if (t & TMASK) { - /* non-simple type */ - p = block(PCONV, p, NIL, t, d, sue); - p->n_qual = q; - return clocal(p); - } - - if (p->n_op == ICON) { - if (t == DOUBLE || t == FLOAT) { - p->n_op = FCON; - if (ISUNSIGNED(p->n_type)) - p->n_dcon = (U_CONSZ) p->n_lval; - else - p->n_dcon = p->n_lval; - p->n_type = t; - p->n_qual = q; - p->n_sue = MKSUE(t); - return (clocal(p)); - } - } - p = block(SCONV, p, NIL, t, d, sue); - p->n_qual = q; - return clocal(p); - -} - -NODE * -block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct suedef *sue) -{ - register NODE *p; - - p = talloc(); - p->n_rval = 0; - p->n_op = o; - p->n_lval = 0; /* Protect against large lval */ - p->n_left = l; - p->n_right = r; - p->n_type = t; - p->n_qual = 0; - p->n_df = d; - p->n_sue = sue; -#if !defined(MULTIPASS) - /* p->n_reg = */p->n_su = 0; - p->n_regw = 0; -#endif - return(p); - } - -int -icons(p) register NODE *p; { - /* if p is an integer constant, return its value */ - int val; - - if( p->n_op != ICON ){ - uerror( "constant expected"); - val = 1; - } - else { - val = p->n_lval; - if( val != p->n_lval ) uerror( "constant too big for cross-compiler" ); - } - tfree( p ); - return(val); -} - -/* - * the intent of this table is to examine the - * operators, and to check them for - * correctness. - * - * The table is searched for the op and the - * modified type (where this is one of the - * types INT (includes char and short), LONG, - * DOUBLE (includes FLOAT), and POINTER - * - * The default action is to make the node type integer - * - * The actions taken include: - * PUN check for puns - * CVTL convert the left operand - * CVTR convert the right operand - * TYPL the type is determined by the left operand - * TYPR the type is determined by the right operand - * TYMATCH force type of left and right to match,by inserting conversions - * PTMATCH like TYMATCH, but for pointers - * LVAL left operand must be lval - * CVTO convert the op - * NCVT do not convert the operands - * OTHER handled by code - * NCVTR convert the left operand, not the right... - * - */ - -# define MINT 01 /* integer */ -# define MDBI 02 /* integer or double */ -# define MSTR 04 /* structure */ -# define MPTR 010 /* pointer */ -# define MPTI 020 /* pointer or integer */ -# define MENU 040 /* enumeration variable or member */ - -int -opact(NODE *p) -{ - int mt12, mt1, mt2, o; - - mt1 = mt2 = mt12 = 0; - - switch (coptype(o = p->n_op)) { - case BITYPE: - mt12=mt2 = moditype(p->n_right->n_type); - case UTYPE: - mt12 &= (mt1 = moditype(p->n_left->n_type)); - break; - } - - switch( o ){ - - case NAME : - case ICON : - case FCON : - case CALL : - case UCALL: - case UMUL: - { return( OTHER ); } - case UMINUS: - if( mt1 & MDBI ) return( TYPL ); - break; - - case COMPL: - if( mt1 & MINT ) return( TYPL ); - break; - - case ADDROF: - return( NCVT+OTHER ); - case NOT: -/* case INIT: */ - case CM: - case CBRANCH: - case ANDAND: - case OROR: - return( 0 ); - - case MUL: - case DIV: - if ((mt1&MDBI) && (mt2&MENU)) return( TYMATCH ); - if ((mt2&MDBI) && (mt1&MENU)) return( TYMATCH ); - if( mt12 & MDBI ) return( TYMATCH ); - break; - - case MOD: - case AND: - case OR: - case ER: - if( mt12 & MINT ) return( TYMATCH ); - break; - - case LS: - case RS: - if( mt12 & MINT ) return( TYPL+OTHER ); - break; - - case EQ: - case NE: - case LT: - case LE: - case GT: - case GE: - if( mt12 & MDBI ) return( TYMATCH+CVTO ); - else if( mt12 & MPTR ) return( PTMATCH+PUN ); - else if( mt12 & MPTI ) return( PTMATCH+PUN ); - else break; - - case QUEST: - case COMOP: - if( mt2&MENU ) return( TYPR+NCVTR ); - return( TYPR ); - - case STREF: - return( NCVTR+OTHER ); - - case FORCE: - return( TYPL ); - - case COLON: - if( mt12 & MDBI ) return( TYMATCH ); - else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN ); - else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN ); - else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN ); - else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); - break; - - case ASSIGN: - case RETURN: - if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER ); - case CAST: - if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH ); -#if 0 - else if(mt1&MENU && mt2&MDBI) return( TYPL+LVAL+TYMATCH ); - else if(mt2&MENU && mt1&MDBI) return( TYPL+LVAL+TYMATCH ); - else if( (mt1&MENU)||(mt2&MENU) ) - return( LVAL+NCVT+TYPL+PTMATCH+PUN ); -#endif - else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN ); - else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); - break; - - case LSEQ: - case RSEQ: - if( mt12 & MINT ) return( TYPL+LVAL+OTHER ); - break; - - case MULEQ: - case DIVEQ: - if( mt12 & MDBI ) return( LVAL+TYMATCH ); - break; - - case MODEQ: - case ANDEQ: - case OREQ: - case EREQ: - if (mt12 & MINT) - return(LVAL+TYMATCH); - break; - - case PLUSEQ: - case MINUSEQ: - case INCR: - case DECR: - if (mt12 & MDBI) - return(TYMATCH+LVAL); - else if ((mt1&MPTR) && (mt2&MINT)) - return(TYPL+LVAL+CVTR); - break; - - case MINUS: - if (mt12 & MPTR) - return(CVTO+PTMATCH+PUN); - if (mt2 & MPTR) - break; - /* FALLTHROUGH */ - case PLUS: - if (mt12 & MDBI) - return(TYMATCH); - else if ((mt1&MPTR) && (mt2&MINT)) - return(TYPL+CVTR); - else if ((mt1&MINT) && (mt2&MPTR)) - return(TYPR+CVTL); - - } - uerror("operands of %s have incompatible types", copst(o)); - return(NCVT); -} - -int -moditype(TWORD ty) -{ - switch (ty) { - - case ENUMTY: - case MOETY: - return( MENU|MINT|MDBI|MPTI ); - - case STRTY: - case UNIONTY: - return( MSTR ); - - case BOOL: - case CHAR: - case SHORT: - case UCHAR: - case USHORT: - case UNSIGNED: - case ULONG: - case ULONGLONG: - case INT: - case LONG: - case LONGLONG: - return( MINT|MDBI|MPTI ); - case FLOAT: - case DOUBLE: - case LDOUBLE: - return( MDBI ); - default: - return( MPTR|MPTI ); - - } -} - -int tvaloff = 100; - -/* - * Returns a TEMP node with temp number nr. - * If nr == 0, return a node with a new number. - */ -NODE * -tempnode(int nr, TWORD type, union dimfun *df, struct suedef *sue) -{ - NODE *r; - - r = block(TEMP, NIL, NIL, type, df, sue); - r->n_lval = nr ? nr : tvaloff; - tvaloff += szty(type); - return r; -} - -/* - * Do sizeof on p. - */ -NODE * -doszof(NODE *p) -{ - union dimfun *df; - TWORD ty; - NODE *rv; - - if (p->n_op == FLD) - uerror("can't apply sizeof to bit-field"); - - /* - * Arrays may be dynamic, may need to make computations. - */ - - rv = bcon(1); - df = p->n_df; - ty = p->n_type; - while (ISARY(ty)) { - rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) : - tempnode(-df->ddim, INT, 0, MKSUE(INT))); - df++; - ty = DECREF(ty); - } - rv = buildtree(MUL, rv, bcon(tsize(ty, p->n_df, p->n_sue)/SZCHAR)); - tfree(p); - return rv; -} - -#ifdef PCC_DEBUG -void -eprint(NODE *p, int down, int *a, int *b) -{ - int ty; - - *a = *b = down+1; - while( down > 1 ){ - printf( "\t" ); - down -= 2; - } - if( down ) printf( " " ); - - ty = coptype( p->n_op ); - - printf("%p) %s, ", p, copst(p->n_op)); - if (ty == LTYPE) { - printf(CONFMT, p->n_lval); - printf(", %d, ", p->n_rval); - } - tprint(stdout, p->n_type, p->n_qual); - printf( ", %p, %p\n", p->n_df, p->n_sue ); -} -# endif - -void -prtdcon(NODE *p) -{ - int o = p->n_op, i; - - if (o != FCON) - return; - - /* Write float constants to memory */ - /* Should be volontary per architecture */ - - setloc1(RDATA); - defalign(p->n_type == FLOAT ? ALFLOAT : p->n_type == DOUBLE ? - ALDOUBLE : ALLDOUBLE ); - deflab1(i = getlab()); - ninval(0, btdims[p->n_type].suesize, p); - p->n_op = NAME; - p->n_lval = 0; - p->n_sp = tmpalloc(sizeof(struct symtab_hdr)); - p->n_sp->sclass = ILABEL; - p->n_sp->soffset = i; -} - -extern int negrel[]; - -/* - * Walk up through the tree from the leaves, - * removing constant operators. - */ -static void -logwalk(NODE *p) -{ - int o = coptype(p->n_op); - NODE *l, *r; - - l = p->n_left; - r = p->n_right; - switch (o) { - case LTYPE: - return; - case BITYPE: - logwalk(r); - case UTYPE: - logwalk(l); - } - if (!clogop(p->n_op)) - return; - if (p->n_op == NOT && l->n_op == ICON) { - p->n_lval = l->n_lval == 0; - nfree(l); - p->n_op = ICON; - } - if (l->n_op == ICON && r->n_op == ICON) { - if (conval(l, p->n_op, r) == 0) { - /* - * people sometimes tend to do really odd compares, - * like "if ("abc" == "def")" etc. - * do it runtime instead. - */ - } else { - p->n_lval = l->n_lval; - p->n_op = ICON; - nfree(l); - nfree(r); - } - } -} - -/* - * Removes redundant logical operators for branch conditions. - */ -static void -fixbranch(NODE *p, int label) -{ - - logwalk(p); - - if (p->n_op == ICON) { - if (p->n_lval != 0) - branch(label); - nfree(p); - } else { - if (!clogop(p->n_op)) /* Always conditional */ - p = buildtree(NE, p, bcon(0)); - ecode(buildtree(CBRANCH, p, bcon(label))); - } -} - -/* - * Write out logical expressions as branches. - */ -static void -andorbr(NODE *p, int true, int false) -{ - NODE *q; - int o, lab; - - lab = -1; - switch (o = p->n_op) { - case EQ: - case NE: - /* - * Remove redundant EQ/NE nodes. - */ - while (((o = p->n_left->n_op) == EQ || o == NE) && - p->n_right->n_op == ICON) { - o = p->n_op; - q = p->n_left; - if (p->n_right->n_lval == 0) { - nfree(p->n_right); - *p = *q; - nfree(q); - if (o == EQ) - p->n_op = negrel[p->n_op - EQ]; -// p->n_op = NE; /* toggla */ - } else if (p->n_right->n_lval == 1) { - nfree(p->n_right); - *p = *q; - nfree(q); - if (o == NE) - p->n_op = negrel[p->n_op - EQ]; -// p->n_op = EQ; /* toggla */ - } else - break; /* XXX - should always be false */ - - } - /* FALLTHROUGH */ - case LE: - case LT: - case GE: - case GT: -calc: if (true < 0) { - p->n_op = negrel[p->n_op - EQ]; - true = false; - false = -1; - } - - rmcops(p->n_left); - rmcops(p->n_right); - fixbranch(p, true); - if (false >= 0) - branch(false); - break; - - case ULE: - case UGT: - /* Convert to friendlier ops */ - if (p->n_right->n_op == ICON && p->n_right->n_lval == 0) - p->n_op = o == ULE ? EQ : NE; - goto calc; - - case UGE: - case ULT: - /* Already true/false by definition */ - if (p->n_right->n_op == ICON && p->n_right->n_lval == 0) { - if (true < 0) { - o = o == ULT ? UGE : ULT; - true = false; - } - rmcops(p->n_left); - ecode(p->n_left); - rmcops(p->n_right); - ecode(p->n_right); - nfree(p); - if (o == UGE) /* true */ - branch(true); - break; - } - goto calc; - - case ANDAND: - lab = false<0 ? getlab() : false ; - andorbr(p->n_left, -1, lab); - andorbr(p->n_right, true, false); - if (false < 0) - plabel( lab); - nfree(p); - break; - - case OROR: - lab = true<0 ? getlab() : true; - andorbr(p->n_left, lab, -1); - andorbr(p->n_right, true, false); - if (true < 0) - plabel( lab); - nfree(p); - break; - - case NOT: - andorbr(p->n_left, false, true); - nfree(p); - break; - - default: - rmcops(p); - if (true >= 0) - fixbranch(p, true); - if (false >= 0) { - if (true >= 0) - branch(false); - else - fixbranch(buildtree(EQ, p, bcon(0)), false); - } - } -} - -/* - * Massage the output trees to remove C-specific nodes: - * COMOPs are split into separate statements. - * QUEST/COLON are rewritten to branches. - * ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation. - * CBRANCH conditions are rewritten for lazy-evaluation. - */ -static void -rmcops(NODE *p) -{ - TWORD type; - NODE *q, *r; - int o, ty, lbl, lbl2, tval = 0; - -again: - o = p->n_op; - ty = coptype(o); - switch (o) { - case QUEST: - - /* - * Create a branch node from ?: - * || and && must be taken special care of. - */ - type = p->n_type; - andorbr(p->n_left, -1, lbl = getlab()); - - /* Make ASSIGN node */ - /* Only if type is not void */ - q = p->n_right->n_left; - if (type != VOID) { - r = tempnode(0, q->n_type, q->n_df, q->n_sue); - tval = r->n_lval; - q = buildtree(ASSIGN, r, q); - } - rmcops(q); - ecode(q); /* Done with assign */ - branch(lbl2 = getlab()); - plabel( lbl); - - q = p->n_right->n_right; - if (type != VOID) { - r = tempnode(tval, q->n_type, q->n_df, q->n_sue); - q = buildtree(ASSIGN, r, q); - } - rmcops(q); - ecode(q); /* Done with assign */ - - plabel( lbl2); - - nfree(p->n_right); - if (p->n_type != VOID) { - r = tempnode(tval, p->n_type, p->n_df, p->n_sue); - *p = *r; - nfree(r); - } else - p->n_op = ICON; - break; - - case ULE: - case ULT: - case UGE: - case UGT: - case EQ: - case NE: - case LE: - case LT: - case GE: - case GT: - case ANDAND: - case OROR: - case NOT: -#ifdef SPECIAL_CCODES -#error fix for private CCODES handling -#else - r = talloc(); - *r = *p; - andorbr(r, -1, lbl = getlab()); - q = tempnode(0, p->n_type, p->n_df, p->n_sue); - tval = q->n_lval; - r = tempnode(tval, p->n_type, p->n_df, p->n_sue); - ecode(buildtree(ASSIGN, q, bcon(1))); - branch(lbl2 = getlab()); - plabel( lbl); - ecode(buildtree(ASSIGN, r, bcon(0))); - plabel( lbl2); - r = tempnode(tval, p->n_type, p->n_df, p->n_sue); - *p = *r; - nfree(r); -#endif - break; - case CBRANCH: - andorbr(p->n_left, p->n_right->n_lval, -1); - nfree(p->n_right); - p->n_op = ICON; p->n_type = VOID; - break; - case COMOP: - rmcops(p->n_left); - ecode(p->n_left); - /* Now when left tree is dealt with, rm COMOP */ - q = p->n_right; - *p = *p->n_right; - nfree(q); - goto again; - - default: - if (ty == LTYPE) - return; - rmcops(p->n_left); - if (ty == BITYPE) - rmcops(p->n_right); - } -} - -/* - * Return 1 if an assignment is found. - */ -static int -has_se(NODE *p) -{ - if (cdope(p->n_op) & ASGFLG) - return 1; - if (coptype(p->n_op) == LTYPE) - return 0; - if (has_se(p->n_left)) - return 1; - if (coptype(p->n_op) == BITYPE) - return has_se(p->n_right); - return 0; -} - -/* - * Find and convert asgop's to separate statements. - * Be careful about side effects. - * assign tells whether ASSIGN should be considered giving - * side effects or not. - */ -static NODE * -delasgop(NODE *p) -{ - NODE *q, *r; - int tval; - - if (p->n_op == INCR || p->n_op == DECR) { - /* - * Rewrite x++ to (x += 1) -1; and deal with it further down. - * Pass2 will remove -1 if unneccessary. - */ - q = ccopy(p); - tfree(p->n_left); - q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ; - p->n_op = (p->n_op==INCR)?MINUS:PLUS; - p->n_left = delasgop(q); - - } else if ((cdope(p->n_op)&ASGOPFLG) && - p->n_op != RETURN && p->n_op != CAST) { - NODE *l = p->n_left; - NODE *ll = l->n_left; - - if (has_se(l)) { - q = tempnode(0, ll->n_type, ll->n_df, ll->n_sue); - tval = q->n_lval; - r = tempnode(tval, ll->n_type, ll->n_df,ll->n_sue); - l->n_left = q; - /* Now the left side of node p has no side effects. */ - /* side effects on the right side must be obeyed */ - p = delasgop(p); - - r = buildtree(ASSIGN, r, ll); - r = delasgop(r); - ecode(r); - } else { -#if 0 /* Cannot call buildtree() here, it would invoke double add shifts */ - p->n_right = buildtree(UNASG p->n_op, ccopy(l), - p->n_right); -#else - p->n_right = block(UNASG p->n_op, ccopy(l), - p->n_right, p->n_type, p->n_df, p->n_sue); -#endif - p->n_op = ASSIGN; - p->n_right = delasgop(p->n_right); - p->n_right = clocal(p->n_right); - } - - } else { - if (coptype(p->n_op) == LTYPE) - return p; - p->n_left = delasgop(p->n_left); - if (coptype(p->n_op) == BITYPE) - p->n_right = delasgop(p->n_right); - } - return p; -} - -int edebug = 0; -void -ecomp(NODE *p) -{ - -#ifdef PCC_DEBUG - if (edebug) - fwalk(p, eprint, 0); -#endif - if (!reached) { - werror("statement not reached"); - reached = 1; - } - p = optim(p); - rmcops(p); - p = delasgop(p); - setloc1(PROG); - if (p->n_op == ICON && p->n_type == VOID) - tfree(p); - else - ecode(p); -} - -#if defined(MULTIPASS) -void -p2tree(NODE *p) -{ - struct symtab *q; - int ty; - -# ifdef MYP2TREE - MYP2TREE(p); /* local action can be taken here; then return... */ -# endif - - ty = coptype(p->n_op); - - printf("%d\t", p->n_op); - - if (ty == LTYPE) { - printf(CONFMT, p->n_lval); - printf("\t"); - } - if (ty != BITYPE) { - if (p->n_op == NAME || p->n_op == ICON) - printf("0\t"); - else - printf("%d\t", p->n_rval); - } - - printf("%o\t", p->n_type); - - /* handle special cases */ - - switch (p->n_op) { - - case NAME: - case ICON: - /* print external name */ - if ((q = p->n_sp) != NULL) { - if ((q->sclass == STATIC && q->slevel > 0) || - q->sclass == ILABEL) { - printf(LABFMT, q->soffset); - } else - printf("%s\n", exname(q->sname)); - } else - printf("\n"); - break; - - case STARG: - case STASG: - case STCALL: - case USTCALL: - /* print out size */ - /* use lhs size, in order to avoid hassles - * with the structure `.' operator - */ - - /* note: p->left not a field... */ - printf(CONFMT, (CONSZ)tsize(STRTY, p->n_left->n_df, - p->n_left->n_sue)); - printf("\t%d\t\n", talign(STRTY, p->n_left->n_sue)); - break; - - default: - printf( "\n" ); - } - - if (ty != LTYPE) - p2tree(p->n_left); - if (ty == BITYPE) - p2tree(p->n_right); -} -#else -void -p2tree(NODE *p) -{ - struct symtab *q; - int ty; - -# ifdef MYP2TREE - MYP2TREE(p); /* local action can be taken here; then return... */ -# endif - - ty = coptype(p->n_op); - - switch( p->n_op ){ - - case NAME: - case ICON: - if ((q = p->n_sp) != NULL) { - if ((q->sclass == STATIC && q->slevel > 0) || -#ifdef GCC_COMPAT - q->sflags == SLBLNAME || -#endif - q->sclass == ILABEL) { - char *cp = (isinlining ? - permalloc(32) : tmpalloc(32)); - int n = q->soffset; - if (n < 0) - n = -n; - snprintf(cp, 32, LABFMT, n); - p->n_name = cp; - } else { -#ifdef GCC_COMPAT - p->n_name = gcc_findname(q); -#else - p->n_name = exname(q->sname); -#endif - } - } else - p->n_name = ""; - break; - - case STASG: - /* STASG used for stack array init */ - if (ISARY(p->n_type)) { - int size1 = tsize(p->n_type, p->n_left->n_df, - p->n_left->n_sue)/SZCHAR; - p->n_stsize = tsize(p->n_type, p->n_right->n_df, - p->n_right->n_sue)/SZCHAR; - if (size1 < p->n_stsize) - p->n_stsize = size1; - p->n_stalign = talign(p->n_type, - p->n_left->n_sue)/SZCHAR; - break; - } - /* FALLTHROUGH */ - case STARG: - case STCALL: - case USTCALL: - /* set up size parameters */ - p->n_stsize = (tsize(STRTY, p->n_left->n_df, - p->n_left->n_sue)+SZCHAR-1)/SZCHAR; - p->n_stalign = talign(STRTY,p->n_left->n_sue)/SZCHAR; - break; - - default: - p->n_name = ""; - } - - if( ty != LTYPE ) p2tree( p->n_left ); - if( ty == BITYPE ) p2tree( p->n_right ); - } - -#endif - -/* - * Change void data types into char. - */ -static void -delvoid(NODE *p) -{ - /* Convert "PTR undef" (void *) to "PTR uchar" */ - if (BTYPE(p->n_type) == VOID) - p->n_type = (p->n_type & ~BTMASK) | UCHAR; - if (BTYPE(p->n_type) == BOOL) { - if (p->n_op == SCONV && p->n_type == BOOL) { - /* create a jump and a set */ - NODE *q, *r, *s; - int l, val; - - q = talloc(); - *q = *p; - q->n_type = BOOL_TYPE; - r = tempnode(0, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE)); - val = r->n_lval; - s = tempnode(val, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE)); - *p = *s; - q = buildtree(ASSIGN, r, q); - cbranch(buildtree(EQ, q, bcon(0)), bcon(l = getlab())); - ecode(buildtree(ASSIGN, s, bcon(1))); - plabel(l); - } else - p->n_type = (p->n_type & ~BTMASK) | BOOL_TYPE; - } - -} - -void -ecode(NODE *p) -{ - /* walk the tree and write out the nodes.. */ - - if (nerrors) - return; - - p = optim(p); - p = delasgop(p); - walkf(p, prtdcon); - walkf(p, delvoid); -#ifdef PCC_DEBUG - if (xdebug) { - printf("Fulltree:\n"); - fwalk(p, eprint, 0); - } -#endif - p2tree(p); -#if !defined(MULTIPASS) - send_passt(IP_NODE, p); -#endif -} - -/* - * Send something further on to the next pass. - */ -void -send_passt(int type, ...) -{ - struct interpass *ip; - struct interpass_prolog *ipp; - extern int crslab; - va_list ap; - int sz; - - va_start(ap, type); - if (type == IP_PROLOG || type == IP_EPILOG) - sz = sizeof(struct interpass_prolog); - else - sz = sizeof(struct interpass); - - ip = isinlining ? permalloc(sz) : tmpalloc(sz); - ip->type = type; - ip->lineno = lineno; - switch (type) { - case IP_NODE: - if (lastloc != PROG) - setloc1(PROG); - ip->ip_node = va_arg(ap, NODE *); - break; - case IP_EPILOG: - case IP_PROLOG: - setloc1(PROG); - ipp = (struct interpass_prolog *)ip; - ipp->ipp_regs = va_arg(ap, int); - ipp->ipp_autos = va_arg(ap, int); - ipp->ipp_name = va_arg(ap, char *); - 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_lblnum = crslab; - if (type == IP_PROLOG) - ipp->ip_lblnum--; - break; - case IP_DEFLAB: - ip->ip_lbl = va_arg(ap, int); - break; - case IP_ASM: - if (blevel == 0) { /* outside function */ - printf("\t%s\n", va_arg(ap, char *)); - va_end(ap); - lastloc = -1; - return; - } - ip->ip_asm = va_arg(ap, char *); - break; - default: - cerror("bad send_passt type %d", type); - } - va_end(ap); - if (isinlining) - inline_addarg(ip); - else - pass2_compile(ip); - if (type == IP_EPILOG) - lastloc = PROG; -} - -char * -copst(int op) -{ - if (op <= MAXOP) - return opst[op]; -#define SNAM(x,y) case x: return #y; - switch (op) { - SNAM(QUALIFIER,QUALIFIER) - SNAM(CLASS,CLASS) - SNAM(RB,]) - SNAM(DOT,.) - SNAM(ELLIPSIS,...) - SNAM(LB,[) - SNAM(TYPE,TYPE) - SNAM(COMOP,COMOP) - SNAM(QUEST,?) - SNAM(COLON,:) - SNAM(ANDAND,&&) - SNAM(OROR,||) - SNAM(NOT,!) - SNAM(CAST,CAST) - SNAM(PLUSEQ,+=) - SNAM(MINUSEQ,-=) - SNAM(MULEQ,*=) - SNAM(DIVEQ,/=) - SNAM(MODEQ,%=) - SNAM(ANDEQ,&=) - SNAM(OREQ,|=) - SNAM(EREQ,^=) - SNAM(LSEQ,<<=) - SNAM(RSEQ,>>=) - SNAM(INCR,++) - SNAM(DECR,--) - default: - cerror("bad copst %d", op); - } - return 0; /* XXX gcc */ -} - -int -cdope(int op) -{ - if (op <= MAXOP) - return dope[op]; - switch (op) { - case QUALIFIER: - case CLASS: - case RB: - case DOT: - case ELLIPSIS: - case TYPE: - return LTYPE; - case COMOP: - case QUEST: - case COLON: - case LB: - return BITYPE; - case ANDAND: - case OROR: - return BITYPE|LOGFLG; - case NOT: - return UTYPE|LOGFLG; - case CAST: - return BITYPE|ASGFLG|ASGOPFLG; - case PLUSEQ: - return BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG; - case MINUSEQ: - return BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG; - case MULEQ: - return BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG; - case OREQ: - case EREQ: - case ANDEQ: - return BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG; - case DIVEQ: - return BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG; - case MODEQ: - return BITYPE|DIVFLG|ASGFLG|ASGOPFLG; - case LSEQ: - case RSEQ: - return BITYPE|SHFFLG|ASGFLG|ASGOPFLG; - case INCR: - case DECR: - return BITYPE|ASGFLG; - } - return 0; /* XXX gcc */ -} - -/* - * make a fresh copy of p - */ -NODE * -ccopy(NODE *p) -{ - NODE *q; - - q = talloc(); - *q = *p; - - switch (coptype(q->n_op)) { - case BITYPE: - q->n_right = ccopy(p->n_right); - case UTYPE: - q->n_left = ccopy(p->n_left); - } - - return(q); -} - -/* - * set PROG-seg label. - */ -void -plabel(int label) -{ - setloc1(PROG); - reached = 1; /* Will this always be correct? */ - send_passt(IP_DEFLAB, label); -} diff --git a/usr.bin/pcc/cc/ccom/vax/Makefile b/usr.bin/pcc/cc/ccom/vax/Makefile deleted file mode 100644 index 5b10f3f479d..00000000000 --- a/usr.bin/pcc/cc/ccom/vax/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -TARGMACH= vax - -.include <bsd.prog.mk> diff --git a/usr.bin/pcc/cc/ccom/x86/Makefile b/usr.bin/pcc/cc/ccom/x86/Makefile deleted file mode 100644 index 2049d325ec4..00000000000 --- a/usr.bin/pcc/cc/ccom/x86/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -TARGMACH= x86 - -.include <bsd.prog.mk> diff --git a/usr.bin/pcc/cc/cpp/Makefile b/usr.bin/pcc/cc/cpp/Makefile deleted file mode 100644 index 467d45f1408..00000000000 --- a/usr.bin/pcc/cc/cpp/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# $OpenBSD: Makefile,v 1.4 2007/09/18 21:06:43 todd Exp $ -# -# Makefile for the cpp part of pcc. -# -PROG= cpp -PREFIX= /usr/local -BINDIR= ${PREFIX}/libexec -MANDIR= ${PREFIX}/man/man -TARGOS= openbsd - -CFLAGS+= -DCPP_DEBUG -Wall -Wmissing-prototypes -Wstrict-prototypes -Werror -CFLAGS+= -DLIBEXECDIR=\"${PREFIX}/libexec\" -CPPFLAGS+= -I. -I${.CURDIR} - -SRCS=cpy.y scanner.l cpp.c - -.include <bsd.prog.mk> diff --git a/usr.bin/pcc/cc/cpp/cpp.1 b/usr.bin/pcc/cc/cpp/cpp.1 deleted file mode 100644 index 9aae1daef42..00000000000 --- a/usr.bin/pcc/cc/cpp/cpp.1 +++ /dev/null @@ -1,194 +0,0 @@ -.\" $Id: cpp.1,v 1.4 2007/10/03 08:05:04 otto Exp $ -.\" $NetBSD$ -.\" $OpenBSD: cpp.1,v 1.4 2007/10/03 08:05:04 otto 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 -.\" 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 -.\" THIS SOFTWARE. -.\" -.Dd September 17, 2007 -.Dt cpp 1 -.Os -.Sh NAME -.Nm cpp -.Nd C preprocessor -.Sh SYNOPSIS -.Nm -.\" TODO also document -Dvar and below without spaces? -.Op Fl CdMt -.Op Fl D Ar macro[=value] -.Op Fl I Ar path -.Op Fl i Ar file -.Op Fl S Ar path -.Op Fl U Ar macro -.Op Ar infile | - -.Op Ar outfile -.Pp -.Sh DESCRIPTION -The -.Nm -utility is a macro preprocessor used by the -.Xr pcc 1 -compiler. -It is used to include header files, -expand macro definitions, -and perform conditional compilation. -.Pp -The -.Ar infile -input file is optional. -If not provided or the file name is -.Qq - -(dash), -.Nm -reads its initial file from standard input. -The -.Ar outfile -output file is also optional. -It writes by default to standard output. -.Pp -.\" TODO: document MAXARG 250 args to a macro, limited by char value -.\" TODO: Include order: -.\" For "..." files, first search "current" dir, then as <...> files. -.\" For <...> files, first search -I directories, then system directories. -.\" -The options are as follows: -.Bl -tag -width Ds -.It Fl C -Do not discard comments. -.It Fl D Ar macro[=value] -Fake a definition at the beginning by using -.Do #define -.Ar macro=value Dc . -If -.Ar value -is not set on command-line, then defines as 1. -.\" TODO: show example -.It Fl dM -Print list of -.Dq #define -statements to standard output for all defined macros other than -builtin macros (see below). -The normal results of preprocessing are not outputted. -.\" TODO this doesn't show predefined macros -.\" other -d options are ignored -.It Fl I Ar path -Add -.Ar path -to the list of directories containing needed header files. -This may be used to override system include directories -(see -.Fl S -option). -.Fl I -may be specified multiple times. -.It Fl i Ar file -Include a file at the beginning by using -.Do #include -.Ar file Dc . -.\" Note: I did not use the .In macro above -.It Fl M -Generate dependencies for -.Xr make 1 . -.\" TODO: explain and show example? -.It Fl S Ar path -Add -.Ar path -to the list of system directories containing needed header files. -.Fl S -may be specified multiple times. -Note: -.Nm -does not have a default include directory defined. -.\" TODO: explain difference between -I and -S -.\" The directories listed by -I are searched first? -.It Fl t -Traditional cpp syntax. -Do not define the -.Dv __TIME__ , -.Dv __DATE__ , -and -.Dv __STDC__ -macros. -.\" -.It Fl U Ar macro -Undefine a macro at the beginning by using -.Do #undef -.Ar macro Dc . -.It Fl v -Display version. -.It Fl V -Verbose debugging output. -.Fl V -can be repeated for further details. -.\" -V only available if cpp source built with CPP_DEBUG, which is the default. -.It Fl ? -Show command line usage for -.Nm . -.El -.Sh Builtin Macros -A few macros are interpreted inside the -.Nm cpp -program: -.Bl -diag -.It __DATE__ -Expands to the date in abbreviated month, day, and year format from -.Xr ctime 3 -in quotes. -.\" TODO: is that ctime(3) format output change according to locale? -.It __FILE__ -Expands to the name of the current input file in quotes. -When read from standard input, it expands to -.Qq Ao stdin Ac . -.It __LINE__ -Expands to the line number of the current line containing the macro. -.It __STDC__ -Expands to the constant 1. -This means the compiler conforms to ISO Standard C. -.It __TIME__ -Expands to the time in hour, minutes, and seconds from -.Xr ctime 3 -in quotes. -.El -.Pp -Also see the -.Fl t -option. -.Sh EXIT STATUS -The -.Nm -utility exits with one of the following values: -.Bl -tag -width Ds -.It 0 -Successfully finished. -.It 1 -An error occurred. -.El -.Sh SEE ALSO -.Xr as 1 , -.Xr ccom 1 , -.Xr pcc 1 -.\" -.Sh HISTORY -The -.Nm -command comes from the original Portable C Compiler by S. C. -Johnson, written in the late 70's. -The code originates from the V6 preprocessor with some additions -from V7 cpp and ansi/c99 support. -.Pp -A lot of the PCC code was rewritten by Anders Magnusson. -.Pp -This product includes software developed or owned by Caldera -International, Inc. diff --git a/usr.bin/pcc/cc/cpp/cpp.c b/usr.bin/pcc/cc/cpp/cpp.c deleted file mode 100644 index 8c05e3eb502..00000000000 --- a/usr.bin/pcc/cc/cpp/cpp.c +++ /dev/null @@ -1,1482 +0,0 @@ -/* $OpenBSD: cpp.c,v 1.10 2007/09/26 12:46:47 otto Exp $ */ - -/* - * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code and documentation must retain the above - * copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of other - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * The C preprocessor. - * This code originates from the V6 preprocessor with some additions - * from V7 cpp, and at last ansi/c99 support. - */ - -#include "../../config.h" - -#include <sys/wait.h> - -#include <fcntl.h> -#include <unistd.h> -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <ctype.h> - -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#endif - -#include "cpp.h" -#include "y.tab.h" - -#define MAXARG 250 /* # of args to a macro, limited by char value */ -#define SBSIZE 600000 - -static usch sbf[SBSIZE]; -/* C command */ - -int tflag; /* traditional cpp syntax */ -#ifdef CPP_DEBUG -int dflag; /* debug printouts */ -#define DPRINT(x) if (dflag) printf x -#define DDPRINT(x) if (dflag > 1) printf x -#else -#define DPRINT(x) -#define DDPRINT(x) -#endif - -int ofd; -usch outbuf[CPPBUF]; -int obufp, istty; -int Cflag, Mflag, dMflag; -usch *Mfile; -struct initar *initar; - -/* avoid recursion */ -struct recur { - struct recur *next; - struct symtab *sp; -}; - -/* include dirs */ -struct incs { - struct incs *next; - usch *dir; -} *incdir[2]; -#define INCINC 0 -#define SYSINC 1 - -static struct symtab *filloc; -static struct symtab *linloc; -static struct symtab *pragloc; -int trulvl; -int flslvl; -int elflvl; -int elslvl; -usch *stringbuf = sbf; - -/* - * Macro replacement list syntax: - * - For object-type macros, replacement strings are stored as-is. - * - For function-type macros, macro args are substituted for the - * character WARN followed by the argument number. - * - The value element points to the end of the string, to simplify - * pushback onto the input queue. - * - * The first character (from the end) in the replacement list is - * the number of arguments: - * VARG - ends with ellipsis, next char is argcount without ellips. - * OBJCT - object-type macro - * 0 - empty parenthesis, foo() - * 1-> - number of args. - */ - -#define VARG 0xfe /* has varargs */ -#define OBJCT 0xff -#define WARN 1 /* SOH, not legal char */ -#define CONC 2 /* STX, not legal char */ -#define SNUFF 3 /* ETX, not legal char */ -#define NOEXP 4 /* EOT, not legal char */ -#define EXPAND 5 /* ENQ, not legal char */ - -/* args for lookup() */ -#define FIND 0 -#define ENTER 1 - -static void expdef(usch *proto, struct recur *, int gotwarn); -void define(void); -static int canexpand(struct recur *, struct symtab *np); -void include(void); -void line(void); -void flbuf(void); -void usage(void); - -int -main(int argc, char **argv) -{ - struct initar *it; - struct incs *w, *w2; - struct symtab *nl; - register int ch; - - while ((ch = getopt(argc, argv, "CD:I:MS:U:d:i:tvV")) != -1) - switch (ch) { - case 'C': /* Do not discard comments */ - Cflag++; - break; - - case 'i': /* include */ - case 'U': /* undef */ - case 'D': /* define something */ - /* XXX should not need malloc() here */ - if ((it = malloc(sizeof(struct initar))) == NULL) - error("couldn't apply -%c %s", ch, optarg); - it->type = ch; - it->str = optarg; - it->next = initar; - initar = it; - break; - - case 'M': /* Generate dependencies for make */ - Mflag++; - break; - - case 'S': - case 'I': - if ((w = calloc(sizeof(struct incs), 1)) == NULL) - error("couldn't apply -%c %s", ch, optarg); - w->dir = (usch *)optarg; - w2 = incdir[ch == 'I' ? INCINC : SYSINC]; - if (w2 != NULL) { - while (w2->next) - w2 = w2->next; - w2->next = w; - } else - incdir[ch == 'I' ? INCINC : SYSINC] = w; - break; - -#ifdef CPP_DEBUG - case 'V': - dflag++; - break; -#endif - case 'v': - printf("cpp: %s\n", VERSSTR); - break; - case 'd': - if (optarg[0] == 'M') { - dMflag = 1; - Mflag = 1; - } - /* ignore others */ - break; - - case 't': - tflag = 1; - break; - - case '?': - usage(); - default: - error("bad arg %c\n", ch); - } - argc -= optind; - argv += optind; - - filloc = lookup((usch *)"__FILE__", ENTER); - linloc = lookup((usch *)"__LINE__", ENTER); - pragloc = lookup((usch *)"_Pragma", ENTER); - filloc->value = linloc->value = (usch *)""; /* Just something */ - pragloc->value = (usch *)""; - - if (tflag == 0) { - time_t t = time(NULL); - usch *n = (usch *)ctime(&t); - - /* - * Manually move in the predefined macros. - */ - nl = lookup((usch *)"__TIME__", ENTER); - savch(0); savch('"'); n[19] = 0; savstr(&n[11]); savch('"'); - savch(OBJCT); - nl->value = stringbuf-1; - - nl = lookup((usch *)"__DATE__", ENTER); - savch(0); savch('"'); n[24] = n[11] = 0; savstr(&n[4]); - savstr(&n[20]); savch('"'); savch(OBJCT); - nl->value = stringbuf-1; - - nl = lookup((usch *)"__STDC__", ENTER); - savch(0); savch('1'); savch(OBJCT); - nl->value = stringbuf-1; - } - - if (Mflag && !dMflag) { - usch *c; - - if (argc < 1) - error("-M and no infile"); - if ((c = (usch *)strrchr(argv[0], '/')) == NULL) - c = (usch *)argv[0]; - else - c++; - Mfile = stringbuf; - savstr(c); savch(0); - if ((c = (usch *)strrchr((char *)Mfile, '.')) == NULL) - error("-M and no extension: "); - c[1] = 'o'; - c[2] = 0; - } - - if (argc == 2) { - if ((ofd = open(argv[1], O_WRONLY|O_CREAT, 0600)) < 0) - error("Can't creat %s", argv[1]); - } else - ofd = 1; /* stdout */ - istty = isatty(ofd); - - if (pushfile((usch *)(argc && strcmp(argv[0], "-") ? argv[0] : NULL))) - error("cannot open %s", argv[0]); - - flbuf(); - close(ofd); - return 0; -} - -/* - * Expand the symbol nl read from input. - * Return a pointer to the fully expanded result. - * It is the responsibility of the caller to reset the heap usage. - */ -usch * -gotident(struct symtab *nl) -{ - struct symtab *thisnl; - usch *osp, *ss2, *base; - int c; - - thisnl = NULL; - slow = 1; - base = osp = stringbuf; - goto found; - - while ((c = yylex()) != 0) { - switch (c) { - case IDENT: - if (flslvl) - break; - osp = stringbuf; - - DPRINT(("IDENT0: %s\n", yytext)); - nl = lookup((usch *)yytext, FIND); - if (nl == 0 || thisnl == 0) - goto found; - if (thisnl == nl) { - nl = 0; - goto found; - } - ss2 = stringbuf; - if ((c = yylex()) == WSPACE) { - savstr((usch *)yytext); - c = yylex(); - } - if (c != EXPAND) { - unpstr((usch *)yytext); - if (ss2 != stringbuf) - unpstr(ss2); - unpstr(nl->namep); - (void)yylex(); /* get yytext correct */ - nl = 0; /* ignore */ - } else { - thisnl = NULL; - if (nl->value[0] == OBJCT) { - unpstr(nl->namep); - (void)yylex(); /* get yytext correct */ - nl = 0; - } - } - stringbuf = ss2; - -found: if (nl == 0 || subst(nl, NULL) == 0) { - if (nl) - savstr(nl->namep); - else - savstr((usch *)yytext); - } else if (osp != stringbuf) { - DPRINT(("IDENT1: unput osp %p stringbuf %p\n", - osp, stringbuf)); - ss2 = stringbuf; - cunput(EXPAND); - while (ss2 > osp) - cunput(*--ss2); - thisnl = nl; - stringbuf = osp; /* clean up heap */ - } - break; - - case EXPAND: - DPRINT(("EXPAND!\n")); - thisnl = NULL; - break; - - case STRING: - case '\n': - case NUMBER: - case FPOINT: - case WSPACE: - savstr((usch *)yytext); - break; - - default: - if (c < 256) - savch(c); - else - savstr((usch *)yytext); - break; - } - if (thisnl == NULL) { - slow = 0; - savch(0); - return base; - } - } - error("preamture EOF"); - /* NOTREACHED */ - return NULL; /* XXX gcc */ -} - -void -line() -{ - static usch *lbuf; - static int llen; - int c; - - slow = 1; - if (yylex() != WSPACE) - goto bad; - if ((c = yylex()) != IDENT || !isdigit((int)yytext[0])) - goto bad; - ifiles->lineno = atoi(yytext); - - if ((c = yylex()) != '\n' && c != WSPACE) - goto bad; - if (c == '\n') { - slow = 0; - return; - } - if (yylex() != STRING) - goto bad; - c = strlen((char *)yytext); - if (llen < c) { - /* XXX may loose heap space */ - lbuf = stringbuf; - stringbuf += c; - llen = c; - } - yytext[strlen(yytext)-1] = 0; - if (strlcpy((char *)lbuf, &yytext[1], SBSIZE) >= SBSIZE) - error("line exceeded buffer size"); - - ifiles->fname = lbuf; - if (yylex() != '\n') - goto bad; - slow = 0; - return; - -bad: error("bad line directive"); -} - -/* - * Include a file. Include order: - * - For <...> files, first search -I directories, then system directories. - * - For "..." files, first search "current" dir, then as <...> files. - */ -void -include() -{ - struct incs *w; - struct symtab *nl; - usch *osp; - usch *fn, *safefn; - int i, c, it; - - if (flslvl) - return; - osp = stringbuf; - slow = 1; -again: - if ((c = yylex()) == WSPACE) - c = yylex(); - if (c != STRING && c != '<' && c != IDENT) - goto bad; - - if (c == IDENT) { - if ((nl = lookup((usch *)yytext, FIND)) == NULL) - goto bad; - if (subst(nl, NULL) == 0) - goto bad; - savch('\0'); - unpstr(osp); - goto again; - } else if (c == '<') { - fn = stringbuf; - while ((c = yylex()) != '>' && c != '\n') { - if (c == '\n') - goto bad; - savstr((usch *)yytext); - } - savch('\0'); - while ((c = yylex()) == WSPACE) - ; - if (c != '\n') - goto bad; - it = SYSINC; - safefn = fn; - } else { - usch *nm = stringbuf; - - yytext[strlen(yytext)-1] = 0; - fn = (usch *)&yytext[1]; - /* first try to open file relative to previous file */ - /* but only if it is not an absolute path */ - if (*fn != '/') { - savstr(ifiles->orgfn); - if ((stringbuf = - (usch *)strrchr((char *)nm, '/')) == NULL) - stringbuf = nm; - else - stringbuf++; - } - safefn = stringbuf; - savstr(fn); savch(0); - while ((c = yylex()) == WSPACE) - ; - if (c != '\n') - goto bad; - slow = 0; - if (pushfile(nm) == 0) - return; - /* XXX may loose stringbuf space */ - } - - /* create search path and try to open file */ - slow = 0; - for (i = 0; i < 2; i++) { - for (w = incdir[i]; w; w = w->next) { - usch *nm = stringbuf; - - savstr(w->dir); savch('/'); - savstr(safefn); savch(0); - if (pushfile(nm) == 0) - return; - stringbuf = nm; - } - } - error("cannot find '%s'", safefn); - /* error() do not return */ - -bad: error("bad include"); - /* error() do not return */ -} - -static int -definp(void) -{ - int c; - - do - c = yylex(); - while (c == WSPACE); - return c; -} - -void -define() -{ - struct symtab *np; - usch *args[MAXARG], *ubuf, *sbeg; - int c, i, redef; - int mkstr = 0, narg = -1; - int ellips = 0; - size_t len; - - if (flslvl) - return; - slow = 1; - if (yylex() != WSPACE || yylex() != IDENT) - goto bad; - - if (isdigit((int)yytext[0])) - goto bad; - - np = lookup((usch *)yytext, ENTER); - redef = np->value != NULL; - - sbeg = stringbuf; - if ((c = yylex()) == '(') { - narg = 0; - /* function-like macros, deal with identifiers */ - for (;;) { - c = definp(); - if (c == ')') - break; - if (c == ELLIPS) { - ellips = 1; - if (definp() != ')') - goto bad; - break; - } - if (c == IDENT) { - len = strlen(yytext); - args[narg] = alloca(len+1); - strlcpy((char *)args[narg], yytext, len+1); - narg++; - if ((c = definp()) == ',') - continue; - if (c == ')') - break; - goto bad; - } - goto bad; - } - c = yylex(); - } else if (c == '\n') { - /* #define foo */ - ; - } else if (c != WSPACE) - goto bad; - - while (c == WSPACE) - c = yylex(); - - /* parse replacement-list, substituting arguments */ - savch('\0'); - while (c != '\n') { - switch (c) { - case WSPACE: - /* remove spaces if it surrounds a ## directive */ - ubuf = stringbuf; - savstr((usch *)yytext); - c = yylex(); - if (c == CONCAT) { - stringbuf = ubuf; - savch(CONC); - if ((c = yylex()) == WSPACE) - c = yylex(); - } - continue; - - case CONCAT: - /* No spaces before concat op */ - savch(CONC); - if ((c = yylex()) == WSPACE) - c = yylex(); - continue; - - case MKSTR: - if (narg < 0) { - /* no meaning in object-type macro */ - savch('#'); - break; - } - /* remove spaces between # and arg */ - savch(SNUFF); - if ((c = yylex()) == WSPACE) - c = yylex(); /* whitespace, ignore */ - mkstr = 1; - if (c == VA_ARGS) - continue; - - /* FALLTHROUGH */ - case IDENT: - if (narg < 0) - goto id; /* just add it if object */ - /* check if its an argument */ - for (i = 0; i < narg; i++) - if (strcmp(yytext, (char *)args[i]) == 0) - break; - if (i == narg) { - if (mkstr) - error("not argument"); - goto id; - } - savch(i); - savch(WARN); - if (mkstr) - savch(SNUFF), mkstr = 0; - break; - - case VA_ARGS: - if (ellips == 0) - error("unwanted %s", yytext); - savch(VARG); - savch(WARN); - if (mkstr) - savch(SNUFF), mkstr = 0; - break; - - default: -id: savstr((usch *)yytext); - break; - } - c = yylex(); - } - /* remove trailing whitespace */ - while (stringbuf > sbeg) { - if (stringbuf[-1] == ' ' || stringbuf[-1] == '\t') - stringbuf--; - else - break; - } - if (ellips) { - savch(narg); - savch(VARG); - } else - savch(narg < 0 ? OBJCT : narg); - if (redef) { - usch *o = np->value, *n = stringbuf-1; - - /* Redefinition to identical replacement-list is allowed */ - while (*o && *o == *n) - o--, n--; - if (*o || *o != *n) - error("%s redefined\nprevious define: %s:%d", - np->namep, np->file, np->line); - stringbuf = sbeg; /* forget this space */ - } else - np->value = stringbuf-1; - -#ifdef CPP_DEBUG - if (dflag) { - usch *w = np->value; - - printf("!define: "); - if (*w == OBJCT) - printf("[object]"); - else if (*w == VARG) - printf("[VARG%d]", *--w); - while (*--w) { - switch (*w) { - case WARN: printf("<%d>", *--w); break; - case CONC: printf("<##>"); break; - case SNUFF: printf("<\">"); break; - default: putchar(*w); break; - } - } - putchar('\n'); - } -#endif - slow = 0; - return; - -bad: error("bad define"); -} - -void -xerror(usch *s) -{ - usch *t; - - flbuf(); - savch(0); - if (ifiles != NULL) { - t = sheap("%s:%d: ", ifiles->fname, ifiles->lineno); - write (2, t, strlen((char *)t)); - } - write (2, s, strlen((char *)s)); - write (2, "\n", 1); - exit(1); -} - -/* - * store a character into the "define" buffer. - */ -void -savch(c) -{ - if (stringbuf-sbf < SBSIZE) { - *stringbuf++ = c; - } else { - stringbuf = sbf; /* need space to write error message */ - error("Too much defining"); - } -} - -/* - * convert _Pragma to #pragma for output. - */ -static void -pragoper(void) -{ - usch *opb; - int t; - - slow = 1; - putstr((usch *)"\n#pragma "); - if ((t = yylex()) == WSPACE) - t = yylex(); - if (t != '(') - goto bad; - if ((t = yylex()) == WSPACE) - t = yylex(); - opb = stringbuf; - while (t != ')') { - savstr((usch *)yytext); - t = yylex(); - } - savch(0); - cunput(WARN); - unpstr(opb); - stringbuf = opb; - expmac(NULL); - while (stringbuf > opb) - cunput(*--stringbuf); - if ((t = yylex()) != STRING) - goto bad; - opb = (usch *)yytext; - if (*opb++ == 'L') - opb++; - while ((t = *opb++) != '\"') { - if (t == '\\' && (*opb == '\"' || *opb == '\\')) - t = *opb++; - putch(t); - } - putch('\n'); - prtline(); - return; -bad: error("bad pragma operator"); -} - -/* - * substitute namep for sp->value. - */ -int -subst(sp, rp) -struct symtab *sp; -struct recur *rp; -{ - struct recur rp2; - register usch *vp, *cp; - int c, rv = 0, ws; - - DPRINT(("subst: %s\n", sp->namep)); - /* - * First check for special macros. - */ - if (sp == filloc) { - (void)sheap("\"%s\"", ifiles->fname); - return 1; - } else if (sp == linloc) { - (void)sheap("%d", ifiles->lineno); - return 1; - } else if (sp == pragloc) { - pragoper(); - return 1; - } - vp = sp->value; - - rp2.next = rp; - rp2.sp = sp; - - if (*vp-- != OBJCT) { - int gotwarn = 0; - - /* should we be here at all? */ - /* check if identifier is followed by parentheses */ - rv = 1; - ws = 0; - do { - c = yylex(); - if (c == WARN) { - gotwarn++; - if (rp == NULL) - goto noid; - } else if (c == WSPACE || c == '\n') - ws = 1; - } while (c == WSPACE || c == '\n' || c == WARN); - - cp = (usch *)yytext; - while (*cp) - cp++; - while (cp > (usch *)yytext) - cunput(*--cp); - DPRINT(("c %d\n", c)); - if (c == '(' ) { - expdef(vp, &rp2, gotwarn); - return rv; - } else { - /* restore identifier */ -noid: while (gotwarn--) - cunput(WARN); - if (ws) - cunput(' '); - cp = sp->namep; - while (*cp) - cp++; - while (cp > sp->namep) - cunput(*--cp); - if ((c = yylex()) != IDENT) - error("internal sync error"); - return 0; - } - } else { - cunput(WARN); - cp = vp; - while (*cp) { - if (*cp != CONC) - cunput(*cp); - cp--; - } - expmac(&rp2); - } - return 1; -} - -/* - * do macro-expansion until WARN character read. - * read from lex buffer and store result on heap. - * will recurse into lookup() for recursive expansion. - * when returning all expansions on the token list is done. - */ -void -expmac(struct recur *rp) -{ - struct symtab *nl; - int c, noexp = 0, orgexp; - usch *och, *stksv; - extern int yyleng; - -#ifdef CPP_DEBUG - if (dflag) { - struct recur *rp2 = rp; - printf("\nexpmac\n"); - while (rp2) { - printf("do not expand %s\n", rp->sp->namep); - rp2 = rp2->next; - } - } -#endif - while ((c = yylex()) != WARN) { - switch (c) { - case NOEXP: noexp++; break; - case EXPAND: noexp--; break; - - case IDENT: - /* - * Handle argument concatenation here. - * If an identifier is found and directly - * after EXPAND or NOEXP then push the - * identifier back on the input stream and - * call yylex() again. - * Be careful to keep the noexp balance. - */ - och = stringbuf; - savstr((usch *)yytext); - DDPRINT(("id: str %s\n", och)); - - orgexp = 0; - while ((c = yylex()) == EXPAND || c == NOEXP) - if (c == EXPAND) - orgexp--; - else - orgexp++; - - DDPRINT(("id1: noexp %d orgexp %d\n", noexp, orgexp)); - if (c == IDENT) { /* XXX numbers? */ - DDPRINT(("id2: str %s\n", yytext)); - /* OK to always expand here? */ - savstr((usch *)yytext); - switch (orgexp) { - case 0: /* been EXP+NOEXP */ - if (noexp == 0) - break; - if (noexp != 1) - error("case 0"); - cunput(NOEXP); - noexp = 0; - break; - case -1: /* been EXP */ - if (noexp != 1) - error("case -1"); - noexp = 0; - break; - case 1: - if (noexp != 0) - error("case 1"); - cunput(NOEXP); - break; - default: - error("orgexp = %d", orgexp); - } - unpstr(och); - stringbuf = och; - continue; /* New longer identifier */ - } - unpstr((usch *)yytext); - if (orgexp == -1) - cunput(EXPAND); - else if (orgexp == 1) - cunput(NOEXP); - unpstr(och); - stringbuf = och; - - - yylex(); /* XXX reget last identifier */ - - if ((nl = lookup((usch *)yytext, FIND)) == NULL) - goto def; - - if (canexpand(rp, nl) == 0) - goto def; - /* - * If noexp == 0 then expansion of any macro is - * allowed. If noexp == 1 then expansion of a - * fun-like macro is allowed iff there is an - * EXPAND between the identifier and the '('. - */ - if (noexp == 0) { - if ((c = subst(nl, rp)) == 0) - goto def; - break; - } -//printf("noexp1 %d nl->namep %s\n", noexp, nl->namep); -//if (noexp > 1) goto def; - if (noexp != 1) - error("bad noexp %d", noexp); - stksv = NULL; - if ((c = yylex()) == WSPACE) { - stksv = alloca(yyleng+1); - strlcpy((char *)stksv, yytext, yyleng+1); - c = yylex(); - } - /* only valid for expansion if fun macro */ - if (c == EXPAND && *nl->value != OBJCT) { - noexp--; - if (subst(nl, rp)) - break; - savstr(nl->namep); - if (stksv) - savstr(stksv); - } else { - unpstr((usch *)yytext); - if (stksv) - unpstr(stksv); - savstr(nl->namep); - } - break; - - case STRING: - /* remove EXPAND/NOEXP from strings */ - if (yytext[1] == NOEXP) { - savch('"'); - och = (usch *)&yytext[2]; - while (*och != EXPAND) - savch(*och++); - savch('"'); - break; - } - /* FALLTHROUGH */ - -def: default: - savstr((usch *)yytext); - break; - } - } - if (noexp) - error("expmac noexp=%d", noexp); - DPRINT(("return from expmac\n")); -} - -/* - * expand a function-like macro. - * vp points to end of replacement-list - * reads function arguments from yylex() - * result is written on top of heap - */ -void -expdef(vp, rp, gotwarn) - usch *vp; - struct recur *rp; -{ - usch **args, *sptr, *ap, *bp, *sp; - int narg, c, i, plev, snuff, instr; - int ellips = 0; - - DPRINT(("expdef %s rp %s\n", vp, (rp ? (char *)rp->sp->namep : ""))); - if ((c = yylex()) != '(') - error("got %c, expected )", c); - if (vp[1] == VARG) { - narg = *vp--; - ellips = 1; - } else - narg = vp[1]; - args = alloca(sizeof(usch *) * (narg+ellips)); - - /* - * read arguments and store them on heap. - * will be removed just before return from this function. - */ - sptr = stringbuf; - for (i = 0; i < narg && c != ')'; i++) { - args[i] = stringbuf; - plev = 0; - while ((c = yylex()) == WSPACE || c == '\n') - ; - for (;;) { - if (plev == 0 && (c == ')' || c == ',')) - break; - if (c == '(') - plev++; - if (c == ')') - plev--; - savstr((usch *)yytext); - while ((c = yylex()) == '\n') - savch('\n'); - } - while (args[i] < stringbuf && - (stringbuf[-1] == ' ' || stringbuf[-1] == '\t')) - stringbuf--; - savch('\0'); - } - if (ellips) - args[i] = (usch *)""; - if (ellips && c != ')') { - args[i] = stringbuf; - plev = 0; - while ((c = yylex()) == WSPACE) - ; - for (;;) { - if (plev == 0 && c == ')') - break; - if (c == '(') - plev++; - if (c == ')') - plev--; - savstr((usch *)yytext); - while ((c = yylex()) == '\n') - savch('\n'); - } - while (args[i] < stringbuf && - (stringbuf[-1] == ' ' || stringbuf[-1] == '\t')) - stringbuf--; - savch('\0'); - - } - if (narg == 0 && ellips == 0) - c = yylex(); - if (c != ')' || (i != narg && ellips == 0) || (i < narg && ellips == 1)) - error("wrong arg count"); - - while (gotwarn--) - cunput(WARN); - - sp = vp; - instr = snuff = 0; - - /* - * push-back replacement-list onto lex buffer while replacing - * arguments. - */ - cunput(WARN); - while (*sp != 0) { - if (*sp == SNUFF) - cunput('\"'), snuff ^= 1; - else if (*sp == CONC) - ; - else if (*sp == WARN) { - - if (sp[-1] == VARG) { - bp = ap = args[narg]; - sp--; - } else - bp = ap = args[(int)*--sp]; - if (sp[2] != CONC && !snuff && sp[-1] != CONC) { - cunput(WARN); - while (*bp) - bp++; - while (bp > ap) - cunput(*--bp); - DPRINT(("expand arg %d string %s\n", *sp, ap)); - bp = ap = stringbuf; - savch(NOEXP); - expmac(NULL); - savch(EXPAND); - savch('\0'); - } - while (*bp) - bp++; - while (bp > ap) { - bp--; - if (snuff && !instr && - (*bp == ' ' || *bp == '\t' || *bp == '\n')){ - while (*bp == ' ' || *bp == '\t' || - *bp == '\n') { - bp--; - } - cunput(' '); - } - cunput(*bp); - if ((*bp == '\'' || *bp == '"') - && bp[-1] != '\\' && snuff) { - instr ^= 1; - if (instr == 0 && *bp == '"') - cunput('\\'); - } - if (instr && (*bp == '\\' || *bp == '"')) - cunput('\\'); - } - } else - cunput(*sp); - sp--; - } - stringbuf = sptr; - - /* scan the input buffer (until WARN) and save result on heap */ - expmac(rp); -} - -usch * -savstr(usch *str) -{ - usch *rv = stringbuf; - - do { - if (stringbuf >= &sbf[SBSIZE]) { - stringbuf = sbf; /* need space to write error message */ - error("out of macro space!"); - } - } while ((*stringbuf++ = *str++)); - stringbuf--; - return rv; -} - -int -canexpand(struct recur *rp, struct symtab *np) -{ - struct recur *w; - - for (w = rp; w && w->sp != np; w = w->next) - ; - if (w != NULL) - return 0; - return 1; -} - -void -unpstr(usch *c) -{ - usch *d = c; - - while (*d) - d++; - while (d > c) { - cunput(*--d); - } -} - -void -flbuf() -{ - if (obufp == 0) - return; - if (Mflag == 0 && write(ofd, outbuf, obufp) < 0) - error("obuf write error"); - obufp = 0; -} - -void -putch(int ch) -{ - outbuf[obufp++] = ch; - if (obufp == CPPBUF || (istty && ch == '\n')) - flbuf(); -} - -void -putstr(usch *s) -{ - for (; *s; s++) { - outbuf[obufp++] = *s; - if (obufp == CPPBUF || (istty && *s == '\n')) - flbuf(); - } -} - -/* - * convert a number to an ascii string. Store it on the heap. - */ -static void -num2str(int num) -{ - static usch buf[12]; - usch *b = buf; - int m = 0; - - if (num < 0) - num = -num, m = 1; - do { - *b++ = num % 10 + '0', num /= 10; - } while (num); - if (m) - *b++ = '-'; - while (b > buf) - savch(*--b); -} - -/* - * similar to sprintf, but only handles %s and %d. - * saves result on heap. - */ -usch * -sheap(char *fmt, ...) -{ - va_list ap; - usch *op = stringbuf; - - va_start(ap, fmt); - for (; *fmt; fmt++) { - if (*fmt == '%') { - fmt++; - switch (*fmt) { - case 's': - savstr(va_arg(ap, usch *)); - break; - case 'd': - num2str(va_arg(ap, int)); - break; - case 'c': - savch(va_arg(ap, int)); - break; - default: - break; /* cannot call error() here */ - } - } else - savch(*fmt); - } - va_end(ap); - *stringbuf = 0; - return op; -} - -void -usage() -{ - error("Usage: cpp [-Cdt] [-Dvar=val] [-Uvar] [-Ipath] [-Spath]"); -} - -#ifdef notyet -/* - * Symbol table stuff. - * The data structure used is a patricia tree implementation using only - * bytes to store offsets. - * The information stored is (lower address to higher): - * - * unsigned char bitno[2]; bit number in the string - * unsigned char left[3]; offset from base to left element - * unsigned char right[3]; offset from base to right element - */ -#endif - -/* - * This patricia implementation is more-or-less the same as - * used in ccom for string matching. - */ -struct tree { - int bitno; - struct tree *lr[2]; -}; - -#define BITNO(x) ((x) & ~(LEFT_IS_LEAF|RIGHT_IS_LEAF)) -#define LEFT_IS_LEAF 0x80000000 -#define RIGHT_IS_LEAF 0x40000000 -#define IS_LEFT_LEAF(x) (((x) & LEFT_IS_LEAF) != 0) -#define IS_RIGHT_LEAF(x) (((x) & RIGHT_IS_LEAF) != 0) -#define P_BIT(key, bit) (key[bit >> 3] >> (bit & 7)) & 1 -#define CHECKBITS 8 - -static struct tree *sympole; -static int numsyms; - -/* - * Allocate a symtab struct and store the string. - */ -static struct symtab * -getsymtab(usch *str) -{ - struct symtab *sp = malloc(sizeof(struct symtab)); - - if (sp == NULL) - error("getsymtab: couldn't allocate symtab"); - sp->namep = savstr(str); - savch('\0'); - sp->value = NULL; - sp->file = ifiles ? ifiles->orgfn : (usch *)"<initial>"; - sp->line = ifiles ? ifiles->lineno : 0; - return sp; -} - -/* - * Do symbol lookup in a patricia tree. - * Only do full string matching, no pointer optimisations. - */ -struct symtab * -lookup(usch *key, int enterf) -{ - struct symtab *sp; - struct tree *w, *new, *last; - int len, cix, bit, fbit, svbit, ix, bitno; - usch *k, *m, *sm; - - /* Count full string length */ - for (k = key, len = 0; *k; k++, len++) - ; - - switch (numsyms) { - case 0: /* no symbols yet */ - if (enterf != ENTER) - return NULL; - sympole = (struct tree *)getsymtab(key); - numsyms++; - return (struct symtab *)sympole; - - case 1: - w = sympole; - svbit = 0; /* XXX gcc */ - break; - - default: - w = sympole; - bitno = len * CHECKBITS; - for (;;) { - bit = BITNO(w->bitno); - fbit = bit > bitno ? 0 : P_BIT(key, bit); - svbit = fbit ? IS_RIGHT_LEAF(w->bitno) : - IS_LEFT_LEAF(w->bitno); - w = w->lr[fbit]; - if (svbit) - break; - } - } - - sp = (struct symtab *)w; - - sm = m = sp->namep; - k = key; - - /* Check for correct string and return */ - for (cix = 0; *m && *k && *m == *k; m++, k++, cix += CHECKBITS) - ; - if (*m == 0 && *k == 0) { - if (enterf != ENTER && sp->value == NULL) - return NULL; - return sp; - } - - if (enterf != ENTER) - return NULL; /* no string found and do not enter */ - - ix = *m ^ *k; - while ((ix & 1) == 0) - ix >>= 1, cix++; - - /* Create new node */ - if ((new = malloc(sizeof *new)) == NULL) - error("getree: couldn't allocate tree"); - bit = P_BIT(key, cix); - new->bitno = cix | (bit ? RIGHT_IS_LEAF : LEFT_IS_LEAF); - new->lr[bit] = (struct tree *)getsymtab(key); - - if (numsyms++ == 1) { - new->lr[!bit] = sympole; - new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF); - sympole = new; - return (struct symtab *)new->lr[bit]; - } - - w = sympole; - last = NULL; - for (;;) { - fbit = w->bitno; - bitno = BITNO(w->bitno); - if (bitno == cix) - error("bitno == cix"); - if (bitno > cix) - break; - svbit = P_BIT(key, bitno); - last = w; - w = w->lr[svbit]; - if (fbit & (svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF)) - break; - } - - new->lr[!bit] = w; - if (last == NULL) { - sympole = new; - } else { - last->lr[svbit] = new; - last->bitno &= ~(svbit ? RIGHT_IS_LEAF : LEFT_IS_LEAF); - } - if (bitno < cix) - new->bitno |= (bit ? LEFT_IS_LEAF : RIGHT_IS_LEAF); - return (struct symtab *)new->lr[bit]; -} - diff --git a/usr.bin/pcc/cc/cpp/cpp.h b/usr.bin/pcc/cc/cpp/cpp.h deleted file mode 100644 index 7b5aa6acb25..00000000000 --- a/usr.bin/pcc/cc/cpp/cpp.h +++ /dev/null @@ -1,120 +0,0 @@ -/* $OpenBSD: cpp.h,v 1.4 2007/09/18 07:16:01 otto Exp $ */ - -/* - * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdio.h> /* for obuf */ - -#include "../../config.h" - -typedef unsigned char usch; -#ifdef YYTEXT_POINTER -extern char *yytext; -#else -extern char yytext[]; -#endif -extern usch *stringbuf; - -extern int trulvl; -extern int flslvl; -extern int elflvl; -extern int elslvl; -extern int tflag, Cflag; -extern int Mflag, dMflag; -extern usch *Mfile; -extern int ofd; - -/* args for lookup() */ -#define FIND 0 -#define ENTER 1 - -/* buffer used internally */ -#ifndef CPPBUF -#ifdef __pdp11__ -#define CPPBUF BUFSIZ -#else -#define CPPBUF 65536 -#endif -#endif - -#define NAMEMAX 64 /* max len of identifier */ - -/* definition for include file info */ -struct includ { - struct includ *next; - usch *fname; /* current fn, changed if #line found */ - usch *orgfn; /* current fn, not changed */ - int lineno; - int infil; - usch *curptr; - usch *maxread; - usch *buffer; - usch bbuf[NAMEMAX+CPPBUF+1]; -} *ifiles; - -/* Symbol table entry */ -struct symtab { - usch *namep; - usch *value; - usch *file; - int line; -}; - -struct initar { - struct initar *next; - int type; - char *str; -}; - -struct recur; /* not used outside cpp.c */ -int subst(struct symtab *, struct recur *); -struct symtab *lookup(usch *namep, int enterf); -usch *gotident(struct symtab *nl); -int slow; /* scan slowly for new tokens */ - -int pushfile(usch *fname); -void popfile(void); -void prtline(void); -int yylex(void); -void cunput(int); -int curline(void); -char *curfile(void); -void setline(int); -void setfile(char *); -int yyparse(void); -void yyerror(char *); -void unpstr(usch *); -usch *savstr(usch *str); -void savch(int c); -void mainscan(void); -void putch(int); -void putstr(usch *s); -void line(void); -usch *sheap(char *fmt, ...); -void xerror(usch *); -#define error(...) xerror(sheap(__VA_ARGS__)) -void expmac(struct recur *); diff --git a/usr.bin/pcc/cc/cpp/cpy.y b/usr.bin/pcc/cc/cpp/cpy.y deleted file mode 100644 index 6de8a694a12..00000000000 --- a/usr.bin/pcc/cc/cpp/cpy.y +++ /dev/null @@ -1,166 +0,0 @@ -/* $OpenBSD: cpy.y,v 1.2 2007/09/15 22:04:39 ray Exp $ */ - -/* - * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code and documentation must retain the above - * copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed or owned by Caldera - * International, Inc. - * Neither the name of Caldera International, Inc. nor the names of other - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA - * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -%{ -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -void yyerror(char *); -int yylex(void); -%} - -%term stop -%term EQ NE LE GE LS RS -%term ANDAND OROR IDENT NUMBER -/* - * The following terminals are not used in the yacc code. - */ -%term STRING FPOINT WSPACE VA_ARGS CONCAT MKSTR ELLIPS - -%left ',' -%right '=' -%right '?' ':' -%left OROR -%left ANDAND -%left '|' '^' -%left '&' -%binary EQ NE -%binary '<' '>' LE GE -%left LS RS -%left '+' '-' -%left '*' '/' '%' -%right '!' '~' UMINUS -%left '(' '.' - -%union { - long long val; -} - -%type <val> term NUMBER e - -%% -S: e '\n' { return($1 != 0);} - - -e: e '*' e - {$$ = $1 * $3;} - | e '/' e - {$$ = $1 / $3;} - | e '%' e - {$$ = $1 % $3;} - | e '+' e - {$$ = $1 + $3;} - | e '-' e - {$$ = $1 - $3;} - | e LS e - {$$ = $1 << $3;} - | e RS e - {$$ = $1 >> $3;} - | e '<' e - {$$ = $1 < $3;} - | e '>' e - {$$ = $1 > $3;} - | e LE e - {$$ = $1 <= $3;} - | e GE e - {$$ = $1 >= $3;} - | e EQ e - {$$ = $1 == $3;} - | e NE e - {$$ = $1 != $3;} - | e '&' e - {$$ = $1 & $3;} - | e '^' e - {$$ = $1 ^ $3;} - | e '|' e - {$$ = $1 | $3;} - | e ANDAND e - {$$ = $1 && $3;} - | e OROR e - {$$ = $1 || $3;} - | e '?' e ':' e - {$$ = $1 ? $3 : $5;} - | e ',' e - {$$ = $3;} - | term - {$$ = $1;} -term: - '-' term %prec UMINUS - {$$ = -$2;} - | '!' term - {$$ = !$2;} - | '~' term - {$$ = ~$2;} - | '(' e ')' - {$$ = $2;} - | NUMBER - {$$= $1;} -%% - -#include "cpp.h" - -void -yyerror(char *err) -{ - error(err); -} diff --git a/usr.bin/pcc/cc/cpp/scanner.l b/usr.bin/pcc/cc/cpp/scanner.l deleted file mode 100644 index 94656769f3c..00000000000 --- a/usr.bin/pcc/cc/cpp/scanner.l +++ /dev/null @@ -1,817 +0,0 @@ -%{ -/* $OpenBSD: scanner.l,v 1.9 2007/10/07 07:58:51 ragge Exp $ */ - -/* - * Copyright (c) 2004 Anders Magnusson. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include <fcntl.h> - -#include "cpp.h" -#include "y.tab.h" -%} - -%{ -static long long cvtdig(int rad); -static int charcon(void); -static void elsestmt(void); -static void ifdefstmt(void); -static void ifndefstmt(void); -static void endifstmt(void); -static void ifstmt(void); -static void cpperror(void); -static void pragmastmt(void); -static void undefstmt(void); -static void cpperror(void); -static void elifstmt(void); -//static void linestmt(void); -static void storepb(void); -void include(void); -void define(void); - -extern int yyget_lineno (void); -extern void yyset_lineno (int); - -static int inch(void); - -static int scale, gotdef, contr; -int inif; - -#ifdef FLEX_SCANNER /* should be set by autoconf instead */ -static int -yyinput(char *b, int m) -{ - int c, i; - - for (i = 0; i < m; i++) { - if ((c = inch()) < 0) - break; - *b++ = c; - if (c == '\n') { - i++; - break; - } - } - return i; -} -#undef YY_INPUT -#undef YY_BUF_SIZE -#define YY_BUF_SIZE 32768 -#define YY_INPUT(b,r,m) (r = yyinput(b, m)) -#define fprintf(x, ...) error(__VA_ARGS__) -#define ECHO putstr((usch *)yytext) -#undef fileno -#define fileno(x) 0 - -#if YY_FLEX_SUBMINOR_VERSION >= 31 -/* Hack to avoid unneccessary warnings */ -FILE *yyget_in (void); -FILE *yyget_out (void); -int yyget_leng (void); -char *yyget_text (void); -void yyset_in (FILE * in_str ); -void yyset_out (FILE * out_str ); -int yyget_debug (void); -void yyset_debug (int bdebug ); -int yylex_destroy (void); -#endif -#else /* Assume lex here */ -#undef input -#undef unput -#define input() inch() -#define unput(ch) unch(ch) -#endif -#define PRTOUT(x) if (YYSTATE || slow) return x; if (!flslvl) putstr((usch *)yytext); -%} - -D [0-9] -L [a-zA-Z_] -H [a-fA-F0-9] -E [Ee][+-]?{D}+ -FS (f|F|l|L) -IS (u|U|l|L)* -WS [\t ] - -%s IFR CONTR DEF - -%% - -"\n" { int os = YYSTATE; - if (os != IFR) - BEGIN 0; - ifiles->lineno++; - if (flslvl == 0) { - if (ifiles->lineno == 1) - prtline(); - else - putch('\n'); - } - if ((os != 0 || slow) && !contr) - return '\n'; - contr = 0; - } - -"\r" { ; /* Ignore CR's */ } - -<IFR>"==" { return EQ; } -<IFR>"!=" { return NE; } -<IFR>"<=" { return LE; } -<IFR>"<<" { return LS; } -<IFR>">>" { return RS; } -<IFR>">=" { return GE; } -<IFR>"||" { return OROR; } -<IFR>"&&" { return ANDAND; } -<IFR>"defined" { int p, c; - gotdef = 1; - if ((p = c = yylex()) == '(') - c = yylex(); - if (c != IDENT || (p != IDENT && p != '(')) - error("syntax error"); - if (p == '(' && yylex() != ')') - error("syntax error"); - return NUMBER; - } - -<IFR>{WS}+ { ; } -<IFR>{L}({L}|{D})* { - if (gotdef) { - yylval.val = - lookup((usch *)yytext, FIND) != 0; - gotdef = 0; - return IDENT; - } - yylval.val = 0; - return NUMBER; - } - -[1-9][0-9]* { if (slow && !YYSTATE) return IDENT; scale = 10; goto num; } - -0[xX]{H}+{IS}? { scale = 16; - num: if (YYSTATE) - yylval.val = cvtdig(scale); - PRTOUT(NUMBER); - } -0{D}+{IS}? { scale = 8; goto num; } -{D}+{IS}? { scale = 10; goto num; } -L?'(\\.|[^\\'])+' { if (YYSTATE) - yylval.val = charcon(); - PRTOUT(NUMBER); - } - -<IFR>. { return yytext[0]; } - -{D}+{E}{FS}? { PRTOUT(FPOINT); } -{D}*"."{D}+({E})?{FS}? { PRTOUT(FPOINT); } -{D}+"."{D}*({E})?{FS}? { PRTOUT(FPOINT); } - -^{WS}*#{WS}* { contr = 1; BEGIN CONTR; } -{WS}+ { PRTOUT(WSPACE); } - -<CONTR>"ifndef" { contr = 0; ifndefstmt(); } -<CONTR>"ifdef" { contr = 0; ifdefstmt(); } -<CONTR>"if" { contr = 0; storepb(); BEGIN IFR; ifstmt(); BEGIN 0; } -<CONTR>"include" { contr = 0; BEGIN 0; include(); prtline(); } -<CONTR>"else" { contr = 0; elsestmt(); } -<CONTR>"endif" { contr = 0; endifstmt(); } -<CONTR>"error" { contr = 0; if (slow) return IDENT; cpperror(); BEGIN 0; } -<CONTR>"define" { contr = 0; BEGIN DEF; define(); BEGIN 0; } -<CONTR>"undef" { contr = 0; if (slow) return IDENT; undefstmt(); } -<CONTR>"line" { contr = 0; storepb(); BEGIN 0; line(); } -<CONTR>"pragma" { contr = 0; pragmastmt(); BEGIN 0; } -<CONTR>"elif" { contr = 0; storepb(); BEGIN IFR; elifstmt(); BEGIN 0; } - - - -"//".*$ { /* if (tflag) yyless(..) */ - if (Cflag) - putstr((usch *)yytext); - else if (!flslvl) - putch(' '); - } -"/*" { int c, wrn; - if (Cflag) - putstr((usch *)yytext); - wrn = 0; - more: while ((c = input()) && c != '*') { - if (c == '\n') - putch(c), ifiles->lineno++; - else if (c == 1) /* WARN */ - wrn = 1; - else if (Cflag) - putch(c); - } - if (c == 0) - return 0; - if (Cflag) - putch(c); - if ((c = input()) && c != '/') { - if (Cflag) - putch('*'); - unput(c); - goto more; - } - if (Cflag) - putch(c); - if (c == 0) - return 0; - if (!tflag && !Cflag && !flslvl) - unput(' '); - if (wrn) - unput(1); - } - -<DEF>"##" { return CONCAT; } -<DEF>"#" { return MKSTR; } -<DEF>"..." { return ELLIPS; } -<DEF>"__VA_ARGS__" { return VA_ARGS; } - -L?\"(\\.|[^\\"])*\" { PRTOUT(STRING); } -[a-zA-Z_0-9]+ { /* {L}({L}|{D})* */ - struct symtab *nl; - if (slow) - return IDENT; - if (YYSTATE == CONTR) { - if (flslvl == 0) { - /*error("undefined control");*/ - while (input() != '\n') - ; - unput('\n'); - BEGIN 0; - goto xx; - } else { - BEGIN 0; /* do nothing */ - } - } - if (flslvl) { - ; /* do nothing */ - } else if (isdigit((int)yytext[0]) == 0 && - (nl = lookup((usch *)yytext, FIND)) != 0) { - usch *op = stringbuf; - putstr(gotident(nl)); - stringbuf = op; - } else - putstr((usch *)yytext); - xx: ; - } - -. { PRTOUT(yytext[0]); } - -%% - -usch *yyp, yybuf[CPPBUF]; - -int yylex(void); -int yywrap(void); - -static int -inpch(void) -{ - int len; - - if (ifiles->curptr < ifiles->maxread) - return *ifiles->curptr++; - - if ((len = read(ifiles->infil, ifiles->buffer, CPPBUF)) < 0) - error("read error on file %s", ifiles->orgfn); - if (len == 0) - return -1; - ifiles->curptr = ifiles->buffer; - ifiles->maxread = ifiles->buffer + len; - return inpch(); -} - -#define unch(c) *--ifiles->curptr = c - -static int -inch(void) -{ - int c; - -again: switch (c = inpch()) { - case '\\': /* continued lines */ - if ((c = inpch()) == '\n') { - ifiles->lineno++; - putch('\n'); - goto again; - } - unch(c); - return '\\'; - case '?': /* trigraphs */ - if ((c = inpch()) != '?') { - unch(c); - return '?'; - } - switch (c = inpch()) { - case '=': c = '#'; break; - case '(': c = '['; break; - case ')': c = ']'; break; - case '<': c = '{'; break; - case '>': c = '}'; break; - case '/': c = '\\'; break; - case '\'': c = '^'; break; - case '!': c = '|'; break; - case '-': c = '~'; break; - default: - unch(c); - unch('?'); - return '?'; - } - unch(c); - goto again; - default: - return c; - } -} - -/* - * Let the command-line args be faked defines at beginning of file. - */ -static void -prinit(struct initar *it, struct includ *ic) -{ - char *a, *pre, *post; - - if (it->next) - prinit(it->next, ic); - pre = post = NULL; /* XXX gcc */ - switch (it->type) { - case 'D': - pre = "#define "; - if ((a = strchr(it->str, '=')) != NULL) { - *a = ' '; - post = "\n"; - } else - post = " 1\n"; - break; - case 'U': - pre = "#undef "; - post = "\n"; - break; - case 'i': - pre = "#include \""; - post = "\"\n"; - break; - default: - error("prinit"); - } - strlcat((char *)ic->buffer, pre, CPPBUF+1); - strlcat((char *)ic->buffer, it->str, CPPBUF+1); - if (strlcat((char *)ic->buffer, post, CPPBUF+1) >= CPPBUF+1) - error("line exceeds buffer size"); - - ic->lineno--; - while (*ic->maxread) - ic->maxread++; -} - -/* - * A new file included. - * If ifiles == NULL, this is the first file and already opened (stdin). - * Return 0 on success, -1 on failure to open file. - */ -int -pushfile(usch *file) -{ - extern struct initar *initar; - struct includ ibuf; - struct includ *old; - struct includ *ic; - int c, otrulvl; - - ic = &ibuf; - old = ifiles; - - slow = 0; - if (file != NULL) { - if ((ic->infil = open((char *)file, O_RDONLY)) < 0) - return -1; - ic->orgfn = ic->fname = file; - } else { - ic->infil = 0; - ic->orgfn = ic->fname = (usch *)"<stdin>"; - } - ic->buffer = ic->bbuf+NAMEMAX; - ic->curptr = ic->buffer; - ifiles = ic; - ic->lineno = 1; - ic->maxread = ic->curptr; - prtline(); - if (initar) { - *ic->maxread = 0; - prinit(initar, ic); - if (dMflag) - write(ofd, ic->buffer, strlen((char *)ic->buffer)); - initar = NULL; - } - - otrulvl = trulvl; - - if ((c = yylex()) != 0) - error("yylex returned %d", c); - - if (otrulvl != trulvl || flslvl) - error("unterminated conditional"); - - ifiles = old; - close(ic->infil); - return 0; -} - -/* - * Print current position to output file. - */ -void -prtline() -{ - usch *s, *os = stringbuf; - - if (Mflag) { - if (dMflag) - return; /* no output */ - if (ifiles->lineno == 1) { - s = sheap("%s: %s\n", Mfile, ifiles->fname); - write(ofd, s, strlen((char *)s)); - } - } else - putstr(sheap("# %d \"%s\"\n", ifiles->lineno, ifiles->fname)); - stringbuf = os; -} - -void -cunput(int c) -{ -#ifdef CPP_DEBUG - extern int dflag; - if (dflag)printf(": '%c'(%d)", c, c); -#endif - unput(c); -} - -int yywrap(void) { return 1; } - -static int -dig2num(int c) -{ - if (c >= 'a') - c = c - 'a' + 10; - else if (c >= 'A') - c = c - 'A' + 10; - else - c = c - '0'; - return c; -} - -/* - * Convert some string numbers to long long. - * Do not care about UL trailers, should we? - */ -static long long -cvtdig(int rad) -{ - long long rv = 0; - char *y = yytext; - int c; - - c = *y++; - if (rad == 16) - y++; - while (isxdigit(c)) { - rv = rv * rad + dig2num(c); - c = *y++; - } - return rv; -} - -static int -charcon(void) -{ - usch *p = (usch *)yytext; - int val, c; - - if (*p == 'L') - p++; - p++; /* first ' */ - val = 0; - if (*p++ == '\\') { - switch (*p++) { - case 'a': val = '\a'; break; - case 'b': val = '\b'; break; - case 'f': val = '\f'; break; - case 'n': val = '\n'; break; - case 'r': val = '\r'; break; - case 't': val = '\t'; break; - case 'v': val = '\v'; break; - case '\"': val = '\"'; break; - case '\'': val = '\''; break; - case '\\': val = '\\'; break; - case 'x': - while (isxdigit(c = *p)) { - val = val * 16 + dig2num(c); - p++; - } - break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - p--; - while (isdigit(c = *p)) { - val = val * 8 + (c - '0'); - p++; - } - break; - default: val = p[-1]; - } - - } else - val = p[-1]; - return val; -} - -static void -chknl(void) -{ - int t; - - while ((t = yylex()) == WSPACE) - ; - if (t != '\n') - error("newline expected, got %d", t); -} - -static void -elsestmt(void) -{ - if (flslvl) { - if (elflvl > trulvl) - ; - else if (--flslvl!=0) { - flslvl++; - } else { - trulvl++; - prtline(); - } - } else if (trulvl) { - flslvl++; - trulvl--; - } else - error("If-less else"); - if (elslvl==trulvl+flslvl) - error("Too many else"); - elslvl=trulvl+flslvl; - chknl(); -} - -static void -ifdefstmt(void) -{ - if (flslvl) { - /* just ignore the rest of the line */ - while (input() != '\n') - ; - unput('\n'); - yylex(); - flslvl++; - return; - } - slow = 1; - if (yylex() != WSPACE || yylex() != IDENT) - error("bad ifdef"); - slow = 0; - if (flslvl == 0 && lookup((usch *)yytext, FIND) != 0) - trulvl++; - else - flslvl++; - chknl(); -} - -static void -ifndefstmt(void) -{ - slow = 1; - if (yylex() != WSPACE || yylex() != IDENT) - error("bad ifndef"); - slow = 0; - if (flslvl == 0 && lookup((usch *)yytext, FIND) == 0) - trulvl++; - else - flslvl++; - chknl(); -} - -static void -endifstmt(void) -{ - if (flslvl) { - flslvl--; - if (flslvl == 0) - prtline(); - } else if (trulvl) - trulvl--; - else - error("If-less endif"); - if (flslvl == 0) - elflvl = 0; - elslvl = 0; - chknl(); -} - -/* - * Note! Ugly! - * Walk over the string s and search for defined, and replace it with - * spaces and a 1 or 0. - */ -static void -fixdefined(usch *s) -{ - usch *bc, oc; - - for (; *s; s++) { - if (*s != 'd') - continue; - if (memcmp(s, "defined", 7)) - continue; - /* Ok, got defined, can scratch it now */ - memset(s, ' ', 7); - s += 7; -#define WSARG(x) (x == ' ' || x == '\t') - if (*s != '(' && !WSARG(*s)) - continue; - while (WSARG(*s)) - s++; - if (*s == '(') - s++; - while (WSARG(*s)) - s++; -#define IDARG(x) ((x>= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x == '_')) -#define NUMARG(x) (x >= '0' && x <= '9') - if (!IDARG(*s)) - error("bad defined arg"); - bc = s; - while (IDARG(*s) || NUMARG(*s)) - s++; - oc = *s; - *s = 0; - *bc = (lookup(bc, FIND) != 0) + '0'; - memset(bc+1, ' ', s-bc-1); - *s = oc; - } -} - -/* - * get the full line of identifiers after an #if, pushback a WARN and - * the line and prepare for expmac() to expand. - * This is done before switching state. When expmac is finished, - * pushback the expanded line, change state and call yyparse. - */ -static void -storepb(void) -{ - usch *opb = stringbuf; - int c; - - while ((c = input()) != '\n') - savch(c); - cunput('\n'); - savch(0); - fixdefined(opb); /* XXX can fail if #line? */ - cunput(1); /* WARN XXX */ - unpstr(opb); - stringbuf = opb; - slow = 1; - expmac(NULL); - slow = 0; - /* line now expanded */ - while (stringbuf > opb) - cunput(*--stringbuf); -} - -static void -ifstmt(void) -{ - if (flslvl == 0) { - slow = 1; - if (yyparse()) - ++trulvl; - else - ++flslvl; - slow = 0; - } else - ++flslvl; -} - -static void -elifstmt(void) -{ - if (flslvl == 0) - elflvl = trulvl; - if (flslvl) { - if (elflvl > trulvl) - ; - else if (--flslvl!=0) - ++flslvl; - else { - slow = 1; - if (yyparse()) { - ++trulvl; - prtline(); - } else - ++flslvl; - slow = 0; - } - } else if (trulvl) { - ++flslvl; - --trulvl; - } else - error("If-less elif"); -} - -static usch * -svinp(void) -{ - int c; - usch *cp = stringbuf; - - while ((c = input()) && c != '\n') - savch(c); - savch('\n'); - savch(0); - BEGIN 0; - return cp; -} - -static void -cpperror(void) -{ - usch *cp; - int c; - - if (flslvl) - return; - c = yylex(); - if (c != WSPACE && c != '\n') - error("bad error"); - cp = svinp(); - if (flslvl) - stringbuf = cp; - else - error("error: %s", cp); -} - -static void -undefstmt(void) -{ - struct symtab *np; - - slow = 1; - if (yylex() != WSPACE || yylex() != IDENT) - error("bad undef"); - if (flslvl == 0 && (np = lookup((usch *)yytext, FIND))) - np->value = 0; - slow = 0; - chknl(); -} - -static void -pragmastmt(void) -{ - int c; - - slow = 1; - if (yylex() != WSPACE) - error("bad pragma"); - if (!flslvl) - putstr((usch *)"#pragma "); - do { - c = input(); - if (!flslvl) - putch(c); /* Do arg expansion instead? */ - } while (c && c != '\n'); - ifiles->lineno++; - prtline(); - slow = 0; -} diff --git a/usr.bin/pcc/cc/cpp/tests/res1 b/usr.bin/pcc/cc/cpp/tests/res1 deleted file mode 100644 index c0bb48019f3..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/res1 +++ /dev/null @@ -1,7 +0,0 @@ -# 1 "<stdin>" - - - - -char p[] = "x ## y"; - diff --git a/usr.bin/pcc/cc/cpp/tests/res2 b/usr.bin/pcc/cc/cpp/tests/res2 deleted file mode 100644 index 1eb808aac47..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/res2 +++ /dev/null @@ -1,26 +0,0 @@ -# 1 "<stdin>" - - - - - - - - - - - - - - -f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t (1); -f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & -f(2 * (0,1))^m (0,1); -int i[] = { 1, 23, 4, 5, }; -char c[2][6] = { "hello", "" }; - - - - - - diff --git a/usr.bin/pcc/cc/cpp/tests/res3 b/usr.bin/pcc/cc/cpp/tests/res3 deleted file mode 100644 index 4219319ddff..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/res3 +++ /dev/null @@ -1,16 +0,0 @@ -# 1 "<stdin>" - - - - - - - - - -printf("x" "1" "= %d, x" "2" "= %s", x1, x2); -fputs( -"strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s); -\#include "vers2.h" -"hello"; -"hello" ", world" diff --git a/usr.bin/pcc/cc/cpp/tests/res4 b/usr.bin/pcc/cc/cpp/tests/res4 deleted file mode 100644 index d7046a01507..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/res4 +++ /dev/null @@ -1,5 +0,0 @@ -# 1 "<stdin>" - - - -(1) diff --git a/usr.bin/pcc/cc/cpp/tests/res5 b/usr.bin/pcc/cc/cpp/tests/res5 deleted file mode 100644 index 291405dcfee..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/res5 +++ /dev/null @@ -1,4 +0,0 @@ -# 1 "<stdin>" - -int j[] = { 123, 45, 67, 89, - 10, 11, 12, }; diff --git a/usr.bin/pcc/cc/cpp/tests/res6 b/usr.bin/pcc/cc/cpp/tests/res6 deleted file mode 100644 index 0bb0f9a1dbf..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/res6 +++ /dev/null @@ -1,6 +0,0 @@ -# 1 "<stdin>" - - - - -foo diff --git a/usr.bin/pcc/cc/cpp/tests/res7 b/usr.bin/pcc/cc/cpp/tests/res7 deleted file mode 100644 index 18c492bda72..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/res7 +++ /dev/null @@ -1,5 +0,0 @@ -# 1 "<stdin>" - - - -a YES diff --git a/usr.bin/pcc/cc/cpp/tests/res8 b/usr.bin/pcc/cc/cpp/tests/res8 deleted file mode 100644 index e7de0945f47..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/res8 +++ /dev/null @@ -1,8 +0,0 @@ -# 1 "<stdin>" - - - - - -(hej.s_s.s_pos) - diff --git a/usr.bin/pcc/cc/cpp/tests/res9 b/usr.bin/pcc/cc/cpp/tests/res9 deleted file mode 100644 index aea239fc9aa..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/res9 +++ /dev/null @@ -1,5 +0,0 @@ -# 1 "<stdin>" - - - -ao diff --git a/usr.bin/pcc/cc/cpp/tests/test1 b/usr.bin/pcc/cc/cpp/tests/test1 deleted file mode 100644 index 79a3c5dc5d4..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/test1 +++ /dev/null @@ -1,6 +0,0 @@ -#define hash_hash # ## # -#define mkstr(a) # a -#define in_between(a) mkstr(a) -#define join(c, d) in_between(c hash_hash d) -char p[] = join(x, y); // equivalent to - // char p[] = "x ## y"; diff --git a/usr.bin/pcc/cc/cpp/tests/test2 b/usr.bin/pcc/cc/cpp/tests/test2 deleted file mode 100644 index 283d4fbc1f0..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/test2 +++ /dev/null @@ -1,25 +0,0 @@ -#define x 3 -#define f(a) f(x * (a)) -#undef x -#define x 2 -#define g f -#define z z[0] -#define h g(~ -#define m(a) a(w) -#define w 0,1 -#define t(a) a -#define p() int -#define q(x) x -#define r(x,y) x ## y -#define str(x) # x -f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); -g(x+(3,4)-w) | h 5) & m -(f)^m(m); -p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; -char c[2][6] = { str(hello), str() }; -/* - * f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); - * f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); - * int i[] = { 1, 23, 4, 5, }; - * char c[2][6] = { "hello", "" }; - */ diff --git a/usr.bin/pcc/cc/cpp/tests/test3 b/usr.bin/pcc/cc/cpp/tests/test3 deleted file mode 100644 index a659245ecbc..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/test3 +++ /dev/null @@ -1,15 +0,0 @@ -#define str(s) # s -#define xstr(s) str(s) -#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \ - x ## s, x ## t) -#define INCFILE(n) vers ## n -#define glue(a, b) a ## b -#define xglue(a, b) glue(a, b) -#define HIGHLOW "hello" -#define LOW LOW ", world" -debug(1, 2); -fputs(str(strncmp("abc\0d", "abc", '\4') // this goes away - == 0) str(: @\n), s); -\#include xstr(INCFILE(2).h) -glue(HIGH, LOW); -xglue(HIGH, LOW) diff --git a/usr.bin/pcc/cc/cpp/tests/test4 b/usr.bin/pcc/cc/cpp/tests/test4 deleted file mode 100644 index 0068f3751b8..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/test4 +++ /dev/null @@ -1,4 +0,0 @@ -#define foobar 1 -#define C(x,y) x##y -#define D(x) (C(x,bar)) -D(foo) diff --git a/usr.bin/pcc/cc/cpp/tests/test5 b/usr.bin/pcc/cc/cpp/tests/test5 deleted file mode 100644 index 3ca0bb6c9c0..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/test5 +++ /dev/null @@ -1,3 +0,0 @@ -#define t(x,y,z) x ## y ## z -int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), - t(10,,), t(,11,), t(,,12), t(,,) }; diff --git a/usr.bin/pcc/cc/cpp/tests/test6 b/usr.bin/pcc/cc/cpp/tests/test6 deleted file mode 100644 index 28cfddece68..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/test6 +++ /dev/null @@ -1,5 +0,0 @@ -#define X(a,b, \ - c,d) \ - foo - -X(1,2,3,4) diff --git a/usr.bin/pcc/cc/cpp/tests/test7 b/usr.bin/pcc/cc/cpp/tests/test7 deleted file mode 100644 index b22b22bbcc9..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/test7 +++ /dev/null @@ -1,4 +0,0 @@ -#define a() YES -#define b() a -b() -b()() diff --git a/usr.bin/pcc/cc/cpp/tests/test8 b/usr.bin/pcc/cc/cpp/tests/test8 deleted file mode 100644 index c5d2f9a1449..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/test8 +++ /dev/null @@ -1,7 +0,0 @@ -// test macro expansion in arguments -#define s_pos s_s.s_pos -#define foo(x) (x) - -//hej.s_pos -foo(hej.s_pos) - diff --git a/usr.bin/pcc/cc/cpp/tests/test9 b/usr.bin/pcc/cc/cpp/tests/test9 deleted file mode 100644 index 4d4368d5663..00000000000 --- a/usr.bin/pcc/cc/cpp/tests/test9 +++ /dev/null @@ -1,4 +0,0 @@ -#define C(a,b,c) a##b##c -#define N(x,y) C(x,_,y) -#define A_O ao -N(A,O) |