Remove files that have been removed from vendor branch

This commit is contained in:
Peter Wemm 2002-01-27 22:41:09 +00:00
parent 8489cc4415
commit d337ceafd7
83 changed files with 0 additions and 32178 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,18 +0,0 @@
Specifying the -g flag to GCC on a RISC iX machine requires upgrading the
standard assembler distributed with both RISC iX 1.1 and RISC iX 1.2 with a
replacement that is available from Acorn. This version of the assembler is
also an order of magnitude faster when assembling to an NFS mounted
file-system.
Users of RISC iX 1.2 and above can obtain a copy of the assembler from the
following places:
1) Via ftp from acorn.acorn.co.uk, directory pub/riscix.
2) From Acorn Customer Services.
3) From Granada Microcare.
Users of versions of RISC iX prior 1.2 should contact Acorn Customer Services;
the assembler available on the net will not work with these versions due to
changes in the shared libraries and system call numbers.

View file

@ -1,55 +0,0 @@
Since COFF-encapsulation is obsolete, this may not be needed anymore.
Return-Path: <jkp@sauna.hut.fi>
Date: Mon, 10 Apr 89 10:13:45 +0300
From: Jyrki Kuoppala <jkp@sauna.hut.fi>
Sender: jkp@sauna.hut.fi
To: info-gcc@prep.ai.mit.edu
Subject: Kernel fix needed for Altos 3068 to get coff-encapsulation working right
Organization: Helsinki University of Technology, Finland.
Here's a description how to fix a kernel bug in Altos 3068 and get
gcc-compiled programs working.
Author: Jyrki Kuoppala (jkp@cs.hut.fi)
Last modified: Mon Apr 10 09:28:40 1989
There's a bug in the Altos 3068 kernel that causes gcc-compiled
programs to fail in certain situations when the machine has a heavy
load and also in some other situations. The bug exists at least in
SVR 2.2 1.0gT1 and SVR 2.2 1.0e.
If you have source code to your system, apply the following change to
os/exec.c (function gethead):
Change the lines containing
u.u_exdata.ux_tstart = sizeof(struct naout) +
sizeof(struct filhd) + (ep->ef.nscns * sizeof(struct scnhdr));
to
u.u_exdata.ux_tstart = u.u_exdata.ux_txtorg;
If you only have binary, use sdb to find out the address of the
previous lines (on our system it's gethead+0x140) and use your
favourite binary editor to change the bytes '3036 0162 fffc 0002 0280
0000' to '23f9 01fb f4ca 01fb f4c2 6016'. This may or may not work in
your case, depending on the version of the operating system and the
phase of the moon.
Here's what is just before gethead+0x140 to ease finding out the right place:
0x9224 (gethead+0x122): 23f9 01fb f4ca 01fb f4ce mov.l &0x1fbf4ca.L,&0
x1fbf4ce.L []
0x922e (gethead+0x12c): 23f9 01fb f4c6 01fb f4ca mov.l &0x1fbf4c6.L,&0
x1fbf4ca.L []
0x9238 (gethead+0x136): 23f9 01fb f4c2 01fb f4c6 mov.l &0x1fbf4c2.L,&0
x1fbf4c6.L []
Good luck !
//Jyrki
jkp@cs.hut.fi

View file

@ -1,112 +0,0 @@
README.apollo
Building GCC 2.0 for 680x0 based Apollo systems requires the GNU
assembler (GAS) version 1.38.1, with John Vasta's patches applied.
If you haven't done so yet, get `gas-1.38.1.tar.Z' from your favourite
GNU distribution site. Furthermore, get `apollo-gas-1.38.1.diffs'
from `labrea.stanford.edu:/pub/gnu', apply the patches, compile and
install gas (under the name as). This should go through without any
problems.
After switching into the BSD environment, you can configure GCC 2.0
with the command
% ./configure m68k-apollo-bsd
The Apollo's `/usr/include/setjmp.h' uses a nonstandard `#options()'
construct. You should create a local copy of this file and remove
these constructs from the declarations of SIGSETJMP and SIGLONGJMP.
The Apollo's `/usr/include/sys/types.h' (BSD Version) doesn't allow
to test for the definition of `size_t'. This should be fixed by
#ifndef _SIZE_T
#define _SIZE_T
typedef long size_t;
#endif
The script `patch-apollo-includes' fixes these two problems, but does
_not_ pretend to be a full fledged `fixincludes' for this system.
If you now follow the standard GCC installation instructions, building
GCC 2.0 (including G++ 2.0) should proceed without any problems.
NB: Debugging is not yet supported for the Apollo. If someone wants
to do a _big_ favour to the Apollo users, he/she should consider
porting the Binary File Description library (BFD) to the Apollo.
This library can be found in the gdb-4.x distributions or in the
binutils-1.9x distributions.
#!/bin/sh
# patch-apollo-includes -- fix some (but not all!) Apollo brain damage.
FILES_TO_PATCH='sys/types.h setjmp.h'
mkdir sys
for i in $FILES_TO_PATCH;
do
cp /bsd4.3/usr/include/$i ./$i
done
patch -b -apollo <<'EOP'
*** /bsd4.3/usr/include/sys/types.h Fri Apr 8 20:29:06 1988
--- sys/types.h Wed Feb 26 21:17:57 1992
***************
*** 38,44 ****
--- 38,47 ----
typedef char * caddr_t;
typedef u_long ino_t;
typedef long swblk_t;
+ #ifndef _SIZE_T
+ #define _SIZE_T
typedef long size_t;
+ #endif
typedef long time_t;
typedef long dev_t;
typedef long off_t;
*** /bsd4.3/usr/include/setjmp.h Fri Feb 3 21:40:21 1989
--- setjmp.h Sun Feb 23 19:06:55 1992
***************
*** 24,30 ****
--- 24,39 ----
#endif
+ #ifdef __GNUC__
#ifdef _PROTOTYPES
+ extern int sigsetjmp (sigjmp_buf env, int savemask);
+ extern void siglongjmp (sigjmp_buf env, int val);
+ #else
+ extern int sigsetjmp();
+ extern void siglongjmp();
+ #endif /* _PROTOTYPES */
+ #else /* not __GNUC__ */
+ #ifdef _PROTOTYPES
extern int sigsetjmp(
sigjmp_buf env,
int savemask
***************
*** 37,43 ****
extern int sigsetjmp() #options(abnormal);
extern void siglongjmp() #options(noreturn);
#endif /* _PROTOTYPES */
!
#undef _PROTOTYPES
#ifdef __cplusplus
--- 46,52 ----
extern int sigsetjmp() #options(abnormal);
extern void siglongjmp() #options(noreturn);
#endif /* _PROTOTYPES */
! #endif /* not __GNUC__ */
#undef _PROTOTYPES
#ifdef __cplusplus
EOP
exit 0

View file

@ -1,17 +0,0 @@
Compiling Fresco with g++
-----------------------------
Fresco is an evolving interface and toolkit for object-oriented
graphics. A preliminary version (written in C++) was released
with x11r6.
Previous versions of Fresco have not compiled using g++,
partly because of the use of true and false as identifiers.
(They are now reserved words in g++, as required by the
ANSI/ISO draft standard for C++.)
If you get x11r6 with public patch #5 or a later version
of Fresco, these problems should now be fixed.
See http://www.faslab.com/fresco/HomePage.html for information
on Fresco, including how to get the latest version.

View file

@ -1,130 +0,0 @@
This file describes the implementation notes of the GNU C Compiler for
the National Semiconductor 32032 chip (and 32000 family).
The 32032 machine description and configuration file for this compiler
is, for NS32000 family machine, primarily machine independent.
However, since this release still depends on vendor-supplied
assemblers and linkers, the compiler must obey the existing
conventions of the actual machine to which this compiler is targeted.
In this case, the actual machine which this compiler was targeted to
is a Sequent Balance 8000, running DYNIX 2.1.
The assembler for DYNIX 2.1 (and DYNIX 3.0, alas) does not cope with
the full generality of the addressing mode REGISTER RELATIVE.
Specifically, it generates incorrect code for operands of the
following form:
sym(rn)
Where `rn' is one of the general registers. Correct code is generated
for operands of the form
sym(pn)
where `pn' is one of the special processor registers (sb, fp, or sp).
An equivalent operand can be generated by the form
sym[rn:b]
although this addressing mode is about twice as slow on the 32032.
The more efficient addressing mode is controlled by defining the
constant SEQUENT_ADDRESS_BUG to 0. It is currently defined to be 1.
Another bug in the assembler makes it impossible to compute with
explicit addresses. In order to compute with a symbolic address, it
is necessary to load that address into a register using the "addr"
instruction. For example, it is not possible to say
cmpd _p,@_x
Rather one must say
addr _x,rn
cmpd _p,rn
The ns32032 chip has a number of known bugs. Any attempt to make the
compiler unaware of these deficiencies will surely bring disaster.
The current list of know bugs are as follows (list provided by Richard
Stallman):
1) instructions with two overlapping operands in memory
(unlikely in C code, perhaps impossible).
2) floating point conversion instructions with constant
operands (these may never happen, but I'm not certain).
3) operands crossing a page boundary. These can be prevented
by setting the flag in tm.h that requires strict alignment.
4) Scaled indexing in an insn following an insn that has a read-write
operand in memory. This can be prevented by placing a no-op in
between. I, Michael Tiemann, do not understand what exactly is meant
by `read-write operand in memory'. If this is referring to the special
TOS mode, for example "addd 5,tos" then one need not fear, since this
will never be generated. However, is this includes "addd 5,-4(fp)"
then there is room for disaster. The Sequent compiler does not insert
a no-op for code involving the latter, and I have been informed that
Sequent is aware of this list of bugs, so I must assume that it is not
a problem.
5) The 32032 cannot shift by 32 bits. It shifts modulo the word size
of the operand. Therefore, for 32-bit operations, 32-bit shifts are
interpreted as zero bit shifts. 32-bit shifts have been removed from
the compiler, but future hackers must be careful not to reintroduce
them.
6) The ns32032 is a very slow chip; however, some instructions are
still very much slower than one might expect. For example, it is
almost always faster to double a quantity by adding it to itself than
by shifting it by one, even if that quantity is deep in memory. The
MOVM instruction has a 20-cycle setup time, after which it moves data
at about the speed that normal moves would. It is also faster to use
address generation instructions than shift instructions for left
shifts less than 4. I do not claim that I generate optimal code for all
given patterns, but where I did escape from National's "clean
architecture", I did so because the timing specification from the data
book says that I will win if I do. I suppose this is called the
"performance gap".
Signed bitfield extraction has not been implemented. It is not
provided by the NS32032, and while it is most certainly possible to do
better than the standard shift-left/shift-right sequence, it is also
quite hairy. Also, since signed bitfields do not yet exist in C, this
omission seems relatively harmless.
Zero extractions could be better implemented if it were possible in
GCC to provide sized zero extractions: i.e. a byte zero extraction
would be allowed to yield a byte result. The current implementation
of GCC manifests 68000-ist thinking, where bitfields are extracted
into a register, and automatically sign/zero extended to fill the
register. See comments in ns32k.md around the "extzv" insn for more
details.
It should be noted that while the NS32000 family was designed to
provide odd-aligned addressing capability for multi-byte data (also
provided by the 68020, but not by the 68000 or 68010), many machines
do not opt to take advantage of this. For example, on the sequent,
although there is no advantage to long-word aligning word data, shorts
must be int-aligned in structs. This is an example of another
machine-specific machine dependency.
Because the ns32032 is has a coherent byte-order/bit-order
architecture, many instructions which would be different for
68000-style machines, fold into the same instruction for the 32032.
The classic case is push effective address, where it does not matter
whether one is pushing a long, word, or byte address. They all will
push the same address.
The macro FUNCTION_VALUE_REGNO_P is probably not sufficient, what is
needed is FUNCTION_VALUE_P, which also takes a MODE parameter. In
this way it will be possible to determine more exactly whether a
register is really a function value register, or just one that happens
to look right.

View file

@ -1,111 +0,0 @@
AIX 3.1 and 3.2 assembler problems
Specifying the -g flag to GCC on the RS/6000 requires upgrading the
standard AIX assembler distributed with AIX 3.1 and versions of AIX
3.2 earlier than 3.2.4 with a replacement that is available from IBM.
Note that Makefile.in specifies the -g when compiling libgcc2.c.
You can test for the presence of a fixed assembler by entering the following:
% as -u < /dev/null
If the command exits normally, the assembler fix already is installed.
If the assembler complains that "-u" is an unknown flag, you need to order
the fix.
If you are running AIX 3.1 (lslpp -h bos.obj output reports
03.01.0005.XXXX where the 0005 can be any higher number and the XXXX
can be any value), call IBM Support at 800-237-5511 and ask for
shipment of AIX/6000 fix PTF U403044 for APAR IX22829 (.extern foo
conflicts with defining foo).
If you are running AIX 3.2 but not 3.2.4 or later (lslpp -h bos.obj
output reports 03.02.0000.0000), a newer update to the assembler fix
is available. Ask for shipment of AIX/6000 fix PTF U416277 for
IX32992 (.global prevents detection of duplicate symbol).
If you are running AIX 3.2.4 or later, you already have the new
assembler.
Any customer can order and get the replacement assembler, and install it on
one or more machines. It is available on diskette from IBM Customer Support
and from the IBM Internet fix anonymous ftp server (FixDist) at
aix.boulder.ibm.com (198.17.57.66).
If you contact IBM Customer Support, they may also ask you for your customer
number. If you do not know it, you will still be able to get the fix, but
you will have to be persistent. IBM has corresponding support organizations
outside of North America. Call your IBM branch office and ask them to put
you in touch with the department that handles fixes for AIX/6000. If that
doesn't work, ask for the department that handles software defect support
for AIX/6000 and ask for the APAR fix.
If you use the GNU assembler instead of the system supplied assembler, you need
an assembler modified after October 16th, 1995 in order to build the GNU C
compiler. This is because the GNU C compiler wants to build a variant of its
library, libgcc.a with the -mcpu=common switch to support building programs
that can run on either the Power or PowerPC machines.
AIX NLS problems
AIX on the RS/6000 provides support (NLS) for environments outside of
the United States. Compilers and assemblers use NLS to support
locale-specific representations of various objects including
floating-point numbers ("." vs "," for separating decimal fractions).
There have been problems reported where the library linked with GCC does
not produce the same floating-point formats that the assembler accepts.
If you have this problem, set the LANG environment variable to "C" or
"En_US".
AIX 3.2.5 XLC-1.3 problems
XLC version 1.3.0.0 distributed with AIX 3.2.5 will miscompile jump.c when
building the stage1 compiler during the bootstrap process. This will cause
GCC to crash and the bootstrap to fail later while compiling libgcc2.c. XLC
version 1.3.0.1 or later fixes this problem. XLC-1.3.0.19 also cannot
bootstrap GCC so please avoid that release as well. You can obtain
XLC-1.3.0.24 by requesting PTF 432238 from IBM, or just ask for the latest
release of XLC-1.3.
There also have been reports of problems bootstrapping GCC with some older
releases of xlc-1.2.1, including xlc-1.2.1.8. Newer releases of xlc-1.2.1
do not exhibit this problem: xlc-1.2.1.28 is known to bootstrap properly.
AIX 3.2 common-mode support
AIX common-mode providing transparent support of both the POWER and PowerPC
architectures is usable in AIX 3.2.3 and above but an export file and
support for hidden export via libc.a will not exist until AIX 4.1. libgcc.a
also must be compiled in common-mode. Note that executables generated for
the POWER (RIOS1 and RSC) architecture will run directly on systems using
the MPC601 chip. Common-mode only improves the performance of a single
executable run on both POWER and PowerPC architecture platforms by not using
POWER- or PowerPC-specific instructions and eliminating the need to trap to
emulation (for POWER instructions run on PowerPC).
To link a common-mode application prior to AIX 4.1 and run it on a system at
AIX level 3.2.3 or above, use the text between the "<>" as an export file
(e.g. milli.exp)
<><><><><><><><><><><>
#!
__mulh 0x3100
__mull 0x3180
__divss 0x3200
__divus 0x3280
__quoss 0x3300
__quous 0x3380
<><><><><><><><><><><>
and then link with -Wl,-bI:milli.exp.
AIX 4.1 binder
Due to changes in the way that GCC invokes the binder (linker) for AIX 4.1,
the link step now may produce warnings of duplicate symbols which were not
reported before. The assembly files generated by GCC for AIX always have
included multiple symbol definitions for certain global variable and
function declarations in the original program. The warnings should not
prevent the linker from producing a correct library or runnable executable.

View file

@ -1,447 +0,0 @@
[This file contains two alternative recipes for compiling X11 with GCC.
The first alternative puts libgcc.a into the shared X library; the second
does not. Neither alternative works on all kinds of systems.
It may be that when using GCC 2.4, both alternatives work okay on
relatively recent Sparc systems. The first alternative is likely
not to work on a Sun 3 without hardware floating point.]
How to compile X11R5 (patch level 11) with GCC version 2:
The patches include support for building the shared libraries with GCC
2 on the Sparc and 68k machines. This version includes the necessary
parts of libgcc.a in the shared library for X, in case functions in
that library need it. Thus the default behavior is now to build
everything, including the libraries, with gcc.
If you build the shared library this way, it may not work with
executables made with older versions of GCC (2.3.3 and earlier).
If that happens, relink those executables with the latest GCC.
IF YOU THINK YOU MIGHT COMPILE X FOR SOLARIS 2, then you really don't
need this patch: get /contrib/R5.SunOS5.patch.tar.Z from
export.lcs.mit.edu instead. It has everything you need to do the
build for Solaris 2, sets you up to everything with GCC, and is
backward compatible with Sunos 4.*. Get the the README
(/contrib/R5.SunOS5.patch.README at export) for more info.
If you see undefined symbols _dlopen, _dlsym, or _dlclose when linking
with -lX11, compile and link against the file mit/util/misc/dlsym.c in
the MIT X11R5 distribution. Alternatively, do dynamic linking
by using a non-GNU ld.
mit/config/Imake.tmpl -- Do not set -fstrength-reduce if we have GCC 2.
If -fstrength-reduce (or any other -f option) is a major win, then it
will most likely be turned on by -O2 optimization.
mit/config/sunLib.rules -- If HasGcc and GccVersion > 1 are true, then
use gcc -fpic to generate PIC code. Make sure that gcc does not use
gas (the GNU assembler) when compiling PIC code; gas does not assemble
it correctly.
***If you have gas installed where gcc uses it by default, you might have
to add -B/bin/ to the PositionIndependentCFlags.***
mit/config/site.def -- Define GccVersion to be 2.
mit/config/sun.cf -- When compiling with GCC 2, use -O2 optimization.
mit/config/sunLib.rules -- When compiling with GCC 2, use -fpic for
position independent code generation.
mit/rgb/Imakefile -- No longer need to compile some modules with
cc on the Sparc since GCC 2 produces proper -fpcc-struct-return code.
mit/server/os/Imakefile -- Likewise.
mit/server/ddx/sun/Imakefile -- When compiling with GCC 2, some modules
should be compiled with -fvolatile.
mit/clients/twm/Imakefile -- Fix bad decls of malloc, realloc in gram.c.
mit/lib/X/Imakefile -- Make libgcc.a a required lib for libX11.so
*** mit/clients/twm/Imakefile Mon May 17 22:05:22 1993
--- new/clients/twm/Imakefile Mon May 17 22:28:46 1993
***************
*** 32,41 ****
--- 32,48 ----
ComplexProgramTarget(twm)
InstallNonExecFile(system.twmrc,$(TWMDIR))
+ #if HasGcc && GccVersion > 1 && defined (SunArchitecture)
gram.h gram.c: gram.y
yacc $(YFLAGS) gram.y
+ sed -e 's/^extern char \*malloc(), \*realloc();//g' y.tab.c >gram.c
+ $(MV) y.tab.h gram.h
+ #else
+ gram.h gram.c: gram.y
+ yacc $(YFLAGS) gram.y
$(MV) y.tab.c gram.c
$(MV) y.tab.h gram.h
+ #endif
clean::
$(RM) y.tab.h y.tab.c lex.yy.c gram.h gram.c lex.c deftwmrc.c
*** mit/config/Imake.tmpl Mon May 17 22:02:57 1993
--- new/config/Imake.tmpl Mon May 17 22:15:06 1993
***************
*** 500,506 ****
--- 500,510 ----
#endif
#ifndef CcCmd
#if HasGcc
+ #if GccVersion > 1
+ #define CcCmd gcc -fpcc-struct-return
+ #else
#define CcCmd gcc -fstrength-reduce -fpcc-struct-return
+ #endif
#else
#define CcCmd cc
#endif
*** mit/config/site.def Mon May 17 22:02:44 1993
--- new/config/site.def Mon May 17 22:22:28 1993
***************
*** 25,31 ****
#ifdef BeforeVendorCF
! /* #define HasGcc YES */
#endif /* BeforeVendorCF */
--- 25,33 ----
#ifdef BeforeVendorCF
! #define HasGcc YES
! /* GccVersion > 1 implies building shared libraries with gcc */
! #define GccVersion 2
#endif /* BeforeVendorCF */
*** mit/config/sun.cf Mon May 17 22:03:02 1993
--- new/config/sun.cf Mon May 17 22:24:55 1993
***************
*** 41,49 ****
--- 41,55 ----
#if HasGcc
+ #if GccVersion > 1
+ #define OptimizedCDebugFlags -O2
+ #else
+ #define OptimizedCDebugFlags -O
#define SharedLibraryCcCmd cc
#define ExtraLoadFlags -B/usr/bin/
#define AllocateLocalDefines /**/
+ #endif
+
.c.o:
$(CC) -c $(CFLAGS) $*.c
*** mit/config/sunLib.rules Mon May 17 22:02:46 1993
--- new/config/sunLib.rules Mon May 17 22:19:06 1993
***************
*** 23,29 ****
--- 23,33 ----
#define SharedLibraryLoadFlags -assert pure-text
#endif
#ifndef PositionIndependentCFlags
+ #if defined(HasGcc) && GccVersion > 1
+ #define PositionIndependentCFlags -fpic
+ #else
#define PositionIndependentCFlags -pic
+ #endif
#endif
/*
*** mit/lib/X/Imakefile Mon May 17 22:05:03 1993
--- new/lib/X/Imakefile Mon May 17 22:32:26 1993
***************
*** 9,14 ****
--- 9,31 ----
#define MotifBC NO
#endif
+ #if defined(SunArchitecture)
+ #if SystemV4
+ #if HasGcc
+ REQUIREDLIBS= -lgcc -lc
+ #else
+ REQUIREDLIBS= -lc
+ #endif
+ #else
+ #if HasGcc && GccVersion > 1
+ XCOMM Hack to fix gcc 2 ``-nostdlib'' deficiency on SunOS 4.x
+ REQUIREDLIBS= `gcc -v 2>&1 | awk '{print $$4}' | sed -e 's/specs$$/libgcc.a/'`
+ #else
+ REQUIREDLIBS=
+ #endif
+ #endif
+ #endif
+
#ifndef BuildXimp
#define BuildXimp NO
#endif
*** mit/rgb/Imakefile Mon May 17 22:05:31 1993
--- new/rgb/Imakefile Mon May 17 22:25:30 1993
***************
*** 17,23 ****
#if !(defined(SGIArchitecture) || SystemV4)
DBMLIB = -ldbm
#endif
! #if defined(SparcArchitecture) && HasGcc
CC = cc
CCOPTIONS = /**/
EXTRA_LOAD_FLAGS = /**/
--- 17,23 ----
#if !(defined(SGIArchitecture) || SystemV4)
DBMLIB = -ldbm
#endif
! #if defined(SparcArchitecture) && HasGcc && GccVersion <= 1
CC = cc
CCOPTIONS = /**/
EXTRA_LOAD_FLAGS = /**/
*** mit/server/ddx/sun/Imakefile Mon May 17 22:05:57 1993
--- new/server/ddx/sun/Imakefile Mon May 17 22:27:23 1993
***************
*** 43,48 ****
--- 43,53 ----
LinkFile(sunGX.o,sunGX.o.dist)
#endif
+ #if HasGcc && GccVersion > 1
+ SpecialObjectRule(sunCG2C.o,sunCG2C.c,-fvolatile)
+ SpecialObjectRule(sunCG2M.o,sunCG2M.c,-fvolatile)
+ #endif
+
sunInitExtMono.o: $(ICONFIGFILES)
ObjectFromSpecialSource(sunInitExtMono,../mi/miinitext,-UPEXEXT)
ObjectFromSpecialSource(sunInitMono,sunInit,-DMONO_ONLY)
*** mit/server/os/Imakefile Mon May 17 22:05:46 1993
--- new/server/os/Imakefile Mon May 17 22:26:02 1993
***************
*** 132,138 ****
SpecialObjectRule(osinit.o,$(ICONFIGFILES),$(ADM_DEFINES))
SpecialObjectRule(WaitFor.o,$(ICONFIGFILES),$(EXT_DEFINES))
SpecialObjectRule(fonttype.o,$(ICONFIGFILES),$(FONT_DEFINES))
! #if defined(SparcArchitecture) && HasGcc
oscolor.o: $(ICONFIGFILES)
$(RM) $@
cc -c $(DBM_DEFINES) $(CDEBUGFLAGS) $(ALLDEFINES) $*.c
--- 132,138 ----
SpecialObjectRule(osinit.o,$(ICONFIGFILES),$(ADM_DEFINES))
SpecialObjectRule(WaitFor.o,$(ICONFIGFILES),$(EXT_DEFINES))
SpecialObjectRule(fonttype.o,$(ICONFIGFILES),$(FONT_DEFINES))
! #if defined(SparcArchitecture) && HasGcc && GccVersion <= 1
oscolor.o: $(ICONFIGFILES)
$(RM) $@
cc -c $(DBM_DEFINES) $(CDEBUGFLAGS) $(ALLDEFINES) $*.c
[This is the older version]
How to compile X11R5 (patch level 11) with GCC version 2:
The patches include support for building the shared libraries with GCC 2 on
the Sparc and 68k machines.
NOTE: Such shared libraries built with GCC version 2.3 DID NOT WORK
with executables previously linked using Sun CC! This is because
neither those executables nor the gcc-compiled shared libraries contain
libgcc.a. The shared libraries did work with executables linked using
GCC (running the Sun linker, of course) because GCC tells the linker to
link in libgcc.a. Because of these limitations the default behavior is
to NOT build the shared libraries with gcc.
Changes in GCC 2.4 seem to have eliminated the problem, and such a
shared library now seems work with all executables. If you want the
gcc-compiled shared libraries turn on "Gcc2BuildLibs" in site.def. If
you try this, please tell bug-gcc@prep.ai.mit.edu whether it works.
Sun forgot to include a static version of libdl.a with some versions
of SunOS (4.1 mainly). If you see undefined symbols _dlopen, _dlsym,
or _dlclose when linking with -lX11, compile and link against the file
mit/util/misc/dlsym.c in the MIT X11R5 distribution.
mit/config/Imake.tmpl -- Do not set -fstrength-reduce if we have GCC 2. If
-fstrength-reduce (or any other -f option) is a major win, then it will
most likely be turned on by -O2 optimization.
mit/config/sunLib.rules -- If HasGcc2 and Gcc2BuildLibs are defined, then
use gcc -fpic to generate PIC code. Make sure that gcc does not use gas (the
GNU assembler) when compiling PIC code; gas does not assemble it correctly.
If you have gas installed where gcc uses it by default, you might have to add
-B/bin/ to the PositionIndependentCFlags.
mit/config/site.def -- Define HasGcc2 to be YES.
mit/config/sun.cf -- When compiling with GCC 2, use -O2 optimization.
mit/rgb/Imakefile -- No longer need to compile some modules with
cc on the Sparc since GCC 2 produces proper -fpcc-struct-return code.
mit/server/os/Imakefile -- Likewise.
mit/clients/twm/Imakefile -- fix bad decls of malloc, realloc in gram.c.
*** mit/config/Imake.tmpl.ORIG Tue Dec 31 11:07:56 1991
--- mit/config/Imake.tmpl Tue Dec 31 12:30:47 1991
***************
*** 499,508 ****
--- 499,512 ----
#define HasGcc NO
#endif
#ifndef CcCmd
+ #if HasGcc2
+ #define CcCmd gcc -fpcc-struct-return
+ #else
#if HasGcc
#define CcCmd gcc -fstrength-reduce -fpcc-struct-return
#else
#define CcCmd cc
+ #endif
#endif
#endif
#if HasFortran
*** mit/config/sunLib.rules.ORIG Tue Dec 31 11:11:24 1991
--- mit/config/sunLib.rules Tue May 5 12:26:12 1992
***************
*** 23,30 ****
--- 23,34 ----
#define SharedLibraryLoadFlags -assert pure-text
#endif
#ifndef PositionIndependentCFlags
+ #if defined(HasGcc2) && defined (Gcc2BuildLibs)
+ #define PositionIndependentCFlags -fpic
+ #else
#define PositionIndependentCFlags -pic
#endif
+ #endif
/*
* InstallSharedLibrary - generate rules to install the shared library.
*** mit/config/site.def.ORIG Tue Dec 31 11:13:49 1991
--- mit/config/site.def Tue Dec 31 12:02:59 1991
***************
*** 25,31 ****
#ifdef BeforeVendorCF
! /* #define HasGcc YES */
#endif /* BeforeVendorCF */
--- 25,33 ----
#ifdef BeforeVendorCF
! #define HasGcc YES
! #define HasGcc2 YES
! /* #define Gcc2BuildLibs YES */
#endif /* BeforeVendorCF */
*** mit/config/sun.cf.ORIG Tue Dec 31 11:13:57 1991
--- mit/config/sun.cf Tue May 5 12:29:50 1992
***************
*** 34,42 ****
--- 41,61 ----
#if HasGcc
+ #if defined(HasGcc2)
+ #define OptimizedCDebugFlags -O2
+ /* Leave Alone XXX */
+ #else
+ #define OptimizedCDebugFlags -O
#define SharedLibraryCcCmd cc
#define ExtraLoadFlags -B/usr/bin/
#define AllocateLocalDefines /**/
+ #endif
+
+ #if !defined(Gcc2BuildLibs)
+ #define SharedLibraryCcCmd cc
+ #define ExtraLoadFlags -B/usr/bin/
+ #define AllocateLocalDefines /**/
+ #endif
.c.o:
$(CC) -c $(CFLAGS) $*.c
*** mit/rgb/Imakefile.ORIG Wed Jan 15 16:43:18 1992
--- mit/rgb/Imakefile Thu Jan 2 13:34:09 1992
***************
*** 17,23 ****
#if !(defined(SGIArchitecture) || SystemV4)
DBMLIB = -ldbm
#endif
! #if defined(SparcArchitecture) && HasGcc
CC = cc
CCOPTIONS = /**/
EXTRA_LOAD_FLAGS = /**/
--- 17,23 ----
#if !(defined(SGIArchitecture) || SystemV4)
DBMLIB = -ldbm
#endif
! #if defined(SparcArchitecture) && HasGcc && !defined(HasGcc2)
CC = cc
CCOPTIONS = /**/
EXTRA_LOAD_FLAGS = /**/
*** mit/server/os/Imakefile.ORIG Wed Jan 15 16:46:23 1992
--- mit/server/os/Imakefile Wed Jan 15 16:46:48 1992
***************
*** 132,138 ****
SpecialObjectRule(osinit.o,$(ICONFIGFILES),$(ADM_DEFINES))
SpecialObjectRule(WaitFor.o,$(ICONFIGFILES),$(EXT_DEFINES))
SpecialObjectRule(fonttype.o,$(ICONFIGFILES),$(FONT_DEFINES))
! #if defined(SparcArchitecture) && HasGcc
oscolor.o: $(ICONFIGFILES)
$(RM) $@
cc -c $(DBM_DEFINES) $(CDEBUGFLAGS) $(ALLDEFINES) $*.c
--- 132,138 ----
SpecialObjectRule(osinit.o,$(ICONFIGFILES),$(ADM_DEFINES))
SpecialObjectRule(WaitFor.o,$(ICONFIGFILES),$(EXT_DEFINES))
SpecialObjectRule(fonttype.o,$(ICONFIGFILES),$(FONT_DEFINES))
! #if defined(SparcArchitecture) && HasGcc && !defined(HasGcc2)
oscolor.o: $(ICONFIGFILES)
$(RM) $@
cc -c $(DBM_DEFINES) $(CDEBUGFLAGS) $(ALLDEFINES) $*.c
*** 1.1 1992/09/08 19:52:07
--- mit/server/ddx/sun/Imakefile 1992/09/08 21:10:22
***************
*** 43,48 ****
--- 43,53 ----
LinkFile(sunGX.o,sunGX.o.dist)
#endif
+ #if HasGcc2
+ SpecialObjectRule(sunCG2C.o,sunCG2C.c,-fvolatile)
+ SpecialObjectRule(sunCG2M.o,sunCG2M.c,-fvolatile)
+ #endif
+
sunInitExtMono.o: $(ICONFIGFILES)
ObjectFromSpecialSource(sunInitExtMono,../mi/miinitext,-UPEXEXT)
ObjectFromSpecialSource(sunInitMono,sunInit,-DMONO_ONLY)
*** /tmp/RCSAa24446 Tue Sep 15 12:23:32 1992
--- mit/clients/twm/Imakefile Thu Aug 13 18:18:07 1992
***************
*** 32,41 ****
--- 32,48 ----
ComplexProgramTarget(twm)
InstallNonExecFile(system.twmrc,$(TWMDIR))
+ #if HasGcc2 && defined (SunArchitecture)
gram.h gram.c: gram.y
yacc $(YFLAGS) gram.y
+ sed -e 's/^extern char \*malloc(), \*realloc();//g' y.tab.c >gram.c
+ $(MV) y.tab.h gram.h
+ #else
+ gram.h gram.c: gram.y
+ yacc $(YFLAGS) gram.y
$(MV) y.tab.c gram.c
$(MV) y.tab.h gram.h
+ #endif
clean::
$(RM) y.tab.h y.tab.c lex.yy.c gram.h gram.c lex.c deftwmrc.c

View file

@ -1,263 +0,0 @@
1998-08-11
This directory contains the egcs variant of version 0.5.24 of the
GNU Fortran compiler (g77). The GNU Fortran compiler is free software.
See the file COPYING.g77 for copying permission.
Currently, two variants of g77 exist. One is the Free Software Foundation
(FSF) variant. The other is the egcs variant. As of egcs version 1.1,
these variants are kept fairly similar in most respects. Pertinent
differences, such as the layout of the source code, are specified below.
Below, `[FSF]' denotes information applicable to only the FSF variant of
g77, while `[egcs]' denotes egcs-only information.
* IMPORTANT: Things you *must* do (or avoid) are marked with a * at the
beginning of the line in this file!!!
The email address to which bugs are to be reported is either
[FSF] <fortran@gnu.org> or [egcs] <egcs-bugs@cygnus.com>.
* *DO NOT* send any email (reporting bugs, asking questions, etc.) to
either of these addresses without *first* reading the g77 documentation.
Use `info', Info mode in GNU Emacs, or a text viewer such as `more' to
do this.
The g77 documentation is in the source files named `g77.info',
`g77.info-1', `g77.info-2', and so on in the `f' subdirectory. If these
files are not present or you can't find them, contact the person or
organization that put together the g77 distribution you are using (probably
not the FSF or egcs), or ask your system administrator for help.
This README applies to only the g77-specific portions of the source-code
tree that contains it. These portions include:
- The README.g77 and [FSF] COPYING.g77 files, in this directory, "this
directory" being [FSF] the top-level directory containing a g77
distribution or [egcs] the gcc/ subdirectory of an egcs distribution.
- The g77 front end, in the f/ subdirectory of this directory.
- The libg2c library, in [FSF] the f/runtime/ subdirectory of this
directory or [egcs] the libf2c/ directory under the top-level
directory of the egcs distribution.
* To build g77, you must have a source distribution of [FSF] gcc
version 2.8 or [egcs] egcs version 1.1. Do not attempt to use
any other version of gcc or egcs, because this version of g77 is
designed to work with only those versions.
Note that you must have *source* copies of the gcc or egcs distribution!
You cannot build g77 just using binaries of gcc or egcs. Also, unless
you are an expert, avoid using any distribution of gcc or egcs not
identical to the ones distributed by the FSF and Cygnus Support,
respectively. The primary FSF distribution site is:
<ftp://ftp.gnu.org/pub/gnu/>
The primary egcs distribution site is:
<ftp://ftp.cygnus.com/pub/egcs/>
Both of these sites have approved mirror sites from which valid
distributions also may be obtained.
* Do not attempt to combine the egcs version of g77 with the FSF
gcc distribution, or the FSF version of g77 with the egcs gcc
distribution. Although the differences are minor, they might
be sufficient to prevent g77 from building properly, or from
working properly if the build appears to succeed.
[FSF] g77 is distributed as g77-<version>/f/ so that unpacking the g77
distribution is done in the normal GNU way, resulting in a directory having
the version number in the name. However, to build g77, the g77 distribution
must be merged with an appropriate gcc distribution, normally in a gcc
source directory, before configuring, building, and installing g77.
[FSF] If you have just unpacked the g77 distribution, before proceeding,
you must merge the contents of the g77 distribution with the appropriate
gcc distribution on your system.
* [FSF] Read and follow the instructions in f/INSTALL that
explain how to merge a g77 source directory into a gcc source
directory. You can use Info to read the same installation
instructions via:
info -f f/g77.info -n Unpacking
[FSF] The resulting directory layout includes the following, where gcc/
might be a link to, for example, gcc-2.8.1/:
gcc/ Non-g77 files in gcc
gcc/COPYING.g77 A copy of the GPL, under which g77 is licensed
gcc/README.g77 This file
gcc/f/ GNU Fortran front end
gcc/f/runtime/ libg2c configuration and g2c.h file generation
gcc/f/runtime/libF77/ Non-I/O portion of libg2c
gcc/f/runtime/libI77/ I/O portion of libg2c
gcc/f/runtime/libU77/ Additional interfaces to libc for libg2c
[FSF] Applying g77 patches in the form of .diff files is done by typing
`patch -p1 -d gcc' (where gcc/ contains the f/ subdirectory). That is,
g77 patches are distributed in the same form, and at the same directory
level, as patches to the gcc distribution. (Note: make sure you're
using GNU patch, version 2.5 or later! Other versions of patch
have trouble with g77-related patches.)
[egcs] The egcs version of g77 is distributed already merged with
the rest of egcs (such as the gcc back end).
[egcs] The resulting directory layout includes the following, where egcs/
might be a link to, for example, egcs-1.1/:
egcs/gcc/ Non-g77 files in gcc
egcs/gcc/README.g77 This file
egcs/gcc/f/ GNU Fortran front end
egcs/libf2c/ libg2c configuration and g2c.h file generation
egcs/libf2c/libF77/ Non-I/O portion of libg2c
egcs/libf2c/libI77/ I/O portion of libg2c
egcs/libf2c/libU77/ Additional interfaces to libc for libg2c
[egcs] Applying g77-specific patches to egcs is done the same way as
applying other egcs patches.
Below, `libf2c/' shall denote [FSF] gcc/f/runtime/ or [egcs] egcs/libf2c/,
while `f/' shall denote [FSF] the rest of gcc/f/ or [egcs] egcs/gcc/f/.
Components of note in g77 are described below.
f/ as a whole contains the program GNU Fortran (g77), while libf2c/
contains a portion of the separate program f2c. Note: The libf2c
code is not part of the program g77, just distributed with it.
f/ contains text files that document the Fortran compiler, source
files for the GNU Fortran Front End (FFE), and some other stuff.
The g77 compiler code is placed in f/ because it, along with its contents,
is designed to be a subdirectory of a GNU CC (gcc) source directory, gcc/,
which is structured so that language-specific front ends can be "dropped
in" as subdirectories. The C++ front end (g++), is an example of this --
it resides in the cp/ subdirectory. Note that the C front end (also
referred to as gcc) is an exception to this, as its source files reside
in the gcc/ directory itself.
libf2c/ contains the run-time libraries for the f2c program, also used
by g77. These libraries normally referred to collectively as libf2c.
When built as part of g77, libf2c is installed under the name libg2c to avoid
conflict with any existing version of libf2c, and thus is often referred
to as libg2c when the g77 version is specifically being referred to.
The netlib version of libf2c/ contains two distinct libraries, libF77 and
libI77, each in their own subdirectories. In g77, this distinction is not
made, beyond maintaining the subdirectory structure in the source-code tree.
libf2c/ is not part of the program g77, just distributed with it. It
contains files not present in the official (netlib) version of libf2c,
and also contains some minor changes made from libf2c, to fix some bugs,
and to facilitate automatic configuration, building, and installation of
libf2c (as libg2c) for use by g77 users.
* See libf2c/README for more information, including licensing conditions
governing distribution of programs containing code from libg2c.
libg2c, g77's version of libf2c, adds Dave Love's implementation of
libU77, in the libf2c/libU77/ directory. This library is distributed
under the GNU Library General Public License (LGPL) -- see the
file libf2c/libU77/COPYING.LIB for more information, as this license
governs distribution conditions for programs containing code from
this portion of the library.
Files of note in g77 are described below.
f/BUGS lists some important bugs known to be in g77. Or:
info -f f/g77.info -n "Actual Bugs"
f/ChangeLog lists recent changes to g77 internals.
libf2c/ChangeLog lists recent changes to libg2c internals.
[FSF] f/INSTALL describes how to build and install GNU Fortran. Or:
info -f f/g77.info -n Installation
f/NEWS contains the per-release changes. These include the user-visible
changes described under "Changes" in the g77 documentation, plus internal
changes of import. Or:
info -f f/g77.info -n News
* All users of g77 (not just installers) should read f/g77.info*
as well, using the `more' command if neither the `info' command,
nor GNU Emacs (with its Info mode), are available, or if they
aren't yet accustomed to using these tools. Read f/BUGS and f/NEWS
plus, if you are planning on building or installing the FSF version
of g77, f/INSTALL, at the very least! All of these files are
readable as "plain text" files.
* Also see <ftp://alpha.gnu.org/g77.plan> for up-to-date information
regarding g77 bug reports, known bugs, bug-fixes, and new versions.
The rest of this file is of note to only those who wish to
debug, modify, or test the FFE (in conjunction with the gcc back end).
If you want to explore the FFE code, which lives entirely in f/, here
are a few clues. The file g77spec.c contains the g77-specific source code
for the `g77' command only -- this just forms a variant of the `gcc'
command, so, just as the `gcc' command itself does not contain
the C front end, the `g77' command does not contain the Fortran front
end (FFE). The FFE code ends up in an executable named `f771', which
does the actual compiling, so it contains the FFE plus the gcc back end
(the latter to do most of the optimization, and the code generation).
The file parse.c is the source file for main() for a stand-alone FFE and
yyparse() for f771. (Stand-alone building of the FFE doesn't work these days.)
The file top.c contains the top-level FFE function ffe_file and it (along
with top.h) define all ffe_[a-z].*, ffe[A-Z].*, and FFE_[A-Za-z].* symbols.
The file fini.c is a main() program that is used when building the FFE to
generate C header and source files for recognizing keywords. The files
malloc.c and malloc.h comprise a memory manager that defines all
malloc_[a-z].*, malloc[A-Z].*, and MALLOC_[A-Za-z].* symbols. All other
modules named <xyz> are comprised of all files named <xyz>*.<ext> and
define all ffe<xyz>_[a-z].*, ffe<xyz>[A-Z].*, and FFE<XYZ>_[A-Za-z].* symbols.
If you understand all this, congratulations -- it's easier for me to remember
how it works than to type in these grep patterns (such as they are). But it
does make it easy to find where a symbol is defined -- for example,
the symbol "ffexyz_set_something" would be defined in xyz.h and implemented
there (if it's a macro) or in xyz.c.
The "porting" files of note currently are: proj.h, which defines the
"language" used by all the other source files (the language being
Standard C plus some useful things like ARRAY_SIZE and such) -- change
this file when you find your system doesn't properly define a Standard C
macro or function, for example; target.h and target.c, which describe
the target machine in terms of what data types are supported, how they are
denoted (what C type does an INTEGER*8 map to, for example), how to convert
between them, and so on (though as of 0.5.3, more and more of this information
is being dynamically configured by ffecom_init_0); com.h and com.c, which
interface to the target back end (currently only FFE stand-alone and the GBE);
ste.c, which contains code for implementing recognized executable statements
in the target back end (again currently either FFE or GBE); src.h and src.c,
which describe information on the format(s) of source files (such as whether
they are never to be processed as case-insensitive with regard to Fortran
keywords); and proj.c, which contains whatever code is needed to support
the language defined by proj.h.
If you want to debug the f771 executable, for example if it crashes,
note that the global variables "lineno" and "input_filename" are set
to reflect the current line being read by the lexer during the first-pass
analysis of a program unit and to reflect the current line being
processed during the second-pass compilation of a program unit. If
an invocation of the function ffestd_exec_end() is on the stack,
the compiler is in the second pass, otherwise it is in the first.
(This information might help you reduce a test case and/or work around
a bug in g77 until a fix is available.)
Any questions or comments on these topics? Read the g77 documentation!

View file

@ -1,504 +0,0 @@
/* alloca.c -- allocate automatically reclaimed memory
(Mostly) portable public-domain implementation -- D A Gwyn
This implementation of the PWB library alloca function,
which is used to allocate space off the run-time stack so
that it is automatically reclaimed upon procedure exit,
was inspired by discussions with J. Q. Johnson of Cornell.
J.Otto Tennant <jot@cray.com> contributed the Cray support.
There are some preprocessor constants that can
be defined when compiling for your specific system, for
improved efficiency; however, the defaults should be okay.
The general concept of this implementation is to keep
track of all alloca-allocated blocks, and reclaim any
that are found to be deeper in the stack than the current
invocation. This heuristic does not reclaim storage as
soon as it becomes invalid, but it will do so eventually.
As a special case, alloca(0) reclaims storage without
allocating any. It is a good idea to use alloca(0) in
your main control loop, etc. to force garbage collection. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef emacs
#include "blockinput.h"
#endif
/* If compiling with GCC 2, this file's not needed. */
#if !defined (__GNUC__) || __GNUC__ < 2
/* If someone has defined alloca as a macro,
there must be some other way alloca is supposed to work. */
#ifndef alloca
#ifdef emacs
#ifdef static
/* actually, only want this if static is defined as ""
-- this is for usg, in which emacs must undefine static
in order to make unexec workable
*/
#ifndef STACK_DIRECTION
you
lose
-- must know STACK_DIRECTION at compile-time
#endif /* STACK_DIRECTION undefined */
#endif /* static */
#endif /* emacs */
/* If your stack is a linked list of frames, you have to
provide an "address metric" ADDRESS_FUNCTION macro. */
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
long i00afunc ();
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
#else
#define ADDRESS_FUNCTION(arg) &(arg)
#endif
#if __STDC__
typedef void *pointer;
#else
typedef char *pointer;
#endif
#ifndef NULL
#define NULL 0
#endif
/* Different portions of Emacs need to call different versions of
malloc. The Emacs executable needs alloca to call xmalloc, because
ordinary malloc isn't protected from input signals. On the other
hand, the utilities in lib-src need alloca to call malloc; some of
them are very simple, and don't have an xmalloc routine.
Non-Emacs programs expect this to call use xmalloc.
Callers below should use malloc. */
#ifndef emacs
#define malloc xmalloc
#endif
extern pointer malloc ();
/* Define STACK_DIRECTION if you know the direction of stack
growth for your system; otherwise it will be automatically
deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#ifndef STACK_DIRECTION
#define STACK_DIRECTION 0 /* Direction unknown. */
#endif
#if STACK_DIRECTION != 0
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
#else /* STACK_DIRECTION == 0; need run-time code. */
static int stack_dir; /* 1 or -1 once known. */
#define STACK_DIR stack_dir
static void
find_stack_direction ()
{
static char *addr = NULL; /* Address of first `dummy', once known. */
auto char dummy; /* To get stack address. */
if (addr == NULL)
{ /* Initial entry. */
addr = ADDRESS_FUNCTION (dummy);
find_stack_direction (); /* Recurse once. */
}
else
{
/* Second entry. */
if (ADDRESS_FUNCTION (dummy) > addr)
stack_dir = 1; /* Stack grew upward. */
else
stack_dir = -1; /* Stack grew downward. */
}
}
#endif /* STACK_DIRECTION == 0 */
/* An "alloca header" is used to:
(a) chain together all alloca'ed blocks;
(b) keep track of stack depth.
It is very important that sizeof(header) agree with malloc
alignment chunk size. The following default should work okay. */
#ifndef ALIGN_SIZE
#define ALIGN_SIZE sizeof(double)
#endif
typedef union hdr
{
char align[ALIGN_SIZE]; /* To force sizeof(header). */
struct
{
union hdr *next; /* For chaining headers. */
char *deep; /* For stack depth measure. */
} h;
} header;
static header *last_alloca_header = NULL; /* -> last alloca header. */
/* Return a pointer to at least SIZE bytes of storage,
which will be automatically reclaimed upon exit from
the procedure that called alloca. Originally, this space
was supposed to be taken from the current stack frame of the
caller, but that method cannot be made to work for some
implementations of C, for example under Gould's UTX/32. */
pointer
alloca (size)
unsigned size;
{
auto char probe; /* Probes stack depth: */
register char *depth = ADDRESS_FUNCTION (probe);
#if STACK_DIRECTION == 0
if (STACK_DIR == 0) /* Unknown growth direction. */
find_stack_direction ();
#endif
/* Reclaim garbage, defined as all alloca'd storage that
was allocated from deeper in the stack than currently. */
{
register header *hp; /* Traverses linked list. */
#ifdef emacs
BLOCK_INPUT;
#endif
for (hp = last_alloca_header; hp != NULL;)
if ((STACK_DIR > 0 && hp->h.deep > depth)
|| (STACK_DIR < 0 && hp->h.deep < depth))
{
register header *np = hp->h.next;
free ((pointer) hp); /* Collect garbage. */
hp = np; /* -> next header. */
}
else
break; /* Rest are not deeper. */
last_alloca_header = hp; /* -> last valid storage. */
#ifdef emacs
UNBLOCK_INPUT;
#endif
}
if (size == 0)
return NULL; /* No allocation required. */
/* Allocate combined header + user data storage. */
{
register pointer new = malloc (sizeof (header) + size);
/* Address of header. */
if (new == 0)
abort();
((header *) new)->h.next = last_alloca_header;
((header *) new)->h.deep = depth;
last_alloca_header = (header *) new;
/* User storage begins just after header. */
return (pointer) ((char *) new + sizeof (header));
}
}
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
#ifdef DEBUG_I00AFUNC
#include <stdio.h>
#endif
#ifndef CRAY_STACK
#define CRAY_STACK
#ifndef CRAY2
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
struct stack_control_header
{
long shgrow:32; /* Number of times stack has grown. */
long shaseg:32; /* Size of increments to stack. */
long shhwm:32; /* High water mark of stack. */
long shsize:32; /* Current size of stack (all segments). */
};
/* The stack segment linkage control information occurs at
the high-address end of a stack segment. (The stack
grows from low addresses to high addresses.) The initial
part of the stack segment linkage control information is
0200 (octal) words. This provides for register storage
for the routine which overflows the stack. */
struct stack_segment_linkage
{
long ss[0200]; /* 0200 overflow words. */
long sssize:32; /* Number of words in this segment. */
long ssbase:32; /* Offset to stack base. */
long:32;
long sspseg:32; /* Offset to linkage control of previous
segment of stack. */
long:32;
long sstcpt:32; /* Pointer to task common address block. */
long sscsnm; /* Private control structure number for
microtasking. */
long ssusr1; /* Reserved for user. */
long ssusr2; /* Reserved for user. */
long sstpid; /* Process ID for pid based multi-tasking. */
long ssgvup; /* Pointer to multitasking thread giveup. */
long sscray[7]; /* Reserved for Cray Research. */
long ssa0;
long ssa1;
long ssa2;
long ssa3;
long ssa4;
long ssa5;
long ssa6;
long ssa7;
long sss0;
long sss1;
long sss2;
long sss3;
long sss4;
long sss5;
long sss6;
long sss7;
};
#else /* CRAY2 */
/* The following structure defines the vector of words
returned by the STKSTAT library routine. */
struct stk_stat
{
long now; /* Current total stack size. */
long maxc; /* Amount of contiguous space which would
be required to satisfy the maximum
stack demand to date. */
long high_water; /* Stack high-water mark. */
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
long hits; /* Number of internal buffer hits. */
long extends; /* Number of block extensions. */
long stko_mallocs; /* Block allocations by $STKOFEN. */
long underflows; /* Number of stack underflow calls ($STKRETN). */
long stko_free; /* Number of deallocations by $STKRETN. */
long stkm_free; /* Number of deallocations by $STKMRET. */
long segments; /* Current number of stack segments. */
long maxs; /* Maximum number of stack segments so far. */
long pad_size; /* Stack pad size. */
long current_address; /* Current stack segment address. */
long current_size; /* Current stack segment size. This
number is actually corrupted by STKSTAT to
include the fifteen word trailer area. */
long initial_address; /* Address of initial segment. */
long initial_size; /* Size of initial segment. */
};
/* The following structure describes the data structure which trails
any stack segment. I think that the description in 'asdef' is
out of date. I only describe the parts that I am sure about. */
struct stk_trailer
{
long this_address; /* Address of this block. */
long this_size; /* Size of this block (does not include
this trailer). */
long unknown2;
long unknown3;
long link; /* Address of trailer block of previous
segment. */
long unknown5;
long unknown6;
long unknown7;
long unknown8;
long unknown9;
long unknown10;
long unknown11;
long unknown12;
long unknown13;
long unknown14;
};
#endif /* CRAY2 */
#endif /* not CRAY_STACK */
#ifdef CRAY2
/* Determine a "stack measure" for an arbitrary ADDRESS.
I doubt that "lint" will like this much. */
static long
i00afunc (long *address)
{
struct stk_stat status;
struct stk_trailer *trailer;
long *block, size;
long result = 0;
/* We want to iterate through all of the segments. The first
step is to get the stack status structure. We could do this
more quickly and more directly, perhaps, by referencing the
$LM00 common block, but I know that this works. */
STKSTAT (&status);
/* Set up the iteration. */
trailer = (struct stk_trailer *) (status.current_address
+ status.current_size
- 15);
/* There must be at least one stack segment. Therefore it is
a fatal error if "trailer" is null. */
if (trailer == 0)
abort ();
/* Discard segments that do not contain our argument address. */
while (trailer != 0)
{
block = (long *) trailer->this_address;
size = trailer->this_size;
if (block == 0 || size == 0)
abort ();
trailer = (struct stk_trailer *) trailer->link;
if ((block <= address) && (address < (block + size)))
break;
}
/* Set the result to the offset in this segment and add the sizes
of all predecessor segments. */
result = address - block;
if (trailer == 0)
{
return result;
}
do
{
if (trailer->this_size <= 0)
abort ();
result += trailer->this_size;
trailer = (struct stk_trailer *) trailer->link;
}
while (trailer != 0);
/* We are done. Note that if you present a bogus address (one
not in any segment), you will get a different number back, formed
from subtracting the address of the first block. This is probably
not what you want. */
return (result);
}
#else /* not CRAY2 */
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
Determine the number of the cell within the stack,
given the address of the cell. The purpose of this
routine is to linearize, in some sense, stack addresses
for alloca. */
static long
i00afunc (long address)
{
long stkl = 0;
long size, pseg, this_segment, stack;
long result = 0;
struct stack_segment_linkage *ssptr;
/* Register B67 contains the address of the end of the
current stack segment. If you (as a subprogram) store
your registers on the stack and find that you are past
the contents of B67, you have overflowed the segment.
B67 also points to the stack segment linkage control
area, which is what we are really interested in. */
stkl = CRAY_STACKSEG_END ();
ssptr = (struct stack_segment_linkage *) stkl;
/* If one subtracts 'size' from the end of the segment,
one has the address of the first word of the segment.
If this is not the first segment, 'pseg' will be
nonzero. */
pseg = ssptr->sspseg;
size = ssptr->sssize;
this_segment = stkl - size;
/* It is possible that calling this routine itself caused
a stack overflow. Discard stack segments which do not
contain the target address. */
while (!(this_segment <= address && address <= stkl))
{
#ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
#endif
if (pseg == 0)
break;
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
this_segment = stkl - size;
}
result = address - this_segment;
/* If you subtract pseg from the current end of the stack,
you get the address of the previous stack segment's end.
This seems a little convoluted to me, but I'll bet you save
a cycle somewhere. */
while (pseg != 0)
{
#ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o\n", pseg, size);
#endif
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
result += size;
}
return (result);
}
#endif /* not CRAY2 */
#endif /* CRAY */
#endif /* no alloca */
#endif /* not GCC version 2 */

View file

@ -1,992 +0,0 @@
/* Output bytecodes for GNU C-compiler.
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "machmode.h"
#include "rtl.h"
#include "real.h"
#include "obstack.h"
#include "bytecode.h"
#ifdef __GNUC__
#include "bytetypes.h"
#endif
#include "bc-emit.h"
#include "bc-opcode.h"
#include "bc-typecd.h"
#include "bi-run.h"
#include <stdio.h>
extern char *xmalloc (), *xrealloc ();
extern void free ();
extern struct obstack *rtl_obstack;
/* Indexed by mode class, gives the narrowest mode for each class. */
extern enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
/* Commonly used modes. */
/* Mode whose width is BITS_PER_UNIT */
extern enum machine_mode byte_mode;
/* Mode whose width is BITS_PER_WORD */
extern enum machine_mode word_mode;
/* Vector indexed by opcode giving info about the args for each opcode. */
static struct arityvec arityvec[] = {
#include "bc-arity.h"
};
/* How to print a symbol name for the assembler. */
static void
prsym (file, s)
FILE *file;
char *s;
{
if (*s == '*')
fprintf (file, "%s", s + 1);
else
#ifdef NAMES_HAVE_UNDERSCORES
fprintf (file, "_%s", s);
#else
fprintf (file, "%s", s);
#endif
}
/* Maintain a bucket hash table for symbol names. */
#define HASH_BITS 32
#define HASH_SIZE 509
static struct bc_sym *hashtab[HASH_SIZE];
static unsigned int
hash (name)
char *name;
{
unsigned int hash = 0;
while (*name)
{
hash = hash << 3 | hash >> HASH_BITS - 3;
hash += *name++;
}
return hash % HASH_SIZE;
}
/* Look up the named symbol, creating it if it doesn't exist. */
struct bc_sym *
sym_lookup (name)
char *name;
{
int i;
struct bc_sym *s;
i = hash (name);
for (s = hashtab[i]; s; s = s->next)
if (!strcmp (s->name, name))
return s;
s = (struct bc_sym *) xmalloc (sizeof (struct bc_sym));
s->name = xmalloc (strlen (name) + 1);
strcpy (s->name, name);
s->defined = s->global = s->common = 0;
s->val = 0;
s->next = hashtab[i];
hashtab[i] = s;
return s;
}
/* Write out .globl and common symbols to the named file. */
static void
bc_sym_write (file)
FILE *file;
{
int i;
struct bc_sym *s;
for (i = 0; i < HASH_SIZE; ++i)
for (s = hashtab[i]; s; s = s->next)
{
if (s->global)
{
fprintf (file, "\n\t.globl ");
prsym (file, s->name);
putc ('\n', file);
if (s->common)
{
fprintf (file, "\n\t.comm ");
prsym (file, s->name);
fprintf (file, ", %lu\n", s->val);
}
}
else if (s->common)
{
fprintf (file, "\n\t.lcomm ");
prsym (file, s->name);
fprintf (file, ", %lu\n", s->val);
}
}
}
/* Create and initialize a new segment. */
static struct bc_seg *
seg_create ()
{
struct bc_seg *result;
result = (struct bc_seg *) xmalloc (sizeof (struct bc_seg));
result->alloc = 256;
result->data = xmalloc (result->alloc);
result->size = 0;
result->syms = 0;
result->relocs = 0;
return result;
}
/* Advance the segment index to the next alignment boundary. */
static void
seg_align (seg, log)
struct bc_seg *seg;
int log;
{
unsigned int oldsize = seg->size;
seg->size = seg->size + (1 << log) - 1 & ~((1 << log) - 1);
if (seg->size > seg->alloc)
{
while (seg->size > seg->alloc)
seg->alloc *= 2;
seg->data = xrealloc (seg->data, seg->alloc);
}
bzero (seg->data + oldsize, seg->size - oldsize);
}
/* Append the given data to the given segment. */
static void
seg_data (seg, data, size)
struct bc_seg *seg;
char *data;
unsigned int size;
{
if (seg->size + size > seg->alloc)
{
while (seg->size + size > seg->alloc)
seg->alloc *= 2;
seg->data = xrealloc (seg->data, seg->alloc);
}
bcopy (data, seg->data + seg->size, size);
seg->size += size;
}
/* Append a zero-filled skip to the given segment. */
static void
seg_skip (seg, size)
struct bc_seg *seg;
unsigned int size;
{
if (seg->size + size > seg->alloc)
{
while (seg->size + size > seg->alloc)
seg->alloc *= 2;
seg->data = xrealloc (seg->data, seg->alloc);
}
memset (seg->data + seg->size, 0, size);
seg->size += size;
}
/* Define the given name as the current offset in the given segment. It
is an error if the name is already defined. Return 0 or 1 indicating
failure or success respectively. */
static int
seg_defsym (seg, name)
struct bc_seg *seg;
char *name;
{
struct bc_sym *sym;
struct bc_segsym *segsym;
sym = sym_lookup (name);
if (sym->defined)
return 0;
sym->defined = 1;
sym->val = seg->size;
segsym = (struct bc_segsym *) xmalloc (sizeof (struct bc_segsym));
segsym->sym = sym;
segsym->next = seg->syms;
seg->syms = segsym;
return 1;
}
/* Generate in seg's data a reference to the given sym, adjusted by
the given offset. */
static void
seg_refsym (seg, name, offset)
struct bc_seg *seg;
char *name;
int offset;
{
struct bc_sym *sym;
struct bc_segreloc *segreloc;
sym = sym_lookup (name);
segreloc = (struct bc_segreloc *) xmalloc (sizeof (struct bc_segreloc));
segreloc->offset = seg->size;
segreloc->sym = sym;
segreloc->next = seg->relocs;
seg->relocs = segreloc;
seg_data (seg, (char *) &offset, sizeof offset);
}
/* Concatenate the contents of given segments into the first argument. */
static void
seg_concat (result, seg)
struct bc_seg *result, *seg;
{
unsigned int fix;
struct bc_segsym *segsym;
struct bc_segreloc *segreloc;
seg_align (result, MACHINE_SEG_ALIGN);
fix = result->size;
seg_data (result, seg->data, seg->size);
free (seg->data);
/* Go through the symbols and relocs of SEG, adjusting their offsets
for their new location in RESULT. */
if (seg->syms)
{
segsym = seg->syms;
do
segsym->sym->val += fix;
while (segsym->next && (segsym = segsym->next));
segsym->next = result->syms;
result->syms = seg->syms;
}
if (seg->relocs)
{
segreloc = seg->relocs;
do
segreloc->offset += fix;
while (segreloc->next && (segreloc = segreloc->next));
segreloc->next = result->relocs;
result->relocs = seg->relocs;
}
free ((char *) seg);
}
/* Write a segment to a file. */
static void
bc_seg_write (seg, file)
struct bc_seg *seg;
FILE *file;
{
struct bc_segsym *segsym, *nsegsym, *psegsym;
struct bc_segreloc *segreloc, *nsegreloc, *psegreloc;
int i, offset, flag;
/* Reverse the list of symbols. */
for (psegsym = 0, segsym = seg->syms; segsym; segsym = nsegsym)
{
nsegsym = segsym->next;
segsym->next = psegsym;
psegsym = segsym;
}
seg->syms = psegsym;
/* Reverse the list of relocs. */
for (psegreloc = 0, segreloc = seg->relocs; segreloc; segreloc = nsegreloc)
{
nsegreloc = segreloc->next;
segreloc->next = psegreloc;
psegreloc = segreloc;
}
seg->relocs = psegreloc;
/* Output each byte of the segment. */
for (i = 0, segsym = seg->syms, segreloc = seg->relocs; i < seg->size; ++i)
{
while (segsym && segsym->sym->val == i)
{
if (i % 8 != 0)
putc ('\n', file);
BC_WRITE_SEGSYM (segsym, file);
segsym = segsym->next;
flag = 1;
}
if (segreloc && segreloc->offset == i)
{
if (i % 8 != 0)
putc ('\n', file);
bcopy (seg->data + i, (char *) &offset, sizeof (int));
i += sizeof (int) - 1;
BC_WRITE_RELOC_ENTRY (segreloc, file, offset);
segreloc = segreloc->next;
flag = 1;
}
else
{
if (i % 8 == 0 || flag)
BC_START_BYTECODE_LINE (file);
BC_WRITE_BYTECODE (i % 8 == 0 || flag ? ' ' : ',',
seg->data[i] & 0xFF,
file);
flag = 0;
if (i % 8 == 7)
putc ('\n', file);
}
}
/* Paranoia check--we should have visited all syms and relocs during
the output pass. */
if (segsym || segreloc)
abort ();
}
/* Text and data segments of the object file in making. */
static struct bc_seg *bc_text_seg;
static struct bc_seg *bc_data_seg;
/* Called before anything else in this module. */
void
bc_initialize ()
{
int min_class_size[(int) MAX_MODE_CLASS];
enum machine_mode mode;
int i;
bc_init_mode_to_code_map ();
bc_text_seg = seg_create ();
bc_data_seg = seg_create ();
dconst0 = REAL_VALUE_ATOF ("0", DFmode);
dconst1 = REAL_VALUE_ATOF ("1", DFmode);
dconst2 = REAL_VALUE_ATOF ("2", DFmode);
dconstm1 = REAL_VALUE_ATOF ("-1", DFmode);
/* Find the narrowest mode for each class and compute the word and byte
modes. */
for (i = 0; i < (int) MAX_MODE_CLASS; i++)
min_class_size[i] = 1000;
for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
mode = (enum machine_mode) ((int) mode + 1))
{
if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
{
class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
}
if (GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_BITSIZE (mode) == BITS_PER_UNIT)
byte_mode = mode;
if (GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_BITSIZE (mode) == BITS_PER_WORD)
word_mode = mode;
}
}
/* External addresses referenced in a function. Rather than trying to
work relocatable address directly into bytecoded functions (which would
require us to provide hairy location info and possibly obey alignment
rules imposed by the architecture) we build an auxiliary table of
pointer constants, and encode just offsets into this table into the
actual bytecode. */
static struct bc_seg *ptrconsts;
/* Trampoline code for the function entry. */
struct bc_seg *trampoline;
/* Actual byte code of the function. */
struct bc_seg *bytecode;
/* List of labels defined in the function. */
struct bc_label *labels;
/* List of label references in the function. */
struct bc_labelref *labelrefs;
/* Add symbol to pointer table. Return offset into table where
pointer was stored. The offset usually goes into the bytecode
stream as a constP literal. */
int
bc_define_pointer (p)
char *p;
{
int offset = ptrconsts->size;
seg_refsym (ptrconsts, p, 0);
return offset;
}
/* Begin a bytecoded function. */
int
bc_begin_function (name)
char *name;
{
ptrconsts = seg_create ();
trampoline = seg_create ();
bytecode = seg_create ();
return seg_defsym (trampoline, name);
}
/* Force alignment in inline bytecode. */
void
bc_align_bytecode (align)
int align;
{
seg_align (bytecode, align);
}
/* Emit data inline into bytecode. */
void
bc_emit_bytecode_const (data, size)
char *data;
unsigned int size;
{
if (bytecode)
seg_data (bytecode, data, size);
}
/* Create a new "bytecode label", to have its value defined later.
Bytecode labels have nothing to do with the object file symbol table,
and are purely local to a given bytecoded function. */
struct bc_label *
bc_get_bytecode_label ()
{
struct bc_label *result;
result = (struct bc_label *) xmalloc (sizeof (struct bc_label));
result->defined = 0;
result->next = labels;
result->uid = 0;
labels = result;
return result;
}
/* Define the given label with the current location counter. */
int
bc_emit_bytecode_labeldef (label)
struct bc_label *label;
{
extern int bc_new_uid ();
if (!label || label->defined)
return 0;
label->offset = bytecode->size;
label->defined = 1;
label->uid = bc_new_uid ();
#ifdef DEBUG_PRINT_CODE
fprintf (stderr, "$%lx:\n", label);
#endif
return 1;
}
/* Generate a location-relative reference to the given bytecode label.
It need not be defined yet; label references will be backpatched later. */
void
bc_emit_bytecode_labelref (label)
struct bc_label *label;
{
struct bc_labelref *labelref;
static int zero;
labelref = (struct bc_labelref *) xmalloc (sizeof (struct bc_labelref));
labelref->label = label;
labelref->offset = bytecode->size;
labelref->next = labelrefs;
labelrefs = labelref;
#ifdef DEBUG_PRINT_CODE
fprintf (stderr, " $%lx", label);
#endif
seg_data (bytecode, (char *) &zero, sizeof zero);
}
/* Emit a reference to an external address; generate the reference in the
ptrconst area, and emit an offset in the bytecode. */
void
bc_emit_code_labelref (name, offset)
char *name;
int offset;
{
int ptroff;
ptroff = ptrconsts->size / sizeof (char *);
seg_data (bytecode, (char *) &ptroff, sizeof ptroff);
seg_refsym (ptrconsts, name, offset);
#ifdef DEBUG_PRINT_CODE
fprintf (stderr, " [external <%x> %s]", ptroff, name);
#endif
}
/* Backpatch label references in the byte code, and concatenate the bytecode
and pointer constant segments to the cumulative text for the object file.
Return a label name for the pointer constants region. */
char *
bc_end_function ()
{
int addr;
struct bc_label *label, *next;
struct bc_labelref *ref, *nextref;
char ptrconsts_label[20];
static int nlab;
/* Backpatch bytecode label references. */
for (ref = labelrefs; ref; ref = ref->next)
if (ref->label->defined)
{
addr = ref->label->offset;
bcopy ((char *) &addr, bytecode->data + ref->offset, sizeof addr);
}
/* Free the chains of labelrefs and labeldefs. */
for (ref = labelrefs; ref; ref = nextref)
{
nextref = ref->next;
free ((char *) ref);
}
for (label = labels; label; label = next)
{
next = label->next;
free ((char *) label);
}
seg_concat (trampoline, bytecode);
seg_align (trampoline, MACHINE_SEG_ALIGN);
sprintf (ptrconsts_label, "*LP%d", nlab++);
seg_defsym (trampoline, ptrconsts_label);
seg_concat (trampoline, ptrconsts);
seg_concat (bc_text_seg, trampoline);
labels = 0;
labelrefs = 0;
trampoline = 0;
bytecode = 0;
ptrconsts = 0;
return sym_lookup (ptrconsts_label)->name;
}
/* Force alignment in const data. */
void
bc_align_const (align)
int align;
{
seg_align (bc_text_seg, align);
}
/* Emit const data. */
void
bc_emit_const (data, size)
char *data;
unsigned int size;
{
seg_data (bc_text_seg, data, size);
}
/* Emit a zero-filled constant skip. */
void
bc_emit_const_skip (size)
unsigned int size;
{
seg_skip (bc_text_seg, size);
}
/* Emit a label definition in const data. */
int
bc_emit_const_labeldef (name)
char *name;
{
return seg_defsym (bc_text_seg, name);
}
/* Emit a label reference in const data. */
void
bc_emit_const_labelref (name, offset)
char *name;
int offset;
{
seg_refsym (bc_text_seg, name, offset);
}
/* Force alignment in data. */
void
bc_align_data (align)
int align;
{
seg_align (bc_data_seg, align);
}
/* Emit data. */
void
bc_emit_data (data, size)
char *data;
unsigned int size;
{
seg_data (bc_data_seg, data, size);
}
/* Emit a zero-filled data skip. */
void
bc_emit_data_skip (size)
unsigned int size;
{
seg_skip (bc_data_seg, size);
}
/* Emit label definition in data. */
int
bc_emit_data_labeldef (name)
char *name;
{
return seg_defsym (bc_data_seg, name);
}
/* Emit label reference in data. */
void
bc_emit_data_labelref (name, offset)
char *name;
int offset;
{
seg_refsym (bc_data_seg, name, offset);
}
/* Emit a common block of the given name and size. Note that
when the .o file is actually written non-global "common"
blocks will have to be turned into space in the data section. */
int
bc_emit_common (name, size)
char *name;
unsigned int size;
{
struct bc_sym *sym;
sym = sym_lookup (name);
if (sym->defined)
return 0;
sym->defined = 1;
sym->common = 1;
sym->val = size;
return 1;
}
/* Globalize the given label. */
void
bc_globalize_label (name)
char *name;
{
struct bc_sym *sym;
sym = sym_lookup (name);
sym->global = 1;
}
static enum { in_text, in_data } section = in_text;
void
bc_text ()
{
section = in_text;
}
void
bc_data ()
{
section = in_data;
}
void
bc_align (align)
int align;
{
if (section == in_text)
bc_align_const (align);
else
bc_align_data (align);
}
void
bc_emit (data, size)
char *data;
unsigned int size;
{
if (section == in_text)
bc_emit_const (data, size);
else
bc_emit_data (data, size);
}
void
bc_emit_skip (size)
unsigned int size;
{
if (section == in_text)
bc_emit_const_skip (size);
else
bc_emit_data_skip (size);
}
int
bc_emit_labeldef (name)
char *name;
{
if (section == in_text)
return bc_emit_const_labeldef (name);
else
return bc_emit_data_labeldef (name);
}
void
bc_emit_labelref (name, offset)
char *name;
int offset;
{
if (section == in_text)
bc_emit_const_labelref (name, offset);
else
bc_emit_data_labelref (name, offset);
}
void
bc_write_file (file)
FILE *file;
{
BC_WRITE_FILE (file);
}
/* Allocate a new bytecode rtx.
If you supply a null BC_LABEL, we generate one. */
rtx
bc_gen_rtx (label, offset, bc_label)
char *label;
int offset;
struct bc_label *bc_label;
{
rtx r;
if (bc_label == 0)
bc_label = (struct bc_label *) xmalloc (sizeof (struct bc_label));
r = gen_rtx (CODE_LABEL, VOIDmode, label, bc_label);
bc_label->offset = offset;
return r;
}
/* Print bytecode rtx */
void
bc_print_rtl (fp, r)
FILE *fp;
rtx r;
{
#if 0 /* This needs to get fixed to really work again. */
/* BC_WRITE_RTL has a definition
that doesn't even make sense for this use. */
BC_WRITE_RTL (r, fp);
#endif
}
/* Emit a bytecode, keeping a running tally of the stack depth. */
void
bc_emit_bytecode (bytecode)
enum bytecode_opcode bytecode;
{
char byte;
static int prev_lineno = -1;
byte = (char) bytecode;
#ifdef BCDEBUG_PRINT_CODE
if (lineno != prev_lineno)
{
fprintf (stderr, "<line %d>\n", lineno);
prev_lineno = lineno;
}
fputs (opcode_name[(unsigned int) bytecode], stderr);
#endif
/* Due to errors we are often requested to output bytecodes that
will cause an interpreter stack undeflow when executed. Instead of
dumping core on such occasions, we omit the bytecode. Erroneous code
should not be executed, regardless. This makes life much easier, since
we don't have to deceive ourselves about the known stack depth. */
bc_emit_bytecode_const (&byte, 1);
if ((stack_depth -= arityvec[(int) bytecode].ninputs) >= 0)
{
if ((stack_depth += arityvec[(int) bytecode].noutputs) > max_stack_depth)
max_stack_depth = stack_depth;
}
#ifdef VALIDATE_STACK_FOR_BC
VALIDATE_STACK_FOR_BC ();
#endif
}
#ifdef BCDEBUG_PRINT_CODE
#define PRLIT(TYPE, PTR) fprintf (stderr, " [%x]", *(TYPE *) PTR)
#else
#define PRLIT(X,Y)
#endif
/* Emit a complete bytecode instruction, expecting the correct number
of literal values in the call. First argument is the instruction, the
remaining arguments are literals of size HOST_WIDE_INT or smaller. */
void
bc_emit_instruction VPROTO((enum bytecode_opcode opcode, ...))
{
#ifndef __STDC__
enum bytecode_opcode opcode;
#endif
va_list arguments;
int nliteral, instruction;
VA_START (arguments, opcode);
#ifndef __STDC__
opcode = va_arg (arguments, enum bytecode_opcode);
#endif
/* Emit instruction bytecode */
bc_emit_bytecode (opcode);
instruction = (int) opcode;
/* Loop literals and emit as bytecode constants */
for (nliteral = 0; nliteral < arityvec[instruction].nliterals; nliteral++)
{
switch (arityvec[instruction].literals[nliteral])
{
/* This conditional is a kludge, but it's necessary
because TYPE might be long long. */
#ifdef __GNUC__
/* Expand definitions into case statements */
#define DEFTYPECODE(CODE, NAME, MODE, TYPE) \
case CODE: \
{ \
TYPE temp = va_arg (arguments, TYPE); \
bc_emit_bytecode_const ((void *) &temp, sizeof temp); \
PRLIT (TYPE, &temp); } \
break;
#include "bc-typecd.def"
#undef DEFTYPECODE
#endif /* __GNUC__ */
default:
abort ();
}
}
#ifdef BCDEBUG_PRINT_CODE
fputc ('\n', stderr);
#endif
}
/* Emit the machine-code interface trampoline at the beginning of a byte
coded function. The argument is a label name of the interpreter
bytecode callinfo structure; the return value is a label name for
the beginning of the actual bytecode. */
char *
bc_emit_trampoline (callinfo)
char *callinfo;
{
char mylab[20];
static int n;
sprintf (mylab, "*LB%d", n++);
BC_EMIT_TRAMPOLINE (trampoline, callinfo);
seg_defsym (bytecode, mylab);
return sym_lookup (mylab)->name;
}
/* Simple strdup */
char *
bc_xstrdup (str)
char *str;
{
char *tmp = xmalloc (strlen (str) + 1);
strcpy (tmp, str);
return tmp;
}

View file

@ -1,133 +0,0 @@
/* bc-emit.h - declare entry points for producing object files of bytecodes. */
/* Internal format of symbol table for the object file. */
struct bc_sym
{
/* Private copy separately malloc'd. */
char *name;
/* Symbol has a defined value. */
unsigned int defined:1;
/* Symbol has been globalized. */
unsigned int global:1;
/* Symbol is common. */
unsigned int common:1;
/* Value if defined. */
unsigned long int val;
/* Used in internal symbol table structure. */
struct bc_sym *next;
};
/* List of symbols defined in a particular segment. */
struct bc_segsym
{
struct bc_sym *sym;
struct bc_segsym *next;
};
/* List of relocations needed in a particular segment. */
struct bc_segreloc
{
/* Offset of datum to be relocated. */
unsigned int offset;
/* Symbol to be relocated by. */
struct bc_sym *sym;
struct bc_segreloc *next;
};
/* Segment of an object file. */
struct bc_seg
{
/* Size allocated to contents. */
unsigned int alloc;
/* Pointer to base of contents. */
char *data;
/* Actual size of contents. */
unsigned int size;
/* List of symbols defined in this segment. */
struct bc_segsym *syms;
/* List of relocations for this segment. */
struct bc_segreloc *relocs;
};
/* Anonymous bytecode label within a single function. */
struct bc_label
{
/* Offset of label from start of segment. */
unsigned int offset;
/* True when offset is valid. */
unsigned int defined:1;
/* Unique bytecode ID, used to determine innermost
block containment */
int uid;
/* Next node in list */
struct bc_label *next;
};
/* Reference to a bc_label; a list of all such references is kept for
the function, then when it is finished they are backpatched to
contain the correct values. */
struct bc_labelref
{
/* Label referenced. */
struct bc_label *label;
/* Code offset of reference. */
unsigned int offset;
/* Next labelref in list */
struct bc_labelref *next;
};
extern void bc_initialize();
extern int bc_begin_function();
extern char *bc_emit_trampoline();
extern void bc_emit_bytecode();
extern void bc_emit_bytecode_const();
extern struct bc_label *bc_get_bytecode_label();
extern int bc_emit_bytecode_labeldef();
extern void bc_emit_bytecode_labelref();
extern void bc_emit_code_labelref();
extern char *bc_end_function();
extern void bc_align_const();
extern void bc_emit_const();
extern void bc_emit_const_skip();
extern int bc_emit_const_labeldef();
extern void bc_emit_const_labelref();
extern void bc_align_data();
extern void bc_emit_data();
extern void bc_emit_data_skip();
extern int bc_emit_data_labeldef();
extern void bc_emit_data_labelref();
extern int bc_define_pointer ();
extern int bc_emit_common();
extern void bc_globalize_label();
extern void bc_text();
extern void bc_data();
extern void bc_align();
extern void bc_emit();
extern void bc_emit_skip();
extern int bc_emit_labeldef();
extern void bc_emit_labelref();
extern void bc_write_file();

View file

@ -1,789 +0,0 @@
/* Bytecode conversion definitions for GNU C-compiler.
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "tree.h"
#include "rtl.h"
#include "machmode.h"
#include "obstack.h"
#include "bytecode.h"
#include "bc-typecd.h"
#include "bc-opcode.h"
#include "bc-optab.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
extern char *xmalloc ();
extern void free ();
/* Table relating interpreter typecodes to machine modes. */
#define GET_TYPECODE_MODE(CODE) (typecode_mode[((int) CODE)])
enum machine_mode typecode_mode[] = {
#define DEFTYPECODE(CODE, NAME, MODE, TYPE) MODE,
#include "bc-typecd.def"
#undef DEFTYPECODE
};
/* Machine mode to type code map */
static enum typecode signed_mode_to_code_map[MAX_MACHINE_MODE+1];
static enum typecode unsigned_mode_to_code_map[MAX_MACHINE_MODE+1];
#define GET_TYPECODE_SIZE(CODE) GET_MODE_SIZE (GET_TYPECODE_MODE (CODE))
#define BIG_ARBITRARY_NUMBER 100000
/* Table of recipes for conversions among scalar types, to be filled
in as needed at run time. */
static struct conversion_recipe
{
unsigned char *opcodes; /* Bytecodes to emit in order. */
int nopcodes; /* Count of bytecodes. */
int cost; /* A rather arbitrary cost function. */
} conversion_recipe[NUM_TYPECODES][NUM_TYPECODES];
/* Binary operator tables. */
struct binary_operator optab_plus_expr[] = {
{ addSI, SIcode, SIcode, SIcode },
{ addDI, DIcode, DIcode, DIcode },
{ addSF, SFcode, SFcode, SFcode },
{ addDF, DFcode, DFcode, DFcode },
{ addXF, XFcode, XFcode, XFcode },
{ addPSI, Pcode, Pcode, SIcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_minus_expr[] = {
{ subSI, SIcode, SIcode, SIcode },
{ subDI, DIcode, DIcode, DIcode },
{ subSF, SFcode, SFcode, SFcode },
{ subDF, DFcode, DFcode, DFcode },
{ subXF, XFcode, XFcode, XFcode },
{ subPP, SIcode, Pcode, Pcode },
{ -1, -1, -1, -1 },
};
/* The ordering of the tables for multiplicative operators
is such that unsigned operations will be preferred to signed
operations when one argument is unsigned. */
struct binary_operator optab_mult_expr[] = {
{ mulSU, SUcode, SUcode, SUcode },
{ mulDU, DUcode, DUcode, DUcode },
{ mulSI, SIcode, SIcode, SIcode },
{ mulDI, DIcode, DIcode, DIcode },
{ mulSF, SFcode, SFcode, SFcode },
{ mulDF, DFcode, DFcode, DFcode },
{ mulXF, XFcode, XFcode, XFcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_trunc_div_expr[] = {
{ divSU, SUcode, SUcode, SUcode },
{ divDU, DUcode, DUcode, DUcode },
{ divSI, SIcode, SIcode, SIcode },
{ divDI, DIcode, DIcode, DIcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_trunc_mod_expr[] = {
{ modSU, SUcode, SUcode, SUcode },
{ modDU, DUcode, DUcode, DUcode },
{ modSI, SIcode, SIcode, SIcode },
{ modDI, DIcode, DIcode, DIcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_rdiv_expr[] = {
{ divSF, SFcode, SFcode, SFcode },
{ divDF, DFcode, DFcode, DFcode },
{ divXF, XFcode, XFcode, XFcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_bit_and_expr[] = {
{ andSI, SIcode, SIcode, SIcode },
{ andDI, DIcode, DIcode, DIcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_bit_ior_expr[] = {
{ iorSI, SIcode, SIcode, SIcode },
{ iorDI, DIcode, DIcode, DIcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_bit_xor_expr[] = {
{ xorSI, SIcode, SIcode, SIcode },
{ xorDI, DIcode, DIcode, DIcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_lshift_expr[] = {
{ lshiftSI, SIcode, SIcode, SIcode },
{ lshiftSU, SUcode, SUcode, SIcode },
{ lshiftDI, DIcode, DIcode, SIcode },
{ lshiftDU, DUcode, DUcode, SIcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_rshift_expr[] = {
{ rshiftSI, SIcode, SIcode, SIcode },
{ rshiftSU, SUcode, SUcode, SIcode },
{ rshiftDI, DIcode, DIcode, SIcode },
{ rshiftDU, DUcode, DUcode, SIcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_truth_and_expr[] = {
{ andSI, SIcode, Tcode, Tcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_truth_or_expr[] = {
{ iorSI, SIcode, Tcode, Tcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_lt_expr[] = {
{ ltSI, Tcode, SIcode, SIcode },
{ ltSU, Tcode, SUcode, SUcode },
{ ltDI, Tcode, DIcode, DIcode },
{ ltDU, Tcode, DUcode, DUcode },
{ ltSF, Tcode, SFcode, SFcode },
{ ltDF, Tcode, DFcode, DFcode },
{ ltXF, Tcode, XFcode, XFcode },
{ ltP, Tcode, Pcode, Pcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_le_expr[] = {
{ leSI, Tcode, SIcode, SIcode },
{ leSU, Tcode, SUcode, SUcode },
{ leDI, Tcode, DIcode, DIcode },
{ leDU, Tcode, DUcode, DUcode },
{ leSF, Tcode, SFcode, SFcode },
{ leDF, Tcode, DFcode, DFcode },
{ leXF, Tcode, XFcode, XFcode },
{ leP, Tcode, Pcode, Pcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_ge_expr[] = {
{ geSI, Tcode, SIcode, SIcode },
{ geSU, Tcode, SUcode, SUcode },
{ geDI, Tcode, DIcode, DIcode },
{ geDU, Tcode, DUcode, DUcode },
{ geSF, Tcode, SFcode, SFcode },
{ geDF, Tcode, DFcode, DFcode },
{ geXF, Tcode, XFcode, XFcode },
{ geP, Tcode, Pcode, Pcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_gt_expr[] = {
{ gtSI, Tcode, SIcode, SIcode },
{ gtSU, Tcode, SUcode, SUcode },
{ gtDI, Tcode, DIcode, DIcode },
{ gtDU, Tcode, DUcode, DUcode },
{ gtSF, Tcode, SFcode, SFcode },
{ gtDF, Tcode, DFcode, DFcode },
{ gtXF, Tcode, XFcode, XFcode },
{ gtP, Tcode, Pcode, Pcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_eq_expr[] = {
{ eqSI, Tcode, SIcode, SIcode },
{ eqDI, Tcode, DIcode, DIcode },
{ eqSF, Tcode, SFcode, SFcode },
{ eqDF, Tcode, DFcode, DFcode },
{ eqXF, Tcode, XFcode, XFcode },
{ eqP, Tcode, Pcode, Pcode },
{ -1, -1, -1, -1 },
};
struct binary_operator optab_ne_expr[] = {
{ neSI, Tcode, SIcode, SIcode },
{ neDI, Tcode, DIcode, DIcode },
{ neSF, Tcode, SFcode, SFcode },
{ neDF, Tcode, DFcode, DFcode },
{ neXF, Tcode, XFcode, XFcode },
{ neP, Tcode, Pcode, Pcode },
{ -1, -1, -1, -1 },
};
/* Unary operator tables. */
struct unary_operator optab_negate_expr[] = {
{ negSI, SIcode, SIcode },
{ negDI, DIcode, DIcode },
{ negSF, SFcode, SFcode },
{ negDF, DFcode, DFcode },
{ negXF, XFcode, XFcode },
{ -1, -1, -1 },
};
struct unary_operator optab_bit_not_expr[] = {
{ notSI, SIcode, SIcode },
{ notDI, DIcode, DIcode },
{ -1, -1, -1 },
};
struct unary_operator optab_truth_not_expr[] = {
{ notT, SIcode, SIcode },
{ -1, -1, -1 },
};
/* Increment operator tables. */
struct increment_operator optab_predecrement_expr[] = {
{ predecQI, QIcode },
{ predecQI, QUcode },
{ predecHI, HIcode },
{ predecHI, HUcode },
{ predecSI, SIcode },
{ predecSI, SUcode },
{ predecDI, DIcode },
{ predecDI, DUcode },
{ predecP, Pcode },
{ predecSF, SFcode },
{ predecDF, DFcode },
{ predecXF, XFcode },
{ -1, -1 },
};
struct increment_operator optab_preincrement_expr[] = {
{ preincQI, QIcode },
{ preincQI, QUcode },
{ preincHI, HIcode },
{ preincHI, HUcode },
{ preincSI, SIcode },
{ preincSI, SUcode },
{ preincDI, DIcode },
{ preincDI, DUcode },
{ preincP, Pcode },
{ preincSF, SFcode },
{ preincDF, DFcode },
{ preincXF, XFcode },
{ -1, -1 },
};
struct increment_operator optab_postdecrement_expr[] = {
{ postdecQI, QIcode },
{ postdecQI, QUcode },
{ postdecHI, HIcode },
{ postdecHI, HUcode },
{ postdecSI, SIcode },
{ postdecSI, SUcode },
{ postdecDI, DIcode },
{ postdecDI, DUcode },
{ postdecP, Pcode },
{ postdecSF, SFcode },
{ postdecDF, DFcode },
{ postdecXF, XFcode },
{ -1, -1 },
};
struct increment_operator optab_postincrement_expr[] = {
{ postincQI, QIcode },
{ postincQI, QUcode },
{ postincHI, HIcode },
{ postincHI, HUcode },
{ postincSI, SIcode },
{ postincSI, SUcode },
{ postincDI, DIcode },
{ postincDI, DUcode },
{ postincP, Pcode },
{ postincSF, SFcode },
{ postincDF, DFcode },
{ postincXF, XFcode },
{ -1, -1 },
};
/* Table of conversions supported by the interpreter. */
static struct conversion_info
{
enum bytecode_opcode opcode; /* here indicates the conversion needs no opcode. */
enum typecode from;
enum typecode to;
int cost; /* 1 for no-op conversions, 2 for widening conversions,
4 for int/float conversions, 8 for narrowing conversions. */
} conversion_info[] = {
{ -1, QIcode, QUcode, 1 },
{ -1, HIcode, HUcode, 1 },
{ -1, SIcode, SUcode, 1 },
{ -1, DIcode, DUcode, 1 },
{ -1, QUcode, QIcode, 1 },
{ -1, HUcode, HIcode, 1 },
{ -1, SUcode, SIcode, 1 },
{ -1, DUcode, DIcode, 1 },
{ -1, Tcode, SIcode, 1 },
{ convertQIHI, QIcode, HIcode, 2 },
{ convertQUHU, QUcode, HUcode, 2 },
{ convertQUSU, QUcode, SUcode, 2 },
{ convertHISI, HIcode, SIcode, 2 },
{ convertHUSU, HUcode, SUcode, 2 },
{ convertSIDI, SIcode, DIcode, 2 },
{ convertSUDU, SUcode, DUcode, 2 },
{ convertSFDF, SFcode, DFcode, 2 },
{ convertDFXF, DFcode, XFcode, 2 },
{ convertHIQI, HIcode, QIcode, 8 },
{ convertSIQI, SIcode, QIcode, 8 },
{ convertSIHI, SIcode, HIcode, 8 },
{ convertSUQU, SUcode, QUcode, 8 },
{ convertDISI, DIcode, SIcode, 8 },
{ convertDFSF, DFcode, SFcode, 8 },
{ convertXFDF, XFcode, DFcode, 8 },
{ convertPSI, Pcode, SIcode, 2 },
{ convertSIP, SIcode, Pcode, 2 },
{ convertSIT, SIcode, Tcode, 2 },
{ convertDIT, DIcode, Tcode, 2 },
{ convertSFT, SFcode, Tcode, 2 },
{ convertDFT, DFcode, Tcode, 2 },
{ convertXFT, XFcode, Tcode, 2 },
{ convertQISI, QIcode, SIcode, 2 },
{ convertPT, Pcode, Tcode, 2 },
{ convertSISF, SIcode, SFcode, 4 },
{ convertSIDF, SIcode, DFcode, 4 },
{ convertSIXF, SIcode, XFcode, 4 },
{ convertSUSF, SUcode, SFcode, 4 },
{ convertSUDF, SUcode, DFcode, 4 },
{ convertSUXF, SUcode, XFcode, 4 },
{ convertDISF, DIcode, SFcode, 4 },
{ convertDIDF, DIcode, DFcode, 4 },
{ convertDIXF, DIcode, XFcode, 4 },
{ convertDUSF, DUcode, SFcode, 4 },
{ convertDUDF, DUcode, DFcode, 4 },
{ convertDUXF, DUcode, XFcode, 4 },
{ convertSFSI, SFcode, SIcode, 4 },
{ convertDFSI, DFcode, SIcode, 4 },
{ convertXFSI, XFcode, SIcode, 4 },
{ convertSFSU, SFcode, SUcode, 4 },
{ convertDFSU, DFcode, SUcode, 4 },
{ convertXFSU, XFcode, SUcode, 4 },
{ convertSFDI, SFcode, DIcode, 4 },
{ convertDFDI, DFcode, DIcode, 4 },
{ convertXFDI, XFcode, DIcode, 4 },
{ convertSFDU, SFcode, DUcode, 4 },
{ convertDFDU, DFcode, DUcode, 4 },
{ convertXFDU, XFcode, DUcode, 4 },
{ convertSIQI, SIcode, QIcode, 8 },
};
#define NUM_CONVERSIONS (sizeof conversion_info / sizeof (struct conversion_info))
/* List form of a conversion recipe. */
struct conversion_list
{
enum bytecode_opcode opcode;
enum typecode to;
int cost;
struct conversion_list *prev;
};
/* Determine if it is "reasonable" to add a given conversion to
a given list of conversions. The following criteria define
"reasonable" conversion lists:
* No typecode appears more than once in the sequence (no loops).
* At most one conversion from integer to float or vice versa is present.
* Either sign extensions or zero extensions may be present, but not both.
* No widening conversions occur after a signed/unsigned conversion.
* The sequence of sizes must be strict nonincreasing or nondecreasing. */
static int
conversion_reasonable_p (conversion, list)
struct conversion_info *conversion;
struct conversion_list *list;
{
struct conversion_list *curr;
int curr_size, prev_size;
int has_int_float, has_float_int;
int has_sign_extend, has_zero_extend;
int has_signed_unsigned, has_unsigned_signed;
has_int_float = 0;
has_float_int = 0;
has_sign_extend = 0;
has_zero_extend = 0;
has_signed_unsigned = 0;
has_unsigned_signed = 0;
/* Make sure the destination typecode doesn't already appear in
the list. */
for (curr = list; curr; curr = curr->prev)
if (conversion->to == curr->to)
return 0;
/* Check for certain kinds of conversions. */
if (TYPECODE_INTEGER_P (conversion->from)
&& TYPECODE_FLOAT_P (conversion->to))
has_int_float = 1;
if (TYPECODE_FLOAT_P (conversion->from)
&& TYPECODE_INTEGER_P (conversion->to))
has_float_int = 1;
if (TYPECODE_SIGNED_P (conversion->from)
&& TYPECODE_SIGNED_P (conversion->to)
&& GET_TYPECODE_SIZE (conversion->from)
< GET_TYPECODE_SIZE (conversion->to))
has_sign_extend = 1;
if (TYPECODE_UNSIGNED_P (conversion->from)
&& TYPECODE_UNSIGNED_P (conversion->to)
&& GET_TYPECODE_SIZE (conversion->from)
< GET_TYPECODE_SIZE (conversion->to))
has_zero_extend = 1;
for (curr = list; curr && curr->prev; curr = curr->prev)
{
if (TYPECODE_INTEGER_P (curr->prev->to)
&& TYPECODE_FLOAT_P (curr->to))
has_int_float = 1;
if (TYPECODE_FLOAT_P (curr->prev->to)
&& TYPECODE_INTEGER_P (curr->to))
has_float_int = 1;
if (TYPECODE_SIGNED_P (curr->prev->to)
&& TYPECODE_SIGNED_P (curr->to)
&& GET_TYPECODE_SIZE (curr->prev->to)
< GET_TYPECODE_SIZE (curr->to))
has_sign_extend = 1;
if (TYPECODE_UNSIGNED_P (curr->prev->to)
&& TYPECODE_UNSIGNED_P (curr->to)
&& GET_TYPECODE_SIZE (curr->prev->to)
< GET_TYPECODE_SIZE (curr->to))
has_zero_extend = 1;
if (TYPECODE_SIGNED_P (curr->prev->to)
&& TYPECODE_UNSIGNED_P (curr->to))
has_signed_unsigned = 1;
if (TYPECODE_UNSIGNED_P (curr->prev->to)
&& TYPECODE_SIGNED_P (curr->to))
has_unsigned_signed = 1;
}
if (TYPECODE_INTEGER_P (conversion->from)
&& TYPECODE_INTEGER_P (conversion->to)
&& GET_TYPECODE_SIZE (conversion->to)
> GET_TYPECODE_SIZE (conversion->from)
&& (has_signed_unsigned || has_unsigned_signed))
return 0;
if (has_float_int && has_int_float || has_sign_extend && has_zero_extend)
return 0;
/* Make sure the sequence of destination typecode sizes is
strictly nondecreasing or strictly nonincreasing. */
prev_size = GET_TYPECODE_SIZE (conversion->to);
for (curr = list; curr; curr = curr->prev)
{
curr_size = GET_TYPECODE_SIZE (curr->to);
if (curr_size != prev_size)
break;
}
if (!curr)
return 1;
if (curr_size < prev_size)
for (prev_size = curr_size; curr; curr = curr->prev)
{
curr_size = GET_TYPECODE_SIZE (curr->to);
if (curr_size > prev_size)
return 0;
prev_size = curr_size;
}
else
for (prev_size = curr_size; curr; curr = curr->prev)
{
curr_size = GET_TYPECODE_SIZE (curr->to);
if (curr_size < prev_size)
return 0;
prev_size = curr_size;
}
return 1;
}
/* Exhaustively search all reasonable conversions to find one to
convert the given types. */
static struct conversion_recipe
deduce_conversion (from, to)
enum typecode from, to;
{
struct rl
{
struct conversion_list *list;
struct rl *next;
} *prev, curr, *good, *temp;
struct conversion_list *conv, *best;
int i, cost, bestcost;
struct conversion_recipe result;
struct obstack recipe_obstack;
obstack_init (&recipe_obstack);
curr.next = (struct rl *) obstack_alloc (&recipe_obstack, sizeof (struct rl));
curr.next->list =
(struct conversion_list *) obstack_alloc (&recipe_obstack,
sizeof (struct conversion_list));
curr.next->list->opcode = -1;
curr.next->list->to = from;
curr.next->list->cost = 0;
curr.next->list->prev = 0;
curr.next->next = 0;
good = 0;
while (curr.next)
{
/* Remove successful conversions from further consideration. */
for (prev = &curr; prev; prev = prev->next)
if (prev->next && prev->next->list->to == to)
{
temp = prev->next->next;
prev->next->next = good;
good = prev->next;
prev->next = temp;
}
/* Go through each of the pending conversion chains, trying
all possible candidate conversions on them. */
for (prev = curr.next, curr.next = 0; prev; prev = prev->next)
for (i = 0; i < NUM_CONVERSIONS; ++i)
if (conversion_info[i].from == prev->list->to
&& conversion_reasonable_p (&conversion_info[i], prev->list))
{
temp = (struct rl *) obstack_alloc (&recipe_obstack,
sizeof (struct rl));
temp->list = (struct conversion_list *)
obstack_alloc (&recipe_obstack,
sizeof (struct conversion_list));
temp->list->opcode = conversion_info[i].opcode;
temp->list->to = conversion_info[i].to;
temp->list->cost = conversion_info[i].cost;
temp->list->prev = prev->list;
temp->next = curr.next;
curr.next = temp;
}
}
bestcost = BIG_ARBITRARY_NUMBER;
best = 0;
for (temp = good; temp; temp = temp->next)
{
for (conv = temp->list, cost = 0; conv; conv = conv->prev)
cost += conv->cost;
if (cost < bestcost)
{
bestcost = cost;
best = temp->list;
}
}
if (!best)
abort ();
for (i = 0, conv = best; conv; conv = conv->prev)
if (conv->opcode != -1)
++i;
result.opcodes = (unsigned char *) xmalloc (i);
result.nopcodes = i;
for (conv = best; conv; conv = conv->prev)
if (conv->opcode != -1)
result.opcodes[--i] = conv->opcode;
result.cost = bestcost;
obstack_free (&recipe_obstack, 0);
return result;
}
#define DEDUCE_CONVERSION(FROM, TO) \
(conversion_recipe[(int) FROM][(int) TO].opcodes ? 0 \
: (conversion_recipe[(int) FROM][(int) TO] \
= deduce_conversion (FROM, TO), 0))
/* Emit a conversion between the given scalar types. */
void
emit_typecode_conversion (from, to)
enum typecode from, to;
{
int i;
DEDUCE_CONVERSION (from, to);
for (i = 0; i < conversion_recipe[(int) from][(int) to].nopcodes; ++i)
bc_emit_instruction (conversion_recipe[(int) from][(int) to].opcodes[i]);
}
/* Initialize mode_to_code_map[] */
void
bc_init_mode_to_code_map ()
{
int mode;
for (mode = 0; mode < MAX_MACHINE_MODE + 1; mode++)
{
signed_mode_to_code_map[mode] =
unsigned_mode_to_code_map[mode] =
LAST_AND_UNUSED_TYPECODE;
}
#define DEF_MODEMAP(SYM, CODE, UCODE, CONST, LOAD, STORE) \
{ signed_mode_to_code_map[(int) SYM] = CODE; \
unsigned_mode_to_code_map[(int) SYM] = UCODE; }
#include "modemap.def"
#undef DEF_MODEMAP
/* Initialize opcode maps for const, load, and store */
bc_init_mode_to_opcode_maps ();
}
/* Given a machine mode return the preferred typecode. */
enum typecode
preferred_typecode (mode, unsignedp)
enum machine_mode mode;
int unsignedp;
{
enum typecode code = (unsignedp
? unsigned_mode_to_code_map
: signed_mode_to_code_map) [MIN ((int) mode,
(int) MAX_MACHINE_MODE)];
if (code == LAST_AND_UNUSED_TYPECODE)
abort ();
return code;
}
/* Expand a conversion between the given types. */
void
bc_expand_conversion (from, to)
tree from, to;
{
enum typecode fcode, tcode;
fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from));
tcode = preferred_typecode (TYPE_MODE (to), TREE_UNSIGNED (to));
emit_typecode_conversion (fcode, tcode);
}
/* Expand a conversion of the given type to a truth value. */
void
bc_expand_truth_conversion (from)
tree from;
{
enum typecode fcode;
fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from));
emit_typecode_conversion (fcode, Tcode);
}
/* Emit an appropriate binary operation. */
void
bc_expand_binary_operation (optab, resulttype, arg0, arg1)
struct binary_operator optab[];
tree resulttype, arg0, arg1;
{
int i, besti, cost, bestcost;
enum typecode resultcode, arg0code, arg1code;
resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype));
arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (resulttype));
arg1code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg1)), TREE_UNSIGNED (resulttype));
besti = -1;
bestcost = BIG_ARBITRARY_NUMBER;
for (i = 0; optab[i].opcode != -1; ++i)
{
cost = 0;
DEDUCE_CONVERSION (arg0code, optab[i].arg0);
cost += conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost;
DEDUCE_CONVERSION (arg1code, optab[i].arg1);
cost += conversion_recipe[(int) arg1code][(int) optab[i].arg1].cost;
if (cost < bestcost)
{
besti = i;
bestcost = cost;
}
}
if (besti == -1)
abort ();
expand_expr (arg1, 0, VOIDmode, 0);
emit_typecode_conversion (arg1code, optab[besti].arg1);
expand_expr (arg0, 0, VOIDmode, 0);
emit_typecode_conversion (arg0code, optab[besti].arg0);
bc_emit_instruction (optab[besti].opcode);
emit_typecode_conversion (optab[besti].result, resultcode);
}
/* Emit an appropriate unary operation. */
void
bc_expand_unary_operation (optab, resulttype, arg0)
struct unary_operator optab[];
tree resulttype, arg0;
{
int i, besti, cost, bestcost;
enum typecode resultcode, arg0code;
resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype));
arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (TREE_TYPE (arg0)));
besti = -1;
bestcost = BIG_ARBITRARY_NUMBER;
for (i = 0; optab[i].opcode != -1; ++i)
{
DEDUCE_CONVERSION (arg0code, optab[i].arg0);
cost = conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost;
if (cost < bestcost)
{
besti = i;
bestcost = cost;
}
}
if (besti == -1)
abort ();
expand_expr (arg0, 0, VOIDmode, 0);
emit_typecode_conversion (arg0code, optab[besti].arg0);
bc_emit_instruction (optab[besti].opcode);
emit_typecode_conversion (optab[besti].result, resultcode);
}
/* Emit an appropriate increment. */
void
bc_expand_increment (optab, type)
struct increment_operator optab[];
tree type;
{
enum typecode code;
int i;
code = preferred_typecode (TYPE_MODE (type), TREE_UNSIGNED (type));
for (i = 0; (int) optab[i].opcode >= 0; ++i)
if (code == optab[i].arg)
{
bc_emit_instruction (optab[i].opcode);
return;
}
abort ();
}

View file

@ -1,75 +0,0 @@
/* Bytecode token definitions for GNU C-compiler.
Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
extern void bc_expand_conversion ();
extern void bc_expand_truth_conversion ();
extern void bc_expand_binary_operation ();
extern void bc_expand_unary_operation ();
struct binary_operator
{
enum bytecode_opcode opcode;
enum typecode result;
enum typecode arg0;
enum typecode arg1;
};
extern struct binary_operator optab_plus_expr[];
extern struct binary_operator optab_minus_expr[];
extern struct binary_operator optab_mult_expr[];
extern struct binary_operator optab_trunc_div_expr[];
extern struct binary_operator optab_trunc_mod_expr[];
extern struct binary_operator optab_rdiv_expr[];
extern struct binary_operator optab_bit_and_expr[];
extern struct binary_operator optab_bit_ior_expr[];
extern struct binary_operator optab_bit_xor_expr[];
extern struct binary_operator optab_lshift_expr[];
extern struct binary_operator optab_rshift_expr[];
extern struct binary_operator optab_truth_and_expr[];
extern struct binary_operator optab_truth_or_expr[];
extern struct binary_operator optab_lt_expr[];
extern struct binary_operator optab_le_expr[];
extern struct binary_operator optab_ge_expr[];
extern struct binary_operator optab_gt_expr[];
extern struct binary_operator optab_eq_expr[];
extern struct binary_operator optab_ne_expr[];
struct unary_operator
{
enum bytecode_opcode opcode;
enum typecode result;
enum typecode arg0;
};
extern struct unary_operator optab_negate_expr[];
extern struct unary_operator optab_bit_not_expr[];
extern struct unary_operator optab_truth_not_expr[];
struct increment_operator
{
enum bytecode_opcode opcode;
enum typecode arg;
};
extern struct increment_operator optab_predecrement_expr[];
extern struct increment_operator optab_preincrement_expr[];
extern struct increment_operator optab_postdecrement_expr[];
extern struct increment_operator optab_postincrement_expr[];

View file

@ -1,21 +0,0 @@
/* Typecodes used by the interpreter and their related
machine modes and types.
The last argument is used for retrieving the given
type from a varargs list. Due to a bug in varargs,
the type has to be the generic machine type of
larger. */
DEFTYPECODE (QIcode, "QI", QImode, SItype)
DEFTYPECODE (QUcode, "QU", QImode, SUtype)
DEFTYPECODE (HIcode, "HI", HImode, SItype)
DEFTYPECODE (HUcode, "HU", HImode, SUtype)
DEFTYPECODE (SIcode, "SI", SImode, SItype)
DEFTYPECODE (SUcode, "SU", SImode, SUtype)
DEFTYPECODE (DIcode, "DI", DImode, DItype)
DEFTYPECODE (DUcode, "DU", DImode, DUtype)
DEFTYPECODE (SFcode, "SF", SFmode, SFtype)
DEFTYPECODE (DFcode, "DF", DFmode, DFtype)
DEFTYPECODE (XFcode, "XF", XFmode, XFtype)
DEFTYPECODE (Pcode, "P", PSImode, Ptype)
DEFTYPECODE (Tcode, "T", SImode, SItype)

View file

@ -1,54 +0,0 @@
/* Typecode definitions for Bytecode Interpreter.
Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef TYPECODE_H
#define TYPECODE_H
enum typecode
{
#define DEFTYPECODE(CODE, NAME, MACHMODE, TYPE) CODE,
#include "bc-typecd.def"
#undef DEFTYPECODE
LAST_AND_UNUSED_TYPECODE
};
/* Determine if a given type is integer. */
#define TYPECODE_INTEGER_P(TYPECODE) ((int) (TYPECODE) < (int) SFcode)
/* Determine if a given type is unsigned. */
#define TYPECODE_UNSIGNED_P(TYPECODE) \
(TYPECODE_INTEGER_P(TYPECODE) && (int) (TYPECODE) & 1)
/* Determine if a given type is signed. */
#define TYPECODE_SIGNED_P(TYPECODE) \
(TYPECODE_INTEGER_P(TYPECODE) && !((int) (TYPECODE) & 1))
/* Determine if a given type is floating. */
#define TYPECODE_FLOAT_P(TYPECODE) \
((int) (TYPECODE) < (int) Pcode && !TYPECODE_INTEGER_P(TYPECODE))
/* Determine if the given type is arithmetic. */
#define TYPECODE_ARITH_P(TYPECODE) \
(TYPECODE_INTEGER_P(TYPECODE) || TYPECODE_FLOAT_P(TYPECODE))
#define NUM_TYPECODES ((int) LAST_AND_UNUSED_TYPECODE)
#endif

View file

@ -1,80 +0,0 @@
/* Bytecode Interpreter utility to generate arity table.
Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include "hconfig.h"
#include "bi-defs.h"
int
length (n)
struct node *n;
{
int k;
for (k = 0; n; n = n->next)
++k;
return k;
}
int
main ()
{
struct def *d;
struct variation *v;
struct node *n;
yyparse ();
reverse ();
for (d = defs; d; d = d->next)
for (v = d->variations; v; v = v->next)
{
printf ("{ %d, %d, %d, {", length (v->inputs),
length (v->outputs), length (v->literals));
for (n = v->literals; n; n = n->next)
printf ("(char) %scode, ", n->text);
if (v->literals == 0)
printf ("0");
printf ("}},\n");
}
fflush (stdout);
exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
/* NOTREACHED */
return 0;
}
/* Safely allocate NBYTES bytes of memory. Returns pointer to block of
memory. */
char *
xmalloc (nbytes)
int nbytes;
{
char *tmp = (char *) malloc (nbytes);
if (!tmp)
{
fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
exit (FATAL_EXIT_CODE);
}
return tmp;
}

View file

@ -1,48 +0,0 @@
/* Definitions for Bytecode Interpreter.
Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
struct node
{
char *text;
struct node *next;
};
struct variation
{
char *name;
int code;
struct node *inputs;
struct node *outputs;
struct node *literals;
struct variation *next;
};
struct def
{
char *basename;
char *template;
struct variation *variations;
struct def *next;
};
extern struct def *defs;
extern int ndefs;
extern void reverse();

View file

@ -1,167 +0,0 @@
/* Lexer for scanner of bytecode definition file.
Copyright (C) 1993, 1995 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include "hconfig.h"
#include "bi-parser.h"
/* Safely allocate NBYTES bytes of memory. Returns pointer to block of
memory. */
static char *
xmalloc (nbytes)
int nbytes;
{
char *tmp = (char *) malloc (nbytes);
if (!tmp)
{
fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
exit (FATAL_EXIT_CODE);
}
return tmp;
}
/* Safely reallocate BLOCK so its size becomes NBYTES.
The block returned may be different from the one supplied. */
static char *
xrealloc (block, nbytes)
char *block;
int nbytes;
{
char *tmp = (block
? (char *) realloc (block, nbytes)
: (char *) malloc (nbytes));
if (!tmp)
{
fprintf (stderr, "can't reallocate %d bytes (out of virtual memory)\n", nbytes);
exit (FATAL_EXIT_CODE);
}
return tmp;
}
/* Scan for string token on standard input. A string is, for our
purposes here, a sequence of characters that starts with the regexp
``[^ #\t\n(),]'' and is then followed by the regexp ``[^#(),]*''. Any
character is accepted if preceded by a backslash, "\\". It is assumed
that the first character has already been checked by the main loop. */
static char *
scan_string ()
{
char *buffer = NULL;
char *point = NULL;
int buffer_size = 0;
int c;
while ((c = getc (stdin)) != EOF
&& c != '#' && c != '(' && c != ')' && c != ',')
{
/* Extend buffer, if necessary (minus two so there's room for the NUL
trailer as well as another character if this one is a backslash). */
if (!buffer_size || (point - buffer >= buffer_size-2))
{
int previous_point_index = point - buffer;
buffer_size = (!buffer_size ? 32 : buffer_size * 2);
if (!buffer)
buffer = xmalloc (buffer_size);
else
buffer = xrealloc (buffer, buffer_size);
point = buffer + previous_point_index;
}
*point++ = c & 0xff;
if (c == '\\')
{
c = getc (stdin);
/* Catch special case: backslash at end of file */
if (c == EOF)
break;
*point++ = c;
}
}
*point = 0;
if (c != EOF)
ungetc (c, stdin);
return buffer;
}
int
yylex ()
{
int c;
char *token;
/* First char determines what token we're looking at */
for (;;)
{
c = getc (stdin);
switch (c)
{
case EOF:
return 0;
case ' ':
case '\t':
case '\n':
/* Ignore whitespace */
continue;
case '#':
/* Comments advance to next line */
while ((c = getc (stdin)) != '\n' && c != EOF);
continue;
default:
if (c != '(' && c != ')' && c != '\\' && c != ',')
{
ungetc (c, stdin);
yylval.string = scan_string ();
/* Check if string is "define_operator"; if so, return
a DEFOP token instead. */
if (!strcmp (yylval.string, "define_operator"))
{
free (yylval.string);
yylval.string = 0;
return DEFOP;
}
return STRING;
}
return c & 0xff;
}
}
}

View file

@ -1,78 +0,0 @@
/* Utility to generate opcode list from bytecode definition.
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include "hconfig.h"
#include "bi-defs.h"
int
main(argc, argv)
int argc;
char **argv;
{
struct def *d;
struct variation *v;
int i;
yyparse();
reverse();
printf ("/* This file is automatically generated from bytecode.def,\n");
printf ("do not make any changes here. Instead edit bytecode.def. */\n\n");
printf ("enum bytecode_opcode\n{");
i = 0;
for (d = defs; d; d = d->next)
for (v = d->variations; v; v = v->next)
{
printf (" %s%s,\n", d->basename, v->name);
++i;
}
puts (" LAST_AND_UNUSED_OPCODE\n};");
if (i > 256)
fprintf (stderr, "%s: warning, number of opcodes is %d\n", *argv, i);
else
fprintf (stderr, "(Number of opcodes is %d)\n", i);
fflush (stdout);
exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
/* NOTREACHED */
return 0;
}
/* Safely allocate NBYTES bytes of memory. Returns pointer to block of
memory. */
char *
xmalloc (nbytes)
int nbytes;
{
char *tmp = (char *) malloc (nbytes);
if (!tmp)
{
fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
exit (FATAL_EXIT_CODE);
}
return tmp;
}

View file

@ -1,59 +0,0 @@
/* Utility to generate opcode name list from bytecode definition file.
Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include "hconfig.h"
#include "bi-defs.h"
int
main()
{
struct def *d;
struct variation *v;
yyparse();
reverse();
for (d = defs; d; d = d->next)
for (v = d->variations; v; v = v->next)
printf("\"%s%s\",\n", d->basename, v->name);
fflush (stdout);
exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
/* NOTREACHED */
return 0;
}
/* Safely allocate NBYTES bytes of memory. Returns pointer to block of
memory. */
char *
xmalloc (nbytes)
int nbytes;
{
char *tmp = (char *) malloc (nbytes);
if (!tmp)
{
fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n", nbytes);
exit (FATAL_EXIT_CODE);
}
return tmp;
}

View file

@ -1,169 +0,0 @@
/* Bytecode definition file parser.
Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
%{
#include <stdio.h>
#include "hconfig.h"
#include "bi-defs.h"
extern char yytext[];
extern int yyleng;
/* Chain of all defs built by the parser. */
struct def *defs;
int ndefs;
static struct node *makenode ();
static struct variation *makevar ();
static struct def *makedef ();
void yyerror ();
%}
%union
{
char *string;
struct def *def;
struct variation *variation;
struct node *node;
}
%token <string> DEFOP STRING
%type <string> opt_string
%type <def> defs def
%type <variation> variations variation
%type <node> list items item
%%
top:
defs
{ defs = $1; }
;
defs:
def
| defs def
{ $2->next = $1; $$ = $2; }
;
def:
DEFOP '(' STRING ',' opt_string ',' '(' variations ')' ')'
{ $$ = makedef ($3, $5, $8); }
;
variations:
variation
| variations ',' variation
{ $3->next = $1; $$ = $3; }
;
variation:
'(' opt_string ')'
{ $$ = makevar ($2, (struct node *) NULL, (struct node *) NULL, (struct node *) NULL); }
| '(' opt_string ',' list ')'
{ $$ = makevar ($2, $4, (struct node *) NULL, (struct node *) NULL); }
| '(' opt_string ',' list ',' list ')'
{ $$ = makevar ($2, $4, $6, (struct node *) NULL); }
| '(' opt_string ',' list ',' list ',' list ')'
{ $$ = makevar ($2, $4, $6, $8); }
;
opt_string:
/* empty */ { $$ = ""; }
| STRING { $$ = $1; }
;
list:
'(' items ')'
{ $$ = $2; }
| /* empty */
{ $$ = NULL; }
;
items:
item
/* Note right recursion. */
| item ',' items
{ $1->next = $3; $$ = $1; }
;
item:
STRING
{ $$ = makenode ($1); }
;
%%
static struct node *
makenode (s)
char *s;
{
struct node *n;
n = (struct node *) malloc (sizeof (struct node));
n->text = s;
n->next = NULL;
return n;
}
static struct variation *
makevar (name, inputs, outputs, literals)
char *name;
struct node *inputs, *outputs, *literals;
{
struct variation *v;
v = (struct variation *) malloc (sizeof (struct variation));
v->name = name;
v->code = ndefs++;
v->inputs = inputs;
v->outputs = outputs;
v->literals = literals;
v->next = NULL;
return v;
}
static struct def *
makedef (name, template, vars)
char *name, *template;
struct variation *vars;
{
struct def *d;
d = (struct def *) malloc (sizeof (struct def));
d->basename = name;
d->template = template;
d->variations = vars;
d->next = NULL;
return d;
}
void
yyerror (s)
char *s;
{
fprintf (stderr, "syntax error in input\n");
exit (FATAL_EXIT_CODE);
}

View file

@ -1,61 +0,0 @@
/* Reverse order of definitions obtained from bytecode definition file.
Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "hconfig.h"
#include "bi-defs.h"
void
reverse()
{
struct def *dp, *d, *dn;
struct variation *vp, *v, *vn;
dp = defs;
if (dp)
{
vp = dp->variations;
if (vp)
{
for (v = vp->next, vp->next = 0; v; vp = v, v = vn)
{
vn = v->next;
v->next = vp;
}
dp->variations = vp;
}
for (d = dp->next, dp->next = 0; d; dp = d, d = dn)
{
vp = d->variations;
if (vp)
{
for (v = vp->next, vp->next = 0; v; vp = v, v = vn)
{
vn = v->next;
v->next = vp;
}
d->variations = vp;
}
dn = d->next;
d->next = dp;
}
defs = dp;
}
}

View file

@ -1,159 +0,0 @@
/* Definitions for Bytecode Interpreter.
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define MAXLITERALS 5
struct arityvec
{
char ninputs;
char noutputs;
char nliterals;
char literals[MAXLITERALS];
};
struct argtype
{
int modealign; /* Argument mode:alignment */
int size; /* Argument size, in bytes */
};
struct callinfo
{
int nargs; /* Number of arguments in call */
struct argtype retvaltype; /* Type of return value */
struct argtype argtypes[1]; /* Argument types */
};
/* Structure describing a bytecode function. If this changes, we also
need to change expand_function_end () in bc-trans.c */
struct bytecode
{
int stacksize; /* Depth required of evaluation stack. */
int localsize; /* Size in bytes of local variables. */
unsigned char *pc0; /* Initial program counter. */
void **ptrlit; /* Vector of (relocatable) pointer literals. */
struct callinfo *callinfo; /* Vector of procedure call type info. */
};
#define INTERP_BPC 8 /* Bits per char */
#define INTERP_BPI \
(sizeof (int) * INTERP_BPC) /* Bits per int */
#ifndef min
#define min(L, R) ((L) < (R) ? (L) : (R))
#endif
/* bit field operations. */
/* Low (high) mask: int with low (high) N bits set */
#define LM(N) ((1 << (N)) - 1)
#define HM(N) ((~LM (INTERP_BPI - (N))))
/* Sign-extend SIZE low bits of VALUE to integer (typeof VALUE)
Signed bitfields are loaded from memory by the sxloadBI instruction,
which first retrieves the bitfield with XFIELD and then sign extends
it to an SItype. */
#define EXTEND(SIZE, VALUE) \
({ SUtype value = (SUtype) (VALUE); \
(value & (1 << ((SIZE) - 1)) ? value | ~LM (SIZE) : value); })
/* Given OFFSET:SIZE for a bitfield, calculate:
[1] BYTE_OFFSET = the byte offset of the bit field.
[2] BIT_OFFSET = the bit offset of the bit field (less than INTERP_BPC).
[3] NBYTES = the number of integral bytes in the bit field.
[4] TRAILING_BITS= the number of trailing bits (less than INTERP_BPC).
, , , , , (memory bytes)
---------------- (bitfield)
| | || | | (divisions)
^ ^ ^ ^
| | | |__ [4] (bits)
| | |_________ [3] (bytes)
| |_________________ [2] (bits)
|___________________________ [1] (bytes)
The above applies to BYTE_LOW_ENDIAN machines. In BYTE_BIG_ENDIAN machines, the
bit numbering is reversed (i.e. bit 0 is the sign bit).
(All right, so I drew this to keep my tongue in cheek while writing the code below,
not because I'm into ASCII art.) */
#define BI_PARAMS(OFFSET, SIZE, BYTE_OFFSET, BIT_OFFSET, NBYTES, TRAILING_BITS) \
{ BYTE_OFFSET = (OFFSET) / (INTERP_BPC); \
BIT_OFFSET = (OFFSET) % (INTERP_BPC); \
NBYTES = ((SIZE) - (INTERP_BPC - (BIT_OFFSET))) / INTERP_BPC; \
if ((NBYTES) < 0 || ((NBYTES) > 64)) \
NBYTES = 0; \
if ((SIZE) + (BIT_OFFSET) <= INTERP_BPC) \
TRAILING_BITS = 0; \
else \
TRAILING_BITS = ((SIZE) - (INTERP_BPC - (BIT_OFFSET))) % INTERP_BPC; }
/* SHIFT_IN_BITS retrieves NBITS bits from SOURCE and shifts into
DEST. The bit field starts OFFSET bits into SOURCE.
OR_IN_BITS copies the NBITS low bits from VALUE into a the bitfield in
DEST offset by OFFSET bits. */
#define SHIFT_IN_BITS(DEST, SOURCE, OFFSET, NBITS) \
(DEST = ((DEST) << (NBITS)) \
| (LM ((NBITS)) \
& ((SOURCE) \
>> (BYTES_BIG_ENDIAN \
? (INTERP_BPC - (OFFSET) - (NBITS)) \
: (OFFSET)))))
#define OR_IN_BITS(DEST, VALUE, OFFSET, NBITS) \
(DEST = ((DEST) & ~(LM ((NBITS)) \
<< (BIG_ENDIAN \
? (INTERP_BPC - (OFFSET) - (NBITS)) \
: (OFFSET))) \
| (((VALUE) & LM ((NBITS))) \
<< (BIG_ENDIAN \
? (INTERP_BPC - (OFFSET) - (NBITS)) \
: (OFFSET)))))
/* Procedure call; arguments are a pointer to the function to be called,
a pointer to a place to store the return value, a pointer to a vector
describing the type of procedure call, and the interpreter's stack pointer,
which will point to the first of the arguments at this point. */
#define CALL(FUNC, CALLDESC, RETVAL, SP) __call(FUNC, CALLDESC, RETVAL, SP)
/* Procedure return; arguments are a pointer to the calldesc for this
function, and a pointer to the place where the value to be returned
may be found. Generally the MACHARGS above contain a machine dependent
cookie that is used to determine where to jump to. */
#define PROCRET(CALLDESC, RETVAL) return

View file

@ -1,322 +0,0 @@
# -*- C -*-
# bytecode.def - definitions of bytecodes for the stack machine.
# The production of the bytecode interpreter and compiler is
# heavily automated by using this file creatively.
# Various elementary data types are understood by the bytecode interpreter.
# Q[IU] - quarter word (byte) signed and unsigned integers (char).
# H[IU] - half word signed and unsigned integers (short int, maybe int).
# S[IU] - single word signed and unsigned integers (maybe int, long int).
# D[IU] - double word signed and unsigned integers (long long int).
# SF - single precision floating point (float).
# DF - double precision floating point (double).
# XF - extended precision floating point (long double).
# P - pointer type for address arithmetic and other purposes.
# The bytecode specification consists of a series of define_operator
# forms, that are parsed by preprocessors to automatically build
# various switch statements.
# define_operator(name,
# <C prototype code for implementing the operator>,
# <list of variations>)
# The <C prototype> is self explanatory.
# The <list of variations> consists of a (parenthesized list) of
# variation items, each of which is in itself a list. A variation
# item consists of a name suffix, the types of the input arguments
# expected on the stack (shallowest item first) and (optionally) the
# types of the output arguments (similarly ordered). Finally, the
# types of the literal arguments (if any) may appear.
# Substitution in the C prototype code is as follows:
# Substitution happens only after a dollar sign. To get a literal
# dollar sign (why would you ever want one anyway?) use $$.
# $R1 means "result 1" $TR1 means "type name of result one"
# $S1 means "source 1" and similarly with $TS1.
# $L1 means "literal (inline) argument 1" and $TL1 means type thereof.
#
# Notice that the number following $R doesn't affect the push order;
# it's used only for clarity and orthogonality, although it's checked
# to make sure it doesn't exceed the number of outputs. A $R reference
# results in a push, and represents the result lvalue. E.g.
# $R1 = 2\, $R2 = 17
# will expand to:
# INTERP_PUSH($TR1) = 2, INTERP_PUSH($TR2) = 17
#
# Opcode 0 should never happen.
define_operator(neverneverland, abort\(\), (()))
# Stack manipulations.
define_operator(drop, 0, ((, (SI))))
define_operator(duplicate, 0, ((, (SI), (SI, SI))))
define_operator(over, 0, ((, (SI), (SI, SI))))
# Adjust stack pointer
define_operator(setstack, 0, ((SI,,,(SI))))
define_operator(adjstack, 0, ((SI,,,(SI))))
# Constants, loads, and stores.
define_operator(const,
$R1 = $L1,
((QI,, (QI), (QI)), (HI,, (HI), (HI)),
(SI,, (SI), (SI)), (DI,, (DI), (DI)),
(SF,, (SF), (SF)), (DF,, (DF), (DF)),
(XF,, (XF), (XF)), (P,, (P), (P))))
define_operator(load,
$R1 = *\($TR1 *\) $S1,
((QI, (P), (QI)), (HI, (P), (HI)),
(SI, (P), (SI)), (DI, (P), (DI)),
(SF, (P), (SF)), (DF, (P), (DF)),
(XF, (P), (XF)), (P, (P), (P))))
define_operator(store,
*\($TS2 *\) $S1 = $S2,
((QI, (P, QI)), (HI, (P, HI)),
(SI, (P, SI)), (DI, (P, DI)),
(SF, (P, SF)), (DF, (P, DF)),
(XF, (P, XF)), (P, (P, P)),
(BLK, (SI, BLK, BLK))))
# Clear memory block
define_operator(clear, $S1 + $S2, ((BLK, (SI, BLK))))
# Advance pointer by SI constant
define_operator(addconst, $R1 = $S1, ((PSI, (P), (P), (SI))))
# newlocalSI is used for creating variable-sized storage during function
# initialization.
# Create local space, return pointer to block
define_operator(newlocal, $R1 = $S1, ((SI, (SI), (P))))
# Push the address of a local variable.
define_operator(local, $R1 = locals + $L1, ((P,, (P), (SI))))
# Push the address of an argument variable.
define_operator(arg, $R1 = args + $L1, ((P,, (P), (SI))))
# Arithmetic conversions.
define_operator(convert,
$R1 = \($TR1\) $S1,
(# Signed integral promotions (sign extensions).
(QIHI, (QI), (HI)), (HISI, (HI), (SI)), (SIDI, (SI), (DI)),
(QISI, (QI), (SI)),
# Unsigned integral promotions (zero extensions).
(QUHU, (QU), (HU)), (HUSU, (HU), (SU)), (SUDU, (SU), (DU)),
(QUSU, (QU), (SU)),
# Floating promotions.
(SFDF, (SF), (DF)), (DFXF, (DF), (XF)),
# Integral truncation.
(HIQI, (HI), (QI)), (SIHI, (SI), (HI)), (DISI, (DI), (SI)),
(SIQI, (SI), (QI)),
# Unsigned truncation.
(SUQU, (SU), (QU)),
# Floating truncation.
(DFSF, (DF), (SF)), (XFDF, (XF), (DF)),
# Integral conversions to floating types.
(SISF, (SI), (SF)), (SIDF, (SI), (DF)), (SIXF, (SI), (XF)),
(SUSF, (SU), (SF)), (SUDF, (SU), (DF)), (SUXF, (SU), (XF)),
(DISF, (DI), (SF)), (DIDF, (DI), (DF)), (DIXF, (DI), (XF)),
(DUSF, (DU), (SF)), (DUDF, (DU), (DF)), (DUXF, (DU), (XF)),
# Floating conversions to integral types.
(SFSI, (SF), (SI)), (DFSI, (DF), (SI)), (XFSI, (XF), (SI)),
(SFSU, (SF), (SU)), (DFSU, (DF), (SU)), (XFSU, (XF), (SU)),
(SFDI, (SF), (DI)), (DFDI, (DF), (DI)), (XFDI, (XF), (DI)),
(SFDU, (SF), (DU)), (DFDU, (DF), (DU)), (XFDU, (XF), (DU)),
# Pointer/integer conversions.
(PSI, (P), (SI)), (SIP, (SI), (P))))
# Truth value conversion. These are necessary because conversions of, e.g.,
# floating types to integers may not function correctly for large values.
define_operator(convert,
$R1 = !!$S1,
((SIT, (SI), (T)), (DIT, (DI), (T)),
(SFT, (SF), (T)), (DFT, (DF), (T)),
(XFT, (XF), (T)), (PT, (P), (T))))
# Bit field load/store.
# Load and zero-extend bitfield
define_operator(zxload, $R1 = $S1, ((BI, (SU, SU, P), (SU))))
# Load and sign-extend bitfield
define_operator(sxload, $R1 = $S1, ((BI, (SU, SU, P), (SI))))
# Store integer in bitfield
define_operator(sstore, $R1 = $S1, ((BI, (SU, SU, P, SI))))
# Binary operations.
define_operator(add,
$R1 = $S1 + $S2,
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
(SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
(XF, (XF, XF), (XF)),
(PSI, (P, SI), (P))))
define_operator(sub,
$R1 = $S1 - $S2,
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
(SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
(XF, (XF, XF), (XF)),
(PP, (P, P), (SI))))
define_operator(mul,
$R1 = $S1 * $S2,
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
(SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)),
(SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
(XF, (XF, XF), (XF))))
define_operator(div,
$R1 = $S1 / $S2,
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
(SU, (SU, SU), (SU)), (DU, (DU, DU), (DU)),
(SF, (SF, SF), (SF)), (DF, (DF, DF), (DF)),
(XF, (XF, XF), (XF))))
define_operator(mod,
$R1 = $S1 % $S2,
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI)),
(SU, (SU, SU), (SU)), (DU, (DU, DU), (DU))))
define_operator(and,
$R1 = $S1 & $S2,
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI))))
define_operator(ior,
$R1 = $S1 | $S2,
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI))))
define_operator(xor,
$R1 = $S1 ^ $S2,
((SI, (SI, SI), (SI)), (DI, (DI, DI), (DI))))
define_operator(lshift,
$R1 = $S1 << $S2,
((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)),
(DI, (DI, SI), (DI)), (DU, (DU, SI), (DU))))
define_operator(rshift,
$R1 = $S1 >> $S2,
((SI, (SI, SI), (SI)), (SU, (SU, SI), (SU)),
(DI, (DI, SI), (DI)), (DU, (DU, SI), (DU))))
define_operator(lt,
$R1 = $S1 < $S2,
((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
(DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
(XF, (XF, XF), (T)), (P, (P, P), (T))))
define_operator(le,
$R1 = $S1 <= $S2,
((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
(DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
(XF, (XF, XF), (T)), (P, (P, P), (T))))
define_operator(ge,
$R1 = $S1 >= $S2,
((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
(DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
(XF, (XF, XF), (T)), (P, (P, P), (T))))
define_operator(gt,
$R1 = $S1 > $S2,
((SI, (SI, SI), (T)), (SU, (SU, SU), (T)),
(DI, (DI, DI), (T)), (DU, (DU, DU), (T)),
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
(XF, (XF, XF), (T)), (P, (P, P), (T))))
define_operator(eq,
$R1 = $S1 == $S2,
((SI, (SI, SI), (T)), (DI, (DI, DI), (T)),
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
(XF, (XF, XF), (T)), (P, (P, P), (T))))
define_operator(ne,
$R1 = $S1 != $S2,
((SI, (SI, SI), (T)), (DI, (DI, DI), (T)),
(SF, (SF, SF), (T)), (DF, (DF, DF), (T)),
(XF, (XF, XF), (T)), (P, (P, P), (T))))
# Unary operations.
define_operator(neg,
$R1 = -$S1,
((SI, (SI), (SI)), (DI, (DI), (DI)),
(SF, (SF), (SF)), (DF, (DF), (DF)),
(XF, (XF), (XF))))
define_operator(not,
$R1 = ~$S1,
((SI, (SI), (SI)), (DI, (DI), (DI))))
define_operator(not,
$R1 = !$S1,
((T, (SI), (SI))))
# Increment operations.
define_operator(predec,
$R1 = *\($TR1 *\) $S1 -= $S2,
((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
(SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
(P, (P, SI), (P)), (SF, (P, SF), (SF)),
(DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
(BI, (SU, SU, P, SI), (SI))))
define_operator(preinc,
$R1 = *\($TR1 *\) $S1 += $S2,
((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
(SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
(P, (P, SI), (P)), (SF, (P, SF), (SF)),
(DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
(BI, (SU, SU, P, SI), (SI))))
define_operator(postdec,
$R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 -= $S2,
((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
(SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
(P, (P, SI), (P)), (SF, (P, SF), (SF)),
(DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
(BI, (SU, SU, P, SI), (SI))))
define_operator(postinc,
$R1 = *\($TR1 *\) $S1\, *\($TR1 *\) $S1 += $S2,
((QI, (P, QI), (QI)), (HI, (P, HI), (HI)),
(SI, (P, SI), (SI)), (DI, (P, DI), (DI)),
(P, (P, SI), (P)), (SF, (P, SF), (SF)),
(DF, (P, DF), (DF)), (XF, (P, XF), (XF)),
(BI, (SU, SU, P, SI), (SI))))
# Jumps.
define_operator(xjumpif, if \($S1\) pc = code->pc0 + $L1, ((, (T),, (SI))))
define_operator(xjumpifnot, if \(! $S1\) pc = code->pc0 + $L1, ((, (T),, (SI))))
define_operator(jump, pc = code->pc0 + $L1, ((,,,(SI))))
# This is for GCC2. It jumps to the address on the stack.
define_operator(jump, pc = \(void *\) $S1, ((P,,)))
# Switches. In order to (eventually) support ranges we provide four different
# varieties of switches. Arguments are the switch index from the stack, the
# bytecode offset of the switch table, the size of the switch table, and
# the default label.
define_operator(caseSI, CASESI\($S1\, $L1\, $L2\, $L3\), ((, (SI),, (SI, SI, SI))))
define_operator(caseSU, CASESU\($S1\, $L1\, $L2\, $L3\), ((, (SU),, (SI, SI, SI))))
define_operator(caseDI, CASEDI\($S1\, $L1\, $L2\, $L3\), ((, (DI),, (SI, SI, SI))))
define_operator(caseDU, CASEDU\($S1\, $L1\, $L2\, $L3\), ((, (DU),, (SI, SI, SI))))
# Procedure call.
# Stack arguments are (deepest first):
# procedure arguments in reverse order.
# pointer to the place to hold the return value.
# address of the call description vector.
# pointer to the procedure to be called.
define_operator(call, CALL\($S1\, $S2\, $S3\, sp\), ((, (P, P, P))))
# Procedure return.
# Pushes on interpreter stack:
# value of retptr (pointer to return value storage slot)
define_operator(return, $R1 = retptr, ((P,,(P))))
# Really return.
define_operator(ret, return, (()))
# Print an obnoxious line number.
define_operator(linenote, fprintf\(stderr\, "%d\\n"\, $L1\), ((,,,(SI))))

View file

@ -1,81 +0,0 @@
/* Bytecode definitions for GNU C-compiler.
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
extern int output_bytecode;
extern int stack_depth;
extern int max_stack_depth;
/* Emit DI constant according to target machine word ordering */
#define bc_emit_bytecode_DI_const(CST) \
{ int opcode; \
opcode = (WORDS_BIG_ENDIAN \
? TREE_INT_CST_HIGH (CST) \
: TREE_INT_CST_LOW (CST)); \
bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \
opcode = (WORDS_BIG_ENDIAN \
? TREE_INT_CST_LOW (CST) \
: TREE_INT_CST_HIGH (CST)); \
bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \
}
extern void bc_expand_expr ();
extern void bc_output_data_constructor ();
extern void bc_store_field ();
extern void bc_load_bit_field ();
extern void bc_store_bit_field ();
extern void bc_push_offset_and_size ();
extern void bc_init_mode_to_code_map ();
/* These are just stubs, so the compiler will compile for targets
that aren't yet supported by the bytecode generator. */
#ifndef TARGET_SUPPORTS_BYTECODE
#define MACHINE_SEG_ALIGN 1
#define INT_ALIGN 1
#define PTR_ALIGN 1
#define NAMES_HAVE_UNDERSCORES
#define BC_NOP (0)
#define BC_GLOBALIZE_LABEL(FP, NAME) BC_NOP
#define BC_OUTPUT_COMMON(FP, NAME, SIZE, ROUNDED) BC_NOP
#define BC_OUTPUT_LOCAL(FP, NAME, SIZE, ROUNDED) BC_NOP
#define BC_OUTPUT_ALIGN(FP, ALIGN) BC_NOP
#define BC_OUTPUT_LABEL(FP, NAME) BC_NOP
#define BC_OUTPUT_SKIP(FP, SIZE) BC_NOP
#define BC_OUTPUT_LABELREF(FP, NAME) BC_NOP
#define BC_OUTPUT_FLOAT(FP, VAL) BC_NOP
#define BC_OUTPUT_DOUBLE(FP, VAL) BC_NOP
#define BC_OUTPUT_BYTE(FP, VAL) BC_NOP
#define BC_OUTPUT_FILE ASM_OUTPUT_FILE
#define BC_OUTPUT_ASCII ASM_OUTPUT_ASCII
#define BC_OUTPUT_IDENT ASM_OUTPUT_IDENT
#define BCXSTR(RTX) ((RTX)->bc_label)
#define BC_WRITE_FILE(FP) BC_NOP
#define BC_WRITE_SEGSYM(SEGSYM, FP) BC_NOP
#define BC_WRITE_RELOC_ENTRY(SEGRELOC, FP, OFFSET) BC_NOP
#define BC_START_BYTECODE_LINE(FP) BC_NOP
#define BC_WRITE_BYTECODE(SEP, VAL, FP) BC_NOP
#define BC_WRITE_RTL(R, FP) BC_NOP
#define BC_EMIT_TRAMPOLINE(TRAMPSEG, CALLINFO) BC_NOP
#define VALIDATE_STACK BC_NOP
#endif /* !TARGET_SUPPORTS_BYTECODE */

View file

@ -1,35 +0,0 @@
/* These should come from genemit */
/* Use __signed__ in case compiling with -traditional. */
typedef __signed__ char QItype;
typedef unsigned char QUtype;
typedef __signed__ short int HItype;
typedef unsigned short int HUtype;
typedef __signed__ long int SItype;
typedef unsigned long int SUtype;
typedef __signed__ long long int DItype;
typedef unsigned long long int DUtype;
typedef float SFtype;
typedef double DFtype;
typedef long double XFtype;
typedef char *Ptype;
typedef int Ttype;
typedef union stacktype
{
QItype QIval;
QUtype QUval;
HItype HIval;
HUtype HUval;
SItype SIval;
SUtype SUval;
DItype DIval;
DUtype DUval;
SFtype SFval;
DFtype DFval;
XFtype XFval;
Ptype Pval;
Ttype Tval;
} stacktype;

976
contrib/gcc/config.sub vendored
View file

@ -1,976 +0,0 @@
#! /bin/sh
# Configuration validation subroutine script, version 1.1.
# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc.
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support. The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
if [ x$1 = x ]
then
echo Configuration name missing. 1>&2
echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
echo "or $0 ALIAS" 1>&2
echo where ALIAS is a recognized configuration type. 1>&2
exit 1
fi
# First pass through any local machine types.
case $1 in
*local*)
echo $1
exit 0
;;
*)
;;
esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
linux-gnu*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
;;
esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
### recognize some manufacturers as not being operating systems, so we
### can provide default operating systems below.
case $os in
-sun*os*)
# Prevent following clause from handling this invalid input.
;;
-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple)
os=
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*)
os=-lynxos
;;
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
-psos*)
os=-psos
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
| arme[lb] | pyramid | mn10200 | mn10300 \
| tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
| mipstx39 | mipstx39el \
| sparc | sparclet | sparclite | sparc64 | v850)
basic_machine=$basic_machine-unknown
;;
thumb | thumbel)
basic_machine=$basic_machine-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i[34567]86)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
| power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
| xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
| alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
| ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
| sparc64-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* \
| mipstx39-* | mipstx39el-* \
| f301-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
alliant | fx80)
basic_machine=fx80-alliant
;;
altos | altos3068)
basic_machine=m68k-altos
;;
am29k)
basic_machine=a29k-none
os=-bsd
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-cbm
;;
amigaos | amigados)
basic_machine=m68k-cbm
os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-cbm
os=-sysv4
;;
apollo68)
basic_machine=m68k-apollo
os=-sysv
;;
aux)
basic_machine=m68k-apple
os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
;;
convex-c2)
basic_machine=c2-convex
os=-bsd
;;
convex-c32)
basic_machine=c32-convex
os=-bsd
;;
convex-c34)
basic_machine=c34-convex
os=-bsd
;;
convex-c38)
basic_machine=c38-convex
os=-bsd
;;
cray | ymp)
basic_machine=ymp-cray
os=-unicos
;;
cray2)
basic_machine=cray2-cray
os=-unicos
;;
[ctj]90-cray)
basic_machine=c90-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
;;
delta88)
basic_machine=m88k-motorola
os=-sysv3
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
;;
dpx2* | dpx2*-bull)
basic_machine=m68k-bull
os=-sysv3
;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
;;
elxsi)
basic_machine=elxsi-elxsi
os=-bsd
;;
encore | umax | mmax)
basic_machine=ns32k-encore
;;
fx2800)
basic_machine=i860-alliant
;;
genix)
basic_machine=ns32k-ns
;;
gmicro)
basic_machine=tron-gmicro
os=-sysv
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
h8300hms)
basic_machine=h8300-hitachi
os=-hms
;;
harris)
basic_machine=m88k-harris
os=-sysv3
;;
hp300-*)
basic_machine=m68k-hp
;;
hp300bsd)
basic_machine=m68k-hp
os=-bsd
;;
hp300hpux)
basic_machine=m68k-hp
os=-hpux
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9] )
basic_machine=hppa1.0-hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9] )
basic_machine=hppa1.1-hp
;;
hp9k78[0-9] | hp78[0-9] )
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | \
hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893 )
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679] )
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hppa-next)
os=-nextstep3
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
os=-mvs
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i[34567]86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i[34567]86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i[34567]86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i[34567]86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
-irix*)
;;
*)
os=-irix4
;;
esac
;;
isi68 | isi)
basic_machine=m68k-isi
os=-sysv
;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
;;
merlin)
basic_machine=ns32k-utek
os=-sysv
;;
miniframe)
basic_machine=m68000-convergent
;;
mipsel*-linux*)
basic_machine=mipsel-unknown
os=-linux-gnu
;;
mips*-linux*)
basic_machine=mips-unknown
os=-linux-gnu
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
;;
news1000)
basic_machine=m68030-sony
os=-newsos
;;
news-3600 | risc-news)
basic_machine=mips-sony
os=-newsos
;;
next | m*-next )
basic_machine=m68k-next
case $os in
-nextstep* )
;;
-ns2*)
os=-nextstep2
;;
*)
os=-nextstep3
;;
esac
;;
nh3000)
basic_machine=m68k-harris
os=-cxux
;;
nh[45]000)
basic_machine=m88k-harris
os=-cxux
;;
nindy960)
basic_machine=i960-intel
os=-nindy
;;
np1)
basic_machine=np1-gould
;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
paragon)
basic_machine=i860-intel
os=-osf
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | nexen)
basic_machine=i586-pc
;;
pentiumpro | p6 | k6 | 6x86)
basic_machine=i686-pc
;;
pentiumii | pentium2)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | nexen-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | k6-* | 6x86-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=rs6000-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
rm[46]00)
basic_machine=mips-siemens
;;
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
sequent)
basic_machine=i386-sequent
;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sps7)
basic_machine=m68k-bull
os=-sysv2
;;
spur)
basic_machine=spur-unknown
;;
sun2)
basic_machine=m68000-sun
;;
sun2os3)
basic_machine=m68000-sun
os=-sunos3
;;
sun2os4)
basic_machine=m68000-sun
os=-sunos4
;;
sun3os3)
basic_machine=m68k-sun
os=-sunos3
;;
sun3os4)
basic_machine=m68k-sun
os=-sunos4
;;
sun4os3)
basic_machine=sparc-sun
os=-sunos3
;;
sun4os4)
basic_machine=sparc-sun
os=-sunos4
;;
sun4sol2)
basic_machine=sparc-sun
os=-solaris2
;;
sun3 | sun3-*)
basic_machine=m68k-sun
;;
sun4)
basic_machine=sparc-sun
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
udi29k)
basic_machine=a29k-amd
os=-udi
;;
ultra3)
basic_machine=a29k-nyu
os=-sym1
;;
vaxv)
basic_machine=vax-dec
os=-sysv
;;
vms)
basic_machine=vax-dec
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
;;
vxworks68)
basic_machine=m68k-wrs
os=-vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
os=-vxworks
;;
xmp)
basic_machine=xmp-cray
os=-unicos
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
none)
basic_machine=none-none
os=-none
;;
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
mips)
if [ x$os = x-linux-gnu ]; then
basic_machine=mips-unknown
else
basic_machine=mips-mips
fi
;;
romp)
basic_machine=romp-ibm
;;
rs6000)
basic_machine=rs6000-ibm
;;
vax)
basic_machine=vax-dec
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sparc)
basic_machine=sparc-sun
;;
cydra)
basic_machine=cydra-cydrome
;;
orion)
basic_machine=orion-highlevel
;;
orion105)
basic_machine=clipper-highlevel
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
;;
*-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
;;
*)
;;
esac
# Decode manufacturer-specific aliases for certain operating systems.
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
-solaris)
os=-solaris2
;;
-svr4*)
os=-sysv4
;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* )
# Remember, each alternative MUST END IN *, to match a version number.
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*)
os=-bsd
;;
-dynix*)
os=-bsd
;;
-acis*)
os=-aos
;;
-ctix* | -uts*)
os=-sysv
;;
-ns2 )
os=-nextstep2
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
-sinix*)
os=-sysv4
;;
-triton*)
os=-sysv3
;;
-oss*)
os=-sysv3
;;
-svr4)
os=-sysv4
;;
-svr3)
os=-sysv3
;;
-sysvr4)
os=-sysv4
;;
# This must come after -sysvr4.
-sysv*)
;;
-xenix)
os=-xenix
;;
-none)
;;
*)
# Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
exit 1
;;
esac
else
# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.
# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system. Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
case $basic_machine in
*-acorn)
os=-riscix1.2
;;
arm*-semi)
os=-aout
;;
pdp11-*)
os=-none
;;
*-dec | vax-*)
os=-ultrix4.2
;;
m68*-apollo)
os=-domain
;;
i386-sun)
os=-sunos4.0.2
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-ibm)
os=-aix
;;
*-hp)
os=-hpux
;;
*-hitachi)
os=-hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
os=-sysv
;;
*-cbm)
os=-amigaos
;;
*-dg)
os=-dgux
;;
*-dolphin)
os=-sysv3
;;
m68k-ccur)
os=-rtu
;;
m88k-omron*)
os=-luna
;;
*-next )
os=-nextstep
;;
*-sequent)
os=-ptx
;;
*-crds)
os=-unos
;;
*-ns)
os=-genix
;;
i370-*)
os=-mvs
;;
*-next)
os=-nextstep3
;;
*-gould)
os=-sysv
;;
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
os=-irix
;;
*-siemens)
os=-sysv4
;;
*-masscomp)
os=-rtu
;;
f301-fujitsu)
os=-uxpv
;;
*-be)
os=-beos
;;
*)
os=-none
;;
esac
fi
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
vendor=unknown
case $basic_machine in
*-unknown)
case $os in
-riscix*)
vendor=acorn
;;
-sunos*)
vendor=sun
;;
-aix*)
vendor=ibm
;;
-hpux*)
vendor=hp
;;
-hiux*)
vendor=hitachi
;;
-unos*)
vendor=crds
;;
-dgux*)
vendor=dg
;;
-luna*)
vendor=omron
;;
-genix*)
vendor=ns
;;
-mvs*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-vxsim* | -vxworks*)
vendor=wrs
;;
-aux*)
vendor=apple
;;
-beos*)
vendor=be
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os

View file

@ -1,96 +0,0 @@
/* Configuration for an i386 running MS-DOS with djgpp/go32. */
#include "dbxcoff.h"
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
#define HANDLE_SYSV_PRAGMA
#define YES_UNDERSCORES
#include "i386/gas.h"
#ifdef CPP_PREDEFINES
#undef CPP_PREDEFINES
#endif
#define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DMSDOS \
-Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386)"
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_ctor, in_dtor
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
CTOR_SECTION_FUNCTION \
DTOR_SECTION_FUNCTION
#define CTOR_SECTION_FUNCTION \
void \
ctor_section () \
{ \
if (in_section != in_ctor) \
{ \
fprintf (asm_out_file, "\t.section .ctor\n"); \
in_section = in_ctor; \
} \
}
#define DTOR_SECTION_FUNCTION \
void \
dtor_section () \
{ \
if (in_section != in_dtor) \
{ \
fprintf (asm_out_file, "\t.section .dtor\n"); \
in_section = in_dtor; \
} \
}
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
do { \
ctor_section (); \
fprintf (FILE, "%s\t", ASM_LONG); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
/* Allow (eg) __attribute__((section "locked")) to work */
#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC)\
do { \
fprintf (FILE, "\t.section %s\n", NAME); \
} while (0)
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
do { \
dtor_section (); \
fprintf (FILE, "%s\t", ASM_LONG); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
/* Output at beginning of assembler file. */
/* The .file command should always begin the output. */
/* Use the main_input_filename instead of dump_base_name */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
do { \
output_file_directive (FILE, main_input_filename); \
} while (0)
/* This is how to output an assembler line
that says to advance the location counter
to a multiple of 2**LOG bytes. */
#undef ASM_OUTPUT_ALIGN
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
if ((LOG) != 0) fprintf ((FILE), "\t.p2align %d\n", LOG)
/* djgpp has atexit (). */
#undef HAVE_ATEXIT
#define HAVE_ATEXIT
/* djgpp automatically calls its own version of __main, so don't define one
in libgcc, nor call one in main(). */
#define HAS_INIT_SECTION

View file

@ -1,67 +0,0 @@
/* Definitions for Intel 386 running Interactive Unix System V,
producing stabs-in-coff output (using a slightly modified gas).
Specifically, this is for recent versions that support POSIX;
for version 2.0.2, use configuration option i386-sysv instead. */
/* Underscores are not used on ISC systems (probably not on any COFF
system), despite the comments in i386/gas.h. If this is not defined,
enquire (for example) will fail to link. --karl@cs.umb.edu */
#define NO_UNDERSCORES
/* Mostly like other gas-using systems. */
#include "i386/gas.h"
/* But with ISC-specific additions. */
#include "i386/isc.h"
/* We do not want to output SDB debugging information. */
#undef SDB_DEBUGGING_INFO
/* We want to output DBX debugging information. */
#define DBX_DEBUGGING_INFO
/* The function `dbxout_init' in dbxout.c omits the first character of
`ltext_label_name' when outputting the main source directory and main
source filename. I don't understand why, but rather than making a
system-independent change there, I override dbxout.c's defaults.
Perhaps it would be better to use ".Ltext0" instead of
`ltext_label_name', but we've already generated the label, so we just
use it here. --karl@cs.umb.edu */
#define DBX_OUTPUT_MAIN_SOURCE_DIRECTORY(asmfile, cwd) \
do { fprintf (asmfile, "%s ", ASM_STABS_OP); \
output_quoted_string (asmfile, cwd); \
fprintf (asmfile, ",%d,0,0,%s\n", N_SO, ltext_label_name); \
} while (0)
#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(asmfile, input_file_name) \
fprintf (asmfile, "%s ", ASM_STABS_OP); \
output_quoted_string (input_file_name); \
fprintf (asmfile, ",%d,0,0,%s\n", N_SO, ltext_label_name); \
text_section (); \
ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Ltext", 0)
/* Because we don't include `svr3.h', we haven't yet defined SIZE_TYPE
and PTRDIFF_TYPE. ISC's definitions don't match GCC's defaults, so: */
#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
/* But we can't use crtbegin.o and crtend.o, because gas 1.38.1 doesn't
grok .section. The definitions here are otherwise identical to those
in i386/isc.h. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{!shlib:%{posix:%{pg:mcrtp1.o%s}%{!pg:%{p:mcrtp1.o%s}%{!p:crtp1.o%s}}}\
%{!posix:%{pg:mcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}\
%{p:-L/lib/libp} %{pg:-L/lib/libp}}}\
%{shlib:%{posix:crtp1.o%s}%{!posix:crt1.o%s}}"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "crtn.o%s"

View file

@ -1,7 +0,0 @@
/* next.c: Functions for NeXT as target machine for GNU C compiler. */
/* Note that the include below means that we can't debug routines in
i386.c when running on a COFF system. */
#include "i386/i386.c"
#include "nextstep.c"

View file

@ -1,7 +0,0 @@
/* Target definitions for GNU compiler for Intel 80386 running System V.4
with gas and gdb. */
/* Use stabs instead of DWARF debug format. */
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#include "i386/sysv4.h"

View file

@ -1,2 +0,0 @@
# The one that comes with the system is POSIX-compliant.
LIMITS_H =

View file

@ -1,4 +0,0 @@
/* Configuration for GCC for Intel i386 running NetBSD as host. */
#include <i386/xm-i386.h>
#include <xm-netbsd.h>

View file

@ -1,6 +0,0 @@
# Don't run fixproto
STMP_FIXPROTO =
# We don't need GCC's own include files.
USER_H =
INSTALL_ASSERT_H =

View file

@ -1,26 +0,0 @@
/* Configuration for GNU C-compiler for hosts running NetBSD.
Copyright (C) 1995 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* This file defines machine-independent things specific to a host
running NetBSD. This file should not be specified as $xm_file itself;
instead $xm_file should be CPU/xm-netbsd.h, which should include both
CPU/xm-CPU.h and this file xm-netbsd.h. */
#define HAVE_VPRINTF

View file

@ -1,117 +0,0 @@
/* Variables and structures for overloading rules.
Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* The following structure is used when comparing various alternatives
for overloading. The unsigned quantity `strikes.i' is used
for fast comparison of two possibilities. This number is an
aggregate of four constituents:
EVIL: if this is non-zero, then the candidate should not be considered
ELLIPSIS: if this is non-zero, then some actual argument has been matched
against an ellipsis
USER: if this is non-zero, then a user-defined type conversion is needed
B_OR_D: if this is non-zero, then use a base pointer instead of the
type of the pointer we started with.
EASY: if this is non-zero, then we have a builtin conversion
(such as int to long, int to float, etc) to do.
If two candidates require user-defined type conversions, and the
type conversions are not identical, then an ambiguity error
is reported.
If two candidates agree on user-defined type conversions,
and one uses pointers of strictly higher type (derived where
another uses base), then that alternative is silently chosen.
Note that this technique really only works for 255 arguments. Perhaps
this is not enough. */
/* These macros and harshness_code are used by the NEW METHOD. */
#define EVIL_CODE (1<<7)
#define CONST_CODE (1<<6)
#define ELLIPSIS_CODE (1<<5)
#define USER_CODE (1<<4)
#define STD_CODE (1<<3)
#define PROMO_CODE (1<<2)
#define QUAL_CODE (1<<1)
#define TRIVIAL_CODE (1<<0)
struct harshness_code
{
/* What kind of conversion is involved. */
unsigned short code;
/* The inheritance distance. */
short distance;
/* For a PROMO_CODE, Any special penalties involved in integral conversions.
This exists because $4.1 of the ARM states that something like
`short unsigned int' should promote to `int', not `unsigned int'.
If, for example, it tries to match two fns, f(int) and f(unsigned),
f(int) should be a better match than f(unsigned) by this rule. Without
this extra metric, they both only appear as "integral promotions", which
will lead to an ambiguity.
For a TRIVIAL_CODE, This is also used by build_overload_call_real and
convert_harshness to keep track of other information we need. */
unsigned short int_penalty;
};
struct candidate
{
struct harshness_code h; /* Used for single-argument conversions. */
int h_len; /* The length of the harshness vector. */
tree function; /* A FUNCTION_DECL */
tree basetypes; /* The path to function. */
tree arg; /* first parm to function. */
/* Indexed by argument number, encodes evil, user, d_to_b, and easy
strikes for that argument. At end of array, we store the index+1
of where we started using default parameters, or 0 if there are
none. */
struct harshness_code *harshness;
union
{
tree field; /* If no evil strikes, the FUNCTION_DECL of
the function (if a member function). */
int bad_arg; /* the index of the first bad argument:
0 if no bad arguments
> 0 is first bad argument
-1 if extra actual arguments
-2 if too few actual arguments.
-3 if const/non const method mismatch.
-4 if type unification failed.
-5 if contravariance violation. */
} u;
};
int rank_for_overload ();
/* Variables shared between class.c and call.c. */
extern int n_vtables;
extern int n_vtable_entries;
extern int n_vtable_searches;
extern int n_vtable_elems;
extern int n_convert_harshness;
extern int n_compute_conversion_costs;
extern int n_build_method_call;
extern int n_inner_fields_searched;

View file

@ -1,928 +0,0 @@
/* Interface to LUCID Cadillac system for GNU compiler.
Copyright (C) 1988, 1992, 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "tree.h"
#include "flags.h"
#include <stdio.h>
#include "cp-tree.h"
#include "obstack.h"
#ifdef CADILLAC
#include <compilerreq.h>
#include <compilerconn.h>
#include <sys/time.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/file.h>
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
void init_cadillac ();
extern char *input_filename;
extern int lineno;
/* Put random information we might want to get back from
Cadillac here. */
typedef struct
{
/* The connection to the Cadillac kernel. */
Connection *conn;
/* Input and output file descriptors for Cadillac. */
short fd_input, fd_output;
/* #include nesting of current file. */
short depth;
/* State variables for the connection. */
char messages;
char conversion;
char emission;
char process_until;
/* #if level of current file. */
int iflevel;
/* Line number that starts current source file. */
int lineno;
/* Name of current file. */
char *filename;
/* Where to stop processing (if process_until is set). */
char *end_filename;
int end_position;
} cadillac_struct;
static cadillac_struct cadillacObj;
/* Nonzero if in the process of exiting. */
static int exiting;
void cadillac_note_source ();
static void CWriteLanguageDecl ();
static void CWriteLanguageType ();
static void CWriteTopLevel ();
static void cadillac_note_filepos ();
static void cadillac_process_request (), cadillac_process_requests ();
static void cadillac_switch_source ();
static void exit_cadillac ();
/* Blocking test. */
static int
readable_p (fd)
int fd;
{
fd_set f;
FD_ZERO (&f);
FD_SET (fd, &f);
return select (32, &f, NULL, NULL, 0) == 1;
}
static CObjectType *tree_to_cadillac_map;
struct obstack cadillac_obstack;
#include "stack.h"
struct context_level
{
struct stack_level base;
tree context;
};
/* Stack for maintaining contexts (in case functions or types are nested).
When defining a struct type, the `context' field is the RECORD_TYPE.
When defining a function, the `context' field is the FUNCTION_DECL. */
static struct context_level *context_stack;
static struct context_level *
push_context_level (stack, obstack)
struct stack_level *stack;
struct obstack *obstack;
{
struct context_level tem;
tem.base.prev = stack;
return (struct context_level *)push_stack_level (obstack, &tem, sizeof (tem));
}
/* Discard a level of search allocation. */
static struct context_level *
pop_context_level (stack)
struct context_level *stack;
{
stack = (struct context_level *)pop_stack_level (stack);
return stack;
}
void
init_cadillac ()
{
extern FILE *finput;
extern int errno;
CCompilerMessage* req;
cadillac_struct *cp = &cadillacObj;
int i;
if (! flag_cadillac)
return;
tree_to_cadillac_map = (CObjectType*) xmalloc (sizeof (CObjectType) * LAST_CPLUS_TREE_CODE);
for (i = 0; i < LAST_CPLUS_TREE_CODE; i++)
tree_to_cadillac_map[i] = MiscOType;
tree_to_cadillac_map[RECORD_TYPE] = StructOType;
tree_to_cadillac_map[UNION_TYPE] = UnionOType;
tree_to_cadillac_map[ENUMERAL_TYPE] = EnumTypeOType;
tree_to_cadillac_map[TYPE_DECL] = TypedefOType;
tree_to_cadillac_map[VAR_DECL] = VariableOType;
tree_to_cadillac_map[CONST_DECL] = EnumConstantOType;
tree_to_cadillac_map[FUNCTION_DECL] = FunctionOType;
tree_to_cadillac_map[FIELD_DECL] = FieldOType;
#ifdef sun
on_exit (&exit_cadillac, 0);
#endif
gcc_obstack_init (&cadillac_obstack);
/* Yow! This is the way Cadillac was designed to deal with
Oregon C++ compiler! */
cp->fd_input = flag_cadillac;
cp->fd_output = flag_cadillac;
/* Start in "turned-on" state. */
cp->messages = 1;
cp->conversion = 1;
cp->emission = 1;
/* Establish a connection with Cadillac here. */
cp->conn = NewConnection (cp, cp->fd_input, cp->fd_output);
CWriteHeader (cp->conn, WaitingMType, 0);
CWriteRequestBuffer (cp->conn);
if (!readable_p (cp->fd_input))
;
req = CReadCompilerMessage (cp->conn);
if (!req)
switch (errno)
{
case EWOULDBLOCK:
sleep (5);
return;
case 0:
fatal ("init_cadillac: EOF on connection to kernel, exiting\n");
break;
default:
perror ("Editor to kernel connection");
exit (0);
}
}
static void
cadillac_process_requests (conn)
Connection *conn;
{
CCompilerMessage *req;
while (req = (CCompilerMessage*) CPeekNextRequest (conn))
{
req = CReadCompilerMessage (conn);
cadillac_process_request (&cadillacObj, req);
}
}
static void
cadillac_process_request (cp, req)
cadillac_struct *cp;
CCompilerMessage *req;
{
if (! req)
return;
switch (req->reqType)
{
case ProcessUntilMType:
if (cp->process_until)
my_friendly_abort (23);
cp->process_until = 1;
/* This is not really right. */
cp->end_position = ((CCompilerCommand*)req)->processuntil.position;
#if 0
cp->end_filename = req->processuntil.filename;
#endif
break;
case CommandMType:
switch (req->header.data)
{
case MessagesOnCType:
cp->messages = 1;
break;
case MessagesOffCType:
cp->messages = 0;
break;
case ConversionOnCType:
cp->conversion = 1;
break;
case ConversionOffCType:
cp->conversion = 0;
break;
case EmissionOnCType:
cp->emission = 1;
break;
case EmissionOffCType:
cp->emission = 0;
break;
case FinishAnalysisCType:
return;
case PuntAnalysisCType:
case ContinueAnalysisCType:
case GotoFileposCType:
case OpenSucceededCType:
case OpenFailedCType:
fprintf (stderr, "request type %d not implemented\n", req->reqType);
return;
case DieCType:
if (! exiting)
my_friendly_abort (24);
return;
}
break;
default:
fatal ("unknown request type %d", req->reqType);
}
}
void
cadillac_start ()
{
Connection *conn = cadillacObj.conn;
CCompilerMessage *req;
/* Let Cadillac know that we start in C++ language scope. */
CWriteHeader (conn, ForeignLinkageMType, LinkCPlus);
CWriteLength (conn);
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
static void
cadillac_printf (msg, name)
{
if (cadillacObj.messages)
printf ("[%s,%4d] %s `%s'\n", input_filename, lineno, msg, name);
}
void
cadillac_start_decl (decl)
tree decl;
{
Connection *conn = cadillacObj.conn;
CObjectType object_type = tree_to_cadillac_map [TREE_CODE (decl)];
if (context_stack)
switch (TREE_CODE (context_stack->context))
{
case FUNCTION_DECL:
/* Currently, cadillac only implements top-level forms. */
return;
case RECORD_TYPE:
case UNION_TYPE:
cadillac_printf ("start class-level decl", IDENTIFIER_POINTER (DECL_NAME (decl)));
break;
default:
my_friendly_abort (25);
}
else
{
cadillac_printf ("start top-level decl", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
CWriteTopLevel (conn, StartMType);
}
CWriteLanguageDecl (conn, decl, tree_to_cadillac_map[TREE_CODE (decl)]);
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
void
cadillac_finish_decl (decl)
tree decl;
{
Connection *conn = cadillacObj.conn;
if (context_stack)
switch (TREE_CODE (context_stack->context))
{
case FUNCTION_DECL:
return;
case RECORD_TYPE:
case UNION_TYPE:
cadillac_printf ("end class-level decl", IDENTIFIER_POINTER (DECL_NAME (decl)));
CWriteHeader (conn, EndDefMType, 0);
CWriteLength (conn);
break;
default:
my_friendly_abort (26);
}
else
{
cadillac_printf ("end top-level decl", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
CWriteHeader (conn, EndDefMType, 0);
CWriteLength (conn);
CWriteTopLevel (conn, StopMType);
}
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
void
cadillac_start_function (fndecl)
tree fndecl;
{
Connection *conn = cadillacObj.conn;
if (context_stack)
/* nested functions not yet handled. */
my_friendly_abort (27);
cadillac_printf ("start top-level function", lang_printable_name (fndecl));
context_stack = push_context_level (context_stack, &cadillac_obstack);
context_stack->context = fndecl;
CWriteTopLevel (conn, StartMType);
my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 202);
CWriteLanguageDecl (conn, fndecl,
(TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE
? MemberFnOType : FunctionOType));
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
void
cadillac_finish_function (fndecl)
tree fndecl;
{
Connection *conn = cadillacObj.conn;
cadillac_printf ("end top-level function", lang_printable_name (fndecl));
context_stack = pop_context_level (context_stack);
if (context_stack)
/* nested functions not yet implemented. */
my_friendly_abort (28);
CWriteHeader (conn, EndDefMType, 0);
CWriteLength (conn);
CWriteTopLevel (conn, StopMType);
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
void
cadillac_finish_anon_union (decl)
tree decl;
{
Connection *conn = cadillacObj.conn;
if (! global_bindings_p ())
return;
cadillac_printf ("finish top-level anon union", "");
CWriteHeader (conn, EndDefMType, 0);
CWriteLength (conn);
CWriteTopLevel (conn, StopMType);
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
void
cadillac_start_enum (type)
tree type;
{
Connection *conn = cadillacObj.conn;
tree name = TYPE_NAME (type);
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
if (context_stack)
switch (TREE_CODE (context_stack->context))
{
case FUNCTION_DECL:
return;
case RECORD_TYPE:
case UNION_TYPE:
break;
default:
my_friendly_abort (29);
}
else
{
cadillac_printf ("start top-level enum", IDENTIFIER_POINTER (name));
CWriteTopLevel (conn, StartMType);
}
CWriteLanguageType (conn, type, tree_to_cadillac_map[ENUMERAL_TYPE]);
}
void
cadillac_finish_enum (type)
tree type;
{
Connection *conn = cadillacObj.conn;
tree name = TYPE_NAME (type);
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
if (context_stack)
switch (TREE_CODE (context_stack->context))
{
case FUNCTION_DECL:
return;
case RECORD_TYPE:
case UNION_TYPE:
CWriteHeader (conn, EndDefMType, 0);
CWriteLength (conn);
break;
default:
my_friendly_abort (30);
}
else
{
CWriteHeader (conn, EndDefMType, 0);
CWriteLength (conn);
cadillac_printf ("finish top-level enum", IDENTIFIER_POINTER (name));
CWriteTopLevel (conn, StopMType);
}
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
void
cadillac_start_struct (type)
tree type;
{
Connection *conn = cadillacObj.conn;
tree name = TYPE_NAME (type);
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
if (context_stack)
switch (TREE_CODE (context_stack->context))
{
case FUNCTION_DECL:
return;
case RECORD_TYPE:
case UNION_TYPE:
return;
default:
my_friendly_abort (31);
}
else
{
cadillac_printf ("start struct", IDENTIFIER_POINTER (name));
CWriteTopLevel (conn, StartMType);
}
context_stack = push_context_level (context_stack, &cadillac_obstack);
context_stack->context = type;
CWriteLanguageType (conn, type,
TYPE_LANG_SPECIFIC (type) && CLASSTYPE_DECLARED_CLASS (type) ? ClassOType : tree_to_cadillac_map[TREE_CODE (type)]);
}
void
cadillac_finish_struct (type)
tree type;
{
Connection *conn = cadillacObj.conn;
tree name = TYPE_NAME (type);
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
context_stack = pop_context_level (context_stack);
if (context_stack)
return;
cadillac_printf ("finish struct", IDENTIFIER_POINTER (name));
CWriteHeader (conn, EndDefMType, 0);
CWriteLength (conn);
CWriteTopLevel (conn, StopMType);
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
void
cadillac_finish_exception (type)
tree type;
{
Connection *conn = cadillacObj.conn;
fatal ("cadillac_finish_exception");
CWriteHeader (conn, EndDefMType, 0);
CWriteLength (conn);
CWriteTopLevel (conn, StopMType);
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
void
cadillac_push_class (type)
tree type;
{
}
void
cadillac_pop_class ()
{
}
void
cadillac_push_lang (name)
tree name;
{
Connection *conn = cadillacObj.conn;
CLinkLanguageType m;
if (name == lang_name_cplusplus)
m = LinkCPlus;
else if (name == lang_name_c)
m = LinkC;
else
my_friendly_abort (32);
CWriteHeader (conn, ForeignLinkageMType, m);
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
void
cadillac_pop_lang ()
{
Connection *conn = cadillacObj.conn;
CWriteHeader (conn, ForeignLinkageMType, LinkPop);
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
void
cadillac_finish_stmt ()
{
}
void
cadillac_note_source ()
{
cadillacObj.lineno = lineno;
cadillacObj.filename = input_filename;
}
static void
CWriteTopLevel (conn, m)
Connection *conn;
CMessageSubType m;
{
static context_id = 0;
CWriteHeader (conn, TopLevelFormMType, m);
cadillac_note_filepos ();
/* Eventually, this will point somewhere into the digest file. */
context_id += 1;
CWriteSomething (conn, &context_id, sizeof (BITS32));
CWriteSomething (conn, &cadillacObj.iflevel, sizeof (BITS32));
CWriteLength (conn);
}
static void
cadillac_note_filepos ()
{
extern FILE *finput;
int pos = ftell (finput);
CWriteSomething (cadillacObj.conn, &pos, sizeof (BITS32));
}
void
cadillac_switch_source (startflag)
int startflag;
{
Connection *conn = cadillacObj.conn;
/* Send out the name of the source file being compiled. */
CWriteHeader (conn, SourceFileMType, startflag ? StartMType : StopMType);
CWriteSomething (conn, &cadillacObj.depth, sizeof (BITS16));
CWriteVstring0 (conn, input_filename);
CWriteLength (conn);
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
void
cadillac_push_source ()
{
cadillacObj.depth += 1;
cadillac_switch_source (1);
}
void
cadillac_pop_source ()
{
cadillacObj.depth -= 1;
cadillac_switch_source (0);
}
struct cadillac_mdep
{
short object_type;
char linkage;
char access;
short length;
};
static void
CWriteLanguageElem (conn, p, name)
Connection *conn;
struct cadillac_mdep *p;
char *name;
{
CWriteSomething (conn, &p->object_type, sizeof (BITS16));
CWriteSomething (conn, &p->linkage, sizeof (BITS8));
CWriteSomething (conn, &p->access, sizeof (BITS8));
CWriteSomething (conn, &p->length, sizeof (BITS16));
CWriteVstring0 (conn, name);
#if 0
/* Don't write date_type. */
CWriteVstring0 (conn, "");
#endif
CWriteLength (conn);
}
static void
CWriteLanguageDecl (conn, decl, object_type)
Connection *conn;
tree decl;
CObjectType object_type;
{
struct cadillac_mdep foo;
tree name;
CWriteHeader (conn, LanguageElementMType, StartDefineMType);
foo.object_type = object_type;
if (decl_type_context (decl))
{
foo.linkage = ParentLinkage;
if (TREE_PRIVATE (decl))
foo.access = PrivateAccess;
else if (TREE_PROTECTED (decl))
foo.access = ProtectedAccess;
else
foo.access = PublicAccess;
}
else
{
if (TREE_PUBLIC (decl))
foo.linkage = GlobalLinkage;
else
foo.linkage = FileLinkage;
foo.access = PublicAccess;
}
name = DECL_NAME (decl);
foo.length = IDENTIFIER_LENGTH (name);
CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name));
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
static void
CWriteLanguageType (conn, type, object_type)
Connection *conn;
tree type;
CObjectType object_type;
{
struct cadillac_mdep foo;
tree name = TYPE_NAME (type);
CWriteHeader (conn, LanguageElementMType, StartDefineMType);
foo.object_type = object_type;
if (current_class_type)
{
foo.linkage = ParentLinkage;
if (TREE_PRIVATE (type))
foo.access = PrivateAccess;
else if (TREE_PROTECTED (type))
foo.access = ProtectedAccess;
else
foo.access = PublicAccess;
}
else
{
foo.linkage = NoLinkage;
foo.access = PublicAccess;
}
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
foo.length = IDENTIFIER_LENGTH (name);
CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name));
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
static void
CWriteUseObject (conn, type, object_type, use)
Connection *conn;
tree type;
CObjectType object_type;
CMessageSubType use;
{
struct cadillac_mdep foo;
tree name = NULL_TREE;
CWriteHeader (conn, LanguageElementMType, use);
foo.object_type = object_type;
if (current_class_type)
{
foo.linkage = ParentLinkage;
if (TREE_PRIVATE (type))
foo.access = PrivateAccess;
else if (TREE_PROTECTED (type))
foo.access = ProtectedAccess;
else
foo.access = PublicAccess;
}
else
{
foo.linkage = NoLinkage;
foo.access = PublicAccess;
}
switch (TREE_CODE (type))
{
case VAR_DECL:
case FIELD_DECL:
case TYPE_DECL:
case CONST_DECL:
case FUNCTION_DECL:
name = DECL_NAME (type);
break;
default:
my_friendly_abort (33);
}
foo.length = IDENTIFIER_LENGTH (name);
CWriteLanguageElem (conn, &foo, IDENTIFIER_POINTER (name));
CWriteRequestBuffer (conn);
cadillac_process_requests (conn);
}
/* Here's how we exit under cadillac. */
static void
exit_cadillac ()
{
extern int errorcount;
Connection *conn = cadillacObj.conn;
if (flag_cadillac)
{
CCompilerMessage *req;
CWriteHeader (conn, FinishedMType,
errorcount ? 0 : CsObjectWritten | CsComplete);
/* Bye, bye! */
CWriteRequestBuffer (conn);
/* Block on read. */
while (! readable_p (cadillacObj.fd_input))
{
if (exiting)
my_friendly_abort (34);
exiting = 1;
}
exiting = 1;
req = CReadCompilerMessage (conn);
cadillac_process_request (&cadillacObj, req);
}
}
#else
/* Stubs. */
void init_cadillac () {}
void cadillac_start () {}
void cadillac_start_decl (decl)
tree decl;
{}
void
cadillac_finish_decl (decl)
tree decl;
{}
void
cadillac_start_function (fndecl)
tree fndecl;
{}
void
cadillac_finish_function (fndecl)
tree fndecl;
{}
void
cadillac_finish_anon_union (decl)
tree decl;
{}
void
cadillac_start_enum (type)
tree type;
{}
void
cadillac_finish_enum (type)
tree type;
{}
void
cadillac_start_struct (type)
tree type;
{}
void
cadillac_finish_struct (type)
tree type;
{}
void
cadillac_finish_exception (type)
tree type;
{}
void
cadillac_push_class (type)
tree type;
{}
void
cadillac_pop_class ()
{}
void
cadillac_push_lang (name)
tree name;
{}
void
cadillac_pop_lang ()
{}
void
cadillac_note_source ()
{}
void
cadillac_finish_stmt ()
{}
void
cadillac_switch_source ()
{}
void
cadillac_push_source ()
{}
void
cadillac_pop_source ()
{}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,236 +0,0 @@
@node ANSI
@chapter @sc{gnu} C++ Conformance to @sc{ansi} C++
These changes in the @sc{gnu} C++ compiler were made to comply more
closely with the @sc{ansi} base document, @cite{The Annotated C++
Reference Manual} (the @sc{arm}). Further reducing the divergences from
@sc{ansi} C++ is a continued goal of the @sc{gnu} C++ Renovation
Project.
@b{Section 3.4}, @i{Start and Termination}. It is now invalid to take
the address of the function @samp{main()}.
@b{Section 4.8}, @i{Pointers to Members}. The compiler produces
an error for trying to convert between a pointer to a member and the type
@samp{void *}.
@b{Section 5.2.5}, @i{Increment and Decrement}. It is an error to use
the increment and decrement operators on an enumerated type.
@b{Section 5.3.2}, @i{Sizeof}. Doing @code{sizeof} on a function is now
an error.
@b{Section 5.3.4}, @i{Delete}. The syntax of a @i{cast-expression} is
now more strictly controlled.
@b{Section 7.1.1}, @i{Storage Class Specifiers}. Using the
@code{static} and @code{extern} specifiers can now only be applied to
names of objects, functions, and anonymous unions.
@b{Section 7.1.1}, @i{Storage Class Specifiers}. The compiler no longer complains
about taking the address of a variable which has been declared to have @code{register}
storage.
@b{Section 7.1.2}, @i{Function Specifiers}. The compiler produces an
error when the @code{inline} or @code{virtual} specifiers are
used on anything other than a function.
@b{Section 8.3}, @i{Function Definitions}. It is now an error to shadow
a parameter name with a local variable; in the past, the compiler only
gave a warning in such a situation.
@b{Section 8.4.1}, @i{Aggregates}. The rules concerning declaration of
an aggregate are now all checked in the @sc{gnu} C++ compiler; they
include having no private or protected members and no base classes.
@b{Section 8.4.3}, @i{References}. Declaring an array of references is
now forbidden. Initializing a reference with an initializer list is
also considered an error.
@b{Section 9.5}, @i{Unions}. Global anonymous unions must be declared
@code{static}.
@b{Section 11.4}, @i{Friends}. Declaring a member to be a friend of a
type that has not yet been defined is an error.
@b{Section 12.1}, @i{Constructors}. The compiler generates a
default copy constructor for a class if no constructor has been declared.
@ignore
@b{Section 12.4}, @i{Destructors}. In accordance with the @sc{ansi} C++
draft standard working paper, a pure virtual destructor must now be
defined.
@end ignore
@b{Section 12.6.2}, @i{Special Member Functions}. When using a
@i{mem-initializer} list, the compiler will now initialize class members
in declaration order, not in the order in which you specify them.
Also, the compiler enforces the rule that non-static @code{const}
and reference members must be initialized with a @i{mem-initializer}
list when their class does not have a constructor.
@b{Section 12.8}, @i{Copying Class Objects}. The compiler generates
default copy constructors correctly, and supplies default assignment
operators compatible with user-defined ones.
@b{Section 13.4}, @i{Overloaded Operators}. An overloaded operator may
no longer have default arguments.
@b{Section 13.4.4}, @i{Function Call}. An overloaded @samp{operator ()}
must be a non-static member function.
@b{Section 13.4.5}, @i{Subscripting}. An overloaded @samp{operator []}
must be a non-static member function.
@b{Section 13.4.6}, @i{Class Member Access}. An overloaded @samp{operator ->}
must be a non-static member function.
@b{Section 13.4.7}, @i{Increment and Decrement}. The compiler will now
make sure a postfix @samp{@w{operator ++}} or @samp{@w{operator --}} has an
@code{int} as its second argument.
@node Encoding
@chapter Name Encoding in @sc{gnu} C++
@c FIXME!! rewrite name encoding section
@c ...to give complete rules rather than diffs from ARM.
@c To avoid plagiarism, invent some different way of structuring the
@c description of the rules than what ARM uses.
@cindex mangling
@cindex name encoding
@cindex encoding information in names
In order to support its strong typing rules and the ability to provide
function overloading, the C++ programming language @dfn{encodes}
information about functions and objects, so that conflicts across object
files can be detected during linking. @footnote{This encoding is also
sometimes called, whimsically enough, @dfn{mangling}; the corresponding
decoding is sometimes called @dfn{demangling}.} These rules tend to be
unique to each individual implementation of C++.
The scheme detailed in the commentary for 7.2.1 of @cite{The Annotated
Reference Manual} offers a description of a possible implementation
which happens to closely resemble the @code{cfront} compiler. The
design used in @sc{gnu} C++ differs from this model in a number of ways:
@itemize @bullet
@item
In addition to the basic types @code{void}, @code{char}, @code{short},
@code{int}, @code{long}, @code{float}, @code{double}, and @code{long
double}, @sc{gnu} C++ supports two additional types: @code{wchar_t}, the wide
character type, and @code{long long} (if the host supports it). The
encodings for these are @samp{w} and @samp{x} respectively.
@item
According to the @sc{arm}, qualified names (e.g., @samp{foo::bar::baz}) are
encoded with a leading @samp{Q}. Followed by the number of
qualifications (in this case, three) and the respective names, this
might be encoded as @samp{Q33foo3bar3baz}. @sc{gnu} C++ adds a leading
underscore to the list, producing @samp{_Q33foo3bar3baz}.
@item
The operator @samp{*=} is encoded as @samp{__aml}, not @samp{__amu}, to
match the normal @samp{*} operator, which is encoded as @samp{__ml}.
@c XXX left out ->(), __wr
@item
In addition to the normal operators, @sc{gnu} C++ also offers the minimum and
maximum operators @samp{>?} and @samp{<?}, encoded as @samp{__mx} and
@samp{__mn}, and the conditional operator @samp{?:}, encoded as @samp{__cn}.
@cindex destructors, encoding of
@cindex constructors, encoding of
@item
Constructors are encoded as simply @samp{__@var{name}}, where @var{name}
is the encoded name (e.g., @code{3foo} for the @code{foo} class
constructor). Destructors are encoded as two leading underscores
separated by either a period or a dollar sign, depending on the
capabilities of the local host, followed by the encoded name. For
example, the destructor @samp{foo::~foo} is encoded as @samp{_$_3foo}.
@item
Virtual tables are encoded with a prefix of @samp{_vt}, rather than
@samp{__vtbl}. The names of their classes are separated by dollar signs
(or periods), and not encoded as normal: the virtual table for
@code{foo} is @samp{__vt$foo}, and the table for @code{foo::bar} is
named @samp{__vt$foo$bar}.
@item
Static members are encoded as a leading underscore, followed by the
encoded name of the class in which they appear, a separating dollar sign
or period, and finally the unencoded name of the variable. For example,
if the class @code{foo} contains a static member @samp{bar}, its
encoding would be @samp{_3foo$bar}.
@item
@sc{gnu} C++ is not as aggressive as other compilers when it comes to always
generating @samp{Fv} for functions with no arguments. In particular,
the compiler does not add the sequence to conversion operators. The
function @samp{foo::bar()} is encoded as @samp{bar__3foo}, not
@samp{bar__3fooFv}.
@item
The argument list for methods is not prefixed by a leading @samp{F}; it
is considered implied.
@item
@sc{gnu} C++ approaches the task of saving space in encodings
differently from that noted in the @sc{arm}. It does use the
@samp{T@var{n}} and @samp{N@var{x}@var{y}} codes to signify copying the
@var{n}th argument's type, and making the next @var{x} arguments be the
type of the @var{y}th argument, respectively. However, the values for
@var{n} and @var{y} begin at zero with @sc{gnu} C++, whereas the
@sc{arm} describes them as starting at one. For the function @samp{foo
(bartype, bartype)}, @sc{gnu} C++ uses @samp{foo__7bartypeT0}, while
compilers following the @sc{arm} example generate @samp{foo__7bartypeT1}.
@c Note it loses on `foo (int, int, int, int, int)'.
@item
@sc{gnu} C++ does not bother using the space-saving methods for types whose
encoding is a single character (like an integer, encoded as @samp{i}).
This is useful in the most common cases (two @code{int}s would result in
using three letters, instead of just @samp{ii}).
@end itemize
@c @node Cfront
@c @chapter @code{cfront} Compared to @sc{gnu} C++
@c
@c
@c FIXME!! Fill in. Consider points in the following:
@c
@c @display
@c Date: Thu, 2 Jan 92 21:35:20 EST
@c From: raeburn@@cygnus.com
@c Message-Id: <9201030235.AA10999@@cambridge.cygnus.com>
@c To: mrs@@charlie.secs.csun.edu
@c Cc: g++@@cygnus.com
@c Subject: Re: ARM and GNU C++ incompatabilities
@c
@c Along with that, we should probably describe how g++ differs from
@c cfront, in ways that the users will notice. (E.g., cfront supposedly
@c allows "free (new char[10])"; does g++? How do the template
@c implementations differ? "New" placement syntax?)
@c @end display
@c
@c XXX For next revision.
@c
@c GNU C++:
@c * supports expanding inline functions in many situations,
@c including those which have static objects, use `for' statements,
@c and other situations. Part of this versatility is due to is
@c ability to not always generate temporaries for assignments.
@c * deliberately allows divide by 0 and mod 0, since [according
@c to Wilson] there are actually situations where you'd like to allow
@c such things. Note on most systems it will cause some sort of trap
@c or bus error. Cfront considers it an error.
@c * does [appear to] support nested classes within templates.
@c * conversion functions among baseclasses are all usable by
@c a class that's derived from all of those bases.
@c * sizeof works even when the class is defined within its ()'s
@c * conditional expressions work with member fns and pointers to
@c members.
@c * can handle non-trivial declarations of variables within switch
@c statements.
@c
@c Cfront:

View file

@ -1,235 +0,0 @@
@node Templates
@chapter The Template Implementation
@cindex templates
@cindex function templates
@cindex class templates
@cindex parameterized types
@cindex types, parameterized
The C++ template@footnote{Class templates are also known as
@dfn{parameterized types}.} facility, which effectively allows use of
variables for types in declarations, is one of the newest features of
the language.
@sc{gnu} C++ is one of the first compilers to implement many
of the template facilities currently defined by the @sc{ansi} committee.
Nevertheless, the template implementation is not yet complete. This
chapter maps the current limitations of the @sc{gnu} C++ template
implementation.
@menu
* Template limitations:: Limitations for function and class templates
* Function templates:: Limitations for function templates
* Class templates:: Limitations for class templates
* Template debugging:: Debugging information for templates
@end menu
@node Template limitations
@section Limitations for function and class templates
@cindex template limitations
@cindex template bugs
@cindex bugs, templates
These limitations apply to any use of templates (function templates or
class templates) with @sc{gnu} C++:
@table @emph
@item Template definitions must be visible
When you compile code with templates, the template definitions must come
first (before the compiler needs to expand them), and template
definitions you use must be visible in the current scope.
@c FIXME! Is this a defined property of templates, rather than a
@c temporary limitation?
@c ANSWER: It's a limitation, but it's hard to say why it's a limitation
@c to someone. We need an infinite link-cycle, in one camp, to
@c accomplish things so you don't need the template definitions around.
@cindex static data in template classes
@cindex template classes, static data in
@item Individual initializers needed for static data
Templates for static data in template classes do not work. @xref{Class
templates,,Limitations for class templates}.
@end table
@node Function templates
@section Limitations for function templates
@cindex function template limitations
Function templates are implemented for the most part. The compiler can
correctly determine template parameter values, and will delay
instantiation of a function that uses templates until the requisite type
information is available.
@noindent
The following limitations remain:
@itemize @bullet
@cindex template vs declaration, functions
@cindex declaration vs template, functions
@cindex function declaration vs template
@item
Narrowed specification: function declarations should not prevent
template expansion. When you declare a function, @sc{gnu} C++
interprets the declaration as an indication that you will provide a
definition for that function. Therefore, @sc{gnu} C++ does not use a
template expansion if there is also an applicable declaration. @sc{gnu}
C++ only expands the template when there is no such declaration.
The specification in Bjarne Stroustrup's @cite{The C++ Programming
Language, Second Edition} is narrower, and the @sc{gnu} C++
implementation is now clearly incorrect. With this new specification, a
declaration that corresponds to an instantiation of a function template
only affects whether conversions are needed to use that version of the
function. It should no longer prevent expansion of the template
definition.
For example, this code fragment must be treated differently:
@smallexample
template <class X> X min (X& x1, X& x2) @{ @dots{} @}
int min (int, int);
@dots{}
int i; short s;
min (i, s); // @r{should call} min(int,int)
// @r{derived from template}
@dots{}
@end smallexample
@item
The compiler does not yet understand function signatures where types are
nested within template parameters. For example, a function like the
following produces a syntax error on the closing @samp{)} of the
definition of the function @code{f}:
@smallexample
template <class T> class A @{ public: T x; class Y @{@}; @};
template <class X> int f (A<X>::Y y) @{ @dots{} @}
@end smallexample
@cindex @code{inline} and function templates
@cindex function templates and @code{inline}
@item
If you declare an @code{inline} function using templates, the compiler
can only inline the code @emph{after} the first time you use
that function with whatever particular type signature the template
was instantiated.
Removing this limitation is akin to supporting nested function
definitions in @sc{gnu} C++; the limitation will probably remain until the
more general problem of nested functions is solved.
@item
All the @emph{method} templates (templates for member functions) for a
class must be visible to the compiler when the class template is
instantiated.
@end itemize
@node Class templates
@section Limitations for class templates
@cindex class template limitations
@ignore
FIXME!! Include a comprehensible version of this if someone can explain it.
(Queried Brendan and Raeburn w/full orig context, 26may1993---pesch)
- [RHP: I don't understand what the following fragment refers to. If it's
the "BIG BUG" section in the original, why does it say "overriding class
declarations" here when the more detailed text refers to *function*
declarations? Here's the fragment I don't understand:]
there are problems with user-supplied overriding class declarations (see
below).
@end ignore
@itemize @bullet
@ignore
@cindex static data, not working in templates
@item
Templates for static data in template classes do not work.
Currently, you must initialize each case of such data
individually.
@c FIXME!! Brendan to see if still true.
@c ANSWER: This section presumes that it's incorrect to have to
@c initialize for each type you instantiate with. It's not, it's the
@c right way to do it.
@end ignore
Unfortunately, individual initializations of this sort are likely to be
considered errors eventually; since they're needed now, you might want to
flag places where you use them with comments to mark the need for a
future transition.
@cindex nested type results vs templates
@item
Member functions in template classes may not have results of nested
type; @sc{gnu} C++ signals a syntax error on the attempt. The following
example illustrates this problem with an @code{enum} type @code{alph}:
@smallexample
template <class T> class list @{
@dots{}
enum alph @{a,b,c@};
alph bar();
@dots{}
@};
template <class T>
list<int>::alph list<int>::bar() // @i{Syntax error here}
@{
@dots{}
@}
@end smallexample
@cindex preprocessor conditionals in templates
@cindex conditionals (preprocessor) in templates
@item
A parsing bug makes it difficult to use preprocessor conditionals within
templates. For example, in this code:
@smallexample
template <class T>
class list @{
@dots{}
#ifdef SYSWRONG
T x;
#endif
@dots{}
@}
@end smallexample
The preprocessor output leaves sourcefile line number information (lines
like @samp{# 6 "foo.cc"} when it expands the @code{#ifdef} block. These
lines confuse the compiler while parsing templates, giving a syntax
error.
If you cannot avoid preprocessor conditionals in templates, you can
suppress the line number information using the @samp{-P} preprocessor
option (but this will make debugging more difficult), by compiling the
affected modules like this:
@smallexample
g++ -P foo.cc -o foo
@end smallexample
@cindex parsing errors, templates
@item
Parsing errors are reported when templates are first
@emph{instantiated}---not on the template definition itself. In
particular, if you do not instantiate a template definition at all, the
compiler never reports any parsing errors that may be in the template
definition.
@end itemize
@node Template debugging
@section Debugging information for templates
@cindex templates and debugging information
@cindex debugging information and templates
Debugging information for templates works for some object code formats,
but not others. It works for stabs@footnote{Except that insufficient
debugging information for methods of template classes is generated in
stabs.} (used primarily in @sc{a.out} object code, but also in the Solaris 2
version of @sc{elf}), and the @sc{mips} version of @sc{coff} debugging
format.
@sc{dwarf} support is currently minimal, and requires further
development.

View file

@ -1,116 +0,0 @@
/* This file contains the definitions and documentation for the
additional tree codes used in the GNU C++ compiler (see tree.def
for the standard codes).
Copyright (C) 1987, 1988, 1990, 1993 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Reference to the contents of an offset
(a value whose type is an OFFSET_TYPE).
Operand 0 is the object within which the offset is taken.
Operand 1 is the offset. The language independent OFFSET_REF
just won't work for us. */
DEFTREECODE (CP_OFFSET_REF, "cp_offset_ref", "r", 2)
/* For DELETE_EXPR, operand 0 is the store to be destroyed.
Operand 1 is the value to pass to the destroying function
saying whether the store should be deallocated as well. */
DEFTREECODE (DELETE_EXPR, "dl_expr", "e", 2)
DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", "e", 2)
/* For a UNSAVE_EXPR, operand 0 is the value to unsave. By unsave, we
mean that all _EXPRs such as TARGET_EXPRs, SAVE_EXPRs,
WITH_CLEANUP_EXPRs, CALL_EXPRs and RTL_EXPRs, that are protected
from being evaluated more than once should be reset so that a new
expand_expr call of this expr will cause those to be re-evaluated.
This is useful when we want to reuse a tree in different places,
but where we must re-expand. */
DEFTREECODE (UNSAVE_EXPR, "unsave_expr", "e", 1)
/* Value is reference to particular overloaded class method.
Operand 0 is the class name (an IDENTIFIER_NODE);
operand 1 is the field (also an IDENTIFIER_NODE).
The COMPLEXITY field holds the class level (usually 0). */
DEFTREECODE (SCOPE_REF, "scope_ref", "r", 2)
/* When composing an object with a member, this is the result.
Operand 0 is the object. Operand 1 is the member (usually
a dereferenced pointer to member). */
DEFTREECODE (MEMBER_REF, "member_ref", "r", 2)
/* Type conversion operator in C++. TREE_TYPE is type that this
operator converts to. Operand is expression to be converted. */
DEFTREECODE (TYPE_EXPR, "type_expr", "e", 1)
/* For CPLUS_NEW_EXPR, operand 0 is function which performs initialization,
operand 1 is argument list to initialization function,
and operand 2 is the slot which was allocated for this expression. */
DEFTREECODE (NEW_EXPR, "nw_expr", "e", 3)
DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", "e", 3)
/* A throw expression. operand 0 is the expression, if there was one,
else it is NULL_TREE. */
DEFTREECODE (THROW_EXPR, "throw_expr", "e", 1)
/* Template definition. The following fields have the specified uses,
although there are other macros in cp-tree.h that should be used for
accessing this data.
DECL_ARGUMENTS template parm vector
DECL_TEMPLATE_INFO template text &c
DECL_VINDEX list of instantiations already produced;
only done for functions so far
For class template:
DECL_INITIAL associated templates (methods &c)
DECL_RESULT null
For non-class templates:
TREE_TYPE type of object to be constructed
DECL_RESULT decl for object to be created
(e.g., FUNCTION_DECL with tmpl parms used)
*/
DEFTREECODE (TEMPLATE_DECL, "template_decl", "d", 0)
/* Index into a template parameter list. This parameter must be a type.
Use TYPE_FIELDS to find parmlist and index. */
DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", "t", 0)
/* Index into a template parameter list. This parameter must not be a
type. */
DEFTREECODE (TEMPLATE_CONST_PARM, "template_const_parm", "c", 2)
/* For uninstantiated parameterized types.
TYPE_VALUES tree list:
TREE_PURPOSE template decl
TREE_VALUE parm vector
TREE_CHAIN null
Other useful fields to be defined later. */
DEFTREECODE (UNINSTANTIATED_P_TYPE, "uninstantiated_p_type", "t", 0)
/* A thunk is a stub function.
Thunks are used to implement multiple inheritance:
At run-time, such a thunk subtracts THUNK_DELTA (an int, not a tree)
from the this pointer, and then jumps to DECL_INITIAL
(which is an ADDR_EXPR whose operand is a FUNCTION_DECL).
Other kinds of thunks may be defined later. */
DEFTREECODE (THUNK_DECL, "thunk_decl", "d", 0)
/* A namespace declaration. */
DEFTREECODE (NAMESPACE_DECL, "namespace_decl", "d", 0)

View file

@ -1,185 +0,0 @@
#!/bin/sh
#
# modified for dgux by hassey@dg-rtp.dg.com based on
#
# fixinc.svr4 written by Ron Guilmette (rfg@ncd.com).
#
# This file is part of GNU CC.
#
# GNU CC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# GNU CC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU CC; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
#
# See README-fixinc for more information.
# Directory containing the original header files.
INPUT=${2-${INPUT-/usr/include}}
# Fail if no arg to specify a directory for the output.
if [ x$1 = x ]
then echo fixincludes: no output directory specified
exit 1
fi
# Directory in which to store the results.
LIB=${1?"fixincludes: output directory not specified"}
# Make sure it exists.
if [ ! -d $LIB ]; then
mkdir $LIB || exit 1
fi
ORIG_DIR=`pwd`
# Make LIB absolute if it is relative.
# Don't do this if not necessary, since may screw up automounters.
case $LIB in
/*)
;;
*)
cd $LIB; LIB=`${PWDCMD-pwd}`
;;
esac
echo 'Building fixincludes in ' ${LIB}
# Determine whether this filesystem has symbolic links.
if ln -s X $LIB/ShouldNotExist 2>/dev/null; then
rm -f $LIB/ShouldNotExist
LINKS=true
else
LINKS=false
fi
echo 'Making directories:'
cd ${INPUT}
if $LINKS; then
files=`ls -LR | sed -n s/:$//p`
else
files=`find . -type d -print | sed '/^.$/d'`
fi
for file in $files; do
rm -rf $LIB/$file
if [ ! -d $LIB/$file ]
then mkdir $LIB/$file
fi
done
# treetops gets an alternating list
# of old directories to copy
# and the new directories to copy to.
treetops="${INPUT} ${LIB}"
if $LINKS; then
echo 'Making internal symbolic directory links'
for file in $files; do
dest=`ls -ld $file | sed -n 's/.*-> //p'`
if [ "$dest" ]; then
cwd=`pwd`
# In case $dest is relative, get to $file's dir first.
cd ${INPUT}
cd `echo ./$file | sed -n 's&[^/]*$&&p'`
# Check that the target directory exists.
# Redirections changed to avoid bug in sh on Ultrix.
(cd $dest) > /dev/null 2>&1
if [ $? = 0 ]; then
cd $dest
# X gets the dir that the link actually leads to.
x=`pwd`
# If link leads back into ${INPUT},
# make a similar link here.
if expr $x : "${INPUT}/.*" > /dev/null; then
# Y gets the actual target dir name, relative to ${INPUT}.
y=`echo $x | sed -n "s&${INPUT}/&&p"`
# DOTS is the relative path from ${LIB}/$file's dir back to ${LIB}.
dots=`echo "$file" |
sed -e 's@^./@@' -e 's@/./@/@g' -e 's@[^/][^/]*@..@g' -e 's@..$@@'`
echo $file '->' $dots$y ': Making link'
rm -fr ${LIB}/$file > /dev/null 2>&1
ln -s $dots$y ${LIB}/$file > /dev/null 2>&1
else
# If the link is to outside ${INPUT},
# treat this directory as if it actually contained the files.
# This line used to have $dest instead of $x.
# $dest seemed to be wrong for links found in subdirectories
# of ${INPUT}. Does this change break anything?
treetops="$treetops $x ${LIB}/$file"
fi
fi
cd $cwd
fi
done
fi
# Completely replace <_int_varargs.h> with a file that defines
# va_list and gnuc_va_list
file=_int_varargs.h
if [ -r ${INPUT}/$file ]; then
echo Replacing $file
cat > ${LIB}/$file << EOF
/* This file was generated by fixinc.dgux. */
#ifndef __INT_VARARGS_H
#define __INT_VARARGS_H
#if defined(__m88k__) && defined (__DGUX__)
#ifndef __GNUC_VA_LIST
#define __GNUC_VA_LIST
typedef struct
{
int __va_arg; /* argument number */
int *__va_stk; /* start of args passed on stack */
int *__va_reg; /* start of args passed in regs */
} __gnuc_va_list;
#endif /* not __GNUC_VA_LIST */
#endif /* 88k && dgux */
#ifndef _VA_LIST_
#define _VA_LIST_
typedef __gnuc_va_list va_list;
#endif /* _VA_LIST_ */
#endif /* __INT_VARARGS_H */
EOF
chmod a+r ${LIB}/$file
fi
echo 'Removing unneeded directories:'
cd $LIB
files=`find . -type d -print | sort -r`
for file in $files; do
rmdir $LIB/$file > /dev/null 2>&1
done
if $LINKS; then
echo 'Making internal symbolic non-directory links'
cd ${INPUT}
files=`find . -type l -print`
for file in $files; do
dest=`ls -ld $file | sed -n 's/.*-> //p'`
if expr "$dest" : '[^/].*' > /dev/null; then
target=${LIB}/`echo file | sed "s|[^/]*\$|$dest|"`
if [ -f $target ]; then
ln -s $dest ${LIB}/$file >/dev/null 2>&1
fi
fi
done
fi
cd ${ORIG_DIR}
exit 0

View file

@ -1,257 +0,0 @@
#! /bin/sh
# Install modified versions of certain ANSI-incompatible
# native Sequent DYNIX/ptx System V Release 3.2 system include files.
# Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
# Contributed by Bill Burton <billb@progress.com>
# Portions adapted from fixinc.svr4 and fixincludes.
#
# This file is part of GNU CC.
#
# GNU CC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# GNU CC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU CC; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
# This script munges the native include files provided with DYNIX/ptx
# so as to remove things which are violations of the ANSI C standard.
# This is done by first running fixinc.svr4 which does most of the
# work. A few includes have fixes made to them afterwards by this
# script. Once munged, the resulting new system include files are
# placed in a directory that GNU C will search *before* searching the
# /usr/include directory. This script should work properly for most
# DYNIX/ptx systems. For other types of systems, you should use the
# `fixincludes' script instead.
#
# See README-fixinc for more information.
# Directory containing the original header files.
INPUT=${2-${INPUT-/usr/include}}
# Fail if no arg to specify a directory for the output.
if [ x$1 = x ]
then echo fixincludes: no output directory specified
exit 1
fi
# Directory in which to store the results.
LIB=${1?"fixincludes: output directory not specified"}
# Make sure it exists.
if [ ! -d $LIB ]; then
mkdir $LIB || exit 1
fi
ORIG_DIR=`pwd`
# Make LIB absolute if it is relative.
# Don't do this if not necessary, since may screw up automounters.
case $LIB in
/*)
;;
*)
LIB=$ORIG_DIR/$LIB
;;
esac
echo 'Running fixinc.svr4'
# DYNIX/ptx has dirname so this is no problem
`dirname $0`/fixinc.svr4 $*
echo 'Finished fixinc.svr4'
echo 'Building fixincludes in ' ${LIB}
# Copied from fixincludes.
# Don't use or define the name va_list in stdio.h.
# This is for ANSI and also to interoperate properly with gcc's varargs.h.
file=stdio.h
if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
chmod +w ${LIB}/$file 2>/dev/null
chmod a+r ${LIB}/$file 2>/dev/null
fi
if [ -r ${LIB}/$file ]; then
echo Fixing $file, use of va_list
# Arrange for stdio.h to use stdarg.h to define __gnuc_va_list
(echo "#define __need___va_list"
echo "#include <stdarg.h>") > ${LIB}/${file}.sed
# Use __gnuc_va_list in arg types in place of va_list.
# On 386BSD use __gnuc_va_list instead of _VA_LIST_. We're hoping the
# trailing parentheses and semicolon save all other systems from this.
# Define __va_list__ (something harmless and unused) instead of va_list.
# Don't claim to have defined va_list.
sed -e 's@ va_list @ __gnuc_va_list @' \
-e 's@ va_list)@ __gnuc_va_list)@' \
-e 's@ _VA_LIST_));@ __gnuc_va_list));@' \
-e 's@ va_list@ __va_list__@' \
-e 's@\*va_list@*__va_list__@' \
-e 's@ __va_list)@ __gnuc_va_list)@' \
-e 's@_NEED___VA_LIST@_NEED___Va_LIST@' \
-e 's@VA_LIST@DUMMY_VA_LIST@' \
-e 's@_NEED___Va_LIST@_NEED___VA_LIST@' \
${LIB}/$file >> ${LIB}/${file}.sed
rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
rm -f ${LIB}/$file
fi
fi
# In pwd.h, PTX 1.x needs stdio.h included since FILE * was added in a
# prototype later on in the file.
file=pwd.h
base=`basename $file`
if [ -r ${LIB}/$file ]; then
file_to_fix=${LIB}/$file
else
if [ -r ${INPUT}/$file ]; then
file_to_fix=${INPUT}/$file
else
file_to_fix=""
fi
fi
if [ \! -z "$file_to_fix" ]; then
echo Checking $file_to_fix
if grep stdio $file_to_fix > /dev/null; then
true
else
sed -e '/#include <sys\/types\.h>/a\
\
#if defined(__STDC__) || defined(__cplusplus)\
#include <stdio.h>\
#endif /* __STDC__ */
' \
$file_to_fix > ${LIB}/${file}.sed
rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
echo Fixed $file_to_fix
fi
fi
# Copied from fixincludes.
# math.h puts the declaration of matherr before the definition
# of struct exception, so the prototype (added by fixproto) causes havoc.
file=math.h
if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
chmod +w ${LIB}/$file 2>/dev/null
chmod a+r ${LIB}/$file 2>/dev/null
fi
if [ -r ${LIB}/$file ]; then
echo Fixing $file, matherr declaration
sed -e '/^struct exception/,$b' \
-e '/matherr/i\
struct exception;
'\
${LIB}/$file > ${LIB}/${file}.sed
rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
rm -f ${LIB}/$file
fi
fi
# In netinet/in.h, the network byte swapping asm functions supported by the
# native cc compiler on PTX 1.x and 2.x is not supported in gcc. Instead,
# include <sys/byteorder.h> written out by the fixinc.svr4 script which has
# these same routines written in an asm format supported by gcc.
file=netinet/in.h
base=`basename $file`
if [ -r ${LIB}/$file ]; then
file_to_fix=${LIB}/$file
else
if [ -r ${INPUT}/$file ]; then
file_to_fix=${INPUT}/$file
else
file_to_fix=""
fi
fi
if [ \! -z "$file_to_fix" ]; then
echo Checking $file_to_fix
if grep __GNUC__ $file_to_fix > /dev/null; then
true
else
sed -e '/#define NETSWAP/a\
\
#if defined (__GNUC__) || defined (__GNUG__)\
#include <sys/byteorder.h>\
#else /* not __GNUC__ */
' \
-e '/#endif[ ]*\/\* NETSWAP \*\//i\
#endif /* not __GNUC__ */
' \
$file_to_fix > ${LIB}/${file}.sed
rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
echo Fixed $file_to_fix
fi
fi
# /usr/include/sys/mc_param.h has an embedded asm for the cpuid instruction
# on the P5. This is not used by anything else so we ifdef it out.
file=sys/mc_param.h
if [ -r ${LIB}/$file ]; then
file_to_fix=${LIB}/$file
else
if [ -r ${INPUT}/$file ]; then
file_to_fix=${INPUT}/$file
else
file_to_fix=""
fi
fi
if [ \! -z "$file_to_fix" ]; then
echo Checking $file_to_fix
if grep __GNUC__ $file_to_fix > /dev/null; then
true
else
sed -e '/__asm/,/}/{
/__asm/i\
#if !defined (__GNUC__) && !defined (__GNUG__)
/}/a\
#endif
}' \
$file_to_fix > ${LIB}/${file}.sed
rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
echo Fixed $file_to_fix
fi
fi
# /usr/include/sys/mc_param.h has an embedded asm for the cpuid instruction
# on the P5. This is not used by anything else so we ifdef it out.
file=sys/mc_param.h
if [ -r ${LIB}/$file ]; then
file_to_fix=${LIB}/$file
else
if [ -r ${INPUT}/$file ]; then
file_to_fix=${INPUT}/$file
else
file_to_fix=""
fi
fi
if [ \! -z "$file_to_fix" ]; then
echo Checking $file_to_fix
if grep __GNUC__ $file_to_fix > /dev/null; then
true
else
sed -e '/__asm/,/}/{
/__asm/i\
#if !defined (__GNUC__) && !defined (__GNUG__)
/}/a\
#endif
}' \
$file_to_fix > ${LIB}/${file}.sed
rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
echo Fixed $file_to_fix
fi
fi
exit 0

View file

@ -1,427 +0,0 @@
#! /bin/sh
#
# fixinc.sco -- Install modified versions of SCO system include
# files.
#
# Based on fixinc.svr4 script by Ron Guilmette (rfg@ncd.com) (SCO
# modifications by Ian Lance Taylor (ian@airs.com)).
#
# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
#
# This file is part of GNU CC.
#
# GNU CC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# GNU CC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU CC; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
# This script munges the native include files provided with SCO
# 3.2v4 systems so as to provide a reasonable namespace when
# compiling with gcc. The header files by default do not
# provide many essential definitions and declarations if
# __STDC__ is 1. This script modifies the header files to check
# for __STRICT_ANSI__ being defined instead. Once munged, the
# resulting new system include files are placed in a directory
# that GNU C will search *before* searching the /usr/include
# directory. This script should work properly for most SCO
# 3.2v4 systems. For other types of systems, you should use the
# `fixincludes' or the `fixinc.svr4' script instead.
#
# See README-fixinc for more information.
# Directory containing the original header files.
INPUT=${2-${INPUT-/usr/include}}
# Fail if no arg to specify a directory for the output.
if [ x$1 = x ]
then echo fixincludes: no output directory specified
exit 1
fi
# Directory in which to store the results.
LIB=${1?"fixincludes: output directory not specified"}
# Make sure it exists.
if [ ! -d $LIB ]; then
mkdir $LIB || exit 1
fi
ORIG_DIR=`pwd`
# Make LIB absolute if it is relative.
# Don't do this if not necessary, since may screw up automounters.
case $LIB in
/*)
;;
*)
cd $LIB; LIB=`${PWDCMD-pwd}`
;;
esac
echo 'Building fixincludes in ' ${LIB}
# Determine whether this filesystem has symbolic links.
if ln -s X $LIB/ShouldNotExist 2>/dev/null; then
rm -f $LIB/ShouldNotExist
LINKS=true
else
LINKS=false
fi
echo 'Making directories:'
cd ${INPUT}
if $LINKS; then
files=`ls -LR | sed -n s/:$//p`
else
files=`find . -type d -print | sed '/^.$/d'`
fi
for file in $files; do
rm -rf $LIB/$file
if [ ! -d $LIB/$file ]
then mkdir $LIB/$file
fi
done
# treetops gets an alternating list
# of old directories to copy
# and the new directories to copy to.
treetops="${INPUT} ${LIB}"
if $LINKS; then
echo 'Making internal symbolic directory links'
for file in $files; do
dest=`ls -ld $file | sed -n 's/.*-> //p'`
if [ "$dest" ]; then
cwd=`pwd`
# In case $dest is relative, get to $file's dir first.
cd ${INPUT}
cd `echo ./$file | sed -n 's&[^/]*$&&p'`
# Check that the target directory exists.
# Redirections changed to avoid bug in sh on Ultrix.
(cd $dest) > /dev/null 2>&1
if [ $? = 0 ]; then
cd $dest
# X gets the dir that the link actually leads to.
x=`pwd`
# If link leads back into ${INPUT},
# make a similar link here.
if expr $x : "${INPUT}/.*" > /dev/null; then
# Y gets the actual target dir name, relative to ${INPUT}.
y=`echo $x | sed -n "s&${INPUT}/&&p"`
echo $file '->' $y ': Making link'
rm -fr ${LIB}/$file > /dev/null 2>&1
ln -s ${LIB}/$y ${LIB}/$file > /dev/null 2>&1
else
# If the link is to outside ${INPUT},
# treat this directory as if it actually contained the files.
# This line used to have $dest instead of $x.
# $dest seemed to be wrong for links found in subdirectories
# of ${INPUT}. Does this change break anything?
treetops="$treetops $x ${LIB}/$file"
fi
fi
cd $cwd
fi
done
fi
set - $treetops
while [ $# != 0 ]; do
# $1 is an old directory to copy, and $2 is the new directory to copy to.
echo "Finding header files in $1:"
cd ${INPUT}
cd $1
files=`find . -name '*.h' -type f -print`
echo 'Checking header files:'
for file in $files; do
if egrep '!__STDC__' $file >/dev/null; then
if [ -r $file ]; then
cp $file $2/$file >/dev/null 2>&1 || echo "Can't copy $file"
chmod +w $2/$file
chmod a+r $2/$file
# The following have been removed from the sed command below
# because it is more useful to leave these things in.
# The only reason to remove them was for -pedantic,
# which isn't much of a reason. -- rms.
# /^[ ]*#[ ]*ident/d
sed -e '
s/!__STDC__/!defined (__STRICT_ANSI__)/g
' $2/$file > $2/$file.sed
mv $2/$file.sed $2/$file
if cmp $file $2/$file >/dev/null 2>&1; then
rm $2/$file
else
echo Fixed $file
fi
fi
fi
done
shift; shift
done
# We shouldn't stay in the directory we just copied.
cd ${INPUT}
# Fix first broken decl of getcwd present on some svr4 systems.
file=stdlib.h
base=`basename $file`
if [ -r ${LIB}/$file ]; then
file_to_fix=${LIB}/$file
else
if [ -r ${INPUT}/$file ]; then
file_to_fix=${INPUT}/$file
else
file_to_fix=""
fi
fi
if [ \! -z "$file_to_fix" ]; then
echo Checking $file_to_fix
sed -e 's/getcwd(char \{0,\}\*, int)/getcwd(char *, size_t)/' $file_to_fix > /tmp/$base
if cmp $file_to_fix /tmp/$base >/dev/null 2>&1; then \
true
else
echo Fixed $file_to_fix
rm -f ${LIB}/$file
cp /tmp/$base ${LIB}/$file
chmod a+r ${LIB}/$file
fi
rm -f /tmp/$base
fi
# Fix second broken decl of getcwd present on some svr4 systems. Also
# fix the incorrect decl of profil present on some svr4 systems.
file=unistd.h
base=`basename $file`
if [ -r ${LIB}/$file ]; then
file_to_fix=${LIB}/$file
else
if [ -r ${INPUT}/$file ]; then
file_to_fix=${INPUT}/$file
else
file_to_fix=""
fi
fi
if [ \! -z "$file_to_fix" ]; then
echo Checking $file_to_fix
sed -e 's/getcwd(char \*, int)/getcwd(char *, size_t)/' $file_to_fix \
| sed -e 's/profil(unsigned short \*, unsigned int, unsigned int, unsigned int)/profil(unsigned short *, size_t, int, unsigned)/' > /tmp/$base
if cmp $file_to_fix /tmp/$base >/dev/null 2>&1; then \
true
else
echo Fixed $file_to_fix
rm -f ${LIB}/$file
cp /tmp/$base ${LIB}/$file
chmod a+r ${LIB}/$file
fi
rm -f /tmp/$base
fi
# Fix third broken decl of getcwd on SCO. Also fix incorrect decl of
# link.
file=prototypes.h
base=`basename $file`
if [ -r ${LIB}/$file ]; then
file_to_fix=${LIB}/$file
else
if [ -r ${INPUT}/$file ]; then
file_to_fix=${INPUT}/$file
else
file_to_fix=""
fi
fi
if [ \! -z "$file_to_fix" ]; then
echo Checking $file_to_fix
sed -e 's/getcwd(char \*, int)/getcwd(char *, size_t)/' $file_to_fix \
| sed -e 's/const int link(const char \*, char \*)/extern int link(const char *, const char *)/' > /tmp/$base
if cmp $file_to_fix /tmp/$base >/dev/null 2>&1; then \
true
else
echo Fixed $file_to_fix
rm -f ${LIB}/$file
cp /tmp/$base ${LIB}/$file
chmod a+r ${LIB}/$file
fi
rm -f /tmp/$base
fi
# Fix an error in this file: the #if says _cplusplus, not the double
# underscore __cplusplus that it should be
file=tinfo.h
if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
mkdir ${LIB}/rpcsvc 2>/dev/null
cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
chmod +w ${LIB}/$file 2>/dev/null
chmod a+r ${LIB}/$file 2>/dev/null
fi
if [ -r ${LIB}/$file ]; then
echo Fixing $file, __cplusplus macro
sed -e 's/[ ]_cplusplus/ __cplusplus/' ${LIB}/$file > ${LIB}/${file}.sed
rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
rm ${LIB}/$file
fi
fi
# Fix prototype declaration of utime in sys/times.h. In 3.2v4.0 the
# const is missing.
file=sys/times.h
if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
chmod +w ${LIB}/$file 2>/dev/null
chmod a+r ${LIB}/$file 2>/dev/null
fi
if [ -r ${LIB}/$file ]; then
echo Fixing $file, utime prototype
sed -e 's/(const char \*, struct utimbuf \*);/(const char *, const struct utimbuf *);/' ${LIB}/$file > ${LIB}/${file}.sed
rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
rm ${LIB}/$file
fi
fi
# This function is borrowed from fixinclude.svr4
# The OpenServer math.h defines struct exception, which conflicts with
# the class exception defined in the C++ file std/stdexcept.h. We
# redefine it to __math_exception. This is not a great fix, but I
# haven't been able to think of anything better.
#
# OpenServer's math.h declares abs as inline int abs... Unfortunately,
# we blow over that one (with C++ linkage) and stick a new one in stdlib.h
# with C linkage. So we eat the one out of math.h.
file=math.h
base=`basename $file`
if [ -r ${LIB}/$file ]; then
file_to_fix=${LIB}/$file
else
if [ -r ${INPUT}/$file ]; then
file_to_fix=${INPUT}/$file
else
file_to_fix=""
fi
fi
if [ \! -z "$file_to_fix" ]; then
echo Checking $file_to_fix
sed -e '/struct exception/i\
#ifdef __cplusplus\
#define exception __math_exception\
#endif'\
-e '/struct exception/a\
#ifdef __cplusplus\
#undef exception\
#endif' \
-e 's@inline int abs(int [a-z][a-z]*) {.*}@extern "C" int abs(int);@' \
$file_to_fix > /tmp/$base
if cmp $file_to_fix /tmp/$base >/dev/null 2>&1; then \
true
else
echo Fixed $file_to_fix
rm -f ${LIB}/$file
cp /tmp/$base ${LIB}/$file
chmod a+r ${LIB}/$file
fi
rm -f /tmp/$base
fi
#
# Also, the static functions lstat() and fchmod() in <sys/stat.h>
# cause G++ grief since they're not wrapped in "if __cplusplus".
# Fix that up now.
#
file=sys/stat.h
if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
chmod +w ${LIB}/$file 2>/dev/null
chmod a+r ${LIB}/$file 2>/dev/null
fi
if [ -r ${LIB}/$file ]; then
echo Fixing $file, static definitions not C++-aware.
sed -e '/^static int[ ]*/i\
#if __cplusplus\
extern "C"\
{\
#endif /* __cplusplus */ \
' \
-e '/^}$/a\
#if __cplusplus\
}\
#endif /* __cplusplus */ \
' ${LIB}/$file > ${LIB}/${file}.sed
rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
rm -f ${LIB}/$file
fi
fi
# This fix has the regex modified from the from fixinc.wrap
# Avoid the definition of the bool type in the following files when using
# g++, since it's now an official type in the C++ language.
for file in term.h tinfo.h
do
if [ -r $INPUT/$file ]; then
echo Checking $INPUT/$file
w='[ ]'
if grep "typedef$w.*char$w.*bool$w*;" $INPUT/$file >/dev/null
then
echo Fixed $file
rm -f $LIB/$file
cat << __EOF__ >$LIB/$file
#ifndef _CURSES_H_WRAPPER
#ifdef __cplusplus
# define bool __curses_bool_t
#endif
#include_next <$file>
#ifdef __cplusplus
# undef bool
#endif
#define _CURSES_H_WRAPPER
#endif /* _CURSES_H_WRAPPER */
__EOF__
# Define _CURSES_H_WRAPPER at the end of the wrapper, not the start,
# so that if #include_next gets another instance of the wrapper,
# this will follow the #include_next chain until we arrive at
# the real system include file.
chmod a+r $LIB/$file
fi
fi
done
echo 'Removing unneeded directories:'
cd $LIB
files=`find . -type d -print | sort -r`
for file in $files; do
rmdir $LIB/$file > /dev/null 2>&1
done
if $LINKS; then
echo 'Making internal symbolic non-directory links'
cd ${INPUT}
files=`find . -type l -print`
for file in $files; do
dest=`ls -ld $file | sed -n 's/.*-> //p'`
if expr "$dest" : '[^/].*' > /dev/null; then
target=${LIB}/`echo file | sed "s|[^/]*\$|$dest|"`
if [ -f $target ]; then
ln -s $dest ${LIB}/$file >/dev/null 2>&1
fi
fi
done
fi
exit 0

File diff suppressed because it is too large Load diff

View file

@ -1,232 +0,0 @@
#! sh
#
# fixinc.winnt -- Install modified versions of Windows NT system include
# files.
#
# Based on fixinc.sco script by Ian Lance Taylor (ian@airs.com)).
# Modifications by Douglas Rupp (drupp@cs.washington.edu)
#
# This file is part of GNU CC.
#
# GNU CC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# GNU CC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU CC; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
# This script munges the native include files provided with Windows NT
# 3.5 SDK systems so as to provide a reasonable namespace when
# compiling with gcc. The header files by default do not
# provide many essential definitions and declarations if
# __STDC__ is 1. This script modifies the header files to check
# for __STRICT_ANSI__ being defined instead. Once munged, the
# resulting new system include files are placed in a directory
# that GNU C will search *before* searching the Include
# directory.
#
# See README-fixinc for more information.
ORIG_DIR=`pwd`
# Directory containing the original header files.
cd $2; SEDFILE=`${PWDCMD-pwd}`/fixinc-nt.sed
echo $SEDFILE
if [ ! -f $SEDFILE ]
then echo fixincludes: sed script 'fixinc-nt.sed' not found
exit 1
fi
echo 'Using sed script: ' ${SEDFILE}
cd $ORIG_DIR
INPUT=${INCLUDE}
echo 'Using the Include environment variable to find header files to fix'
# Fail if no arg to specify a directory for the output.
if [ x$1 = x ]
then echo fixincludes: no output directory specified
exit 1
fi
# Directory in which to store the results.
LIB=${1?"fixincludes: output directory not specified"}
# Make sure it exists.
if [ ! -d $LIB ]; then
mkdir $LIB || exit 1
fi
ORIG_DIR=`pwd`
# Make LIB absolute if it is relative.
# Don't do this if not necessary, since may screw up automounters.
case $LIB in
/*)
;;
*)
cd $LIB; LIB=`${PWDCMD-pwd}`
;;
esac
echo 'Building fixincludes in ' ${LIB}
# Determine whether this filesystem has symbolic links.
if ln -s X $LIB/ShouldNotExist 2>NUL; then
rm -f $LIB/ShouldNotExist
LINKS=true
else
LINKS=false
fi
echo 'Making directories:'
cd ${INPUT}
if $LINKS; then
files=`ls -LR | sed -n s/:$//p`
else
files=`find . -type d -print | sed '/^.$/d'`
fi
for file in $files; do
rm -rf $LIB/$file
if [ ! -d $LIB/$file ]
then mkdir $LIB/$file
fi
done
# treetops gets an alternating list
# of old directories to copy
# and the new directories to copy to.
treetops="${INPUT} ${LIB}"
set - $treetops
while [ $# != 0 ]; do
# $1 is an old directory to copy, and $2 is the new directory to copy to.
echo "Finding header files in $1:"
cd ${INPUT}
cd $1
files=`find . -name '*.[hH]' -type f -print`
echo 'Checking header files:'
for file in $files; do
echo $file
if egrep "!__STDC__" $file >NUL; then
if [ -r $file ]; then
cp $file $2/$file >NUL 2>&1 || echo "Can't copy $file"
chmod +w,a+r $2/$file
# The following have been removed from the sed command below
# because it is more useful to leave these things in.
# The only reason to remove them was for -pedantic,
# which isn't much of a reason. -- rms.
# /^[ ]*#[ ]*ident/d
sed -e '
s/!__STDC__/!defined (__STRICT_ANSI__)/g
' $2/$file > $2/$file.sed
mv $2/$file.sed $2/$file
if cmp $file $2/$file >NUL 2>&1; then
rm $2/$file
else
echo Fixed $file
fi
fi
fi
done
shift; shift
done
# Fix first broken decl of getcwd present on some svr4 systems.
file=direct.h
base=`basename $file`
if [ -r ${LIB}/$file ]; then
file_to_fix=${LIB}/$file
else
if [ -r ${INPUT}/$file ]; then
file_to_fix=${INPUT}/$file
else
file_to_fix=""
fi
fi
if [ \! -z "$file_to_fix" ]; then
echo Checking $file_to_fix
sed -e 's/getcwd(char \*, int)/getcwd(char *, size_t)/' $file_to_fix > /tmp/$base
if cmp $file_to_fix /tmp/$base >NUL 2>&1; then \
true
else
echo Fixed $file_to_fix
rm -f ${LIB}/$file
cp /tmp/$base ${LIB}/$file
chmod a+r ${LIB}/$file
fi
rm -f /tmp/$base
fi
file=rpcndr.h
base=`basename $file`
if [ -r ${LIB}/$file ]; then
file_to_fix=${LIB}/$file
else
if [ -r ${INPUT}/$file ]; then
file_to_fix=${INPUT}/$file
else
file_to_fix=""
fi
fi
if [ \! -z "$file_to_fix" ]; then
echo Checking $file_to_fix
sed -e 's/Format\[\]/Format\[1\]/' $file_to_fix > /tmp/$base
if cmp $file_to_fix /tmp/$base >NUL 2>&1; then \
true
else
echo Fixed $file_to_fix
rm -f ${LIB}/$file
cp /tmp/$base ${LIB}/$file
chmod a+r ${LIB}/$file
fi
rm -f /tmp/$base
fi
file=winnt.h
base=`basename $file`
if [ -r ${LIB}/$file ]; then
file_to_fix=${LIB}/$file
else
if [ -r ${INPUT}/$file ]; then
file_to_fix=${INPUT}/$file
else
file_to_fix=""
fi
fi
if [ \! -z "$file_to_fix" ]; then
echo Checking $file_to_fix
sed -e '
s/^#if !defined (__cplusplus)/#if 0/
s/^#define DECLSPEC_IMPORT __declspec(dllimport)/#define DECLSPEC_IMPORT/
' $file_to_fix > /tmp/$base
if cmp $file_to_fix /tmp/$base >NUL 2>&1; then \
true
else
echo Fixed $file_to_fix
rm -f ${LIB}/$file
cp /tmp/$base ${LIB}/$file
chmod a+r ${LIB}/$file
fi
rm -f /tmp/$base
fi
echo 'Removing unneeded directories:'
cd $LIB
files=`find . -type d -print | sort -r`
for file in $files; do
rmdir $LIB/$file > NUL 2>&1
done
exit 0

View file

@ -1,238 +0,0 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

View file

@ -1,31 +0,0 @@
/* Bytecode specific machine mode info for GNU C-compiler.
Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Map mode to signed, unsigned typecodes, bytecode to push const,
to load, to store */
DEF_MODEMAP(QImode, QIcode, QUcode, constQI, loadQI, storeQI)
DEF_MODEMAP(HImode, HIcode, HUcode, constHI, loadHI, storeHI)
DEF_MODEMAP(VOIDmode, SIcode, SUcode, constSI, loadSI, storeSI)
DEF_MODEMAP(SImode, SIcode, SUcode, constSI, loadSI, storeSI)
DEF_MODEMAP(DImode, DIcode, DUcode, constDI, loadDI, storeDI)
DEF_MODEMAP(PSImode, Pcode, Pcode, constP, loadP, storeP)
DEF_MODEMAP(BLKmode, Pcode, Pcode, constP, loadP, neverneverland)
DEF_MODEMAP(SFmode, SFcode, SFcode, constSF, loadSF, storeSF)
DEF_MODEMAP(DFmode, DFcode, DFcode, constDF, loadDF, storeDF)

File diff suppressed because it is too large Load diff

View file

@ -1,117 +0,0 @@
/* Declarations for objc-act.c.
Copyright (C) 1990 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/*** Public Interface (procedures) ***/
/* used by yyparse */
void finish_file PROTO((void));
tree start_class PROTO((enum tree_code, tree, tree, tree));
tree continue_class PROTO((tree));
void finish_class PROTO((tree));
void start_method_def PROTO((tree));
void continue_method_def PROTO((void));
void finish_method_def PROTO((void));
tree start_protocol PROTO((enum tree_code, tree, tree));
void finish_protocol PROTO((tree));
void add_objc_decls PROTO((void));
tree is_ivar PROTO((tree, tree));
int is_private PROTO((tree));
int is_public PROTO((tree, tree));
tree add_instance_variable PROTO((tree, int, tree, tree, tree));
tree add_class_method PROTO((tree, tree));
tree add_instance_method PROTO((tree, tree));
tree get_super_receiver PROTO((void));
tree get_class_ivars PROTO((tree));
tree get_class_reference PROTO((tree));
tree get_static_reference PROTO((tree, tree));
tree get_object_reference PROTO((tree));
tree build_message_expr PROTO((tree));
tree build_selector_expr PROTO((tree));
tree build_ivar_reference PROTO((tree));
tree build_keyword_decl PROTO((tree, tree, tree));
tree build_method_decl PROTO((enum tree_code, tree, tree, tree));
tree build_protocol_expr PROTO((tree));
tree build_objc_string_object PROTO((tree));
extern tree objc_ivar_chain;
extern tree objc_method_context;
void objc_declare_alias PROTO((tree, tree));
void objc_declare_class PROTO((tree));
extern int objc_receiver_context;
/* the following routines are used to implement statically typed objects */
int objc_comptypes PROTO((tree, tree, int));
void objc_check_decl PROTO((tree));
/* NeXT extensions */
tree build_encode_expr PROTO((tree));
/* Objective-C structures */
/* KEYWORD_DECL */
#define KEYWORD_KEY_NAME(DECL) ((DECL)->decl.name)
#define KEYWORD_ARG_NAME(DECL) ((DECL)->decl.arguments)
/* INSTANCE_METHOD_DECL, CLASS_METHOD_DECL */
#define METHOD_SEL_NAME(DECL) ((DECL)->decl.name)
#define METHOD_SEL_ARGS(DECL) ((DECL)->decl.arguments)
#define METHOD_ADD_ARGS(DECL) ((DECL)->decl.result)
#define METHOD_DEFINITION(DECL) ((DECL)->decl.initial)
#define METHOD_ENCODING(DECL) ((DECL)->decl.context)
/* CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
CATEGORY_INTERFACE_TYPE, CATEGORY_IMPLEMENTATION_TYPE,
PROTOCOL_INTERFACE_TYPE */
#define CLASS_NAME(CLASS) ((CLASS)->type.name)
#define CLASS_SUPER_NAME(CLASS) ((CLASS)->type.context)
#define CLASS_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 0)
#define CLASS_RAW_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1)
#define CLASS_NST_METHODS(CLASS) ((CLASS)->type.minval)
#define CLASS_CLS_METHODS(CLASS) ((CLASS)->type.maxval)
#define CLASS_STATIC_TEMPLATE(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 2)
#define CLASS_CATEGORY_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 3)
#define CLASS_PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 4)
#define PROTOCOL_NAME(CLASS) ((CLASS)->type.name)
#define PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 0)
#define PROTOCOL_NST_METHODS(CLASS) ((CLASS)->type.minval)
#define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval)
#define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1)
#define TYPE_PROTOCOL_LIST(TYPE) ((TYPE)->type.context)
/* Define the Objective-C or Objective-C++ language-specific tree codes. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
enum objc_tree_code {
#ifdef OBJCPLUS
dummy_tree_code = LAST_CPLUS_TREE_CODE,
#else
dummy_tree_code = LAST_AND_UNUSED_TREE_CODE,
#endif
#include "objc-tree.def"
LAST_OBJC_TREE_CODE
};
#undef DEFTREECODE

View file

@ -1,37 +0,0 @@
/* This file contains the definitions and documentation for the
additional tree codes used in the Objective C front end (see tree.def
for the standard codes).
Copyright (C) 1990 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Objective-C types. */
DEFTREECODE (CLASS_INTERFACE_TYPE, "class_interface_type", "t", 0)
DEFTREECODE (CLASS_IMPLEMENTATION_TYPE, "class_implementation_type", "t", 0)
DEFTREECODE (CATEGORY_INTERFACE_TYPE, "category_interface_type", "t", 0)
DEFTREECODE (CATEGORY_IMPLEMENTATION_TYPE,"category_implementation_type","t",0)
DEFTREECODE (PROTOCOL_INTERFACE_TYPE, "protocol_interface_type", "t", 0)
/* Objective-C decls. */
DEFTREECODE (KEYWORD_DECL, "keyword_decl", "d", 0)
DEFTREECODE (INSTANCE_METHOD_DECL, "instance_method_decl", "d", 0)
DEFTREECODE (CLASS_METHOD_DECL, "class_method_decl", "d", 0)
/* Objective-C constants. */
DEFTREECODE (OBJC_STRING_CST, "objc_string_cst", "c", 3)

View file

@ -1,100 +0,0 @@
# GNU Objective C Runtime Makefile
# Copyright (C) 1993, 1995 Free Software Foundation, Inc.
#
# This file is part of GNU CC.
#
# GNU CC is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2, or (at your option) any later version.
#
# GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# GNU CC; see the file COPYING. If not, write to the Free Software
# Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# This makefile is run by the parent dir's makefile.
# thisdir1=`pwd`; \
# srcdir1=`cd $(srcdir); pwd`; \
# cd objc; \
# $(MAKE) $(MAKEFLAGS) -f $$srcdir1/objc/Makefile libobjc.a \
# srcdir=$$srcdir1 tooldir=$(tooldir) AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" \
# GCC_FOR_TARGET="$$thisdir1/xgcc -B$$thisdir1/" \
# GCC_CFLAGS="$(GCC_CFLAGS)" incinstalldir=$$thisdir1/include
# Two targets are used by ../Makefile: `all' and `mostlyclean'.
SHELL=/bin/sh
.SUFFIXES: .m
OPTIMIZE= -O
VPATH = $(srcdir)/objc
AR = ar
AR_FLAGS = rc
# Always search these dirs when compiling.
SUBDIR_INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/config
.c.o:
$(GCC_FOR_TARGET) $(OPTIMIZE) \
-c $(GCC_CFLAGS) $(SUBDIR_INCLUDES) $<
.m.o:
$(GCC_FOR_TARGET) $(OPTIMIZE) -fgnu-runtime \
-c $(GCC_CFLAGS) $(SUBDIR_INCLUDES) $<
# If we were not invoked from the parent dir,
# invoke make in the parent dir and have reinvoke this makefile.
# That's necessary to get the right values for srcdir, etc.
all:
cd ..; $(MAKE) sublibobjc.a
OBJC_O = hash.o sarray.o class.o sendmsg.o init.o archive.o encoding.o \
selector.o objects.o misc.o NXConstStr.o Object.o Protocol.o
libobjc.a: $(OBJC_O)
-rm -f libobjc.a
$(AR) rc libobjc.a $?
# ranlib is run in the parent directory's makefile.
OBJC_H = hash.h list.h sarray.h objc.h \
objc-api.h \
NXConstStr.h Object.h Protocol.h encoding.h typedstream.h
# copy objc headers to installation include directory
copy-headers:
-rm -fr $(incinstalldir)/objc
-mkdir $(incinstalldir)/objc
for file in $(OBJC_H); do \
realfile=$(srcdir)/objc/$${file}; \
cp $${realfile} $(incinstalldir)/objc; \
chmod a+r $(incinstalldir)/objc/$${file}; \
done
mostlyclean:
-rm -f *.o libobjc.a xforward fflags
clean: mostlyclean
distclean: mostlyclean
extraclean: mostlyclean
# For Sun VPATH.
hash.o: hash.c
sarray.o: sarray.c
class.o: class.c
sendmsg.o: sendmsg.c
init.o: init.c
archive.o: archive.c
encoding.o: encoding.c
selector.o: selector.c
objects.o: objects.c
misc.o: misc.c
NXConstStr.o: NXConstStr.m
Object.o: Object.m
Protocol.o: Protocol.m

View file

@ -1,44 +0,0 @@
/* Interface for the NXConstantString class for Objective-C.
Copyright (C) 1995 Free Software Foundation, Inc.
Contributed by Pieter J. Schoenmakers <tiggr@es.ele.tue.nl>
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#ifndef __nxconstantstring_INCLUDE_GNU
#define __nxconstantstring_INCLUDE_GNU
#include "objc/Object.h"
@interface NXConstantString: Object
{
char *c_string;
unsigned int len;
}
-(const char *) cString;
-(unsigned int) length;
@end
#endif

View file

@ -1,42 +0,0 @@
/* Implementation of the NXConstantString class for Objective-C.
Copyright (C) 1995 Free Software Foundation, Inc.
Contributed by Pieter J. Schoenmakers <tiggr@es.ele.tue.nl>
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#include "objc/NXConstStr.h"
@implementation NXConstantString
-(const char *) cString
{
return (c_string);
} /* -cString */
-(unsigned int) length
{
return (len);
} /* -length */
@end

View file

@ -1,124 +0,0 @@
/* Interface for the Object class for Objective-C.
Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled
with GCC to produce an executable, this does not cause the resulting
executable to be covered by the GNU General Public License. This
exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License. */
#ifndef __object_INCLUDE_GNU
#define __object_INCLUDE_GNU
#include <objc/objc.h>
#include <objc/typedstream.h>
/*
* All classes are derived from Object. As such,
* this is the overhead tacked onto those objects.
*/
@interface Object
{
Class isa; /* A pointer to the instance's class structure */
}
/* Initializing classes and instances */
+ initialize;
- init;
/* Creating, freeing, and copying instances */
+ new;
+ alloc;
- free;
- copy;
- shallowCopy;
- deepen;
- deepCopy;
/* Identifying classes */
- (Class)class;
- (Class)superClass;
- (MetaClass)metaClass;
- (const char *)name;
/* Identifying and comparing objects */
- self;
- (unsigned int)hash;
- (BOOL)isEqual:anObject;
- (int)compare:anotherObject;
/* Testing object type */
- (BOOL)isMetaClass;
- (BOOL)isClass;
- (BOOL)isInstance;
/* Testing inheritance relationships */
- (BOOL)isKindOf:(Class)aClassObject;
- (BOOL)isMemberOf:(Class)aClassObject;
- (BOOL)isKindOfClassNamed:(const char *)aClassName;
- (BOOL)isMemberOfClassNamed:(const char *)aClassName;
/* Testing class functionality */
+ (BOOL)instancesRespondTo:(SEL)aSel;
- (BOOL)respondsTo:(SEL)aSel;
/* Testing protocol conformance */
- (BOOL)conformsTo:(Protocol*)aProtocol;
/* Introspection */
+ (IMP)instanceMethodFor:(SEL)aSel;
- (IMP)methodFor:(SEL)aSel;
+ (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel;
- (struct objc_method_description *)descriptionForMethod:(SEL)aSel;
/* Sending messages determined at run time */
- perform:(SEL)aSel;
- perform:(SEL)aSel with:anObject;
- perform:(SEL)aSel with:anObject1 with:anObject2;
/* Forwarding */
- (retval_t)forward:(SEL)aSel :(arglist_t)argFrame;
- (retval_t)performv:(SEL)aSel :(arglist_t)argFrame;
/* Posing */
+ poseAs:(Class)aClassObject;
- (Class)transmuteClassTo:(Class)aClassObject;
/* Enforcing intentions */
- subclassResponsibility:(SEL)aSel;
- notImplemented:(SEL)aSel;
- shouldNotImplement:(SEL)aSel;
/* Error handling */
- doesNotRecognize:(SEL)aSel;
- error:(const char *)aString, ...;
/* Archiving */
+ (int)version;
+ setVersion:(int)aVersion;
+ (int)streamVersion: (TypedStream*)aStream;
- read: (TypedStream*)aStream;
- write: (TypedStream*)aStream;
- awake;
@end
#endif

View file

@ -1,387 +0,0 @@
/* The implementation of class Object for Objective-C.
Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled
with GCC to produce an executable, this does not cause the resulting
executable to be covered by the GNU General Public License. This
exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License. */
#include <stdarg.h>
#include "objc/Object.h"
#include "objc/Protocol.h"
#include "objc/objc-api.h"
extern int errno;
#define MAX_CLASS_NAME_LEN 256
@implementation Object
+ initialize
{
return self;
}
- init
{
return self;
}
+ new
{
return [[self alloc] init];
}
+ alloc
{
return class_create_instance(self);
}
- free
{
return object_dispose(self);
}
- copy
{
return [[self shallowCopy] deepen];
}
- shallowCopy
{
return object_copy(self);
}
- deepen
{
return self;
}
- deepCopy
{
return [self copy];
}
- (Class)class
{
return object_get_class(self);
}
- (Class)superClass
{
return object_get_super_class(self);
}
- (MetaClass)metaClass
{
return object_get_meta_class(self);
}
- (const char *)name
{
return object_get_class_name(self);
}
- self
{
return self;
}
- (unsigned int)hash
{
return (size_t)self;
}
- (BOOL)isEqual:anObject
{
return self==anObject;
}
- (int)compare:anotherObject;
{
if ([self isEqual:anotherObject])
return 0;
// Ordering objects by their address is pretty useless,
// so subclasses should override this is some useful way.
else if (self > anotherObject)
return 1;
else
return -1;
}
- (BOOL)isMetaClass
{
return NO;
}
- (BOOL)isClass
{
return object_is_class(self);
}
- (BOOL)isInstance
{
return object_is_instance(self);
}
- (BOOL)isKindOf:(Class)aClassObject
{
Class class;
for (class = self->isa; class!=Nil; class = class_get_super_class(class))
if (class==aClassObject)
return YES;
return NO;
}
- (BOOL)isMemberOf:(Class)aClassObject
{
return self->isa==aClassObject;
}
- (BOOL)isKindOfClassNamed:(const char *)aClassName
{
Class class;
if (aClassName!=NULL)
for (class = self->isa; class!=Nil; class = class_get_super_class(class))
if (!strcmp(class_get_class_name(class), aClassName))
return YES;
return NO;
}
- (BOOL)isMemberOfClassNamed:(const char *)aClassName
{
return ((aClassName!=NULL)
&&!strcmp(class_get_class_name(self->isa), aClassName));
}
+ (BOOL)instancesRespondTo:(SEL)aSel
{
return class_get_instance_method(self, aSel)!=METHOD_NULL;
}
- (BOOL)respondsTo:(SEL)aSel
{
return ((object_is_instance(self)
?class_get_instance_method(self->isa, aSel)
:class_get_class_method(self->isa, aSel))!=METHOD_NULL);
}
+ (IMP)instanceMethodFor:(SEL)aSel
{
return method_get_imp(class_get_instance_method(self, aSel));
}
// Indicates if the receiving class or instance conforms to the given protocol
// not usually overridden by subclasses
//
// Modified 9/5/94 to always search the class object's protocol list, rather
// than the meta class.
+ (BOOL) conformsTo: (Protocol*)aProtocol
{
int i;
struct objc_protocol_list* proto_list;
id parent;
for (proto_list = ((Class)self)->protocols;
proto_list; proto_list = proto_list->next)
{
for (i=0; i < proto_list->count; i++)
{
if ([proto_list->list[i] conformsTo: aProtocol])
return YES;
}
}
if ((parent = [self superClass]))
return [parent conformsTo: aProtocol];
else
return NO;
}
- (BOOL) conformsTo: (Protocol*)aProtocol
{
return [[self class] conformsTo:aProtocol];
}
- (IMP)methodFor:(SEL)aSel
{
return (method_get_imp(object_is_instance(self)
?class_get_instance_method(self->isa, aSel)
:class_get_class_method(self->isa, aSel)));
}
+ (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
{
return ((struct objc_method_description *)
class_get_instance_method(self, aSel));
}
- (struct objc_method_description *)descriptionForMethod:(SEL)aSel
{
return ((struct objc_method_description *)
(object_is_instance(self)
?class_get_instance_method(self->isa, aSel)
:class_get_class_method(self->isa, aSel)));
}
- perform:(SEL)aSel
{
IMP msg = objc_msg_lookup(self, aSel);
if (!msg)
return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
return (*msg)(self, aSel);
}
- perform:(SEL)aSel with:anObject
{
IMP msg = objc_msg_lookup(self, aSel);
if (!msg)
return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
return (*msg)(self, aSel, anObject);
}
- perform:(SEL)aSel with:anObject1 with:anObject2
{
IMP msg = objc_msg_lookup(self, aSel);
if (!msg)
return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
return (*msg)(self, aSel, anObject1, anObject2);
}
- (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
{
return (retval_t)[self doesNotRecognize: aSel];
}
- (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
{
return objc_msg_sendv(self, aSel, argFrame);
}
+ poseAs:(Class)aClassObject
{
return class_pose_as(self, aClassObject);
}
- (Class)transmuteClassTo:(Class)aClassObject
{
if (object_is_instance(self))
if (class_is_class(aClassObject))
if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
if ([self isKindOf:aClassObject])
{
Class old_isa = isa;
isa = aClassObject;
return old_isa;
}
return nil;
}
- subclassResponsibility:(SEL)aSel
{
return [self error:"subclass should override %s", sel_get_name(aSel)];
}
- notImplemented:(SEL)aSel
{
return [self error:"method %s not implemented", sel_get_name(aSel)];
}
- shouldNotImplement:(SEL)aSel
{
return [self error:"%s should not implement %s",
object_get_class_name(self), sel_get_name(aSel)];
}
- doesNotRecognize:(SEL)aSel
{
return [self error:"%s does not recognize %s",
object_get_class_name(self), sel_get_name(aSel)];
}
#ifdef __alpha__
extern size_t strlen(const char*);
#endif
- error:(const char *)aString, ...
{
#define FMT "error: %s (%s)\n%s\n"
char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self))
+((aString!=NULL)?strlen((char*)aString):0)+8)];
va_list ap;
sprintf(fmt, FMT, object_get_class_name(self),
object_is_instance(self)?"instance":"class",
(aString!=NULL)?aString:"");
va_start(ap, aString);
objc_verror(self, OBJC_ERR_UNKNOWN, fmt, ap);
va_end(ap);
return nil;
#undef FMT
}
+ (int)version
{
return class_get_version(self);
}
+ setVersion:(int)aVersion
{
class_set_version(self, aVersion);
return self;
}
+ (int)streamVersion: (TypedStream*)aStream
{
if (aStream->mode == OBJC_READONLY)
return objc_get_stream_class_version (aStream, self);
else
return class_get_version (self);
}
// These are used to write or read the instance variables
// declared in this particular part of the object. Subclasses
// should extend these, by calling [super read/write: aStream]
// before doing their own archiving. These methods are private, in
// the sense that they should only be called from subclasses.
- read: (TypedStream*)aStream
{
// [super read: aStream];
return self;
}
- write: (TypedStream*)aStream
{
// [super write: aStream];
return self;
}
- awake
{
// [super awake];
return self;
}
@end

View file

@ -1,58 +0,0 @@
/* Declare the class Protocol for Objective C programs.
Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#ifndef __Protocol_INCLUDE_GNU
#define __Protocol_INCLUDE_GNU
#include "objc/Object.h"
@interface Protocol : Object
{
@private
char *protocol_name;
struct objc_protocol_list *protocol_list;
struct objc_method_description_list *instance_methods, *class_methods;
}
/* Obtaining attributes intrinsic to the protocol */
- (const char *)name;
/* Testing protocol conformance */
- (BOOL) conformsTo: (Protocol *)aProtocolObject;
/* Looking up information specific to a protocol */
- (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel;
- (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel;
@end
#endif __Protocol_INCLUDE_GNU

View file

@ -1,128 +0,0 @@
/* This file contains the implementation of class Protocol.
Copyright (C) 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#include "objc/Protocol.h"
#include "objc/objc-api.h"
/* Method description list */
struct objc_method_description_list {
int count;
struct objc_method_description list[1];
};
@implementation Protocol
{
@private
char *protocol_name;
struct objc_protocol_list *protocol_list;
struct objc_method_description_list *instance_methods, *class_methods;
}
/* Obtaining attributes intrinsic to the protocol */
- (const char *)name
{
return protocol_name;
}
/* Testing protocol conformance */
- (BOOL) conformsTo: (Protocol *)aProtocolObject
{
int i;
struct objc_protocol_list* proto_list;
if (!strcmp(aProtocolObject->protocol_name, self->protocol_name))
return YES;
for (proto_list = protocol_list; proto_list; proto_list = proto_list->next)
{
for (i=0; i < proto_list->count; i++)
{
if ([proto_list->list[i] conformsTo: aProtocolObject])
return YES;
}
}
return NO;
}
/* Looking up information specific to a protocol */
- (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel
{
int i;
struct objc_protocol_list* proto_list;
const char* name = sel_get_name (aSel);
struct objc_method_description *result;
for (i = 0; i < instance_methods->count; i++)
{
if (!strcmp ((char*)instance_methods->list[i].name, name))
return &(instance_methods->list[i]);
}
for (proto_list = protocol_list; proto_list; proto_list = proto_list->next)
{
for (i=0; i < proto_list->count; i++)
{
if ((result = [proto_list->list[i]
descriptionForInstanceMethod: aSel]))
return result;
}
}
return NULL;
}
- (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel;
{
int i;
struct objc_protocol_list* proto_list;
const char* name = sel_get_name (aSel);
struct objc_method_description *result;
for (i = 0; i < class_methods->count; i++)
{
if (!strcmp ((char*)class_methods->list[i].name, name))
return &(class_methods->list[i]);
}
for (proto_list = protocol_list; proto_list; proto_list = proto_list->next)
{
for (i=0; i < proto_list->count; i++)
{
if ((result = [proto_list->list[i]
descriptionForClassMethod: aSel]))
return result;
}
}
return NULL;
}
@end

File diff suppressed because it is too large Load diff

View file

@ -1,358 +0,0 @@
/* GNU Objective C Runtime class related functions
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup and Dennis Glatting.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2, or (at your option) any later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
GNU CC; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled with
GCC to produce an executable, this does not cause the resulting executable
to be covered by the GNU General Public License. This exception does not
however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */
#include "runtime.h" /* the kitchen sink */
#include "sarray.h"
/* The table of classname->class. Used for objc_lookup_class and friends */
static cache_ptr __objc_class_hash = 0; /* !T:MUTEX */
/* This is a hook which is called by objc_get_class and
objc_lookup_class if the runtime is not able to find the class.
This may e.g. try to load in the class using dynamic loading */
Class (*_objc_lookup_class)(const char* name) = 0; /* !T:SAFE */
/* True when class links has been resolved */
BOOL __objc_class_links_resolved = NO; /* !T:UNUSED */
/* Initial number of buckets size of class hash table. */
#define CLASS_HASH_SIZE 32
void __objc_init_class_tables()
{
/* Allocate the class hash table */
if(__objc_class_hash)
return;
objc_mutex_lock(__objc_runtime_mutex);
__objc_class_hash
= hash_new (CLASS_HASH_SIZE,
(hash_func_type) hash_string,
(compare_func_type) compare_strings);
objc_mutex_unlock(__objc_runtime_mutex);
}
/* This function adds a class to the class hash table, and assigns the
class a number, unless it's already known */
void
__objc_add_class_to_hash(Class class)
{
Class h_class;
objc_mutex_lock(__objc_runtime_mutex);
/* make sure the table is there */
assert(__objc_class_hash);
/* make sure it's not a meta class */
assert(CLS_ISCLASS(class));
/* Check to see if the class is already in the hash table. */
h_class = hash_value_for_key (__objc_class_hash, class->name);
if (!h_class)
{
/* The class isn't in the hash table. Add the class and assign a class
number. */
static unsigned int class_number = 1;
CLS_SETNUMBER(class, class_number);
CLS_SETNUMBER(class->class_pointer, class_number);
++class_number;
hash_add (&__objc_class_hash, class->name, class);
}
objc_mutex_unlock(__objc_runtime_mutex);
}
/* Get the class object for the class named NAME. If NAME does not
identify a known class, the hook _objc_lookup_class is called. If
this fails, nil is returned */
Class objc_lookup_class (const char* name)
{
Class class;
objc_mutex_lock(__objc_runtime_mutex);
/* Make sure the class hash table exists. */
assert (__objc_class_hash);
class = hash_value_for_key (__objc_class_hash, name);
objc_mutex_unlock(__objc_runtime_mutex);
if (class)
return class;
if (_objc_lookup_class)
return (*_objc_lookup_class)(name);
else
return 0;
}
/* Get the class object for the class named NAME. If NAME does not
identify a known class, the hook _objc_lookup_class is called. If
this fails, an error message is issued and the system aborts */
Class
objc_get_class (const char *name)
{
Class class;
objc_mutex_lock(__objc_runtime_mutex);
/* Make sure the class hash table exists. */
assert (__objc_class_hash);
class = hash_value_for_key (__objc_class_hash, name);
objc_mutex_unlock(__objc_runtime_mutex);
if (class)
return class;
if (_objc_lookup_class)
class = (*_objc_lookup_class)(name);
if(class)
return class;
objc_error(nil, OBJC_ERR_BAD_CLASS,
"objc runtime: cannot find class %s\n", name);
return 0;
}
MetaClass
objc_get_meta_class(const char *name)
{
return objc_get_class(name)->class_pointer;
}
/* This function provides a way to enumerate all the classes in the
executable. Pass *ENUM_STATE == NULL to start the enumeration. The
function will return 0 when there are no more classes.
For example:
id class;
void *es = NULL;
while ((class = objc_next_class(&es)))
... do something with class;
*/
Class
objc_next_class(void **enum_state)
{
objc_mutex_lock(__objc_runtime_mutex);
/* make sure the table is there */
assert(__objc_class_hash);
*(node_ptr*)enum_state =
hash_next(__objc_class_hash, *(node_ptr*)enum_state);
objc_mutex_unlock(__objc_runtime_mutex);
if (*(node_ptr*)enum_state)
return (*(node_ptr*)enum_state)->value;
return (Class)0;
}
/* Resolve super/subclass links for all classes. The only thing we
can be sure of is that the class_pointer for class objects point
to the right meta class objects */
void __objc_resolve_class_links()
{
node_ptr node;
Class object_class = objc_get_class ("Object");
assert(object_class);
objc_mutex_lock(__objc_runtime_mutex);
/* Assign subclass links */
for (node = hash_next (__objc_class_hash, NULL); node;
node = hash_next (__objc_class_hash, node))
{
Class class1 = node->value;
/* Make sure we have what we think we have. */
assert (CLS_ISCLASS(class1));
assert (CLS_ISMETA(class1->class_pointer));
/* The class_pointer of all meta classes point to Object's meta class. */
class1->class_pointer->class_pointer = object_class->class_pointer;
if (!(CLS_ISRESOLV(class1)))
{
CLS_SETRESOLV(class1);
CLS_SETRESOLV(class1->class_pointer);
if(class1->super_class)
{
Class a_super_class
= objc_get_class ((char *) class1->super_class);
assert (a_super_class);
DEBUG_PRINTF ("making class connections for: %s\n",
class1->name);
/* assign subclass links for superclass */
class1->sibling_class = a_super_class->subclass_list;
a_super_class->subclass_list = class1;
/* Assign subclass links for meta class of superclass */
if (a_super_class->class_pointer)
{
class1->class_pointer->sibling_class
= a_super_class->class_pointer->subclass_list;
a_super_class->class_pointer->subclass_list
= class1->class_pointer;
}
}
else /* a root class, make its meta object */
/* be a subclass of Object */
{
class1->class_pointer->sibling_class
= object_class->subclass_list;
object_class->subclass_list = class1->class_pointer;
}
}
}
/* Assign superclass links */
for (node = hash_next (__objc_class_hash, NULL); node;
node = hash_next (__objc_class_hash, node))
{
Class class1 = node->value;
Class sub_class;
for (sub_class = class1->subclass_list; sub_class;
sub_class = sub_class->sibling_class)
{
sub_class->super_class = class1;
if(CLS_ISCLASS(sub_class))
sub_class->class_pointer->super_class = class1->class_pointer;
}
}
objc_mutex_unlock(__objc_runtime_mutex);
}
#define CLASSOF(c) ((c)->class_pointer)
Class
class_pose_as (Class impostor, Class super_class)
{
node_ptr node;
Class class1;
if (!CLS_ISRESOLV (impostor))
__objc_resolve_class_links ();
/* preconditions */
assert (impostor);
assert (super_class);
assert (impostor->super_class == super_class);
assert (CLS_ISCLASS (impostor));
assert (CLS_ISCLASS (super_class));
assert (impostor->instance_size == super_class->instance_size);
{
Class *subclass = &(super_class->subclass_list);
/* move subclasses of super_class to impostor */
while (*subclass)
{
Class nextSub = (*subclass)->sibling_class;
if (*subclass != impostor)
{
Class sub = *subclass;
/* classes */
sub->sibling_class = impostor->subclass_list;
sub->super_class = impostor;
impostor->subclass_list = sub;
/* It will happen that SUB is not a class object if it is
the top of the meta class hierarchy chain. (root
meta-class objects inherit their class object) If that is
the case... don't mess with the meta-meta class. */
if (CLS_ISCLASS (sub))
{
/* meta classes */
CLASSOF (sub)->sibling_class =
CLASSOF (impostor)->subclass_list;
CLASSOF (sub)->super_class = CLASSOF (impostor);
CLASSOF (impostor)->subclass_list = CLASSOF (sub);
}
}
*subclass = nextSub;
}
/* set subclasses of superclass to be impostor only */
super_class->subclass_list = impostor;
CLASSOF (super_class)->subclass_list = CLASSOF (impostor);
/* set impostor to have no sibling classes */
impostor->sibling_class = 0;
CLASSOF (impostor)->sibling_class = 0;
}
/* check relationship of impostor and super_class is kept. */
assert (impostor->super_class == super_class);
assert (CLASSOF (impostor)->super_class == CLASSOF (super_class));
/* This is how to update the lookup table. Regardless of
what the keys of the hashtable is, change all values that are
superclass into impostor. */
objc_mutex_lock(__objc_runtime_mutex);
for (node = hash_next (__objc_class_hash, NULL); node;
node = hash_next (__objc_class_hash, node))
{
class1 = (Class)node->value;
if (class1 == super_class)
{
node->value = impostor; /* change hash table value */
}
}
objc_mutex_unlock(__objc_runtime_mutex);
/* next, we update the dispatch tables... */
__objc_update_dispatch_table_for_class (CLASSOF (impostor));
__objc_update_dispatch_table_for_class (impostor);
return impostor;
}

View file

@ -1,554 +0,0 @@
/* Encoding of types for Objective C.
Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#include "encoding.h"
#define MAX(X, Y) \
({ typeof(X) __x = (X), __y = (Y); \
(__x > __y ? __x : __y); })
#define MIN(X, Y) \
({ typeof(X) __x = (X), __y = (Y); \
(__x < __y ? __x : __y); })
#define ROUND(V, A) \
({ typeof(V) __v=(V); typeof(A) __a=(A); \
__a*((__v+__a-1)/__a); })
static inline int
atoi (const char* str)
{
int res = 0;
while (isdigit (*str))
res *= 10, res += (*str++ - '0');
return res;
}
/*
return the size of an object specified by type
*/
int
objc_sizeof_type(const char* type)
{
switch(*type) {
case _C_ID:
return sizeof(id);
break;
case _C_CLASS:
return sizeof(Class);
break;
case _C_SEL:
return sizeof(SEL);
break;
case _C_CHR:
return sizeof(char);
break;
case _C_UCHR:
return sizeof(unsigned char);
break;
case _C_SHT:
return sizeof(short);
break;
case _C_USHT:
return sizeof(unsigned short);
break;
case _C_INT:
return sizeof(int);
break;
case _C_UINT:
return sizeof(unsigned int);
break;
case _C_LNG:
return sizeof(long);
break;
case _C_ULNG:
return sizeof(unsigned long);
break;
case _C_FLT:
return sizeof(float);
break;
case _C_DBL:
return sizeof(double);
break;
case _C_VOID:
return sizeof(void);
break;
case _C_PTR:
case _C_ATOM:
case _C_CHARPTR:
return sizeof(char*);
break;
case _C_ARY_B:
{
int len = atoi(type+1);
while (isdigit(*++type));
return len*objc_aligned_size (type);
}
break;
case _C_STRUCT_B:
{
int acc_size = 0;
int align;
while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
while (*type != _C_STRUCT_E)
{
align = objc_alignof_type (type); /* padd to alignment */
acc_size = ROUND (acc_size, align);
acc_size += objc_sizeof_type (type); /* add component size */
type = objc_skip_typespec (type); /* skip component */
}
return acc_size;
}
case _C_UNION_B:
{
int max_size = 0;
while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
while (*type != _C_UNION_E)
{
max_size = MAX (max_size, objc_sizeof_type (type));
type = objc_skip_typespec (type);
}
return max_size;
}
default:
{
objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
return 0;
}
}
}
/*
Return the alignment of an object specified by type
*/
int
objc_alignof_type(const char* type)
{
switch(*type) {
case _C_ID:
return __alignof__(id);
break;
case _C_CLASS:
return __alignof__(Class);
break;
case _C_SEL:
return __alignof__(SEL);
break;
case _C_CHR:
return __alignof__(char);
break;
case _C_UCHR:
return __alignof__(unsigned char);
break;
case _C_SHT:
return __alignof__(short);
break;
case _C_USHT:
return __alignof__(unsigned short);
break;
case _C_INT:
return __alignof__(int);
break;
case _C_UINT:
return __alignof__(unsigned int);
break;
case _C_LNG:
return __alignof__(long);
break;
case _C_ULNG:
return __alignof__(unsigned long);
break;
case _C_FLT:
return __alignof__(float);
break;
case _C_DBL:
return __alignof__(double);
break;
case _C_PTR:
case _C_ATOM:
case _C_CHARPTR:
return __alignof__(char*);
break;
case _C_ARY_B:
while (isdigit(*++type)) /* do nothing */;
return objc_alignof_type (type);
case _C_STRUCT_B:
{
struct { int x; double y; } fooalign;
while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */;
if (*type != _C_STRUCT_E)
return MAX (objc_alignof_type (type), __alignof__ (fooalign));
else
return __alignof__ (fooalign);
}
case _C_UNION_B:
{
int maxalign = 0;
while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
while (*type != _C_UNION_E)
{
maxalign = MAX (maxalign, objc_alignof_type (type));
type = objc_skip_typespec (type);
}
return maxalign;
}
default:
{
objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
return 0;
}
}
}
/*
The aligned size if the size rounded up to the nearest alignment.
*/
int
objc_aligned_size (const char* type)
{
int size = objc_sizeof_type (type);
int align = objc_alignof_type (type);
return ROUND (size, align);
}
/*
The size rounded up to the nearest integral of the wordsize, taken
to be the size of a void*.
*/
int
objc_promoted_size (const char* type)
{
int size = objc_sizeof_type (type);
int wordsize = sizeof (void*);
return ROUND (size, wordsize);
}
/*
Skip type qualifiers. These may eventually precede typespecs
occurring in method prototype encodings.
*/
inline const char*
objc_skip_type_qualifiers (const char* type)
{
while (*type == _C_CONST
|| *type == _C_IN
|| *type == _C_INOUT
|| *type == _C_OUT
|| *type == _C_BYCOPY
|| *type == _C_ONEWAY)
{
type += 1;
}
return type;
}
/*
Skip one typespec element. If the typespec is prepended by type
qualifiers, these are skipped as well.
*/
const char*
objc_skip_typespec (const char* type)
{
type = objc_skip_type_qualifiers (type);
switch (*type) {
case _C_ID:
/* An id may be annotated by the actual type if it is known
with the @"ClassName" syntax */
if (*++type != '"')
return type;
else
{
while (*++type != '"') /* do nothing */;
return type + 1;
}
/* The following are one character type codes */
case _C_CLASS:
case _C_SEL:
case _C_CHR:
case _C_UCHR:
case _C_CHARPTR:
case _C_ATOM:
case _C_SHT:
case _C_USHT:
case _C_INT:
case _C_UINT:
case _C_LNG:
case _C_ULNG:
case _C_FLT:
case _C_DBL:
case _C_VOID:
case _C_UNDEF:
return ++type;
break;
case _C_ARY_B:
/* skip digits, typespec and closing ']' */
while(isdigit(*++type));
type = objc_skip_typespec(type);
if (*type == _C_ARY_E)
return ++type;
else
{
objc_error(nil, OBJC_ERR_BAD_TYPE, "bad array type %s\n", type);
return 0;
}
case _C_STRUCT_B:
/* skip name, and elements until closing '}' */
while (*type != _C_STRUCT_E && *type++ != '=');
while (*type != _C_STRUCT_E) { type = objc_skip_typespec (type); }
return ++type;
case _C_UNION_B:
/* skip name, and elements until closing ')' */
while (*type != _C_UNION_E && *type++ != '=');
while (*type != _C_UNION_E) { type = objc_skip_typespec (type); }
return ++type;
case _C_PTR:
/* Just skip the following typespec */
return objc_skip_typespec (++type);
default:
{
objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
return 0;
}
}
}
/*
Skip an offset as part of a method encoding. This is prepended by a
'+' if the argument is passed in registers.
*/
inline const char*
objc_skip_offset (const char* type)
{
if (*type == '+') type++;
while(isdigit(*++type));
return type;
}
/*
Skip an argument specification of a method encoding.
*/
const char*
objc_skip_argspec (const char* type)
{
type = objc_skip_typespec (type);
type = objc_skip_offset (type);
return type;
}
/*
Return the number of arguments that the method MTH expects.
Note that all methods need two implicit arguments `self' and
`_cmd'.
*/
int
method_get_number_of_arguments (struct objc_method* mth)
{
int i = 0;
const char* type = mth->method_types;
while (*type)
{
type = objc_skip_argspec (type);
i += 1;
}
return i - 1;
}
/*
Return the size of the argument block needed on the stack to invoke
the method MTH. This may be zero, if all arguments are passed in
registers.
*/
int
method_get_sizeof_arguments (struct objc_method* mth)
{
const char* type = objc_skip_typespec (mth->method_types);
return atoi (type);
}
/*
Return a pointer to the next argument of ARGFRAME. type points to
the last argument. Typical use of this look like:
{
char *datum, *type;
for (datum = method_get_first_argument (method, argframe, &type);
datum; datum = method_get_next_argument (argframe, &type))
{
unsigned flags = objc_get_type_qualifiers (type);
type = objc_skip_type_qualifiers (type);
if (*type != _C_PTR)
[portal encodeData: datum ofType: type];
else
{
if ((flags & _F_IN) == _F_IN)
[portal encodeData: *(char**)datum ofType: ++type];
}
}
}
*/
char*
method_get_next_argument (arglist_t argframe,
const char **type)
{
const char *t = objc_skip_argspec (*type);
if (*t == '\0')
return 0;
*type = t;
t = objc_skip_typespec (t);
if (*t == '+')
return argframe->arg_regs + atoi (++t);
else
return argframe->arg_ptr + atoi (t);
}
/*
Return a pointer to the value of the first argument of the method
described in M with the given argumentframe ARGFRAME. The type
is returned in TYPE. type must be passed to successive calls of
method_get_next_argument.
*/
char*
method_get_first_argument (struct objc_method* m,
arglist_t argframe,
const char** type)
{
*type = m->method_types;
return method_get_next_argument (argframe, type);
}
/*
Return a pointer to the ARGth argument of the method
M from the frame ARGFRAME. The type of the argument
is returned in the value-result argument TYPE
*/
char*
method_get_nth_argument (struct objc_method* m,
arglist_t argframe, int arg,
const char **type)
{
const char* t = objc_skip_argspec (m->method_types);
if (arg > method_get_number_of_arguments (m))
return 0;
while (arg--)
t = objc_skip_argspec (t);
*type = t;
t = objc_skip_typespec (t);
if (*t == '+')
return argframe->arg_regs + atoi (++t);
else
return argframe->arg_ptr + atoi (t);
}
unsigned
objc_get_type_qualifiers (const char* type)
{
unsigned res = 0;
BOOL flag = YES;
while (flag)
switch (*type++)
{
case _C_CONST: res |= _F_CONST; break;
case _C_IN: res |= _F_IN; break;
case _C_INOUT: res |= _F_INOUT; break;
case _C_OUT: res |= _F_OUT; break;
case _C_BYCOPY: res |= _F_BYCOPY; break;
case _C_ONEWAY: res |= _F_ONEWAY; break;
default: flag = NO;
}
return res;
}

View file

@ -1,75 +0,0 @@
/* Encoding of types for Objective C.
Copyright (C) 1993, 1997 Free Software Foundation, Inc.
Author: Kresten Krab Thorup
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#ifndef __encoding_INCLUDE_GNU
#define __encoding_INCLUDE_GNU
#include <ctype.h>
#include "objc/objc-api.h"
#define _C_CONST 'r'
#define _C_IN 'n'
#define _C_INOUT 'N'
#define _C_OUT 'o'
#define _C_BYCOPY 'O'
#define _C_ONEWAY 'V'
#define _F_CONST 0x01
#define _F_IN 0x01
#define _F_OUT 0x02
#define _F_INOUT 0x03
#define _F_BYCOPY 0x04
#define _F_ONEWAY 0x08
int objc_aligned_size (const char* type);
int objc_sizeof_type (const char* type);
int objc_alignof_type (const char* type);
int objc_aligned_size (const char* type);
int objc_promoted_size (const char* type);
const char* objc_skip_type_qualifiers (const char* type);
const char* objc_skip_typespec (const char* type);
const char* objc_skip_offset (const char* type);
const char* objc_skip_argspec (const char* type);
int method_get_number_of_arguments (struct objc_method*);
int method_get_sizeof_arguments (struct objc_method*);
char* method_get_first_argument (struct objc_method*,
arglist_t argframe,
const char** type);
char* method_get_next_argument (arglist_t argframe,
const char **type);
char* method_get_nth_argument (struct objc_method* m,
arglist_t argframe,
int arg,
const char **type);
unsigned objc_get_type_qualifiers (const char* type);
#endif /* __encoding_INCLUDE_GNU */

View file

@ -1,283 +0,0 @@
/* Hash tables for Objective C internal structures
Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#include "assert.h"
#include "objc/hash.h"
#include "runtime.h" /* for DEBUG_PRINTF */
/* These two macros determine when a hash table is full and
by how much it should be expanded respectively.
These equations are percentages. */
#define FULLNESS(cache) \
((((cache)->size * 75) / 100) <= (cache)->used)
#define EXPANSION(cache) \
((cache)->size * 2)
cache_ptr
hash_new (unsigned int size, hash_func_type hash_func,
compare_func_type compare_func)
{
cache_ptr cache;
/* Pass me a value greater than 0 and a power of 2. */
assert (size);
assert (!(size & (size - 1)));
/* Allocate the cache structure. calloc insures
its initialization for default values. */
cache = (cache_ptr) objc_calloc (1, sizeof (struct cache));
assert (cache);
/* Allocate the array of buckets for the cache.
calloc initializes all of the pointers to NULL. */
cache->node_table
= (node_ptr *) objc_calloc (size, sizeof (node_ptr));
assert (cache->node_table);
cache->size = size;
/* This should work for all processor architectures? */
cache->mask = (size - 1);
/* Store the hashing function so that codes can be computed. */
cache->hash_func = hash_func;
/* Store the function that compares hash keys to
determine if they are equal. */
cache->compare_func = compare_func;
return cache;
}
void
hash_delete (cache_ptr cache)
{
node_ptr node;
node_ptr next_node;
unsigned int i;
/* Purge all key/value pairs from the table. */
/* Step through the nodes one by one and remove every node WITHOUT
using hash_next. this makes hash_delete much more efficient. */
for (i = 0;i < cache->size;i++) {
if ((node = cache->node_table[i])) {
/* an entry in the hash table has been found, now step through the
nodes next in the list and free them. */
while ((next_node = node->next)) {
hash_remove (cache,node->key);
node = next_node;
}
hash_remove (cache,node->key);
}
}
/* Release the array of nodes and the cache itself. */
objc_free(cache->node_table);
objc_free(cache);
}
void
hash_add (cache_ptr *cachep, const void *key, void *value)
{
size_t indx = (*(*cachep)->hash_func)(*cachep, key);
node_ptr node = (node_ptr) objc_calloc (1, sizeof (struct cache_node));
assert (node);
/* Initialize the new node. */
node->key = key;
node->value = value;
node->next = (*cachep)->node_table[indx];
/* Debugging.
Check the list for another key. */
#ifdef DEBUG
{ node_ptr node1 = (*cachep)->node_table[indx];
while (node1) {
assert (node1->key != key);
node1 = node1->next;
}
}
#endif
/* Install the node as the first element on the list. */
(*cachep)->node_table[indx] = node;
/* Bump the number of entries in the cache. */
++(*cachep)->used;
/* Check the hash table's fullness. We're going
to expand if it is above the fullness level. */
if (FULLNESS (*cachep)) {
/* The hash table has reached its fullness level. Time to
expand it.
I'm using a slow method here but is built on other
primitive functions thereby increasing its
correctness. */
node_ptr node1 = NULL;
cache_ptr new = hash_new (EXPANSION (*cachep),
(*cachep)->hash_func,
(*cachep)->compare_func);
DEBUG_PRINTF ("Expanding cache %#x from %d to %d\n",
*cachep, (*cachep)->size, new->size);
/* Copy the nodes from the first hash table to the new one. */
while ((node1 = hash_next (*cachep, node1)))
hash_add (&new, node1->key, node1->value);
/* Trash the old cache. */
hash_delete (*cachep);
/* Return a pointer to the new hash table. */
*cachep = new;
}
}
void
hash_remove (cache_ptr cache, const void *key)
{
size_t indx = (*cache->hash_func)(cache, key);
node_ptr node = cache->node_table[indx];
/* We assume there is an entry in the table. Error if it is not. */
assert (node);
/* Special case. First element is the key/value pair to be removed. */
if ((*cache->compare_func)(node->key, key)) {
cache->node_table[indx] = node->next;
objc_free(node);
} else {
/* Otherwise, find the hash entry. */
node_ptr prev = node;
BOOL removed = NO;
do {
if ((*cache->compare_func)(node->key, key)) {
prev->next = node->next, removed = YES;
objc_free(node);
} else
prev = node, node = node->next;
} while (!removed && node);
assert (removed);
}
/* Decrement the number of entries in the hash table. */
--cache->used;
}
node_ptr
hash_next (cache_ptr cache, node_ptr node)
{
/* If the scan is being started then reset the last node
visitied pointer and bucket index. */
if (!node)
cache->last_bucket = 0;
/* If there is a node visited last then check for another
entry in the same bucket; Otherwise step to the next bucket. */
if (node) {
if (node->next)
/* There is a node which follows the last node
returned. Step to that node and retun it. */
return node->next;
else
++cache->last_bucket;
}
/* If the list isn't exhausted then search the buckets for
other nodes. */
if (cache->last_bucket < cache->size) {
/* Scan the remainder of the buckets looking for an entry
at the head of the list. Return the first item found. */
while (cache->last_bucket < cache->size)
if (cache->node_table[cache->last_bucket])
return cache->node_table[cache->last_bucket];
else
++cache->last_bucket;
/* No further nodes were found in the hash table. */
return NULL;
} else
return NULL;
}
/* Given KEY, return corresponding value for it in CACHE.
Return NULL if the KEY is not recorded. */
void *
hash_value_for_key (cache_ptr cache, const void *key)
{
node_ptr node = cache->node_table[(*cache->hash_func)(cache, key)];
void *retval = NULL;
if (node)
do {
if ((*cache->compare_func)(node->key, key)) {
retval = node->value;
break;
} else
node = node->next;
} while (!retval && node);
return retval;
}
/* Given KEY, return YES if it exists in the CACHE.
Return NO if it does not */
BOOL
hash_is_key_in_hash (cache_ptr cache, const void *key)
{
node_ptr node = cache->node_table[(*cache->hash_func)(cache, key)];
if (node)
do {
if ((*cache->compare_func)(node->key, key))
return YES;
else
node = node->next;
} while (node);
return NO;
}

View file

@ -1,206 +0,0 @@
/* Hash tables for Objective C method dispatch.
Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#ifndef __hash_INCLUDE_GNU
#define __hash_INCLUDE_GNU
#include <stddef.h>
#include <objc/objc.h>
/*
* This data structure is used to hold items
* stored in a hash table. Each node holds
* a key/value pair.
*
* Items in the cache are really of type void *.
*/
typedef struct cache_node
{
struct cache_node *next; /* Pointer to next entry on the list.
NULL indicates end of list. */
const void *key; /* Key used to locate the value. Used
to locate value when more than one
key computes the same hash
value. */
void *value; /* Value stored for the key. */
} *node_ptr;
/*
* This data type is the function that computes a hash code given a key.
* Therefore, the key can be a pointer to anything and the function specific
* to the key type.
*
* Unfortunately there is a mutual data structure reference problem with this
* typedef. Therefore, to remove compiler warnings the functions passed to
* hash_new will have to be casted to this type.
*/
typedef unsigned int (*hash_func_type)(void *, const void *);
/*
* This data type is the function that compares two hash keys and returns an
* integer greater than, equal to, or less than 0, according as the first
* parameter is lexicographically greater than, equal to, or less than the
* second.
*/
typedef int (*compare_func_type)(const void *, const void *);
/*
* This data structure is the cache.
*
* It must be passed to all of the hashing routines
* (except for new).
*/
typedef struct cache
{
/* Variables used to implement the hash itself. */
node_ptr *node_table; /* Pointer to an array of hash nodes. */
/* Variables used to track the size of the hash table so to determine
when to resize it. */
unsigned int size; /* Number of buckets allocated for the hash table
(number of array entries allocated for
"node_table"). Must be a power of two. */
unsigned int used; /* Current number of entries in the hash table. */
unsigned int mask; /* Precomputed mask. */
/* Variables used to implement indexing through the hash table. */
unsigned int last_bucket; /* Tracks which entry in the array where
the last value was returned. */
/* Function used to compute a hash code given a key.
This function is specified when the hash table is created. */
hash_func_type hash_func;
/* Function used to compare two hash keys to see if they are equal. */
compare_func_type compare_func;
} *cache_ptr;
/* Two important hash tables. */
extern cache_ptr module_hash_table, class_hash_table;
/* Allocate and initialize a hash table. */
cache_ptr hash_new (unsigned int size,
hash_func_type hash_func,
compare_func_type compare_func);
/* Deallocate all of the hash nodes and the cache itself. */
void hash_delete (cache_ptr cache);
/* Add the key/value pair to the hash table. If the
hash table reaches a level of fullness then it will be resized.
assert if the key is already in the hash. */
void hash_add (cache_ptr *cachep, const void *key, void *value);
/* Remove the key/value pair from the hash table.
assert if the key isn't in the table. */
void hash_remove (cache_ptr cache, const void *key);
/* Used to index through the hash table. Start with NULL
to get the first entry.
Successive calls pass the value returned previously.
** Don't modify the hash during this operation ***
Cache nodes are returned such that key or value can
be extracted. */
node_ptr hash_next (cache_ptr cache, node_ptr node);
/* Used to return a value from a hash table using a given key. */
void *hash_value_for_key (cache_ptr cache, const void *key);
/* Used to determine if the given key exists in the hash table */
BOOL hash_is_key_in_hash (cache_ptr cache, const void *key);
/************************************************
Useful hashing functions.
Declared inline for your pleasure.
************************************************/
/* Calculate a hash code by performing some
manipulation of the key pointer. (Use the lowest bits
except for those likely to be 0 due to alignment.) */
static inline unsigned int
hash_ptr (cache_ptr cache, const void *key)
{
return ((size_t)key / sizeof (void *)) & cache->mask;
}
/* Calculate a hash code by iterating over a NULL
terminate string. */
static inline unsigned int
hash_string (cache_ptr cache, const void *key)
{
unsigned int ret = 0;
unsigned int ctr = 0;
while (*(char*)key) {
ret ^= *(char*)key++ << ctr;
ctr = (ctr + 1) % sizeof (void *);
}
return ret & cache->mask;
}
/* Compare two pointers for equality. */
static inline int
compare_ptrs (const void *k1, const void *k2)
{
return !(k1 - k2);
}
/* Compare two strings. */
static inline int
compare_strings (const void *k1, const void *k2)
{
if (k1 == k2)
return 1;
else if (k1 == 0 || k2 == 0)
return 0;
else
return !strcmp (k1, k2);
}
#endif /* not __hash_INCLUDE_GNU */

View file

@ -1,834 +0,0 @@
/* GNU Objective C Runtime initialization
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup
+load support contributed by Ovidiu Predescu <ovidiu@net-community.com>
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2, or (at your option) any later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
GNU CC; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled with
GCC to produce an executable, this does not cause the resulting executable
to be covered by the GNU General Public License. This exception does not
however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */
#include "runtime.h"
/* The version number of this runtime. This must match the number
defined in gcc (objc-act.c) */
#define OBJC_VERSION 8
#define PROTOCOL_VERSION 2
/* This list contains all modules currently loaded into the runtime */
static struct objc_list* __objc_module_list = 0; /* !T:MUTEX */
/* This list contains all proto_list's not yet assigned class links */
static struct objc_list* unclaimed_proto_list = 0; /* !T:MUTEX */
/* List of unresolved static instances. */
static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
/* Global runtime "write" mutex. */
objc_mutex_t __objc_runtime_mutex = 0;
/* Number of threads that are alive. */
int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
/* Check compiler vs runtime version */
static void init_check_module_version (Module_t);
/* Assign isa links to protos */
static void __objc_init_protocols (struct objc_protocol_list* protos);
/* Add protocol to class */
static void __objc_class_add_protocols (Class, struct objc_protocol_list*);
/* This is a hook which is called by __objc_exec_class every time a class
or a category is loaded into the runtime. This may e.g. help a
dynamic loader determine the classes that have been loaded when
an object file is dynamically linked in */
void (*_objc_load_callback)(Class class, Category* category); /* !T:SAFE */
/* Is all categories/classes resolved? */
BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
extern SEL
__sel_register_typed_name (const char *name, const char *types,
struct objc_selector *orig, BOOL is_const);
/* Sends +load to all classes and categories in certain situations. */
static void objc_send_load (void);
/* Inserts all the classes defined in module in a tree of classes that
resembles the class hierarchy. This tree is traversed in preorder and the
classes in its nodes receive the +load message if these methods were not
executed before. The algorithm ensures that when the +load method of a class
is executed all the superclasses have been already received the +load
message. */
static void __objc_create_classes_tree (Module_t module);
static void __objc_call_callback (Module_t module);
/* A special version that works only before the classes are completely
installed in the runtime. */
static BOOL class_is_subclass_of_class (Class class, Class superclass);
typedef struct objc_class_tree {
Class class;
struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
} objc_class_tree;
/* This is a linked list of objc_class_tree trees. The head of these trees
are root classes (their super class is Nil). These different trees
represent different class hierarchies. */
static struct objc_list *__objc_class_tree_list = NULL;
/* Keeps the +load methods who have been already executed. This hash should
not be destroyed during the execution of the program. */
static cache_ptr __objc_load_methods = NULL;
/* Creates a tree of classes whose topmost class is directly inherited from
`upper' and the bottom class in this tree is `bottom_class'. The classes
in this tree are super classes of `bottom_class'. `subclasses' member
of each tree node point to the next subclass tree node. */
static objc_class_tree *
create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
{
Class superclass = bottom_class->super_class ?
objc_lookup_class ((char*)bottom_class->super_class)
: Nil;
objc_class_tree *tree, *prev;
DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
DEBUG_PRINTF ("bottom_class = %s, upper = %s\n",
(bottom_class ? bottom_class->name : NULL),
(upper ? upper->name : NULL));
tree = prev = objc_calloc (1, sizeof (objc_class_tree));
prev->class = bottom_class;
while (superclass != upper)
{
tree = objc_calloc (1, sizeof (objc_class_tree));
tree->class = superclass;
tree->subclasses = list_cons (prev, tree->subclasses);
superclass = (superclass->super_class ?
objc_lookup_class ((char*)superclass->super_class)
: Nil);
prev = tree;
}
return tree;
}
/* Insert the `class' into the proper place in the `tree' class hierarchy. This
function returns a new tree if the class has been successfully inserted into
the tree or NULL if the class is not part of the classes hierarchy described
by `tree'. This function is private to objc_tree_insert_class(), you should
not call it directly. */
static objc_class_tree *
__objc_tree_insert_class (objc_class_tree *tree, Class class)
{
DEBUG_PRINTF ("__objc_tree_insert_class: tree = %x, class = %s\n",
tree, class->name);
if (tree == NULL)
return create_tree_of_subclasses_inherited_from (class, NULL);
else if (class == tree->class)
{
/* `class' has been already inserted */
DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
return tree;
}
else if ((class->super_class ?
objc_lookup_class ((char*)class->super_class)
: Nil)
== tree->class)
{
/* If class is a direct subclass of tree->class then add class to the
list of subclasses. First check to see if it wasn't already
inserted. */
struct objc_list *list = tree->subclasses;
objc_class_tree *node;
while (list)
{
/* Class has been already inserted; do nothing just return
the tree. */
if (((objc_class_tree*)list->head)->class == class)
{
DEBUG_PRINTF ("2. class %s was previously inserted\n",
class->name);
return tree;
}
list = list->tail;
}
/* Create a new node class and insert it into the list of subclasses */
node = objc_calloc (1, sizeof (objc_class_tree));
node->class = class;
tree->subclasses = list_cons (node, tree->subclasses);
DEBUG_PRINTF ("3. class %s inserted\n", class->name);
return tree;
}
else
{
/* The class is not a direct subclass of tree->class. Search for class's
superclasses in the list of subclasses. */
struct objc_list *subclasses = tree->subclasses;
/* Precondition: the class must be a subclass of tree->class; otherwise
return NULL to indicate our caller that it must take the next tree. */
if (!class_is_subclass_of_class (class, tree->class))
return NULL;
for (; subclasses != NULL; subclasses = subclasses->tail)
{
Class aClass = ((objc_class_tree*)(subclasses->head))->class;
if (class_is_subclass_of_class (class, aClass))
{
/* If we found one of class's superclasses we insert the class
into its subtree and return the original tree since nothing
has been changed. */
subclasses->head
= __objc_tree_insert_class (subclasses->head, class);
DEBUG_PRINTF ("4. class %s inserted\n", class->name);
return tree;
}
}
/* We haven't found a subclass of `class' in the `subclasses' list.
Create a new tree of classes whose topmost class is a direct subclass
of tree->class. */
{
objc_class_tree *new_tree
= create_tree_of_subclasses_inherited_from (class, tree->class);
tree->subclasses = list_cons (new_tree, tree->subclasses);
DEBUG_PRINTF ("5. class %s inserted\n", class->name);
return tree;
}
}
}
/* This function inserts `class' in the right tree hierarchy classes. */
static void
objc_tree_insert_class (Class class)
{
struct objc_list *list_node;
objc_class_tree *tree;
list_node = __objc_class_tree_list;
while (list_node)
{
tree = __objc_tree_insert_class (list_node->head, class);
if (tree)
{
list_node->head = tree;
break;
}
else
list_node = list_node->tail;
}
/* If the list was finished but the class hasn't been inserted, insert it
here. */
if (!list_node)
{
__objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
__objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
}
}
/* Traverse tree in preorder. Used to send +load. */
static void
objc_preorder_traverse (objc_class_tree *tree,
int level,
void (*function)(objc_class_tree*, int))
{
struct objc_list *node;
(*function) (tree, level);
for (node = tree->subclasses; node; node = node->tail)
objc_preorder_traverse (node->head, level + 1, function);
}
/* Traverse tree in postorder. Used to destroy a tree. */
static void
objc_postorder_traverse (objc_class_tree *tree,
int level,
void (*function)(objc_class_tree*, int))
{
struct objc_list *node;
for (node = tree->subclasses; node; node = node->tail)
objc_postorder_traverse (node->head, level + 1, function);
(*function) (tree, level);
}
/* Used to print a tree class hierarchy. */
#ifdef DEBUG
static void
__objc_tree_print (objc_class_tree *tree, int level)
{
int i;
for (i = 0; i < level; i++)
printf (" ");
printf ("%s\n", tree->class->name);
}
#endif
/* Walks on a linked list of methods in the reverse order and executes all
the methods corresponding to `op' selector. Walking in the reverse order
assures the +load of class is executed first and then +load of categories
because of the way in which categories are added to the class methods. */
static void
__objc_send_message_in_list (MethodList_t method_list, Class class, SEL op)
{
int i;
if (!method_list)
return;
/* First execute the `op' message in the following method lists */
__objc_send_message_in_list (method_list->method_next, class, op);
/* Search the method list. */
for (i = 0; i < method_list->method_count; i++)
{
Method_t mth = &method_list->method_list[i];
if (mth->method_name && sel_eq (mth->method_name, op)
&& !hash_is_key_in_hash (__objc_load_methods, mth->method_name))
{
/* The method was found and wasn't previously executed. */
(*mth->method_imp) ((id)class, mth->method_name);
/* Add this method into the +load hash table */
hash_add (&__objc_load_methods, mth->method_imp, mth->method_imp);
DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
break;
}
}
}
static void
__objc_send_load (objc_class_tree *tree, int level)
{
static SEL load_sel = 0;
Class class = tree->class;
MethodList_t method_list = class->class_pointer->methods;
if (!load_sel)
load_sel = sel_register_name ("load");
__objc_send_message_in_list (method_list, class, load_sel);
}
static void
__objc_destroy_class_tree_node (objc_class_tree *tree, int level)
{
objc_free (tree);
}
/* This is used to check if the relationship between two classes before the
runtime completely installs the classes. */
static BOOL
class_is_subclass_of_class (Class class, Class superclass)
{
for (; class != Nil;)
{
if (class == superclass)
return YES;
class = (class->super_class ?
objc_lookup_class ((char*)class->super_class)
: Nil);
}
return NO;
}
/* This list contains all the classes in the runtime system for whom their
superclasses are not yet know to the runtime. */
static struct objc_list* unresolved_classes = 0;
/* Static function used to reference the Object and NXConstantString classes.
*/
static void
__objc_force_linking (void)
{
extern void __objc_linking (void);
__objc_linking ();
/* Call the function to avoid compiler warning */
__objc_force_linking ();
}
/* Run through the statics list, removing modules as soon as all its statics
have been initialized. */
static void
objc_init_statics (void)
{
struct objc_list **cell = &uninitialized_statics;
struct objc_static_instances **statics_in_module;
objc_mutex_lock(__objc_runtime_mutex);
while (*cell)
{
int module_initialized = 1;
for (statics_in_module = (*cell)->head;
*statics_in_module; statics_in_module++)
{
struct objc_static_instances *statics = *statics_in_module;
Class class = objc_lookup_class (statics->class_name);
if (!class)
module_initialized = 0;
/* Actually, the static's class_pointer will be NULL when we
haven't been here before. However, the comparison is to be
reminded of taking into account class posing and to think about
possible semantics... */
else if (class != statics->instances[0]->class_pointer)
{
id *inst;
for (inst = &statics->instances[0]; *inst; inst++)
{
(*inst)->class_pointer = class;
/* ??? Make sure the object will not be freed. With
refcounting, invoke `-retain'. Without refcounting, do
nothing and hope that `-free' will never be invoked. */
/* ??? Send the object an `-initStatic' or something to
that effect now or later on? What are the semantics of
statically allocated instances, besides the trivial
NXConstantString, anyway? */
}
}
}
if (module_initialized)
{
/* Remove this module from the uninitialized list. */
struct objc_list *this = *cell;
*cell = this->tail;
objc_free(this);
}
else
cell = &(*cell)->tail;
}
objc_mutex_unlock(__objc_runtime_mutex);
} /* objc_init_statics */
/* This function is called by constructor functions generated for each
module compiled. (_GLOBAL_$I$...) The purpose of this function is to
gather the module pointers so that they may be processed by the
initialization routines as soon as possible */
void
__objc_exec_class (Module_t module)
{
/* Have we processed any constructors previously? This flag is used to
indicate that some global data structures need to be built. */
static BOOL previous_constructors = 0;
static struct objc_list* unclaimed_categories = 0;
/* The symbol table (defined in objc-api.h) generated by gcc */
Symtab_t symtab = module->symtab;
/* The statics in this module */
struct objc_static_instances **statics
= symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
/* Entry used to traverse hash lists */
struct objc_list** cell;
/* The table of selector references for this module */
SEL selectors = symtab->refs;
/* dummy counter */
int i;
DEBUG_PRINTF ("received module: %s\n", module->name);
/* check gcc version */
init_check_module_version(module);
/* On the first call of this routine, initialize some data structures. */
if (!previous_constructors)
{
/* Initialize thread-safe system */
__objc_init_thread_system();
__objc_runtime_threads_alive = 1;
__objc_runtime_mutex = objc_mutex_allocate();
__objc_init_selector_tables();
__objc_init_class_tables();
__objc_init_dispatch_tables();
__objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
__objc_load_methods
= hash_new (128, (hash_func_type)hash_ptr, compare_ptrs);
previous_constructors = 1;
}
/* Save the module pointer for later processing. (not currently used) */
objc_mutex_lock(__objc_runtime_mutex);
__objc_module_list = list_cons(module, __objc_module_list);
/* Replace referenced selectors from names to SEL's. */
if (selectors)
{
for (i = 0; selectors[i].sel_id; ++i)
{
const char *name, *type;
name = (char*)selectors[i].sel_id;
type = (char*)selectors[i].sel_types;
/* Constructors are constant static data so we can safely store
pointers to them in the runtime structures. is_const == YES */
__sel_register_typed_name (name, type,
(struct objc_selector*)&(selectors[i]),
YES);
}
}
/* Parse the classes in the load module and gather selector information. */
DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
for (i = 0; i < symtab->cls_def_cnt; ++i)
{
Class class = (Class) symtab->defs[i];
const char* superclass = (char*)class->super_class;
/* Make sure we have what we think. */
assert (CLS_ISCLASS(class));
assert (CLS_ISMETA(class->class_pointer));
DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
/* Initialize the subclass list to be NULL.
In some cases it isn't and this crashes the program. */
class->subclass_list = NULL;
/* Store the class in the class table and assign class numbers. */
__objc_add_class_to_hash (class);
/* Register all of the selectors in the class and meta class. */
__objc_register_selectors_from_class (class);
__objc_register_selectors_from_class ((Class) class->class_pointer);
/* Install the fake dispatch tables */
__objc_install_premature_dtable(class);
__objc_install_premature_dtable(class->class_pointer);
/* Register the instance methods as class methods, this is
only done for root classes. */
__objc_register_instance_methods_to_class(class);
if (class->protocols)
__objc_init_protocols (class->protocols);
/* Check to see if the superclass is known in this point. If it's not
add the class to the unresolved_classes list. */
if (superclass && !objc_lookup_class (superclass))
unresolved_classes = list_cons (class, unresolved_classes);
}
/* Process category information from the module. */
for (i = 0; i < symtab->cat_def_cnt; ++i)
{
Category_t category = symtab->defs[i + symtab->cls_def_cnt];
Class class = objc_lookup_class (category->class_name);
/* If the class for the category exists then append its methods. */
if (class)
{
DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
module->name,
class->name);
/* Do instance methods. */
if (category->instance_methods)
class_add_method_list (class, category->instance_methods);
/* Do class methods. */
if (category->class_methods)
class_add_method_list ((Class) class->class_pointer,
category->class_methods);
if (category->protocols)
{
__objc_init_protocols (category->protocols);
__objc_class_add_protocols (class, category->protocols);
}
/* Register the instance methods as class methods, this is
only done for root classes. */
__objc_register_instance_methods_to_class(class);
}
else
{
/* The object to which the category methods belong can't be found.
Save the information. */
unclaimed_categories = list_cons(category, unclaimed_categories);
}
}
if (statics)
uninitialized_statics = list_cons (statics, uninitialized_statics);
if (uninitialized_statics)
objc_init_statics ();
/* Scan the unclaimed category hash. Attempt to attach any unclaimed
categories to objects. */
for (cell = &unclaimed_categories;
*cell;
({ if (*cell) cell = &(*cell)->tail; }))
{
Category_t category = (*cell)->head;
Class class = objc_lookup_class (category->class_name);
if (class)
{
DEBUG_PRINTF ("attaching stored categories to object: %s\n",
class->name);
list_remove_head (cell);
if (category->instance_methods)
class_add_method_list (class, category->instance_methods);
if (category->class_methods)
class_add_method_list ((Class) class->class_pointer,
category->class_methods);
if (category->protocols)
{
__objc_init_protocols (category->protocols);
__objc_class_add_protocols (class, category->protocols);
}
/* Register the instance methods as class methods, this is
only done for root classes. */
__objc_register_instance_methods_to_class(class);
}
}
if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
{
list_mapcar (unclaimed_proto_list,(void(*)(void*))__objc_init_protocols);
list_free (unclaimed_proto_list);
unclaimed_proto_list = 0;
}
objc_send_load ();
objc_mutex_unlock(__objc_runtime_mutex);
}
static void objc_send_load (void)
{
if (!__objc_module_list)
return;
/* Try to find out if all the classes loaded so far also have their
superclasses known to the runtime. We suppose that the objects that are
allocated in the +load method are in general of a class declared in the
same module. */
if (unresolved_classes)
{
Class class = unresolved_classes->head;
while (objc_lookup_class ((char*)class->super_class))
{
list_remove_head (&unresolved_classes);
if (unresolved_classes)
class = unresolved_classes->head;
else
break;
}
/*
* If we still have classes for whom we don't have yet their super
* classes known to the runtime we don't send the +load messages.
*/
if (unresolved_classes)
return;
}
/* Special check to allow creating and sending messages to constant strings
in +load methods. If these classes are not yet known, even if all the
other classes are known, delay sending of +load. */
if (!objc_lookup_class ("NXConstantString") ||
!objc_lookup_class ("Object"))
return;
/* Iterate over all modules in the __objc_module_list and call on them the
__objc_create_classes_tree function. This function creates a tree of
classes that resembles the class hierarchy. */
list_mapcar (__objc_module_list, (void(*)(void*))__objc_create_classes_tree);
while (__objc_class_tree_list)
{
#ifdef DEBUG
objc_preorder_traverse (__objc_class_tree_list->head,
0, __objc_tree_print);
#endif
objc_preorder_traverse (__objc_class_tree_list->head,
0, __objc_send_load);
objc_postorder_traverse (__objc_class_tree_list->head,
0, __objc_destroy_class_tree_node);
list_remove_head (&__objc_class_tree_list);
}
list_mapcar (__objc_module_list, (void(*)(void*))__objc_call_callback);
list_free (__objc_module_list);
__objc_module_list = NULL;
}
static void
__objc_create_classes_tree (Module_t module)
{
/* The runtime mutex is locked in this point */
Symtab_t symtab = module->symtab;
int i;
/* Iterate thru classes defined in this module and insert them in the classes
tree hierarchy. */
for (i = 0; i < symtab->cls_def_cnt; i++)
{
Class class = (Class) symtab->defs[i];
objc_tree_insert_class (class);
}
}
static void
__objc_call_callback (Module_t module)
{
/* The runtime mutex is locked in this point */
Symtab_t symtab = module->symtab;
int i;
/* Iterate thru classes defined in this module and call the callback for
each one. */
for (i = 0; i < symtab->cls_def_cnt; i++)
{
Class class = (Class) symtab->defs[i];
/* Call the _objc_load_callback for this class. */
if (_objc_load_callback)
_objc_load_callback(class, 0);
}
/* Call the _objc_load_callback for categories. Don't register the instance
methods as class methods for categories to root classes since they were
already added in the class. */
for (i = 0; i < symtab->cat_def_cnt; i++)
{
Category_t category = symtab->defs[i + symtab->cls_def_cnt];
Class class = objc_lookup_class (category->class_name);
if (_objc_load_callback)
_objc_load_callback(class, category);
}
}
/* Sanity check the version of gcc used to compile `module'*/
static void init_check_module_version(Module_t module)
{
if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
{
int code;
if(module->version > OBJC_VERSION)
code = OBJC_ERR_OBJC_VERSION;
else if (module->version < OBJC_VERSION)
code = OBJC_ERR_GCC_VERSION;
else
code = OBJC_ERR_MODULE_SIZE;
objc_error(nil, code, "Module %s version %d doesn't match runtime %d\n",
module->name, (int)module->version, OBJC_VERSION);
}
}
static void
__objc_init_protocols (struct objc_protocol_list* protos)
{
int i;
static Class proto_class = 0;
if (! protos)
return;
objc_mutex_lock(__objc_runtime_mutex);
if (!proto_class)
proto_class = objc_lookup_class("Protocol");
if (!proto_class)
{
unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
objc_mutex_unlock(__objc_runtime_mutex);
return;
}
#if 0
assert (protos->next == 0); /* only single ones allowed */
#endif
for(i = 0; i < protos->count; i++)
{
struct objc_protocol* aProto = protos->list[i];
if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
{
/* assign class pointer */
aProto->class_pointer = proto_class;
/* init super protocols */
__objc_init_protocols (aProto->protocol_list);
}
else if (protos->list[i]->class_pointer != proto_class)
{
objc_error(nil, OBJC_ERR_PROTOCOL_VERSION,
"Version %d doesn't match runtime protocol version %d\n",
(int)((char*)protos->list[i]->class_pointer-(char*)0),
PROTOCOL_VERSION);
}
}
objc_mutex_unlock(__objc_runtime_mutex);
}
static void __objc_class_add_protocols (Class class,
struct objc_protocol_list* protos)
{
/* Well... */
if (! protos)
return;
/* Add it... */
protos->next = class->protocols;
class->protocols = protos;
}

View file

@ -1,150 +0,0 @@
/* Generic single linked list to keep various information
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
Author: Kresten Krab Thorup
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled with
GCC to produce an executable, this does not cause the resulting executable
to be covered by the GNU General Public License. This exception does not
however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */
#ifndef __GNU_OBJC_LIST_H
#define __GNU_OBJC_LIST_H
void * __objc_xrealloc (void *optr, size_t size);
void * __objc_xmalloc (size_t size);
struct objc_list {
void *head;
struct objc_list *tail;
};
/* Return a cons cell produced from (head . tail) */
static inline struct objc_list*
list_cons(void* head, struct objc_list* tail)
{
struct objc_list* cell;
cell = (struct objc_list*)__objc_xmalloc(sizeof(struct objc_list));
cell->head = head;
cell->tail = tail;
return cell;
}
/* Return the length of a list, list_length(NULL) returns zero */
static inline int
list_length(struct objc_list* list)
{
int i = 0;
while(list)
{
i += 1;
list = list->tail;
}
return i;
}
/* Return the Nth element of LIST, where N count from zero. If N
larger than the list length, NULL is returned */
static inline void*
list_nth(int index, struct objc_list* list)
{
while(index-- != 0)
{
if(list->tail)
list = list->tail;
else
return 0;
}
return list->head;
}
/* Remove the element at the head by replacing it by its successor */
static inline void
list_remove_head(struct objc_list** list)
{
if ((*list)->tail)
{
struct objc_list* tail = (*list)->tail; /* fetch next */
*(*list) = *tail; /* copy next to list head */
free(tail); /* free next */
}
else /* only one element in list */
{
free (*list);
(*list) = 0;
}
}
/* Remove the element with `car' set to ELEMENT */
static inline void
list_remove_elem(struct objc_list** list, void* elem)
{
while (*list) {
if ((*list)->head == elem)
list_remove_head(list);
list = &((*list)->tail);
}
}
/* Map FUNCTION over all elements in LIST */
static inline void
list_mapcar(struct objc_list* list, void(*function)(void*))
{
while(list)
{
(*function)(list->head);
list = list->tail;
}
}
/* Return element that has ELEM as car */
static inline struct objc_list**
list_find(struct objc_list** list, void* elem)
{
while(*list)
{
if ((*list)->head == elem)
return list;
list = &((*list)->tail);
}
return NULL;
}
/* Free list (backwards recursive) */
static void
list_free(struct objc_list* list)
{
if(list)
{
list_free(list->tail);
free(list);
}
}
#endif __GNU_OBJC_LIST_H

View file

@ -1,56 +0,0 @@
# GNU Objective C Runtime Makefile for compiling with djgpp
# Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
#
# This file is part of GNU CC.
#
# GNU CC is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2, or (at your option) any later version.
#
# GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# GNU CC; see the file COPYING. If not, write to the Free Software
# Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# This Makefile is configured for GnuMAKE
GCC_FOR_TARGET=gcc
.SUFFIXES: .o .m
OPTIMIZE = -O2
# Always search these dirs when compiling.
SUBDIR_INCLUDES = -I. -I.. -I../config
.c.o:
$(GCC_FOR_TARGET) $(OPTIMIZE) \
-c $(GCC_CFLAGS) $(SUBDIR_INCLUDES) $<
.m.o:
$(GCC_FOR_TARGET) $(OPTIMIZE) -fgnu-runtime \
-c $(GCC_CFLAGS) $(SUBDIR_INCLUDES) $<
OBJC_O = hash.o sarray.o class.o sendmsg.o init.o archive.o \
selector.o objects.o misc.o object.o protocol.o encoding.o thread.o
libobjc.a: $(OBJC_O)
-rm -f libobjc.a
ar rc libobjc.a $(OBJC_O)
ranlib libobjc.a
OBJC_H = hash.h objc-list.h sarray.h objc.h \
objc-api.h \
object.h protocol.h mutex.h \
typedstream.h thread.h
mostlyclean:
-rm -f *.o libobjc.a xforward fflags
clean: mostlyclean
distclean: mostlyclean
extraclean: mostlyclean

View file

@ -1,152 +0,0 @@
/* GNU Objective C Runtime Miscellaneous
Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled with
GCC to produce an executable, this does not cause the resulting executable
to be covered by the GNU General Public License. This exception does not
however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */
#define __USE_FIXED_PROTOTYPES__
#include <stdlib.h>
#include "runtime.h"
/*
** Error handler function
** NULL so that default is to just print to stderr
*/
static objc_error_handler _objc_error_handler = NULL;
/* Trigger an objc error */
void
objc_error(id object, int code, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
objc_verror(object, code, fmt, ap);
va_end(ap);
}
/* Trigger an objc error */
void
objc_verror(id object, int code, const char* fmt, va_list ap)
{
BOOL result = NO;
/* Call the error handler if its there
Otherwise print to stderr */
if (_objc_error_handler)
result = (*_objc_error_handler)(object, code, fmt, ap);
else
vfprintf (stderr, fmt, ap);
/* Continue if the error handler says its ok
Otherwise abort the program */
if (result)
return;
else
abort();
}
/* Set the error handler */
objc_error_handler
objc_set_error_handler(objc_error_handler func)
{
objc_error_handler temp = _objc_error_handler;
_objc_error_handler = func;
return temp;
}
/*
** Standard functions for memory allocation and disposal.
** Users should use these functions in their ObjC programs so
** that they work properly with garbage collectors as well as
** can take advantage of the exception/error handling available.
*/
void *
objc_malloc(size_t size)
{
void* res = (void*) (*_objc_malloc)(size);
if(!res)
objc_error(nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n");
return res;
}
void *
objc_atomic_malloc(size_t size)
{
void* res = (void*) (*_objc_atomic_malloc)(size);
if(!res)
objc_error(nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n");
return res;
}
void *
objc_valloc(size_t size)
{
void* res = (void*) (*_objc_valloc)(size);
if(!res)
objc_error(nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n");
return res;
}
void *
objc_realloc(void *mem, size_t size)
{
void* res = (void*) (*_objc_realloc)(mem, size);
if(!res)
objc_error(nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n");
return res;
}
void *
objc_calloc(size_t nelem, size_t size)
{
void* res = (void*) (*_objc_calloc)(nelem, size);
if(!res)
objc_error(nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n");
return res;
}
void
objc_free(void *mem)
{
(*_objc_free)(mem);
}
/*
** Hook functions for memory allocation and disposal.
** This makes it easy to substitute garbage collection systems
** such as Boehm's GC by assigning these function pointers
** to the GC's allocation routines. By default these point
** to the ANSI standard malloc, realloc, free, etc.
**
** Users should call the normal objc routines above for
** memory allocation and disposal within their programs.
*/
void *(*_objc_malloc)(size_t) = malloc;
void *(*_objc_atomic_malloc)(size_t) = malloc;
void *(*_objc_valloc)(size_t) = malloc;
void *(*_objc_realloc)(void *, size_t) = realloc;
void *(*_objc_calloc)(size_t, size_t) = calloc;
void (*_objc_free)(void *) = free;

View file

@ -1,584 +0,0 @@
/* GNU Objective-C Runtime API.
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled
with GCC to produce an executable, this does not cause the resulting
executable to be covered by the GNU General Public License. This
exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License. */
#ifndef __objc_api_INCLUDE_GNU
#define __objc_api_INCLUDE_GNU
#include "objc/objc.h"
#include "objc/hash.h"
#include "objc/thr.h"
#include <stdio.h>
#include <stdarg.h>
/* For functions which return Method_t */
#define METHOD_NULL (Method_t)0
/* Boolean typedefs */
/*
** Method descriptor returned by introspective Object methods.
** This is really just the first part of the more complete objc_method
** structure defined below and used internally by the runtime.
*/
struct objc_method_description
{
SEL name; /* this is a selector, not a string */
char *types; /* type encoding */
};
/* Filer types used to describe Ivars and Methods. */
#define _C_ID '@'
#define _C_CLASS '#'
#define _C_SEL ':'
#define _C_CHR 'c'
#define _C_UCHR 'C'
#define _C_SHT 's'
#define _C_USHT 'S'
#define _C_INT 'i'
#define _C_UINT 'I'
#define _C_LNG 'l'
#define _C_ULNG 'L'
#define _C_FLT 'f'
#define _C_DBL 'd'
#define _C_BFLD 'b'
#define _C_VOID 'v'
#define _C_UNDEF '?'
#define _C_PTR '^'
#define _C_CHARPTR '*'
#define _C_ATOM '%'
#define _C_ARY_B '['
#define _C_ARY_E ']'
#define _C_UNION_B '('
#define _C_UNION_E ')'
#define _C_STRUCT_B '{'
#define _C_STRUCT_E '}'
/*
** Error handling
**
** Call objc_error() or objc_verror() to record an error; this error
** routine will generally exit the program but not necessarily if the
** user has installed his own error handler.
**
** Call objc_set_error_handler to assign your own function for
** handling errors. The function should return YES if it is ok
** to continue execution, or return NO or just abort if the
** program should be stopped. The default error handler is just to
** print a message on stderr.
**
** The error handler function should be of type objc_error_handler
** The first parameter is an object instance of relevance.
** The second parameter is an error code.
** The third parameter is a format string in the printf style.
** The fourth parameter is a variable list of arguments.
*/
extern void objc_error(id object, int code, const char* fmt, ...);
extern void objc_verror(id object, int code, const char* fmt, va_list ap);
typedef BOOL (*objc_error_handler)(id, int code, const char *fmt, va_list ap);
objc_error_handler objc_set_error_handler(objc_error_handler func);
/*
** Error codes
** These are used by the runtime library, and your
** error handling may use them to determine if the error is
** hard or soft thus whether execution can continue or abort.
*/
#define OBJC_ERR_UNKNOWN 0 /* Generic error */
#define OBJC_ERR_OBJC_VERSION 1 /* Incorrect runtime version */
#define OBJC_ERR_GCC_VERSION 2 /* Incorrect compiler version */
#define OBJC_ERR_MODULE_SIZE 3 /* Bad module size */
#define OBJC_ERR_PROTOCOL_VERSION 4 /* Incorrect protocol version */
#define OBJC_ERR_MEMORY 10 /* Out of memory */
#define OBJC_ERR_RECURSE_ROOT 20 /* Attempt to archive the root
object more than once. */
#define OBJC_ERR_BAD_DATA 21 /* Didn't read expected data */
#define OBJC_ERR_BAD_KEY 22 /* Bad key for object */
#define OBJC_ERR_BAD_CLASS 23 /* Unknown class */
#define OBJC_ERR_BAD_TYPE 24 /* Bad type specification */
#define OBJC_ERR_NO_READ 25 /* Cannot read stream */
#define OBJC_ERR_NO_WRITE 26 /* Cannot write stream */
#define OBJC_ERR_STREAM_VERSION 27 /* Incorrect stream version */
#define OBJC_ERR_BAD_OPCODE 28 /* Bad opcode */
#define OBJC_ERR_UNIMPLEMENTED 30 /* Method is not implemented */
#define OBJC_ERR_BAD_STATE 40 /* Bad thread state */
/*
** Set this variable nonzero to print a line describing each
** message that is sent. (this is currently disabled)
*/
extern BOOL objc_trace;
/* For every class which happens to have statically allocated instances in
this module, one OBJC_STATIC_INSTANCES is allocated by the compiler.
INSTANCES is NULL terminated and points to all statically allocated
instances of this class. */
struct objc_static_instances
{
char *class_name;
id instances[0];
};
/*
** Whereas a Module (defined further down) is the root (typically) of a file,
** a Symtab is the root of the class and category definitions within the
** module.
**
** A Symtab contains a variable length array of pointers to classes and
** categories defined in the module.
*/
typedef struct objc_symtab {
unsigned long sel_ref_cnt; /* Unknown. */
SEL refs; /* Unknown. */
unsigned short cls_def_cnt; /* Number of classes compiled
(defined) in the module. */
unsigned short cat_def_cnt; /* Number of categories
compiled (defined) in the
module. */
void *defs[1]; /* Variable array of pointers.
cls_def_cnt of type Class
followed by cat_def_cnt of
type Category_t, followed
by a NULL terminated array
of objc_static_instances. */
} Symtab, *Symtab_t;
/*
** The compiler generates one of these structures for each module that
** composes the executable (eg main.m).
**
** This data structure is the root of the definition tree for the module.
**
** A collect program runs between ld stages and creates a ObjC ctor array.
** That array holds a pointer to each module structure of the executable.
*/
typedef struct objc_module {
unsigned long version; /* Compiler revision. */
unsigned long size; /* sizeof(Module). */
const char* name; /* Name of the file where the
module was generated. The
name includes the path. */
Symtab_t symtab; /* Pointer to the Symtab of
the module. The Symtab
holds an array of
pointers to
the classes and categories
defined in the module. */
} Module, *Module_t;
/*
** The compiler generates one of these structures for a class that has
** instance variables defined in its specification.
*/
typedef struct objc_ivar* Ivar_t;
typedef struct objc_ivar_list {
int ivar_count; /* Number of structures (Ivar)
contained in the list. One
structure per instance
variable defined in the
class. */
struct objc_ivar {
const char* ivar_name; /* Name of the instance
variable as entered in the
class definition. */
const char* ivar_type; /* Description of the Ivar's
type. Useful for
debuggers. */
int ivar_offset; /* Byte offset from the base
address of the instance
structure to the variable. */
} ivar_list[1]; /* Variable length
structure. */
} IvarList, *IvarList_t;
/*
** The compiler generates one (or more) of these structures for a class that
** has methods defined in its specification.
**
** The implementation of a class can be broken into separate pieces in a file
** and categories can break them across modules. To handle this problem is a
** singly linked list of methods.
*/
typedef struct objc_method Method;
typedef Method* Method_t;
typedef struct objc_method_list {
struct objc_method_list* method_next; /* This variable is used to link
a method list to another. It
is a singly linked list. */
int method_count; /* Number of methods defined in
this structure. */
struct objc_method {
SEL method_name; /* This variable is the method's
name. It is a char*.
The unique integer passed to
objc_msg_send is a char* too.
It is compared against
method_name using strcmp. */
const char* method_types; /* Description of the method's
parameter list. Useful for
debuggers. */
IMP method_imp; /* Address of the method in the
executable. */
} method_list[1]; /* Variable length
structure. */
} MethodList, *MethodList_t;
struct objc_protocol_list {
struct objc_protocol_list *next;
int count;
Protocol *list[1];
};
/*
** This is used to assure consistent access to the info field of
** classes
*/
#ifndef HOST_BITS_PER_LONG
#define HOST_BITS_PER_LONG (sizeof(long)*8)
#endif
#define __CLS_INFO(cls) ((cls)->info)
#define __CLS_ISINFO(cls, mask) ((__CLS_INFO(cls)&mask)==mask)
#define __CLS_SETINFO(cls, mask) (__CLS_INFO(cls) |= mask)
/* The structure is of type MetaClass */
#define _CLS_META 0x2L
#define CLS_ISMETA(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_META))
/* The structure is of type Class */
#define _CLS_CLASS 0x1L
#define CLS_ISCLASS(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_CLASS))
/*
** The class is initialized within the runtime. This means that
** it has had correct super and sublinks assigned
*/
#define _CLS_RESOLV 0x8L
#define CLS_ISRESOLV(cls) __CLS_ISINFO(cls, _CLS_RESOLV)
#define CLS_SETRESOLV(cls) __CLS_SETINFO(cls, _CLS_RESOLV)
/*
** The class has been send a +initialize message or a such is not
** defined for this class
*/
#define _CLS_INITIALIZED 0x04L
#define CLS_ISINITIALIZED(cls) __CLS_ISINFO(cls, _CLS_INITIALIZED)
#define CLS_SETINITIALIZED(cls) __CLS_SETINFO(cls, _CLS_INITIALIZED)
/*
** The class number of this class. This must be the same for both the
** class and its meta class object
*/
#define CLS_GETNUMBER(cls) (__CLS_INFO(cls) >> (HOST_BITS_PER_LONG/2))
#define CLS_SETNUMBER(cls, num) \
({ (cls)->info <<= (HOST_BITS_PER_LONG/2); \
(cls)->info >>= (HOST_BITS_PER_LONG/2); \
__CLS_SETINFO(cls, (((unsigned long)num) << (HOST_BITS_PER_LONG/2))); })
/*
** The compiler generates one of these structures for each category. A class
** may have many categories and contain both instance and factory methods.
*/
typedef struct objc_category {
const char* category_name; /* Name of the category. Name
contained in the () of the
category definition. */
const char* class_name; /* Name of the class to which
the category belongs. */
MethodList_t instance_methods; /* Linked list of instance
methods defined in the
category. NULL indicates no
instance methods defined. */
MethodList_t class_methods; /* Linked list of factory
methods defined in the
category. NULL indicates no
class methods defined. */
struct objc_protocol_list *protocols; /* List of Protocols
conformed to */
} Category, *Category_t;
/*
** Structure used when a message is send to a class's super class. The
** compiler generates one of these structures and passes it to
** objc_msg_super.
*/
typedef struct objc_super {
id self; /* Id of the object sending
the message. */
Class class; /* Object's super class. */
} Super, *Super_t;
IMP objc_msg_lookup_super(Super_t super, SEL sel);
retval_t objc_msg_sendv(id, SEL, arglist_t);
/*
** This is a hook which is called by objc_lookup_class and
** objc_get_class if the runtime is not able to find the class.
** This may e.g. try to load in the class using dynamic loading.
** The function is guaranteed to be passed a non-NULL name string.
*/
extern Class (*_objc_lookup_class)(const char *name);
/*
** This is a hook which is called by __objc_exec_class every time a class
** or a category is loaded into the runtime. This may e.g. help a
** dynamic loader determine the classes that have been loaded when
** an object file is dynamically linked in.
*/
extern void (*_objc_load_callback)(Class class, Category* category);
/*
** Hook functions for allocating, copying and disposing of instances
*/
extern id (*_objc_object_alloc)(Class class);
extern id (*_objc_object_copy)(id object);
extern id (*_objc_object_dispose)(id object);
/*
** Standard functions for memory allocation and disposal.
** Users should use these functions in their ObjC programs so
** that they work properly with garbage collectors as well as
** can take advantage of the exception/error handling available.
*/
void *
objc_malloc(size_t size);
void *
objc_atomic_malloc(size_t size);
void *
objc_valloc(size_t size);
void *
objc_realloc(void *mem, size_t size);
void *
objc_calloc(size_t nelem, size_t size);
void
objc_free(void *mem);
/*
** Hook functions for memory allocation and disposal.
** This makes it easy to substitute garbage collection systems
** such as Boehm's GC by assigning these function pointers
** to the GC's allocation routines. By default these point
** to the ANSI standard malloc, realloc, free, etc.
**
** Users should call the normal objc routines above for
** memory allocation and disposal within their programs.
*/
extern void *(*_objc_malloc)(size_t);
extern void *(*_objc_atomic_malloc)(size_t);
extern void *(*_objc_valloc)(size_t);
extern void *(*_objc_realloc)(void *, size_t);
extern void *(*_objc_calloc)(size_t, size_t);
extern void (*_objc_free)(void *);
Method_t class_get_class_method(MetaClass class, SEL aSel);
Method_t class_get_instance_method(Class class, SEL aSel);
Class class_pose_as(Class impostor, Class superclass);
Class objc_get_class(const char *name);
Class objc_lookup_class(const char *name);
Class objc_next_class(void **enum_state);
const char *sel_get_name(SEL selector);
const char *sel_get_type(SEL selector);
SEL sel_get_uid(const char *name);
SEL sel_get_any_uid(const char *name);
SEL sel_get_any_typed_uid(const char *name);
SEL sel_get_typed_uid(const char *name, const char*);
SEL sel_register_name(const char *name);
SEL sel_register_typed_name(const char *name, const char*type);
BOOL sel_is_mapped (SEL aSel);
extern id class_create_instance(Class class);
static inline const char *
class_get_class_name(Class class)
{
return CLS_ISCLASS(class)?class->name:((class==Nil)?"Nil":0);
}
static inline long
class_get_instance_size(Class class)
{
return CLS_ISCLASS(class)?class->instance_size:0;
}
static inline MetaClass
class_get_meta_class(Class class)
{
return CLS_ISCLASS(class)?class->class_pointer:Nil;
}
static inline Class
class_get_super_class(Class class)
{
return CLS_ISCLASS(class)?class->super_class:Nil;
}
static inline int
class_get_version(Class class)
{
return CLS_ISCLASS(class)?class->version:-1;
}
static inline BOOL
class_is_class(Class class)
{
return CLS_ISCLASS(class);
}
static inline BOOL
class_is_meta_class(Class class)
{
return CLS_ISMETA(class);
}
static inline void
class_set_version(Class class, long version)
{
if (CLS_ISCLASS(class))
class->version = version;
}
static inline IMP
method_get_imp(Method_t method)
{
return (method!=METHOD_NULL)?method->method_imp:(IMP)0;
}
IMP get_imp (Class class, SEL sel);
/* Redefine on NeXTSTEP so as not to conflict with system function */
#ifdef __NeXT__
#define object_copy gnu_object_copy
#define object_dispose gnu_object_dispose
#endif
id object_copy(id object);
id object_dispose(id object);
static inline Class
object_get_class(id object)
{
return ((object!=nil)
? (CLS_ISCLASS(object->class_pointer)
? object->class_pointer
: (CLS_ISMETA(object->class_pointer)
? (Class)object
: Nil))
: Nil);
}
static inline const char *
object_get_class_name(id object)
{
return ((object!=nil)?(CLS_ISCLASS(object->class_pointer)
?object->class_pointer->name
:((Class)object)->name)
:"Nil");
}
static inline MetaClass
object_get_meta_class(id object)
{
return ((object!=nil)?(CLS_ISCLASS(object->class_pointer)
?object->class_pointer->class_pointer
:(CLS_ISMETA(object->class_pointer)
?object->class_pointer
:Nil))
:Nil);
}
static inline Class
object_get_super_class
(id object)
{
return ((object!=nil)?(CLS_ISCLASS(object->class_pointer)
?object->class_pointer->super_class
:(CLS_ISMETA(object->class_pointer)
?((Class)object)->super_class
:Nil))
:Nil);
}
static inline BOOL
object_is_class(id object)
{
return CLS_ISCLASS((Class)object);
}
static inline BOOL
object_is_instance(id object)
{
return (object!=nil)&&CLS_ISCLASS(object->class_pointer);
}
static inline BOOL
object_is_meta_class(id object)
{
return CLS_ISMETA((Class)object);
}
struct sarray*
objc_get_uninstalled_dtable(void);
#endif /* not __objc_api_INCLUDE_GNU */

View file

@ -1,157 +0,0 @@
/* Basic data types for Objective C.
Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#ifndef __objc_INCLUDE_GNU
#define __objc_INCLUDE_GNU
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
/*
** Definition of the boolean type.
*/
#ifdef __vxworks
typedef int BOOL;
#else
typedef unsigned char BOOL;
#endif
#define YES (BOOL)1
#define NO (BOOL)0
/*
** Definition of a selector. Selectors themselves are not unique, but
** the sel_id is a unique identifier.
*/
typedef const struct objc_selector
{
void *sel_id;
const char *sel_types;
} *SEL;
inline static BOOL
sel_eq (SEL s1, SEL s2)
{
if (s1 == 0 || s2 == 0)
return s1 == s2;
else
return s1->sel_id == s2->sel_id;
}
/*
** ObjC uses this typedef for untyped instances.
*/
typedef struct objc_object {
struct objc_class* class_pointer;
} *id;
/*
** Definition of method type. When retrieving the implementation of a
** method, this is type of the pointer returned
*/
typedef id (*IMP)(id, SEL, ...);
/*
** More simple types...
*/
#define nil (id)0 /* id of Nil instance */
#define Nil (Class)0 /* id of Nil class */
typedef char *STR; /* String alias */
/*
** The compiler generates one of these structures for each class.
**
** This structure is the definition for classes.
**
** This structure is generated by the compiler in the executable and used by
** the run-time during normal messaging operations. Therefore some members
** change type. The compiler generates "char* const" and places a string in
** the following member variables: super_class.
*/
typedef struct objc_class *MetaClass;
typedef struct objc_class *Class;
struct objc_class {
MetaClass class_pointer; /* Pointer to the class's
meta class. */
struct objc_class* super_class; /* Pointer to the super
class. NULL for class
Object. */
const char* name; /* Name of the class. */
long version; /* Unknown. */
unsigned long info; /* Bit mask. See class masks
defined above. */
long instance_size; /* Size in bytes of the class.
The sum of the class
definition and all super
class definitions. */
struct objc_ivar_list* ivars; /* Pointer to a structure that
describes the instance
variables in the class
definition. NULL indicates
no instance variables. Does
not include super class
variables. */
struct objc_method_list* methods; /* Linked list of instance
methods defined for the
class. */
struct sarray * dtable; /* Pointer to instance
method dispatch table. */
struct objc_class* subclass_list; /* Subclasses */
struct objc_class* sibling_class;
struct objc_protocol_list *protocols; /* Protocols conformed to */
};
#ifndef __OBJC__
typedef struct objc_protocol {
struct objc_class* class_pointer;
char *protocol_name;
struct objc_protocol_list *protocol_list;
struct objc_method_description_list *instance_methods, *class_methods;
} Protocol;
#else /* __OBJC__ */
@class Protocol;
#endif
typedef void* retval_t; /* return value */
typedef void(*apply_t)(void); /* function pointer */
typedef union {
char *arg_ptr;
char arg_regs[sizeof (char*)];
} *arglist_t; /* argument frame */
IMP objc_msg_lookup(id receiver, SEL op);
#ifdef __cplusplus
}
#endif
#endif /* not __objc_INCLUDE_GNU */

View file

@ -1,92 +0,0 @@
/* GNU Objective C Runtime class related functions
Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2, or (at your option) any later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
GNU CC; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled with
GCC to produce an executable, this does not cause the resulting executable
to be covered by the GNU General Public License. This exception does not
however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */
#include "../tconfig.h" /* include defs of bzero for target */
#include "runtime.h" /* the kitchen sink */
id __objc_object_alloc(Class);
id __objc_object_dispose(id);
id __objc_object_copy(id);
id (*_objc_object_alloc)(Class) = __objc_object_alloc; /* !T:SINGLE */
id (*_objc_object_dispose)(id) = __objc_object_dispose; /* !T:SINGLE */
id (*_objc_object_copy)(id) = __objc_object_copy; /* !T:SINGLE */
id
class_create_instance(Class class)
{
id new = nil;
if (CLS_ISCLASS(class))
new = (*_objc_object_alloc)(class);
if (new!=nil)
{
memset (new, 0, class->instance_size);
new->class_pointer = class;
}
return new;
}
id
object_copy(id object)
{
if ((object!=nil)&&CLS_ISCLASS(object->class_pointer))
return (*_objc_object_copy)(object);
else
return nil;
}
id
object_dispose(id object)
{
if ((object!=nil)&&CLS_ISCLASS(object->class_pointer))
{
if (_objc_object_dispose)
(*_objc_object_dispose)(object);
else
objc_free(object);
}
return nil;
}
id __objc_object_alloc(Class class)
{
return (id)objc_malloc(class->instance_size);
}
id __objc_object_dispose(id object)
{
objc_free(object);
return 0;
}
id __objc_object_copy(id object)
{
id copy = class_create_instance(object->class_pointer);
memcpy(copy, object, object->class_pointer->instance_size);
return copy;
}

View file

@ -1,88 +0,0 @@
/* GNU Objective C Runtime internal declarations
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2, or (at your option) any later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
GNU CC; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled with
GCC to produce an executable, this does not cause the resulting executable
to be covered by the GNU General Public License. This exception does not
however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */
#ifndef __objc_runtime_INCLUDE_GNU
#define __objc_runtime_INCLUDE_GNU
#include <stdarg.h> /* for varargs and va_list's */
#include <stdio.h>
#include <ctype.h>
#include <stddef.h> /* so noone else will get system versions */
#include "assert.h"
#include "objc/objc.h" /* core data types */
#include "objc/objc-api.h" /* runtime api functions */
#include "objc/thr.h" /* thread and mutex support */
#include "objc/hash.h" /* hash structures */
#include "objc/objc-list.h" /* linear lists */
extern void __objc_add_class_to_hash(Class); /* (objc-class.c) */
extern void __objc_init_selector_tables(void); /* (objc-sel.c) */
extern void __objc_init_class_tables(void); /* (objc-class.c) */
extern void __objc_init_dispatch_tables(void); /* (objc-dispatch.c) */
extern void __objc_install_premature_dtable(Class); /* (objc-dispatch.c) */
extern void __objc_resolve_class_links(void); /* (objc-class.c) */
extern void __objc_register_selectors_from_class(Class); /* (objc-sel.c) */
extern void __objc_update_dispatch_table_for_class (Class);/* (objc-msg.c) */
extern int __objc_init_thread_system(void); /* thread.c */
extern int __objc_fini_thread_system(void); /* thread.c */
extern void __objc_print_dtable_stats(void); /* sendmsg.c */
extern void class_add_method_list(Class, MethodList_t);
/* Registering instance methods as class methods for root classes */
extern void __objc_register_instance_methods_to_class(Class);
extern Method_t search_for_method_in_list(MethodList_t list, SEL op);
/* True when class links has been resolved */
extern BOOL __objc_class_links_resolved;
/* Number of selectors stored in each of the selector tables */
extern int __objc_selector_max_index;
/* Mutex locking __objc_selector_max_index and its arrays. */
extern objc_mutex_t __objc_runtime_mutex;
/* Number of threads which are alive. */
extern int __objc_runtime_threads_alive;
#ifdef DEBUG
#define DEBUG_PRINTF(format, args...) printf (format, ## args)
#else
#define DEBUG_PRINTF(format, args...)
#endif
BOOL __objc_responds_to (id object, SEL sel); /* for internal use only! */
SEL __sel_register_typed_name (const char*, const char*,
struct objc_selector*, BOOL is_const);
#endif /* not __objc_runtime_INCLUDE_GNU */

View file

@ -1,522 +0,0 @@
/* Sparse Arrays for Objective C dispatch tables
Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#include "objc/sarray.h"
#include "objc/runtime.h"
#include <stdio.h>
#include "assert.h"
int nbuckets = 0; /* !T:MUTEX */
int nindices = 0; /* !T:MUTEX */
int narrays = 0; /* !T:MUTEX */
int idxsize = 0; /* !T:MUTEX */
static void * first_free_data = NULL; /* !T:MUTEX */
#ifdef OBJC_SPARSE2
const char* __objc_sparse2_id = "2 level sparse indices";
#endif
#ifdef OBJC_SPARSE3
const char* __objc_sparse3_id = "3 level sparse indices";
#endif
#ifdef __alpha__
const void *memcpy (void*, const void*, size_t);
#endif
/* This function removes any structures left over from free operations
that were not safe in a multi-threaded environment. */
void
sarray_remove_garbage(void)
{
void **vp;
void *np;
objc_mutex_lock(__objc_runtime_mutex);
vp = first_free_data;
first_free_data = NULL;
while (vp) {
np = *vp;
objc_free(vp);
vp = np;
}
objc_mutex_unlock(__objc_runtime_mutex);
}
/* Free a block of dynamically allocated memory. If we are in multi-threaded
mode, it is ok to free it. If not, we add it to the garbage heap to be
freed later. */
static void
sarray_free_garbage(void *vp)
{
objc_mutex_lock(__objc_runtime_mutex);
if (__objc_runtime_threads_alive == 1) {
objc_free(vp);
if (first_free_data)
sarray_remove_garbage();
}
else {
*(void **)vp = first_free_data;
first_free_data = vp;
}
objc_mutex_unlock(__objc_runtime_mutex);
}
/* sarray_at_put : copies data in such a way as to be thread reader safe. */
void
sarray_at_put(struct sarray* array, sidx index, void* element)
{
#ifdef OBJC_SPARSE3
struct sindex** the_index;
struct sindex* new_index;
#endif
struct sbucket** the_bucket;
struct sbucket* new_bucket;
#ifdef OBJC_SPARSE3
size_t ioffset;
#endif
size_t boffset;
size_t eoffset;
#ifdef PRECOMPUTE_SELECTORS
union sofftype xx;
xx.idx = index;
#ifdef OBJC_SPARSE3
ioffset = xx.off.ioffset;
#endif
boffset = xx.off.boffset;
eoffset = xx.off.eoffset;
#else /* not PRECOMPUTE_SELECTORS */
#ifdef OBJC_SPARSE3
ioffset = index/INDEX_CAPACITY;
boffset = (index/BUCKET_SIZE)%INDEX_SIZE;
eoffset = index%BUCKET_SIZE;
#else
boffset = index/BUCKET_SIZE;
eoffset = index%BUCKET_SIZE;
#endif
#endif /* not PRECOMPUTE_SELECTORS */
assert(soffset_decode(index) < array->capacity); /* Range check */
#ifdef OBJC_SPARSE3
the_index = &(array->indices[ioffset]);
the_bucket = &((*the_index)->buckets[boffset]);
#else
the_bucket = &(array->buckets[boffset]);
#endif
if ((*the_bucket)->elems[eoffset] == element)
return; /* great! we just avoided a lazy copy */
#ifdef OBJC_SPARSE3
/* First, perform lazy copy/allocation of index if needed */
if ((*the_index) == array->empty_index) {
/* The index was previously empty, allocate a new */
new_index = (struct sindex*)objc_malloc(sizeof(struct sindex));
memcpy(new_index, array->empty_index, sizeof(struct sindex));
new_index->version.version = array->version.version;
*the_index = new_index; /* Prepared for install. */
the_bucket = &((*the_index)->buckets[boffset]);
nindices += 1;
} else if ((*the_index)->version.version != array->version.version) {
/* This index must be lazy copied */
struct sindex* old_index = *the_index;
new_index = (struct sindex*)objc_malloc(sizeof(struct sindex));
memcpy( new_index, old_index, sizeof(struct sindex));
new_index->version.version = array->version.version;
*the_index = new_index; /* Prepared for install. */
the_bucket = &((*the_index)->buckets[boffset]);
nindices += 1;
}
#endif /* OBJC_SPARSE3 */
/* next, perform lazy allocation/copy of the bucket if needed */
if ((*the_bucket) == array->empty_bucket) {
/* The bucket was previously empty (or something like that), */
/* allocate a new. This is the effect of `lazy' allocation */
new_bucket = (struct sbucket*)objc_malloc(sizeof(struct sbucket));
memcpy((void *) new_bucket, (const void*)array->empty_bucket,
sizeof(struct sbucket));
new_bucket->version.version = array->version.version;
*the_bucket = new_bucket; /* Prepared for install. */
nbuckets += 1;
} else if ((*the_bucket)->version.version != array->version.version) {
/* Perform lazy copy. */
struct sbucket* old_bucket = *the_bucket;
new_bucket = (struct sbucket*)objc_malloc(sizeof(struct sbucket));
memcpy( new_bucket, old_bucket, sizeof(struct sbucket));
new_bucket->version.version = array->version.version;
*the_bucket = new_bucket; /* Prepared for install. */
nbuckets += 1;
}
(*the_bucket)->elems[eoffset] = element;
}
void
sarray_at_put_safe(struct sarray* array, sidx index, void* element)
{
if(soffset_decode(index) >= array->capacity)
sarray_realloc(array, soffset_decode(index)+1);
sarray_at_put(array, index, element);
}
struct sarray*
sarray_new (int size, void* default_element)
{
struct sarray* arr;
#ifdef OBJC_SPARSE3
size_t num_indices = ((size-1)/(INDEX_CAPACITY))+1;
struct sindex ** new_indices;
#else /* OBJC_SPARSE2 */
size_t num_indices = ((size-1)/BUCKET_SIZE)+1;
struct sbucket ** new_buckets;
#endif
int counter;
assert(size > 0);
/* Allocate core array */
arr = (struct sarray*) objc_malloc(sizeof(struct sarray));
arr->version.version = 0;
/* Initialize members */
#ifdef OBJC_SPARSE3
arr->capacity = num_indices*INDEX_CAPACITY;
new_indices = (struct sindex**)
objc_malloc(sizeof(struct sindex*)*num_indices);
arr->empty_index = (struct sindex*) objc_malloc(sizeof(struct sindex));
arr->empty_index->version.version = 0;
narrays += 1;
idxsize += num_indices;
nindices += 1;
#else /* OBJC_SPARSE2 */
arr->capacity = num_indices*BUCKET_SIZE;
new_buckets = (struct sbucket**)
objc_malloc(sizeof(struct sbucket*)*num_indices);
narrays += 1;
idxsize += num_indices;
#endif
arr->empty_bucket = (struct sbucket*) objc_malloc(sizeof(struct sbucket));
arr->empty_bucket->version.version = 0;
nbuckets += 1;
arr->ref_count = 1;
arr->is_copy_of = (struct sarray*)0;
for (counter=0; counter<BUCKET_SIZE; counter++)
arr->empty_bucket->elems[counter] = default_element;
#ifdef OBJC_SPARSE3
for (counter=0; counter<INDEX_SIZE; counter++)
arr->empty_index->buckets[counter] = arr->empty_bucket;
for (counter=0; counter<num_indices; counter++)
new_indices[counter] = arr->empty_index;
#else /* OBJC_SPARSE2 */
for (counter=0; counter<num_indices; counter++)
new_buckets[counter] = arr->empty_bucket;
#endif
#ifdef OBJC_SPARSE3
arr->indices = new_indices;
#else /* OBJC_SPARSE2 */
arr->buckets = new_buckets;
#endif
return arr;
}
/* Reallocate the sparse array to hold `newsize' entries
Note: We really allocate and then free. We have to do this to ensure that
any concurrent readers notice the update. */
void
sarray_realloc(struct sarray* array, int newsize)
{
#ifdef OBJC_SPARSE3
size_t old_max_index = (array->capacity-1)/INDEX_CAPACITY;
size_t new_max_index = ((newsize-1)/INDEX_CAPACITY);
size_t rounded_size = (new_max_index+1)*INDEX_CAPACITY;
struct sindex ** new_indices;
struct sindex ** old_indices;
#else /* OBJC_SPARSE2 */
size_t old_max_index = (array->capacity-1)/BUCKET_SIZE;
size_t new_max_index = ((newsize-1)/BUCKET_SIZE);
size_t rounded_size = (new_max_index+1)*BUCKET_SIZE;
struct sbucket ** new_buckets;
struct sbucket ** old_buckets;
#endif
int counter;
assert(newsize > 0);
/* The size is the same, just ignore the request */
if(rounded_size <= array->capacity)
return;
assert(array->ref_count == 1); /* stop if lazy copied... */
/* We are asked to extend the array -- allocate new bucket table, */
/* and insert empty_bucket in newly allocated places. */
if(rounded_size > array->capacity)
{
#ifdef OBJC_SPARSE3
new_max_index += 4;
rounded_size = (new_max_index+1)*INDEX_CAPACITY;
#else /* OBJC_SPARSE2 */
new_max_index += 4;
rounded_size = (new_max_index+1)*BUCKET_SIZE;
#endif
/* update capacity */
array->capacity = rounded_size;
#ifdef OBJC_SPARSE3
/* alloc to force re-read by any concurrent readers. */
old_indices = array->indices;
new_indices = (struct sindex**)
objc_malloc((new_max_index+1)*sizeof(struct sindex*));
#else /* OBJC_SPARSE2 */
old_buckets = array->buckets;
new_buckets = (struct sbucket**)
objc_malloc((new_max_index+1)*sizeof(struct sbucket*));
#endif
/* copy buckets below old_max_index (they are still valid) */
for(counter = 0; counter <= old_max_index; counter++ ) {
#ifdef OBJC_SPARSE3
new_indices[counter] = old_indices[counter];
#else /* OBJC_SPARSE2 */
new_buckets[counter] = old_buckets[counter];
#endif
}
#ifdef OBJC_SPARSE3
/* reset entries above old_max_index to empty_bucket */
for(counter = old_max_index+1; counter <= new_max_index; counter++)
new_indices[counter] = array->empty_index;
#else /* OBJC_SPARSE2 */
/* reset entries above old_max_index to empty_bucket */
for(counter = old_max_index+1; counter <= new_max_index; counter++)
new_buckets[counter] = array->empty_bucket;
#endif
#ifdef OBJC_SPARSE3
/* install the new indices */
array->indices = new_indices;
#else /* OBJC_SPARSE2 */
array->buckets = new_buckets;
#endif
#ifdef OBJC_SPARSE3
/* free the old indices */
sarray_free_garbage(old_indices);
#else /* OBJC_SPARSE2 */
sarray_free_garbage(old_buckets);
#endif
idxsize += (new_max_index-old_max_index);
return;
}
}
/* Free a sparse array allocated with sarray_new */
void
sarray_free(struct sarray* array) {
#ifdef OBJC_SPARSE3
size_t old_max_index = (array->capacity-1)/INDEX_CAPACITY;
struct sindex ** old_indices;
#else
size_t old_max_index = (array->capacity-1)/BUCKET_SIZE;
struct sbucket ** old_buckets;
#endif
int counter = 0;
assert(array->ref_count != 0); /* Freed multiple times!!! */
if(--(array->ref_count) != 0) /* There exists copies of me */
return;
#ifdef OBJC_SPARSE3
old_indices = array->indices;
#else
old_buckets = array->buckets;
#endif
if((array->is_copy_of) && ((array->is_copy_of->ref_count - 1) == 0))
sarray_free(array->is_copy_of);
/* Free all entries that do not point to empty_bucket */
for(counter = 0; counter <= old_max_index; counter++ ) {
#ifdef OBJC_SPARSE3
struct sindex* idx = old_indices[counter];
if((idx != array->empty_index) &&
(idx->version.version == array->version.version)) {
int c2;
for(c2=0; c2<INDEX_SIZE; c2++) {
struct sbucket* bkt = idx->buckets[c2];
if((bkt != array->empty_bucket) &&
(bkt->version.version == array->version.version))
{
sarray_free_garbage(bkt);
nbuckets -= 1;
}
}
sarray_free_garbage(idx);
nindices -= 1;
}
#else /* OBJC_SPARSE2 */
struct sbucket* bkt = array->buckets[counter];
if ((bkt != array->empty_bucket) &&
(bkt->version.version == array->version.version))
{
sarray_free_garbage(bkt);
nbuckets -= 1;
}
#endif
}
#ifdef OBJC_SPARSE3
/* free empty_index */
if(array->empty_index->version.version == array->version.version) {
sarray_free_garbage(array->empty_index);
nindices -= 1;
}
#endif
/* free empty_bucket */
if(array->empty_bucket->version.version == array->version.version) {
sarray_free_garbage(array->empty_bucket);
nbuckets -= 1;
}
idxsize -= (old_max_index+1);
narrays -= 1;
#ifdef OBJC_SPARSE3
/* free bucket table */
sarray_free_garbage(array->indices);
#else
/* free bucket table */
sarray_free_garbage(array->buckets);
#endif
/* free array */
sarray_free_garbage(array);
}
/* This is a lazy copy. Only the core of the structure is actually */
/* copied. */
struct sarray*
sarray_lazy_copy(struct sarray* oarr)
{
struct sarray* arr;
#ifdef OBJC_SPARSE3
size_t num_indices = ((oarr->capacity-1)/INDEX_CAPACITY)+1;
struct sindex ** new_indices;
#else /* OBJC_SPARSE2 */
size_t num_indices = ((oarr->capacity-1)/BUCKET_SIZE)+1;
struct sbucket ** new_buckets;
#endif
/* Allocate core array */
arr = (struct sarray*) objc_malloc(sizeof(struct sarray)); /* !!! */
arr->version.version = oarr->version.version + 1;
#ifdef OBJC_SPARSE3
arr->empty_index = oarr->empty_index;
#endif
arr->empty_bucket = oarr->empty_bucket;
arr->ref_count = 1;
oarr->ref_count += 1;
arr->is_copy_of = oarr;
arr->capacity = oarr->capacity;
#ifdef OBJC_SPARSE3
/* Copy bucket table */
new_indices = (struct sindex**)
objc_malloc(sizeof(struct sindex*)*num_indices);
memcpy( new_indices,oarr->indices,
sizeof(struct sindex*)*num_indices);
arr->indices = new_indices;
#else
/* Copy bucket table */
new_buckets = (struct sbucket**)
objc_malloc(sizeof(struct sbucket*)*num_indices);
memcpy( new_buckets,oarr->buckets,
sizeof(struct sbucket*)*num_indices);
arr->buckets = new_buckets;
#endif
idxsize += num_indices;
narrays += 1;
return arr;
}

View file

@ -1,237 +0,0 @@
/* Sparse Arrays for Objective C dispatch tables
Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#ifndef __sarray_INCLUDE_GNU
#define __sarray_INCLUDE_GNU
#define OBJC_SPARSE2 /* 2-level sparse array */
/* #define OBJC_SPARSE3 */ /* 3-level sparse array */
#ifdef OBJC_SPARSE2
extern const char* __objc_sparse2_id;
#endif
#ifdef OBJC_SPARSE3
extern const char* __objc_sparse3_id;
#endif
#include <stddef.h>
#include "objc/thr.h"
extern int nbuckets; /* for stats */
extern int nindices;
extern int narrays;
extern int idxsize;
#include <assert.h>
/* An unsigned integer of same size as a pointer */
#define SIZET_BITS (sizeof(size_t)*8)
#if defined(__sparc__) || defined(OBJC_SPARSE2)
#define PRECOMPUTE_SELECTORS
#endif
#ifdef OBJC_SPARSE3
/* Buckets are 8 words each */
#define BUCKET_BITS 3
#define BUCKET_SIZE (1<<BUCKET_BITS)
#define BUCKET_MASK (BUCKET_SIZE-1)
/* Indices are 16 words each */
#define INDEX_BITS 4
#define INDEX_SIZE (1<<INDEX_BITS)
#define INDEX_MASK (INDEX_SIZE-1)
#define INDEX_CAPACITY (BUCKET_SIZE*INDEX_SIZE)
#else /* OBJC_SPARSE2 */
/* Buckets are 32 words each */
#define BUCKET_BITS 5
#define BUCKET_SIZE (1<<BUCKET_BITS)
#define BUCKET_MASK (BUCKET_SIZE-1)
#endif /* OBJC_SPARSE2 */
typedef size_t sidx;
#ifdef PRECOMPUTE_SELECTORS
struct soffset {
#ifdef OBJC_SPARSE3
unsigned int unused : SIZET_BITS/4;
unsigned int eoffset : SIZET_BITS/4;
unsigned int boffset : SIZET_BITS/4;
unsigned int ioffset : SIZET_BITS/4;
#else /* OBJC_SPARSE2 */
#ifdef __sparc__
unsigned int boffset : (SIZET_BITS - 2) - BUCKET_BITS;
unsigned int eoffset : BUCKET_BITS;
unsigned int unused : 2;
#else
unsigned int boffset : SIZET_BITS/2;
unsigned int eoffset : SIZET_BITS/2;
#endif
#endif /* OBJC_SPARSE2 */
};
union sofftype {
struct soffset off;
sidx idx;
};
#endif /* not PRECOMPUTE_SELECTORS */
union sversion {
int version;
void *next_free;
};
struct sbucket {
void* elems[BUCKET_SIZE]; /* elements stored in array */
union sversion version; /* used for copy-on-write */
};
#ifdef OBJC_SPARSE3
struct sindex {
struct sbucket* buckets[INDEX_SIZE];
union sversion version; /* used for copy-on-write */
};
#endif /* OBJC_SPARSE3 */
struct sarray {
#ifdef OBJC_SPARSE3
struct sindex** indices;
struct sindex* empty_index;
#else /* OBJC_SPARSE2 */
struct sbucket** buckets;
#endif /* OBJC_SPARSE2 */
struct sbucket* empty_bucket;
union sversion version; /* used for copy-on-write */
short ref_count;
struct sarray* is_copy_of;
size_t capacity;
};
struct sarray* sarray_new(int, void* default_element);
void sarray_free(struct sarray*);
struct sarray* sarray_lazy_copy(struct sarray*);
void sarray_realloc(struct sarray*, int new_size);
void sarray_at_put(struct sarray*, sidx index, void* elem);
void sarray_at_put_safe(struct sarray*, sidx index, void* elem);
struct sarray* sarray_hard_copy(struct sarray*); /* ... like the name? */
void sarray_remove_garbage(void);
#ifdef PRECOMPUTE_SELECTORS
/* Transform soffset values to ints and vica verca */
static inline unsigned int
soffset_decode(sidx index)
{
union sofftype x;
x.idx = index;
#ifdef OBJC_SPARSE3
return x.off.eoffset
+ (x.off.boffset*BUCKET_SIZE)
+ (x.off.ioffset*INDEX_CAPACITY);
#else /* OBJC_SPARSE2 */
return x.off.eoffset + (x.off.boffset*BUCKET_SIZE);
#endif /* OBJC_SPARSE2 */
}
static inline sidx
soffset_encode(size_t offset)
{
union sofftype x;
x.off.eoffset = offset%BUCKET_SIZE;
#ifdef OBJC_SPARSE3
x.off.boffset = (offset/BUCKET_SIZE)%INDEX_SIZE;
x.off.ioffset = offset/INDEX_CAPACITY;
#else /* OBJC_SPARSE2 */
x.off.boffset = offset/BUCKET_SIZE;
#endif
return (sidx)x.idx;
}
#else /* not PRECOMPUTE_SELECTORS */
static inline size_t
soffset_decode(sidx index)
{
return index;
}
static inline sidx
soffset_encode(size_t offset)
{
return offset;
}
#endif /* not PRECOMPUTE_SELECTORS */
/* Get element from the Sparse array `array' at offset `index' */
static inline void* sarray_get(struct sarray* array, sidx index)
{
#ifdef PRECOMPUTE_SELECTORS
union sofftype x;
x.idx = index;
#ifdef OBJC_SPARSE3
return
array->
indices[x.off.ioffset]->
buckets[x.off.boffset]->
elems[x.off.eoffset];
#else /* OBJC_SPARSE2 */
return array->buckets[x.off.boffset]->elems[x.off.eoffset];
#endif /* OBJC_SPARSE2 */
#else /* not PRECOMPUTE_SELECTORS */
#ifdef OBJC_SPARSE3
return array->
indices[index/INDEX_CAPACITY]->
buckets[(index/BUCKET_SIZE)%INDEX_SIZE]->
elems[index%BUCKET_SIZE];
#else /* OBJC_SPARSE2 */
return array->buckets[index/BUCKET_SIZE]->elems[index%BUCKET_SIZE];
#endif /* not OBJC_SPARSE3 */
#endif /* not PRECOMPUTE_SELECTORS */
}
static inline void* sarray_get_safe(struct sarray* array, sidx index)
{
if(soffset_decode(index) < array->capacity)
return sarray_get(array, index);
else
return (array->empty_bucket->elems[0]);
}
#endif /* __sarray_INCLUDE_GNU */

View file

@ -1,458 +0,0 @@
/* GNU Objective C Runtime selector related functions
Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2, or (at your option) any later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
GNU CC; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled with
GCC to produce an executable, this does not cause the resulting executable
to be covered by the GNU General Public License. This exception does not
however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */
#include "runtime.h"
#include "objc/sarray.h"
#include "encoding.h"
/* Initial selector hash table size. Value doesn't matter much */
#define SELECTOR_HASH_SIZE 128
/* Tables mapping selector names to uid and opposite */
static struct sarray* __objc_selector_array = 0; /* uid -> sel !T:MUTEX */
static struct sarray* __objc_selector_names = 0; /* uid -> name !T:MUTEX */
static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */
static void register_selectors_from_list(MethodList_t);
/* Number of selectors stored in each of the above tables */
int __objc_selector_max_index = 0; /* !T:MUTEX */
void __objc_init_selector_tables()
{
__objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0);
__objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0);
__objc_selector_hash
= hash_new (SELECTOR_HASH_SIZE,
(hash_func_type) hash_string,
(compare_func_type) compare_strings);
}
/* This routine is given a class and records all of the methods in its class
structure in the record table. */
void
__objc_register_selectors_from_class (Class class)
{
MethodList_t method_list;
method_list = class->methods;
while (method_list)
{
register_selectors_from_list (method_list);
method_list = method_list->method_next;
}
}
/* This routine is given a list of methods and records each of the methods in
the record table. This is the routine that does the actual recording
work.
This one is only called for Class objects. For categories,
class_add_method_list is called.
*/
static void
register_selectors_from_list (MethodList_t method_list)
{
int i = 0;
while (i < method_list->method_count)
{
Method_t method = &method_list->method_list[i];
method->method_name
= sel_register_typed_name ((const char*)method->method_name,
method->method_types);
i += 1;
}
}
/* Register instance methods as class methods for root classes */
void __objc_register_instance_methods_to_class(Class class)
{
MethodList_t method_list;
MethodList_t class_method_list;
int max_methods_no = 16;
MethodList_t new_list;
Method_t curr_method;
/* Only if a root class. */
if(class->super_class)
return;
/* Allocate a method list to hold the new class methods */
new_list = objc_calloc(sizeof(struct objc_method_list)
+ sizeof(struct objc_method[max_methods_no]), 1);
method_list = class->methods;
class_method_list = class->class_pointer->methods;
curr_method = &new_list->method_list[0];
/* Iterate through the method lists for the class */
while (method_list)
{
int i;
/* Iterate through the methods from this method list */
for (i = 0; i < method_list->method_count; i++)
{
Method_t mth = &method_list->method_list[i];
if (mth->method_name
&& !search_for_method_in_list (class_method_list,
mth->method_name))
{
/* This instance method isn't a class method.
Add it into the new_list. */
*curr_method = *mth;
/* Reallocate the method list if necessary */
if(++new_list->method_count == max_methods_no)
new_list =
objc_realloc(new_list, sizeof(struct objc_method_list)
+ sizeof(struct
objc_method[max_methods_no += 16]));
curr_method = &new_list->method_list[new_list->method_count];
}
}
method_list = method_list->method_next;
}
/* If we created any new class methods
then attach the method list to the class */
if (new_list->method_count)
{
new_list =
objc_realloc(new_list, sizeof(struct objc_method_list)
+ sizeof(struct objc_method[new_list->method_count]));
new_list->method_next = class->class_pointer->methods;
class->class_pointer->methods = new_list;
}
__objc_update_dispatch_table_for_class (class->class_pointer);
}
/* Returns YES iff t1 and t2 have same method types, but we ignore
the argframe layout */
BOOL
sel_types_match (const char* t1, const char* t2)
{
if (!t1 || !t2)
return NO;
while (*t1 && *t2)
{
if (*t1 == '+') t1++;
if (*t2 == '+') t2++;
while (isdigit(*t1)) t1++;
while (isdigit(*t2)) t2++;
/* xxx Remove these next two lines when qualifiers are put in
all selectors, not just Protocol selectors. */
t1 = objc_skip_type_qualifiers(t1);
t2 = objc_skip_type_qualifiers(t2);
if (!*t1 && !*t2)
return YES;
if (*t1 != *t2)
return NO;
t1++;
t2++;
}
return NO;
}
/* return selector representing name */
SEL
sel_get_typed_uid (const char *name, const char *types)
{
struct objc_list *l;
sidx i;
objc_mutex_lock(__objc_runtime_mutex);
i = (sidx) hash_value_for_key (__objc_selector_hash, name);
if (i == 0)
{
objc_mutex_unlock(__objc_runtime_mutex);
return 0;
}
for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i);
l; l = l->tail)
{
SEL s = (SEL)l->head;
if (types == 0 || s->sel_types == 0)
{
if (s->sel_types == types)
{
objc_mutex_unlock(__objc_runtime_mutex);
return s;
}
}
else if (sel_types_match (s->sel_types, types))
{
objc_mutex_unlock(__objc_runtime_mutex);
return s;
}
}
objc_mutex_unlock(__objc_runtime_mutex);
return 0;
}
/* Return selector representing name; prefer a selector with non-NULL type */
SEL
sel_get_any_typed_uid (const char *name)
{
struct objc_list *l;
sidx i;
SEL s = NULL;
objc_mutex_lock(__objc_runtime_mutex);
i = (sidx) hash_value_for_key (__objc_selector_hash, name);
if (i == 0)
{
objc_mutex_unlock(__objc_runtime_mutex);
return 0;
}
for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i);
l; l = l->tail)
{
s = (SEL) l->head;
if (s->sel_types)
{
objc_mutex_unlock(__objc_runtime_mutex);
return s;
}
}
objc_mutex_unlock(__objc_runtime_mutex);
return s;
}
/* return selector representing name */
SEL
sel_get_any_uid (const char *name)
{
struct objc_list *l;
sidx i;
objc_mutex_lock(__objc_runtime_mutex);
i = (sidx) hash_value_for_key (__objc_selector_hash, name);
if (soffset_decode (i) == 0)
{
objc_mutex_unlock(__objc_runtime_mutex);
return 0;
}
l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i);
objc_mutex_unlock(__objc_runtime_mutex);
if (l == 0)
return 0;
return (SEL)l->head;
}
/* return selector representing name */
SEL
sel_get_uid (const char *name)
{
return sel_register_typed_name (name, 0);
}
/* Get name of selector. If selector is unknown, the empty string ""
is returned */
const char*
sel_get_name (SEL selector)
{
const char *ret;
objc_mutex_lock(__objc_runtime_mutex);
if ((soffset_decode((sidx)selector->sel_id) > 0)
&& (soffset_decode((sidx)selector->sel_id) <= __objc_selector_max_index))
ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id);
else
ret = 0;
objc_mutex_unlock(__objc_runtime_mutex);
return ret;
}
BOOL
sel_is_mapped (SEL selector)
{
unsigned int idx = soffset_decode ((sidx)selector->sel_id);
return ((idx > 0) && (idx <= __objc_selector_max_index));
}
const char*
sel_get_type (SEL selector)
{
if (selector)
return selector->sel_types;
else
return 0;
}
/* The uninstalled dispatch table */
extern struct sarray* __objc_uninstalled_dtable;
/* Store the passed selector name in the selector record and return its
selector value (value returned by sel_get_uid).
Assumes that the calling function has locked down __objc_runtime_mutex. */
/* is_const parameter tells us if the name and types parameters
are really constant or not. If YES then they are constant and
we can just store the pointers. If NO then we need to copy
name and types because the pointers may disappear later on. */
SEL
__sel_register_typed_name (const char *name, const char *types,
struct objc_selector *orig, BOOL is_const)
{
struct objc_selector* j;
sidx i;
struct objc_list *l;
i = (sidx) hash_value_for_key (__objc_selector_hash, name);
if (soffset_decode (i) != 0)
{
for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i);
l; l = l->tail)
{
SEL s = (SEL)l->head;
if (types == 0 || s->sel_types == 0)
{
if (s->sel_types == types)
{
if (orig)
{
orig->sel_id = (void*)i;
return orig;
}
else
return s;
}
}
else if (!strcmp (s->sel_types, types))
{
if (orig)
{
orig->sel_id = (void*)i;
return orig;
}
else
return s;
}
}
if (orig)
j = orig;
else
j = objc_malloc (sizeof (struct objc_selector));
j->sel_id = (void*)i;
/* Can we use the pointer or must copy types? Don't copy if NULL */
if ((is_const) || (types == 0))
j->sel_types = (const char*)types;
else {
j->sel_types = (char *) objc_malloc(strlen(types)+1);
strcpy((char *)j->sel_types, types);
}
l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i);
}
else
{
__objc_selector_max_index += 1;
i = soffset_encode(__objc_selector_max_index);
if (orig)
j = orig;
else
j = objc_malloc (sizeof (struct objc_selector));
j->sel_id = (void*)i;
/* Can we use the pointer or must copy types? Don't copy if NULL */
if ((is_const) || (types == 0))
j->sel_types = (const char*)types;
else {
j->sel_types = (char *) objc_malloc(strlen(types)+1);
strcpy((char *)j->sel_types, types);
}
l = 0;
}
DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types,
soffset_decode (i));
{
int is_new = (l == 0);
const char *new_name;
/* Can we use the pointer or must copy name? Don't copy if NULL */
if ((is_const) || (name == 0))
new_name = name;
else {
new_name = (char *) objc_malloc(strlen(name)+1);
strcpy((char *)new_name, name);
}
l = list_cons ((void*)j, l);
sarray_at_put_safe (__objc_selector_names, i, (void *) new_name);
sarray_at_put_safe (__objc_selector_array, i, (void *) l);
if (is_new)
hash_add (&__objc_selector_hash, (void *) new_name, (void *) i);
}
sarray_realloc(__objc_uninstalled_dtable, __objc_selector_max_index+1);
return (SEL) j;
}
SEL
sel_register_name (const char *name)
{
SEL ret;
objc_mutex_lock(__objc_runtime_mutex);
/* Assume that name is not constant static memory and needs to be
copied before put into a runtime structure. is_const == NO */
ret = __sel_register_typed_name (name, 0, 0, NO);
objc_mutex_unlock(__objc_runtime_mutex);
return ret;
}
SEL
sel_register_typed_name (const char *name, const char *type)
{
SEL ret;
objc_mutex_lock(__objc_runtime_mutex);
/* Assume that name and type are not constant static memory and need to
be copied before put into a runtime structure. is_const == NO */
ret = __sel_register_typed_name (name, type, 0, NO);
objc_mutex_unlock(__objc_runtime_mutex);
return ret;
}

View file

@ -1,132 +0,0 @@
/* GNU Objective-C Typed Streams interface.
Copyright (C) 1993, 1995 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU CC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files compiled
with GCC to produce an executable, this does not cause the resulting
executable to be covered by the GNU General Public License. This
exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License. */
#ifndef __typedstream_INCLUDE_GNU
#define __typedstream_INCLUDE_GNU
#include "objc/objc.h"
#include "objc/hash.h"
#include <stdio.h>
typedef int (*objc_typed_read_func)(void*, char*, int);
typedef int (*objc_typed_write_func)(void*, const char*, int);
typedef int (*objc_typed_flush_func)(void*);
typedef int (*objc_typed_eof_func)(void*);
#define OBJC_READONLY 0x01
#define OBJC_WRITEONLY 0x02
#define OBJC_MANAGED_STREAM 0x01
#define OBJC_FILE_STREAM 0x02
#define OBJC_MEMORY_STREAM 0x04
#define OBJC_TYPED_STREAM_VERSION 0x01
typedef struct objc_typed_stream {
void* physical;
cache_ptr object_table; /* read/written objects */
cache_ptr stream_table; /* other read/written but shared things.. */
cache_ptr class_table; /* class version mapping */
cache_ptr object_refs; /* forward references */
int mode; /* OBJC_READONLY or OBJC_WRITEONLY */
int type; /* MANAGED, FILE, MEMORY etc bit string */
int version; /* version used when writing */
int writing_root_p;
objc_typed_read_func read;
objc_typed_write_func write;
objc_typed_eof_func eof;
objc_typed_flush_func flush;
} TypedStream;
/* opcode masks */
#define _B_VALUE 0x1fU
#define _B_CODE 0xe0U
#define _B_SIGN 0x10U
#define _B_NUMBER 0x0fU
/* standard opcodes */
#define _B_INVALID 0x00U
#define _B_SINT 0x20U
#define _B_NINT 0x40U
#define _B_SSTR 0x60U
#define _B_NSTR 0x80U
#define _B_RCOMM 0xa0U
#define _B_UCOMM 0xc0U
#define _B_EXT 0xe0U
/* eXtension opcodes */
#define _BX_OBJECT 0x00U
#define _BX_CLASS 0x01U
#define _BX_SEL 0x02U
#define _BX_OBJREF 0x03U
#define _BX_OBJROOT 0x04U
#define _BX_EXT 0x1fU
/*
** Read and write objects as specified by TYPE. All the `last'
** arguments are pointers to the objects to read/write.
*/
int objc_write_type (TypedStream* stream, const char* type, const void* data);
int objc_read_type (TypedStream* stream, const char* type, void* data);
int objc_write_types (TypedStream* stream, const char* type, ...);
int objc_read_types (TypedStream* stream, const char* type, ...);
int objc_write_object_reference (TypedStream* stream, id object);
int objc_write_root_object (TypedStream* stream, id object);
long objc_get_stream_class_version (TypedStream* stream, Class class);
/*
** Convenience functions
*/
int objc_write_array (TypedStream* stream, const char* type,
int count, const void* data);
int objc_read_array (TypedStream* stream, const char* type,
int count, void* data);
int objc_write_object (TypedStream* stream, id object);
int objc_read_object (TypedStream* stream, id* object);
/*
** Open a typed stream for reading or writing. MODE may be either of
** OBJC_READONLY or OBJC_WRITEONLY.
*/
TypedStream* objc_open_typed_stream (FILE* physical, int mode);
TypedStream* objc_open_typed_stream_for_file (const char* file_name, int mode);
void objc_close_typed_stream (TypedStream* stream);
BOOL objc_end_of_typed_stream (TypedStream* stream);
void objc_flush_typed_stream (TypedStream* stream);
#endif /* not __typedstream_INCLUDE_GNU */

View file

@ -1,25 +0,0 @@
# Use the libio which comes with the local libc.
# Comment this out to avoid including the stdio functions in libiostream.a:
# LIBIOSTREAM_OBJECTS = $(IO_OBJECTS) $(IOSTREAM_OBJECTS) $(STDIO_WRAP_OBJECTS) $(OSPRIM_OBJECTS)
# LIBIOSTREAM_DEP = $(LIBIOSTREAM_OBJECTS) stdio.list
# LIBIOSTREAM_USE = $(LIBIOSTREAM_OBJECTS) `cat stdio.list`
# Comment the above and uncomment the below to use the code in the Linux libc:
# We have _G_config.h in /usr/include.
_G_CONFIG_H=
# We must not see the libio.h file from this library.
LIBIO_INCLUDE=
# We have those in libc.a.
IO_OBJECTS= iogetline.o
STDIO_WRAP_OBJECTS=
OSPRIM_OBJECTS=
STDIO_OBJECTS=
# We have the rest in /usr/include.
USER_INCLUDES=PlotFile.h SFile.h builtinbuf.h editbuf.h fstream.h \
indstream.h iomanip.h iostream.h istream.h ostream.h \
parsestream.h pfstream.h procbuf.h stdiostream.h stream.h \
streambuf.h strfile.h strstream.h

View file

@ -1,25 +0,0 @@
# Use the libio which comes with the local libc.
# Comment this out to avoid including the stdio functions in libiostream.a:
# LIBIOSTREAM_OBJECTS = $(IO_OBJECTS) $(IOSTREAM_OBJECTS) $(STDIO_WRAP_OBJECTS) $(OSPRIM_OBJECTS)
# LIBIOSTREAM_DEP = $(LIBIOSTREAM_OBJECTS) stdio.list
# LIBIOSTREAM_USE = $(LIBIOSTREAM_OBJECTS) `cat stdio.list`
# Comment the above and uncomment the below to use the code in the Linux libc:
# We have _G_config.h in /usr/include.
_G_CONFIG_H=
# We must not see the libio.h file from this library.
LIBIO_INCLUDE=
# We have those in libc.a.
IO_OBJECTS= iogetline.o
STDIO_WRAP_OBJECTS=
OSPRIM_OBJECTS=
STDIO_OBJECTS=
# We have the rest in /usr/include.
USER_INCLUDES=PlotFile.h SFile.h builtinbuf.h editbuf.h fstream.h \
indstream.h iomanip.h iostream.h istream.h ostream.h \
parsestream.h pfstream.h procbuf.h stdiostream.h stream.h \
streambuf.h strfile.h strstream.h

View file

@ -1,20 +0,0 @@
# Flags to pass to gen-params when building _G_config.h.
# For example: G_CONFIG_ARGS = size_t="unsigned long"
G_CONFIG_ARGS = DOLLAR_IN_LABEL=1
#
# gen-params tries to determine whether or not printf_fp exists by
# simply compiling a test program. Since MPE is by definition a
# shared runtime environment, this won't work unless the resulting
# program is run. Simply run _G_config.h through a sed script to
# update the values accordingly.
#
_G_CONFIG_H = stmp-Gconfig
stmp-Gconfig: _G_config.h
sed -e "s/_G_HAVE_PRINTF_FP 1/_G_HAVE_PRINTF_FP 0/" \
-e "s/_G_HAVE_LONG_DOUBLE_IO 1/_G_HAVE_LONG_DOUBLE_IO 0/" \
<_G_config.h > tmp-config.h
mv -f tmp-config.h _G_config.h
touch stmp-Gconfig
$(MAKE) $(FLAGS_TO_PASS) _G_CONFIG_H=_G_config.h all

View file

@ -1,3 +0,0 @@
# Flags to pass to gen-params when building _G_config.h.
# For example: G_CONFIG_ARGS = size_t="unsigned long"
G_CONFIG_ARGS = MATH_H_INLINES=1

View file

@ -1 +0,0 @@
G_CONFIG_ARGS = HAVE_PRINTF_FP=0 HAVE_LONG_DOUBLE_IO=0

View file

@ -1,4 +0,0 @@
LIBS = $(ARLIB) $(ARLINK) $(SHLIB) mshlink $(SHLINK)
SHFLAGS = -Wl,-soname,$(MSHLINK)
DEPLIBS = ../$(SHLIB)
SHOPT = -nostart