summaryrefslogtreecommitdiff
path: root/usr.bin/pcc/cc
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2007-10-07 17:58:53 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2007-10-07 17:58:53 +0000
commit14b353bdf99a61b29314822d06fff3f7250019ac (patch)
treecfb9b82ab66c64756933986a1d66b0b133819ab4 /usr.bin/pcc/cc
parent71267fa7f73e6e874cf9cb489551cb44ead37aba (diff)
reorg pcc tree; requested by and ok deraadt@; ok ragge@
Diffstat (limited to 'usr.bin/pcc/cc')
-rw-r--r--usr.bin/pcc/cc/Makefile17
-rw-r--r--usr.bin/pcc/cc/cc.1 (renamed from usr.bin/pcc/cc/cc/cc.1)4
-rw-r--r--usr.bin/pcc/cc/cc.c (renamed from usr.bin/pcc/cc/cc/cc.c)4
-rw-r--r--usr.bin/pcc/cc/cc/Makefile16
-rw-r--r--usr.bin/pcc/cc/ccom/Makefile9
-rw-r--r--usr.bin/pcc/cc/ccom/Makefile.inc45
-rw-r--r--usr.bin/pcc/cc/ccom/ccom.1167
-rw-r--r--usr.bin/pcc/cc/ccom/cgram.y1403
-rw-r--r--usr.bin/pcc/cc/ccom/gcc_compat.c126
-rw-r--r--usr.bin/pcc/cc/ccom/init.c968
-rw-r--r--usr.bin/pcc/cc/ccom/inline.c209
-rw-r--r--usr.bin/pcc/cc/ccom/main.c317
-rw-r--r--usr.bin/pcc/cc/ccom/optim.c355
-rw-r--r--usr.bin/pcc/cc/ccom/pass1.h394
-rw-r--r--usr.bin/pcc/cc/ccom/pftn.c2676
-rw-r--r--usr.bin/pcc/cc/ccom/scan.l467
-rw-r--r--usr.bin/pcc/cc/ccom/stabs.c374
-rw-r--r--usr.bin/pcc/cc/ccom/symtabs.c356
-rw-r--r--usr.bin/pcc/cc/ccom/trees.c2466
-rw-r--r--usr.bin/pcc/cc/ccom/vax/Makefile3
-rw-r--r--usr.bin/pcc/cc/ccom/x86/Makefile3
-rw-r--r--usr.bin/pcc/cc/cpp/Makefile17
-rw-r--r--usr.bin/pcc/cc/cpp/cpp.1194
-rw-r--r--usr.bin/pcc/cc/cpp/cpp.c1482
-rw-r--r--usr.bin/pcc/cc/cpp/cpp.h120
-rw-r--r--usr.bin/pcc/cc/cpp/cpy.y166
-rw-r--r--usr.bin/pcc/cc/cpp/scanner.l817
-rw-r--r--usr.bin/pcc/cc/cpp/tests/res17
-rw-r--r--usr.bin/pcc/cc/cpp/tests/res226
-rw-r--r--usr.bin/pcc/cc/cpp/tests/res316
-rw-r--r--usr.bin/pcc/cc/cpp/tests/res45
-rw-r--r--usr.bin/pcc/cc/cpp/tests/res54
-rw-r--r--usr.bin/pcc/cc/cpp/tests/res66
-rw-r--r--usr.bin/pcc/cc/cpp/tests/res75
-rw-r--r--usr.bin/pcc/cc/cpp/tests/res88
-rw-r--r--usr.bin/pcc/cc/cpp/tests/res95
-rw-r--r--usr.bin/pcc/cc/cpp/tests/test16
-rw-r--r--usr.bin/pcc/cc/cpp/tests/test225
-rw-r--r--usr.bin/pcc/cc/cpp/tests/test315
-rw-r--r--usr.bin/pcc/cc/cpp/tests/test44
-rw-r--r--usr.bin/pcc/cc/cpp/tests/test53
-rw-r--r--usr.bin/pcc/cc/cpp/tests/test65
-rw-r--r--usr.bin/pcc/cc/cpp/tests/test74
-rw-r--r--usr.bin/pcc/cc/cpp/tests/test87
-rw-r--r--usr.bin/pcc/cc/cpp/tests/test94
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)