From 43815d1720d15b62761a83e971820038b212e796 Mon Sep 17 00:00:00 2001 From: Andrew McCallum Date: Sat, 7 Sep 1996 19:43:29 +0000 Subject: [PATCH] New file. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1713 72102866-910b-0410-8b05-ffd578937521 --- gcc-2.7.2-objc.diff | 16756 ++++++++++++++++++++++++++++++++++++++++ gcc-2.7.2.1-objc.diff | 14388 ++++++++++++++++++++++++++++++++++ 2 files changed, 31144 insertions(+) create mode 100644 gcc-2.7.2-objc.diff create mode 100644 gcc-2.7.2.1-objc.diff diff --git a/gcc-2.7.2-objc.diff b/gcc-2.7.2-objc.diff new file mode 100644 index 000000000..e2c09dffb --- /dev/null +++ b/gcc-2.7.2-objc.diff @@ -0,0 +1,16756 @@ +Changes for GCC version 2.7.2 and Objective-C runtime snapshot 960906. +These include the patches for GCC version 2.7.2.1 as well. + +Go to the directory gcc-2.7.2 and perform these steps + + rm objc/list.h + +Then use this command + + patch -p1 + +feeding it the following diffs as input. + +diff -rcP gcc-2.7.2/ChangeLog gcc-2.7.2.1-objc-960906/ChangeLog +*** gcc-2.7.2/ChangeLog Fri Sep 6 14:24:48 1996 +--- gcc-2.7.2.1-objc-960906/ChangeLog Fri Sep 6 10:23:44 1996 +*************** +*** 1,3 **** +--- 1,448 ---- ++ Thu Sep 5 19:09:27 1996 Ovidiu Predescu ++ ++ * objc-act.c (encode_aggregate_within): New function. ++ (encode_aggregate): Generates encodings for unions similar ++ to those for structs except surrounded by parenthesis instead ++ of braces. ++ ++ Thu Sep 5 10:24:36 1996 Scott Christley ++ ++ Major reorganization of objc error handling. ++ * objc/Object.m (-error:): Call objc_error function instead of ++ using function pointer. ++ * objc/archive.c: Replace call to abort or __objc_fatal functions ++ with call to objc_error function throughout the complete file. ++ * objc/class.c (objc_get_class): Replace call to abort function ++ with call to objc_error function. ++ * objc/encoding.c (objc_sizeof_type, objc_alignof_type): Replace ++ call to abort function with call to objc_error function. ++ (objc_skip_typespec): Likewise. ++ * objc/init.c (init_check_module_version): Replace call to ++ abort function with call to objc_error function. ++ * objc/misc.c (objc_verror): New function. ++ (objc_fatal): Remove function. ++ (objc_set_error_handler): New function. ++ (_objc_error_handler): New global variable. ++ (__alpha__): Remove unneeded code. ++ (objc_error): Allow user specified error handler function to ++ trap and handle the objc error. Added an error code parameter ++ which indicates the specific error that occured. ++ (objc_malloc, objc_atomic_malloc): Replace call to objc_fatal ++ function with call to objc_error function. ++ (objc_valloc, objc_realloc, objc_calloc): Likewise. ++ * objc/objc-api.h: Declare error handling functions and typedef ++ for user specified error handler function. Define error codes ++ used by the runtime library. ++ * objc/runtime.h: Remove error handling declarations. ++ * objc/sendmsg.c (__objc_forward): Replace call to abort function ++ with call to objc_error function. ++ ++ Mon Aug 26 12:36:16 1996 Scott Christley ++ ++ * install.texi: Add instructions for the Objective-C runtime ++ library regarding thread support. ++ ++ Mon Aug 26 11:17:32 1996 Thomas Baier ++ ++ * objc/hash.c (hash_delete): Step through the hash nodes ++ versus using hash_next to increase efficiency. ++ * objc/archive.c (__objc_finish_read_root_object): Use hash ++ table instead of list. ++ ++ Thu Aug 8 08:56:05 1996 Scott Christley ++ ++ Create consistent mechanism for memory allocation and release ++ so that garbage collection routines can be easily subsititued ++ for the ANSI standard malloc, realloc, free, etc. ++ * objc/archive.c: Replace use of __objc_xmalloc and free ++ with objc_malloc and objc_free. ++ * objc/hash.c: Replace use of __objc_xcalloc and free ++ with objc_calloc and objc_free. ++ * objc/init.c: Replace use of free with objc_free. ++ * objc/misc.c (objc_malloc): Renamed from __objc_xmalloc. ++ (objc_realloc): Renamed from __objc_realloc. ++ (objc_atomic_malloc): New function. ++ (objc_valloc): New function. ++ (objc_calloc): Renamed from __objc_calloc. ++ (objc_free): New function. ++ * objc/objc-api.h (_objc_malloc): New function pointer. ++ (_objc_atomic_malloc, _objc_valloc): Likewise. ++ (_objc_realloc, _objc_calloc, _objc_free): Likewise ++ * objc/objc-list.h: Replace use of __obj_xmalloc and free ++ with objc_malloc and objc_free. ++ * objc/objects.c: Likewise. ++ * objc/runtime.h (__objc_xmalloc): Delete. ++ (__objc_xrealloc, __objc_xcalloc): Delete. ++ * objc/sarray.c: Replace use of __objc_xmalloc and free ++ with objc_malloc and objc_free. ++ * objc/sarray.h (__objc_xmalloc, __objc_xrealloc): Delete. ++ * objc/selector.c: Replace use of __objc_xcalloc, __objc_xrealloc, ++ and __objc_xmalloc with objc_calloc, objc_realloc, and objc_malloc. ++ * objc/thr-decosf1.c: Replace use of __objc_xmalloc and free ++ with objc_malloc and objc_free. ++ * objc/thr-irix.c: Likewise. ++ * objc/thr-mach.c: Likewise. ++ * objc/thr-os2.c: Likewise. ++ * objc/thr-posix.c: Likewise. ++ * objc/thr-pthreads.c: Likewise. ++ * objc/thr-single.c: Likewise. ++ * objc/thr-solaris.c: Likewise. ++ * objc/thr-win32.c: Likewise. ++ * objc/thr.c: Likewise. ++ ++ Tue Aug 6 12:42:25 1996 Ovidiu Predescu (ovidiu@xpro.pcnet.ro) ++ ++ * objc/encoding.c (method_get_next_argument): Take into consideration ++ OBJC_FORWARDING_STACK_OFFSET for accessing stack variables. ++ (method_get_nth_argument): Likewise. ++ ++ * objc/encoding.h (method_get_sizeof_arguments): Fix typo. ++ ++ * objc/selector.c (__objc_register_instance_methods_to_class): New ++ function. ++ * objc/runtime.h: Likewise. Add missing function prototypes. ++ ++ * objc/init.c (__objc_exec_class): Initialize subclass to NULL. ++ Call __objc_register_instance_methods_to_class to register ++ instance methods as class methods for root classes. ++ ++ * objc/objc-api.h: On NeXT redefine object_copy and object_dispose ++ to avoid a conflict with those defined in system library. ++ ++ * objc/sendmsg.c: Also check if STRUCT_VALUE is even defined. ++ (search_for_method_in_list): No longer static. ++ ++ Tue Aug 6 09:40:29 1996 Scott Christley ++ ++ Add condition mutex support to the objc runtime. ++ * objc/THREADS: Update information. ++ * objc/thr-mach.c (objc_condition_allocate): New function. ++ (objc_condition_deallocate): New function. ++ (objc_condition_wait): New function. ++ (objc_condition_broadcast): New function. ++ (objc_condition_signal): New function. ++ * objc/thr-pthreads.c (objc_condition_allocate): New function. ++ (objc_condition_deallocate): New function. ++ (objc_condition_wait): New function. ++ (objc_condition_broadcast): New function. ++ (objc_condition_signal): New function. ++ * objc/thr-solaris.c (objc_condition_allocate): New function. ++ (objc_condition_deallocate): New function. ++ (objc_condition_wait): New function. ++ (objc_condition_broadcast): New function. ++ (objc_condition_signal): New function. ++ * objc/thr.h: Prototypes for new functions. ++ ++ * objc/init.c (__objc_runtime_mutex): Eliminate leading underscore ++ from name of objc mutex and thread structures. ++ * objc/runtime.h: Likewise. ++ * objc/thr-decosf1.c: Likewise. ++ * objc/thr-irix.c: Likewise. ++ * objc/thr-mach.c: Likewise. ++ * objc/thr-os2.c: Likewise. ++ * objc/thr-posix.c: Likewise. ++ * objc/thr-pthreads.c: Likewise. ++ * objc/thr-single.c: Likewise. ++ * objc/thr-solaris.c: Likewise. ++ * objc/thr.c: Likewise. ++ * objc/thr.h: Likewise. ++ * objc/thr-win32.c: Likewise. Define __OBJC__ before including ++ Windows header files. ++ ++ * config/i386/next.h (OBJC_MAX_STRUCT_BY_VALUE): New definition. ++ * objc/sendmsg.c (get_imp, objc_msg_lookup): Add logic to determine ++ when structures are passed by value. ++ ++ * objc/selector.c (__sel_register_typed_name): Eliminate compiler ++ warnings with explicit cast. ++ ++ Mon Aug 5 12:40:29 1996 Scott Christley ++ ++ * expr.c (expand_builtin_apply): Use SAVE_NONLOCAL on PPC. ++ ++ * objc/sendmsg.c: Clean up comments, make code fit with 80 columns. ++ * objc/objc.h: Likewise. ++ * objc/objc-api.h: Likewise. ++ * objc/archive.c: Likewise. ++ * objc/class.c: Likewise. ++ * objc/sarray.c: Likewise. ++ * objc/thr-mach.c: Likewise. ++ * objc/thr-posix.c: Likewise. ++ * objc/thr-pthreads.c: Likewise. ++ * objc/thr-win32.c: Likewise. ++ * objc/thr-os2.c: Likewise. ++ * objc/thr-solaris.c: Likewise. ++ * objc/thr.c: Likewise. ++ ++ Fri Jun 28 18:37:20 1996 Stephen L Moshier ++ ++ * objc/sarray.c (ifdef __alpha__): Don't declare `free'. ++ * objc/thr-decosf1.c (objc_thread_id): Use pthread_getunique_np ++ to obtain a thread ID value. ++ (objc_mutex_allocate): Cast mutex->owner to _objc_thread_t. ++ (objc_mutex_deallocate): Likewise. ++ (objc_mutex_unlock): Likewise. ++ (objc_mutex_trylock): Declare thread_id as _objc_thread_t. ++ (objc_mutex_lock): Likewise. ++ (objc_mutex_unlock): Likewise. ++ ++ Wed Jun 19 12:22:58 1996 Scott Christley ++ ++ * objc/sendmsg.c (__objc_double_forward): New function. ++ (get_imp, objc_msg_lookup): Use different forwarding function ++ when returning a floating point value. ++ ++ Wed Jun 5 09:46:22 1996 Scott Christley ++ ++ * objc/Makefile (libobjc.a): Don't delete the library; its contents ++ would be incorrect if only a single file was recompiled. ++ ++ * objc/thr.h (objc_set_thread_callback): New function. ++ (objc_thread_callback): Typedef for the hook function which is ++ called when the runtime first becomes multi-threaded. ++ * objc/thr.c (__objc_thread_detach_function): Clear thread storage. ++ Call the thread hook function when first becoming multi-threaded. ++ (objc_set_thread_callback): New function. ++ ++ * objc/selector.c (__sel_register_typed_name): Implement additional ++ parameter which indicates whether name and type parameters are truly ++ constant or not. Previously runtime assumed they were; now it ++ assumes that they are not. If constant then the actual pointers ++ passed as parameters can be stored in the runtime structures; ++ otherwise, the data must be copied into malloced space. ++ * objc/runtime.h (__sel_register_typed_name): Likewise. ++ * objc/init.c (__sel_register_typed_name): Likewise. ++ ++ Tue Jun 4 18:15:31 1996 Scott Christley ++ ++ * objc/init.c (__objc_init_protocols): Need to unlock mutex. ++ ++ Wed May 22 12:43:49 1996 Scott Christley ++ ++ * objc/sendmsg.c (objc_get_uninstalled_dtable): New function. ++ * objc/objc-api.h (objc_get_uninstalled_dtable): Likewise. ++ ++ * Makefile.in (OBJC_THREAD_FILE): New variable that holds the ++ source file name to be compiled for Objective-C Runtime Library ++ thread support. It is passed directly down to the Objective-C ++ Runtime Library makefile. ++ * configure (objc_thread_file): Set new variable to appropriate ++ values based upon target operating system; default is `thr-single'. ++ * objc/Makefile (OBJC_THREAD_FILE): Add target and dependency. ++ (thr.o): Remove OS specific thread files as dependencies. ++ * objc/thr-decosf1.c: Now compiles as a separate source file, so ++ include in appropriate Objective-C headers. ++ * objc/thr-mach.c: Likewise. ++ * objc/thr-os2.c: Likewise. ++ * objc/thr-posix.c: Likewise. ++ * objc/thr-pthreads.c: Likewise. ++ * objc/thr-irix.c: Likewise. ++ * objc/thr-single.c: Likewise. ++ * objc/thr-solaris.c: Likewise. ++ * objc/thr-win32.c: Likewise. ++ * objc/thr.c: Remove inclusion of source files. ++ * objc/thr.h (__objc_thread_exit_status): Declare global variable. ++ * objc/thr-pthreads.c: New file. ++ ++ Fri May 17 08:12:37 1996 Scott Christley ++ ++ * objc/thr-os2.c, objc/thr-posix.c, objc/thr-mach.c: New files. ++ * objc/THREADS.MACH: New file. ++ ++ * objc/sendmsg.c (nil_method): Deleted from here. ++ * objc/nil_method.c: New file. ++ * Makefile (OBJC_O): Add dependency for nil_method.c. ++ ++ * objc/hash.c (hash_is_key_in_hash): New function. ++ * objc/hash.h: Include objc/objc.h here instead of in objc/hash.c ++ to get BOOL typedef. ++ ++ Tue Apr 16 06:22:00 1996 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++ ++ * objc/thr-decosf1.c (_objc_thread_id): Correct return type from ++ int to _objc_thread_id. ++ ++ Sun Apr 14 07:52:28 1996 Manor Askenazi ++ ++ * objc/encoding.c (objc_skip_typespec): Don't abort for _C_UNDEF. ++ ++ Thu Apr 4 12:17:08 1996 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++ ++ * objc/Makefile: Rename thread* to thr*. ++ * objc/thread.c: Rename thread-* to thr-*. ++ * objc/thr-decosf1.c: Renamed from thread-decosf1.c ++ * objc/thr-irix.c: Renamed from thread-irix.c. ++ * objc/thr-single.c: Renamed from thread-single.c. ++ * objc/thr-solarius.c: Renamed from thread-solaris.c. ++ * objc/thr-win32.c: Renamed from thread-win32.c. ++ * objc/objc-api.h: Include thr.h, not thread.h. ++ * objc/runtime.h, objc/sarray.h: Likewise. ++ ++ Mon Mar 25 08:09:59 1996 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++ ++ * objc/thread-single.c (objc_mutex_unlock): Properly declare thread_id. ++ ++ Tue Mar 5 09:22:20 1996 Scott Christley (scottc@net-community.com) ++ ++ * objc/objc-api.h, objc/runtime.h: Include objc/thread.h. ++ * objc/class.c (__objc_init_class_tables): Surround sarray access ++ with mutex lock/unlock. ++ (__objc_add_class_to_hash, objc_lookup_class): Likewise. ++ (objc_get_class, objc_get_next_class): Likewise. ++ (__objc_resolve_class_links, class_pose_as): Likewise. ++ * objc/init.c (__objc_runtime_mutux, __objc_runtime_thread_alive): ++ New variables. ++ (objc_init_statics, __objc_init_protocols): Surround sarray access ++ with mutex lock/unlock ++ (__objc_exec_class): Likewise. ++ Initialization for thread-safe global variables. ++ Declarations for thread-safe functions and global variables ++ * objc/sendmsg.c (get_imp, __objc_responds_to): ++ Surround sarray access with mutex lock/unlock. ++ (__objc_init_install_dtable): Likewise. ++ (__objc_update_dispatch_table_for_class): Likewise. ++ (__objc_print_dtable_stats): Likewise. ++ * objc/selector.c (sel_get_typed_uid, sel_get_any_typed_uid): Likewise. ++ (sel_get_any_uid, sel_get_name, sel_register_name): Likewise. ++ (sel_register_typed_name): Likewise. ++ * objc/sarray.h (union sversion): New. ++ (struct sarray): Maintain multiple versions. ++ (sarray_remove_garbage): Add prototype. ++ * objc/sarray.c (sarray_{remove,free}_garbage): New functions. ++ (sarray_at_put, sarray_new, sarray_lazy_copy): ++ Modify/copy sarray structure/data in a thread-safe manner ++ (sarray_{realloc,free}): Reallocate/free sarray structure/data in a ++ thread-safe manner. ++ ++ * objc/THREADS, objc/thread.c, objc/thread.h: New files. ++ * objc/thread-{decosf1,irix,solaris,win32,single}.c: New files. ++ * objc/objc-list.h: Renamed from objc/list.h. ++ * objc/Makefile: Changes to compile new files and name renaming. ++ * objc/makefile.dos: Likewise. ++ ++ Mon Jan 15 06:20:38 1996 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++ ++ * objc/archive.c (objc_{write,read}_type, case _C_STRUCT_B): Fix typo. ++ ++ Mon Dec 18 19:31:23 1995 Adam Fedor ++ ++ * objc/encoding.c (objc_alignof_type): Handle _C_PTR case. ++ ++ Sat Jun 29 12:33:39 1996 Richard Kenner ++ ++ * Version 2.7.2.1 released. ++ ++ Tue Jun 11 20:18:03 1996 Per Bothner ++ ++ * fix-header.c (read_scna_file): Invoke FIXPROTO_INIT if defined. ++ * alpha.h (FIXPROTO_INIT): Define new macro. ++ ++ Fri May 10 18:35:00 1996 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++ ++ * loop.c (maybe_eliminate_biv_1): Disable all but two cases ++ of biv elimination with givs and restrict those two cases to ++ an ADD_VAL that is an address. ++ ++ Mon Apr 22 16:50:19 1996 Jeremy Bettis ++ ++ * objc/hash.c (hash_value_for_key): Prevent endless loop when 0 was ++ stored in a hashtable. ++ ++ Wed Apr 17 17:53:23 1996 Michael Meissner ++ ++ * rs6000.c (expand_block_move_mem): Copy RTX_UNCHANGING_P. ++ (expand_block_move): Copy dest/src to registers using ++ copy_addr_to_reg, call expand_block_move_mem to copy all of the ++ bits. ++ ++ Mon Apr 8 13:46:28 1996 Michael Meissner ++ ++ * rs6000.c (output_{prolog,epilog}): For V.4/eabi systems, change ++ prologue and epilogue so that accesses beyond the current stack ++ pointer are not done like they are for AIX. ++ ++ Fri Mar 26 05:43:06 1996 Torbjorn Granlund ++ ++ * vax.md (insv matcher): Call CC_STATUS_INIT. ++ * vax.h (NOTICE_UPDATE_CC): Handle ZERO_EXTRACT destination. ++ ++ Sat Mar 23 18:25:39 1996 J"orn Rennecke (amylaar@meolyon.hanse.de) ++ ++ * c-typeck.c (set_init_index): Check for use outside an array ++ initializer. ++ ++ Sat Mar 23 09:21:40 1996 Doug Evans ++ ++ * sparc/sparc.h (CONDITIONAL_REGISTER_USAGE): Don't unfix %g[234] ++ if fixed with -ffixed-. ++ ++ Wed Mar 13 20:36:10 1996 Jim Wilson ++ ++ * mips.c (mips_expand_prologue): Change TYPE_NEEDS_CONSTRUCTING to ++ TREE_ADDRESSABLE; ++ * pa.h (ASM_DECLARE_FUNCTION_NAME): Likewise. ++ ++ Tue Mar 12 14:36:02 1996 Jason Merrill ++ ++ * lex.c (real_yylex): Warn about using the `namespace' keyword. ++ ++ Tue Feb 27 08:18:12 1996 Richard Earnshaw (rearnsha@armltd.co.uk) ++ ++ * arm.md (mov{si,sf,df}cc and matchers): All conditional move ++ patterns must have a mode. ++ ++ Mon Feb 19 07:35:07 1996 Torbjorn Granlund ++ ++ * rs6000.md (not:SI with assign and compare): Fix typo. ++ ++ Wed Jan 24 18:00:12 1996 Brendan Kehoe ++ ++ * alpha.c (alpha_write_verstamp): Only emit MS_STAMP and LS_STAMP, ++ not the extra numbers. ++ ++ Wed Jan 17 21:22:40 1996 Brendan Kehoe ++ ++ * cp/decl2.c (grokfield): Call cplus_decl_attributes with the attrlist. ++ Pass a null tree to grokdeclarator for its ATTRLIST arg, since it's ++ only ever used for functions in it. ++ ++ Tue Jan 16 06:01:28 1996 Thomas Graichen ++ ++ * i386/freebsd.h (ASM_WEAKEN_LABEL): Deleted; not supported. ++ ++ Sun Jan 7 17:11:11 1996 David Edelsohn ++ ++ * collect2.c (scan_libraries): Correct Import File ID interpretation. ++ ++ Thu Dec 28 22:24:53 1995 Michael Meissner ++ ++ * rs6000.md (common mode functions): Add condition reg clobbers. ++ ++ Tue Dec 19 15:08:31 1995 Jason Merrill ++ ++ * collect2.c: Remove auto_export functionality. ++ ++ Mon Dec 18 18:40:34 1995 Jim Wilson ++ ++ * svr4.h (ASM_IDENTIFY_GCC): Don't output stab here. ++ (ASM_IDENTIFY_GCC_AFTER_SOURCE): Output stab here instead of ++ above. ++ ++ Sat Dec 16 07:03:33 1995 Philippe De Muyter (phdm@info.ucl.ac.be) ++ ++ * stor-layout.c (layout_record): When PCC_BITFIELD_TYPE_MATTERS, ++ compute bitpos using field_size % type_align instead of field_size. ++ ++ Fri Dec 15 18:41:50 1995 Philippe De Muyter (phdm@info.ucl.ac.be) ++ ++ * fixincludes (sys/wait.h): Add forward declaration of struct rusage ++ on AIX 3.2.5. ++ ++ Sat Dec 9 18:05:03 1995 Jim Wilson ++ ++ * expr.c (expand_expr, case INDIRECT_REF): Correct typo in May 8 ++ change. ++ + Sun Nov 26 14:47:42 1995 Richard Kenner + + * Version 2.7.2 released. +diff -rcP gcc-2.7.2/INSTALL gcc-2.7.2.1-objc-960906/INSTALL +*** gcc-2.7.2/INSTALL Fri Sep 6 14:25:33 1996 +--- gcc-2.7.2.1-objc-960906/INSTALL Fri Sep 6 10:24:28 1996 +*************** +*** 427,432 **** +--- 427,474 ---- + a C++ run-time library. All I/O functionality, special class + libraries, etc., are available in the libg++ distribution. + ++ 17. GNU C does include a runtime library for Objective-C because it is ++ an integral part of the language; all of the files associated with ++ the library are located in the subdirectory `objc'. The GNU ++ Objective-C Runtime Library does require header files for the ++ target's C library in order to be compiled, and it will also ++ require the header files for the target's thread library if you ++ want thread support. *Note Cross-Compilers and Header Files: ++ Cross Headers, for discussion about header files issues for ++ cross-compilation. ++ ++ When you run `configure', it picks the appropriate Objective-C ++ back-end thread implementation file for the target platform. In ++ some situations, you may wish to choose a different back-end as ++ some platforms support multiple thread implementations, or you may ++ wish to disable thread support completely. This can be done by ++ specifying a value for the OBJC_THREAD_FILE makefile variable on ++ the command line when you run make, for example: ++ ++ make CC="stage2/xgcc -Bstage2/" CFLAGS="-g -O2" OBJC_THREAD_FILE=thr-single ++ ++ Below is a list of the currently available back-ends. ++ ++ * thr-single; disable thread support, should work for all ++ platforms. ++ ++ * thr-decosf1; DEC OSF/1 thread support. ++ ++ * thr-irix; SGI IRIX thread support. ++ ++ * thr-mach; Generic MACH thread support, known to work on ++ NEXTSTEP. ++ ++ * thr-os2; IBM OS/2 thread support. ++ ++ * thr-posix; Generix POSIX thread support. ++ ++ * thr-pthreads; PCThreads on Linux based GNU systems. ++ ++ * thr-solaris; SUN Solaris thread support. ++ ++ * thr-win32; Microsoft Win32 API thread support. ++ + Configurations Supported by GNU CC + ================================== + +*************** +*** 657,732 **** + Structures are no longer a multiple of 2 bytes. + + `hppa*-*-*' +! There are two variants of this CPU, called 1.0 and 1.1, which have +! different machine descriptions. You must use the right one for +! your machine. All 7NN machines and 8N7 machines use 1.1, while +! all other 8NN machines use 1.0. +! +! The easiest way to handle this problem is to use `configure hpNNN' +! or `configure hpNNN-hpux', where NNN is the model number of the +! machine. Then `configure' will figure out if the machine is a 1.0 +! or 1.1. Use `uname -a' to find out the model number of your +! machine. + + `-g' does not work on HP-UX, since that system uses a peculiar + debugging format which GNU CC does not know about. However, `-g' + will work if you also use GAS and GDB in conjunction with GCC. We + highly recommend using GAS for all HP-PA configurations. + +! You should be using GAS-2.3 (or later) along with GDB-4.12 (or + later). These can be retrieved from all the traditional GNU ftp + archive sites. + +! Build GAS and install the resulting binary as: +! +! /usr/local/lib/gcc-lib/CONFIGURATION/GCCVERSION/as + +! where CONFIGURATION is the configuration name (perhaps +! `hpNNN-hpux') and GCCVERSION is the GNU CC version number. Do +! this *before* starting the build process, otherwise you will get +! errors from the HPUX assembler while building `libgcc2.a'. The +! command +! +! make install-dir +! +! will create the necessary directory hierarchy so you can install +! GAS before building GCC. +! +! To enable debugging, configure GNU CC with the `--with-gnu-as' +! option before building. +! +! It has been reported that GNU CC produces invalid assembly code for +! 1.1 machines running HP-UX 8.02 when using the HP assembler. +! Typically the errors look like this: +! as: bug.s @line#15 [err#1060] +! Argument 0 or 2 in FARG upper +! - lookahead = ARGW1=FR,RTNVAL=GR +! as: foo.s @line#28 [err#1060] +! Argument 0 or 2 in FARG upper +! - lookahead = ARGW1=FR +! +! You can check the version of HP-UX you are running by executing +! the command `uname -r'. If you are indeed running HP-UX 8.02 on +! a PA and using the HP assembler then configure GCC with +! "hpNNN-hpux8.02". + + `i370-*-*' + This port is very preliminary and has many known bugs. We hope to + have a higher-quality port for this machine soon. + + `i386-*-linuxoldld' +! Use this configuration to generate a.out binaries on Linux if you +! do not have gas/binutils version 2.5.2 or later installed. This is +! an obsolete configuration. + + `i386-*-linuxaout' +! Use this configuration to generate a.out binaries on Linux. This +! configuration is being superseded. You must use gas/binutils +! version 2.5.2 or later. + + `i386-*-linux' +! Use this configuration to generate ELF binaries on Linux. You must +! use gas/binutils version 2.5.2 or later. + + `i386-*-sco' + Compilation with RCC is recommended. Also, it may be a good idea +--- 699,745 ---- + Structures are no longer a multiple of 2 bytes. + + `hppa*-*-*' +! There are several variants of the HP-PA processor which run a +! variety of operating systems. GNU CC must be configured to use +! the correct processor type and operating system, or GNU CC will +! not function correctly. The easiest way to handle this problem is +! to *not* specify a target when configuring GNU CC, the `configure' +! script will try to automatically determine the right processor +! type and operating system. + + `-g' does not work on HP-UX, since that system uses a peculiar + debugging format which GNU CC does not know about. However, `-g' + will work if you also use GAS and GDB in conjunction with GCC. We + highly recommend using GAS for all HP-PA configurations. + +! You should be using GAS-2.6 (or later) along with GDB-4.16 (or + later). These can be retrieved from all the traditional GNU ftp + archive sites. + +! GAS will need to be installed into a directory before `/bin', +! `/usr/bin', and `/usr/ccs/bin' in your search path. You should +! install GAS before you build GNU CC. + +! To enable debugging, you must configure GNU CC with the +! `--with-gnu-as' option before building. + + `i370-*-*' + This port is very preliminary and has many known bugs. We hope to + have a higher-quality port for this machine soon. + + `i386-*-linuxoldld' +! Use this configuration to generate a.out binaries on Linux-based +! GNU systems, if you do not have gas/binutils version 2.5.2 or later +! installed. This is an obsolete configuration. + + `i386-*-linuxaout' +! Use this configuration to generate a.out binaries on Linux-based +! GNU systems. This configuration is being superseded. You must use +! gas/binutils version 2.5.2 or later. + + `i386-*-linux' +! Use this configuration to generate ELF binaries on Linux-based GNU +! systems. You must use gas/binutils version 2.5.2 or later. + + `i386-*-sco' + Compilation with RCC is recommended. Also, it may be a good idea +diff -rcP gcc-2.7.2/Makefile.in gcc-2.7.2.1-objc-960906/Makefile.in +*** gcc-2.7.2/Makefile.in Fri Sep 6 14:25:34 1996 +--- gcc-2.7.2.1-objc-960906/Makefile.in Fri Sep 6 10:24:29 1996 +*************** +*** 174,179 **** +--- 174,180 ---- + host_xm_file= ... `configure' substitutes actual host xm- file name here. + lang_specs_files= ... `configure' substitutes actual lang spec file names here. + lang_options_files= ... `configure' puts actual lang options file names here. ++ OBJC_THREAD_FILE= ... `configure' puts actual objc thread file name here. + version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < $(srcdir)/version.c` + mainversion=`sed -e 's/.*\"\([0-9]*\.[0-9]*\).*/\1/' < $(srcdir)/version.c` + +*************** +*** 995,1001 **** + $(MAKE) -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)" + -rm -f libobjc.a + ln objc/libobjc.a . >/dev/null 2>&1 || cp objc/libobjc.a . + -if $(RANLIB_TEST) ; then $(RANLIB) libobjc.a; else true; fi +--- 996,1002 ---- + $(MAKE) -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)" OBJC_THREAD_FILE="$(OBJC_THREAD_FILE)" + -rm -f libobjc.a + ln objc/libobjc.a . >/dev/null 2>&1 || cp objc/libobjc.a . + -if $(RANLIB_TEST) ; then $(RANLIB) libobjc.a; else true; fi +*************** +*** 1008,1014 **** + $(MAKE) -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)" + + # Compile two additional files that are linked with every program + # linked using GCC on systems using COFF or ELF, for the sake of C++ +--- 1009,1015 ---- + $(MAKE) -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)" OBJC_THREAD_FILE="$(OBJC_THREAD_FILE)" + + # Compile two additional files that are linked with every program + # linked using GCC on systems using COFF or ELF, for the sake of C++ +diff -rcP gcc-2.7.2/NEWS gcc-2.7.2.1-objc-960906/NEWS +*** gcc-2.7.2/NEWS Fri Sep 6 14:25:34 1996 +--- gcc-2.7.2.1-objc-960906/NEWS Fri Sep 6 10:24:29 1996 +*************** +*** 1,3 **** +--- 1,7 ---- ++ Noteworthy changes in GCC version 2.7.2.1: ++ ++ This release fixes some serious bugs discovered since the 2.7.2 release. ++ + Noteworthy changes in GCC version 2.7.2: + + A few bugs have been fixed (most notably the generation of an +diff -rcP gcc-2.7.2/bi-parser.c gcc-2.7.2.1-objc-960906/bi-parser.c +*** gcc-2.7.2/bi-parser.c Fri Sep 6 14:25:46 1996 +--- gcc-2.7.2.1-objc-960906/bi-parser.c Fri Sep 6 10:24:41 1996 +*************** +*** 1,5 **** + +! /* A Bison parser, made from bi-parser.y with Bison version GNU Bison version 1.22 + */ + + #define YYBISON 1 /* Identify Bison output. */ +--- 1,5 ---- + +! /* A Bison parser, made from bi-parser.y with Bison version GNU Bison version 1.24 + */ + + #define YYBISON 1 /* Identify Bison output. */ +*************** +*** 123,131 **** + 93, 95, 98, 101, 105, 108, 112 + }; + +! static const char * const yytname[] = { "$","error","$illegal.","DEFOP","STRING", +! "'('","','","')'","top","defs","def","variations","variation","opt_string","list", +! "items","item","" + }; + #endif + +--- 123,131 ---- + 93, 95, 98, 101, 105, 108, 112 + }; + +! static const char * const yytname[] = { "$","error","$undefined.","DEFOP", +! "STRING","'('","','","')'","top","defs","def","variations","variation","opt_string", +! "list","items","item","" + }; + #endif + +*************** +*** 179,192 **** + -1, 12, -1, -1, 16 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/local/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman + + This program 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 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, +--- 179,192 ---- + -1, 12, -1, -1, 16 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program 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. + + This program is distributed in the hope that it will be useful, +*************** +*** 198,203 **** +--- 198,207 ---- + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++ /* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ + + #ifndef alloca + #ifdef __GNUC__ +*************** +*** 271,280 **** +--- 275,292 ---- + + #ifdef YYPURE + #ifdef YYLSP_NEEDED ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) ++ #else + #define YYLEX yylex(&yylval, &yylloc) ++ #endif ++ #else /* not YYLSP_NEEDED */ ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, YYLEX_PARAM) + #else + #define YYLEX yylex(&yylval) + #endif ++ #endif /* not YYLSP_NEEDED */ + #endif + + /* If nonreentrant, generate the variables here */ +*************** +*** 322,335 **** + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (from, to, count) + char *from; + char *to; + int count; +--- 334,347 ---- + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (from, to, count) + char *from; + char *to; + int count; +*************** +*** 347,353 **** + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +--- 359,365 ---- + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +*************** +*** 360,366 **** + #endif + #endif + +! #line 184 "/usr/local/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +--- 372,378 ---- + #endif + #endif + +! #line 192 "/usr/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +*************** +*** 493,504 **** + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +--- 505,516 ---- + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +*************** +*** 716,722 **** + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 480 "/usr/local/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +--- 728,734 ---- + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 487 "/usr/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +diff -rcP gcc-2.7.2/c-gperf.h gcc-2.7.2.1-objc-960906/c-gperf.h +*** gcc-2.7.2/c-gperf.h Fri Sep 6 14:25:54 1996 +--- gcc-2.7.2.1-objc-960906/c-gperf.h Fri Sep 6 10:24:48 1996 +*************** +*** 1,5 **** + /* C code produced by gperf version 2.5 (GNU C++ version) */ +! /* Command-line: gperf -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ c-parse.gperf */ + struct resword { char *name; short token; enum rid rid; }; + + #define TOTAL_KEYWORDS 79 +--- 1,6 ---- + /* C code produced by gperf version 2.5 (GNU C++ version) */ +! /* Command-line: gperf -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ ./c-parse.gperf */ +! /* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ + struct resword { char *name; short token; enum rid rid; }; + + #define TOTAL_KEYWORDS 79 +*************** +*** 10,16 **** + /* maximum key range = 135, duplicates = 0 */ + + #ifdef __GNUC__ +! __inline + #endif + static unsigned int + hash (str, len) +--- 11,17 ---- + /* maximum key range = 135, duplicates = 0 */ + + #ifdef __GNUC__ +! inline + #endif + static unsigned int + hash (str, len) +*************** +*** 43,167 **** + case 2: + case 1: + hval += asso_values[str[0]]; + } + return hval + asso_values[str[len - 1]]; + } + + static struct resword wordlist[] = + { +! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, +! {"",}, +! {"int", TYPESPEC, RID_INT}, +! {"",}, {"",}, +! {"__typeof__", TYPEOF, NORID}, +! {"__signed__", TYPESPEC, RID_SIGNED}, +! {"__imag__", IMAGPART, NORID}, +! {"switch", SWITCH, NORID}, +! {"__inline__", SCSPEC, RID_INLINE}, +! {"else", ELSE, NORID}, +! {"__iterator__", SCSPEC, RID_ITERATOR}, +! {"__inline", SCSPEC, RID_INLINE}, +! {"__extension__", EXTENSION, NORID}, +! {"struct", STRUCT, NORID}, +! {"__real__", REALPART, NORID}, +! {"__const", TYPE_QUAL, RID_CONST}, +! {"while", WHILE, NORID}, +! {"__const__", TYPE_QUAL, RID_CONST}, +! {"case", CASE, NORID}, +! {"__complex__", TYPESPEC, RID_COMPLEX}, +! {"__iterator", SCSPEC, RID_ITERATOR}, +! {"bycopy", TYPE_QUAL, RID_BYCOPY}, +! {"",}, {"",}, {"",}, +! {"__complex", TYPESPEC, RID_COMPLEX}, +! {"",}, +! {"in", TYPE_QUAL, RID_IN}, +! {"break", BREAK, NORID}, +! {"@defs", DEFS, NORID}, +! {"",}, {"",}, {"",}, +! {"extern", SCSPEC, RID_EXTERN}, +! {"if", IF, NORID}, +! {"typeof", TYPEOF, NORID}, +! {"typedef", SCSPEC, RID_TYPEDEF}, +! {"__typeof", TYPEOF, NORID}, +! {"sizeof", SIZEOF, NORID}, +! {"",}, +! {"return", RETURN, NORID}, +! {"const", TYPE_QUAL, RID_CONST}, +! {"__volatile__", TYPE_QUAL, RID_VOLATILE}, +! {"@private", PRIVATE, NORID}, +! {"@selector", SELECTOR, NORID}, +! {"__volatile", TYPE_QUAL, RID_VOLATILE}, +! {"__asm__", ASM_KEYWORD, NORID}, +! {"",}, {"",}, +! {"continue", CONTINUE, NORID}, +! {"__alignof__", ALIGNOF, NORID}, +! {"__imag", IMAGPART, NORID}, +! {"__attribute__", ATTRIBUTE, NORID}, +! {"",}, {"",}, +! {"__attribute", ATTRIBUTE, NORID}, +! {"for", FOR, NORID}, +! {"",}, +! {"@encode", ENCODE, NORID}, +! {"id", OBJECTNAME, RID_ID}, +! {"static", SCSPEC, RID_STATIC}, +! {"@interface", INTERFACE, NORID}, +! {"",}, +! {"__signed", TYPESPEC, RID_SIGNED}, +! {"",}, +! {"__label__", LABEL, NORID}, +! {"",}, {"",}, +! {"__asm", ASM_KEYWORD, NORID}, +! {"char", TYPESPEC, RID_CHAR}, +! {"",}, +! {"inline", SCSPEC, RID_INLINE}, +! {"out", TYPE_QUAL, RID_OUT}, +! {"register", SCSPEC, RID_REGISTER}, +! {"__real", REALPART, NORID}, +! {"short", TYPESPEC, RID_SHORT}, +! {"",}, +! {"enum", ENUM, NORID}, +! {"inout", TYPE_QUAL, RID_INOUT}, +! {"",}, +! {"oneway", TYPE_QUAL, RID_ONEWAY}, +! {"union", UNION, NORID}, +! {"",}, +! {"__alignof", ALIGNOF, NORID}, +! {"",}, +! {"@implementation", IMPLEMENTATION, NORID}, +! {"",}, +! {"@class", CLASS, NORID}, +! {"",}, +! {"@public", PUBLIC, NORID}, +! {"asm", ASM_KEYWORD, NORID}, +! {"",}, {"",}, {"",}, {"",}, {"",}, +! {"default", DEFAULT, NORID}, +! {"",}, +! {"void", TYPESPEC, RID_VOID}, +! {"",}, +! {"@protected", PROTECTED, NORID}, +! {"@protocol", PROTOCOL, NORID}, +! {"",}, {"",}, {"",}, +! {"volatile", TYPE_QUAL, RID_VOLATILE}, +! {"",}, {"",}, +! {"signed", TYPESPEC, RID_SIGNED}, +! {"float", TYPESPEC, RID_FLOAT}, +! {"@end", END, NORID}, +! {"",}, {"",}, +! {"unsigned", TYPESPEC, RID_UNSIGNED}, +! {"@compatibility_alias", ALIAS, NORID}, +! {"double", TYPESPEC, RID_DOUBLE}, +! {"",}, {"",}, +! {"auto", SCSPEC, RID_AUTO}, +! {"",}, +! {"goto", GOTO, NORID}, +! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, +! {"do", DO, NORID}, +! {"",}, {"",}, {"",}, {"",}, +! {"long", TYPESPEC, RID_LONG}, + }; + + #ifdef __GNUC__ +! __inline + #endif + struct resword * + is_reserved_word (str, len) +--- 44,169 ---- + case 2: + case 1: + hval += asso_values[str[0]]; ++ break; + } + return hval + asso_values[str[len - 1]]; + } + + static struct resword wordlist[] = + { +! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, +! {"",}, +! {"int", TYPESPEC, RID_INT}, +! {"",}, {"",}, +! {"__typeof__", TYPEOF, NORID}, +! {"__signed__", TYPESPEC, RID_SIGNED}, +! {"__imag__", IMAGPART, NORID}, +! {"switch", SWITCH, NORID}, +! {"__inline__", SCSPEC, RID_INLINE}, +! {"else", ELSE, NORID}, +! {"__iterator__", SCSPEC, RID_ITERATOR}, +! {"__inline", SCSPEC, RID_INLINE}, +! {"__extension__", EXTENSION, NORID}, +! {"struct", STRUCT, NORID}, +! {"__real__", REALPART, NORID}, +! {"__const", TYPE_QUAL, RID_CONST}, +! {"while", WHILE, NORID}, +! {"__const__", TYPE_QUAL, RID_CONST}, +! {"case", CASE, NORID}, +! {"__complex__", TYPESPEC, RID_COMPLEX}, +! {"__iterator", SCSPEC, RID_ITERATOR}, +! {"bycopy", TYPE_QUAL, RID_BYCOPY}, +! {"",}, {"",}, {"",}, +! {"__complex", TYPESPEC, RID_COMPLEX}, +! {"",}, +! {"in", TYPE_QUAL, RID_IN}, +! {"break", BREAK, NORID}, +! {"@defs", DEFS, NORID}, +! {"",}, {"",}, {"",}, +! {"extern", SCSPEC, RID_EXTERN}, +! {"if", IF, NORID}, +! {"typeof", TYPEOF, NORID}, +! {"typedef", SCSPEC, RID_TYPEDEF}, +! {"__typeof", TYPEOF, NORID}, +! {"sizeof", SIZEOF, NORID}, +! {"",}, +! {"return", RETURN, NORID}, +! {"const", TYPE_QUAL, RID_CONST}, +! {"__volatile__", TYPE_QUAL, RID_VOLATILE}, +! {"@private", PRIVATE, NORID}, +! {"@selector", SELECTOR, NORID}, +! {"__volatile", TYPE_QUAL, RID_VOLATILE}, +! {"__asm__", ASM_KEYWORD, NORID}, +! {"",}, {"",}, +! {"continue", CONTINUE, NORID}, +! {"__alignof__", ALIGNOF, NORID}, +! {"__imag", IMAGPART, NORID}, +! {"__attribute__", ATTRIBUTE, NORID}, +! {"",}, {"",}, +! {"__attribute", ATTRIBUTE, NORID}, +! {"for", FOR, NORID}, +! {"",}, +! {"@encode", ENCODE, NORID}, +! {"id", OBJECTNAME, RID_ID}, +! {"static", SCSPEC, RID_STATIC}, +! {"@interface", INTERFACE, NORID}, +! {"",}, +! {"__signed", TYPESPEC, RID_SIGNED}, +! {"",}, +! {"__label__", LABEL, NORID}, +! {"",}, {"",}, +! {"__asm", ASM_KEYWORD, NORID}, +! {"char", TYPESPEC, RID_CHAR}, +! {"",}, +! {"inline", SCSPEC, RID_INLINE}, +! {"out", TYPE_QUAL, RID_OUT}, +! {"register", SCSPEC, RID_REGISTER}, +! {"__real", REALPART, NORID}, +! {"short", TYPESPEC, RID_SHORT}, +! {"",}, +! {"enum", ENUM, NORID}, +! {"inout", TYPE_QUAL, RID_INOUT}, +! {"",}, +! {"oneway", TYPE_QUAL, RID_ONEWAY}, +! {"union", UNION, NORID}, +! {"",}, +! {"__alignof", ALIGNOF, NORID}, +! {"",}, +! {"@implementation", IMPLEMENTATION, NORID}, +! {"",}, +! {"@class", CLASS, NORID}, +! {"",}, +! {"@public", PUBLIC, NORID}, +! {"asm", ASM_KEYWORD, NORID}, +! {"",}, {"",}, {"",}, {"",}, {"",}, +! {"default", DEFAULT, NORID}, +! {"",}, +! {"void", TYPESPEC, RID_VOID}, +! {"",}, +! {"@protected", PROTECTED, NORID}, +! {"@protocol", PROTOCOL, NORID}, +! {"",}, {"",}, {"",}, +! {"volatile", TYPE_QUAL, RID_VOLATILE}, +! {"",}, {"",}, +! {"signed", TYPESPEC, RID_SIGNED}, +! {"float", TYPESPEC, RID_FLOAT}, +! {"@end", END, NORID}, +! {"",}, {"",}, +! {"unsigned", TYPESPEC, RID_UNSIGNED}, +! {"@compatibility_alias", ALIAS, NORID}, +! {"double", TYPESPEC, RID_DOUBLE}, +! {"",}, {"",}, +! {"auto", SCSPEC, RID_AUTO}, +! {"",}, +! {"goto", GOTO, NORID}, +! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, +! {"do", DO, NORID}, +! {"",}, {"",}, {"",}, {"",}, +! {"long", TYPESPEC, RID_LONG}, + }; + + #ifdef __GNUC__ +! inline + #endif + struct resword * + is_reserved_word (str, len) +diff -rcP gcc-2.7.2/c-parse.c gcc-2.7.2.1-objc-960906/c-parse.c +*** gcc-2.7.2/c-parse.c Fri Sep 6 14:25:58 1996 +--- gcc-2.7.2.1-objc-960906/c-parse.c Fri Sep 6 10:24:51 1996 +*************** +*** 1,5 **** + +! /* A Bison parser, made from c-parse.y with Bison version GNU Bison version 1.22 + */ + + #define YYBISON 1 /* Identify Bison output. */ +--- 1,5 ---- + +! /* A Bison parser, made from c-parse.y with Bison version GNU Bison version 1.24 + */ + + #define YYBISON 1 /* Identify Bison output. */ +*************** +*** 406,412 **** + 2053, 2056, 2061, 2064 + }; + +! static const char * const yytname[] = { "$","error","$illegal.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT", + "BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ATTRIBUTE", +--- 406,412 ---- + 2053, 2056, 2061, 2064 + }; + +! static const char * const yytname[] = { "$","error","$undefined.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT", + "BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ATTRIBUTE", +*************** +*** 1130,1143 **** + 48, 49, 50, 51, 52 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/local/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman + + This program 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 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, +--- 1130,1143 ---- + 48, 49, 50, 51, 52 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program 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. + + This program is distributed in the hope that it will be useful, +*************** +*** 1149,1154 **** +--- 1149,1158 ---- + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++ /* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ + + #ifndef alloca + #ifdef __GNUC__ +*************** +*** 1222,1231 **** +--- 1226,1243 ---- + + #ifdef YYPURE + #ifdef YYLSP_NEEDED ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) ++ #else + #define YYLEX yylex(&yylval, &yylloc) ++ #endif ++ #else /* not YYLSP_NEEDED */ ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, YYLEX_PARAM) + #else + #define YYLEX yylex(&yylval) + #endif ++ #endif /* not YYLSP_NEEDED */ + #endif + + /* If nonreentrant, generate the variables here */ +*************** +*** 1273,1286 **** + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (from, to, count) + char *from; + char *to; + int count; +--- 1285,1298 ---- + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (from, to, count) + char *from; + char *to; + int count; +*************** +*** 1298,1304 **** + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +--- 1310,1316 ---- + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +*************** +*** 1311,1317 **** + #endif + #endif + +! #line 184 "/usr/local/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +--- 1323,1329 ---- + #endif + #endif + +! #line 192 "/usr/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +*************** +*** 1444,1455 **** + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +--- 1456,1467 ---- + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +*************** +*** 3483,3489 **** + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 480 "/usr/local/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +--- 3495,3501 ---- + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 487 "/usr/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +diff -rcP gcc-2.7.2/c-typeck.c gcc-2.7.2.1-objc-960906/c-typeck.c +*** gcc-2.7.2/c-typeck.c Fri Sep 6 14:26:04 1996 +--- gcc-2.7.2.1-objc-960906/c-typeck.c Fri Sep 6 10:24:57 1996 +*************** +*** 5723,5728 **** +--- 5723,5730 ---- + error_init ("nonconstant array index in initializer%s", " for `%s'", NULL); + else if (last != 0 && TREE_CODE (last) != INTEGER_CST) + error_init ("nonconstant array index in initializer%s", " for `%s'", NULL); ++ else if (! constructor_unfilled_index) ++ error_init ("array index in non-array initializer%s", " for `%s'", NULL); + else if (tree_int_cst_lt (first, constructor_unfilled_index)) + error_init ("duplicate array index in initializer%s", " for `%s'", NULL); + else +diff -rcP gcc-2.7.2/cexp.c gcc-2.7.2.1-objc-960906/cexp.c +*** gcc-2.7.2/cexp.c Fri Sep 6 14:26:10 1996 +--- gcc-2.7.2.1-objc-960906/cexp.c Fri Sep 6 10:25:03 1996 +*************** +*** 1,5 **** + +! /* A Bison parser, made from cexp.y with Bison version GNU Bison version 1.22 + */ + + #define YYBISON 1 /* Identify Bison output. */ +--- 1,5 ---- + +! /* A Bison parser, made from cexp.y with Bison version GNU Bison version 1.24 + */ + + #define YYBISON 1 /* Identify Bison output. */ +*************** +*** 241,247 **** + 332, 335, 337, 340, 343, 345, 347, 352, 354, 367 + }; + +! static const char * const yytname[] = { "$","error","$illegal.","INT","CHAR", + "NAME","ERROR","'?'","':'","','","OR","AND","'|'","'^'","'&'","EQUAL","NOTEQUAL", + "'<'","'>'","LEQ","GEQ","LSH","RSH","'+'","'-'","'*'","'/'","'%'","UNARY","'!'", + "'~'","'#'","'('","')'","start","exp1","exp","@1","@2","@3","@4","@5","keywords", +--- 241,247 ---- + 332, 335, 337, 340, 343, 345, 347, 352, 354, 367 + }; + +! static const char * const yytname[] = { "$","error","$undefined.","INT","CHAR", + "NAME","ERROR","'?'","':'","','","OR","AND","'|'","'^'","'&'","EQUAL","NOTEQUAL", + "'<'","'>'","LEQ","GEQ","LSH","RSH","'+'","'-'","'*'","'/'","'%'","UNARY","'!'", + "'~'","'#'","'('","')'","start","exp1","exp","@1","@2","@3","@4","@5","keywords", +*************** +*** 341,354 **** + 26, 27, 23, 24, 25, 26, 27, 0, 9 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/local/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman + + This program 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 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, +--- 341,354 ---- + 26, 27, 23, 24, 25, 26, 27, 0, 9 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program 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. + + This program is distributed in the hope that it will be useful, +*************** +*** 360,365 **** +--- 360,369 ---- + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++ /* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ + + #ifndef alloca + #ifdef __GNUC__ +*************** +*** 433,442 **** +--- 437,454 ---- + + #ifdef YYPURE + #ifdef YYLSP_NEEDED ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) ++ #else + #define YYLEX yylex(&yylval, &yylloc) ++ #endif ++ #else /* not YYLSP_NEEDED */ ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, YYLEX_PARAM) + #else + #define YYLEX yylex(&yylval) + #endif ++ #endif /* not YYLSP_NEEDED */ + #endif + + /* If nonreentrant, generate the variables here */ +*************** +*** 484,497 **** + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (from, to, count) + char *from; + char *to; + int count; +--- 496,509 ---- + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (from, to, count) + char *from; + char *to; + int count; +*************** +*** 509,515 **** + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +--- 521,527 ---- + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +*************** +*** 522,528 **** + #endif + #endif + +! #line 184 "/usr/local/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +--- 534,540 ---- + #endif + #endif + +! #line 192 "/usr/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +*************** +*** 655,666 **** + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +--- 667,678 ---- + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +*************** +*** 1084,1090 **** + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 480 "/usr/local/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +--- 1096,1102 ---- + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 487 "/usr/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +diff -rcP gcc-2.7.2/collect2.c gcc-2.7.2.1-objc-960906/collect2.c +*** gcc-2.7.2/collect2.c Fri Sep 6 14:26:12 1996 +--- gcc-2.7.2.1-objc-960906/collect2.c Fri Sep 6 10:25:05 1996 +*************** +*** 255,261 **** + static char *c_file; /* .c for constructor/destructor list. */ + static char *o_file; /* .o for constructor/destructor list. */ + static char *export_file; /* .x for AIX export list. */ +- static int auto_export = 1; /* true if exporting everything. */ + char *ldout; /* File for ld errors. */ + static char *output_file; /* Output file for ld. */ + static char *nm_file_name; /* pathname of nm */ +--- 255,260 ---- +*************** +*** 1243,1257 **** + } + break; + +- #ifdef COLLECT_EXPORT_LIST +- case 'b': +- if ((!strncmp (arg, "-bE:", 4) +- || !strncmp (arg, "-bexport:", 9)) +- && strcmp (arg, "-bexport:/usr/lib/libg.exp")) +- auto_export = 0; +- break; +- #endif +- + case 'l': + if (first_file) + { +--- 1242,1247 ---- +*************** +*** 2554,2561 **** + break; + + default: /* not a constructor or destructor */ +- if (which_pass == PASS_OBJ && auto_export) +- add_to_list (&exports, name); + continue; + } + +--- 2544,2549 ---- +*************** +*** 2606,2667 **** + { + LDHDR ldh; + char *impbuf; +! int idx; + FSEEK (ldptr, ldsh.s_scnptr, BEGINNING); +! FREAD (&ldh, sizeof ldh, 1, ldptr); + /* read import library list */ + impbuf = alloca (ldh.l_istlen); + FSEEK (ldptr, ldh.l_impoff + ldsh.s_scnptr, BEGINNING); + FREAD (impbuf, ldh.l_istlen, 1, ldptr); +! idx = strlen (impbuf) + 1; +! idx += strlen (impbuf+idx) + 1; + if (debug) + fprintf (stderr, "LIBPATH=%s\n", impbuf); + prefix_from_string (impbuf, &libpath); +! while (idx < ldh.l_istlen) + { +! char *implib = impbuf + idx; + char *impmem = implib + strlen (implib) + 1; +! char *soname = 0; + LDFILE *libptr = NULL; + struct prefix_list *pl; + ARCHDR ah; +! idx += strlen (implib) + 1; +! if (!implib[0]) + continue; +! idx += strlen (impmem) + 1; +! if (*implib == '/') + { +! if (access (soname, R_OK) == 0) +! soname = implib; + } + else +! { +! char *temp = alloca (libpath.max_len + strlen (implib) + 1); +! for (pl = libpath.plist; pl; pl = pl->next) +! { +! strcpy (temp, pl->prefix); +! strcat (temp, implib); +! if (access (temp, R_OK) == 0) +! { +! soname = temp; +! break; +! } +! } +! } +! if (!soname) +! { +! fatal ("%s: library not found", implib); +! continue; +! } + if (debug) +! { +! if (impmem[0]) +! fprintf (stderr, "%s (%s)\n", soname, impmem); +! else +! fprintf (stderr, "%s\n", soname); +! } +! ah.ar_name[0] = 0; + do + { + /* scan imported shared objects for GCC GLOBAL ctors */ +--- 2594,2665 ---- + { + LDHDR ldh; + char *impbuf; +! int entry; +! + FSEEK (ldptr, ldsh.s_scnptr, BEGINNING); +! FREAD (&ldh, sizeof (ldh), 1, ldptr); + /* read import library list */ + impbuf = alloca (ldh.l_istlen); + FSEEK (ldptr, ldh.l_impoff + ldsh.s_scnptr, BEGINNING); + FREAD (impbuf, ldh.l_istlen, 1, ldptr); +! + if (debug) + fprintf (stderr, "LIBPATH=%s\n", impbuf); + prefix_from_string (impbuf, &libpath); +! +! /* skip LIBPATH and empty base and member fields */ +! impbuf += strlen (impbuf) + 3; +! for (entry = 1; entry < ldh.l_nimpid; ++entry) + { +! char *impath = impbuf; +! char *implib = impath + strlen (impath) + 1; + char *impmem = implib + strlen (implib) + 1; +! char *soname = NULL; +! char *trial; +! int pathlen; + LDFILE *libptr = NULL; + struct prefix_list *pl; + ARCHDR ah; +! +! impbuf = impmem + strlen (impmem) + 1; +! if (debug) +! fprintf (stderr, "PATH+BASE=%s%s\n", impath, implib); +! /* Skip AIX kernel exports */ +! if (*impath == '/' && *(impath+1) == '\0' +! && strcmp (implib, "unix") == 0) + continue; +! pathlen = strlen (impath); +! trial = alloca (MAX (pathlen + 1, libpath.max_len) +! + strlen (implib) + 1); +! if (*impath) + { +! strcpy (trial, impath); +! if (impath[pathlen - 1] != '/') +! trial[pathlen++] = '/'; +! strcpy (trial + pathlen, implib); +! if (access (trial, R_OK) == 0) +! soname = trial; + } + else +! for (pl = libpath.plist; pl; pl = pl->next) +! { +! strcpy (trial, pl->prefix); +! strcat (trial, implib); +! if (access (trial, R_OK) == 0) +! { +! soname = trial; +! break; +! } +! } +! +! if (! soname) +! fatal ("%s: library not found", implib); + if (debug) +! if (*impmem) +! fprintf (stderr, "%s (%s)\n", soname, impmem); +! else +! fprintf (stderr, "%s\n", soname); +! + do + { + /* scan imported shared objects for GCC GLOBAL ctors */ +*************** +*** 2671,2677 **** + if (TYPE (libptr) == ARTYPE) + { + LDFILE *memptr; +! if (!impmem[0]) + fatal ("%s: no archive member specified", soname); + ldahread (libptr, &ah); + if (strcmp (ah.ar_name, impmem)) +--- 2669,2675 ---- + if (TYPE (libptr) == ARTYPE) + { + LDFILE *memptr; +! if (! *impmem) + fatal ("%s: no archive member specified", soname); + ldahread (libptr, &ah); + if (strcmp (ah.ar_name, impmem)) +*************** +*** 2688,2699 **** + if (!ldnshread (libptr, _LOADER, &soldsh)) + fatal ("%s: not an import library", soname); + FSEEK (libptr, soldsh.s_scnptr, BEGINNING); +! if (FREAD (&soldh, sizeof soldh, 1, libptr) != 1) + fatal ("%s: can't read loader section", soname); + /*fprintf (stderr, "\tscanning %s\n", soname);*/ + symcnt = soldh.l_nsyms; +! lsyms = (LDSYM*) alloca (symcnt * sizeof *lsyms); +! symcnt = FREAD (lsyms, sizeof *lsyms, symcnt, libptr); + ldstrings = alloca (soldh.l_stlen); + FSEEK (libptr, soldsh.s_scnptr+soldh.l_stoff, BEGINNING); + FREAD (ldstrings, soldh.l_stlen, 1, libptr); +--- 2686,2697 ---- + if (!ldnshread (libptr, _LOADER, &soldsh)) + fatal ("%s: not an import library", soname); + FSEEK (libptr, soldsh.s_scnptr, BEGINNING); +! if (FREAD (&soldh, sizeof (soldh), 1, libptr) != 1) + fatal ("%s: can't read loader section", soname); + /*fprintf (stderr, "\tscanning %s\n", soname);*/ + symcnt = soldh.l_nsyms; +! lsyms = (LDSYM*) alloca (symcnt * sizeof (*lsyms)); +! symcnt = FREAD (lsyms, sizeof (*lsyms), symcnt, libptr); + ldstrings = alloca (soldh.l_stlen); + FSEEK (libptr, soldsh.s_scnptr+soldh.l_stoff, BEGINNING); + FREAD (ldstrings, soldh.l_stlen, 1, libptr); +diff -rcP gcc-2.7.2/config/alpha/alpha.c gcc-2.7.2.1-objc-960906/config/alpha/alpha.c +*** gcc-2.7.2/config/alpha/alpha.c Fri Sep 6 14:29:37 1996 +--- gcc-2.7.2.1-objc-960906/config/alpha/alpha.c Fri Sep 6 10:28:23 1996 +*************** +*** 1247,1258 **** + FILE *file; + { + #ifdef MS_STAMP +! char *p; +! +! fprintf (file, "\t.verstamp %d %d ", MS_STAMP, LS_STAMP); +! for (p = version_string; *p != ' ' && *p != 0; p++) +! fprintf (file, "%c", *p == '.' ? ' ' : *p); +! fprintf (file, "\n"); + #endif + } + +--- 1247,1253 ---- + FILE *file; + { + #ifdef MS_STAMP +! fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP); + #endif + } + +diff -rcP gcc-2.7.2/config/alpha/alpha.h gcc-2.7.2.1-objc-960906/config/alpha/alpha.h +*** gcc-2.7.2/config/alpha/alpha.h Fri Sep 6 14:29:38 1996 +--- gcc-2.7.2.1-objc-960906/config/alpha/alpha.h Fri Sep 6 10:28:24 1996 +*************** +*** 2076,2081 **** +--- 2076,2084 ---- + /* The system headers under OSF/1 are C++-aware. */ + #define NO_IMPLICIT_EXTERN_C + ++ /* Also define __LANGUAGE_C__ when running fix-header. */ ++ #define FIXPROTO_INIT(CPPFILE) cpp_define (CPPFILE, "__LANGUAGE_C__") ++ + /* The linker will stick __main into the .init section. */ + #define HAS_INIT_SECTION + #define LD_INIT_SWITCH "-init" +diff -rcP gcc-2.7.2/config/arm/arm.md gcc-2.7.2.1-objc-960906/config/arm/arm.md +*** gcc-2.7.2/config/arm/arm.md Fri Sep 6 14:29:47 1996 +--- gcc-2.7.2.1-objc-960906/config/arm/arm.md Fri Sep 6 10:28:33 1996 +*************** +*** 3316,3324 **** + + (define_expand "movsicc" + [(set (match_operand:SI 0 "register_operand" "") +! (if_then_else (match_operand 1 "comparison_operator" "") +! (match_operand:SI 2 "arm_not_operand" "") +! (match_operand:SI 3 "register_operand" "")))] + "" + " + { +--- 3316,3324 ---- + + (define_expand "movsicc" + [(set (match_operand:SI 0 "register_operand" "") +! (if_then_else:SI (match_operand 1 "comparison_operator" "") +! (match_operand:SI 2 "arm_not_operand" "") +! (match_operand:SI 3 "register_operand" "")))] + "" + " + { +*************** +*** 3331,3339 **** + + (define_expand "movsfcc" + [(set (match_operand:SF 0 "register_operand" "") +! (if_then_else (match_operand 1 "comparison_operator" "") +! (match_operand:SF 2 "nonmemory_operand" "") +! (match_operand:SF 3 "register_operand" "")))] + "" + " + { +--- 3331,3339 ---- + + (define_expand "movsfcc" + [(set (match_operand:SF 0 "register_operand" "") +! (if_then_else:SF (match_operand 1 "comparison_operator" "") +! (match_operand:SF 2 "nonmemory_operand" "") +! (match_operand:SF 3 "register_operand" "")))] + "" + " + { +*************** +*** 3346,3354 **** + + (define_expand "movdfcc" + [(set (match_operand:DF 0 "register_operand" "") +! (if_then_else (match_operand 1 "comparison_operator" "") +! (match_operand:DF 2 "nonmemory_operand" "") +! (match_operand:DF 3 "register_operand" "")))] + "TARGET_HARD_FLOAT" + " + { +--- 3346,3354 ---- + + (define_expand "movdfcc" + [(set (match_operand:DF 0 "register_operand" "") +! (if_then_else:DF (match_operand 1 "comparison_operator" "") +! (match_operand:DF 2 "nonmemory_operand" "") +! (match_operand:DF 3 "register_operand" "")))] + "TARGET_HARD_FLOAT" + " + { +*************** +*** 3361,3370 **** + + (define_insn "*movsicc_insn" + [(set (match_operand:SI 0 "register_operand" "=r,r") +! (if_then_else (match_operator 1 "comparison_operator" +! [(reg 24) (const_int 0)]) +! (match_operand:SI 2 "arm_not_operand" "rI,K") +! (match_operand:SI 3 "register_operand" "0,0")))] + "" + "@ + mov%d1\\t%0, %2 +--- 3361,3370 ---- + + (define_insn "*movsicc_insn" + [(set (match_operand:SI 0 "register_operand" "=r,r") +! (if_then_else:SI (match_operator 1 "comparison_operator" +! [(reg 24) (const_int 0)]) +! (match_operand:SI 2 "arm_not_operand" "rI,K") +! (match_operand:SI 3 "register_operand" "0,0")))] + "" + "@ + mov%d1\\t%0, %2 +*************** +*** 3374,3383 **** + + (define_insn "*movsfcc_hard_insn" + [(set (match_operand:SF 0 "register_operand" "=f") +! (if_then_else (match_operator 1 "comparison_operator" +! [(reg 24) (const_int 0)]) +! (match_operand:SF 2 "register_operand" "f") +! (match_operand:SF 3 "register_operand" "0")))] + "TARGET_HARD_FLOAT" + "mvf%d1s\\t%0, %2" + [(set_attr "type" "ffarith") +--- 3374,3383 ---- + + (define_insn "*movsfcc_hard_insn" + [(set (match_operand:SF 0 "register_operand" "=f") +! (if_then_else:SF (match_operator 1 "comparison_operator" +! [(reg 24) (const_int 0)]) +! (match_operand:SF 2 "register_operand" "f") +! (match_operand:SF 3 "register_operand" "0")))] + "TARGET_HARD_FLOAT" + "mvf%d1s\\t%0, %2" + [(set_attr "type" "ffarith") +*************** +*** 3385,3394 **** + + (define_insn "*movsfcc_soft_insn" + [(set (match_operand:SF 0 "register_operand" "=r") +! (if_then_else (match_operator 1 "comparison_operator" +! [(reg 24) (const_int 0)]) +! (match_operand:SF 2 "register_operand" "r") +! (match_operand:SF 3 "register_operand" "0")))] + "TARGET_SOFT_FLOAT" + "mov%d1\\t%0, %2" + [(set_attr "type" "*") +--- 3385,3394 ---- + + (define_insn "*movsfcc_soft_insn" + [(set (match_operand:SF 0 "register_operand" "=r") +! (if_then_else:SF (match_operator 1 "comparison_operator" +! [(reg 24) (const_int 0)]) +! (match_operand:SF 2 "register_operand" "r") +! (match_operand:SF 3 "register_operand" "0")))] + "TARGET_SOFT_FLOAT" + "mov%d1\\t%0, %2" + [(set_attr "type" "*") +*************** +*** 3396,3405 **** + + (define_insn "*movdfcc_insn" + [(set (match_operand:DF 0 "register_operand" "=f") +! (if_then_else (match_operator 1 "comparison_operator" +! [(reg 24) (const_int 0)]) +! (match_operand:DF 2 "register_operand" "f") +! (match_operand:DF 3 "register_operand" "0")))] + "TARGET_HARD_FLOAT" + "mvf%d1d\\t%0, %2" + [(set_attr "type" "ffarith") +--- 3396,3405 ---- + + (define_insn "*movdfcc_insn" + [(set (match_operand:DF 0 "register_operand" "=f") +! (if_then_else:DF (match_operator 1 "comparison_operator" +! [(reg 24) (const_int 0)]) +! (match_operand:DF 2 "register_operand" "f") +! (match_operand:DF 3 "register_operand" "0")))] + "TARGET_HARD_FLOAT" + "mvf%d1d\\t%0, %2" + [(set_attr "type" "ffarith") +diff -rcP gcc-2.7.2/config/i386/freebsd.h gcc-2.7.2.1-objc-960906/config/i386/freebsd.h +*** gcc-2.7.2/config/i386/freebsd.h Fri Sep 6 14:30:23 1996 +--- gcc-2.7.2.1-objc-960906/config/i386/freebsd.h Fri Sep 6 10:29:08 1996 +*************** +*** 120,131 **** + #define TYPE_ASM_OP ".type" + #define SIZE_ASM_OP ".size" + +- /* This is how we tell the assembler that a symbol is weak. */ +- +- #define ASM_WEAKEN_LABEL(FILE,NAME) \ +- do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \ +- fputc ('\n', FILE); } while (0) +- + /* The following macro defines the format used to output the second + operand of the .type assembler directive. Different svr4 assemblers + expect various different forms for this operand. The one given here +--- 120,125 ---- +diff -rcP gcc-2.7.2/config/i386/next.h gcc-2.7.2.1-objc-960906/config/i386/next.h +*** gcc-2.7.2/config/i386/next.h Fri Sep 6 14:30:33 1996 +--- gcc-2.7.2.1-objc-960906/config/i386/next.h Fri Sep 6 10:29:17 1996 +*************** +*** 224,226 **** +--- 224,243 ---- + == void_type_node))) ? (SIZE) : 0) + + /* END Calling Convention CHANGES */ ++ ++ /* OBJC_MAX_STRUCT_BY_VALUE should be defined in the platform specific ++ configuration file. Some platforms, i386 on NeXTSTEP for example, ++ pass small structures as values on the stack versus through a ++ hidden pointer as for larger structures. In order for forwarding ++ to work properly, the ObjC runtime needs to know when the structure ++ is being passed by value or not so it can perform the appropriate ++ forwarding function. The value of OBJC_MAX_STRUCT_BY_VALUE should ++ be the maximum number of bytes for the size of the structure for it ++ to be passed as a value, so a value of 8 indicates that a structure ++ of size 8 gets passed as a value while a structure of size 9 gets ++ passed as a hidden pointer. ++ ++ Leave OBJC_MAX_STRUCT_BY_VALUE undefined for platforms that always pass ++ structures as hidden pointers. */ ++ ++ #define OBJC_MAX_STRUCT_BY_VALUE 7 +diff -rcP gcc-2.7.2/config/mips/mips.c gcc-2.7.2.1-objc-960906/config/mips/mips.c +*** gcc-2.7.2/config/mips/mips.c Fri Sep 6 14:32:06 1996 +--- gcc-2.7.2.1-objc-960906/config/mips/mips.c Fri Sep 6 10:30:47 1996 +*************** +*** 4928,4934 **** + enum machine_mode passed_mode = TYPE_MODE (passed_type); + rtx entry_parm; + +! if (TYPE_NEEDS_CONSTRUCTING (passed_type)) + { + passed_type = build_pointer_type (passed_type); + passed_mode = Pmode; +--- 4928,4934 ---- + enum machine_mode passed_mode = TYPE_MODE (passed_type); + rtx entry_parm; + +! if (TREE_ADDRESSABLE (passed_type)) + { + passed_type = build_pointer_type (passed_type); + passed_mode = Pmode; +diff -rcP gcc-2.7.2/config/msdos/top.sed gcc-2.7.2.1-objc-960906/config/msdos/top.sed +*** gcc-2.7.2/config/msdos/top.sed Fri Sep 6 14:32:26 1996 +--- gcc-2.7.2.1-objc-960906/config/msdos/top.sed Fri Sep 6 10:31:05 1996 +*************** +*** 19,27 **** + /^xmake_file=/ d + /^tmake_file=/ d + /^version=/ c\ +! version=2.7.2 + /^mainversion=/ c\ +! mainversion=2.7.2 + s/CC = cc/CC = gcc/ + s/:\$/: \$/g + s/^ \ *\.\// / +--- 19,27 ---- + /^xmake_file=/ d + /^tmake_file=/ d + /^version=/ c\ +! version=2.7.2.1 + /^mainversion=/ c\ +! mainversion=2.7.2.1 + s/CC = cc/CC = gcc/ + s/:\$/: \$/g + s/^ \ *\.\// / +diff -rcP gcc-2.7.2/config/pa/pa.h gcc-2.7.2.1-objc-960906/config/pa/pa.h +*** gcc-2.7.2/config/pa/pa.h Fri Sep 6 14:32:40 1996 +--- gcc-2.7.2.1-objc-960906/config/pa/pa.h Fri Sep 6 10:31:19 1996 +*************** +*** 1067,1073 **** + /* Passing structs by invisible reference uses \ + one general register. */ \ + if (arg_size > 2 \ +! || TYPE_NEEDS_CONSTRUCTING (DECL_ARG_TYPE (parm)))\ + arg_size = 1; \ + if (arg_size == 2 && i <= 2) \ + { \ +--- 1067,1073 ---- + /* Passing structs by invisible reference uses \ + one general register. */ \ + if (arg_size > 2 \ +! || TREE_ADDRESSABLE (DECL_ARG_TYPE (parm)))\ + arg_size = 1; \ + if (arg_size == 2 && i <= 2) \ + { \ +diff -rcP gcc-2.7.2/config/rs6000/rs6000.c gcc-2.7.2.1-objc-960906/config/rs6000/rs6000.c +*** gcc-2.7.2/config/rs6000/rs6000.c Fri Sep 6 14:33:04 1996 +--- gcc-2.7.2.1-objc-960906/config/rs6000/rs6000.c Fri Sep 6 10:31:43 1996 +*************** +*** 1164,1169 **** +--- 1164,1170 ---- + rtx orig_mem; + { + rtx mem = gen_rtx (MEM, mode, addr); ++ RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (orig_mem); + MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem); + MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (orig_mem); + return mem; +*************** +*** 1183,1188 **** +--- 1184,1191 ---- + expand_block_move (operands) + rtx operands[]; + { ++ rtx orig_dest = operands[0]; ++ rtx orig_src = operands[1]; + rtx bytes_rtx = operands[2]; + rtx align_rtx = operands[3]; + int constp = (GET_CODE (bytes_rtx) == CONST_INT); +*************** +*** 1224,1231 **** + return 0; + + /* Move the address into scratch registers. */ +! dest_reg = copy_addr_to_reg (XEXP (operands[0], 0)); +! src_reg = copy_addr_to_reg (XEXP (operands[1], 0)); + + if (TARGET_STRING) /* string instructions are available */ + { +--- 1227,1234 ---- + return 0; + + /* Move the address into scratch registers. */ +! dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0)); +! src_reg = copy_addr_to_reg (XEXP (orig_src, 0)); + + if (TARGET_STRING) /* string instructions are available */ + { +*************** +*** 1242,1249 **** + && !fixed_regs[12]) + { + move_bytes = (bytes > 32) ? 32 : bytes; +! emit_insn (gen_movstrsi_8reg (dest_reg, +! src_reg, + GEN_INT ((move_bytes == 32) ? 0 : move_bytes), + align_rtx)); + } +--- 1245,1252 ---- + && !fixed_regs[12]) + { + move_bytes = (bytes > 32) ? 32 : bytes; +! emit_insn (gen_movstrsi_8reg (expand_block_move_mem (BLKmode, dest_reg, orig_dest), +! expand_block_move_mem (BLKmode, src_reg, orig_src), + GEN_INT ((move_bytes == 32) ? 0 : move_bytes), + align_rtx)); + } +*************** +*** 1256,1263 **** + && !fixed_regs[12]) + { + move_bytes = (bytes > 24) ? 24 : bytes; +! emit_insn (gen_movstrsi_6reg (dest_reg, +! src_reg, + GEN_INT (move_bytes), + align_rtx)); + } +--- 1259,1266 ---- + && !fixed_regs[12]) + { + move_bytes = (bytes > 24) ? 24 : bytes; +! emit_insn (gen_movstrsi_6reg (expand_block_move_mem (BLKmode, dest_reg, orig_dest), +! expand_block_move_mem (BLKmode, src_reg, orig_src), + GEN_INT (move_bytes), + align_rtx)); + } +*************** +*** 1268,1283 **** + && !fixed_regs[12]) + { + move_bytes = (bytes > 16) ? 16 : bytes; +! emit_insn (gen_movstrsi_4reg (dest_reg, +! src_reg, + GEN_INT (move_bytes), + align_rtx)); + } + else if (bytes > 4 && !TARGET_64BIT) + { /* move up to 8 bytes at a time */ + move_bytes = (bytes > 8) ? 8 : bytes; +! emit_insn (gen_movstrsi_2reg (dest_reg, +! src_reg, + GEN_INT (move_bytes), + align_rtx)); + } +--- 1271,1286 ---- + && !fixed_regs[12]) + { + move_bytes = (bytes > 16) ? 16 : bytes; +! emit_insn (gen_movstrsi_4reg (expand_block_move_mem (BLKmode, dest_reg, orig_dest), +! expand_block_move_mem (BLKmode, src_reg, orig_src), + GEN_INT (move_bytes), + align_rtx)); + } + else if (bytes > 4 && !TARGET_64BIT) + { /* move up to 8 bytes at a time */ + move_bytes = (bytes > 8) ? 8 : bytes; +! emit_insn (gen_movstrsi_2reg (expand_block_move_mem (BLKmode, dest_reg, orig_dest), +! expand_block_move_mem (BLKmode, src_reg, orig_src), + GEN_INT (move_bytes), + align_rtx)); + } +*************** +*** 1285,1312 **** + { /* move 4 bytes */ + move_bytes = 4; + tmp_reg = gen_reg_rtx (SImode); +! emit_move_insn (tmp_reg, gen_rtx (MEM, SImode, src_reg)); +! emit_move_insn (gen_rtx (MEM, SImode, dest_reg), tmp_reg); + } + else if (bytes == 2 && (align >= 2 || !STRICT_ALIGNMENT)) + { /* move 2 bytes */ + move_bytes = 2; + tmp_reg = gen_reg_rtx (HImode); +! emit_move_insn (tmp_reg, gen_rtx (MEM, HImode, src_reg)); +! emit_move_insn (gen_rtx (MEM, HImode, dest_reg), tmp_reg); + } + else if (bytes == 1) /* move 1 byte */ + { + move_bytes = 1; + tmp_reg = gen_reg_rtx (QImode); +! emit_move_insn (tmp_reg, gen_rtx (MEM, QImode, src_reg)); +! emit_move_insn (gen_rtx (MEM, QImode, dest_reg), tmp_reg); + } + else + { /* move up to 4 bytes at a time */ + move_bytes = (bytes > 4) ? 4 : bytes; +! emit_insn (gen_movstrsi_1reg (dest_reg, +! src_reg, + GEN_INT (move_bytes), + align_rtx)); + } +--- 1288,1315 ---- + { /* move 4 bytes */ + move_bytes = 4; + tmp_reg = gen_reg_rtx (SImode); +! emit_move_insn (tmp_reg, expand_block_move_mem (SImode, src_reg, orig_src)); +! emit_move_insn (expand_block_move_mem (SImode, dest_reg, orig_dest), tmp_reg); + } + else if (bytes == 2 && (align >= 2 || !STRICT_ALIGNMENT)) + { /* move 2 bytes */ + move_bytes = 2; + tmp_reg = gen_reg_rtx (HImode); +! emit_move_insn (tmp_reg, expand_block_move_mem (HImode, src_reg, orig_src)); +! emit_move_insn (expand_block_move_mem (HImode, dest_reg, orig_dest), tmp_reg); + } + else if (bytes == 1) /* move 1 byte */ + { + move_bytes = 1; + tmp_reg = gen_reg_rtx (QImode); +! emit_move_insn (tmp_reg, expand_block_move_mem (QImode, src_reg, orig_src)); +! emit_move_insn (expand_block_move_mem (QImode, dest_reg, orig_dest), tmp_reg); + } + else + { /* move up to 4 bytes at a time */ + move_bytes = (bytes > 4) ? 4 : bytes; +! emit_insn (gen_movstrsi_1reg (expand_block_move_mem (BLKmode, dest_reg, orig_dest), +! expand_block_move_mem (BLKmode, src_reg, orig_src), + GEN_INT (move_bytes), + align_rtx)); + } +*************** +*** 1337,1362 **** + } + + /* Generate the appropriate load and store, saving the stores for later */ +! if (bytes >= 4 && (align >= 4 || !STRICT_ALIGNMENT)) + { + move_bytes = 4; + tmp_reg = gen_reg_rtx (SImode); +! emit_insn (gen_movsi (tmp_reg, gen_rtx (MEM, SImode, src_addr))); +! stores[ num_reg++ ] = gen_movsi (gen_rtx (MEM, SImode, dest_addr), tmp_reg); + } + else if (bytes >= 2 && (align >= 2 || !STRICT_ALIGNMENT)) + { + move_bytes = 2; + tmp_reg = gen_reg_rtx (HImode); +! emit_insn (gen_movhi (tmp_reg, gen_rtx (MEM, HImode, src_addr))); +! stores[ num_reg++ ] = gen_movhi (gen_rtx (MEM, HImode, dest_addr), tmp_reg); + } + else + { + move_bytes = 1; + tmp_reg = gen_reg_rtx (QImode); +! emit_insn (gen_movqi (tmp_reg, gen_rtx (MEM, QImode, src_addr))); +! stores[ num_reg++ ] = gen_movqi (gen_rtx (MEM, QImode, dest_addr), tmp_reg); + } + + if (num_reg >= MAX_MOVE_REG) +--- 1340,1372 ---- + } + + /* Generate the appropriate load and store, saving the stores for later */ +! if (bytes >= 8 && TARGET_64BIT && (align >= 8 || !STRICT_ALIGNMENT)) +! { +! move_bytes = 8; +! tmp_reg = gen_reg_rtx (DImode); +! emit_insn (gen_movdi (tmp_reg, expand_block_move_mem (DImode, src_addr, orig_src))); +! stores[ num_reg++ ] = gen_movdi (expand_block_move_mem (DImode, dest_addr, orig_dest), tmp_reg); +! } +! else if (bytes >= 4 && (align >= 4 || !STRICT_ALIGNMENT)) + { + move_bytes = 4; + tmp_reg = gen_reg_rtx (SImode); +! emit_insn (gen_movsi (tmp_reg, expand_block_move_mem (SImode, src_addr, orig_src))); +! stores[ num_reg++ ] = gen_movsi (expand_block_move_mem (SImode, dest_addr, orig_dest), tmp_reg); + } + else if (bytes >= 2 && (align >= 2 || !STRICT_ALIGNMENT)) + { + move_bytes = 2; + tmp_reg = gen_reg_rtx (HImode); +! emit_insn (gen_movsi (tmp_reg, expand_block_move_mem (HImode, src_addr, orig_src))); +! stores[ num_reg++ ] = gen_movhi (expand_block_move_mem (HImode, dest_addr, orig_dest), tmp_reg); + } + else + { + move_bytes = 1; + tmp_reg = gen_reg_rtx (QImode); +! emit_insn (gen_movsi (tmp_reg, expand_block_move_mem (QImode, src_addr, orig_src))); +! stores[ num_reg++ ] = gen_movqi (expand_block_move_mem (QImode, dest_addr, orig_dest), tmp_reg); + } + + if (num_reg >= MAX_MOVE_REG) +*************** +*** 1367,1377 **** + } + } + +! if (num_reg > 0) +! { +! for (i = 0; i < num_reg; i++) +! emit_insn (stores[i]); +! } + } + + return 1; +--- 1377,1384 ---- + } + } + +! for (i = 0; i < num_reg; i++) +! emit_insn (stores[i]); + } + + return 1; +*************** +*** 2611,2616 **** +--- 2618,2626 ---- + { + rs6000_stack_t *info = rs6000_stack_info (); + char *store_reg = (TARGET_64BIT) ? "\tstd %s,%d(%s)" : "\t{st|stw} %s,%d(%s)\n"; ++ int reg_size = info->reg_size; ++ int sp_reg = 1; ++ int sp_offset = 0; + + if (TARGET_DEBUG_STACK) + debug_stack_info (info); +*************** +*** 2644,2655 **** + common_mode_defined = 1; + } + + /* If we use the link register, get it into r0. */ + if (info->lr_save_p) + asm_fprintf (file, "\tmflr %s\n", reg_names[0]); + + /* If we need to save CR, put it into r12. */ +! if (info->cr_save_p) + asm_fprintf (file, "\tmfcr %s\n", reg_names[12]); + + /* Do any required saving of fpr's. If only one or two to save, do it +--- 2654,2691 ---- + common_mode_defined = 1; + } + ++ /* For V.4, update stack before we do any saving and set back pointer. */ ++ #ifdef USING_SVR4_H ++ if (info->push_p && TARGET_V4_CALLS) ++ { ++ if (info->total_size < 32767) ++ { ++ asm_fprintf (file, ++ (!TARGET_64BIT) ? "\t{stu|stwu} %s,%d(%s)\n" : "\tstdu %s,%d(%s)\n", ++ reg_names[1], - info->total_size, reg_names[1]); ++ sp_offset = info->total_size; ++ } ++ else ++ { ++ int neg_size = - info->total_size; ++ sp_reg = 12; ++ asm_fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]); ++ asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n", ++ reg_names[0], (neg_size >> 16) & 0xffff, ++ reg_names[0], reg_names[0], neg_size & 0xffff); ++ asm_fprintf (file, ++ (!TARGET_64BIT) ? "\t{stux|stwux} %s,%s,%s\n" : "\tstdux %s,%s,%s\n", ++ reg_names[1], reg_names[1], reg_names[0]); ++ } ++ } ++ #endif ++ + /* If we use the link register, get it into r0. */ + if (info->lr_save_p) + asm_fprintf (file, "\tmflr %s\n", reg_names[0]); + + /* If we need to save CR, put it into r12. */ +! if (info->cr_save_p && sp_reg != 12) + asm_fprintf (file, "\tmfcr %s\n", reg_names[12]); + + /* Do any required saving of fpr's. If only one or two to save, do it +*************** +*** 2658,2667 **** + if (FP_SAVE_INLINE (info->first_fp_reg_save)) + { + int regno = info->first_fp_reg_save; +! int loc = info->fp_save_offset; + + for ( ; regno < 64; regno++, loc += 8) +! asm_fprintf (file, "\tstfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[1]); + } + else if (info->first_fp_reg_save != 64) + asm_fprintf (file, "\tbl %s%d%s\n", SAVE_FP_PREFIX, +--- 2694,2703 ---- + if (FP_SAVE_INLINE (info->first_fp_reg_save)) + { + int regno = info->first_fp_reg_save; +! int loc = info->fp_save_offset + sp_offset; + + for ( ; regno < 64; regno++, loc += 8) +! asm_fprintf (file, "\tstfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]); + } + else if (info->first_fp_reg_save != 64) + asm_fprintf (file, "\tbl %s%d%s\n", SAVE_FP_PREFIX, +*************** +*** 2671,2699 **** + if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) + { + int regno = info->first_gp_reg_save; +! int loc = info->gp_save_offset; +! int reg_size = (TARGET_64BIT) ? 8 : 4; + + for ( ; regno < 32; regno++, loc += reg_size) +! asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[1]); + } + + else if (info->first_gp_reg_save != 32) + asm_fprintf (file, "\t{stm|stmw} %s,%d(%s)\n", + reg_names[info->first_gp_reg_save], +! info->gp_save_offset, +! reg_names[1]); + + /* Save lr if we used it. */ + if (info->lr_save_p) +! asm_fprintf (file, store_reg, reg_names[0], info->lr_save_offset, reg_names[1]); + + /* Save CR if we use any that must be preserved. */ + if (info->cr_save_p) +! asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset, reg_names[1]); + +! /* Update stack and set back pointer. */ +! if (info->push_p) + { + if (info->total_size < 32767) + asm_fprintf (file, +--- 2707,2750 ---- + if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) + { + int regno = info->first_gp_reg_save; +! int loc = info->gp_save_offset + sp_offset; + + for ( ; regno < 32; regno++, loc += reg_size) +! asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[sp_reg]); + } + + else if (info->first_gp_reg_save != 32) + asm_fprintf (file, "\t{stm|stmw} %s,%d(%s)\n", + reg_names[info->first_gp_reg_save], +! info->gp_save_offset + sp_offset, +! reg_names[sp_reg]); + + /* Save lr if we used it. */ + if (info->lr_save_p) +! asm_fprintf (file, store_reg, reg_names[0], info->lr_save_offset + sp_offset, +! reg_names[sp_reg]); + + /* Save CR if we use any that must be preserved. */ + if (info->cr_save_p) +! { +! if (sp_reg == 12) /* If r12 is used to hold the original sp, copy cr now */ +! { +! asm_fprintf (file, "\tmfcr %s\n", reg_names[0]); +! asm_fprintf (file, store_reg, reg_names[0], +! info->cr_save_offset + sp_offset, +! reg_names[sp_reg]); +! } +! else +! asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset + sp_offset, +! reg_names[sp_reg]); +! } + +! /* Update stack and set back pointer and we have already done so for V.4. */ +! if (info->push_p +! #ifdef USING_SVR4_H +! && TARGET_AIX_CALLS +! #endif +! ) + { + if (info->total_size < 32767) + asm_fprintf (file, +*************** +*** 2791,2796 **** +--- 2842,2849 ---- + rs6000_stack_t *info = rs6000_stack_info (); + char *load_reg = (TARGET_64BIT) ? "\tld %s,%d(%s)" : "\t{l|lwz} %s,%d(%s)\n"; + rtx insn = get_last_insn (); ++ int sp_reg = 1; ++ int sp_offset = 0; + int i; + + /* Forget about any temporaries created */ +*************** +*** 2808,2816 **** + we know what size to update it with. */ + if (frame_pointer_needed || current_function_calls_alloca + || info->total_size > 32767) +! asm_fprintf (file, load_reg, reg_names[1], 0, reg_names[1]); + else if (info->push_p) + { + if (TARGET_NEW_MNEMONICS) + asm_fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], info->total_size); + else +--- 2861,2883 ---- + we know what size to update it with. */ + if (frame_pointer_needed || current_function_calls_alloca + || info->total_size > 32767) +! { +! /* Under V.4, don't reset the stack pointer until after we're done +! loading the saved registers. */ +! #ifdef USING_SVR4_H +! if (TARGET_V4_CALLS) +! sp_reg = 11; +! #endif +! +! asm_fprintf (file, load_reg, reg_names[sp_reg], 0, reg_names[1]); +! } + else if (info->push_p) + { ++ #ifdef USING_SVR4_H ++ if (TARGET_V4_CALLS) ++ sp_offset = info->total_size; ++ else ++ #endif + if (TARGET_NEW_MNEMONICS) + asm_fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], info->total_size); + else +*************** +*** 2819,2829 **** + + /* Get the old lr if we saved it. */ + if (info->lr_save_p) +! asm_fprintf (file, load_reg, reg_names[0], info->lr_save_offset, reg_names[1]); + + /* Get the old cr if we saved it. */ + if (info->cr_save_p) +! asm_fprintf (file, load_reg, reg_names[12], info->cr_save_offset, reg_names[1]); + + /* Set LR here to try to overlap restores below. */ + if (info->lr_save_p) +--- 2886,2896 ---- + + /* Get the old lr if we saved it. */ + if (info->lr_save_p) +! asm_fprintf (file, load_reg, reg_names[0], info->lr_save_offset + sp_offset, reg_names[sp_reg]); + + /* Get the old cr if we saved it. */ + if (info->cr_save_p) +! asm_fprintf (file, load_reg, reg_names[12], info->cr_save_offset + sp_offset, reg_names[sp_reg]); + + /* Set LR here to try to overlap restores below. */ + if (info->lr_save_p) +*************** +*** 2833,2859 **** + if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) + { + int regno = info->first_gp_reg_save; +! int loc = info->gp_save_offset; + int reg_size = (TARGET_64BIT) ? 8 : 4; + + for ( ; regno < 32; regno++, loc += reg_size) +! asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[1]); + } + + else if (info->first_gp_reg_save != 32) + asm_fprintf (file, "\t{lm|lmw} %s,%d(%s)\n", + reg_names[info->first_gp_reg_save], +! info->gp_save_offset, +! reg_names[1]); + + /* Restore fpr's if we can do it without calling a function. */ + if (FP_SAVE_INLINE (info->first_fp_reg_save)) + { + int regno = info->first_fp_reg_save; +! int loc = info->fp_save_offset; + + for ( ; regno < 64; regno++, loc += 8) +! asm_fprintf (file, "\tlfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[1]); + } + + /* If we saved cr, restore it here. Just those of cr2, cr3, and cr4 +--- 2900,2926 ---- + if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) + { + int regno = info->first_gp_reg_save; +! int loc = info->gp_save_offset + sp_offset; + int reg_size = (TARGET_64BIT) ? 8 : 4; + + for ( ; regno < 32; regno++, loc += reg_size) +! asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[sp_reg]); + } + + else if (info->first_gp_reg_save != 32) + asm_fprintf (file, "\t{lm|lmw} %s,%d(%s)\n", + reg_names[info->first_gp_reg_save], +! info->gp_save_offset + sp_offset, +! reg_names[sp_reg]); + + /* Restore fpr's if we can do it without calling a function. */ + if (FP_SAVE_INLINE (info->first_fp_reg_save)) + { + int regno = info->first_fp_reg_save; +! int loc = info->fp_save_offset + sp_offset; + + for ( ; regno < 64; regno++, loc += 8) +! asm_fprintf (file, "\tlfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]); + } + + /* If we saved cr, restore it here. Just those of cr2, cr3, and cr4 +*************** +*** 2863,2868 **** +--- 2930,2948 ---- + (regs_ever_live[70] != 0) * 0x20 + + (regs_ever_live[71] != 0) * 0x10 + + (regs_ever_live[72] != 0) * 0x8, reg_names[12]); ++ ++ /* If this is V.4, unwind the stack pointer after all of the loads have been done */ ++ #ifdef USING_SVR4_H ++ if (sp_offset) ++ { ++ if (TARGET_NEW_MNEMONICS) ++ asm_fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], sp_offset); ++ else ++ asm_fprintf (file, "\tcal %s,%d(%s)\n", reg_names[1], sp_offset, reg_names[1]); ++ } ++ else if (sp_reg != 1) ++ asm_fprintf (file, "\tmr %s,%s\n", reg_names[1], reg_names[sp_reg]); ++ #endif + + /* If we have to restore more than two FP registers, branch to the + restore function. It will return to our caller. */ +diff -rcP gcc-2.7.2/config/rs6000/rs6000.md gcc-2.7.2.1-objc-960906/config/rs6000/rs6000.md +*** gcc-2.7.2/config/rs6000/rs6000.md Fri Sep 6 14:33:09 1996 +--- gcc-2.7.2.1-objc-960906/config/rs6000/rs6000.md Fri Sep 6 10:31:47 1996 +*************** +*** 814,820 **** + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (not:SI (match_dup 1)))] + "" +! "nor. %0,%2,%1" + [(set_attr "type" "compare")]) + + (define_insn "" +--- 814,820 ---- + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (not:SI (match_dup 1)))] + "" +! "nor. %0,%1,%1" + [(set_attr "type" "compare")]) + + (define_insn "" +*************** +*** 1492,1498 **** + (set (reg:SI 4) + (umod:SI (reg:SI 3) (reg:SI 4))) + (clobber (match_scratch:SI 0 "=l")) +! (clobber (reg:SI 0))] + "! TARGET_POWER && ! TARGET_POWERPC" + "bla __divus") + +--- 1492,1500 ---- + (set (reg:SI 4) + (umod:SI (reg:SI 3) (reg:SI 4))) + (clobber (match_scratch:SI 0 "=l")) +! (clobber (reg:SI 0)) +! (clobber (match_scratch:CC 1 "=x")) +! (clobber (reg:CC 69))] + "! TARGET_POWER && ! TARGET_POWERPC" + "bla __divus") + +*************** +*** 1507,1513 **** + [(set (reg:SI 3) + (udiv:SI (reg:SI 3) (reg:SI 4))) + (clobber (match_scratch:SI 0 "=l")) +! (clobber (reg:SI 0))] + "! TARGET_POWER && ! TARGET_POWERPC" + "bla __quous") + +--- 1509,1517 ---- + [(set (reg:SI 3) + (udiv:SI (reg:SI 3) (reg:SI 4))) + (clobber (match_scratch:SI 0 "=l")) +! (clobber (reg:SI 0)) +! (clobber (match_scratch:CC 1 "=x")) +! (clobber (reg:CC 69))] + "! TARGET_POWER && ! TARGET_POWERPC" + "bla __quous") + +*************** +*** 4823,4832 **** + ;; Argument 3 is the alignment + + (define_expand "movstrsi" +! [(parallel [(set (match_operand:BLK 0 "memory_operand" "") +! (match_operand:BLK 1 "memory_operand" "")) +! (use (match_operand:SI 2 "general_operand" "")) +! (use (match_operand:SI 3 "immediate_operand" ""))])] + "" + " + { +--- 4827,4836 ---- + ;; Argument 3 is the alignment + + (define_expand "movstrsi" +! [(parallel [(set (match_operand:BLK 0 "" "") +! (match_operand:BLK 1 "" "")) +! (use (match_operand:SI 2 "" "")) +! (use (match_operand:SI 3 "" ""))])] + "" + " + { +*************** +*** 4839,4848 **** + ;; Move up to 32 bytes at a time. The fixed registers are needed because the + ;; register allocator doesn't have a clue about allocating 8 word registers + (define_expand "movstrsi_8reg" +! [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) +! (mem:BLK (match_operand:SI 1 "register_operand" ""))) +! (use (match_operand:SI 2 "immediate_operand" "")) +! (use (match_operand:SI 3 "immediate_operand" "")) + (clobber (reg:SI 5)) + (clobber (reg:SI 6)) + (clobber (reg:SI 7)) +--- 4843,4852 ---- + ;; Move up to 32 bytes at a time. The fixed registers are needed because the + ;; register allocator doesn't have a clue about allocating 8 word registers + (define_expand "movstrsi_8reg" +! [(parallel [(set (match_operand 0 "" "") +! (match_operand 1 "" "")) +! (use (match_operand 2 "" "")) +! (use (match_operand 3 "" "")) + (clobber (reg:SI 5)) + (clobber (reg:SI 6)) + (clobber (reg:SI 7)) +*************** +*** 4875,4881 **** + && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 5" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "length" "8")]) + + (define_insn "" + [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) +--- 4879,4886 ---- + && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 5" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "type" "load") +! (set_attr "length" "8")]) + + (define_insn "" + [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) +*************** +*** 4897,4911 **** + && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 5" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "length" "8")]) + + ;; Move up to 24 bytes at a time. The fixed registers are needed because the + ;; register allocator doesn't have a clue about allocating 6 word registers + (define_expand "movstrsi_6reg" +! [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) +! (mem:BLK (match_operand:SI 1 "register_operand" ""))) +! (use (match_operand:SI 2 "immediate_operand" "")) +! (use (match_operand:SI 3 "immediate_operand" "")) + (clobber (reg:SI 7)) + (clobber (reg:SI 8)) + (clobber (reg:SI 9)) +--- 4902,4917 ---- + && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 5" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "type" "load") +! (set_attr "length" "8")]) + + ;; Move up to 24 bytes at a time. The fixed registers are needed because the + ;; register allocator doesn't have a clue about allocating 6 word registers + (define_expand "movstrsi_6reg" +! [(parallel [(set (match_operand 0 "" "") +! (match_operand 1 "" "")) +! (use (match_operand 2 "" "")) +! (use (match_operand 3 "" "")) + (clobber (reg:SI 7)) + (clobber (reg:SI 8)) + (clobber (reg:SI 9)) +*************** +*** 4934,4940 **** + && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 7" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "length" "8")]) + + (define_insn "" + [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) +--- 4940,4947 ---- + && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 7" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "type" "load") +! (set_attr "length" "8")]) + + (define_insn "" + [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) +*************** +*** 4954,4968 **** + && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 7" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "length" "8")]) + + ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems + ;; with TImode + (define_expand "movstrsi_4reg" +! [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) +! (mem:BLK (match_operand:SI 1 "register_operand" ""))) +! (use (match_operand:SI 2 "immediate_operand" "")) +! (use (match_operand:SI 3 "immediate_operand" "")) + (clobber (reg:SI 9)) + (clobber (reg:SI 10)) + (clobber (reg:SI 11)) +--- 4961,4976 ---- + && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 7" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "type" "load") +! (set_attr "length" "8")]) + + ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems + ;; with TImode + (define_expand "movstrsi_4reg" +! [(parallel [(set (match_operand 0 "" "") +! (match_operand 1 "" "")) +! (use (match_operand 2 "" "")) +! (use (match_operand 3 "" "")) + (clobber (reg:SI 9)) + (clobber (reg:SI 10)) + (clobber (reg:SI 11)) +*************** +*** 4987,4993 **** + && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 9" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "length" "8")]) + + (define_insn "" + [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) +--- 4995,5002 ---- + && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 9" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "type" "load") +! (set_attr "length" "8")]) + + (define_insn "" + [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) +*************** +*** 5005,5018 **** + && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 9" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "length" "8")]) + + ;; Move up to 8 bytes at a time. + (define_expand "movstrsi_2reg" +! [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) +! (mem:BLK (match_operand:SI 1 "register_operand" ""))) +! (use (match_operand:SI 2 "immediate_operand" "")) +! (use (match_operand:SI 3 "immediate_operand" "")) + (clobber (match_scratch:DI 4 "")) + (clobber (match_scratch:SI 5 ""))])] + "TARGET_STRING && !TARGET_64BIT" +--- 5014,5028 ---- + && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12) + && REGNO (operands[4]) == 9" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "type" "load") +! (set_attr "length" "8")]) + + ;; Move up to 8 bytes at a time. + (define_expand "movstrsi_2reg" +! [(parallel [(set (match_operand 0 "" "") +! (match_operand 1 "" "")) +! (use (match_operand 2 "" "")) +! (use (match_operand 3 "" "")) + (clobber (match_scratch:DI 4 "")) + (clobber (match_scratch:SI 5 ""))])] + "TARGET_STRING && !TARGET_64BIT" +*************** +*** 5028,5034 **** + "TARGET_STRING && TARGET_POWER && !TARGET_64BIT + && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "length" "8")]) + + (define_insn "" + [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) +--- 5038,5045 ---- + "TARGET_STRING && TARGET_POWER && !TARGET_64BIT + && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "type" "load") +! (set_attr "length" "8")]) + + (define_insn "" + [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) +*************** +*** 5040,5053 **** + "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT + && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "length" "8")]) + + ;; Move up to 4 bytes at a time. + (define_expand "movstrsi_1reg" +! [(parallel [(set (mem:BLK (match_operand:SI 0 "register_operand" "")) +! (mem:BLK (match_operand:SI 1 "register_operand" ""))) +! (use (match_operand:SI 2 "immediate_operand" "")) +! (use (match_operand:SI 3 "immediate_operand" "")) + (clobber (match_scratch:SI 4 "")) + (clobber (match_scratch:SI 5 ""))])] + "TARGET_STRING" +--- 5051,5065 ---- + "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT + && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "type" "load") +! (set_attr "length" "8")]) + + ;; Move up to 4 bytes at a time. + (define_expand "movstrsi_1reg" +! [(parallel [(set (match_operand 0 "" "") +! (match_operand 1 "" "")) +! (use (match_operand 2 "" "")) +! (use (match_operand 3 "" "")) + (clobber (match_scratch:SI 4 "")) + (clobber (match_scratch:SI 5 ""))])] + "TARGET_STRING" +*************** +*** 5063,5069 **** + "TARGET_STRING && TARGET_POWER + && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "length" "8")]) + + (define_insn "" + [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) +--- 5075,5082 ---- + "TARGET_STRING && TARGET_POWER + && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "type" "load") +! (set_attr "length" "8")]) + + (define_insn "" + [(set (mem:BLK (match_operand:SI 0 "register_operand" "b")) +*************** +*** 5075,5081 **** + "TARGET_STRING && !TARGET_POWER + && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "length" "8")]) + + + ;; Define insns that do load or store with update. Some of these we can +--- 5088,5095 ---- + "TARGET_STRING && !TARGET_POWER + && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" + "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" +! [(set_attr "type" "load") +! (set_attr "length" "8")]) + + + ;; Define insns that do load or store with update. Some of these we can +diff -rcP gcc-2.7.2/config/sparc/sparc.h gcc-2.7.2.1-objc-960906/config/sparc/sparc.h +*** gcc-2.7.2/config/sparc/sparc.h Fri Sep 6 14:33:26 1996 +--- gcc-2.7.2.1-objc-960906/config/sparc/sparc.h Fri Sep 6 10:32:05 1996 +*************** +*** 621,638 **** + for (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno++) \ + fixed_regs[regno] = 1; \ + } \ +! if (! TARGET_APP_REGS) \ +! { \ +! fixed_regs[2] = 1; \ +! fixed_regs[3] = 1; \ +! fixed_regs[4] = 1; \ +! } \ +! else \ +! { \ +! fixed_regs[2] = 0; \ +! fixed_regs[3] = 0; \ +! fixed_regs[4] = TARGET_MEDANY != 0; \ +! } \ + if (TARGET_FLAT) \ + { \ + /* Let the compiler believe the frame pointer is still \ +--- 621,630 ---- + for (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno++) \ + fixed_regs[regno] = 1; \ + } \ +! /* Don't unfix g2-g4 if they were fixed with -ffixed-. */ \ +! fixed_regs[2] |= ! TARGET_APP_REGS; \ +! fixed_regs[3] |= ! TARGET_APP_REGS; \ +! fixed_regs[4] |= ! TARGET_APP_REGS || TARGET_MEDANY; \ + if (TARGET_FLAT) \ + { \ + /* Let the compiler believe the frame pointer is still \ +diff -rcP gcc-2.7.2/config/svr4.h gcc-2.7.2.1-objc-960906/config/svr4.h +*** gcc-2.7.2/config/svr4.h Fri Sep 6 14:29:21 1996 +--- gcc-2.7.2.1-objc-960906/config/svr4.h Fri Sep 6 10:28:09 1996 +*************** +*** 273,287 **** + #define DBX_BLOCKS_FUNCTION_RELATIVE 1 + + /* When using stabs, gcc2_compiled must be a stabs entry, not an +! ordinary symbol, or gdb won't see it. The stabs entry must be +! before the N_SO in order for gdb to find it. */ + + #define ASM_IDENTIFY_GCC(FILE) \ + do \ + { \ + if (write_symbols != DBX_DEBUG) \ + fputs ("gcc2_compiled.:\n", FILE); \ +! else \ + fputs ("\t.stabs\t\"gcc2_compiled.\", 0x3c, 0, 0, 0\n", FILE); \ + } \ + while (0) +--- 273,295 ---- + #define DBX_BLOCKS_FUNCTION_RELATIVE 1 + + /* When using stabs, gcc2_compiled must be a stabs entry, not an +! ordinary symbol, or gdb won't see it. Furthermore, since gdb reads +! the input piecemeal, starting with each N_SO, it's a lot easier if +! the gcc2 flag symbol is *after* the N_SO rather than before it. So +! we emit an N_OPT stab there. */ + + #define ASM_IDENTIFY_GCC(FILE) \ + do \ + { \ + if (write_symbols != DBX_DEBUG) \ + fputs ("gcc2_compiled.:\n", FILE); \ +! } \ +! while (0) +! +! #define ASM_IDENTIFY_GCC_AFTER_SOURCE(FILE) \ +! do \ +! { \ +! if (write_symbols == DBX_DEBUG) \ + fputs ("\t.stabs\t\"gcc2_compiled.\", 0x3c, 0, 0, 0\n", FILE); \ + } \ + while (0) +diff -rcP gcc-2.7.2/config/vax/vax.h gcc-2.7.2.1-objc-960906/config/vax/vax.h +*** gcc-2.7.2/config/vax/vax.h Fri Sep 6 14:33:41 1996 +--- gcc-2.7.2.1-objc-960906/config/vax/vax.h Fri Sep 6 10:32:20 1996 +*************** +*** 963,969 **** + { if (GET_CODE (EXP) == SET) \ + { if (GET_CODE (SET_SRC (EXP)) == CALL) \ + CC_STATUS_INIT; \ +! else if (GET_CODE (SET_DEST (EXP)) != PC) \ + { cc_status.flags = 0; \ + cc_status.value1 = SET_DEST (EXP); \ + cc_status.value2 = SET_SRC (EXP); } } \ +--- 963,970 ---- + { if (GET_CODE (EXP) == SET) \ + { if (GET_CODE (SET_SRC (EXP)) == CALL) \ + CC_STATUS_INIT; \ +! else if (GET_CODE (SET_DEST (EXP)) != ZERO_EXTRACT \ +! && GET_CODE (SET_DEST (EXP)) != PC) \ + { cc_status.flags = 0; \ + cc_status.value1 = SET_DEST (EXP); \ + cc_status.value2 = SET_SRC (EXP); } } \ +diff -rcP gcc-2.7.2/config/vax/vax.md gcc-2.7.2.1-objc-960906/config/vax/vax.md +*** gcc-2.7.2/config/vax/vax.md Fri Sep 6 14:33:42 1996 +--- gcc-2.7.2.1-objc-960906/config/vax/vax.md Fri Sep 6 10:32:21 1996 +*************** +*** 1341,1346 **** +--- 1341,1347 ---- + operands[0] + = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8); + ++ CC_STATUS_INIT; + if (INTVAL (operands[1]) == 8) + return \"movb %3,%0\"; + return \"movw %3,%0\"; +diff -rcP gcc-2.7.2/config/winnt/config-nt.sed gcc-2.7.2.1-objc-960906/config/winnt/config-nt.sed +*** gcc-2.7.2/config/winnt/config-nt.sed Fri Sep 6 14:33:47 1996 +--- gcc-2.7.2.1-objc-960906/config/winnt/config-nt.sed Fri Sep 6 10:32:27 1996 +*************** +*** 13,19 **** + /^lang_specs_files=/ d + /^lang_options_files=/ d + /^version=/ c\ +! version=2.7.2 + s/CC = cc/CC = cl/ + s/^SHELL =.*/SHELL =/ + s/CFLAGS = -g/CFLAGS =/ +--- 13,19 ---- + /^lang_specs_files=/ d + /^lang_options_files=/ d + /^version=/ c\ +! version=2.7.2.1 + s/CC = cc/CC = cl/ + s/^SHELL =.*/SHELL =/ + s/CFLAGS = -g/CFLAGS =/ +diff -rcP gcc-2.7.2/configure gcc-2.7.2.1-objc-960906/configure +*** gcc-2.7.2/configure Fri Sep 6 14:26:19 1996 +--- gcc-2.7.2.1-objc-960906/configure Fri Sep 6 10:25:12 1996 +*************** +*** 509,514 **** +--- 509,516 ---- + truncate_target= + # Set this if gdb needs a dir command with `dirname $out_file` + gdb_needs_out_file_path= ++ # Set this to the Objective-C runtime thread file to compile ++ objc_thread_file=thr-single + + case $machine in + # Support site-specific machine types. +*************** +*** 597,602 **** +--- 599,605 ---- + then + extra_programs=ld.exe + fi ++ objc_thread_file=thr-win32 + ;; + arm-*-riscix1.[01]*) # Acorn RISC machine (early versions) + tm_file=arm/riscix1-1.h +*************** +*** 874,879 **** +--- 877,883 ---- + xm_file=i386/xm-next.h + tmake_file=i386/t-next + xmake_file=i386/x-next ++ objc_thread_file=thr-mach + ;; + i[345]86-sequent-bsd*) # 80386 from Sequent + cpu_type=i386 +*************** +*** 989,994 **** +--- 993,999 ---- + fixincludes=Makefile.in #On Linux, the headers are ok already. + broken_install=yes + gnu_ld=yes ++ objc_thread_file=thr-posix + ;; + i[345]86-*-linux*aout*) # Intel 80386's running Linux + cpu_type=i386 # with a.out format +*************** +*** 998,1003 **** +--- 1003,1009 ---- + fixincludes=Makefile.in #On Linux, the headers are ok already. + broken_install=yes + gnu_ld=yes ++ objc_thread_file=thr-posix + ;; + i[345]86-*-linux*) # Intel 80386's running Linux + cpu_type=i386 # with ELF format +*************** +*** 1010,1015 **** +--- 1016,1022 ---- + # Don't use it. Linux uses a slightly different one. + # The real one comes with the Linux C library. + #extra_parts="crtbegin.o crtend.o" ++ objc_thread_file=thr-posix + ;; + i[345]86-go32-msdos | i[345]86-*-go32) + cpu_type=i386 +*************** +*** 1092,1097 **** +--- 1099,1105 ---- + xmake_file=x-svr4 + fixincludes=fixinc.svr4 + broken_install=yes ++ objc_thread_file=thr-solaris + ;; + i[345]86-*-sysv4*) # Intel 80386's running system V.4 + cpu_type=i386 +*************** +*** 1148,1153 **** +--- 1156,1162 ---- + then + extra_programs=ld.exe + fi ++ objc_thread_file=thr-win32 + ;; + i860-alliant-*) # Alliant FX/2800 + xm_file=i860/xm-fx2800.h +*************** +*** 1453,1458 **** +--- 1462,1468 ---- + tmake_file=m68k/t-next + xmake_file=m68k/x-next + extra_headers=math-68881.h ++ objc_thread_file=thr-mach + ;; + m68k-sun-sunos3*) + if [ x$nfp = xyes ] +*************** +*** 1531,1536 **** +--- 1541,1547 ---- + fixincludes=Makefile.in #On Linux, the headers are ok already. + extra_headers=math-68881.h + gnu_ld=yes ++ objc_thread_file=thr-posix + ;; + m68k-*-linux*) # Motorola m68k's running Linux + xm_file=m68k/xm-linux.h # with ELF format +*************** +*** 1543,1548 **** +--- 1554,1560 ---- + # Don't use it. Linux uses a slightly different one. + # The real one comes with the Linux C library. + #extra_parts="crtbegin.o crtend.o" ++ objc_thread_file=thr-posix + ;; + m88k-dg-dgux*) + case $machine in +*************** +*** 1629,1634 **** +--- 1641,1647 ---- + tmake_file=mips/t-iris6 + # See comment in mips/iris[56].h files. + use_collect2=yes ++ objc_thread_file=thr-irix + ;; + mips-sgi-irix5cross64) # Irix5 host, Irix 6 target, cross64 + tm_file=mips/cross64.h +*************** +*** 1639,1644 **** +--- 1652,1658 ---- + tmake_file=mips/t-cross64 + # See comment in mips/iris[56].h files. + use_collect2=yes ++ objc_thread_file=thr-irix + ;; + mips-sgi-irix5*) # SGI System V.4., IRIX 5 + if [ x$gas = xyes ] +*************** +*** 1660,1665 **** +--- 1674,1680 ---- + tmake_file=mips/t-mips-gas + # See comment in mips/iris5.h file. + use_collect2=yes ++ objc_thread_file=thr-irix + ;; + mips-sgi-irix4loser*) # Mostly like a MIPS. + if [ x$stabs = xyes ]; then +*************** +*** 1680,1685 **** +--- 1695,1701 ---- + then + use_collect2=yes + fi ++ objc_thread_file=thr-irix + ;; + mips-sgi-irix4*) # Mostly like a MIPS. + if [ x$stabs = xyes ]; then +*************** +*** 1700,1705 **** +--- 1716,1722 ---- + then + use_collect2=yes + fi ++ objc_thread_file=thr-irix + ;; + mips-sgi-*) # Mostly like a MIPS. + if [ x$stabs = xyes ]; then +*************** +*** 2280,2285 **** +--- 2297,2303 ---- + extra_parts="crt1.o crti.o crtn.o gmon.o crtbegin.o crtend.o" + fixincludes=fixinc.svr4 + broken_install=yes ++ objc_thread_file=thr-solaris + ;; + sparc-*-sunos4.0*) + tm_file=sparc/sunos4.h +*************** +*** 2490,2495 **** +--- 2508,2518 ---- + then tmake_file=$cpu_type/t-$cpu_type + fi + ++ if [ x$objc_thread_file = x ] ++ then objc_thread_file=thr-single ++ fi ++ echo "Using \`$objc_thread_file' for Objective-C Runtime thread file." ++ + # Say what files are being used for the output code and MD file. + echo "Using \`$srcdir/config/$out_file' to output insns." + echo "Using \`$srcdir/config/$md_file' as machine description file." +*************** +*** 2982,2987 **** +--- 3005,3011 ---- + echo "s|^build_xm_file=.*$|build_xm_file=${srcdir}/config/${build_xm_file}|" >> Makefile.sed + echo "s|^lang_specs_files=.*$|lang_specs_files=${lang_specs_files}|" >> Makefile.sed + echo "s|^lang_options_files=.*$|lang_options_files=${lang_options_files}|" >> Makefile.sed ++ echo "s|^OBJC_THREAD_FILE=.*$|OBJC_THREAD_FILE=${objc_thread_file}|" >> Makefile.sed + echo "s|^prefix[ ]*=.*|prefix = $prefix|" >> Makefile.sed + echo "s|^gxx_include_dir[ ]*=.*|gxx_include_dir = $gxx_include_dir|" >> Makefile.sed + echo "s|^local_prefix[ ]*=.*|local_prefix = $local_prefix|" >> Makefile.sed +diff -rcP gcc-2.7.2/cp/decl2.c gcc-2.7.2.1-objc-960906/cp/decl2.c +*** gcc-2.7.2/cp/decl2.c Fri Sep 6 14:34:11 1996 +--- gcc-2.7.2.1-objc-960906/cp/decl2.c Fri Sep 6 10:32:50 1996 +*************** +*** 1363,1369 **** + init = NULL_TREE; + + value = grokdeclarator (declarator, declspecs, FIELD, init != 0, +! raises, attrlist); + if (! value) + return value; /* friend or constructor went bad. */ + +--- 1363,1369 ---- + init = NULL_TREE; + + value = grokdeclarator (declarator, declspecs, FIELD, init != 0, +! raises, NULL_TREE); + if (! value) + return value; /* friend or constructor went bad. */ + +*************** +*** 1476,1481 **** +--- 1476,1485 ---- + + /* The corresponding pop_obstacks is in cp_finish_decl. */ + push_obstacks_nochange (); ++ ++ if (attrlist) ++ cplus_decl_attributes (value, TREE_PURPOSE (attrlist), ++ TREE_VALUE (attrlist)); + + if (TREE_CODE (value) == VAR_DECL) + { +diff -rcP gcc-2.7.2/cp/lex.c gcc-2.7.2.1-objc-960906/cp/lex.c +*** gcc-2.7.2/cp/lex.c Fri Sep 6 14:34:22 1996 +--- gcc-2.7.2.1-objc-960906/cp/lex.c Fri Sep 6 10:33:00 1996 +*************** +*** 3313,3318 **** +--- 3313,3326 ---- + token_buffer[0] = '^'; + token_buffer[1] = 0; + } ++ else if (ptr->token == NAMESPACE) ++ { ++ static int warned; ++ if (! warned) ++ warning ("namespaces are mostly broken in this version of g++"); ++ ++ warned = 1; ++ } + + value = (int) ptr->token; + } +diff -rcP gcc-2.7.2/cp/parse.c gcc-2.7.2.1-objc-960906/cp/parse.c +*** gcc-2.7.2/cp/parse.c Fri Sep 6 14:34:27 1996 +--- gcc-2.7.2.1-objc-960906/cp/parse.c Fri Sep 6 10:33:05 1996 +*************** +*** 1,5 **** + +! /* A Bison parser, made from parse.y with Bison version GNU Bison version 1.22 + */ + + #define YYBISON 1 /* Identify Bison output. */ +--- 1,5 ---- + +! /* A Bison parser, made from parse.y with Bison version GNU Bison version 1.24 + */ + + #define YYBISON 1 /* Identify Bison output. */ +*************** +*** 669,675 **** + 3875, 3877, 3879, 3881, 3883, 3885, 3887, 3890, 3892 + }; + +! static const char * const yytname[] = { "$","error","$illegal.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT","BREAK","CONTINUE", + "RETURN","GOTO","ASM_KEYWORD","GCC_ASM_KEYWORD","TYPEOF","ALIGNOF","SIGOF","ATTRIBUTE", +--- 669,675 ---- + 3875, 3877, 3879, 3881, 3883, 3885, 3887, 3890, 3892 + }; + +! static const char * const yytname[] = { "$","error","$undefined.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT","BREAK","CONTINUE", + "RETURN","GOTO","ASM_KEYWORD","GCC_ASM_KEYWORD","TYPEOF","ALIGNOF","SIGOF","ATTRIBUTE", +*************** +*** 3157,3170 **** + 80, 81, 82 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/local/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman + + This program 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 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, +--- 3157,3170 ---- + 80, 81, 82 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program 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. + + This program is distributed in the hope that it will be useful, +*************** +*** 3176,3181 **** +--- 3176,3185 ---- + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++ /* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ + + #ifndef alloca + #ifdef __GNUC__ +*************** +*** 3249,3258 **** +--- 3253,3270 ---- + + #ifdef YYPURE + #ifdef YYLSP_NEEDED ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) ++ #else + #define YYLEX yylex(&yylval, &yylloc) ++ #endif ++ #else /* not YYLSP_NEEDED */ ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, YYLEX_PARAM) + #else + #define YYLEX yylex(&yylval) + #endif ++ #endif /* not YYLSP_NEEDED */ + #endif + + /* If nonreentrant, generate the variables here */ +*************** +*** 3300,3313 **** + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (from, to, count) + char *from; + char *to; + int count; +--- 3312,3325 ---- + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (from, to, count) + char *from; + char *to; + int count; +*************** +*** 3325,3331 **** + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +--- 3337,3343 ---- + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +*************** +*** 3338,3344 **** + #endif + #endif + +! #line 184 "/usr/local/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +--- 3350,3356 ---- + #endif + #endif + +! #line 192 "/usr/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +*************** +*** 3471,3482 **** + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +--- 3483,3494 ---- + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +*************** +*** 7546,7552 **** + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 480 "/usr/local/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +--- 7558,7564 ---- + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 487 "/usr/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +diff -rcP gcc-2.7.2/cpp.info gcc-2.7.2.1-objc-960906/cpp.info +*** gcc-2.7.2/cpp.info Fri Sep 6 14:26:22 1996 +--- gcc-2.7.2.1-objc-960906/cpp.info Fri Sep 6 10:25:16 1996 +*************** +*** 1,4 **** +! This is Info file cpp.info, produced by Makeinfo-1.55 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +--- 1,4 ---- +! This is Info file cpp.info, produced by Makeinfo-1.63 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +diff -rcP gcc-2.7.2/cpp.info-1 gcc-2.7.2.1-objc-960906/cpp.info-1 +*** gcc-2.7.2/cpp.info-1 Fri Sep 6 14:26:23 1996 +--- gcc-2.7.2.1-objc-960906/cpp.info-1 Fri Sep 6 10:25:17 1996 +*************** +*** 1,4 **** +! This is Info file cpp.info, produced by Makeinfo-1.55 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +--- 1,4 ---- +! This is Info file cpp.info, produced by Makeinfo-1.63 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +diff -rcP gcc-2.7.2/cpp.info-2 gcc-2.7.2.1-objc-960906/cpp.info-2 +*** gcc-2.7.2/cpp.info-2 Fri Sep 6 14:26:24 1996 +--- gcc-2.7.2.1-objc-960906/cpp.info-2 Fri Sep 6 10:25:18 1996 +*************** +*** 1,4 **** +! This is Info file cpp.info, produced by Makeinfo-1.55 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +--- 1,4 ---- +! This is Info file cpp.info, produced by Makeinfo-1.63 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +diff -rcP gcc-2.7.2/cpp.info-3 gcc-2.7.2.1-objc-960906/cpp.info-3 +*** gcc-2.7.2/cpp.info-3 Fri Sep 6 14:26:24 1996 +--- gcc-2.7.2.1-objc-960906/cpp.info-3 Fri Sep 6 10:25:18 1996 +*************** +*** 1,4 **** +! This is Info file cpp.info, produced by Makeinfo-1.55 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +--- 1,4 ---- +! This is Info file cpp.info, produced by Makeinfo-1.63 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +*************** +*** 430,466 **** + * -Wcomment: Invocation. + * -Wtraditional: Invocation. + * -Wtrigraphs: Invocation. +- * BSD: Nonstandard Predefined. +- * defined: Conditionals-Macros. +- * M68020: Nonstandard Predefined. +- * m68k: Nonstandard Predefined. +- * mc68000: Nonstandard Predefined. +- * ns32000: Nonstandard Predefined. +- * pyr: Nonstandard Predefined. +- * sequent: Nonstandard Predefined. +- * sun: Nonstandard Predefined. +- * system header files: Header Uses. +- * unix: Nonstandard Predefined. +- * vax: Nonstandard Predefined. +- * _AM29000: Nonstandard Predefined. +- * _AM29K: Nonstandard Predefined. + * __BASE_FILE__: Standard Predefined. + * __CHAR_UNSIGNED__: Standard Predefined. + * __cplusplus: Standard Predefined. + * __DATE__: Standard Predefined. + * __FILE__: Standard Predefined. +- * __GNUC_MINOR__: Standard Predefined. + * __GNUC__: Standard Predefined. + * __GNUG__: Standard Predefined. + * __INCLUDE_LEVEL_: Standard Predefined. + * __LINE__: Standard Predefined. + * __OPTIMIZE__: Standard Predefined. + * __REGISTER_PREFIX__: Standard Predefined. +- * __STDC_VERSION__: Standard Predefined. + * __STDC__: Standard Predefined. + * __STRICT_ANSI__: Standard Predefined. + * __TIME__: Standard Predefined. + * __USER_LABEL_PREFIX__: Standard Predefined. + * __VERSION__: Standard Predefined. + + +--- 430,466 ---- + * -Wcomment: Invocation. + * -Wtraditional: Invocation. + * -Wtrigraphs: Invocation. + * __BASE_FILE__: Standard Predefined. + * __CHAR_UNSIGNED__: Standard Predefined. + * __cplusplus: Standard Predefined. + * __DATE__: Standard Predefined. + * __FILE__: Standard Predefined. + * __GNUC__: Standard Predefined. ++ * __GNUC_MINOR__: Standard Predefined. + * __GNUG__: Standard Predefined. + * __INCLUDE_LEVEL_: Standard Predefined. + * __LINE__: Standard Predefined. + * __OPTIMIZE__: Standard Predefined. + * __REGISTER_PREFIX__: Standard Predefined. + * __STDC__: Standard Predefined. ++ * __STDC_VERSION__: Standard Predefined. + * __STRICT_ANSI__: Standard Predefined. + * __TIME__: Standard Predefined. + * __USER_LABEL_PREFIX__: Standard Predefined. + * __VERSION__: Standard Predefined. ++ * _AM29000: Nonstandard Predefined. ++ * _AM29K: Nonstandard Predefined. ++ * BSD: Nonstandard Predefined. ++ * defined: Conditionals-Macros. ++ * M68020: Nonstandard Predefined. ++ * m68k: Nonstandard Predefined. ++ * mc68000: Nonstandard Predefined. ++ * ns32000: Nonstandard Predefined. ++ * pyr: Nonstandard Predefined. ++ * sequent: Nonstandard Predefined. ++ * sun: Nonstandard Predefined. ++ * system header files: Header Uses. ++ * unix: Nonstandard Predefined. ++ * vax: Nonstandard Predefined. + + +diff -rcP gcc-2.7.2/expr.c gcc-2.7.2.1-objc-960906/expr.c +*** gcc-2.7.2/expr.c Fri Sep 6 14:26:48 1996 +--- gcc-2.7.2.1-objc-960906/expr.c Fri Sep 6 10:25:42 1996 +*************** +*** 4582,4588 **** + through a pointer to const does not mean that the value there can + never change. Languages where it can never change should + also set TREE_STATIC. */ +! RTX_UNCHANGING_P (temp) = TREE_READONLY (exp) | TREE_STATIC (exp); + return temp; + } + +--- 4582,4588 ---- + through a pointer to const does not mean that the value there can + never change. Languages where it can never change should + also set TREE_STATIC. */ +! RTX_UNCHANGING_P (temp) = TREE_READONLY (exp) & TREE_STATIC (exp); + return temp; + } + +*************** +*** 8290,8296 **** +--- 8290,8304 ---- + + /* Push a new argument block and copy the arguments. */ + do_pending_stack_adjust (); ++ ++ /* For now use SAVE_NONLOCAL on PPC architectures as it does not ++ have SAVE_BLOCK. This should possibly be changed to check the ++ insn-flag HAVE_save_stack_block? */ ++ #ifdef __PPC__ ++ emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX); ++ #else + emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX); ++ #endif /* __PPC__ */ + + /* Push a block of memory onto the stack to store the memory arguments. + Save the address in a register, and copy the memory arguments. ??? I +*************** +*** 8416,8422 **** +--- 8424,8437 ---- + CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage; + + /* Restore the stack. */ ++ /* For now use SAVE_NONLOCAL on PPC architectures as it does not ++ have SAVE_BLOCK. This should possibly be changed to check the ++ insn-flag HAVE_save_stack_block? */ ++ #ifdef __PPC__ ++ emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX); ++ #else + emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX); ++ #endif /* __PPC__ */ + + /* Return the address of the result block. */ + return copy_addr_to_reg (XEXP (result, 0)); +diff -rcP gcc-2.7.2/fix-header.c gcc-2.7.2.1-objc-960906/fix-header.c +*** gcc-2.7.2/fix-header.c Fri Sep 6 14:26:52 1996 +--- gcc-2.7.2.1-objc-960906/fix-header.c Fri Sep 6 10:25:46 1996 +*************** +*** 531,537 **** +--- 531,548 ---- + push_parse_file (&scan_in, in_fname); + CPP_OPTIONS (&scan_in)->no_line_commands = 1; + ++ #ifdef FIXPROTO_INIT ++ /* Some targets may assume special definitions (for example ++ OSF header files assume __LANGUAGE_C__). These macros ++ are normally passed to cpplib by gcc - but we here invoke ++ cpplib directly, without going through gcc. ++ Handle these and other target-dependent initializations here. */ ++ FIXPROTO_INIT (&scan_in); ++ #endif ++ ++ /* Actually (pre-)process the header file. */ + scan_decls (&scan_in, argc, argv); ++ + check_macro_names (&scan_in, include_entry->required); + check_macro_names (&scan_in, include_entry->extra); + +diff -rcP gcc-2.7.2/fixincludes gcc-2.7.2.1-objc-960906/fixincludes +*** gcc-2.7.2/fixincludes Fri Sep 6 14:26:56 1996 +--- gcc-2.7.2.1-objc-960906/fixincludes Fri Sep 6 10:25:50 1996 +*************** +*** 1520,1525 **** +--- 1520,1552 ---- + fi + fi + ++ # sys/wait.h on AIX 3.2.5 puts the declaration of wait3 before the definition ++ # of struct rusage, so the prototype (added by fixproto) causes havoc. ++ file=sys/wait.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 ++ fi ++ ++ if [ -r ${LIB}/$file ] \ ++ && grep 'bos325,' ${LIB}/$file >/dev/null; then ++ echo Fixing $file, wait3 declaration ++ sed -e '/^extern pid_t wait3();$/i\ ++ struct rusage; ++ '\ ++ ${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 ++ else ++ # Find any include directives that use "file". ++ for include in `egrep '^[ ]*#[ ]*include[ ]*"[^/]' ${LIB}/$file | sed -e 's/^[ ]*#[ ]*include[ ]*"\([^"]*\)".*$/\1/'`; do ++ dir=`echo $file | sed -e s'|/[^/]*$||'` ++ required="$required ${INPUT} $dir/$include ${LIB}/$dir/$include" ++ done ++ fi ++ fi ++ + # NeXT 2.0 defines 'int wait(union wait*)', which conflicts with Posix.1. + # Note that version 3 of the NeXT system has wait.h in a different directory, + # so that this code won't do anything. But wait.h in version 3 has a +diff -rcP gcc-2.7.2/gcc.info gcc-2.7.2.1-objc-960906/gcc.info +*** gcc-2.7.2/gcc.info Fri Sep 6 14:27:11 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info Fri Sep 6 10:26:03 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 32,61 **** +  + Indirect: + gcc.info-1: 1382 +! gcc.info-2: 42854 +! gcc.info-3: 80578 +! gcc.info-4: 127608 +! gcc.info-5: 173792 +! gcc.info-6: 214726 +! gcc.info-7: 235436 +! gcc.info-8: 285158 +! gcc.info-9: 333642 +! gcc.info-10: 382691 +! gcc.info-11: 419654 +! gcc.info-12: 468472 +! gcc.info-13: 517503 +! gcc.info-14: 564845 +! gcc.info-15: 604398 +! gcc.info-16: 654371 +! gcc.info-17: 703324 +! gcc.info-18: 751502 +! gcc.info-19: 797360 +! gcc.info-20: 846162 +! gcc.info-21: 890260 +! gcc.info-22: 933466 +! gcc.info-23: 982355 +! gcc.info-24: 1032258 +! gcc.info-25: 1067513 +  + Tag Table: + (Indirect) +--- 32,61 ---- +  + Indirect: + gcc.info-1: 1382 +! gcc.info-2: 43097 +! gcc.info-3: 80821 +! gcc.info-4: 127851 +! gcc.info-5: 174035 +! gcc.info-6: 214969 +! gcc.info-7: 237409 +! gcc.info-8: 286095 +! gcc.info-9: 334579 +! gcc.info-10: 383628 +! gcc.info-11: 420591 +! gcc.info-12: 469430 +! gcc.info-13: 518461 +! gcc.info-14: 565803 +! gcc.info-15: 605356 +! gcc.info-16: 655329 +! gcc.info-17: 704282 +! gcc.info-18: 752460 +! gcc.info-19: 798318 +! gcc.info-20: 847120 +! gcc.info-21: 891218 +! gcc.info-22: 934424 +! gcc.info-23: 983313 +! gcc.info-24: 1033216 +! gcc.info-25: 1068471 +  + Tag Table: + (Indirect) +*************** +*** 64,297 **** + Node: Contributors22249 + Node: Funding27395 + Node: Look and Feel29892 +! Node: G++ and GCC37258 +! Node: Invoking GCC39475 +! Node: Option Summary42854 +! Node: Overall Options53305 +! Node: Invoking G++57868 +! Node: C Dialect Options59742 +! Node: C++ Dialect Options69842 +! Node: Warning Options80578 +! Node: Debugging Options95513 +! Node: Optimize Options105094 +! Node: Preprocessor Options115596 +! Node: Assembler Options122059 +! Node: Link Options122426 +! Node: Directory Options127608 +! Node: Target Options131100 +! Node: Submodel Options134757 +! Node: M680x0 Options136138 +! Node: VAX Options139647 +! Node: SPARC Options140182 +! Node: Convex Options146602 +! Node: AMD29K Options148783 +! Node: ARM Options151814 +! Node: M88K Options153231 +! Node: RS/6000 and PowerPC Options161178 +! Node: RT Options172088 +! Node: MIPS Options173792 +! Node: i386 Options181418 +! Node: HPPA Options186857 +! Node: Intel 960 Options189953 +! Node: DEC Alpha Options192563 +! Node: Clipper Options194235 +! Node: H8/300 Options194634 +! Node: System V Options195079 +! Node: Code Gen Options195765 +! Node: Environment Variables204274 +! Node: Running Protoize208497 +! Node: Installation214726 +! Node: Configurations235436 +! Node: Other Dir271347 +! Node: Cross-Compiler273063 +! Node: Steps of Cross274894 +! Node: Configure Cross276012 +! Node: Tools and Libraries276649 +! Node: Cross Runtime279092 +! Node: Cross Headers283173 +! Node: Build Cross285158 +! Node: Sun Install287034 +! Node: VMS Install288166 +! Node: Collect2298095 +! Node: Header Dirs300804 +! Node: C Extensions302218 +! Node: Statement Exprs305497 +! Node: Local Labels307391 +! Node: Labels as Values309453 +! Node: Nested Functions311318 +! Node: Constructing Calls315174 +! Node: Naming Types317231 +! Node: Typeof318325 +! Node: Lvalues320190 +! Node: Conditionals322630 +! Node: Long Long323521 +! Node: Complex324965 +! Node: Zero Length326827 +! Node: Variable Length327501 +! Node: Macro Varargs330026 +! Node: Subscripting332129 +! Node: Pointer Arith332612 +! Node: Initializers333177 +! Node: Constructors333642 +! Node: Labeled Elements335336 +! Node: Case Ranges337965 +! Node: Cast to Union338646 +! Node: Function Attributes339724 +! Node: Function Prototypes348987 +! Node: C++ Comments350786 +! Node: Dollar Signs351322 +! Node: Character Escapes352102 +! Node: Alignment352383 +! Node: Variable Attributes353855 +! Node: Type Attributes361763 +! Node: Inline368282 +! Node: Extended Asm372159 +! Node: Asm Labels382691 +! Node: Explicit Reg Vars384010 +! Node: Global Reg Vars385258 +! Node: Local Reg Vars389823 +! Node: Alternate Keywords391415 +! Node: Incomplete Enums392817 +! Node: Function Names393573 +! Node: C++ Extensions394824 +! Node: Naming Results396061 +! Node: Min and Max399375 +! Node: Destructors and Goto400825 +! Node: C++ Interface401375 +! Node: Template Instantiation406598 +! Node: C++ Signatures412330 +! Node: Trouble416674 +! Node: Actual Bugs418385 +! Node: Installation Problems419654 +! Node: Cross-Compiler Problems433440 +! Node: Interoperation434911 +! Node: External Bugs448275 +! Node: Incompatibilities450407 +! Node: Fixed Headers458957 +! Node: Standard Libraries461299 +! Node: Disappointments462546 +! Node: C++ Misunderstandings466771 +! Node: Static Definitions467418 +! Node: Temporaries468472 +! Node: Protoize Caveats470676 +! Node: Non-bugs474632 +! Node: Warnings and Errors483592 +! Node: Bugs485362 +! Node: Bug Criteria486722 +! Node: Bug Lists489152 +! Node: Bug Reporting490545 +! Node: Sending Patches502963 +! Node: Service508350 +! Node: VMS508911 +! Node: Include Files and VMS509304 +! Node: Global Declarations513194 +! Node: VMS Misc517503 +! Node: Portability521829 +! Node: Interface523592 +! Node: Passes528225 +! Node: RTL545568 +! Node: RTL Objects547456 +! Node: Accessors550500 +! Node: Flags555826 +! Node: Machine Modes564845 +! Node: Constants572479 +! Node: Regs and Memory577667 +! Node: Arithmetic589377 +! Node: Comparisons595275 +! Node: Bit Fields599337 +! Node: Conversions600701 +! Node: RTL Declarations603589 +! Node: Side Effects604398 +! Node: Incdec616945 +! Node: Assembler619461 +! Node: Insns620983 +! Node: Calls641836 +! Node: Sharing644431 +! Node: Reading RTL647507 +! Node: Machine Desc648446 +! Node: Patterns650299 +! Node: Example653243 +! Node: RTL Template654371 +! Node: Output Template666569 +! Node: Output Statement670530 +! Node: Constraints674243 +! Node: Simple Constraints675246 +! Node: Multi-Alternative686679 +! Node: Class Preferences689515 +! Node: Modifiers690395 +! Node: Machine Constraints693555 +! Node: No Constraints702203 +! Node: Standard Names703324 +! Node: Pattern Ordering731232 +! Node: Dependent Patterns732458 +! Node: Jump Patterns735273 +! Node: Insn Canonicalizations741089 +! Node: Peephole Definitions744584 +! Node: Expander Definitions751502 +! Node: Insn Splitting758948 +! Node: Insn Attributes765962 +! Node: Defining Attributes767009 +! Node: Expressions769021 +! Node: Tagging Insns775333 +! Node: Attr Example779696 +! Node: Insn Lengths782072 +! Node: Constant Attributes785436 +! Node: Delay Slots786596 +! Node: Function Units789807 +! Node: Target Macros795477 +! Node: Driver797360 +! Node: Run-time Target809090 +! Node: Storage Layout814977 +! Node: Type Layout828925 +! Node: Registers835348 +! Node: Register Basics836328 +! Node: Allocation Order840365 +! Node: Values in Registers841783 +! Node: Leaf Functions846162 +! Node: Stack Registers848637 +! Node: Obsolete Register Macros849470 +! Node: Register Classes852165 +! Node: Stack and Calling871700 +! Node: Frame Layout872136 +! Node: Frame Registers875576 +! Node: Elimination879386 +! Node: Stack Arguments883642 +! Node: Register Arguments890260 +! Node: Scalar Return898935 +! Node: Aggregate Return902898 +! Node: Caller Saves906613 +! Node: Function Entry907763 +! Node: Profiling916691 +! Node: Varargs919595 +! Node: Trampolines927004 +! Node: Library Calls933466 +! Node: Addressing Modes941524 +! Node: Condition Code949112 +! Node: Costs955311 +! Node: Sections963690 +! Node: PIC968479 +! Node: Assembler Format971189 +! Node: File Framework972194 +! Node: Data Output976431 +! Node: Uninitialized Data982355 +! Node: Label Output985062 +! Node: Initialization994456 +! Node: Macros for Initialization1000599 +! Node: Instruction Output1005196 +! Node: Dispatch Tables1013191 +! Node: Alignment Output1015568 +! Node: Debugging Info1017308 +! Node: All Debuggers1017917 +! Node: DBX Options1020331 +! Node: DBX Hooks1025216 +! Node: File Names and DBX1028555 +! Node: SDB and DWARF1030528 +! Node: Cross-compilation1032258 +! Node: Misc1038705 +! Node: Config1055831 +! Node: Fragments1063276 +! Node: Target Fragment1063873 +! Node: Host Fragment1066911 +! Node: Index1067513 +  + End Tag Table +--- 64,297 ---- + Node: Contributors22249 + Node: Funding27395 + Node: Look and Feel29892 +! Node: G++ and GCC37501 +! Node: Invoking GCC39718 +! Node: Option Summary43097 +! Node: Overall Options53548 +! Node: Invoking G++58111 +! Node: C Dialect Options59985 +! Node: C++ Dialect Options70085 +! Node: Warning Options80821 +! Node: Debugging Options95756 +! Node: Optimize Options105337 +! Node: Preprocessor Options115839 +! Node: Assembler Options122302 +! Node: Link Options122669 +! Node: Directory Options127851 +! Node: Target Options131343 +! Node: Submodel Options135000 +! Node: M680x0 Options136381 +! Node: VAX Options139890 +! Node: SPARC Options140425 +! Node: Convex Options146845 +! Node: AMD29K Options149026 +! Node: ARM Options152057 +! Node: M88K Options153474 +! Node: RS/6000 and PowerPC Options161421 +! Node: RT Options172331 +! Node: MIPS Options174035 +! Node: i386 Options181661 +! Node: HPPA Options187100 +! Node: Intel 960 Options190196 +! Node: DEC Alpha Options192806 +! Node: Clipper Options194478 +! Node: H8/300 Options194877 +! Node: System V Options195322 +! Node: Code Gen Options196008 +! Node: Environment Variables204517 +! Node: Running Protoize208740 +! Node: Installation214969 +! Node: Configurations237409 +! Node: Other Dir272284 +! Node: Cross-Compiler274000 +! Node: Steps of Cross275831 +! Node: Configure Cross276949 +! Node: Tools and Libraries277586 +! Node: Cross Runtime280029 +! Node: Cross Headers284110 +! Node: Build Cross286095 +! Node: Sun Install287971 +! Node: VMS Install289103 +! Node: Collect2299032 +! Node: Header Dirs301741 +! Node: C Extensions303155 +! Node: Statement Exprs306434 +! Node: Local Labels308328 +! Node: Labels as Values310390 +! Node: Nested Functions312255 +! Node: Constructing Calls316111 +! Node: Naming Types318168 +! Node: Typeof319262 +! Node: Lvalues321127 +! Node: Conditionals323567 +! Node: Long Long324458 +! Node: Complex325902 +! Node: Zero Length327764 +! Node: Variable Length328438 +! Node: Macro Varargs330963 +! Node: Subscripting333066 +! Node: Pointer Arith333549 +! Node: Initializers334114 +! Node: Constructors334579 +! Node: Labeled Elements336273 +! Node: Case Ranges338902 +! Node: Cast to Union339583 +! Node: Function Attributes340661 +! Node: Function Prototypes349924 +! Node: C++ Comments351723 +! Node: Dollar Signs352259 +! Node: Character Escapes353039 +! Node: Alignment353320 +! Node: Variable Attributes354792 +! Node: Type Attributes362700 +! Node: Inline369219 +! Node: Extended Asm373096 +! Node: Asm Labels383628 +! Node: Explicit Reg Vars384947 +! Node: Global Reg Vars386195 +! Node: Local Reg Vars390760 +! Node: Alternate Keywords392352 +! Node: Incomplete Enums393754 +! Node: Function Names394510 +! Node: C++ Extensions395761 +! Node: Naming Results396998 +! Node: Min and Max400312 +! Node: Destructors and Goto401762 +! Node: C++ Interface402312 +! Node: Template Instantiation407535 +! Node: C++ Signatures413267 +! Node: Trouble417611 +! Node: Actual Bugs419322 +! Node: Installation Problems420591 +! Node: Cross-Compiler Problems434398 +! Node: Interoperation435869 +! Node: External Bugs449233 +! Node: Incompatibilities451365 +! Node: Fixed Headers459915 +! Node: Standard Libraries462257 +! Node: Disappointments463504 +! Node: C++ Misunderstandings467729 +! Node: Static Definitions468376 +! Node: Temporaries469430 +! Node: Protoize Caveats471634 +! Node: Non-bugs475590 +! Node: Warnings and Errors484550 +! Node: Bugs486320 +! Node: Bug Criteria487680 +! Node: Bug Lists490110 +! Node: Bug Reporting491503 +! Node: Sending Patches503921 +! Node: Service509308 +! Node: VMS509869 +! Node: Include Files and VMS510262 +! Node: Global Declarations514152 +! Node: VMS Misc518461 +! Node: Portability522787 +! Node: Interface524550 +! Node: Passes529183 +! Node: RTL546526 +! Node: RTL Objects548414 +! Node: Accessors551458 +! Node: Flags556784 +! Node: Machine Modes565803 +! Node: Constants573437 +! Node: Regs and Memory578625 +! Node: Arithmetic590335 +! Node: Comparisons596233 +! Node: Bit Fields600295 +! Node: Conversions601659 +! Node: RTL Declarations604547 +! Node: Side Effects605356 +! Node: Incdec617903 +! Node: Assembler620419 +! Node: Insns621941 +! Node: Calls642794 +! Node: Sharing645389 +! Node: Reading RTL648465 +! Node: Machine Desc649404 +! Node: Patterns651257 +! Node: Example654201 +! Node: RTL Template655329 +! Node: Output Template667527 +! Node: Output Statement671488 +! Node: Constraints675201 +! Node: Simple Constraints676204 +! Node: Multi-Alternative687637 +! Node: Class Preferences690473 +! Node: Modifiers691353 +! Node: Machine Constraints694513 +! Node: No Constraints703161 +! Node: Standard Names704282 +! Node: Pattern Ordering732190 +! Node: Dependent Patterns733416 +! Node: Jump Patterns736231 +! Node: Insn Canonicalizations742047 +! Node: Peephole Definitions745542 +! Node: Expander Definitions752460 +! Node: Insn Splitting759906 +! Node: Insn Attributes766920 +! Node: Defining Attributes767967 +! Node: Expressions769979 +! Node: Tagging Insns776291 +! Node: Attr Example780654 +! Node: Insn Lengths783030 +! Node: Constant Attributes786394 +! Node: Delay Slots787554 +! Node: Function Units790765 +! Node: Target Macros796435 +! Node: Driver798318 +! Node: Run-time Target810048 +! Node: Storage Layout815935 +! Node: Type Layout829883 +! Node: Registers836306 +! Node: Register Basics837286 +! Node: Allocation Order841323 +! Node: Values in Registers842741 +! Node: Leaf Functions847120 +! Node: Stack Registers849595 +! Node: Obsolete Register Macros850428 +! Node: Register Classes853123 +! Node: Stack and Calling872658 +! Node: Frame Layout873094 +! Node: Frame Registers876534 +! Node: Elimination880344 +! Node: Stack Arguments884600 +! Node: Register Arguments891218 +! Node: Scalar Return899893 +! Node: Aggregate Return903856 +! Node: Caller Saves907571 +! Node: Function Entry908721 +! Node: Profiling917649 +! Node: Varargs920553 +! Node: Trampolines927962 +! Node: Library Calls934424 +! Node: Addressing Modes942482 +! Node: Condition Code950070 +! Node: Costs956269 +! Node: Sections964648 +! Node: PIC969437 +! Node: Assembler Format972147 +! Node: File Framework973152 +! Node: Data Output977389 +! Node: Uninitialized Data983313 +! Node: Label Output986020 +! Node: Initialization995414 +! Node: Macros for Initialization1001557 +! Node: Instruction Output1006154 +! Node: Dispatch Tables1014149 +! Node: Alignment Output1016526 +! Node: Debugging Info1018266 +! Node: All Debuggers1018875 +! Node: DBX Options1021289 +! Node: DBX Hooks1026174 +! Node: File Names and DBX1029513 +! Node: SDB and DWARF1031486 +! Node: Cross-compilation1033216 +! Node: Misc1039663 +! Node: Config1056789 +! Node: Fragments1064234 +! Node: Target Fragment1064831 +! Node: Host Fragment1067869 +! Node: Index1068471 +  + End Tag Table +diff -rcP gcc-2.7.2/gcc.info-1 gcc-2.7.2.1-objc-960906/gcc.info-1 +*** gcc-2.7.2/gcc.info-1 Fri Sep 6 14:27:12 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-1 Fri Sep 6 10:26:04 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 653,670 **** + reasons only partly related to the general issue of interface copyright. + + Lotus won lawsuits against two small companies, which were thus put +! out of business. Then they sued Borland; they won in the trial court + (no surprise, since it was the same court that had ruled for Lotus twice +! before), but the decision was reversed by the court of appeals, with +! help from the League for Programming Freedom in the form of a +! friend-of-the-court brief. We are now waiting to see if the Supreme +! Court will hear the case. If it does, the League for Programming +! Freedom will again submit a brief. +! +! The battle is not over. Just this summer a company that produced a +! simulator for a CDC computer was shut down by a copyright lawsuit by +! CDC, which charged that the simulator infringed the copyright on the +! manuals for the computer. + + If the monopolists get their way, they will hobble the software + field: +--- 653,675 ---- + reasons only partly related to the general issue of interface copyright. + + Lotus won lawsuits against two small companies, which were thus put +! out of business. Then Lotus sued Borland; Lotus won in the trial court + (no surprise, since it was the same court that had ruled for Lotus twice +! before), but the court of appeals ruled in favor of Borland, which was +! assisted by a friend-of-the-court brief from the League for Programming +! Freedom. +! +! Lotus appealed the case to the Supreme Court, which heard the case +! but was unable to reach a decision. This failure means that the appeals +! court decision stands, in one portion of the United States, and may +! influence the other appeals courts, but it does not set a nationwide +! precedent. The battle is not over, and it is not limited to the United +! States. +! +! The battle is extending into other areas of software as well. In +! 1995 a company that produced a simulator for a CDC computer was shut +! down by a copyright lawsuit, in which CDC charged that the simulator +! infringed the copyright on the manuals for the computer. + + If the monopolists get their way, they will hobble the software + field: +diff -rcP gcc-2.7.2/gcc.info-10 gcc-2.7.2.1-objc-960906/gcc.info-10 +*** gcc-2.7.2/gcc.info-10 Fri Sep 6 14:27:12 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-10 Fri Sep 6 10:26:05 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-11 gcc-2.7.2.1-objc-960906/gcc.info-11 +*** gcc-2.7.2/gcc.info-11 Fri Sep 6 14:27:13 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-11 Fri Sep 6 10:26:05 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 85,95 **** + GNU CC. The fix is to get rid of the file `real-ld' which purify + installs--so that GNU CC won't try to use it. + +! * On Linux SLS 1.01, there is a problem with `libc.a': it does not +! contain the obstack functions. However, GNU CC assumes that the +! obstack functions are in `libc.a' when it is the GNU C library. +! To work around this problem, change the `__GNU_LIBRARY__' +! conditional around line 31 to `#if 1'. + + * On some 386 systems, building the compiler never finishes because + `enquire' hangs due to a hardware problem in the motherboard--it +--- 85,95 ---- + GNU CC. The fix is to get rid of the file `real-ld' which purify + installs--so that GNU CC won't try to use it. + +! * On SLS 1.01, a Linux-based GNU system, there is a problem with +! `libc.a': it does not contain the obstack functions. However, GNU +! CC assumes that the obstack functions are in `libc.a' when it is +! the GNU C library. To work around this problem, change the +! `__GNU_LIBRARY__' conditional around line 31 to `#if 1'. + + * On some 386 systems, building the compiler never finishes because + `enquire' hangs due to a hardware problem in the motherboard--it +diff -rcP gcc-2.7.2/gcc.info-12 gcc-2.7.2.1-objc-960906/gcc.info-12 +*** gcc-2.7.2/gcc.info-12 Fri Sep 6 14:27:14 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-12 Fri Sep 6 10:26:06 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-13 gcc-2.7.2.1-objc-960906/gcc.info-13 +*** gcc-2.7.2/gcc.info-13 Fri Sep 6 14:27:15 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-13 Fri Sep 6 10:26:07 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-14 gcc-2.7.2.1-objc-960906/gcc.info-14 +*** gcc-2.7.2/gcc.info-14 Fri Sep 6 14:27:16 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-14 Fri Sep 6 10:26:08 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 909,915 **** + + `(float_extend:M X)' + Represents the result of extending the value X to machine mode M. +! m must be a floating point mode and X a floating point value of a + mode narrower than M. + + `(truncate:M X)' +--- 909,915 ---- + + `(float_extend:M X)' + Represents the result of extending the value X to machine mode M. +! M must be a floating point mode and X a floating point value of a + mode narrower than M. + + `(truncate:M X)' +diff -rcP gcc-2.7.2/gcc.info-15 gcc-2.7.2.1-objc-960906/gcc.info-15 +*** gcc-2.7.2/gcc.info-15 Fri Sep 6 14:27:17 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-15 Fri Sep 6 10:26:09 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 295,302 **** + `(pre_dec:M X)' + Represents the side effect of decrementing X by a standard amount + and represents also the value that X has after being decremented. +! x must be a `reg' or `mem', but most machines allow only a `reg'. +! m must be the machine mode for pointers on the machine in use. + The amount X is decremented by is the length in bytes of the + machine mode of the containing memory reference of which this + expression serves as the address. Here is an example of its use: +--- 295,302 ---- + `(pre_dec:M X)' + Represents the side effect of decrementing X by a standard amount + and represents also the value that X has after being decremented. +! X must be a `reg' or `mem', but most machines allow only a `reg'. +! M must be the machine mode for pointers on the machine in use. + The amount X is decremented by is the length in bytes of the + machine mode of the containing memory reference of which this + expression serves as the address. Here is an example of its use: +diff -rcP gcc-2.7.2/gcc.info-16 gcc-2.7.2.1-objc-960906/gcc.info-16 +*** gcc-2.7.2/gcc.info-16 Fri Sep 6 14:27:18 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-16 Fri Sep 6 10:26:10 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-17 gcc-2.7.2.1-objc-960906/gcc.info-17 +*** gcc-2.7.2/gcc.info-17 Fri Sep 6 14:27:18 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-17 Fri Sep 6 10:26:10 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 385,391 **** + `sCOND' + Store zero or nonzero in the operand according to the condition + codes. Value stored is nonzero iff the condition COND is true. +! cOND is the name of a comparison operation expression code, such + as `eq', `lt' or `leu'. + + You specify the mode that the operand must have when you write the +--- 385,391 ---- + `sCOND' + Store zero or nonzero in the operand according to the condition + codes. Value stored is nonzero iff the condition COND is true. +! COND is the name of a comparison operation expression code, such + as `eq', `lt' or `leu'. + + You specify the mode that the operand must have when you write the +diff -rcP gcc-2.7.2/gcc.info-18 gcc-2.7.2.1-objc-960906/gcc.info-18 +*** gcc-2.7.2/gcc.info-18 Fri Sep 6 14:27:20 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-18 Fri Sep 6 10:26:11 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-19 gcc-2.7.2.1-objc-960906/gcc.info-19 +*** gcc-2.7.2/gcc.info-19 Fri Sep 6 14:27:21 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-19 Fri Sep 6 10:26:12 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-2 gcc-2.7.2.1-objc-960906/gcc.info-2 +*** gcc-2.7.2/gcc.info-2 Fri Sep 6 14:27:21 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-2 Fri Sep 6 10:26:12 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-20 gcc-2.7.2.1-objc-960906/gcc.info-20 +*** gcc-2.7.2/gcc.info-20 Fri Sep 6 14:27:22 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-20 Fri Sep 6 10:26:13 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 657,663 **** + `RETURN_ADDR_RTX (COUNT, FRAMEADDR)' + A C expression whose value is RTL representing the value of the + return address for the frame COUNT steps up from the current frame. +! fRAMEADDR is the frame pointer of the COUNT frame, or the frame + pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' + is defined. + +--- 657,663 ---- + `RETURN_ADDR_RTX (COUNT, FRAMEADDR)' + A C expression whose value is RTL representing the value of the + return address for the frame COUNT steps up from the current frame. +! FRAMEADDR is the frame pointer of the COUNT frame, or the frame + pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' + is defined. + +diff -rcP gcc-2.7.2/gcc.info-21 gcc-2.7.2.1-objc-960906/gcc.info-21 +*** gcc-2.7.2/gcc.info-21 Fri Sep 6 14:27:23 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-21 Fri Sep 6 10:26:14 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 841,847 **** + + `INITIALIZE_TRAMPOLINE (ADDR, FNADDR, STATIC_CHAIN)' + A C statement to initialize the variable parts of a trampoline. +! aDDR is an RTX for the address of the trampoline; FNADDR is an RTX + for the address of the nested function; STATIC_CHAIN is an RTX for + the static chain value that should be passed to the function when + it is called. +--- 841,847 ---- + + `INITIALIZE_TRAMPOLINE (ADDR, FNADDR, STATIC_CHAIN)' + A C statement to initialize the variable parts of a trampoline. +! ADDR is an RTX for the address of the trampoline; FNADDR is an RTX + for the address of the nested function; STATIC_CHAIN is an RTX for + the static chain value that should be passed to the function when + it is called. +diff -rcP gcc-2.7.2/gcc.info-22 gcc-2.7.2.1-objc-960906/gcc.info-22 +*** gcc-2.7.2/gcc.info-22 Fri Sep 6 14:27:24 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-22 Fri Sep 6 10:26:14 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-23 gcc-2.7.2.1-objc-960906/gcc.info-23 +*** gcc-2.7.2/gcc.info-23 Fri Sep 6 14:27:24 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-23 Fri Sep 6 10:26:15 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-24 gcc-2.7.2.1-objc-960906/gcc.info-24 +*** gcc-2.7.2/gcc.info-24 Fri Sep 6 14:27:25 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-24 Fri Sep 6 10:26:15 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 100,106 **** + A macro whose definition is a C expression to round the + target-machine floating point value X towards zero to an unsigned + integer value (but still represented as a floating point number). +! x has type `REAL_VALUE_TYPE', and so does the value. + + `REAL_VALUE_ATOF (STRING, MODE)' + A macro for a C expression which converts STRING, an expression of +--- 100,106 ---- + A macro whose definition is a C expression to round the + target-machine floating point value X towards zero to an unsigned + integer value (but still represented as a floating point number). +! X has type `REAL_VALUE_TYPE', and so does the value. + + `REAL_VALUE_ATOF (STRING, MODE)' + A macro for a C expression which converts STRING, an expression of +diff -rcP gcc-2.7.2/gcc.info-25 gcc-2.7.2.1-objc-960906/gcc.info-25 +*** gcc-2.7.2/gcc.info-25 Fri Sep 6 14:27:27 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-25 Fri Sep 6 10:26:17 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 53,59 **** + * -lgcc, use with -nostdlib: Link Options. + * -nodefaultlibs and unresolved references: Link Options. + * -nostdlib and unresolved references: Link Options. +! * ?: extensions: Conditionals. + * ?: extensions: Lvalues. + * absM2 instruction pattern: Standard Names. + * abs and attributes: Expressions. +--- 53,59 ---- + * -lgcc, use with -nostdlib: Link Options. + * -nodefaultlibs and unresolved references: Link Options. + * -nostdlib and unresolved references: Link Options. +! * ?: extensions <1>: Conditionals. + * ?: extensions: Lvalues. + * absM2 instruction pattern: Standard Names. + * abs and attributes: Expressions. +*************** +*** 62,68 **** + * addr_diff_vec, length of: Insn Lengths. + * addr_vec, length of: Insn Lengths. + * alias attribute: Function Attributes. +! * aligned attribute: Type Attributes. + * aligned attribute: Variable Attributes. + * allocate_stack instruction pattern: Standard Names. + * alloca and SunOs: Installation. +--- 62,68 ---- + * addr_diff_vec, length of: Insn Lengths. + * addr_vec, length of: Insn Lengths. + * alias attribute: Function Attributes. +! * aligned attribute <1>: Type Attributes. + * aligned attribute: Variable Attributes. + * allocate_stack instruction pattern: Standard Names. + * alloca and SunOs: Installation. +*************** +*** 98,109 **** + * code_label and /i: Flags. + * compare, canonicalization of: Insn Canonicalizations. + * cond and attributes: Expressions. +- * constructor function attribute: Function Attributes. + * const_double, RTL sharing: Sharing. + * const_int and attribute tests: Expressions. + * const_int and attributes: Expressions. + * const_int, RTL sharing: Sharing. + * const_string and attributes: Expressions. + * const applied to function: Function Attributes. + * const function attribute: Function Attributes. + * define_insn example: Example. +--- 98,109 ---- + * code_label and /i: Flags. + * compare, canonicalization of: Insn Canonicalizations. + * cond and attributes: Expressions. + * const_double, RTL sharing: Sharing. + * const_int and attribute tests: Expressions. + * const_int and attributes: Expressions. + * const_int, RTL sharing: Sharing. + * const_string and attributes: Expressions. ++ * constructor function attribute: Function Attributes. + * const applied to function: Function Attributes. + * const function attribute: Function Attributes. + * define_insn example: Example. +*************** +*** 122,130 **** + * ffsM2 instruction pattern: Standard Names. + * FIRST_PARM_OFFSET and virtual registers: Regs and Memory. + * fixMN2 instruction pattern: Standard Names. + * fixunsMN2 instruction pattern: Standard Names. + * fixuns_truncMN2 instruction pattern: Standard Names. +- * fix_truncMN2 instruction pattern: Standard Names. + * floatMN2 instruction pattern: Standard Names. + * floatunsMN2 instruction pattern: Standard Names. + * float as function value type: Incompatibilities. +--- 122,130 ---- + * ffsM2 instruction pattern: Standard Names. + * FIRST_PARM_OFFSET and virtual registers: Regs and Memory. + * fixMN2 instruction pattern: Standard Names. ++ * fix_truncMN2 instruction pattern: Standard Names. + * fixunsMN2 instruction pattern: Standard Names. + * fixuns_truncMN2 instruction pattern: Standard Names. + * floatMN2 instruction pattern: Standard Names. + * floatunsMN2 instruction pattern: Standard Names. + * float as function value type: Incompatibilities. +*************** +*** 148,153 **** +--- 148,159 ---- + * HImode, in insn: Insns. + * if_then_else and attributes: Expressions. + * if_then_else usage: Side Effects. ++ * in_struct, in code_label: Flags. ++ * in_struct, in insn: Flags. ++ * in_struct, in label_ref: Flags. ++ * in_struct, in mem: Flags. ++ * in_struct, in reg: Flags. ++ * in_struct, in subreg: Flags. + * indirect_jump instruction pattern: Standard Names. + * inline automatic for C++ member fns: Inline. + * insn and /i: Flags. +*************** +*** 156,168 **** + * insv instruction pattern: Standard Names. + * integrated, in insn: Flags. + * integrated, in reg: Flags. +- * in_struct, in code_label: Flags. +- * in_struct, in insn: Flags. +- * in_struct, in insn: Flags. +- * in_struct, in label_ref: Flags. +- * in_struct, in mem: Flags. +- * in_struct, in reg: Flags. +- * in_struct, in subreg: Flags. + * iorM3 instruction pattern: Standard Names. + * ior and attributes: Expressions. + * ior, canonicalization of: Insn Canonicalizations. +--- 162,167 ---- +*************** +*** 172,178 **** + * le and attributes: Expressions. + * load_multiple instruction pattern: Standard Names. + * long long data types: Long Long. +! * longjmp and automatic variables: Interface. + * longjmp and automatic variables: C Dialect Options. + * longjmp incompatibilities: Incompatibilities. + * longjmp warnings: Warning Options. +--- 171,177 ---- + * le and attributes: Expressions. + * load_multiple instruction pattern: Standard Names. + * long long data types: Long Long. +! * longjmp and automatic variables <1>: Interface. + * longjmp and automatic variables: C Dialect Options. + * longjmp incompatibilities: Incompatibilities. + * longjmp warnings: Warning Options. +*************** +*** 250,257 **** + * section function attribute: Function Attributes. + * section variable attribute: Variable Attributes. + * setjmp incompatibilities: Incompatibilities. +- * signature in C++, advantages: C++ Signatures. + * sign_extract, canonicalization of: Insn Canonicalizations. + * smulM3_highpart instruction pattern: Standard Names. + * sqrtM2 instruction pattern: Standard Names. + * sscanf, and constant strings: Incompatibilities. +--- 249,256 ---- + * section function attribute: Function Attributes. + * section variable attribute: Variable Attributes. + * setjmp incompatibilities: Incompatibilities. + * sign_extract, canonicalization of: Insn Canonicalizations. ++ * signature in C++, advantages: C++ Signatures. + * smulM3_highpart instruction pattern: Standard Names. + * sqrtM2 instruction pattern: Standard Names. + * sscanf, and constant strings: Incompatibilities. +*************** +*** 319,325 **** + * + in constraint: Modifiers. + * /i in RTL dump: Flags. + * /s in RTL dump: Flags. +- * /s in RTL dump: Flags. + * /u in RTL dump: Flags. + * /v in RTL dump: Flags. + * 0 in constraint: Simple Constraints. +--- 318,323 ---- +*************** +*** 327,339 **** + * = in constraint: Modifiers. + * > in constraint: Simple Constraints. + * ? in constraint: Multi-Alternative. + * d in constraint: Simple Constraints. + * E in constraint: Simple Constraints. + * F in constraint: Simple Constraints. + * G in constraint: Simple Constraints. +- * g in constraint: Simple Constraints. + * H in constraint: Simple Constraints. +- * I in constraint: Simple Constraints. + * i in constraint: Simple Constraints. + * m in constraint: Simple Constraints. + * n in constraint: Simple Constraints. +--- 325,336 ---- + * = in constraint: Modifiers. + * > in constraint: Simple Constraints. + * ? in constraint: Multi-Alternative. ++ * _ in variables in macros: Naming Types. + * d in constraint: Simple Constraints. + * E in constraint: Simple Constraints. + * F in constraint: Simple Constraints. + * G in constraint: Simple Constraints. + * H in constraint: Simple Constraints. + * i in constraint: Simple Constraints. + * m in constraint: Simple Constraints. + * n in constraint: Simple Constraints. +*************** +*** 345,376 **** + * s in constraint: Simple Constraints. + * V in constraint: Simple Constraints. + * X in constraint: Simple Constraints. +! * _ in variables in macros: Naming Types. +! * abort: Portability. + * abort: C Dialect Options. +! * abs: Arithmetic. + * abs: C Dialect Options. + * absolute value: Arithmetic. + * access to operands: Accessors. + * accessors: Accessors. + * ACCUMULATE_OUTGOING_ARGS: Stack Arguments. + * ADDITIONAL_REGISTER_NAMES: Instruction Output. + * address: RTL Template. + * address constraints: Simple Constraints. + * address of a label: Labels as Values. +- * addressing modes: Addressing Modes. + * ADDRESS_COST: Costs. + * address_operand: Simple Constraints. +! * addr_diff_vec: Side Effects. +! * addr_vec: Side Effects. + * ADJUST_COST: Costs. + * ADJUST_INSN_LENGTH: Insn Lengths. + * aggregates as return values: Aggregate Return. + * alignment: Alignment. + * Alliant: Interoperation. + * alloca: C Dialect Options. + * ALLOCATE_TRAMPOLINE: Trampolines. +- * ALL_REGS: Register Classes. + * alternate keywords: Alternate Keywords. + * AMD29K options: AMD29K Options. + * analysis, data flow: Passes. +--- 342,384 ---- + * s in constraint: Simple Constraints. + * V in constraint: Simple Constraints. + * X in constraint: Simple Constraints. +! * \: Output Template. +! * __bb_init_func: Profiling. +! * __builtin_apply: Constructing Calls. +! * __builtin_apply_args: Constructing Calls. +! * __builtin_args_info: Varargs. +! * __builtin_classify_type: Varargs. +! * __builtin_next_arg: Varargs. +! * __builtin_return: Constructing Calls. +! * __builtin_saveregs: Varargs. +! * __CTOR_LIST__: Initialization. +! * __DTOR_LIST__: Initialization. +! * __main: Collect2. +! * abort <1>: Portability. + * abort: C Dialect Options. +! * abs <1>: Arithmetic. + * abs: C Dialect Options. + * absolute value: Arithmetic. + * access to operands: Accessors. + * accessors: Accessors. + * ACCUMULATE_OUTGOING_ARGS: Stack Arguments. + * ADDITIONAL_REGISTER_NAMES: Instruction Output. ++ * addr_diff_vec: Side Effects. ++ * addr_vec: Side Effects. + * address: RTL Template. + * address constraints: Simple Constraints. + * address of a label: Labels as Values. + * ADDRESS_COST: Costs. + * address_operand: Simple Constraints. +! * addressing modes: Addressing Modes. + * ADJUST_COST: Costs. + * ADJUST_INSN_LENGTH: Insn Lengths. + * aggregates as return values: Aggregate Return. + * alignment: Alignment. ++ * ALL_REGS: Register Classes. + * Alliant: Interoperation. + * alloca: C Dialect Options. + * ALLOCATE_TRAMPOLINE: Trampolines. + * alternate keywords: Alternate Keywords. + * AMD29K options: AMD29K Options. + * analysis, data flow: Passes. +*************** +*** 378,390 **** + * ANSI support: C Dialect Options. + * apostrophes: Incompatibilities. + * APPLY_RESULT_SIZE: Scalar Return. + * ARGS_GROW_DOWNWARD: Frame Layout. + * argument passing: Interface. + * arguments in frame (88k): M88K Options. + * arguments in registers: Register Arguments. + * arguments on stack: Stack Arguments. +- * ARG_POINTER_REGNUM: Frame Registers. +- * arg_pointer_rtx: Frame Registers. + * arithmetic libraries: Interface. + * arithmetic shift: Arithmetic. + * arithmetic simplifications: Passes. +--- 386,398 ---- + * ANSI support: C Dialect Options. + * apostrophes: Incompatibilities. + * APPLY_RESULT_SIZE: Scalar Return. ++ * ARG_POINTER_REGNUM: Frame Registers. ++ * arg_pointer_rtx: Frame Registers. + * ARGS_GROW_DOWNWARD: Frame Layout. + * argument passing: Interface. + * arguments in frame (88k): M88K Options. + * arguments in registers: Register Arguments. + * arguments on stack: Stack Arguments. + * arithmetic libraries: Interface. + * arithmetic shift: Arithmetic. + * arithmetic simplifications: Passes. +*************** +*** 413,427 **** + * ASM_GLOBALIZE_LABEL: Label Output. + * ASM_IDENTIFY_GCC: File Framework. + * asm_input: Side Effects. +- * asm_noperands: Insns. + * ASM_NO_SKIP_IN_TEXT: Alignment Output. + * ASM_OPEN_PAREN: Data Output. + * ASM_OUTPUT_ADDR_DIFF_ELT: Dispatch Tables. + * ASM_OUTPUT_ADDR_VEC_ELT: Dispatch Tables. + * ASM_OUTPUT_ALIGN: Alignment Output. + * ASM_OUTPUT_ALIGNED_COMMON: Uninitialized Data. + * ASM_OUTPUT_ALIGNED_LOCAL: Uninitialized Data. +- * ASM_OUTPUT_ALIGN_CODE: Alignment Output. + * ASM_OUTPUT_ASCII: Data Output. + * ASM_OUTPUT_BYTE: Data Output. + * ASM_OUTPUT_CASE_END: Dispatch Tables. +--- 421,435 ---- + * ASM_GLOBALIZE_LABEL: Label Output. + * ASM_IDENTIFY_GCC: File Framework. + * asm_input: Side Effects. + * ASM_NO_SKIP_IN_TEXT: Alignment Output. ++ * asm_noperands: Insns. + * ASM_OPEN_PAREN: Data Output. + * ASM_OUTPUT_ADDR_DIFF_ELT: Dispatch Tables. + * ASM_OUTPUT_ADDR_VEC_ELT: Dispatch Tables. + * ASM_OUTPUT_ALIGN: Alignment Output. ++ * ASM_OUTPUT_ALIGN_CODE: Alignment Output. + * ASM_OUTPUT_ALIGNED_COMMON: Uninitialized Data. + * ASM_OUTPUT_ALIGNED_LOCAL: Uninitialized Data. + * ASM_OUTPUT_ASCII: Data Output. + * ASM_OUTPUT_BYTE: Data Output. + * ASM_OUTPUT_CASE_END: Dispatch Tables. +*************** +*** 462,486 **** + * ASM_STABN_OP: DBX Options. + * ASM_STABS_OP: DBX Options. + * ASM_WEAKEN_LABEL: Label Output. + * assembler format: File Framework. + * assembler instructions: Extended Asm. + * assembler instructions in RTL: Assembler. + * assembler names for identifiers: Asm Labels. + * assembler syntax, 88k: M88K Options. + * ASSEMBLER_DIALECT: Instruction Output. +- * assemble_name: Label Output. + * assembly code, invalid: Bug Criteria. + * assigning attribute values to insns: Tagging Insns. + * asterisk in template: Output Statement. + * atof: Cross-compilation. + * attr: Tagging Insns. + * attribute expressions: Expressions. + * attribute of types: Type Attributes. + * attribute of variables: Variable Attributes. + * attribute specifications: Attr Example. + * attribute specifications example: Attr Example. + * attributes, defining: Defining Attributes. +- * attr_flag: Expressions. + * autoincrement addressing, availability: Portability. + * autoincrement/decrement addressing: Simple Constraints. + * autoincrement/decrement analysis: Passes. +--- 470,494 ---- + * ASM_STABN_OP: DBX Options. + * ASM_STABS_OP: DBX Options. + * ASM_WEAKEN_LABEL: Label Output. ++ * assemble_name: Label Output. + * assembler format: File Framework. + * assembler instructions: Extended Asm. + * assembler instructions in RTL: Assembler. + * assembler names for identifiers: Asm Labels. + * assembler syntax, 88k: M88K Options. + * ASSEMBLER_DIALECT: Instruction Output. + * assembly code, invalid: Bug Criteria. + * assigning attribute values to insns: Tagging Insns. + * asterisk in template: Output Statement. + * atof: Cross-compilation. + * attr: Tagging Insns. ++ * attr_flag: Expressions. + * attribute expressions: Expressions. + * attribute of types: Type Attributes. + * attribute of variables: Variable Attributes. + * attribute specifications: Attr Example. + * attribute specifications example: Attr Example. + * attributes, defining: Defining Attributes. + * autoincrement addressing, availability: Portability. + * autoincrement/decrement addressing: Simple Constraints. + * autoincrement/decrement analysis: Passes. +*************** +*** 515,522 **** + * bugs, known: Trouble. + * builtin functions: C Dialect Options. + * byte writes (29k): AMD29K Options. +- * BYTES_BIG_ENDIAN: Storage Layout. + * byte_mode: Machine Modes. + * bzero: Config. + * C compilation options: Invoking GCC. + * C intermediate output, nonexistent: G++ and GCC. +--- 523,530 ---- + * bugs, known: Trouble. + * builtin functions: C Dialect Options. + * byte writes (29k): AMD29K Options. + * byte_mode: Machine Modes. ++ * BYTES_BIG_ENDIAN: Storage Layout. + * bzero: Config. + * C compilation options: Invoking GCC. + * C intermediate output, nonexistent: G++ and GCC. +*************** +*** 539,559 **** + * C++ static data, declaring and defining: Static Definitions. + * C++ subtype polymorphism: C++ Signatures. + * C++ type abstraction: C++ Signatures. + * call: Side Effects. + * call-clobbered register: Register Basics. + * call-saved register: Register Basics. + * call-used register: Register Basics. +- * CALLER_SAVE_PROFITABLE: Caller Saves. +- * calling conventions: Stack and Calling. +- * calling functions in RTL: Calls. + * call_insn: Insns. + * CALL_INSN_FUNCTION_USAGE: Insns. + * CALL_USED_REGISTERS: Register Basics. + * call_used_regs: Register Basics. +! * canonicalization of instructions: Insn Canonicalizations. +! * CANONICALIZE_COMPARISON: Condition Code. + * CAN_DEBUG_WITHOUT_FP: Run-time Target. + * CAN_ELIMINATE: Elimination. + * case labels in initializers: Labeled Elements. + * case ranges: Case Ranges. + * case sensitivity and VMS: VMS Misc. +--- 547,568 ---- + * C++ static data, declaring and defining: Static Definitions. + * C++ subtype polymorphism: C++ Signatures. + * C++ type abstraction: C++ Signatures. ++ * C_INCLUDE_PATH: Environment Variables. + * call: Side Effects. + * call-clobbered register: Register Basics. + * call-saved register: Register Basics. + * call-used register: Register Basics. + * call_insn: Insns. + * CALL_INSN_FUNCTION_USAGE: Insns. + * CALL_USED_REGISTERS: Register Basics. + * call_used_regs: Register Basics. +! * CALLER_SAVE_PROFITABLE: Caller Saves. +! * calling conventions: Stack and Calling. +! * calling functions in RTL: Calls. + * CAN_DEBUG_WITHOUT_FP: Run-time Target. + * CAN_ELIMINATE: Elimination. ++ * canonicalization of instructions: Insn Canonicalizations. ++ * CANONICALIZE_COMPARISON: Condition Code. + * case labels in initializers: Labeled Elements. + * case ranges: Case Ranges. + * case sensitivity and VMS: VMS Misc. +*************** +*** 566,577 **** + * CC: Host Fragment. + * cc0: Regs and Memory. + * cc0_rtx: Regs and Memory. +- * CC1PLUS_SPEC: Driver. + * CC1_SPEC: Driver. +! * CCmode: Machine Modes. + * cc_status: Condition Code. + * CC_STATUS_MDEP: Condition Code. + * CC_STATUS_MDEP_INIT: Condition Code. + * CDImode: Machine Modes. + * change_address: Standard Names. + * CHAR_TYPE_SIZE: Type Layout. +--- 575,586 ---- + * CC: Host Fragment. + * cc0: Regs and Memory. + * cc0_rtx: Regs and Memory. + * CC1_SPEC: Driver. +! * CC1PLUS_SPEC: Driver. + * cc_status: Condition Code. + * CC_STATUS_MDEP: Condition Code. + * CC_STATUS_MDEP_INIT: Condition Code. ++ * CCmode: Machine Modes. + * CDImode: Machine Modes. + * change_address: Standard Names. + * CHAR_TYPE_SIZE: Type Layout. +*************** +*** 579,602 **** + * CHImode: Machine Modes. + * class definitions, register: Register Classes. + * class preference constraints: Class Preferences. +- * classes of RTX codes: Accessors. + * CLASS_LIKELY_SPILLED_P: Register Classes. + * CLASS_MAX_NREGS: Register Classes. + * CLEAR_INSN_CACHE: Trampolines. + * CLIB: Host Fragment. + * clobber: Side Effects. + * code generation conventions: Code Gen Options. + * code generation RTL sequences: Expander Definitions. + * code motion: Passes. +- * codes, RTL expression: RTL Objects. + * code_label: Insns. + * CODE_LABEL_NUMBER: Insns. + * COImode: Machine Modes. + * COLLECT_EXPORT_LIST: Config. + * combiner pass: Regs and Memory. + * command options: Invoking GCC. + * comments, C++ style: C++ Comments. + * common subexpression elimination: Passes. + * compare: Arithmetic. + * compilation in a separate directory: Other Dir. + * compiler bugs, reporting: Bug Reporting. +--- 588,612 ---- + * CHImode: Machine Modes. + * class definitions, register: Register Classes. + * class preference constraints: Class Preferences. + * CLASS_LIKELY_SPILLED_P: Register Classes. + * CLASS_MAX_NREGS: Register Classes. ++ * classes of RTX codes: Accessors. + * CLEAR_INSN_CACHE: Trampolines. + * CLIB: Host Fragment. + * clobber: Side Effects. + * code generation conventions: Code Gen Options. + * code generation RTL sequences: Expander Definitions. + * code motion: Passes. + * code_label: Insns. + * CODE_LABEL_NUMBER: Insns. ++ * codes, RTL expression: RTL Objects. + * COImode: Machine Modes. + * COLLECT_EXPORT_LIST: Config. + * combiner pass: Regs and Memory. + * command options: Invoking GCC. + * comments, C++ style: C++ Comments. + * common subexpression elimination: Passes. ++ * COMP_TYPE_ATTRIBUTES: Misc. + * compare: Arithmetic. + * compilation in a separate directory: Other Dir. + * compiler bugs, reporting: Bug Reporting. +*************** +*** 610,616 **** + * compound expressions as lvalues: Lvalues. + * computed gotos: Labels as Values. + * computing the length of an insn: Insn Lengths. +- * COMP_TYPE_ATTRIBUTES: Misc. + * cond: Comparisons. + * condition code register: Regs and Memory. + * condition code status: Condition Code. +--- 620,625 ---- +*************** +*** 623,642 **** + * configurations supported by GNU CC: Configurations. + * conflicting types: Disappointments. + * const0_rtx: Constants. +- * CONST0_RTX: Constants. + * const1_rtx: Constants. +- * CONST1_RTX: Constants. +- * CONST2_RTX: Constants. + * const2_rtx: Constants. + * constant attributes: Constant Attributes. + * constant folding: Passes. + * constant folding and floating point: Cross-compilation. + * constant propagation: Passes. +- * constants in constraints: Simple Constraints. + * CONSTANT_ADDRESS_P: Addressing Modes. + * CONSTANT_ALIGNMENT: Storage Layout. + * CONSTANT_P: Addressing Modes. + * CONSTANT_POOL_ADDRESS_P: Flags. + * constm1_rtx: Constants. + * constraint modifier characters: Modifiers. + * constraint, matching: Simple Constraints. +--- 632,659 ---- + * configurations supported by GNU CC: Configurations. + * conflicting types: Disappointments. + * const0_rtx: Constants. + * const1_rtx: Constants. + * const2_rtx: Constants. ++ * CONST_CALL_P: Flags. ++ * CONST_COSTS: Costs. ++ * const_double: Constants. ++ * CONST_DOUBLE_CHAIN: Constants. ++ * CONST_DOUBLE_LOW: Constants. ++ * CONST_DOUBLE_MEM: Constants. ++ * CONST_DOUBLE_OK_FOR_LETTER_P: Register Classes. ++ * const_int: Constants. ++ * CONST_OK_FOR_LETTER_P: Register Classes. ++ * const_string: Constants. ++ * const_true_rtx: Constants. + * constant attributes: Constant Attributes. + * constant folding: Passes. + * constant folding and floating point: Cross-compilation. + * constant propagation: Passes. + * CONSTANT_ADDRESS_P: Addressing Modes. + * CONSTANT_ALIGNMENT: Storage Layout. + * CONSTANT_P: Addressing Modes. + * CONSTANT_POOL_ADDRESS_P: Flags. ++ * constants in constraints: Simple Constraints. + * constm1_rtx: Constants. + * constraint modifier characters: Modifiers. + * constraint, matching: Simple Constraints. +*************** +*** 647,663 **** + * constructors vs goto: Destructors and Goto. + * constructors, automatic calls: Collect2. + * constructors, output of: Initialization. +- * CONST_CALL_P: Flags. +- * CONST_COSTS: Costs. +- * const_double: Constants. +- * CONST_DOUBLE_CHAIN: Constants. +- * CONST_DOUBLE_LOW: Constants. +- * CONST_DOUBLE_MEM: Constants. +- * CONST_DOUBLE_OK_FOR_LETTER_P: Register Classes. +- * const_int: Constants. +- * CONST_OK_FOR_LETTER_P: Register Classes. +- * const_string: Constants. +- * const_true_rtx: Constants. + * contributors: Contributors. + * controlling register usage: Register Basics. + * controlling the compilation driver: Driver. +--- 664,669 ---- +*************** +*** 686,692 **** + * current_function_outgoing_args_size: Stack Arguments. + * current_function_pops_args: Function Entry. + * current_function_pretend_args_size: Function Entry. +- * C_INCLUDE_PATH: Environment Variables. + * data flow analysis: Passes. + * DATA_ALIGNMENT: Storage Layout. + * data_section: Sections. +--- 692,697 ---- +*************** +*** 706,713 **** + * DBX_OUTPUT_FUNCTION_END: DBX Hooks. + * DBX_OUTPUT_LBRAC: DBX Hooks. + * DBX_OUTPUT_MAIN_SOURCE_DIRECTORY: File Names and DBX. +- * DBX_OUTPUT_MAIN_SOURCE_FILENAME: File Names and DBX. + * DBX_OUTPUT_MAIN_SOURCE_FILE_END: File Names and DBX. + * DBX_OUTPUT_RBRAC: DBX Hooks. + * DBX_OUTPUT_SOURCE_FILENAME: File Names and DBX. + * DBX_OUTPUT_STANDARD_TYPES: DBX Hooks. +--- 711,718 ---- + * DBX_OUTPUT_FUNCTION_END: DBX Hooks. + * DBX_OUTPUT_LBRAC: DBX Hooks. + * DBX_OUTPUT_MAIN_SOURCE_DIRECTORY: File Names and DBX. + * DBX_OUTPUT_MAIN_SOURCE_FILE_END: File Names and DBX. ++ * DBX_OUTPUT_MAIN_SOURCE_FILENAME: File Names and DBX. + * DBX_OUTPUT_RBRAC: DBX Hooks. + * DBX_OUTPUT_SOURCE_FILENAME: File Names and DBX. + * DBX_OUTPUT_STANDARD_TYPES: DBX Hooks. +*************** +*** 724,736 **** + * dead_or_set_p: Peephole Definitions. + * deallocating variable length arrays: Variable Length. + * death notes: Obsolete Register Macros. + * DEBUGGER_ARG_OFFSET: All Debuggers. + * DEBUGGER_AUTO_OFFSET: All Debuggers. + * debugging information generation: Passes. + * debugging information options: Debugging Options. + * debugging, 88k OCS: M88K Options. +- * debug_rtx: Bug Reporting. +- * DEBUG_SYMS_TEXT: DBX Options. + * declaration scope: Incompatibilities. + * declarations inside expressions: Statement Exprs. + * declarations, RTL: RTL Declarations. +--- 729,741 ---- + * dead_or_set_p: Peephole Definitions. + * deallocating variable length arrays: Variable Length. + * death notes: Obsolete Register Macros. ++ * debug_rtx: Bug Reporting. ++ * DEBUG_SYMS_TEXT: DBX Options. + * DEBUGGER_ARG_OFFSET: All Debuggers. + * DEBUGGER_AUTO_OFFSET: All Debuggers. + * debugging information generation: Passes. + * debugging information options: Debugging Options. + * debugging, 88k OCS: M88K Options. + * declaration scope: Incompatibilities. + * declarations inside expressions: Statement Exprs. + * declarations, RTL: RTL Declarations. +*************** +*** 757,764 **** + * defining RTL sequences for code generation: Expander Definitions. + * defining static data in C++: Static Definitions. + * delay slots, defining: Delay Slots. +- * delayed branch scheduling: Passes. + * DELAY_SLOTS_FOR_EPILOGUE: Function Entry. + * dependencies for make as output: Environment Variables. + * dependencies, make: Preprocessor Options. + * DEPENDENCIES_OUTPUT: Environment Variables. +--- 762,769 ---- + * defining RTL sequences for code generation: Expander Definitions. + * defining static data in C++: Static Definitions. + * delay slots, defining: Delay Slots. + * DELAY_SLOTS_FOR_EPILOGUE: Function Entry. ++ * delayed branch scheduling: Passes. + * dependencies for make as output: Environment Variables. + * dependencies, make: Preprocessor Options. + * DEPENDENCIES_OUTPUT: Environment Variables. +*************** +*** 770,785 **** + * dialect options: C Dialect Options. + * digits in constraint: Simple Constraints. + * DImode: Machine Modes. +- * directory options: Directory Options. + * DIR_SEPARATOR: Config. + * disabling certain registers: Register Basics. + * dispatch table: Dispatch Tables. + * div: Arithmetic. + * DIVDI3_LIBCALL: Library Calls. + * divide instruction, 88k: M88K Options. + * division: Arithmetic. +- * division: Arithmetic. +- * division: Arithmetic. + * DIVSI3_LIBCALL: Library Calls. + * dollar signs in identifier names: Dollar Signs. + * DOLLARS_IN_IDENTIFIERS: Misc. +--- 775,788 ---- + * dialect options: C Dialect Options. + * digits in constraint: Simple Constraints. + * DImode: Machine Modes. + * DIR_SEPARATOR: Config. ++ * directory options: Directory Options. + * disabling certain registers: Register Basics. + * dispatch table: Dispatch Tables. + * div: Arithmetic. + * DIVDI3_LIBCALL: Library Calls. + * divide instruction, 88k: M88K Options. + * division: Arithmetic. + * DIVSI3_LIBCALL: Library Calls. + * dollar signs in identifier names: Dollar Signs. + * DOLLARS_IN_IDENTIFIERS: Misc. +*************** +*** 807,814 **** + * environment variables: Environment Variables. + * epilogue: Function Entry. + * eq: Comparisons. +- * equal: Comparisons. + * eq_attr: Expressions. + * error messages: Warnings and Errors. + * escape sequences, traditional: C Dialect Options. + * exclamation point: Multi-Alternative. +--- 810,817 ---- + * environment variables: Environment Variables. + * epilogue: Function Entry. + * eq: Comparisons. + * eq_attr: Expressions. ++ * equal: Comparisons. + * error messages: Warnings and Errors. + * escape sequences, traditional: C Dialect Options. + * exclamation point: Multi-Alternative. +*************** +*** 818,835 **** + * exit status and VMS: VMS Misc. + * EXIT_BODY: Misc. + * EXIT_IGNORE_STACK: Function Entry. +- * expander definitions: Expander Definitions. + * EXPAND_BUILTIN_SAVEREGS: Varargs. + * explicit register variables: Explicit Reg Vars. + * expression codes: RTL Objects. + * expressions containing statements: Statement Exprs. + * expressions, compound, as lvalues: Lvalues. + * expressions, conditional, as lvalues: Lvalues. + * expressions, constructor: Constructors. +- * expr_list: Insns. + * extended asm: Extended Asm. + * extensible constraints: Simple Constraints. +! * extensions, ?:: Conditionals. + * extensions, ?:: Lvalues. + * extensions, C language: C Extensions. + * extensions, C++ language: C++ Extensions. +--- 821,838 ---- + * exit status and VMS: VMS Misc. + * EXIT_BODY: Misc. + * EXIT_IGNORE_STACK: Function Entry. + * EXPAND_BUILTIN_SAVEREGS: Varargs. ++ * expander definitions: Expander Definitions. + * explicit register variables: Explicit Reg Vars. ++ * expr_list: Insns. + * expression codes: RTL Objects. + * expressions containing statements: Statement Exprs. + * expressions, compound, as lvalues: Lvalues. + * expressions, conditional, as lvalues: Lvalues. + * expressions, constructor: Constructors. + * extended asm: Extended Asm. + * extensible constraints: Simple Constraints. +! * extensions, ?: <1>: Conditionals. + * extensions, ?:: Lvalues. + * extensions, C language: C Extensions. + * extensions, C++ language: C++ Extensions. +*************** +*** 838,876 **** + * EXTRA_CC_MODES: Condition Code. + * EXTRA_CC_NAMES: Condition Code. + * EXTRA_CONSTRAINT: Register Classes. +- * EXTRA_SECTIONS: Sections. + * EXTRA_SECTION_FUNCTIONS: Sections. + * fabs: C Dialect Options. + * FAIL: Expander Definitions. + * fatal signal: Bug Criteria. + * FATAL_EXIT_CODE: Config. + * features, optional, in system conventions: Run-time Target. + * ffs: C Dialect Options. +- * ffs: Arithmetic. + * file name suffix: Overall Options. + * file names: Link Options. + * files and passes of the compiler: Passes. + * final pass: Passes. +- * FINALIZE_PIC: PIC. + * FINAL_PRESCAN_INSN: Instruction Output. + * FINAL_REG_PARM_STACK_SPACE: Stack Arguments. + * final_scan_insn: Function Entry. + * final_sequence: Instruction Output. + * FIRST_INSN_ADDRESS: Insn Lengths. + * FIRST_PARM_OFFSET: Frame Layout. + * FIRST_PSEUDO_REGISTER: Register Basics. + * FIRST_STACK_REG: Stack Registers. + * FIRST_VIRTUAL_REGISTER: Regs and Memory. + * fix: Conversions. +- * fix: Conversions. + * fixed register: Register Basics. + * FIXED_REGISTERS: Register Basics. + * fixed_regs: Register Basics. + * FIXUNS_TRUNC_LIKE_FIX_TRUNC: Misc. + * flags in RTL expression: Flags. + * float: Conversions. +- * FLOATIFY: Library Calls. +- * floating point and cross compilation: Cross-compilation. + * FLOAT_ARG_TYPE: Library Calls. + * float_extend: Conversions. + * FLOAT_STORE_FLAG_VALUE: Misc. +--- 841,876 ---- + * EXTRA_CC_MODES: Condition Code. + * EXTRA_CC_NAMES: Condition Code. + * EXTRA_CONSTRAINT: Register Classes. + * EXTRA_SECTION_FUNCTIONS: Sections. ++ * EXTRA_SECTIONS: Sections. + * fabs: C Dialect Options. + * FAIL: Expander Definitions. + * fatal signal: Bug Criteria. + * FATAL_EXIT_CODE: Config. + * features, optional, in system conventions: Run-time Target. ++ * ffs <1>: Arithmetic. + * ffs: C Dialect Options. + * file name suffix: Overall Options. + * file names: Link Options. + * files and passes of the compiler: Passes. + * final pass: Passes. + * FINAL_PRESCAN_INSN: Instruction Output. + * FINAL_REG_PARM_STACK_SPACE: Stack Arguments. + * final_scan_insn: Function Entry. + * final_sequence: Instruction Output. ++ * FINALIZE_PIC: PIC. + * FIRST_INSN_ADDRESS: Insn Lengths. + * FIRST_PARM_OFFSET: Frame Layout. + * FIRST_PSEUDO_REGISTER: Register Basics. + * FIRST_STACK_REG: Stack Registers. + * FIRST_VIRTUAL_REGISTER: Regs and Memory. + * fix: Conversions. + * fixed register: Register Basics. + * FIXED_REGISTERS: Register Basics. + * fixed_regs: Register Basics. + * FIXUNS_TRUNC_LIKE_FIX_TRUNC: Misc. + * flags in RTL expression: Flags. + * float: Conversions. + * FLOAT_ARG_TYPE: Library Calls. + * float_extend: Conversions. + * FLOAT_STORE_FLAG_VALUE: Misc. +*************** +*** 878,883 **** +--- 878,885 ---- + * FLOAT_TYPE_SIZE: Type Layout. + * FLOAT_VALUE_TYPE: Library Calls. + * FLOAT_WORDS_BIG_ENDIAN: Storage Layout. ++ * FLOATIFY: Library Calls. ++ * floating point and cross compilation: Cross-compilation. + * force_reg: Standard Names. + * forwarding calls: Constructing Calls. + * frame layout: Frame Layout. +*************** +*** 894,910 **** + * function units, for scheduling: Function Units. + * function, size of pointer to: Pointer Arith. + * function-call insns: Calls. +- * functions in arbitrary sections: Function Attributes. +- * functions that are passed arguments in registers on the 386: Function Attributes. +- * functions that are passed arguments in registers on the 386: Function Attributes. +- * functions that do not pop the argument stack on the 386: Function Attributes. +- * functions that do pop the argument stack on the 386: Function Attributes. +- * functions that have no side effects: Function Attributes. +- * functions that never return: Function Attributes. +- * functions that pop the argument stack on the 386: Function Attributes. +- * functions that pop the argument stack on the 386: Function Attributes. +- * functions with printf or scanf style arguments: Function Attributes. +- * functions, leaf: Leaf Functions. + * FUNCTION_ARG: Register Arguments. + * FUNCTION_ARG_ADVANCE: Register Arguments. + * FUNCTION_ARG_BOUNDARY: Register Arguments. +--- 896,901 ---- +*************** +*** 924,943 **** + * FUNCTION_PROLOGUE: Function Entry. + * FUNCTION_VALUE: Scalar Return. + * FUNCTION_VALUE_REGNO_P: Scalar Return. +! * G++: G++ and GCC. + * g++: Invoking G++. + * GCC: G++ and GCC. + * GCC_EXEC_PREFIX: Environment Variables. + * ge: Comparisons. + * gencodes: Passes. + * genconfig: Passes. +- * generalized lvalues: Lvalues. + * general_operand: RTL Template. + * GENERAL_REGS: Register Classes. + * generating assembler output: Output Statement. + * generating insns: RTL Template. + * genflags: Passes. +- * GEN_ERRNO_RTX: Library Calls. + * get_attr: Expressions. + * get_attr_length: Insn Lengths. + * GET_CLASS_NARROWEST_MODE: Machine Modes. +--- 915,943 ---- + * FUNCTION_PROLOGUE: Function Entry. + * FUNCTION_VALUE: Scalar Return. + * FUNCTION_VALUE_REGNO_P: Scalar Return. +! * functions in arbitrary sections: Function Attributes. +! * functions that are passed arguments in registers on the 386: Function Attributes. +! * functions that do not pop the argument stack on the 386: Function Attributes. +! * functions that do pop the argument stack on the 386: Function Attributes. +! * functions that have no side effects: Function Attributes. +! * functions that never return: Function Attributes. +! * functions that pop the argument stack on the 386: Function Attributes. +! * functions with printf or scanf style arguments: Function Attributes. +! * functions, leaf: Leaf Functions. + * g++: Invoking G++. ++ * G++: G++ and GCC. + * GCC: G++ and GCC. + * GCC_EXEC_PREFIX: Environment Variables. + * ge: Comparisons. ++ * GEN_ERRNO_RTX: Library Calls. + * gencodes: Passes. + * genconfig: Passes. + * general_operand: RTL Template. + * GENERAL_REGS: Register Classes. ++ * generalized lvalues: Lvalues. + * generating assembler output: Output Statement. + * generating insns: RTL Template. + * genflags: Passes. + * get_attr: Expressions. + * get_attr_length: Insn Lengths. + * GET_CLASS_NARROWEST_MODE: Machine Modes. +*************** +*** 969,990 **** + * GLOBALVALUEREF: Global Declarations. + * GNU CC and portability: Portability. + * GNU CC command options: Invoking GCC. +- * goto with computed label: Labels as Values. + * GO_IF_LEGITIMATE_ADDRESS: Addressing Modes. + * GO_IF_MODE_DEPENDENT_ADDRESS: Addressing Modes. + * gp-relative references (MIPS): MIPS Options. + * greater than: Comparisons. +- * greater than: Comparisons. +- * greater than: Comparisons. + * grouping options: Invoking GCC. + * gt: Comparisons. + * gtu: Comparisons. + * HANDLE_PRAGMA: Misc. + * hard registers: Regs and Memory. +- * hardware models and configurations, specifying: Submodel Options. + * HARD_FRAME_POINTER_REGNUM: Frame Registers. + * HARD_REGNO_MODE_OK: Values in Registers. + * HARD_REGNO_NREGS: Values in Registers. + * HAS_INIT_SECTION: Macros for Initialization. + * HAVE_ATEXIT: Misc. + * HAVE_POST_DECREMENT: Addressing Modes. +--- 969,988 ---- + * GLOBALVALUEREF: Global Declarations. + * GNU CC and portability: Portability. + * GNU CC command options: Invoking GCC. + * GO_IF_LEGITIMATE_ADDRESS: Addressing Modes. + * GO_IF_MODE_DEPENDENT_ADDRESS: Addressing Modes. ++ * goto with computed label: Labels as Values. + * gp-relative references (MIPS): MIPS Options. + * greater than: Comparisons. + * grouping options: Invoking GCC. + * gt: Comparisons. + * gtu: Comparisons. + * HANDLE_PRAGMA: Misc. + * hard registers: Regs and Memory. + * HARD_FRAME_POINTER_REGNUM: Frame Registers. + * HARD_REGNO_MODE_OK: Values in Registers. + * HARD_REGNO_NREGS: Values in Registers. ++ * hardware models and configurations, specifying: Submodel Options. + * HAS_INIT_SECTION: Macros for Initialization. + * HAVE_ATEXIT: Misc. + * HAVE_POST_DECREMENT: Addressing Modes. +*************** +*** 1019,1024 **** +--- 1017,1025 ---- + * implicit argument: return value: Naming Results. + * IMPLICIT_FIX_EXPR: Misc. + * implied #pragma implementation: C++ Interface. ++ * in_data: Sections. ++ * in_struct: Flags. ++ * in_text: Sections. + * include files and VMS: Include Files and VMS. + * INCLUDE_DEFAULTS: Driver. + * inclusive-or, bitwise: Arithmetic. +*************** +*** 1026,1044 **** + * incompatibilities of GNU CC: Incompatibilities. + * increment operators: Bug Criteria. + * INDEX_REG_CLASS: Register Classes. +- * initialization routines: Initialization. +- * initializations in expressions: Constructors. +- * initializers with labeled elements: Labeled Elements. +- * initializers, non-constant: Initializers. +- * INITIALIZE_TRAMPOLINE: Trampolines. +- * INITIAL_ELIMINATION_OFFSET: Elimination. +- * INITIAL_FRAME_POINTER_OFFSET: Elimination. + * INIT_CUMULATIVE_ARGS: Register Arguments. + * INIT_CUMULATIVE_INCOMING_ARGS: Register Arguments. + * INIT_ENVIRONMENT: Driver. +! * INIT_SECTION_ASM_OP: Macros for Initialization. + * INIT_SECTION_ASM_OP: Sections. + * INIT_TARGET_OPTABS: Library Calls. + * inline functions: Inline. + * inline functions, omission of: Inline. + * inline, automatic: Passes. +--- 1027,1045 ---- + * incompatibilities of GNU CC: Incompatibilities. + * increment operators: Bug Criteria. + * INDEX_REG_CLASS: Register Classes. + * INIT_CUMULATIVE_ARGS: Register Arguments. + * INIT_CUMULATIVE_INCOMING_ARGS: Register Arguments. + * INIT_ENVIRONMENT: Driver. +! * INIT_SECTION_ASM_OP <1>: Macros for Initialization. + * INIT_SECTION_ASM_OP: Sections. + * INIT_TARGET_OPTABS: Library Calls. ++ * INITIAL_ELIMINATION_OFFSET: Elimination. ++ * INITIAL_FRAME_POINTER_OFFSET: Elimination. ++ * initialization routines: Initialization. ++ * initializations in expressions: Constructors. ++ * INITIALIZE_TRAMPOLINE: Trampolines. ++ * initializers with labeled elements: Labeled Elements. ++ * initializers, non-constant: Initializers. + * inline functions: Inline. + * inline functions, omission of: Inline. + * inline, automatic: Passes. +*************** +*** 1049,1057 **** + * insn lengths, computing: Insn Lengths. + * insn splitting: Insn Splitting. + * insn-attr.h: Defining Attributes. +- * insns: Insns. +- * insns, generating: RTL Template. +- * insns, recognizing: RTL Template. + * INSN_ANNULLED_BRANCH_P: Flags. + * INSN_CACHE_DEPTH: Trampolines. + * INSN_CACHE_LINE_WIDTH: Trampolines. +--- 1050,1055 ---- +*************** +*** 1064,1069 **** +--- 1062,1070 ---- + * INSN_REFERENCES_ARE_DELAYED: Misc. + * INSN_SETS_ARE_DELAYED: Misc. + * INSN_UID: Insns. ++ * insns: Insns. ++ * insns, generating: RTL Template. ++ * insns, recognizing: RTL Template. + * INSTALL: Host Fragment. + * installation trouble: Trouble. + * installing GNU CC: Installation. +*************** +*** 1074,1083 **** + * instruction patterns: Patterns. + * instruction recognizer: Passes. + * instruction scheduling: Passes. +- * instruction scheduling: Passes. + * instruction splitting: Insn Splitting. +! * integrated: Flags. + * INTEGRATE_THRESHOLD: Misc. + * integrating function code: Inline. + * Intel 386 Options: i386 Options. + * Interdependence of Patterns: Dependent Patterns. +--- 1075,1084 ---- + * instruction patterns: Patterns. + * instruction recognizer: Passes. + * instruction scheduling: Passes. + * instruction splitting: Insn Splitting. +! * INT_TYPE_SIZE: Type Layout. + * INTEGRATE_THRESHOLD: Misc. ++ * integrated: Flags. + * integrating function code: Inline. + * Intel 386 Options: i386 Options. + * Interdependence of Patterns: Dependent Patterns. +*************** +*** 1086,1103 **** + * intermediate C version, nonexistent: G++ and GCC. + * INTIFY: Library Calls. + * introduction: Top. +- * INT_TYPE_SIZE: Type Layout. + * invalid assembly code: Bug Criteria. + * invalid input: Bug Criteria. + * INVOKE__main: Macros for Initialization. + * invoking g++: Invoking G++. +- * in_data: Sections. +- * in_struct: Flags. +- * in_text: Sections. + * ior: Arithmetic. + * isinf: Cross-compilation. + * isnan: Cross-compilation. +- * IS_ASM_LOGICAL_LINE_SEPARATOR: Data Output. + * jump instruction patterns: Jump Patterns. + * jump instructions and set: Side Effects. + * jump optimization: Passes. +--- 1087,1100 ---- + * intermediate C version, nonexistent: G++ and GCC. + * INTIFY: Library Calls. + * introduction: Top. + * invalid assembly code: Bug Criteria. + * invalid input: Bug Criteria. + * INVOKE__main: Macros for Initialization. + * invoking g++: Invoking G++. + * ior: Arithmetic. ++ * IS_ASM_LOGICAL_LINE_SEPARATOR: Data Output. + * isinf: Cross-compilation. + * isnan: Cross-compilation. + * jump instruction patterns: Jump Patterns. + * jump instructions and set: Side Effects. + * jump optimization: Passes. +*************** +*** 1108,1135 **** + * kernel and user registers (29k): AMD29K Options. + * keywords, alternate: Alternate Keywords. + * known causes of trouble: Trouble. +- * labeled elements in initializers: Labeled Elements. +- * labels as values: Labels as Values. + * LABEL_NUSES: Insns. + * LABEL_OUTSIDE_LOOP_P: Flags. + * LABEL_PRESERVE_P: Flags. + * label_ref: Constants. + * labs: C Dialect Options. + * language dialect options: C Dialect Options. + * large bit shifts (88k): M88K Options. + * large return values: Aggregate Return. + * LAST_STACK_REG: Stack Registers. + * LAST_VIRTUAL_REGISTER: Regs and Memory. +- * LDD_SUFFIX: Macros for Initialization. +- * ldexp: Cross-compilation. + * LD_FINI_SWITCH: Macros for Initialization. + * LD_INIT_SWITCH: Macros for Initialization. + * le: Comparisons. + * leaf functions: Leaf Functions. + * leaf_function: Leaf Functions. + * leaf_function_p: Standard Names. +- * LEAF_REGISTERS: Leaf Functions. + * LEAF_REG_REMAP: Leaf Functions. + * left rotate: Arithmetic. + * left shift: Arithmetic. + * LEGITIMATE_CONSTANT_P: Addressing Modes. +--- 1105,1132 ---- + * kernel and user registers (29k): AMD29K Options. + * keywords, alternate: Alternate Keywords. + * known causes of trouble: Trouble. + * LABEL_NUSES: Insns. + * LABEL_OUTSIDE_LOOP_P: Flags. + * LABEL_PRESERVE_P: Flags. + * label_ref: Constants. ++ * labeled elements in initializers: Labeled Elements. ++ * labels as values: Labels as Values. + * labs: C Dialect Options. + * language dialect options: C Dialect Options. + * large bit shifts (88k): M88K Options. + * large return values: Aggregate Return. + * LAST_STACK_REG: Stack Registers. + * LAST_VIRTUAL_REGISTER: Regs and Memory. + * LD_FINI_SWITCH: Macros for Initialization. + * LD_INIT_SWITCH: Macros for Initialization. ++ * LDD_SUFFIX: Macros for Initialization. ++ * ldexp: Cross-compilation. + * le: Comparisons. + * leaf functions: Leaf Functions. + * leaf_function: Leaf Functions. + * leaf_function_p: Standard Names. + * LEAF_REG_REMAP: Leaf Functions. ++ * LEAF_REGISTERS: Leaf Functions. + * left rotate: Arithmetic. + * left shift: Arithmetic. + * LEGITIMATE_CONSTANT_P: Addressing Modes. +*************** +*** 1140,1145 **** +--- 1137,1143 ---- + * less than or equal: Comparisons. + * leu: Comparisons. + * LIB2FUNCS_EXTRA: Target Fragment. ++ * LIB_SPEC: Driver. + * LIBCALL_VALUE: Scalar Return. + * LIBGCC1: Target Fragment. + * LIBGCC2_CFLAGS: Target Fragment. +*************** +*** 1149,1160 **** + * Libraries: Link Options. + * library subroutine names: Library Calls. + * LIBRARY_PATH: Environment Variables. +- * LIB_SPEC: Driver. + * LIMIT_RELOAD_CLASS: Register Classes. + * link options: Link Options. + * LINK_LIBGCC_SPECIAL: Driver. + * LINK_LIBGCC_SPECIAL_1: Driver. + * LINK_SPEC: Driver. + * load address instruction: Simple Constraints. + * LOAD_EXTEND_OP: Misc. + * local labels: Local Labels. +--- 1147,1158 ---- + * Libraries: Link Options. + * library subroutine names: Library Calls. + * LIBRARY_PATH: Environment Variables. + * LIMIT_RELOAD_CLASS: Register Classes. + * link options: Link Options. + * LINK_LIBGCC_SPECIAL: Driver. + * LINK_LIBGCC_SPECIAL_1: Driver. + * LINK_SPEC: Driver. ++ * lo_sum: Arithmetic. + * load address instruction: Simple Constraints. + * LOAD_EXTEND_OP: Misc. + * local labels: Local Labels. +*************** +*** 1163,1177 **** + * local variables, specifying registers: Local Reg Vars. + * LOCAL_INCLUDE_DIR: Driver. + * LOCAL_LABEL_PREFIX: Instruction Output. +- * logical-and, bitwise: Arithmetic. + * LOG_LINKS: Insns. +! * longjmp: Global Reg Vars. +! * LONGJMP_RESTORE_FROM_STACK: Elimination. + * LONG_DOUBLE_TYPE_SIZE: Type Layout. + * LONG_LONG_TYPE_SIZE: Type Layout. + * LONG_TYPE_SIZE: Type Layout. + * loop optimization: Passes. +- * lo_sum: Arithmetic. + * lshiftrt: Arithmetic. + * lt: Comparisons. + * ltu: Comparisons. +--- 1161,1174 ---- + * local variables, specifying registers: Local Reg Vars. + * LOCAL_INCLUDE_DIR: Driver. + * LOCAL_LABEL_PREFIX: Instruction Output. + * LOG_LINKS: Insns. +! * logical-and, bitwise: Arithmetic. + * LONG_DOUBLE_TYPE_SIZE: Type Layout. + * LONG_LONG_TYPE_SIZE: Type Layout. + * LONG_TYPE_SIZE: Type Layout. ++ * longjmp: Global Reg Vars. ++ * LONGJMP_RESTORE_FROM_STACK: Elimination. + * loop optimization: Passes. + * lshiftrt: Arithmetic. + * lt: Comparisons. + * ltu: Comparisons. +*************** +*** 1194,1213 **** + * macros, target description: Target Macros. + * macros, types of arguments: Typeof. + * make: Preprocessor Options. +- * makefile fragment: Fragments. + * make_safe_from: Expander Definitions. +! * matching constraint: Simple Constraints. +! * matching operands: Output Template. + * match_dup: RTL Template. + * match_operand: RTL Template. + * match_operator: RTL Template. +- * match_op_dup: RTL Template. +- * match_parallel: RTL Template. + * match_par_dup: RTL Template. + * match_scratch: RTL Template. + * math libraries: Interface. + * math, in RTL: Arithmetic. +- * maximum operator: Min and Max. + * MAX_BITS_PER_WORD: Storage Layout. + * MAX_CHAR_TYPE_SIZE: Type Layout. + * MAX_FIXED_MODE_SIZE: Storage Layout. +--- 1191,1209 ---- + * macros, target description: Target Macros. + * macros, types of arguments: Typeof. + * make: Preprocessor Options. + * make_safe_from: Expander Definitions. +! * makefile fragment: Fragments. + * match_dup: RTL Template. ++ * match_op_dup: RTL Template. + * match_operand: RTL Template. + * match_operator: RTL Template. + * match_par_dup: RTL Template. ++ * match_parallel: RTL Template. + * match_scratch: RTL Template. ++ * matching constraint: Simple Constraints. ++ * matching operands: Output Template. + * math libraries: Interface. + * math, in RTL: Arithmetic. + * MAX_BITS_PER_WORD: Storage Layout. + * MAX_CHAR_TYPE_SIZE: Type Layout. + * MAX_FIXED_MODE_SIZE: Storage Layout. +*************** +*** 1217,1222 **** +--- 1213,1219 ---- + * MAX_OFILE_ALIGNMENT: Storage Layout. + * MAX_REGS_PER_ADDRESS: Addressing Modes. + * MAX_WCHAR_TYPE_SIZE: Type Layout. ++ * maximum operator: Min and Max. + * MAYBE_REG_PARM_STACK_SPACE: Stack Arguments. + * mcount: Profiling. + * MD_CALL_PROTOTYPES: Config. +*************** +*** 1224,1229 **** +--- 1221,1228 ---- + * MD_STARTFILE_PREFIX: Driver. + * MD_STARTFILE_PREFIX_1: Driver. + * mem: Regs and Memory. ++ * MEM_IN_STRUCT_P: Flags. ++ * MEM_VOLATILE_P: Flags. + * member fns, automatically inline: Inline. + * memcmp: C Dialect Options. + * memcpy: C Dialect Options. +*************** +*** 1231,1250 **** + * memory reference, nonoffsettable: Simple Constraints. + * memory references in constraints: Simple Constraints. + * MEMORY_MOVE_COST: Costs. +- * MEM_IN_STRUCT_P: Flags. +- * MEM_VOLATILE_P: Flags. + * messages, warning: Warning Options. + * messages, warning and error: Warnings and Errors. + * middle-operands, omitted: Conditionals. + * minimum operator: Min and Max. + * minus: Arithmetic. +- * MIN_UNITS_PER_WORD: Storage Layout. + * MIPS options: MIPS Options. + * misunderstandings in C++: C++ Misunderstandings. + * mod: Arithmetic. + * MODDI3_LIBCALL: Library Calls. + * mode classes: Machine Modes. +- * MODES_TIEABLE_P: Values in Registers. + * MODE_CC: Machine Modes. + * MODE_COMPLEX_FLOAT: Machine Modes. + * MODE_COMPLEX_INT: Machine Modes. +--- 1230,1246 ---- + * memory reference, nonoffsettable: Simple Constraints. + * memory references in constraints: Simple Constraints. + * MEMORY_MOVE_COST: Costs. + * messages, warning: Warning Options. + * messages, warning and error: Warnings and Errors. + * middle-operands, omitted: Conditionals. ++ * MIN_UNITS_PER_WORD: Storage Layout. + * minimum operator: Min and Max. + * minus: Arithmetic. + * MIPS options: MIPS Options. + * misunderstandings in C++: C++ Misunderstandings. + * mod: Arithmetic. + * MODDI3_LIBCALL: Library Calls. + * mode classes: Machine Modes. + * MODE_CC: Machine Modes. + * MODE_COMPLEX_FLOAT: Machine Modes. + * MODE_COMPLEX_INT: Machine Modes. +*************** +*** 1253,1258 **** +--- 1249,1255 ---- + * MODE_INT: Machine Modes. + * MODE_PARTIAL_INT: Machine Modes. + * MODE_RANDOM: Machine Modes. ++ * MODES_TIEABLE_P: Values in Registers. + * modifiers in constraints: Modifiers. + * MODSI3_LIBCALL: Library Calls. + * MOVE_MAX: Misc. +*************** +*** 1268,1273 **** +--- 1265,1271 ---- + * multiple alternative constraints: Multi-Alternative. + * multiplication: Arithmetic. + * multiprecision arithmetic: Long Long. ++ * N_REG_CLASSES: Register Classes. + * name augmentation: VMS Misc. + * named patterns and conditions: Patterns. + * named return value in C++: Naming Results. +*************** +*** 1286,1297 **** + * nil: RTL Objects. + * no constraints: No Constraints. + * no-op move instructions: Passes. + * non-constant initializers: Initializers. + * non-static inline function: Inline. + * nongcc_SI_type: Library Calls. + * nongcc_word_type: Library Calls. + * nonoffsettable memory reference: Simple Constraints. +- * NON_SAVING_SETJMP: Register Basics. + * not: Arithmetic. + * not equal: Comparisons. + * not using constraints: No Constraints. +--- 1284,1306 ---- + * nil: RTL Objects. + * no constraints: No Constraints. + * no-op move instructions: Passes. ++ * NO_BUILTIN_PTRDIFF_TYPE: Driver. ++ * NO_BUILTIN_SIZE_TYPE: Driver. ++ * NO_DOLLAR_IN_LABEL: Misc. ++ * NO_DOT_IN_LABEL: Misc. ++ * NO_FUNCTION_CSE: Costs. ++ * NO_IMPLICIT_EXTERN_C: Misc. ++ * NO_MD_PROTOTYPES: Config. ++ * NO_RECURSIVE_FUNCTION_CSE: Costs. ++ * NO_REGS: Register Classes. ++ * NO_STAB_H: Config. ++ * NO_SYS_SIGLIST: Config. + * non-constant initializers: Initializers. + * non-static inline function: Inline. ++ * NON_SAVING_SETJMP: Register Basics. + * nongcc_SI_type: Library Calls. + * nongcc_word_type: Library Calls. + * nonoffsettable memory reference: Simple Constraints. + * not: Arithmetic. + * not equal: Comparisons. + * not using constraints: No Constraints. +*************** +*** 1308,1335 **** + * NOTE_LINE_NUMBER: Insns. + * NOTE_SOURCE_FILE: Insns. + * NOTICE_UPDATE_CC: Condition Code. +- * NO_BUILTIN_PTRDIFF_TYPE: Driver. +- * NO_BUILTIN_SIZE_TYPE: Driver. +- * NO_DOLLAR_IN_LABEL: Misc. +- * NO_DOT_IN_LABEL: Misc. +- * NO_FUNCTION_CSE: Costs. +- * NO_IMPLICIT_EXTERN_C: Misc. +- * NO_MD_PROTOTYPES: Config. +- * NO_RECURSIVE_FUNCTION_CSE: Costs. +- * NO_REGS: Register Classes. +- * NO_STAB_H: Config. +- * NO_SYS_SIGLIST: Config. + * NUM_MACHINE_MODES: Machine Modes. +- * N_REG_CLASSES: Register Classes. + * OBJC_GEN_METHOD_LABEL: Label Output. + * OBJC_INCLUDE_PATH: Environment Variables. + * OBJC_INT_SELECTORS: Type Layout. + * OBJC_PROLOGUE: File Framework. + * OBJC_SELECTORS_WITHOUT_LABELS: Type Layout. +- * Objective C: G++ and GCC. + * OBJECT_FORMAT_COFF: Macros for Initialization. + * OBJECT_FORMAT_ROSE: Macros for Initialization. + * OBJECT_SUFFIX: Config. + * OBSTACK_CHUNK_ALLOC: Config. + * OBSTACK_CHUNK_FREE: Config. + * OBSTACK_CHUNK_SIZE: Config. +--- 1317,1332 ---- + * NOTE_LINE_NUMBER: Insns. + * NOTE_SOURCE_FILE: Insns. + * NOTICE_UPDATE_CC: Condition Code. + * NUM_MACHINE_MODES: Machine Modes. + * OBJC_GEN_METHOD_LABEL: Label Output. + * OBJC_INCLUDE_PATH: Environment Variables. + * OBJC_INT_SELECTORS: Type Layout. + * OBJC_PROLOGUE: File Framework. + * OBJC_SELECTORS_WITHOUT_LABELS: Type Layout. + * OBJECT_FORMAT_COFF: Macros for Initialization. + * OBJECT_FORMAT_ROSE: Macros for Initialization. + * OBJECT_SUFFIX: Config. ++ * Objective C: G++ and GCC. + * OBSTACK_CHUNK_ALLOC: Config. + * OBSTACK_CHUNK_FREE: Config. + * OBSTACK_CHUNK_SIZE: Config. +*************** +*** 1364,1374 **** + * order of evaluation, side effects: Non-bugs. + * order of options: Invoking GCC. + * order of register allocation: Allocation Order. +- * Ordering of Patterns: Pattern Ordering. + * ORDER_REGS_FOR_LOCAL_ALLOC: Allocation Order. + * other directory, compilation in: Other Dir. +- * OUTGOING_REGNO: Register Basics. + * OUTGOING_REG_PARM_STACK_SPACE: Stack Arguments. + * output file option: Overall Options. + * output of assembler code: File Framework. + * output statements: Output Statement. +--- 1361,1371 ---- + * order of evaluation, side effects: Non-bugs. + * order of options: Invoking GCC. + * order of register allocation: Allocation Order. + * ORDER_REGS_FOR_LOCAL_ALLOC: Allocation Order. ++ * Ordering of Patterns: Pattern Ordering. + * other directory, compilation in: Other Dir. + * OUTGOING_REG_PARM_STACK_SPACE: Stack Arguments. ++ * OUTGOING_REGNO: Register Basics. + * output file option: Overall Options. + * output of assembler code: File Framework. + * output statements: Output Statement. +*************** +*** 1383,1390 **** + * parameter forward declaration: Variable Length. + * parameters, miscellaneous: Misc. + * PARM_BOUNDARY: Storage Layout. +- * parser generator, Bison: Installation. + * PARSE_LDD_OUTPUT: Macros for Initialization. + * parsing pass: Passes. + * passes and files of the compiler: Passes. + * passing arguments: Interface. +--- 1380,1387 ---- + * parameter forward declaration: Variable Length. + * parameters, miscellaneous: Misc. + * PARM_BOUNDARY: Storage Layout. + * PARSE_LDD_OUTPUT: Macros for Initialization. ++ * parser generator, Bison: Installation. + * parsing pass: Passes. + * passes and files of the compiler: Passes. + * passing arguments: Interface. +*************** +*** 1395,1418 **** + * Pattern Ordering: Pattern Ordering. + * patterns: Patterns. + * pc: Regs and Memory. + * PCC_BITFIELD_TYPE_MATTERS: Storage Layout. + * PCC_STATIC_STRUCT_RETURN: Aggregate Return. +- * pc_rtx: Regs and Memory. + * PDImode: Machine Modes. + * peephole optimization: Passes. + * peephole optimization, RTL representation: Side Effects. + * peephole optimizer definitions: Peephole Definitions. + * percent sign: Output Template. + * perform_...: Library Calls. + * PIC: Code Gen Options. +- * PIC: PIC. +- * PIC_OFFSET_TABLE_REGNUM: PIC. + * PIC_OFFSET_TABLE_REG_CALL_CLOBBERED: PIC. + * plus: Arithmetic. + * Pmode: Misc. + * pointer arguments: Function Attributes. +- * POINTERS_EXTEND_UNSIGNED: Storage Layout. + * POINTER_SIZE: Storage Layout. + * portability: Portability. + * portions of temporary objects, pointers to: Temporaries. + * position independent code: PIC. +--- 1392,1415 ---- + * Pattern Ordering: Pattern Ordering. + * patterns: Patterns. + * pc: Regs and Memory. ++ * pc_rtx: Regs and Memory. + * PCC_BITFIELD_TYPE_MATTERS: Storage Layout. + * PCC_STATIC_STRUCT_RETURN: Aggregate Return. + * PDImode: Machine Modes. + * peephole optimization: Passes. + * peephole optimization, RTL representation: Side Effects. + * peephole optimizer definitions: Peephole Definitions. + * percent sign: Output Template. + * perform_...: Library Calls. ++ * PIC <1>: PIC. + * PIC: Code Gen Options. + * PIC_OFFSET_TABLE_REG_CALL_CLOBBERED: PIC. ++ * PIC_OFFSET_TABLE_REGNUM: PIC. + * plus: Arithmetic. + * Pmode: Misc. + * pointer arguments: Function Attributes. + * POINTER_SIZE: Storage Layout. ++ * POINTERS_EXTEND_UNSIGNED: Storage Layout. + * portability: Portability. + * portions of temporary objects, pointers to: Temporaries. + * position independent code: PIC. +*************** +*** 1423,1428 **** +--- 1420,1427 ---- + * pragma, reason for not using: Function Attributes. + * pragmas in C++, effect on inlining: C++ Interface. + * pragmas, interface and implementation: C++ Interface. ++ * pre_dec: Incdec. ++ * pre_inc: Incdec. + * predefined macros: Run-time Target. + * PREDICATE_CODES: Misc. + * PREFERRED_DEBUGGING_TYPE: All Debuggers. +*************** +*** 1435,1442 **** + * prev_active_insn: Peephole Definitions. + * prev_cc0_setter: Jump Patterns. + * PREV_INSN: Insns. +- * pre_dec: Incdec. +- * pre_inc: Incdec. + * PRINT_OPERAND: Instruction Output. + * PRINT_OPERAND_ADDRESS: Instruction Output. + * PRINT_OPERAND_PUNCT_VALID_P: Instruction Output. +--- 1434,1439 ---- +*************** +*** 1457,1467 **** + * PTRDIFF_TYPE: Type Layout. + * push address instruction: Simple Constraints. + * PUSH_ROUNDING: Stack Arguments. +- * putenv: Config. + * PUT_CODE: RTL Objects. + * PUT_MODE: Machine Modes. + * PUT_REG_NOTE_KIND: Insns. + * PUT_SDB_...: SDB and DWARF. + * QImode: Machine Modes. + * question mark: Multi-Alternative. + * quotient: Arithmetic. +--- 1454,1464 ---- + * PTRDIFF_TYPE: Type Layout. + * push address instruction: Simple Constraints. + * PUSH_ROUNDING: Stack Arguments. + * PUT_CODE: RTL Objects. + * PUT_MODE: Machine Modes. + * PUT_REG_NOTE_KIND: Insns. + * PUT_SDB_...: SDB and DWARF. ++ * putenv: Config. + * QImode: Machine Modes. + * question mark: Multi-Alternative. + * quotient: Arithmetic. +*************** +*** 1472,1479 **** + * REAL_ARITHMETIC: Cross-compilation. + * REAL_INFINITY: Cross-compilation. + * REAL_NM_FILE_NAME: Macros for Initialization. +- * REAL_VALUES_EQUAL: Cross-compilation. +- * REAL_VALUES_LESS: Cross-compilation. + * REAL_VALUE_ATOF: Cross-compilation. + * REAL_VALUE_FIX: Cross-compilation. + * REAL_VALUE_FROM_INT: Cross-compilation. +--- 1469,1474 ---- +*************** +*** 1491,1527 **** + * REAL_VALUE_TYPE: Cross-compilation. + * REAL_VALUE_UNSIGNED_FIX: Cross-compilation. + * REAL_VALUE_UNSIGNED_RNDZINT: Cross-compilation. +! * recognizing insns: RTL Template. + * recog_operand: Instruction Output. + * reg: Regs and Memory. +- * register allocation: Passes. +- * register allocation order: Allocation Order. +- * register allocation, stupid: Passes. +- * register class definitions: Register Classes. +- * register class preference constraints: Class Preferences. +- * register class preference pass: Passes. +- * register pairs: Values in Registers. +- * register positions in frame (88k): M88K Options. +- * register positions in frame (88k): M88K Options. +- * Register Transfer Language (RTL): RTL. +- * register usage: Registers. +- * register use analysis: Passes. +- * register variable after longjmp: Global Reg Vars. +- * register-to-stack conversion: Passes. +- * registers: Extended Asm. +- * registers arguments: Register Arguments. +- * registers for local variables: Local Reg Vars. +- * registers in constraints: Simple Constraints. +- * registers, global allocation: Explicit Reg Vars. +- * registers, global variables in: Global Reg Vars. +- * REGISTER_MOVE_COST: Costs. +- * REGISTER_NAMES: Instruction Output. +- * register_operand: RTL Template. +- * REGISTER_PREFIX: Instruction Output. +- * REGNO_OK_FOR_BASE_P: Register Classes. +- * REGNO_OK_FOR_INDEX_P: Register Classes. +- * REGNO_REG_CLASS: Register Classes. +- * regs_ever_live: Function Entry. + * REG_ALLOC_ORDER: Allocation Order. + * REG_CC_SETTER: Insns. + * REG_CC_USER: Insns. +--- 1486,1496 ---- + * REAL_VALUE_TYPE: Cross-compilation. + * REAL_VALUE_UNSIGNED_FIX: Cross-compilation. + * REAL_VALUE_UNSIGNED_RNDZINT: Cross-compilation. +! * REAL_VALUES_EQUAL: Cross-compilation. +! * REAL_VALUES_LESS: Cross-compilation. + * recog_operand: Instruction Output. ++ * recognizing insns: RTL Template. + * reg: Regs and Memory. + * REG_ALLOC_ORDER: Allocation Order. + * REG_CC_SETTER: Insns. + * REG_CC_USER: Insns. +*************** +*** 1539,1548 **** + * REG_LIBCALL: Insns. + * REG_LOOP_TEST_P: Flags. + * reg_names: Instruction Output. + * REG_NONNEG: Insns. +- * REG_NOTES: Insns. + * REG_NOTE_KIND: Insns. +! * REG_NO_CONFLICT: Insns. + * REG_OK_FOR_BASE_P: Addressing Modes. + * REG_OK_FOR_INDEX_P: Addressing Modes. + * REG_OK_STRICT: Addressing Modes. +--- 1508,1517 ---- + * REG_LIBCALL: Insns. + * REG_LOOP_TEST_P: Flags. + * reg_names: Instruction Output. ++ * REG_NO_CONFLICT: Insns. + * REG_NONNEG: Insns. + * REG_NOTE_KIND: Insns. +! * REG_NOTES: Insns. + * REG_OK_FOR_BASE_P: Addressing Modes. + * REG_OK_FOR_INDEX_P: Addressing Modes. + * REG_OK_STRICT: Addressing Modes. +*************** +*** 1551,1562 **** + * REG_UNUSED: Insns. + * REG_USERVAR_P: Flags. + * REG_WAS_0: Insns. + * relative costs: Costs. + * RELATIVE_PREFIX_NOT_LINKDIR: Driver. + * reload pass: Regs and Memory. +- * reloading: Passes. + * reload_completed: Standard Names. + * reload_in_progress: Standard Names. + * remainder: Arithmetic. + * reordering, warning: Warning Options. + * reporting bugs: Bugs. +--- 1520,1558 ---- + * REG_UNUSED: Insns. + * REG_USERVAR_P: Flags. + * REG_WAS_0: Insns. ++ * register allocation: Passes. ++ * register allocation order: Allocation Order. ++ * register allocation, stupid: Passes. ++ * register class definitions: Register Classes. ++ * register class preference constraints: Class Preferences. ++ * register class preference pass: Passes. ++ * register pairs: Values in Registers. ++ * register positions in frame (88k): M88K Options. ++ * Register Transfer Language (RTL): RTL. ++ * register usage: Registers. ++ * register use analysis: Passes. ++ * register variable after longjmp: Global Reg Vars. ++ * register-to-stack conversion: Passes. ++ * REGISTER_MOVE_COST: Costs. ++ * REGISTER_NAMES: Instruction Output. ++ * register_operand: RTL Template. ++ * REGISTER_PREFIX: Instruction Output. ++ * registers: Extended Asm. ++ * registers arguments: Register Arguments. ++ * registers for local variables: Local Reg Vars. ++ * registers in constraints: Simple Constraints. ++ * registers, global allocation: Explicit Reg Vars. ++ * registers, global variables in: Global Reg Vars. ++ * REGNO_OK_FOR_BASE_P: Register Classes. ++ * REGNO_OK_FOR_INDEX_P: Register Classes. ++ * REGNO_REG_CLASS: Register Classes. ++ * regs_ever_live: Function Entry. + * relative costs: Costs. + * RELATIVE_PREFIX_NOT_LINKDIR: Driver. + * reload pass: Regs and Memory. + * reload_completed: Standard Names. + * reload_in_progress: Standard Names. ++ * reloading: Passes. + * remainder: Arithmetic. + * reordering, warning: Warning Options. + * reporting bugs: Bugs. +*************** +*** 1568,1584 **** + * return value of main: VMS Misc. + * return value, named, in C++: Naming Results. + * return values in registers: Scalar Return. +- * returning aggregate values: Aggregate Return. +- * returning structures and unions: Interface. + * RETURN_ADDR_IN_PREVIOUS_FRAME: Frame Layout. + * RETURN_ADDR_RTX: Frame Layout. + * RETURN_IN_MEMORY: Aggregate Return. + * RETURN_POPS_ARGS: Stack Arguments. + * REVERSIBLE_CC_MODE: Condition Code. + * right rotate: Arithmetic. + * right shift: Arithmetic. + * rotate: Arithmetic. +- * rotate: Arithmetic. + * rotatert: Arithmetic. + * ROUND_TYPE_ALIGN: Storage Layout. + * ROUND_TYPE_SIZE: Storage Layout. +--- 1564,1579 ---- + * return value of main: VMS Misc. + * return value, named, in C++: Naming Results. + * return values in registers: Scalar Return. + * RETURN_ADDR_IN_PREVIOUS_FRAME: Frame Layout. + * RETURN_ADDR_RTX: Frame Layout. + * RETURN_IN_MEMORY: Aggregate Return. + * RETURN_POPS_ARGS: Stack Arguments. ++ * returning aggregate values: Aggregate Return. ++ * returning structures and unions: Interface. + * REVERSIBLE_CC_MODE: Condition Code. + * right rotate: Arithmetic. + * right shift: Arithmetic. + * rotate: Arithmetic. + * rotatert: Arithmetic. + * ROUND_TYPE_ALIGN: Storage Layout. + * ROUND_TYPE_SIZE: Storage Layout. +*************** +*** 1624,1633 **** + * saveable_obstack: Addressing Modes. + * scalars, returned as values: Scalar Return. + * SCCS_DIRECTIVE: Misc. + * scheduling, delayed branch: Passes. + * scheduling, instruction: Passes. +- * scheduling, instruction: Passes. +- * SCHED_GROUP_P: Flags. + * SCmode: Machine Modes. + * scope of a variable length array: Variable Length. + * scope of declaration: Disappointments. +--- 1619,1627 ---- + * saveable_obstack: Addressing Modes. + * scalars, returned as values: Scalar Return. + * SCCS_DIRECTIVE: Misc. ++ * SCHED_GROUP_P: Flags. + * scheduling, delayed branch: Passes. + * scheduling, instruction: Passes. + * SCmode: Machine Modes. + * scope of a variable length array: Variable Length. + * scope of declaration: Disappointments. +*************** +*** 1654,1667 **** + * sequence: Side Effects. + * sequential consistency on 88k: M88K Options. + * set: Side Effects. +- * setjmp: Global Reg Vars. +- * SETUP_FRAME_ADDRESSES: Frame Layout. +- * SETUP_INCOMING_VARARGS: Varargs. + * set_attr: Tagging Insns. + * set_attr_alternative: Tagging Insns. + * SET_DEFAULT_TYPE_ATTRIBUTES: Misc. + * SET_DEST: Side Effects. + * SET_SRC: Side Effects. + * SFmode: Machine Modes. + * shared strings: Incompatibilities. + * shared VMS run time system: VMS Misc. +--- 1648,1661 ---- + * sequence: Side Effects. + * sequential consistency on 88k: M88K Options. + * set: Side Effects. + * set_attr: Tagging Insns. + * set_attr_alternative: Tagging Insns. + * SET_DEFAULT_TYPE_ATTRIBUTES: Misc. + * SET_DEST: Side Effects. + * SET_SRC: Side Effects. ++ * setjmp: Global Reg Vars. ++ * SETUP_FRAME_ADDRESSES: Frame Layout. ++ * SETUP_INCOMING_VARARGS: Varargs. + * SFmode: Machine Modes. + * shared strings: Incompatibilities. + * shared VMS run time system: VMS Misc. +*************** +*** 1673,1678 **** +--- 1667,1674 ---- + * side effect in ?:: Conditionals. + * side effects, macro argument: Statement Exprs. + * side effects, order of evaluation: Non-bugs. ++ * sign_extend: Conversions. ++ * sign_extract: Bit Fields. + * signature: C++ Signatures. + * signature member function default implementation: C++ Signatures. + * signatures, C++: C++ Signatures. +*************** +*** 1680,1699 **** + * signed maximum: Arithmetic. + * signed minimum: Arithmetic. + * SIGNED_CHAR_SPEC: Driver. +- * sign_extend: Conversions. +- * sign_extract: Bit Fields. + * SImode: Machine Modes. + * simple constraints: Simple Constraints. + * simplifications, arithmetic: Passes. + * sin: C Dialect Options. +- * sizeof: Typeof. + * SIZE_TYPE: Type Layout. + * SLOW_BYTE_ACCESS: Costs. + * SLOW_UNALIGNED_ACCESS: Costs. + * SLOW_ZERO_EXTEND: Costs. + * smaller data references (88k): M88K Options. + * smaller data references (MIPS): MIPS Options. +- * SMALL_REGISTER_CLASSES: Register Classes. + * smax: Arithmetic. + * smin: Arithmetic. + * SPARC options: SPARC Options. +--- 1676,1693 ---- + * signed maximum: Arithmetic. + * signed minimum: Arithmetic. + * SIGNED_CHAR_SPEC: Driver. + * SImode: Machine Modes. + * simple constraints: Simple Constraints. + * simplifications, arithmetic: Passes. + * sin: C Dialect Options. + * SIZE_TYPE: Type Layout. ++ * sizeof: Typeof. + * SLOW_BYTE_ACCESS: Costs. + * SLOW_UNALIGNED_ACCESS: Costs. + * SLOW_ZERO_EXTEND: Costs. ++ * SMALL_REGISTER_CLASSES: Register Classes. + * smaller data references (88k): M88K Options. + * smaller data references (MIPS): MIPS Options. + * smax: Arithmetic. + * smin: Arithmetic. + * SPARC options: SPARC Options. +*************** +*** 1704,1710 **** + * specifying registers for local variables: Local Reg Vars. + * speed of instructions: Costs. + * splitting instructions: Insn Splitting. +! * sqrt: Arithmetic. + * sqrt: C Dialect Options. + * square root: Arithmetic. + * stack arguments: Stack Arguments. +--- 1698,1704 ---- + * specifying registers for local variables: Local Reg Vars. + * speed of instructions: Costs. + * splitting instructions: Insn Splitting. +! * sqrt <1>: Arithmetic. + * sqrt: C Dialect Options. + * square root: Arithmetic. + * stack arguments: Stack Arguments. +*************** +*** 1733,1743 **** + * STATIC_CHAIN_INCOMING_REGNUM: Frame Registers. + * STATIC_CHAIN_REGNUM: Frame Registers. + * storage layout: Storage Layout. +- * storem bug (29k): AMD29K Options. + * STORE_FLAG_VALUE: Misc. + * strcmp: C Dialect Options. + * strcpy: C Dialect Options. +- * strcpy: Storage Layout. + * strength-reduction: Passes. + * STRICT_ALIGNMENT: Storage Layout. + * STRICT_ARGUMENT_NAMING: Varargs. +--- 1727,1737 ---- + * STATIC_CHAIN_INCOMING_REGNUM: Frame Registers. + * STATIC_CHAIN_REGNUM: Frame Registers. + * storage layout: Storage Layout. + * STORE_FLAG_VALUE: Misc. ++ * storem bug (29k): AMD29K Options. + * strcmp: C Dialect Options. ++ * strcpy <1>: Storage Layout. + * strcpy: C Dialect Options. + * strength-reduction: Passes. + * STRICT_ALIGNMENT: Storage Layout. + * STRICT_ARGUMENT_NAMING: Varargs. +*************** +*** 1746,1761 **** + * string constants vs newline: C Dialect Options. + * STRIP_NAME_ENCODING: Sections. + * strlen: C Dialect Options. + * structure passing (88k): M88K Options. + * structure value address: Aggregate Return. + * structures: Incompatibilities. + * structures, constructor expression: Constructors. + * structures, returning: Interface. +- * STRUCTURE_SIZE_BOUNDARY: Storage Layout. +- * STRUCT_VALUE: Aggregate Return. +- * STRUCT_VALUE_INCOMING: Aggregate Return. +- * STRUCT_VALUE_INCOMING_REGNUM: Aggregate Return. +- * STRUCT_VALUE_REGNUM: Aggregate Return. + * stupid register allocation: Passes. + * submodel options: Submodel Options. + * subreg: Regs and Memory. +--- 1740,1755 ---- + * string constants vs newline: C Dialect Options. + * STRIP_NAME_ENCODING: Sections. + * strlen: C Dialect Options. ++ * STRUCT_VALUE: Aggregate Return. ++ * STRUCT_VALUE_INCOMING: Aggregate Return. ++ * STRUCT_VALUE_INCOMING_REGNUM: Aggregate Return. ++ * STRUCT_VALUE_REGNUM: Aggregate Return. + * structure passing (88k): M88K Options. + * structure value address: Aggregate Return. ++ * STRUCTURE_SIZE_BOUNDARY: Storage Layout. + * structures: Incompatibilities. + * structures, constructor expression: Constructors. + * structures, returning: Interface. + * stupid register allocation: Passes. + * submodel options: Submodel Options. + * subreg: Regs and Memory. +*************** +*** 1773,1788 **** + * suppressing warnings: Warning Options. + * surprises in C++: C++ Misunderstandings. + * SVr4: M88K Options. +- * SWITCHES_NEED_SPACES: Driver. + * SWITCH_TAKES_ARG: Driver. +! * symbolic label: Sharing. + * symbol_ref: Constants. + * SYMBOL_REF_FLAG: Flags. + * SYMBOL_REF_USED: Flags. + * syntax checking: Warning Options. + * synthesized methods, warning: Warning Options. +- * SYSTEM_INCLUDE_DIR: Driver. + * sys_siglist: Config. + * tagging insns: Tagging Insns. + * tail recursion optimization: Passes. + * target description macros: Target Macros. +--- 1767,1782 ---- + * suppressing warnings: Warning Options. + * surprises in C++: C++ Misunderstandings. + * SVr4: M88K Options. + * SWITCH_TAKES_ARG: Driver. +! * SWITCHES_NEED_SPACES: Driver. + * symbol_ref: Constants. + * SYMBOL_REF_FLAG: Flags. + * SYMBOL_REF_USED: Flags. ++ * symbolic label: Sharing. + * syntax checking: Warning Options. + * synthesized methods, warning: Warning Options. + * sys_siglist: Config. ++ * SYSTEM_INCLUDE_DIR: Driver. + * tagging insns: Tagging Insns. + * tail recursion optimization: Passes. + * target description macros: Target Macros. +*************** +*** 1818,1828 **** + * top level of compiler: Passes. + * traditional C language: C Dialect Options. + * TRADITIONAL_RETURN_FLOAT: Scalar Return. +- * trampolines for nested functions: Trampolines. + * TRAMPOLINE_ALIGNMENT: Trampolines. + * TRAMPOLINE_SECTION: Trampolines. + * TRAMPOLINE_SIZE: Trampolines. + * TRAMPOLINE_TEMPLATE: Trampolines. + * TRANSFER_FROM_TRAMPOLINE: Trampolines. + * TRULY_NOOP_TRUNCATION: Misc. + * truncate: Conversions. +--- 1812,1822 ---- + * top level of compiler: Passes. + * traditional C language: C Dialect Options. + * TRADITIONAL_RETURN_FLOAT: Scalar Return. + * TRAMPOLINE_ALIGNMENT: Trampolines. + * TRAMPOLINE_SECTION: Trampolines. + * TRAMPOLINE_SIZE: Trampolines. + * TRAMPOLINE_TEMPLATE: Trampolines. ++ * trampolines for nested functions: Trampolines. + * TRANSFER_FROM_TRAMPOLINE: Trampolines. + * TRULY_NOOP_TRUNCATION: Misc. + * truncate: Conversions. +*************** +*** 1856,1863 **** + * unshare_all_rtl: Sharing. + * unsigned division: Arithmetic. + * unsigned greater than: Comparisons. +- * unsigned greater than: Comparisons. +- * unsigned less than: Comparisons. + * unsigned less than: Comparisons. + * unsigned minimum and maximum: Arithmetic. + * unsigned_fix: Conversions. +--- 1850,1855 ---- +*************** +*** 1865,1874 **** + * unspec: Side Effects. + * unspec_volatile: Side Effects. + * use: Side Effects. +- * used: Flags. +- * USER_LABEL_PREFIX: Instruction Output. + * USE_C_ALLOCA: Config. + * USE_PROTOTYPES: Config. + * USG: Config. + * VALID_MACHINE_DECL_ATTRIBUTE: Misc. + * VALID_MACHINE_TYPE_ATTRIBUTE: Misc. +--- 1857,1866 ---- + * unspec: Side Effects. + * unspec_volatile: Side Effects. + * use: Side Effects. + * USE_C_ALLOCA: Config. + * USE_PROTOTYPES: Config. ++ * used: Flags. ++ * USER_LABEL_PREFIX: Instruction Output. + * USG: Config. + * VALID_MACHINE_DECL_ATTRIBUTE: Misc. + * VALID_MACHINE_TYPE_ATTRIBUTE: Misc. +*************** +*** 1910,1919 **** + * WCHAR_TYPE_SIZE: Type Layout. + * which_alternative: Output Statement. + * whitespace: Incompatibilities. +- * WORDS_BIG_ENDIAN: Storage Layout. + * word_mode: Machine Modes. + * WORD_REGISTER_OPERATIONS: Misc. + * WORD_SWITCH_TAKES_ARG: Driver. + * XCmode: Machine Modes. + * XCOFF_DEBUGGING_INFO: DBX Options. + * XEXP: Accessors. +--- 1902,1911 ---- + * WCHAR_TYPE_SIZE: Type Layout. + * which_alternative: Output Statement. + * whitespace: Incompatibilities. + * word_mode: Machine Modes. + * WORD_REGISTER_OPERATIONS: Misc. + * WORD_SWITCH_TAKES_ARG: Driver. ++ * WORDS_BIG_ENDIAN: Storage Layout. + * XCmode: Machine Modes. + * XCOFF_DEBUGGING_INFO: DBX Options. + * XEXP: Accessors. +*************** +*** 1929,1945 **** + * zero-length arrays: Zero Length. + * zero_extend: Conversions. + * zero_extract: Bit Fields. +- * \: Output Template. +- * __bb_init_func: Profiling. +- * __builtin_apply: Constructing Calls. +- * __builtin_apply_args: Constructing Calls. +- * __builtin_args_info: Varargs. +- * __builtin_classify_type: Varargs. +- * __builtin_next_arg: Varargs. +- * __builtin_return: Constructing Calls. +- * __builtin_saveregs: Varargs. +- * __CTOR_LIST__: Initialization. +- * __DTOR_LIST__: Initialization. +- * __main: Collect2. + + +--- 1921,1925 ---- +diff -rcP gcc-2.7.2/gcc.info-3 gcc-2.7.2.1-objc-960906/gcc.info-3 +*** gcc-2.7.2/gcc.info-3 Fri Sep 6 14:27:28 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-3 Fri Sep 6 10:26:18 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-4 gcc-2.7.2.1-objc-960906/gcc.info-4 +*** gcc-2.7.2/gcc.info-4 Fri Sep 6 14:27:28 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-4 Fri Sep 6 10:26:18 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-5 gcc-2.7.2.1-objc-960906/gcc.info-5 +*** gcc-2.7.2/gcc.info-5 Fri Sep 6 14:27:29 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-5 Fri Sep 6 10:26:19 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-6 gcc-2.7.2.1-objc-960906/gcc.info-6 +*** gcc-2.7.2/gcc.info-6 Fri Sep 6 14:27:30 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-6 Fri Sep 6 10:26:19 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 465,468 **** +--- 465,510 ---- + does not distribute a C runtime library, it also does not include + a C++ run-time library. All I/O functionality, special class + libraries, etc., are available in the libg++ distribution. ++ ++ 17. GNU C does include a runtime library for Objective-C because it is ++ an integral part of the language; all of the files associated with ++ the library are located in the subdirectory `objc'. The GNU ++ Objective-C Runtime Library does require header files for the ++ target's C library in order to be compiled, and it will also ++ require the header files for the target's thread library if you ++ want thread support. *Note Cross-Compilers and Header Files: ++ Cross Headers, for discussion about header files issues for ++ cross-compilation. ++ ++ When you run `configure', it picks the appropriate Objective-C ++ back-end thread implementation file for the target platform. In ++ some situations, you may wish to choose a different back-end as ++ some platforms support multiple thread implementations, or you may ++ wish to disable thread support completely. This can be done by ++ specifying a value for the OBJC_THREAD_FILE makefile variable on ++ the command line when you run make, for example: ++ ++ make CC="stage2/xgcc -Bstage2/" CFLAGS="-g -O2" OBJC_THREAD_FILE=thr-single ++ ++ Below is a list of the currently available back-ends. ++ ++ * thr-single; disable thread support, should work for all ++ platforms. ++ ++ * thr-decosf1; DEC OSF/1 thread support. ++ ++ * thr-irix; SGI IRIX thread support. ++ ++ * thr-mach; Generic MACH thread support, known to work on ++ NEXTSTEP. ++ ++ * thr-os2; IBM OS/2 thread support. ++ ++ * thr-posix; Generix POSIX thread support. ++ ++ * thr-pthreads; PCThreads on Linux based GNU systems. ++ ++ * thr-solaris; SUN Solaris thread support. ++ ++ * thr-win32; Microsoft Win32 API thread support. + +diff -rcP gcc-2.7.2/gcc.info-7 gcc-2.7.2.1-objc-960906/gcc.info-7 +*** gcc-2.7.2/gcc.info-7 Fri Sep 6 14:27:30 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-7 Fri Sep 6 10:26:20 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 262,337 **** + Structures are no longer a multiple of 2 bytes. + + `hppa*-*-*' +! There are two variants of this CPU, called 1.0 and 1.1, which have +! different machine descriptions. You must use the right one for +! your machine. All 7NN machines and 8N7 machines use 1.1, while +! all other 8NN machines use 1.0. +! +! The easiest way to handle this problem is to use `configure hpNNN' +! or `configure hpNNN-hpux', where NNN is the model number of the +! machine. Then `configure' will figure out if the machine is a 1.0 +! or 1.1. Use `uname -a' to find out the model number of your +! machine. + + `-g' does not work on HP-UX, since that system uses a peculiar + debugging format which GNU CC does not know about. However, `-g' + will work if you also use GAS and GDB in conjunction with GCC. We + highly recommend using GAS for all HP-PA configurations. + +! You should be using GAS-2.3 (or later) along with GDB-4.12 (or + later). These can be retrieved from all the traditional GNU ftp + archive sites. + +! Build GAS and install the resulting binary as: + +! /usr/local/lib/gcc-lib/CONFIGURATION/GCCVERSION/as +! +! where CONFIGURATION is the configuration name (perhaps +! `hpNNN-hpux') and GCCVERSION is the GNU CC version number. Do +! this *before* starting the build process, otherwise you will get +! errors from the HPUX assembler while building `libgcc2.a'. The +! command +! +! make install-dir +! +! will create the necessary directory hierarchy so you can install +! GAS before building GCC. +! +! To enable debugging, configure GNU CC with the `--with-gnu-as' +! option before building. +! +! It has been reported that GNU CC produces invalid assembly code for +! 1.1 machines running HP-UX 8.02 when using the HP assembler. +! Typically the errors look like this: +! as: bug.s @line#15 [err#1060] +! Argument 0 or 2 in FARG upper +! - lookahead = ARGW1=FR,RTNVAL=GR +! as: foo.s @line#28 [err#1060] +! Argument 0 or 2 in FARG upper +! - lookahead = ARGW1=FR +! +! You can check the version of HP-UX you are running by executing +! the command `uname -r'. If you are indeed running HP-UX 8.02 on +! a PA and using the HP assembler then configure GCC with +! "hpNNN-hpux8.02". + + `i370-*-*' + This port is very preliminary and has many known bugs. We hope to + have a higher-quality port for this machine soon. + + `i386-*-linuxoldld' +! Use this configuration to generate a.out binaries on Linux if you +! do not have gas/binutils version 2.5.2 or later installed. This is +! an obsolete configuration. + + `i386-*-linuxaout' +! Use this configuration to generate a.out binaries on Linux. This +! configuration is being superseded. You must use gas/binutils +! version 2.5.2 or later. + + `i386-*-linux' +! Use this configuration to generate ELF binaries on Linux. You must +! use gas/binutils version 2.5.2 or later. + + `i386-*-sco' + Compilation with RCC is recommended. Also, it may be a good idea +--- 262,308 ---- + Structures are no longer a multiple of 2 bytes. + + `hppa*-*-*' +! There are several variants of the HP-PA processor which run a +! variety of operating systems. GNU CC must be configured to use +! the correct processor type and operating system, or GNU CC will +! not function correctly. The easiest way to handle this problem is +! to *not* specify a target when configuring GNU CC, the `configure' +! script will try to automatically determine the right processor +! type and operating system. + + `-g' does not work on HP-UX, since that system uses a peculiar + debugging format which GNU CC does not know about. However, `-g' + will work if you also use GAS and GDB in conjunction with GCC. We + highly recommend using GAS for all HP-PA configurations. + +! You should be using GAS-2.6 (or later) along with GDB-4.16 (or + later). These can be retrieved from all the traditional GNU ftp + archive sites. + +! GAS will need to be installed into a directory before `/bin', +! `/usr/bin', and `/usr/ccs/bin' in your search path. You should +! install GAS before you build GNU CC. + +! To enable debugging, you must configure GNU CC with the +! `--with-gnu-as' option before building. + + `i370-*-*' + This port is very preliminary and has many known bugs. We hope to + have a higher-quality port for this machine soon. + + `i386-*-linuxoldld' +! Use this configuration to generate a.out binaries on Linux-based +! GNU systems, if you do not have gas/binutils version 2.5.2 or later +! installed. This is an obsolete configuration. + + `i386-*-linuxaout' +! Use this configuration to generate a.out binaries on Linux-based +! GNU systems. This configuration is being superseded. You must use +! gas/binutils version 2.5.2 or later. + + `i386-*-linux' +! Use this configuration to generate ELF binaries on Linux-based GNU +! systems. You must use gas/binutils version 2.5.2 or later. + + `i386-*-sco' + Compilation with RCC is recommended. Also, it may be a good idea +diff -rcP gcc-2.7.2/gcc.info-8 gcc-2.7.2.1-objc-960906/gcc.info-8 +*** gcc-2.7.2/gcc.info-8 Fri Sep 6 14:27:31 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-8 Fri Sep 6 10:26:21 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.info-9 gcc-2.7.2.1-objc-960906/gcc.info-9 +*** gcc-2.7.2/gcc.info-9 Fri Sep 6 14:27:32 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-9 Fri Sep 6 10:26:22 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2/gcc.texi gcc-2.7.2.1-objc-960906/gcc.texi +*** gcc-2.7.2/gcc.texi Fri Sep 6 14:27:35 1996 +--- gcc-2.7.2.1-objc-960906/gcc.texi Fri Sep 6 10:26:24 1996 +*************** +*** 147,157 **** + @sp 2 + @center Richard M. Stallman + @sp 3 +! @center Last updated 26 November 1995 + @sp 1 + @c The version number appears twice more in this file. + +! @center for version 2.7.2 + @page + @vskip 0pt plus 1filll + Copyright @copyright{} 1988, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. +--- 147,157 ---- + @sp 2 + @center Richard M. Stallman + @sp 3 +! @center Last updated 29 June 1996 + @sp 1 + @c The version number appears twice more in this file. + +! @center for version 2.7.2.1 + @page + @vskip 0pt plus 1filll + Copyright @copyright{} 1988, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. +*************** +*** 904,921 **** + reasons only partly related to the general issue of interface copyright. + + Lotus won lawsuits against two small companies, which were thus put out +! of business. Then they sued Borland; they won in the trial court (no + surprise, since it was the same court that had ruled for Lotus twice +! before), but the decision was reversed by the court of appeals, with +! help from the League for Programming Freedom in the form of a +! friend-of-the-court brief. We are now waiting to see if the Supreme +! Court will hear the case. If it does, the League for Programming +! Freedom will again submit a brief. +! +! The battle is not over. Just this summer a company that produced a +! simulator for a CDC computer was shut down by a copyright lawsuit by +! CDC, which charged that the simulator infringed the copyright on the +! manuals for the computer. + + If the monopolists get their way, they will hobble the software field: + +--- 904,926 ---- + reasons only partly related to the general issue of interface copyright. + + Lotus won lawsuits against two small companies, which were thus put out +! of business. Then Lotus sued Borland; Lotus won in the trial court (no + surprise, since it was the same court that had ruled for Lotus twice +! before), but the court of appeals ruled in favor of Borland, which was +! assisted by a friend-of-the-court brief from the League for Programming +! Freedom. +! +! Lotus appealed the case to the Supreme Court, which heard the case but +! was unable to reach a decision. This failure means that the appeals +! court decision stands, in one portion of the United States, and may +! influence the other appeals courts, but it does not set a nationwide +! precedent. The battle is not over, and it is not limited to the United +! States. +! +! The battle is extending into other areas of software as well. In 1995 a +! company that produced a simulator for a CDC computer was shut down by a +! copyright lawsuit, in which CDC charged that the simulator infringed the +! copyright on the manuals for the computer. + + If the monopolists get their way, they will hobble the software field: + +*************** +*** 1238,1248 **** + installs---so that GNU CC won't try to use it. + + @item +! On Linux SLS 1.01, there is a problem with @file{libc.a}: it does not +! contain the obstack functions. However, GNU CC assumes that the obstack +! functions are in @file{libc.a} when it is the GNU C library. To work +! around this problem, change the @code{__GNU_LIBRARY__} conditional +! around line 31 to @samp{#if 1}. + + @item + On some 386 systems, building the compiler never finishes because +--- 1243,1253 ---- + installs---so that GNU CC won't try to use it. + + @item +! On SLS 1.01, a Linux-based GNU system, there is a problem with +! @file{libc.a}: it does not contain the obstack functions. However, GNU +! CC assumes that the obstack functions are in @file{libc.a} when it is +! the GNU C library. To work around this problem, change the +! @code{__GNU_LIBRARY__} conditional around line 31 to @samp{#if 1}. + + @item + On some 386 systems, building the compiler never finishes because +diff -rcP gcc-2.7.2/install.texi gcc-2.7.2.1-objc-960906/install.texi +*** gcc-2.7.2/install.texi Fri Sep 6 14:27:49 1996 +--- gcc-2.7.2.1-objc-960906/install.texi Fri Sep 6 10:26:38 1996 +*************** +*** 497,502 **** +--- 497,540 ---- + distribute a C runtime library, it also does not include a C++ run-time + library. All I/O functionality, special class libraries, etc., are + available in the libg++ distribution. ++ ++ @item ++ GNU C does include a runtime library for Objective-C because it is an ++ integral part of the language; all of the files associated with the ++ library are located in the subdirectory @file{objc}. The GNU ++ Objective-C Runtime Library does require header files for the target's C ++ library in order to be compiled, and it will also require the header ++ files for the target's thread library if you want thread support. ++ @xref{Cross Headers, Cross-Compilers and Header Files, Cross-Compilers ++ and Header Files}, for discussion about header files issues for ++ cross-compilation. ++ ++ When you run @file{configure}, it picks the appropriate Objective-C ++ back-end thread implementation file for the target platform. In some ++ situations, you may wish to choose a different back-end as some ++ platforms support multiple thread implementations, or you may wish to ++ disable thread support completely. This can be done by specifying a ++ value for the @var{OBJC_THREAD_FILE} makefile variable on the command ++ line when you run make, for example: ++ ++ @smallexample ++ make CC="stage2/xgcc -Bstage2/" CFLAGS="-g -O2" OBJC_THREAD_FILE=thr-single ++ @end smallexample ++ ++ @noindent ++ Below is a list of the currently available back-ends. ++ ++ @itemize @bullet ++ @item thr-single; disable thread support, should work for all platforms. ++ @item thr-decosf1; DEC OSF/1 thread support. ++ @item thr-irix; SGI IRIX thread support. ++ @item thr-mach; Generic MACH thread support, known to work on NEXTSTEP. ++ @item thr-os2; IBM OS/2 thread support. ++ @item thr-posix; Generix POSIX thread support. ++ @item thr-pthreads; PCThreads on Linux based GNU systems. ++ @item thr-solaris; SUN Solaris thread support. ++ @item thr-win32; Microsoft Win32 API thread support. ++ @end itemize + @end enumerate + + @node Configurations +*************** +*** 778,859 **** + longer a multiple of 2 bytes. + + @item hppa*-*-* +! There are two variants of this CPU, called 1.0 and 1.1, which have +! different machine descriptions. You must use the right one for your +! machine. All 7@var{nn} machines and 8@var{n}7 machines use 1.1, while +! all other 8@var{nn} machines use 1.0. +! +! The easiest way to handle this problem is to use @samp{configure +! hp@var{nnn}} or @samp{configure hp@var{nnn}-hpux}, where @var{nnn} is +! the model number of the machine. Then @file{configure} will figure out +! if the machine is a 1.0 or 1.1. Use @samp{uname -a} to find out the +! model number of your machine. + + @samp{-g} does not work on HP-UX, since that system uses a peculiar + debugging format which GNU CC does not know about. However, @samp{-g} + will work if you also use GAS and GDB in conjunction with GCC. We + highly recommend using GAS for all HP-PA configurations. + +! You should be using GAS-2.3 (or later) along with GDB-4.12 (or later). These + can be retrieved from all the traditional GNU ftp archive sites. + +! Build GAS and install the resulting binary as: + +! @example +! /usr/local/lib/gcc-lib/@var{configuration}/@var{gccversion}/as +! @end example +! +! @noindent +! where @var{configuration} is the configuration name (perhaps +! @samp{hp@var{nnn}-hpux}) and @var{gccversion} is the GNU CC version +! number. Do this @emph{before} starting the build process, otherwise you will +! get errors from the HPUX assembler while building @file{libgcc2.a}. The +! command +! +! @example +! make install-dir +! @end example +! +! @noindent +! will create the necessary directory hierarchy so you can install GAS before +! building GCC. +! +! To enable debugging, configure GNU CC with the @samp{--with-gnu-as} option +! before building. +! +! It has been reported that GNU CC produces invalid assembly code for +! 1.1 machines running HP-UX 8.02 when using the HP assembler. Typically +! the errors look like this: +! @example +! as: bug.s @@line#15 [err#1060] +! Argument 0 or 2 in FARG upper +! - lookahead = ARGW1=FR,RTNVAL=GR +! as: foo.s @@line#28 [err#1060] +! Argument 0 or 2 in FARG upper +! - lookahead = ARGW1=FR +! @end example +! +! You can check the version of HP-UX you are running by executing the command +! @samp{uname -r}. If you are indeed running HP-UX 8.02 on a PA and +! using the HP assembler then configure GCC with "hp@var{nnn}-hpux8.02". + + @item i370-*-* + This port is very preliminary and has many known bugs. We hope to + have a higher-quality port for this machine soon. + + @item i386-*-linuxoldld +! Use this configuration to generate a.out binaries on Linux if you do not +! have gas/binutils version 2.5.2 or later installed. This is an obsolete +! configuration. + + @item i386-*-linuxaout +! Use this configuration to generate a.out binaries on Linux. This configuration +! is being superseded. You must use gas/binutils version 2.5.2 or +! later. + + @item i386-*-linux +! Use this configuration to generate ELF binaries on Linux. You must +! use gas/binutils version 2.5.2 or later. + + @item i386-*-sco + Compilation with RCC is recommended. Also, it may be a good idea to +--- 816,860 ---- + longer a multiple of 2 bytes. + + @item hppa*-*-* +! There are several variants of the HP-PA processor which run a variety +! of operating systems. GNU CC must be configured to use the correct +! processor type and operating system, or GNU CC will not function correctly. +! The easiest way to handle this problem is to @emph{not} specify a target +! when configuring GNU CC, the @file{configure} script will try to automatically +! determine the right processor type and operating system. + + @samp{-g} does not work on HP-UX, since that system uses a peculiar + debugging format which GNU CC does not know about. However, @samp{-g} + will work if you also use GAS and GDB in conjunction with GCC. We + highly recommend using GAS for all HP-PA configurations. + +! You should be using GAS-2.6 (or later) along with GDB-4.16 (or later). These + can be retrieved from all the traditional GNU ftp archive sites. + +! GAS will need to be installed into a directory before @code{/bin}, +! @code{/usr/bin}, and @code{/usr/ccs/bin} in your search path. You +! should install GAS before you build GNU CC. + +! To enable debugging, you must configure GNU CC with the @samp{--with-gnu-as} +! option before building. + + @item i370-*-* + This port is very preliminary and has many known bugs. We hope to + have a higher-quality port for this machine soon. + + @item i386-*-linuxoldld +! Use this configuration to generate a.out binaries on Linux-based GNU +! systems, if you do not have gas/binutils version 2.5.2 or later +! installed. This is an obsolete configuration. + + @item i386-*-linuxaout +! Use this configuration to generate a.out binaries on Linux-based GNU +! systems. This configuration is being superseded. You must use +! gas/binutils version 2.5.2 or later. + + @item i386-*-linux +! Use this configuration to generate ELF binaries on Linux-based GNU +! systems. You must use gas/binutils version 2.5.2 or later. + + @item i386-*-sco + Compilation with RCC is recommended. Also, it may be a good idea to +diff -rcP gcc-2.7.2/loop.c gcc-2.7.2.1-objc-960906/loop.c +*** gcc-2.7.2/loop.c Fri Sep 6 14:28:04 1996 +--- gcc-2.7.2.1-objc-960906/loop.c Fri Sep 6 10:26:52 1996 +*************** +*** 6041,6053 **** + { + /* Can replace with any giv that was reduced and + that has (MULT_VAL != 0) and (ADD_VAL == 0). +! Require a constant for MULT_VAL, so we know it's nonzero. */ + + for (v = bl->giv; v; v = v->next_iv) + if (CONSTANT_P (v->mult_val) && v->mult_val != const0_rtx + && v->add_val == const0_rtx + && ! v->ignore && ! v->maybe_dead && v->always_computable +! && v->mode == mode) + { + if (! eliminate_p) + return 1; +--- 6041,6056 ---- + { + /* Can replace with any giv that was reduced and + that has (MULT_VAL != 0) and (ADD_VAL == 0). +! Require a constant for MULT_VAL, so we know it's nonzero. +! ??? We disable this optimization to avoid potential +! overflows. */ + + for (v = bl->giv; v; v = v->next_iv) + if (CONSTANT_P (v->mult_val) && v->mult_val != const0_rtx + && v->add_val == const0_rtx + && ! v->ignore && ! v->maybe_dead && v->always_computable +! && v->mode == mode +! && 0) + { + if (! eliminate_p) + return 1; +*************** +*** 6067,6078 **** + + /* Look for a giv with (MULT_VAL != 0) and (ADD_VAL != 0); + replace test insn with a compare insn (cmp REDUCED_GIV ADD_VAL). +! Require a constant for MULT_VAL, so we know it's nonzero. */ + + for (v = bl->giv; v; v = v->next_iv) + if (CONSTANT_P (v->mult_val) && v->mult_val != const0_rtx + && ! v->ignore && ! v->maybe_dead && v->always_computable +! && v->mode == mode) + { + if (! eliminate_p) + return 1; +--- 6070,6088 ---- + + /* Look for a giv with (MULT_VAL != 0) and (ADD_VAL != 0); + replace test insn with a compare insn (cmp REDUCED_GIV ADD_VAL). +! Require a constant for MULT_VAL, so we know it's nonzero. +! ??? Do this only if ADD_VAL is a pointer to avoid a potential +! overflow problem. */ + + for (v = bl->giv; v; v = v->next_iv) + if (CONSTANT_P (v->mult_val) && v->mult_val != const0_rtx + && ! v->ignore && ! v->maybe_dead && v->always_computable +! && v->mode == mode +! && (GET_CODE (v->add_val) == SYMBOL_REF +! || GET_CODE (v->add_val) == LABEL_REF +! || GET_CODE (v->add_val) == CONST +! || (GET_CODE (v->add_val) == REG +! && REGNO_POINTER_FLAG (REGNO (v->add_val))))) + { + if (! eliminate_p) + return 1; +*************** +*** 6127,6133 **** + + for (v = bl->giv; v; v = v->next_iv) + if (CONSTANT_P (v->mult_val) && INTVAL (v->mult_val) > 0 +! && CONSTANT_P (v->add_val) + && ! v->ignore && ! v->maybe_dead && v->always_computable + && v->mode == mode) + { +--- 6137,6147 ---- + + for (v = bl->giv; v; v = v->next_iv) + if (CONSTANT_P (v->mult_val) && INTVAL (v->mult_val) > 0 +! && (GET_CODE (v->add_val) == SYMBOL_REF +! || GET_CODE (v->add_val) == LABEL_REF +! || GET_CODE (v->add_val) == CONST +! || (GET_CODE (v->add_val) == REG +! && REGNO_POINTER_FLAG (REGNO (v->add_val)))) + && ! v->ignore && ! v->maybe_dead && v->always_computable + && v->mode == mode) + { +*************** +*** 6160,6171 **** + } + + /* Look for giv with positive constant mult_val and nonconst add_val. +! Insert insns to calculate new compare value. */ + + for (v = bl->giv; v; v = v->next_iv) + if (CONSTANT_P (v->mult_val) && INTVAL (v->mult_val) > 0 + && ! v->ignore && ! v->maybe_dead && v->always_computable +! && v->mode == mode) + { + rtx tem; + +--- 6174,6187 ---- + } + + /* Look for giv with positive constant mult_val and nonconst add_val. +! Insert insns to calculate new compare value. +! ??? Turn this off due to possible overflow. */ + + for (v = bl->giv; v; v = v->next_iv) + if (CONSTANT_P (v->mult_val) && INTVAL (v->mult_val) > 0 + && ! v->ignore && ! v->maybe_dead && v->always_computable +! && v->mode == mode +! && 0) + { + rtx tem; + +*************** +*** 6191,6202 **** + if (invariant_p (arg) == 1) + { + /* Look for giv with constant positive mult_val and nonconst +! add_val. Insert insns to compute new compare value. */ + + for (v = bl->giv; v; v = v->next_iv) + if (CONSTANT_P (v->mult_val) && INTVAL (v->mult_val) > 0 + && ! v->ignore && ! v->maybe_dead && v->always_computable +! && v->mode == mode) + { + rtx tem; + +--- 6207,6220 ---- + if (invariant_p (arg) == 1) + { + /* Look for giv with constant positive mult_val and nonconst +! add_val. Insert insns to compute new compare value. +! ??? Turn this off due to possible overflow. */ + + for (v = bl->giv; v; v = v->next_iv) + if (CONSTANT_P (v->mult_val) && INTVAL (v->mult_val) > 0 + && ! v->ignore && ! v->maybe_dead && v->always_computable +! && v->mode == mode +! && 0) + { + rtx tem; + +diff -rcP gcc-2.7.2/objc/Makefile gcc-2.7.2.1-objc-960906/objc/Makefile +*** gcc-2.7.2/objc/Makefile Fri Sep 6 14:34:46 1996 +--- gcc-2.7.2.1-objc-960906/objc/Makefile Fri Sep 6 10:33:25 1996 +*************** +*** 1,5 **** + # GNU Objective C Runtime Makefile +! # Copyright (C) 1993, 1995 Free Software Foundation, Inc. + # + # This file is part of GNU CC. + # +--- 1,5 ---- + # GNU Objective C Runtime Makefile +! # Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + # + # This file is part of GNU CC. + # +*************** +*** 25,30 **** +--- 25,31 ---- + # srcdir=$$srcdir1 tooldir=$(tooldir) AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" \ + # GCC_FOR_TARGET="$$thisdir1/xgcc -B$$thisdir1/" \ + # GCC_CFLAGS="$(GCC_CFLAGS)" incinstalldir=$$thisdir1/include ++ # OBJC_THREAD_FILE="$(OBJC_THREAD_FILE)" + # Two targets are used by ../Makefile: `all' and `mostlyclean'. + + SHELL=/bin/sh +*************** +*** 56,71 **** + 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: +--- 57,72 ---- + 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 \ +! nil_method.o thr.o $(OBJC_THREAD_FILE).o + + libobjc.a: $(OBJC_O) + $(AR) rc libobjc.a $? + # ranlib is run in the parent directory's makefile. + +! OBJC_H = hash.h objc-list.h sarray.h objc.h \ + objc-api.h \ +! NXConstStr.h Object.h Protocol.h encoding.h typedstream.h thr.h + + # copy objc headers to installation include directory + copy-headers: +*************** +*** 98,100 **** +--- 99,104 ---- + NXConstStr.o: NXConstStr.m + Object.o: Object.m + Protocol.o: Protocol.m ++ thr.o: thr.h thr.c ++ $(OBJC_THREAD_FILE).o: $(OBJC_THREAD_FILE).c ++ nil_method.o: nil_method.c +diff -rcP gcc-2.7.2/objc/Object.m gcc-2.7.2.1-objc-960906/objc/Object.m +*** gcc-2.7.2/objc/Object.m Fri Sep 6 14:34:47 1996 +--- gcc-2.7.2.1-objc-960906/objc/Object.m Fri Sep 6 10:33:26 1996 +*************** +*** 29,36 **** + #include "objc/Protocol.h" + #include "objc/objc-api.h" + +- extern void (*_objc_error)(id object, const char *format, va_list); +- + extern int errno; + + #define MAX_CLASS_NAME_LEN 256 +--- 29,34 ---- +*************** +*** 337,343 **** + object_is_instance(self)?"instance":"class", + (aString!=NULL)?aString:""); + va_start(ap, aString); +! (*_objc_error)(self, fmt, ap); + va_end(ap); + return nil; + #undef FMT +--- 335,341 ---- + object_is_instance(self)?"instance":"class", + (aString!=NULL)?aString:""); + va_start(ap, aString); +! objc_error(self, OBJC_ERR_UNKNOWN, fmt, ap); + va_end(ap); + return nil; + #undef FMT +diff -rcP gcc-2.7.2/objc/README.threads gcc-2.7.2.1-objc-960906/objc/README.threads +*** gcc-2.7.2/objc/README.threads Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/README.threads Fri Sep 6 10:33:27 1996 +*************** +*** 0 **** +--- 1,50 ---- ++ ============================================================================== ++ README - Wed Nov 29 15:16:24 EST 1995 ++ ------------------------------------------------------------------------------ ++ ++ Limited documentation is available in the THREADS file. ++ ++ This version has been tested on Sun Solaris, SGI Irix, and Windows NT. ++ It should also work on any single threaded system. ++ ++ Thanks go to the following people for help test and debug the library: ++ ++ Scott Christley, scottc@ocbi.com ++ Andrew McCallum, mccallum@cs.rochester.edu ++ ++ galen ++ gchunt@cs.rochester.edu ++ ++ Any questions, bug reports, etc should be directed to: ++ ++ Scott Christley, scottc@ocbi.com ++ ++ Please do not bug Galen with email as he no longer supports the code. ++ ++ ============================================================================== ++ Changes from prior releases (in revered chronological order): ++ ------------------------------------------------------------------------------ ++ ++ * Fixed bug in copy part of sarray_realloc. I had an < which should ++ have been <=. (Bug report from Scott). ++ ++ ------------------------------------------------------------------------------ ++ ++ * Support for DEC OSF/1 is definitely broken. My programs always ++ seg-fault when I link with libpthreads.a. ++ ++ * Thread id's are no longer int's, but are instead of type ++ _objc_thread_t which is typedef'ed from a void *. An invalid thread ++ id is denoted by NULL and not -1 as before. ++ ++ ------------------------------------------------------------------------------ ++ ++ * Renamed thread-winnt.c to thread-win32.c to better reflect support ++ for the API on both Windows NT and Windows 95 platforms. ++ (Who knows, maybe even Win32s :-). ++ ++ * Fixed bugs in Win32 support as per report from Scott Christley. ++ ++ * Fixed bug in sarray_get as per report from Scott Christley. ++ ++ +diff -rcP gcc-2.7.2/objc/THREADS gcc-2.7.2.1-objc-960906/objc/THREADS +*** gcc-2.7.2/objc/THREADS Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/THREADS Fri Sep 6 10:33:28 1996 +*************** +*** 0 **** +--- 1,336 ---- ++ This file describes in little detail the modifications to the ++ Objective-C runtime needed to make it thread safe. ++ ++ First off, kudos to Galen Hunt who is the author of this great work. ++ ++ If you have an comments or just want to know where to ++ send me money to express your undying graditude for threading the ++ Objective-C runtime you can reach Galen at: ++ ++ gchunt@cs.rochester.edu ++ ++ Any questions, comments, bug reports, etc. should send email either to the ++ GCC bug account or to: ++ ++ Scott Christley ++ ++ * Sarray Threading: ++ ++ The most critical component of the Objective-C runtime is the sparse array ++ structure (sarray). Sarrays store object selectors and implementations. ++ Following in the tradition of the Objective-C runtime, my threading ++ support assumes that fast message dispatching is far more important ++ than *ANY* and *ALL* other operations. The message dispatching thus ++ uses *NO* locks on any kind. In fact, if you look in sarray.h, you ++ will notice that the message dispatching has not been modified. ++ Instead, I have modified the sarray management functions so that all ++ updates to the sarray data structure can be made in parallel will ++ message dispatching. ++ ++ To support concurrent message dispatching, no dynamically allocated ++ sarray data structures are freed while more than one thread is ++ operational. Sarray data structures that are no longer in use are ++ kept in a linked list of garbage and are released whenever the program ++ is operating with a single thread. The programmer can also flush the ++ garbage list by calling sarray_remove_garbage when the programmer can ++ ensure that no message dispatching is taking place concurrently. The ++ amount of un-reclaimed sarray garbage should normally be extremely ++ small in a real program as sarray structures are freed only when using ++ the "poseAs" functionality and early in program initialization, which ++ normally occurs while the program is single threaded. ++ ++ ****************************************************************************** ++ * Static Variables: ++ ++ The following variables are either statically or globally defined. This list ++ does not include variables which are internal to implementation dependent ++ versions of thread-*.c. ++ ++ The following threading designations are used: ++ SAFE : Implicitly thread safe. ++ SINGLE : Must only be used in single thread mode. ++ MUTEX : Protected by single global mutex objc_runtime_mutex. ++ UNUSED : Not used in the runtime. ++ ++ Variable Name: Usage: Defined: Also used in: ++ =========================== ====== ============ ===================== ++ __objc_class_hash MUTEX class.c ++ __objc_class_links_resolved UNUSED class.c runtime.h ++ __objc_class_number MUTEX class.c ++ __objc_dangling_categories UNUSED init.c ++ __objc_module_list MUTEX init.c ++ __objc_selector_array MUTEX selector.c ++ __objc_selector_hash MUTEX selector.c ++ __objc_selector_max_index MUTEX selector.c sendmsg.c runtime.h ++ __objc_selector_names MUTEX selector.c ++ __objc_thread_exit_status SAFE thread.c ++ __objc_uninstalled_dtable MUTEX sendmsg.c selector.c ++ _objc_load_callback SAFE init.c objc-api.h ++ _objc_lookup_class SAFE class.c objc-api.h ++ _objc_object_alloc SINGLE objects.c objc-api.h ++ _objc_object_copy SINGLE objects.c objc-api.h ++ _objc_object_dispose SINGLE objects.c objc-api.h ++ frwd_sel SAFE2 sendmsg.c ++ idxsize MUTEX sarray.c sendmsg.c sarray.h ++ initialize_sel SAFE2 sendmsg.c ++ narrays MUTEX sarray.c sendmsg.c sarray.h ++ nbuckets MUTEX sarray.c sendmsg.c sarray.h ++ nindices MUTEX sarray.c sarray.h ++ previous_constructors SAFE1 init.c ++ proto_class SAFE1 init.c ++ unclaimed_categories MUTEX init.c ++ unclaimed_proto_list MUTEX init.c ++ uninitialized_statics MUTEX init.c ++ ++ Notes: ++ 1) Initialized once in unithread mode. ++ 2) Initialized value will always be same, guaranteed by lock on selector ++ hash table. ++ ++ ++ ****************************************************************************** ++ * Frontend/Backend design: ++ ++ The design of the Objective-C runtime thread and mutex functions utilizes a ++ frontend/backend implementation. ++ ++ The frontend, as characterized by the files thr.h and thr.c, is a set ++ of platform independent structures and functions which represent the ++ user interface. Objective-C programs should use these structures and ++ functions for their thread and mutex work if they wish to maintain a ++ high degree of portability across platforms. ++ ++ The backend is composed of a file with the necessary code to map the ObjC ++ thread and mutex to a platform specific implementation. For example, the ++ file thr-solaris.c contains the implementation for Solaris. When you ++ configure GCC, it attempts to pick an appropriate backend file for the ++ target platform; however, you can override this choice by assign the ++ OBJC_THREAD_FILE make variable to the basename of the backend file. This ++ is especially useful on platforms which have multiple thread libraries. ++ For example: ++ ++ make OBJC_THREAD_FILE=thr-posix ++ ++ would indicate that the generic posix backend file, thr-posix.c, should be ++ compiled with the ObjC runtime library. If your platform does not support ++ threads then you should specify the OBJC_THREAD_FILE=thr-single backend file ++ to compile the ObjC runtime library without thread or mutex support; note ++ that programs which rely upon the ObjC thread and mutex functions will ++ compile and link correctly but attempting to create a thread or mutex will ++ result in an error. ++ ++ ++ ****************************************************************************** ++ * Threads: ++ ++ The thread system attempts to create multiple threads using whatever ++ operating system or library thread support is available. It does ++ assume that all system functions are thread safe. Notably this means ++ that the system implementation of malloc and free must be thread safe. ++ If a system has multiple processors, the threads are configured for ++ full parallel processing. ++ ++ ***** ++ * Frontend thread functions ++ * User programs should use these thread functions. ++ ++ objc_thread_detach(SEL selector, id object, id argument), objc_thread_t ++ Creates and detaches a new thread. The new thread starts by ++ sending the given selector with a single argument to the ++ given object. ++ ++ objc_thread_set_priority(int priority), int ++ Sets a thread's relative priority within the program. Valid ++ options are: ++ ++ OBJC_THREAD_INTERACTIVE_PRIORITY ++ OBJC_THREAD_BACKGROUND_PRIORITY ++ OBJC_THREAD_LOW_PRIORITY ++ ++ objc_thread_get_priority(void), int ++ Query a thread's priority. ++ ++ objc_thread_yield(void), void ++ Yields processor to another thread with equal or higher ++ priority. It is up to the system scheduler to determine if ++ the processor is taken or not. ++ ++ objc_thread_exit(void), int ++ Terminates a thread. If this is the last thread executing ++ then the program will terminate. ++ ++ objc_thread_id(void), int ++ Returns the current thread's id. ++ ++ objc_thread_set_data(void *value), int ++ Set a pointer to the thread's local storage. Local storage is ++ thread specific. ++ ++ objc_thread_get_data(void), void * ++ Returns the pointer to the thread's local storage. ++ ++ ***** ++ * Backend thread functions ++ * User programs should *NOT* directly call these functions. ++ ++ __objc_init_thread_system(void), int ++ Initialize the thread subsystem. Called once by __objc_exec_class. ++ Return -1 if error otherwise return 0. ++ ++ __objc_fini_thread_system(void), int ++ Closes the thread subsystem, not currently guaranteed to be called. ++ Return -1 if error otherwise return 0. ++ ++ __objc_thread_create(void (*func)(void *arg), void *arg), objc_thread_t ++ Spawns a new thread executing func, called by objc_thread_detach. ++ Return NULL if error otherwise return thread id. ++ ++ __objc_thread_set_priority(int priority), int ++ Set the thread's priority, called by objc_thread_set_priority. ++ Return -1 if error otherwise return 0. ++ ++ __objc_thread_get_priority(void), int ++ Query a thread's priority, called by objc_thread_get_priority. ++ Return -1 if error otherwise return the priority. ++ ++ __objc_thread_yield(void), void ++ Yields the processor, called by objc_thread_yield. ++ ++ __objc_thread_exit(void), int ++ Terminates the thread, called by objc_thread_exit. ++ Return -1 if error otherwise function does not return. ++ ++ __objc_thread_id(void), objc_thread_t ++ Returns the current thread's id, called by objc_thread_id. ++ Return -1 if error otherwise return thread id. ++ ++ __objc_thread_set_data(void *value), int ++ Set pointer for thread local storage, called by objc_thread_set_data. ++ Returns -1 if error otherwise return 0. ++ ++ __objc_thread_get_data(void), void * ++ Returns the pointer to the thread's local storage. ++ Returns NULL if error, called by objc_thread_get_data. ++ ++ ++ ****************************************************************************** ++ * Mutexs: ++ ++ Mutexs can be locked recursively. Each locked mutex remembers ++ its owner (by thread id) and how many times it has been locked. The ++ last unlock on a mutex removes the system lock and allows other ++ threads to access the mutex. ++ ++ ***** ++ * Frontend thread functions ++ * User programs should use these thread functions. ++ ++ objc_mutex_allocate(void), objc_mutex_t ++ Allocates a new mutex. Mutex is initially unlocked. ++ ++ objc_mutex_deallocate(objc_mutex_t mutex), int ++ Free a mutex. Before freeing the mutex, makes sure that no ++ one else is using it. ++ ++ objc_mutex_lock(objc_mutex_t mutex), int ++ Locks a mutex. As mentioned earlier, the same thread may call ++ this routine repeatedly. ++ ++ objc_mutex_trylock(objc_mutex_t mutex), int ++ Attempts to lock a mutex. Returns -1 if failed. If lock on ++ mutex can be acquired then function operates exactly as ++ objc_mutex_lock. ++ ++ objc_mutex_unlock(objc_mutex_t mutex), int ++ Unlocks the mutex by one level. Other threads may not acquire ++ the mutex until this thread has released all locks on it. ++ ++ ***** ++ * Backend thread functions ++ * User programs should *NOT* directly call these functions. ++ ++ __objc_mutex_allocate(void), objc_mutex_t ++ Allocates a new mutex, called by objc_mutex_allocate. ++ Return NULL if error otherwise return mutex pointer. ++ ++ __objc_mutex_deallocate(objc_mutex_t mutex), int ++ Free a mutex, called by objc_mutex_deallocate. ++ Return -1 if error otherwise return 0. ++ ++ __objc_mutex_lock(objc_mutex_t mutex), int ++ Locks a mutex, called by objc_mutex_lock. ++ Return -1 if error otherwise return 0. ++ ++ __objc_mutex_trylock(objc_mutex_t mutex), int ++ Attempts to lock a mutex, called by objc_mutex_trylock. ++ Return -1 if failed to acquire lock or error otherwise return 0. ++ ++ __objc_mutex_unlock(objc_mutex_t mutex), int ++ Unlocks the mutex, called by objc_mutex_unlock. ++ Return -1 if error otherwise return 0. ++ ++ ****************************************************************************** ++ * Condition Mutexs: ++ ++ Mutexs can be locked recursively. Each locked mutex remembers ++ its owner (by thread id) and how many times it has been locked. The ++ last unlock on a mutex removes the system lock and allows other ++ threads to access the mutex. ++ ++ ***** ++ * Frontend thread functions ++ * User programs should use these thread functions. ++ ++ objc_condition_allocate(void), objc_condition_t ++ Allocate a condition mutex. ++ Return NULL if error otherwise return condition pointer. ++ ++ objc_condition_deallocate(objc_condition_t condition), int ++ Deallocate a condition. Note that this includes an implicit ++ condition_broadcast to insure that waiting threads have the ++ opportunity to wake. It is legal to dealloc a condition only ++ if no other thread is/will be using it. Does NOT check for ++ other threads waiting but just wakes them up. ++ ++ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int ++ Wait on the condition unlocking the mutex until objc_condition_signal() ++ or objc_condition_broadcast() are called for the same condition. The ++ given mutex *must* have the depth 1 so that it can be unlocked ++ here, for someone else can lock it and signal/broadcast the condition. ++ The mutex is used to lock access to the shared data that make up the ++ "condition" predicate. ++ ++ objc_condition_broadcast(objc_condition_t condition), int ++ Wake up all threads waiting on this condition. It is recommended that ++ the called would lock the same mutex as the threads in ++ objc_condition_wait before changing the "condition predicate" ++ and make this call and unlock it right away after this call. ++ ++ objc_condition_signal(objc_condition_t condition), int ++ Wake up one thread waiting on this condition. ++ ++ ***** ++ * Backend thread functions ++ * User programs should *NOT* directly call these functions. ++ ++ __objc_condition_allocate(void), objc_condition_t ++ Allocate a condition mutex, called by objc_condition_allocate. ++ Return NULL if error otherwise return condition pointer. ++ ++ __objc_condition_deallocate(objc_condition_t condition), int ++ Deallocate a condition, called by objc_condition_deallocate. ++ Return -1 if error otherwise return 0. ++ ++ __objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int ++ Wait on the condition, called by objc_condition_wait. ++ Return -1 if error otherwise return 0 when condition is met. ++ ++ __objc_condition_broadcast(objc_condition_t condition), int ++ Wake up all threads waiting on this condition. ++ Called by objc_condition_broadcast. ++ Return -1 if error otherwise return 0. ++ ++ __objc_condition_signal(objc_condition_t condition), int ++ Wake up one thread waiting on this condition. ++ Called by objc_condition_signal. ++ Return -1 if error otherwise return 0. +\ No newline at end of file +diff -rcP gcc-2.7.2/objc/THREADS.MACH gcc-2.7.2.1-objc-960906/objc/THREADS.MACH +*** gcc-2.7.2/objc/THREADS.MACH Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/THREADS.MACH Fri Sep 6 10:33:28 1996 +*************** +*** 0 **** +--- 1,23 ---- ++ This readme refers to the file thr-mach.c. ++ ++ Under mach, thread priorities are kinda strange-- any given thread has ++ a MAXIMUM priority and a BASE priority. The BASE priority is the ++ current priority of the thread and the MAXIMUM is the maximum possible ++ priority the thread can assume. The developer can lower, but never ++ raise the maximum priority. ++ ++ The gcc concept of thread priorities is that they run at one of three ++ levels; interactive, background, and low. ++ ++ Under mach, this is translated to: ++ ++ interactive -- set priority to maximum ++ background -- set priority to 2/3 of maximum ++ low -- set priority to 1/3 of maximum ++ ++ This means that it is possible for a thread with the priority of ++ interactive to actually run at a lower priority than another thread ++ with a background, or even low, priority if the developer has modified ++ the maximum priority. ++ ++ +diff -rcP gcc-2.7.2/objc/archive.c gcc-2.7.2.1-objc-960906/objc/archive.c +*** gcc-2.7.2/objc/archive.c Fri Sep 6 14:34:49 1996 +--- gcc-2.7.2.1-objc-960906/objc/archive.c Fri Sep 6 10:33:28 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime archiving +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime archiving +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 37,47 **** + #define PTR2LONG(P) (((char*)(P))-(char*)0) + #define LONG2PTR(L) (((char*)0)+(L)) + +- #define __objc_fatal(format, args...) \ +- { fprintf(stderr, "archiving: "); \ +- fprintf(stderr, format, ## args); \ +- fprintf(stderr, "\n"); abort(); } +- + /* Declare some functions... */ + + static int +--- 37,42 ---- +*************** +*** 141,147 **** + } + + int +! objc_write_unsigned_short (struct objc_typed_stream* stream, unsigned short value) + { + unsigned char buf[sizeof (unsigned short)+1]; + int len = __objc_code_unsigned_short (buf, value); +--- 136,143 ---- + } + + int +! objc_write_unsigned_short (struct objc_typed_stream* stream, +! unsigned short value) + { + unsigned char buf[sizeof (unsigned short)+1]; + int len = __objc_code_unsigned_short (buf, value); +*************** +*** 252,258 **** + } + + int +! objc_write_unsigned_long (struct objc_typed_stream* stream, unsigned long value) + { + unsigned char buf[sizeof(unsigned long)+1]; + int len = __objc_code_unsigned_long (buf, value); +--- 248,255 ---- + } + + int +! objc_write_unsigned_long (struct objc_typed_stream* stream, +! unsigned long value) + { + unsigned char buf[sizeof(unsigned long)+1]; + int len = __objc_code_unsigned_long (buf, value); +*************** +*** 315,321 **** + } + + static int +! objc_write_register_common (struct objc_typed_stream* stream, unsigned long key) + { + unsigned char buf[sizeof (unsigned long)+2]; + int len = __objc_code_unsigned_long (buf+1, key); +--- 312,319 ---- + } + + static int +! objc_write_register_common (struct objc_typed_stream* stream, +! unsigned long key) + { + unsigned char buf[sizeof (unsigned long)+2]; + int len = __objc_code_unsigned_long (buf+1, key); +*************** +*** 359,365 **** + return (*stream->write)(stream->physical, &buf, 1); + } + else +! abort(); + } + + __inline__ int +--- 357,364 ---- + return (*stream->write)(stream->physical, &buf, 1); + } + else +! objc_error(nil, OBJC_ERR_BAD_OPCODE, +! "__objc_write_extension: bad opcode %c\n", code); + } + + __inline__ int +*************** +*** 394,400 **** + { + int len; + if (stream->writing_root_p) +! __objc_fatal ("objc_write_root_object called recursively") + else + { + stream->writing_root_p = 1; +--- 393,400 ---- + { + int len; + if (stream->writing_root_p) +! objc_error (nil, OBJC_ERR_RECURSE_ROOT, +! "objc_write_root_object called recursively"); + else + { + stream->writing_root_p = 1; +*************** +*** 488,494 **** + else + { + int length; +! hash_add (&stream->stream_table, LONG2PTR(key=PTR2LONG(sel_name)), (char*)sel_name); + if ((length = objc_write_register_common (stream, key))) + return __objc_write_selector (stream, selector); + return length; +--- 488,495 ---- + else + { + int length; +! hash_add (&stream->stream_table, +! LONG2PTR(key=PTR2LONG(sel_name)), (char*)sel_name); + if ((length = objc_write_register_common (stream, key))) + return __objc_write_selector (stream, selector); + return length; +*************** +*** 520,527 **** + } + + else +! __objc_fatal("expected 8bit signed int, got %dbit int", +! (int)(buf&_B_NUMBER)*8); + } + return len; + } +--- 521,529 ---- + } + + else +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected 8bit signed int, got %dbit int", +! (int)(buf&_B_NUMBER)*8); + } + return len; + } +*************** +*** 541,548 **** + len = (*stream->read)(stream->physical, val, 1); + + else +! __objc_fatal("expected 8bit unsigned int, got %dbit int", +! (int)(buf&_B_NUMBER)*8); + } + return len; + } +--- 543,551 ---- + len = (*stream->read)(stream->physical, val, 1); + + else +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected 8bit unsigned int, got %dbit int", +! (int)(buf&_B_NUMBER)*8); + } + return len; + } +*************** +*** 562,568 **** + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (short)) +! __objc_fatal("expected short, got bigger (%dbits)", nbytes*8); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +--- 565,572 ---- + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (short)) +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected short, got bigger (%dbits)", nbytes*8); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +*************** +*** 590,596 **** + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (short)) +! __objc_fatal("expected short, got int or bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +--- 594,601 ---- + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (short)) +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected short, got int or bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +*************** +*** 616,622 **** + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (int)) +! __objc_fatal("expected int, got bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +--- 621,627 ---- + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (int)) +! objc_error(nil, OBJC_ERR_BAD_DATA, "expected int, got bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +*************** +*** 643,649 **** + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (long)) +! __objc_fatal("expected long, got bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +--- 648,654 ---- + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (long)) +! objc_error(nil, OBJC_ERR_BAD_DATA, "expected long, got bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +*************** +*** 663,669 **** + unsigned char buf[sizeof(unsigned int)+1]; + + if (nbytes > sizeof (int)) +! __objc_fatal("expected int, got bigger"); + + len = (*stream->read)(stream->physical, buf, nbytes); + (*val) = 0; +--- 668,674 ---- + unsigned char buf[sizeof(unsigned int)+1]; + + if (nbytes > sizeof (int)) +! objc_error(nil, OBJC_ERR_BAD_DATA, "expected int, got bigger"); + + len = (*stream->read)(stream->physical, buf, nbytes); + (*val) = 0; +*************** +*** 699,705 **** + unsigned char buf[sizeof(unsigned long)+1]; + + if (nbytes > sizeof (long)) +! __objc_fatal("expected long, got bigger"); + + len = (*stream->read)(stream->physical, buf, nbytes); + (*val) = 0; +--- 704,710 ---- + unsigned char buf[sizeof(unsigned long)+1]; + + if (nbytes > sizeof (long)) +! objc_error(nil, OBJC_ERR_BAD_DATA, "expected long, got bigger"); + + len = (*stream->read)(stream->physical, buf, nbytes); + (*val) = 0; +*************** +*** 747,753 **** + case _B_SSTR: + { + int length = buf[0]&_B_VALUE; +! (*string) = (char*)__objc_xmalloc(length+1); + if (key) + hash_add (&stream->stream_table, LONG2PTR(key), *string); + len = (*stream->read)(stream->physical, *string, length); +--- 752,758 ---- + case _B_SSTR: + { + int length = buf[0]&_B_VALUE; +! (*string) = (char*)objc_malloc(length+1); + if (key) + hash_add (&stream->stream_table, LONG2PTR(key), *string); + len = (*stream->read)(stream->physical, *string, length); +*************** +*** 760,766 **** + char *tmp; + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + tmp = hash_value_for_key (stream->stream_table, LONG2PTR (key)); +! *string = __objc_xmalloc (strlen(tmp) + 1); + strcpy (*string, tmp); + } + break; +--- 765,771 ---- + char *tmp; + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + tmp = hash_value_for_key (stream->stream_table, LONG2PTR (key)); +! *string = objc_malloc (strlen(tmp) + 1); + strcpy (*string, tmp); + } + break; +*************** +*** 770,776 **** + unsigned int nbytes = buf[0]&_B_VALUE; + len = __objc_read_nbyte_uint(stream, nbytes, &nbytes); + if (len) { +! (*string) = (char*)__objc_xmalloc(nbytes+1); + if (key) + hash_add (&stream->stream_table, LONG2PTR(key), *string); + len = (*stream->read)(stream->physical, *string, nbytes); +--- 775,781 ---- + unsigned int nbytes = buf[0]&_B_VALUE; + len = __objc_read_nbyte_uint(stream, nbytes, &nbytes); + if (len) { +! (*string) = (char*)objc_malloc(nbytes+1); + if (key) + hash_add (&stream->stream_table, LONG2PTR(key), *string); + len = (*stream->read)(stream->physical, *string, nbytes); +*************** +*** 780,786 **** + break; + + default: +! __objc_fatal("expected string, got opcode %c\n", (buf[0]&_B_CODE)); + } + } + +--- 785,792 ---- + break; + + default: +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected string, got opcode %c\n", (buf[0]&_B_CODE)); + } + } + +*************** +*** 825,837 **** + /* check null-byte */ + len = (*stream->read)(stream->physical, buf, 1); + if (buf[0] != '\0') +! __objc_fatal("expected null-byte, got opcode %c", buf[0]); + } + + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! __objc_fatal("cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + (*object) = hash_value_for_key (stream->object_table, LONG2PTR(key)); + } +--- 831,844 ---- + /* check null-byte */ + len = (*stream->read)(stream->physical, buf, 1); + if (buf[0] != '\0') +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected null-byte, got opcode %c", buf[0]); + } + + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + (*object) = hash_value_for_key (stream->object_table, LONG2PTR(key)); + } +*************** +*** 840,859 **** + { + struct objc_list* other; + len = objc_read_unsigned_long (stream, &key); +! other = (struct objc_list*)hash_value_for_key (stream->object_refs, LONG2PTR(key)); +! hash_add (&stream->object_refs, LONG2PTR(key), (void*)list_cons(object, other)); + } + + else if (buf[0] == (_B_EXT | _BX_OBJROOT)) /* a root object */ + { + if (key) +! __objc_fatal("cannot register root object..."); + len = objc_read_object (stream, object); + __objc_finish_read_root_object (stream); + } + + else +! __objc_fatal("expected object, got opcode %c", buf[0]); + } + return len; + } +--- 847,870 ---- + { + struct objc_list* other; + len = objc_read_unsigned_long (stream, &key); +! other = (struct objc_list*)hash_value_for_key (stream->object_refs, +! LONG2PTR(key)); +! hash_add (&stream->object_refs, LONG2PTR(key), +! (void*)list_cons(object, other)); + } + + else if (buf[0] == (_B_EXT | _BX_OBJROOT)) /* a root object */ + { + if (key) +! objc_error(nil, OBJC_ERR_BAD_KEY, +! "cannot register root object..."); + len = objc_read_object (stream, object); + __objc_finish_read_root_object (stream); + } + + else +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected object, got opcode %c", buf[0]); + } + return len; + } +*************** +*** 881,887 **** + /* get class */ + len = objc_read_string (stream, &class_name); + (*class) = objc_get_class(class_name); +! free (class_name); + + /* register */ + if (key) +--- 892,898 ---- + /* get class */ + len = objc_read_string (stream, &class_name); + (*class) = objc_get_class(class_name); +! objc_free(class_name); + + /* register */ + if (key) +*************** +*** 894,908 **** + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! __objc_fatal("cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + (*class) = hash_value_for_key (stream->stream_table, LONG2PTR(key)); + if (!*class) +! __objc_fatal("cannot find class for key %lu", key); + } + + else +! __objc_fatal("expected class, got opcode %c", buf[0]); + } + return len; + } +--- 905,921 ---- + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + (*class) = hash_value_for_key (stream->stream_table, LONG2PTR(key)); + if (!*class) +! objc_error(nil, OBJC_ERR_BAD_CLASS, +! "cannot find class for key %lu", key); + } + + else +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected class, got opcode %c", buf[0]); + } + return len; + } +*************** +*** 936,942 **** + } + else + (*selector) = sel_get_any_uid(selector_name); +! free (selector_name); + + /* register */ + if (key) +--- 949,955 ---- + } + else + (*selector) = sel_get_any_uid(selector_name); +! objc_free(selector_name); + + /* register */ + if (key) +*************** +*** 946,958 **** + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! __objc_fatal("cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); +! (*selector) = hash_value_for_key (stream->stream_table, LONG2PTR(key)); + } + + else +! __objc_fatal("expected selector, got opcode %c", buf[0]); + } + return len; + } +--- 959,973 ---- + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); +! (*selector) = hash_value_for_key (stream->stream_table, +! LONG2PTR(key)); + } + + else +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected selector, got opcode %c", buf[0]); + } + return len; + } +*************** +*** 1019,1031 **** + break; + + case _C_ATOM: +! return objc_write_string_atomic (stream, *(char**)data, strlen(*(char**)data)); + break; + + case _C_ARY_B: + { + int len = atoi(type+1); +! while (isdigit(*++type)); + return objc_write_array (stream, type, len, data); + } + break; +--- 1034,1048 ---- + break; + + case _C_ATOM: +! return objc_write_string_atomic (stream, *(char**)data, +! strlen(*(char**)data)); + break; + + case _C_ARY_B: + { + int len = atoi(type+1); +! while (isdigit(*++type)) +! ; + return objc_write_array (stream, type, len, data); + } + break; +*************** +*** 1034,1041 **** + { + int acc_size = 0; + int align; +! while (*type != _C_STRUCT_E && *type++ != '='); /* skip "=" */ +! while (*type != _C_STRUCT_E); + { + align = objc_alignof_type (type); /* padd to alignment */ + acc_size += ROUND (acc_size, align); +--- 1051,1059 ---- + { + int acc_size = 0; + int align; +! while (*type != _C_STRUCT_E && *type++ != '=') +! ; /* skip "=" */ +! while (*type != _C_STRUCT_E) + { + align = objc_alignof_type (type); /* padd to alignment */ + acc_size += ROUND (acc_size, align); +*************** +*** 1047,1054 **** + } + + default: +! fprintf(stderr, "objc_write_type: cannot parse typespec: %s\n", type); +! abort(); + } + } + +--- 1065,1072 ---- + } + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, +! "objc_write_type: cannot parse typespec: %s\n", type); + } + } + +*************** +*** 1116,1122 **** + case _C_ARY_B: + { + int len = atoi(type+1); +! while (isdigit(*++type)); + return objc_read_array (stream, type, len, data); + } + break; +--- 1134,1141 ---- + case _C_ARY_B: + { + int len = atoi(type+1); +! while (isdigit(*++type)) +! ; + return objc_read_array (stream, type, len, data); + } + break; +*************** +*** 1125,1132 **** + { + int acc_size = 0; + int align; +! while (*type != _C_STRUCT_E && *type++ != '='); /* skip "=" */ +! while (*type != _C_STRUCT_E); + { + align = objc_alignof_type (type); /* padd to alignment */ + acc_size += ROUND (acc_size, align); +--- 1144,1152 ---- + { + int acc_size = 0; + int align; +! while (*type != _C_STRUCT_E && *type++ != '=') +! ; /* skip "=" */ +! while (*type != _C_STRUCT_E) + { + align = objc_alignof_type (type); /* padd to alignment */ + acc_size += ROUND (acc_size, align); +*************** +*** 1138,1145 **** + } + + default: +! fprintf(stderr, "objc_read_type: cannot parse typespec: %s\n", type); +! abort(); + } + } + +--- 1158,1165 ---- + } + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, +! "objc_read_type: cannot parse typespec: %s\n", type); + } + } + +*************** +*** 1229,1245 **** + { + int len = atoi(c+1); + const char* t = c; +! while (isdigit(*++t)); + res = objc_write_array (stream, t, len, va_arg(args, void*)); + t = objc_skip_typespec (t); + if (*t != _C_ARY_E) +! __objc_fatal("expected `]', got: %s", t); + } + break; + + default: +! fprintf(stderr, "objc_write_types: cannot parse typespec: %s\n", type); +! abort(); + } + } + va_end(args); +--- 1249,1266 ---- + { + int len = atoi(c+1); + const char* t = c; +! while (isdigit(*++t)) +! ; + res = objc_write_array (stream, t, len, va_arg(args, void*)); + t = objc_skip_typespec (t); + if (*t != _C_ARY_E) +! objc_error(nil, OBJC_ERR_BAD_TYPE, "expected `]', got: %s", t); + } + break; + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, +! "objc_write_types: cannot parse typespec: %s\n", type); + } + } + va_end(args); +*************** +*** 1320,1336 **** + { + int len = atoi(c+1); + const char* t = c; +! while (isdigit(*++t)); + res = objc_read_array (stream, t, len, va_arg(args, void*)); + t = objc_skip_typespec (t); + if (*t != _C_ARY_E) +! __objc_fatal("expected `]', got: %s", t); + } + break; + + default: +! fprintf(stderr, "objc_read_types: cannot parse typespec: %s\n", type); +! abort(); + } + } + va_end(args); +--- 1341,1358 ---- + { + int len = atoi(c+1); + const char* t = c; +! while (isdigit(*++t)) +! ; + res = objc_read_array (stream, t, len, va_arg(args, void*)); + t = objc_skip_typespec (t); + if (*t != _C_ARY_E) +! objc_error(nil, OBJC_ERR_BAD_TYPE, "expected `]', got: %s", t); + } + break; + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, +! "objc_read_types: cannot parse typespec: %s\n", type); + } + } + va_end(args); +*************** +*** 1379,1390 **** + return 1; + } + +- static void +- __objc_free (void* p) +- { +- free (p); +- } +- + static int + __objc_fread(FILE* file, char* data, int len) + { +--- 1401,1406 ---- +*************** +*** 1406,1418 **** + static int + __objc_no_write(FILE* file, char* data, int len) + { +! __objc_fatal ("TypedStream not open for writing"); + } + + static int + __objc_no_read(FILE* file, char* data, int len) + { +! __objc_fatal ("TypedStream not open for reading"); + } + + static int +--- 1422,1434 ---- + static int + __objc_no_write(FILE* file, char* data, int len) + { +! objc_error (nil, OBJC_ERR_NO_WRITE, "TypedStream not open for writing"); + } + + static int + __objc_no_read(FILE* file, char* data, int len) + { +! objc_error (nil, OBJC_ERR_NO_READ, "TypedStream not open for reading"); + } + + static int +*************** +*** 1422,1431 **** + int pos = 0; + do + (*stream->read)(stream->physical, buffer+pos, 1); +! while (buffer[pos++] != '\0'); + sscanf (buffer, "GNU TypedStream %d", &stream->version); + if (stream->version != OBJC_TYPED_STREAM_VERSION) +! __objc_fatal ("cannot handle TypedStream version %d", stream->version); + return 1; + } + +--- 1438,1449 ---- + int pos = 0; + do + (*stream->read)(stream->physical, buffer+pos, 1); +! while (buffer[pos++] != '\0') +! ; + sscanf (buffer, "GNU TypedStream %d", &stream->version); + if (stream->version != OBJC_TYPED_STREAM_VERSION) +! objc_error (nil, OBJC_ERR_STREAM_VERSION, +! "cannot handle TypedStream version %d", stream->version); + return 1; + } + +*************** +*** 1450,1460 **** + static void __objc_finish_read_root_object(struct objc_typed_stream* stream) + { + node_ptr node; +- struct objc_list* free_list; + SEL awake_sel = sel_get_any_uid ("awake"); + + /* resolve object forward references */ +- free_list = list_cons(NULL, NULL); + for (node = hash_next (stream->object_refs, NULL); node; + node = hash_next (stream->object_refs, node)) + { +--- 1468,1479 ---- + static void __objc_finish_read_root_object(struct objc_typed_stream* stream) + { + node_ptr node; + SEL awake_sel = sel_get_any_uid ("awake"); ++ cache_ptr free_list = hash_new (64, ++ (hash_func_type) hash_ptr, ++ (compare_func_type) compare_ptrs); + + /* resolve object forward references */ + for (node = hash_next (stream->object_refs, NULL); node; + node = hash_next (stream->object_refs, node)) + { +*************** +*** 1464,1476 **** + while(reflist) + { + *((id*)reflist->head) = object; +! if (list_find(&free_list, reflist) == NULL) +! free_list = list_cons (reflist, free_list); + reflist = reflist->tail; + } + } +! list_mapcar (free_list, __objc_free); +! list_free (free_list); + + /* empty object reference table */ + hash_delete (stream->object_refs); +--- 1483,1501 ---- + while(reflist) + { + *((id*)reflist->head) = object; +! if (hash_value_for_key (free_list,reflist) == NULL) +! hash_add (&free_list,reflist,reflist); +! + reflist = reflist->tail; + } + } +! +! /* apply __objc_free to all objects stored in free_list */ +! for (node = hash_next (free_list, NULL); node; +! node = hash_next (free_list, node)) +! objc_free ((void *) node->key); +! +! hash_delete (free_list); + + /* empty object reference table */ + hash_delete (stream->object_refs); +*************** +*** 1503,1509 **** + TypedStream* + objc_open_typed_stream (FILE* physical, int mode) + { +! TypedStream* s = (TypedStream*)__objc_xmalloc(sizeof(TypedStream)); + + s->mode = mode; + s->physical = physical; +--- 1528,1534 ---- + TypedStream* + objc_open_typed_stream (FILE* physical, int mode) + { +! TypedStream* s = (TypedStream*)objc_malloc(sizeof(TypedStream)); + + s->mode = mode; + s->physical = physical; +*************** +*** 1590,1596 **** + if (stream->type == (OBJC_MANAGED_STREAM | OBJC_FILE_STREAM)) + fclose ((FILE*)stream->physical); + +! free (stream); + } + + BOOL +--- 1615,1621 ---- + if (stream->type == (OBJC_MANAGED_STREAM | OBJC_FILE_STREAM)) + fclose ((FILE*)stream->physical); + +! objc_free(stream); + } + + BOOL +diff -rcP gcc-2.7.2/objc/class.c gcc-2.7.2.1-objc-960906/objc/class.c +*** gcc-2.7.2/objc/class.c Fri Sep 6 14:34:50 1996 +--- gcc-2.7.2.1-objc-960906/objc/class.c Fri Sep 6 10:33:29 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime class related functions +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup and Dennis Glatting. + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime class related functions +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup and Dennis Glatting. + + This file is part of GNU CC. +*************** +*** 27,42 **** + #include "sarray.h" + + /* The table of classname->class. Used for objc_lookup_class and friends */ +! static cache_ptr __objc_class_hash = 0; + + /* 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; + + + /* True when class links has been resolved */ +! BOOL __objc_class_links_resolved = NO; + + + /* Initial number of buckets size of class hash table. */ +--- 27,42 ---- + #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. */ +*************** +*** 49,58 **** +--- 49,62 ---- + 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 +*************** +*** 62,67 **** +--- 66,73 ---- + { + Class h_class; + ++ objc_mutex_lock(__objc_runtime_mutex); ++ + /* make sure the table is there */ + assert(__objc_class_hash); + +*************** +*** 82,87 **** +--- 88,95 ---- + ++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 +*************** +*** 91,101 **** +--- 99,113 ---- + { + 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; + +*************** +*** 113,123 **** +--- 125,139 ---- + { + 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; + +*************** +*** 127,134 **** + if(class) + return class; + +! fprintf(stderr, "objc runtime: cannot find class %s\n", name); +! abort(); + } + + MetaClass +--- 143,150 ---- + if(class) + return class; + +! objc_error(nil, OBJC_ERR_BAD_CLASS, +! "objc runtime: cannot find class %s\n", name); + } + + MetaClass +*************** +*** 149,159 **** +--- 165,180 ---- + 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; +*************** +*** 169,174 **** +--- 190,197 ---- + + 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)) +*************** +*** 234,239 **** +--- 257,264 ---- + sub_class->class_pointer->super_class = class1->class_pointer; + } + } ++ ++ objc_mutex_unlock(__objc_runtime_mutex); + } + + +*************** +*** 281,287 **** + 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); + } +--- 306,313 ---- + 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); + } +*************** +*** 307,312 **** +--- 333,340 ---- + 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)) + { +*************** +*** 316,321 **** +--- 344,351 ---- + 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)); +diff -rcP gcc-2.7.2/objc/encoding.c gcc-2.7.2.1-objc-960906/objc/encoding.c +*** gcc-2.7.2/objc/encoding.c Fri Sep 6 14:34:50 1996 +--- gcc-2.7.2.1-objc-960906/objc/encoding.c Fri Sep 6 10:33:29 1996 +*************** +*** 1,5 **** + /* Encoding of types for Objective C. +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* Encoding of types for Objective C. +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 25,32 **** +--- 25,37 ---- + 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 "encoding.h" + ++ #ifndef OBJC_FORWARDING_STACK_OFFSET ++ # define OBJC_FORWARDING_STACK_OFFSET 0 ++ #endif ++ + #define MAX(X, Y) \ + ({ typeof(X) __x = (X), __y = (Y); \ + (__x > __y ? __x : __y); }) +*************** +*** 153,159 **** + } + + default: +! abort(); + } + } + +--- 158,164 ---- + } + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type); + } + } + +*************** +*** 218,223 **** +--- 223,229 ---- + return __alignof__(double); + break; + ++ case _C_PTR: + case _C_ATOM: + case _C_CHARPTR: + return __alignof__(char*); +*************** +*** 250,256 **** + } + + default: +! abort(); + } + } + +--- 256,262 ---- + } + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type); + } + } + +*************** +*** 341,346 **** +--- 347,353 ---- + case _C_FLT: + case _C_DBL: + case _C_VOID: ++ case _C_UNDEF: + return ++type; + break; + +*************** +*** 352,358 **** + if (*type == _C_ARY_E) + return ++type; + else +! abort(); + + case _C_STRUCT_B: + /* skip name, and elements until closing '}' */ +--- 359,365 ---- + if (*type == _C_ARY_E) + return ++type; + else +! objc_error(nil, OBJC_ERR_BAD_TYPE, "bad array type %s\n", type); + + case _C_STRUCT_B: + /* skip name, and elements until closing '}' */ +*************** +*** 374,380 **** + return objc_skip_typespec (++type); + + default: +! abort(); + } + } + +--- 381,387 ---- + return objc_skip_typespec (++type); + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type); + } + } + +*************** +*** 467,475 **** + t = objc_skip_typespec (t); + + if (*t == '+') +! return argframe->arg_regs + atoi (++t); + else +! return argframe->arg_ptr + atoi (t); + } + + /* +--- 474,482 ---- + t = objc_skip_typespec (t); + + if (*t == '+') +! return argframe->arg_regs + atoi (++t) - OBJC_FORWARDING_STACK_OFFSET; + else +! return argframe->arg_ptr + atoi (t) - OBJC_FORWARDING_STACK_OFFSET; + } + + /* +*************** +*** 510,518 **** + t = objc_skip_typespec (t); + + if (*t == '+') +! return argframe->arg_regs + atoi (++t); + else +! return argframe->arg_ptr + atoi (t); + } + + unsigned +--- 517,525 ---- + t = objc_skip_typespec (t); + + if (*t == '+') +! return argframe->arg_regs + atoi (++t) - OBJC_FORWARDING_STACK_OFFSET; + else +! return argframe->arg_ptr + atoi (t) - OBJC_FORWARDING_STACK_OFFSET; + } + + unsigned +diff -rcP gcc-2.7.2/objc/encoding.h gcc-2.7.2.1-objc-960906/objc/encoding.h +*** gcc-2.7.2/objc/encoding.h Fri Sep 6 14:34:50 1996 +--- gcc-2.7.2.1-objc-960906/objc/encoding.h Fri Sep 6 10:33:29 1996 +*************** +*** 57,63 **** + 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_size_of_arguments (struct objc_method*); + + char* method_get_first_argument (struct objc_method*, + arglist_t argframe, +--- 57,63 ---- + 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, +diff -rcP gcc-2.7.2/objc/hash.c gcc-2.7.2.1-objc-960906/objc/hash.c +*** gcc-2.7.2/objc/hash.c Fri Sep 6 14:34:51 1996 +--- gcc-2.7.2.1-objc-960906/objc/hash.c Fri Sep 6 10:33:30 1996 +*************** +*** 1,5 **** + /* Hash tables for Objective C internal structures +! Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + +--- 1,5 ---- + /* Hash tables for Objective C internal structures +! Copyright (C) 1993, 1996 Free Software Foundation, Inc. + + This file is part of GNU CC. + +*************** +*** 27,33 **** + #include "assert.h" + + #include "objc/hash.h" +- #include "objc/objc.h" + + #include "runtime.h" /* for DEBUG_PRINTF */ + +--- 27,32 ---- +*************** +*** 40,47 **** + #define EXPANSION(cache) \ + ((cache)->size * 2) + +- void *__objc_xcalloc (size_t, size_t); +- + cache_ptr + hash_new (unsigned int size, hash_func_type hash_func, + compare_func_type compare_func) +--- 39,44 ---- +*************** +*** 54,66 **** + + /* Allocate the cache structure. calloc insures + its initialization for default values. */ +! cache = (cache_ptr) __objc_xcalloc (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_xcalloc (size, sizeof (node_ptr)); + assert (cache->node_table); + + cache->size = size; +--- 51,63 ---- + + /* 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; +*************** +*** 83,97 **** + hash_delete (cache_ptr cache) + { + node_ptr node; +! + + /* Purge all key/value pairs from the table. */ +! while ((node = hash_next (cache, NULL))) +! hash_remove (cache, node->key); + + /* Release the array of nodes and the cache itself. */ +! free (cache->node_table); +! free (cache); + } + + +--- 80,107 ---- + 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); + } + + +*************** +*** 99,105 **** + hash_add (cache_ptr *cachep, const void *key, void *value) + { + size_t indx = (*(*cachep)->hash_func)(*cachep, key); +! node_ptr node = (node_ptr) __objc_xcalloc (1, sizeof (struct cache_node)); + + + assert (node); +--- 109,115 ---- + 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); +*************** +*** 172,178 **** + /* 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; +! free (node); + } else { + + /* Otherwise, find the hash entry. */ +--- 182,188 ---- + /* 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. */ +*************** +*** 183,189 **** + + if ((*cache->compare_func)(node->key, key)) { + prev->next = node->next, removed = YES; +! free (node); + } else + prev = node, node = node->next; + } while (!removed && node); +--- 193,199 ---- + + 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); +*************** +*** 243,253 **** + + if (node) + do { +! if ((*cache->compare_func)(node->key, key)) + retval = node->value; +! else + node = node->next; + } while (!retval && node); + + return retval; + } +--- 253,283 ---- + + 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; + } +diff -rcP gcc-2.7.2/objc/hash.h gcc-2.7.2.1-objc-960906/objc/hash.h +*** gcc-2.7.2/objc/hash.h Fri Sep 6 14:34:51 1996 +--- gcc-2.7.2.1-objc-960906/objc/hash.h Fri Sep 6 10:33:30 1996 +*************** +*** 1,5 **** + /* Hash tables for Objective C method dispatch. +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + + This file is part of GNU CC. + +--- 1,5 ---- + /* Hash tables for Objective C method dispatch. +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + + This file is part of GNU CC. + +*************** +*** 29,34 **** +--- 29,35 ---- + #define __hash_INCLUDE_GNU + + #include ++ #include + + /* + * This data structure is used to hold items +*************** +*** 140,145 **** +--- 141,149 ---- + + 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); + + /************************************************ + +diff -rcP gcc-2.7.2/objc/init.c gcc-2.7.2.1-objc-960906/objc/init.c +*** gcc-2.7.2/objc/init.c Fri Sep 6 14:34:51 1996 +--- gcc-2.7.2.1-objc-960906/objc/init.c Fri Sep 6 10:33:30 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime initialization +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime initialization +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 31,43 **** + #define PROTOCOL_VERSION 2 + + /* This list contains all modules currently loaded into the runtime */ +! static struct objc_list* __objc_module_list = 0; + + /* This list contains all proto_list's not yet assigned class links */ +! static struct objc_list* unclaimed_proto_list = 0; + + /* List of unresolved static instances. */ +! static struct objc_list *uninitialized_statics; + + /* Check compiler vs runtime version */ + static void init_check_module_version (Module_t); +--- 31,49 ---- + #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; +! +! /* 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); +*************** +*** 52,65 **** + 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) = 0; + + /* Is all categories/classes resolved? */ +! BOOL __objc_dangling_categories = NO; + + extern SEL + __sel_register_typed_name (const char *name, const char *types, +! struct objc_selector *orig); + + /* Run through the statics list, removing modules as soon as all its statics + have been initialized. */ +--- 58,71 ---- + 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) = 0; /* !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); + + /* Run through the statics list, removing modules as soon as all its statics + have been initialized. */ +*************** +*** 69,74 **** +--- 75,82 ---- + 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; +*************** +*** 109,119 **** + /* Remove this module from the uninitialized list. */ + struct objc_list *this = *cell; + *cell = this->tail; +! free (this); + } + else + cell = &(*cell)->tail; + } + } /* objc_init_statics */ + + /* This function is called by constructor functions generated for each +--- 117,129 ---- + /* 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 +*************** +*** 150,155 **** +--- 160,170 ---- + /* 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(); +*************** +*** 157,162 **** +--- 172,178 ---- + } + + /* 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. */ +*************** +*** 167,174 **** + const char *name, *type; + name = (char*)selectors[i].sel_id; + type = (char*)selectors[i].sel_types; + __sel_register_typed_name (name, type, +! (struct objc_selector*)&(selectors[i])); + } + } + +--- 183,193 ---- + 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); + } + } + +*************** +*** 183,188 **** +--- 202,211 ---- + 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); + +*************** +*** 190,195 **** +--- 213,222 ---- + __objc_register_selectors_from_class (class); + __objc_register_selectors_from_class ((Class) class->class_pointer); + ++ /* Register the instance methods as class methods, this is ++ only done for root classes. */ ++ __objc_register_instance_methods_to_class(class); ++ + /* Install the fake dispatch tables */ + __objc_install_premature_dtable(class); + __objc_install_premature_dtable(class->class_pointer); +*************** +*** 230,235 **** +--- 257,266 ---- + __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 (_objc_load_callback) + _objc_load_callback(class, category); + } +*************** +*** 275,280 **** +--- 306,315 ---- + __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 (_objc_load_callback) + _objc_load_callback(class, category); + } +*************** +*** 287,292 **** +--- 322,328 ---- + unclaimed_proto_list = 0; + } + ++ objc_mutex_unlock(__objc_runtime_mutex); + } + + /* Sanity check the version of gcc used to compile `module'*/ +*************** +*** 294,308 **** + { + if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module))) + { +! fprintf (stderr, "Module %s version %d doesn't match runtime %d\n", +! module->name, (int)module->version, OBJC_VERSION); + if(module->version > OBJC_VERSION) +! fprintf (stderr, "Runtime (libobjc.a) is out of date\n"); + else if (module->version < OBJC_VERSION) +! fprintf (stderr, "Compiler (gcc) is out of date\n"); + else +! fprintf (stderr, "Objective C internal error -- bad Module size\n"); +! abort (); + } + } + +--- 330,346 ---- + { + 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); + } + } + +*************** +*** 315,326 **** +--- 353,367 ---- + 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; + } + +*************** +*** 341,353 **** + } + else if (protos->list[i]->class_pointer != proto_class) + { +! fprintf (stderr, +! "Version %d doesn't match runtime protocol version %d\n", +! (int)((char*)protos->list[i]->class_pointer-(char*)0), +! PROTOCOL_VERSION); +! abort (); + } + } + } + + static void __objc_class_add_protocols (Class class, +--- 382,395 ---- + } + 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, +diff -rcP gcc-2.7.2/objc/makefile.dos gcc-2.7.2.1-objc-960906/objc/makefile.dos +*** gcc-2.7.2/objc/makefile.dos Fri Sep 6 14:34:52 1996 +--- gcc-2.7.2.1-objc-960906/objc/makefile.dos Fri Sep 6 10:33:31 1996 +*************** +*** 1,5 **** + # GNU Objective C Runtime Makefile for compiling with djgpp +! # Copyright (C) 1993, 1994 Free Software Foundation, Inc. + # + # This file is part of GNU CC. + # +--- 1,5 ---- + # 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. + # +*************** +*** 37,53 **** + -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 + + libobjc.a: $(OBJC_O) + -rm -f libobjc.a + ar rc libobjc.a $(OBJC_O) + ranlib libobjc.a + +! OBJC_H = hash.h list.h sarray.h objc.h \ + objc-api.h \ + object.h protocol.h mutex.h \ +! typedstream.h + + mostlyclean: + -rm -f *.o libobjc.a xforward fflags +--- 37,53 ---- + -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 +diff -rcP gcc-2.7.2/objc/misc.c gcc-2.7.2.1-objc-960906/objc/misc.c +*** gcc-2.7.2/objc/misc.c Fri Sep 6 14:34:52 1996 +--- gcc-2.7.2.1-objc-960906/objc/misc.c Fri Sep 6 10:33:31 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime Miscellaneous +! Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. + + Author: Kresten Krab Thorup + +--- 1,5 ---- + /* GNU Objective C Runtime Miscellaneous +! Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. + + Author: Kresten Krab Thorup + +*************** +*** 26,80 **** + however invalidate any other reasons why the executable file might be + covered by the GNU General Public License. */ + +- #ifdef __alpha__ + #include +- extern int write (int, const char*, int); +- extern size_t strlen (const char*); +- #endif +- + #include "runtime.h" + +! void objc_error(id object, const char* fmt, va_list); + +! void (*_objc_error)(id, const char*, va_list) = objc_error; + + void +! objc_error(id object, const char* fmt, va_list ap) + { +! vfprintf (stderr, fmt, ap); +! abort (); + } + +! volatile void +! objc_fatal(const char* msg) + { +! write(2, msg, (int)strlen((const char*)msg)); +! abort(); + } + +! void* +! __objc_xmalloc(size_t size) + { +! void* res = (void*) malloc(size); + if(!res) +! objc_fatal("Virtual memory exhausted\n"); + return res; + } + +! void* +! __objc_xrealloc(void* mem, size_t size) + { +! void* res = (void*) realloc(mem, size); + if(!res) +! objc_fatal("Virtual memory exhausted\n"); + return res; + } + +! void* +! __objc_xcalloc(size_t nelem, size_t size) + { +! void* res = (void*)calloc(nelem, size); + if(!res) +! objc_fatal("Virtual memory exhausted\n"); + return res; + } +--- 26,152 ---- + however invalidate any other reasons why the executable file might be + covered by the GNU General Public License. */ + + #include + #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; +diff -rcP gcc-2.7.2/objc/nil_method.c gcc-2.7.2.1-objc-960906/objc/nil_method.c +*** gcc-2.7.2/objc/nil_method.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/nil_method.c Fri Sep 6 10:33:32 1996 +*************** +*** 0 **** +--- 1,40 ---- ++ /* GNU Objective C Runtime nil receiver function ++ 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. */ ++ ++ /* This is the nil method, the function that is called when the receiver ++ of a method is nil */ ++ ++ #include "runtime.h" ++ ++ id ++ nil_method(id receiver, SEL op, ...) ++ { ++ return receiver; ++ } ++ ++ ++ ++ +diff -rcP gcc-2.7.2/objc/objc-api.h gcc-2.7.2.1-objc-960906/objc/objc-api.h +*** gcc-2.7.2/objc/objc-api.h Fri Sep 6 14:34:53 1996 +--- gcc-2.7.2.1-objc-960906/objc/objc-api.h Fri Sep 6 10:33:32 1996 +*************** +*** 1,5 **** + /* GNU Objective-C Runtime API. +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + + This file is part of GNU CC. + +--- 1,5 ---- + /* GNU Objective-C Runtime API. +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + + This file is part of GNU CC. + +*************** +*** 29,35 **** +--- 29,37 ---- + + #include "objc/objc.h" + #include "objc/hash.h" ++ #include "objc/thr.h" + #include ++ #include + + /* For functions which return Method_t */ + #define METHOD_NULL (Method_t)0 +*************** +*** 73,78 **** +--- 75,131 ---- + #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 */ + + /* + ** Set this variable nonzero to print a line describing each +*************** +*** 135,141 **** + + 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; +--- 188,195 ---- + + 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; +*************** +*** 308,319 **** + */ + extern void (*_objc_load_callback)(Class class, Category* category); + + extern id (*_objc_object_alloc)(Class class); +- + extern id (*_objc_object_copy)(id object); +- + extern id (*_objc_object_dispose)(id object); + + Method_t class_get_class_method(MetaClass class, SEL aSel); + + Method_t class_get_instance_method(Class class, SEL aSel); +--- 362,415 ---- + */ + 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); +*************** +*** 405,410 **** +--- 501,512 ---- + + 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); +*************** +*** 470,475 **** +--- 572,580 ---- + { + return CLS_ISMETA((Class)object); + } ++ ++ struct sarray* ++ objc_get_uninstalled_dtable(); + + #endif /* not __objc_api_INCLUDE_GNU */ + +diff -rcP gcc-2.7.2/objc/objc-list.h gcc-2.7.2.1-objc-960906/objc/objc-list.h +*** gcc-2.7.2/objc/objc-list.h Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/objc-list.h Fri Sep 6 10:33:32 1996 +*************** +*** 0 **** +--- 1,148 ---- ++ /* Generic single linked list to keep various information ++ Copyright (C) 1993, 1994, 1996 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 ++ ++ 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_malloc(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 */ ++ objc_free(tail); /* free next */ ++ } ++ else /* only one element in list */ ++ { ++ objc_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); ++ objc_free(list); ++ } ++ } ++ #endif __GNU_OBJC_LIST_H +diff -rcP gcc-2.7.2/objc/objc.h gcc-2.7.2.1-objc-960906/objc/objc.h +*** gcc-2.7.2/objc/objc.h Fri Sep 6 14:34:53 1996 +--- gcc-2.7.2.1-objc-960906/objc/objc.h Fri Sep 6 10:33:33 1996 +*************** +*** 103,111 **** + 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 +--- 103,111 ---- + 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 +diff -rcP gcc-2.7.2/objc/objects.c gcc-2.7.2.1-objc-960906/objc/objects.c +*** gcc-2.7.2/objc/objects.c Fri Sep 6 14:34:53 1996 +--- gcc-2.7.2.1-objc-960906/objc/objects.c Fri Sep 6 10:33:33 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime class related functions +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* 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. +*************** +*** 31,39 **** + id __objc_object_dispose(id); + id __objc_object_copy(id); + +! id (*_objc_object_alloc)(Class) = __objc_object_alloc; +! id (*_objc_object_dispose)(id) = __objc_object_dispose; +! id (*_objc_object_copy)(id) = __objc_object_copy; + + id + class_create_instance(Class class) +--- 31,39 ---- + 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) +*************** +*** 66,84 **** + if (_objc_object_dispose) + (*_objc_object_dispose)(object); + else +! free(object); + } + return nil; + } + + id __objc_object_alloc(Class class) + { +! return (id)__objc_xmalloc(class->instance_size); + } + + id __objc_object_dispose(id object) + { +! free(object); + return 0; + } + +--- 66,84 ---- + 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; + } + +diff -rcP gcc-2.7.2/objc/runtime.h gcc-2.7.2.1-objc-960906/objc/runtime.h +*** gcc-2.7.2/objc/runtime.h Fri Sep 6 14:34:53 1996 +--- gcc-2.7.2.1-objc-960906/objc/runtime.h Fri Sep 6 10:33:33 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime internal declarations +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime internal declarations +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 37,44 **** + #include "objc/objc.h" /* core data types */ + #include "objc/objc-api.h" /* runtime api functions */ + + #include "objc/hash.h" /* hash structures */ +! #include "objc/list.h" /* linear lists */ + + extern void __objc_add_class_to_hash(Class); /* (objc-class.c) */ + extern void __objc_init_selector_tables(); /* (objc-sel.c) */ +--- 37,46 ---- + #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(); /* (objc-sel.c) */ +*************** +*** 48,57 **** + extern void __objc_resolve_class_links(); /* (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 void class_add_method_list(Class, MethodList_t); + +! extern void objc_error(id object, const char* fmt, va_list); +! extern void (*_objc_error)(id, const char*, va_list); + + /* True when class links has been resolved */ + extern BOOL __objc_class_links_resolved; +--- 50,64 ---- + extern void __objc_resolve_class_links(); /* (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 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; +*************** +*** 59,64 **** +--- 66,77 ---- + /* 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 +*************** +*** 67,73 **** + + BOOL __objc_responds_to (id object, SEL sel); /* for internal use only! */ + SEL __sel_register_typed_name (const char*, const char*, +! struct objc_selector*); + + #endif /* not __objc_runtime_INCLUDE_GNU */ + +--- 80,86 ---- + + 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 */ + +diff -rcP gcc-2.7.2/objc/sarray.c gcc-2.7.2.1-objc-960906/objc/sarray.c +*** gcc-2.7.2/objc/sarray.c Fri Sep 6 14:34:54 1996 +--- gcc-2.7.2.1-objc-960906/objc/sarray.c Fri Sep 6 10:33:34 1996 +*************** +*** 1,5 **** + /* Sparse Arrays for Objective C dispatch tables +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + + This file is part of GNU CC. + +--- 1,5 ---- + /* Sparse Arrays for Objective C dispatch tables +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + + This file is part of GNU CC. + +*************** +*** 25,37 **** + the executable file might be covered by the GNU General Public License. */ + + #include "objc/sarray.h" + #include + #include "assert.h" + +! int nbuckets = 0; +! int nindices = 0; +! int narrays = 0; +! int idxsize = 0; + + #ifdef OBJC_SPARSE2 + const char* __objc_sparse2_id = "2 level sparse indices"; +--- 25,40 ---- + the executable file might be covered by the GNU General Public License. */ + + #include "objc/sarray.h" ++ #include "objc/runtime.h" + #include + #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"; +*************** +*** 43,58 **** + + #ifdef __alpha__ + const void *memcpy (void*, const void*, size_t); +- void free (const void*); + #endif + + void + sarray_at_put(struct sarray* array, sidx index, void* element) + { + #ifdef OBJC_SPARSE3 + struct sindex** the_index; + #endif + struct sbucket** the_bucket; + #ifdef OBJC_SPARSE3 + size_t ioffset; + #endif +--- 46,107 ---- + + #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 +*************** +*** 96,117 **** + if ((*the_index) == array->empty_index) { + + /* The index was previously empty, allocate a new */ +! *the_index = (struct sindex*)__objc_xmalloc(sizeof(struct sindex)); +! memcpy(*the_index, array->empty_index, sizeof(struct sindex)); +! (*the_index)->version = array->version; + the_bucket = &((*the_index)->buckets[boffset]); +- nindices += 1; + +! } else if ((*the_index)->version != array->version) { + + /* This index must be lazy copied */ + struct sindex* old_index = *the_index; +! *the_index = (struct sindex*)__objc_xmalloc(sizeof(struct sindex)); +! memcpy( *the_index,old_index, sizeof(struct sindex)); +! (*the_index)->version = array->version; + the_bucket = &((*the_index)->buckets[boffset]); +- nindices += 1; + + } + + #endif /* OBJC_SPARSE3 */ +--- 145,168 ---- + 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 */ +*************** +*** 122,139 **** + + /* The bucket was previously empty (or something like that), */ + /* allocate a new. This is the effect of `lazy' allocation */ +! *the_bucket = (struct sbucket*)__objc_xmalloc(sizeof(struct sbucket)); +! memcpy((void *) *the_bucket, (const void*)array->empty_bucket, sizeof(struct sbucket)); +! (*the_bucket)->version = array->version; + nbuckets += 1; + +! } else if ((*the_bucket)->version != array->version) { + + /* Perform lazy copy. */ + struct sbucket* old_bucket = *the_bucket; +! *the_bucket = (struct sbucket*)__objc_xmalloc(sizeof(struct sbucket)); +! memcpy( *the_bucket,old_bucket, sizeof(struct sbucket)); +! (*the_bucket)->version = array->version; + nbuckets += 1; + + } +--- 173,195 ---- + + /* 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; + + } +*************** +*** 151,192 **** + struct sarray* + sarray_new (int size, void* default_element) + { + #ifdef OBJC_SPARSE3 + size_t num_indices = ((size-1)/(INDEX_CAPACITY))+1; + #else /* OBJC_SPARSE2 */ + size_t num_indices = ((size-1)/BUCKET_SIZE)+1; + #endif + int counter; +- struct sarray* arr; + + assert(size > 0); + + /* Allocate core array */ +! arr = (struct sarray*) __objc_xmalloc(sizeof(struct sarray)); +! arr->version = 0; +! narrays += 1; + + /* Initialize members */ + #ifdef OBJC_SPARSE3 + arr->capacity = num_indices*INDEX_CAPACITY; +! arr->indices = (struct sindex**) +! __objc_xmalloc(sizeof(struct sindex*)*num_indices); +! idxsize += num_indices; + +! arr->empty_index = (struct sindex*) __objc_xmalloc(sizeof(struct sindex)); +! arr->empty_index->version = 0; + nindices += 1; + + #else /* OBJC_SPARSE2 */ + arr->capacity = num_indices*BUCKET_SIZE; +! arr->buckets = (struct sbucket**) +! __objc_xmalloc(sizeof(struct sbucket*)*num_indices); + idxsize += num_indices; + + #endif + +! arr->empty_bucket = (struct sbucket*) __objc_xmalloc(sizeof(struct sbucket)); +! arr->empty_bucket->version = 0; + nbuckets += 1; + + arr->ref_count = 1; +--- 207,254 ---- + 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; +*************** +*** 200,219 **** + arr->empty_index->buckets[counter] = arr->empty_bucket; + + for (counter=0; counterindices[counter] = arr->empty_index; + + #else /* OBJC_SPARSE2 */ + + for (counter=0; counterbuckets[counter] = arr->empty_bucket; + + #endif +! + return arr; + } + + +! /* Reallocate the sparse array to hold `newsize' entries */ + + void + sarray_realloc(struct sarray* array, int newsize) +--- 262,289 ---- + arr->empty_index->buckets[counter] = arr->empty_bucket; + + for (counter=0; counterempty_index; + + #else /* OBJC_SPARSE2 */ + + for (counter=0; counterempty_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) +*************** +*** 223,233 **** +--- 293,309 ---- + 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; +*************** +*** 235,321 **** + 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... */ + +! if(rounded_size < array->capacity) + { +- /* update capacity */ +- array->capacity = rounded_size; + +- /* free buckets above new_max_index */ +- for(counter = old_max_index; counter > new_max_index; counter-- ) { + #ifdef OBJC_SPARSE3 +! struct sindex* idx = array->indices[counter]; +! if((idx != array->empty_index) && (idx->version == array->version)) { +! int c2; +! for(c2=0; c2buckets[c2]; +! if((bkt != array->empty_bucket) && (bkt->version == array->version)) +! { +! free(bkt); +! nbuckets -= 1; +! } +! } +! free(idx); +! nindices -= 1; +! } + #else /* OBJC_SPARSE2 */ +! struct sbucket* bkt = array->buckets[counter]; +! if ((bkt != array->empty_bucket) && (bkt->version == array->version)) +! { +! free(bkt); +! nbuckets -= 1; +! } + #endif +! } +! +! #ifdef OBJC_SPARSE3 +! /* realloc to free the space above new_max_index */ +! array->indices = (struct sindex**) +! __objc_xrealloc(array->indices, +! (new_max_index+1)*sizeof(struct sindex*)); +! #else /* OBJC_SPARSE2 */ +! array->buckets = (struct sbucket**) +! __objc_xrealloc(array->buckets, +! (new_max_index+1)*sizeof(struct sbucket*)); +! #endif +! idxsize -= (old_max_index-new_max_index); +! +! return; +! } +! +! /* We are asked to extend the array -- reallocate the bucket table, */ +! /* and insert empty_bucket in newly allocated places. */ +! if(rounded_size > array->capacity) +! { + /* update capacity */ + array->capacity = rounded_size; + + #ifdef OBJC_SPARSE3 +! /* realloc to make room in table above old_max_index */ +! array->indices = (struct sindex**) +! __objc_xrealloc(array->indices, +! (new_max_index+1)*sizeof(struct sindex*)); + + /* reset entries above old_max_index to empty_bucket */ + for(counter = old_max_index+1; counter <= new_max_index; counter++) +! array->indices[counter] = array->empty_index; +! + #else /* OBJC_SPARSE2 */ +- +- /* realloc to make room in table above old_max_index */ +- array->buckets = (struct sbucket**) +- __objc_xrealloc(array->buckets, +- (new_max_index+1)*sizeof(struct sbucket*)); +- + /* reset entries above old_max_index to empty_bucket */ + for(counter = old_max_index+1; counter <= new_max_index; counter++) +! array->buckets[counter] = array->empty_bucket; + + #endif + idxsize += (new_max_index-old_max_index); + return; + } +--- 311,382 ---- + 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; + } +*************** +*** 326,335 **** +--- 387,399 ---- + + 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; + +*************** +*** 338,368 **** + if(--(array->ref_count) != 0) /* There exists copies of me */ + return; + + 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 = array->indices[counter]; +! if((idx != array->empty_index) && (idx->version == array->version)) { + int c2; + for(c2=0; c2buckets[c2]; +! if((bkt != array->empty_bucket) && (bkt->version == array->version)) + { +! free(bkt); + nbuckets -= 1; + } + } +! free(idx); + nindices -= 1; + } + #else /* OBJC_SPARSE2 */ + struct sbucket* bkt = array->buckets[counter]; +! if ((bkt != array->empty_bucket) && (bkt->version == array->version)) + { +! free(bkt); + nbuckets -= 1; + } + #endif +--- 402,441 ---- + 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; c2buckets[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 +*************** +*** 370,402 **** + + #ifdef OBJC_SPARSE3 + /* free empty_index */ +! if(array->empty_index->version == array->version) { +! free(array->empty_index); + nindices -= 1; + } + #endif + + /* free empty_bucket */ +! if(array->empty_bucket->version == array->version) { +! free(array->empty_bucket); + nbuckets -= 1; + } + + #ifdef OBJC_SPARSE3 + /* free bucket table */ +! free(array->indices); +! idxsize -= (old_max_index+1); + + #else + /* free bucket table */ +! free(array->buckets); +! idxsize -= (old_max_index+1); + + #endif +! + /* free array */ +! free(array); +! narrays -= 1; + } + + /* This is a lazy copy. Only the core of the structure is actually */ +--- 443,474 ---- + + #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 */ +*************** +*** 405,441 **** + struct sarray* + sarray_lazy_copy(struct sarray* oarr) + { + #ifdef OBJC_SPARSE3 + size_t num_indices = ((oarr->capacity-1)/INDEX_CAPACITY)+1; + #else /* OBJC_SPARSE2 */ + size_t num_indices = ((oarr->capacity-1)/BUCKET_SIZE)+1; + #endif +- struct sarray* arr; + + /* Allocate core array */ +! arr = (struct sarray*) __objc_xmalloc(sizeof(struct sarray)); +! memcpy( arr,oarr, sizeof(struct sarray)); +! arr->version = oarr->version + 1; +! arr->is_copy_of = oarr; +! oarr->ref_count += 1; + arr->ref_count = 1; + + #ifdef OBJC_SPARSE3 + /* Copy bucket table */ +! arr->indices = (struct sindex**) +! __objc_xmalloc(sizeof(struct sindex*)*num_indices); +! memcpy( arr->indices,oarr->indices, + sizeof(struct sindex*)*num_indices); + #else + /* Copy bucket table */ +! arr->buckets = (struct sbucket**) +! __objc_xmalloc(sizeof(struct sbucket*)*num_indices); +! memcpy( arr->buckets,oarr->buckets, + sizeof(struct sbucket*)*num_indices); + #endif + + idxsize += num_indices; + narrays += 1; +! + return arr; + } +--- 477,522 ---- + 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; + } +diff -rcP gcc-2.7.2/objc/sarray.h gcc-2.7.2.1-objc-960906/objc/sarray.h +*** gcc-2.7.2/objc/sarray.h Fri Sep 6 14:34:54 1996 +--- gcc-2.7.2.1-objc-960906/objc/sarray.h Fri Sep 6 10:33:34 1996 +*************** +*** 1,5 **** + /* Sparse Arrays for Objective C dispatch tables +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + + Author: Kresten Krab Thorup + +--- 1,5 ---- + /* Sparse Arrays for Objective C dispatch tables +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + + Author: Kresten Krab Thorup + +*************** +*** 42,47 **** +--- 42,49 ---- + + #include + ++ #include "objc/thr.h" ++ + extern int nbuckets; /* for stats */ + extern int nindices; + extern int narrays; +*************** +*** 108,126 **** + + #endif /* not PRECOMPUTE_SELECTORS */ + +! void * __objc_xrealloc (void *optr, size_t size); +! void * __objc_xmalloc (size_t size); + + struct sbucket { + void* elems[BUCKET_SIZE]; /* elements stored in array */ +! short version; /* used for copy-on-write */ + }; + + #ifdef OBJC_SPARSE3 + + struct sindex { + struct sbucket* buckets[INDEX_SIZE]; +! short version; + }; + + #endif /* OBJC_SPARSE3 */ +--- 110,130 ---- + + #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 */ +*************** +*** 133,139 **** + struct sbucket** buckets; + #endif /* OBJC_SPARSE2 */ + struct sbucket* empty_bucket; +! short version; + short ref_count; + struct sarray* is_copy_of; + size_t capacity; +--- 137,143 ---- + 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; +*************** +*** 142,151 **** + struct sarray* sarray_new(int, void* default_element); + void sarray_free(struct sarray*); + struct sarray* sarray_lazy_copy(struct sarray*); +- struct sarray* sarray_hard_copy(struct sarray*); /* ... like the name? */ + 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); + + + #ifdef PRECOMPUTE_SELECTORS +--- 146,157 ---- + 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 +diff -rcP gcc-2.7.2/objc/selector.c gcc-2.7.2.1-objc-960906/objc/selector.c +*** gcc-2.7.2/objc/selector.c Fri Sep 6 14:34:55 1996 +--- gcc-2.7.2.1-objc-960906/objc/selector.c Fri Sep 6 10:33:34 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime selector related functions +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime selector related functions +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 31,44 **** + #define SELECTOR_HASH_SIZE 128 + + /* Tables mapping selector names to uid and opposite */ +! static struct sarray* __objc_selector_array = 0; /* uid -> sel */ +! static struct sarray* __objc_selector_names = 0; /* uid -> name */ +! static cache_ptr __objc_selector_hash = 0; /* name -> uid */ + + static void register_selectors_from_list(MethodList_t); + + /* Number of selectors stored in each of the above tables */ +! int __objc_selector_max_index = 0; + + void __objc_init_selector_tables() + { +--- 31,44 ---- + #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() + { +*************** +*** 88,93 **** +--- 88,153 ---- + } + + ++ /* 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 for this method list */ ++ for (i = 0; i < method_list->method_count; i++) ++ if (!search_for_method_in_list ++ (class_method_list, ++ method_list->method_list[i].method_name)) ++ { ++ /* This instance method isn't a class method. ++ Add it into the new_list. */ ++ *curr_method = method_list->method_list[i]; ++ ++ /* 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; ++ } ++ } ++ ++ + /* Returns YES iff t1 and t2 have same method types, but we ignore + the argframe layout */ + BOOL +*************** +*** 122,130 **** + struct objc_list *l; + sidx i; + + i = (sidx) hash_value_for_key (__objc_selector_hash, name); + if (i == 0) +! return 0; + + for (l = (struct objc_list*)sarray_get (__objc_selector_array, i); + l; l = l->tail) +--- 182,195 ---- + 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 (__objc_selector_array, i); + l; l = l->tail) +*************** +*** 134,148 **** +--- 199,216 ---- + { + 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; + } + +*************** +*** 154,171 **** + sidx i; + SEL s; + + i = (sidx) hash_value_for_key (__objc_selector_hash, name); + if (i == 0) +! return 0; + + for (l = (struct objc_list*)sarray_get (__objc_selector_array, i); + l; l = l->tail) + { + s = (SEL) l->head; + if (s->sel_types) +! return s; + } + + return s; + } + +--- 222,248 ---- + sidx i; + SEL s; + ++ 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 (__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; + } + +*************** +*** 176,186 **** + struct objc_list *l; + sidx i; + + i = (sidx) hash_value_for_key (__objc_selector_hash, name); + if (soffset_decode (i) == 0) +! return 0; + + l = (struct objc_list*)sarray_get (__objc_selector_array, i); + if (l == 0) + return 0; + +--- 253,270 ---- + 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 (__objc_selector_array, i); ++ objc_mutex_unlock(__objc_runtime_mutex); ++ + if (l == 0) + return 0; + +*************** +*** 199,209 **** + const char* + sel_get_name (SEL selector) + { + if ((soffset_decode((sidx)selector->sel_id) > 0) + && (soffset_decode((sidx)selector->sel_id) <= __objc_selector_max_index)) +! return sarray_get (__objc_selector_names, (sidx) selector->sel_id); + else +! return 0; + } + + BOOL +--- 283,298 ---- + 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 (__objc_selector_names, (sidx) selector->sel_id); + else +! ret = 0; +! objc_mutex_unlock(__objc_runtime_mutex); +! return ret; + } + + BOOL +*************** +*** 227,236 **** + 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). */ + SEL + __sel_register_typed_name (const char *name, const char *types, +! struct objc_selector *orig) + { + struct objc_selector* j; + sidx i; +--- 316,330 ---- + 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; +*************** +*** 270,279 **** + if (orig) + j = orig; + else +! j = __objc_xmalloc (sizeof (struct objc_selector)); + + j->sel_id = (void*)i; +! j->sel_types = (const char*)types; + l = (struct objc_list*)sarray_get (__objc_selector_array, i); + } + else +--- 364,379 ---- + 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 (__objc_selector_array, i); + } + else +*************** +*** 283,292 **** + if (orig) + j = orig; + else +! j = __objc_xmalloc (sizeof (struct objc_selector)); + + j->sel_id = (void*)i; +! j->sel_types = (const char*)types; + l = 0; + } + +--- 383,398 ---- + 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; + } + +*************** +*** 295,305 **** + + { + int is_new = (l == 0); + l = list_cons ((void*)j, l); +! sarray_at_put_safe (__objc_selector_names, i, (void *) name); + sarray_at_put_safe (__objc_selector_array, i, (void *) l); + if (is_new) +! hash_add (&__objc_selector_hash, (void *) name, (void *) i); + } + + sarray_realloc(__objc_uninstalled_dtable, __objc_selector_max_index+1); +--- 401,421 ---- + + { + 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); +*************** +*** 310,321 **** + SEL + sel_register_name (const char *name) + { +! return __sel_register_typed_name (name, 0, 0); + } + + SEL + sel_register_typed_name (const char *name, const char *type) + { +! return __sel_register_typed_name (name, type, 0); + } + +--- 426,453 ---- + 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; + } + +diff -rcP gcc-2.7.2/objc/sendmsg.c gcc-2.7.2.1-objc-960906/objc/sendmsg.c +*** gcc-2.7.2/objc/sendmsg.c Fri Sep 6 14:34:55 1996 +--- gcc-2.7.2.1-objc-960906/objc/sendmsg.c Fri Sep 6 10:33:35 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime message lookup +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime message lookup +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 33,46 **** + #define gen_rtx(args...) 1 + #define rtx int + +! #if STRUCT_VALUE == 0 + #define INVISIBLE_STRUCT_RETURN 1 + #else + #define INVISIBLE_STRUCT_RETURN 0 + #endif + + /* The uninstalled dispatch table */ +! struct sarray* __objc_uninstalled_dtable = 0; + + /* Send +initialize to class */ + static void __objc_send_initialize(Class); +--- 33,46 ---- + #define gen_rtx(args...) 1 + #define rtx int + +! #if !defined(STRUCT_VALUE) || STRUCT_VALUE == 0 + #define INVISIBLE_STRUCT_RETURN 1 + #else + #define INVISIBLE_STRUCT_RETURN 0 + #endif + + /* The uninstalled dispatch table */ +! struct sarray* __objc_uninstalled_dtable = 0; /* !T:MUTEX */ + + /* Send +initialize to class */ + static void __objc_send_initialize(Class); +*************** +*** 49,54 **** +--- 49,62 ---- + + /* Forward declare some functions */ + static void __objc_init_install_dtable(id, SEL); ++ ++ /* Various forwarding functions that are used based upon the ++ return type for the selector. ++ __objc_block_forward for structures. ++ __objc_double_forward for floats/doubles. ++ __objc_word_forward for pointers or types that fit in registers. ++ */ ++ static double __objc_double_forward(id, SEL, ...); + static id __objc_word_forward(id, SEL, ...); + typedef struct { id many[8]; } __big; + #if INVISIBLE_STRUCT_RETURN +*************** +*** 57,71 **** + static id + #endif + __objc_block_forward(id, SEL, ...); + static Method_t search_for_method_in_hierarchy (Class class, SEL sel); +! static Method_t search_for_method_in_list(MethodList_t list, SEL op); + id nil_method(id, SEL, ...); + +! id +! nil_method(id receiver, SEL op, ...) +! { +! return receiver; +! } + + /* Given a class and selector, return the selector's implementation. */ + __inline__ +--- 65,89 ---- + static id + #endif + __objc_block_forward(id, SEL, ...); ++ + static Method_t search_for_method_in_hierarchy (Class class, SEL sel); +! Method_t search_for_method_in_list(MethodList_t list, SEL op); + id nil_method(id, SEL, ...); + +! /* OBJC_MAX_STRUCT_BY_VALUE should be defined in the platform specific +! configuration file. Some platforms, i386 on NeXTSTEP for example, +! pass small structures as values on the stack versus through a +! hidden pointer as for larger structures. In order for forwarding +! to work properly, the ObjC runtime needs to know when the structure +! is being passed by value or not so it can perform the appropriate +! forwarding function. The value of OBJC_MAX_STRUCT_BY_VALUE should +! be the maximum number of bytes for the size of the structure for it +! to be passed as a value, so a value of 8 indicates that a structure +! of size 8 gets passed as a value while a structure of size 9 gets +! passed as a hidden pointer. +! +! Leave OBJC_MAX_STRUCT_BY_VALUE undefined for platforms that always pass +! structures as hidden pointers. */ + + /* Given a class and selector, return the selector's implementation. */ + __inline__ +*************** +*** 76,89 **** + void* res = sarray_get (class->dtable, (size_t) sel->sel_id); + if(res == __objc_init_install_dtable) + { + __objc_install_dispatch_table_for_class (class); + res = sarray_get (class->dtable, (size_t) sel->sel_id); + } + if (res == 0) + { + const char *t = sel->sel_types; +! if (t && (*t == '[' || *t == '(' || *t == '{')) + res = (IMP)__objc_block_forward; + else + res = (IMP)__objc_word_forward; + } +--- 94,115 ---- + void* res = sarray_get (class->dtable, (size_t) sel->sel_id); + if(res == __objc_init_install_dtable) + { ++ objc_mutex_lock(__objc_runtime_mutex); + __objc_install_dispatch_table_for_class (class); ++ objc_mutex_unlock(__objc_runtime_mutex); + res = sarray_get (class->dtable, (size_t) sel->sel_id); + } + if (res == 0) + { + const char *t = sel->sel_types; +! if (t && (*t == '[' || *t == '(' || *t == '{') +! #ifdef OBJC_MAX_STRUCT_BY_VALUE +! && (objc_sizeof_type(t) >= OBJC_MAX_STRUCT_BY_VALUE) +! #endif +! ) + res = (IMP)__objc_block_forward; ++ else if (t && (*t == 'f' || *t == 'd')) ++ res = (IMP)__objc_double_forward; + else + res = (IMP)__objc_word_forward; + } +*************** +*** 96,102 **** +--- 122,130 ---- + void* res = sarray_get (object->class_pointer->dtable, (size_t) sel->sel_id); + if(res == __objc_init_install_dtable) + { ++ objc_mutex_lock(__objc_runtime_mutex); + __objc_install_dispatch_table_for_class (object->class_pointer); ++ objc_mutex_unlock(__objc_runtime_mutex); + res = sarray_get (object->class_pointer->dtable, (size_t) sel->sel_id); + } + return (res != 0); +*************** +*** 116,123 **** + if (result == 0) + { + const char *t = op->sel_types; +! if (t && (*t == '[' || *t == '(' || *t == '{')) + result = (IMP)__objc_block_forward; + else + result = (IMP)__objc_word_forward; + } +--- 144,157 ---- + if (result == 0) + { + const char *t = op->sel_types; +! if (t && (*t == '[' || *t == '(' || *t == '{') +! #ifdef OBJC_MAX_STRUCT_BY_VALUE +! && (objc_sizeof_type(t) >= OBJC_MAX_STRUCT_BY_VALUE) +! #endif +! ) + result = (IMP)__objc_block_forward; ++ else if (t && (*t == 'f' || *t == 'd')) ++ result = (IMP)__objc_double_forward; + else + result = (IMP)__objc_word_forward; + } +*************** +*** 172,177 **** +--- 206,213 ---- + if(receiver->class_pointer->dtable != __objc_uninstalled_dtable) + goto already_initialized; + ++ objc_mutex_lock(__objc_runtime_mutex); ++ + if(CLS_ISCLASS(receiver->class_pointer)) + { + /* receiver is an ordinary object */ +*************** +*** 198,203 **** +--- 234,240 ---- + else + CLS_SETINITIALIZED((Class)receiver); + } ++ objc_mutex_unlock(__objc_runtime_mutex); + + already_initialized: + +*************** +*** 269,274 **** +--- 306,312 ---- + } + } + ++ /* Assumes that __objc_runtime_mutex is locked down. */ + static void + __objc_install_dispatch_table_for_class (Class class) + { +*************** +*** 289,295 **** +--- 327,335 ---- + /* Allocate dtable if necessary */ + if (super == 0) + { ++ objc_mutex_lock(__objc_runtime_mutex); + class->dtable = sarray_new (__objc_selector_max_index, 0); ++ objc_mutex_unlock(__objc_runtime_mutex); + } + else + class->dtable = sarray_lazy_copy (super->dtable); +*************** +*** 311,335 **** + void __objc_update_dispatch_table_for_class (Class class) + { + Class next; + + /* not yet installed -- skip it */ + if (class->dtable == __objc_uninstalled_dtable) + return; + +! sarray_free (class->dtable); /* release memory */ + __objc_install_premature_dtable (class); /* someone might require it... */ +! __objc_install_dispatch_table_for_class (class); /* could have been lazy... */ + + if (class->subclass_list) /* Traverse subclasses */ + for (next = class->subclass_list; next; next = next->sibling_class) + __objc_update_dispatch_table_for_class (next); + + } + + + /* This function adds a method list to a class. This function is + typically called by another function specific to the run-time. As +! such this function does not worry about thread safe issued. + + This one is only called for categories. Class objects have their + methods installed right away, and their selectors are made into +--- 351,382 ---- + void __objc_update_dispatch_table_for_class (Class class) + { + Class next; ++ struct sarray *arr; + + /* not yet installed -- skip it */ + if (class->dtable == __objc_uninstalled_dtable) + return; + +! objc_mutex_lock(__objc_runtime_mutex); +! +! arr = class->dtable; + __objc_install_premature_dtable (class); /* someone might require it... */ +! sarray_free (arr); /* release memory */ +! +! /* could have been lazy... */ +! __objc_install_dispatch_table_for_class (class); + + if (class->subclass_list) /* Traverse subclasses */ + for (next = class->subclass_list; next; next = next->sibling_class) + __objc_update_dispatch_table_for_class (next); + ++ objc_mutex_unlock(__objc_runtime_mutex); + } + + + /* This function adds a method list to a class. This function is + typically called by another function specific to the run-time. As +! such this function does not worry about thread safe issues. + + This one is only called for categories. Class objects have their + methods installed right away, and their selectors are made into +*************** +*** 338,344 **** + class_add_method_list (Class class, MethodList_t list) + { + int i; +! static SEL initialize_sel = 0; + if (!initialize_sel) + initialize_sel = sel_register_name ("initialize"); + +--- 385,392 ---- + class_add_method_list (Class class, MethodList_t list) + { + int i; +! static SEL initialize_sel = 0; /* !T:SAFE2 */ +! + if (!initialize_sel) + initialize_sel = sel_register_name ("initialize"); + +*************** +*** 414,420 **** + /* Given a linked list of method and a method's name. Search for the named + method's method structure. Return a pointer to the method's method + structure if found. NULL otherwise. */ +! static Method_t + search_for_method_in_list (MethodList_t list, SEL op) + { + MethodList_t method_list = list; +--- 462,468 ---- + /* Given a linked list of method and a method's name. Search for the named + method's method structure. Return a pointer to the method's method + structure if found. NULL otherwise. */ +! Method_t + search_for_method_in_list (MethodList_t list, SEL op) + { + MethodList_t method_list = list; +*************** +*** 447,452 **** +--- 495,501 ---- + + static retval_t __objc_forward (id object, SEL sel, arglist_t args); + ++ /* Forwarding pointers/integers through the normal registers */ + static id + __objc_word_forward (id rcv, SEL op, ...) + { +*************** +*** 460,465 **** +--- 509,529 ---- + return res; + } + ++ /* Specific routine for forwarding floats/double because of ++ architectural differences on some processors. i386s for ++ example which uses a floating point stack versus general ++ registers for floating point numbers. This forward routine ++ makes sure that GCC restores the proper return values */ ++ static double ++ __objc_double_forward (id rcv, SEL op, ...) ++ { ++ void *args, *res; ++ ++ args = __builtin_apply_args (); ++ res = __objc_forward (rcv, op, args); ++ __builtin_return (res); ++ } ++ + #if INVISIBLE_STRUCT_RETURN + static __big + #else +*************** +*** 482,488 **** + __objc_forward (id object, SEL sel, arglist_t args) + { + IMP imp; +! static SEL frwd_sel = 0; + SEL err_sel; + + /* first try if the object understands forward:: */ +--- 546,552 ---- + __objc_forward (id object, SEL sel, arglist_t args) + { + IMP imp; +! static SEL frwd_sel = 0; /* !T:SAFE2 */ + SEL err_sel; + + /* first try if the object understands forward:: */ +*************** +*** 526,539 **** + + /* The object doesn't respond to doesNotRecognize: or error:; Therefore, + a default action is taken. */ +! fprintf (stderr, "fatal: %s\n", msg); +! abort (); + } + } + + void __objc_print_dtable_stats() + { + int total = 0; + printf("memory usage: (%s)\n", + #ifdef OBJC_SPARSE2 + "2-level sparse arrays" +--- 590,605 ---- + + /* The object doesn't respond to doesNotRecognize: or error:; Therefore, + a default action is taken. */ +! objc_error (object, OBJC_ERR_UNIMPLEMENTED, "%s\n", msg); + } + } + + void __objc_print_dtable_stats() + { + int total = 0; ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ + printf("memory usage: (%s)\n", + #ifdef OBJC_SPARSE2 + "2-level sparse arrays" +*************** +*** 542,550 **** + #endif + ); + +! printf("arrays: %d = %ld bytes\n", narrays, (int)narrays*sizeof(struct sarray)); + total += narrays*sizeof(struct sarray); +! printf("buckets: %d = %ld bytes\n", nbuckets, (int)nbuckets*sizeof(struct sbucket)); + total += nbuckets*sizeof(struct sbucket); + + printf("idxtables: %d = %ld bytes\n", idxsize, (int)idxsize*sizeof(void*)); +--- 608,618 ---- + #endif + ); + +! printf("arrays: %d = %ld bytes\n", narrays, +! (int)narrays*sizeof(struct sarray)); + total += narrays*sizeof(struct sarray); +! printf("buckets: %d = %ld bytes\n", nbuckets, +! (int)nbuckets*sizeof(struct sbucket)); + total += nbuckets*sizeof(struct sbucket); + + printf("idxtables: %d = %ld bytes\n", idxsize, (int)idxsize*sizeof(void*)); +*************** +*** 552,558 **** + printf("-----------------------------------\n"); + printf("total: %d bytes\n", total); + printf("===================================\n"); +- } +- + + +--- 620,633 ---- + printf("-----------------------------------\n"); + printf("total: %d bytes\n", total); + printf("===================================\n"); + ++ objc_mutex_unlock(__objc_runtime_mutex); ++ } + ++ /* Returns the dispatch table */ ++ __inline__ ++ struct sarray* ++ objc_get_uninstalled_dtable() ++ { ++ return __objc_uninstalled_dtable; ++ } +diff -rcP gcc-2.7.2/objc/thr-decosf1.c gcc-2.7.2.1-objc-960906/objc/thr-decosf1.c +*** gcc-2.7.2/objc/thr-decosf1.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-decosf1.c Fri Sep 6 10:33:35 1996 +*************** +*** 0 **** +--- 1,326 ---- ++ /* GNU Objective C Runtime Thread Interface ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */ ++ ++ /* 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 ++ #include ++ #include "runtime.h" ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ pthread_mutex_t lock; /* pthread mutex. */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ static pthread_key_t __objc_thread_data_key; /* Data key for thread data.*/ ++ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ printf("__objc_init_thread_system\n"); ++ ++ if (pthread_keycreate(&__objc_thread_data_key, NULL) == 0) ++ return 0; /* Yes, return success. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id = NULL; /* Detached thread id. */ ++ pthread_t new_thread_handle; /* DCE thread handle. */ ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ if (pthread_create(&new_thread_handle, pthread_attr_default, ++ (void *)func, arg) == 0) { ++ /* ??? May not work! (64bit)*/ ++ thread_id = *(objc_thread_t *)&new_thread_handle; ++ pthread_detach(&new_thread_handle); /* Fully detach thread. */ ++ __objc_runtime_threads_alive++; ++ } ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ int sys_priority = 0; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2; ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; ++ break; ++ } ++ ++ if (pthread_setprio(pthread_self(), sys_priority) >= 0) ++ return 0; /* Changed priority. End. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ int sys_priority; /* DCE thread priority. */ ++ ++ if ((sys_priority = pthread_getprio(pthread_self())) >= 0) { ++ if (sys_priority >= PRI_FG_MIN_NP && sys_priority <= PRI_FG_MAX_NP) ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; ++ if (sys_priority >= PRI_BG_MIN_NP && sys_priority <= PRI_BG_MAX_NP) ++ return OBJC_THREAD_BACKGROUND_PRIORITY; ++ return OBJC_THREAD_LOW_PRIORITY; ++ } ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ pthread_yield(); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ pthread_exit(&__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * -1 which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ pthread_t self = pthread_self(); ++ ++ return (objc_thread_t) pthread_getuniqe_np (&self); ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ if (pthread_setspecific(__objc_thread_data_key, (void *)value) == 0) ++ return 0; /* Return thread data. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ void * value = NULL; ++ ++ if (pthread_getspecific(__objc_thread_data_key, (void *)&value) == 0) ++ return value; /* Return thread data. */ ++ ++ return NULL; ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if ++ * the allocation fails for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ err = pthread_mutex_init(&mutex->lock, pthread_mutexattr_default); ++ ++ if (err != 0) { /* System init failed? */ ++ objc_free(mutex); /* Yes, free local memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = (objc_thread_t) -1; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ pthread_mutex_unlock(&mutex->lock); /* Must unlock system mutex.*/ ++ pthread_mutex_destroy(&mutex->lock); /* Free system mutex. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (pthread_mutex_lock(&mutex->lock) != 0) /* Lock DCE system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (pthread_mutex_trylock(&mutex->lock) != 1) /* Lock DCE system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/ ++ ++ if (pthread_mutex_unlock(&mutex->lock) != 0) /* Unlock system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2/objc/thr-irix.c gcc-2.7.2.1-objc-960906/objc/thr-irix.c +*** gcc-2.7.2/objc/thr-irix.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-irix.c Fri Sep 6 10:33:35 1996 +*************** +*** 0 **** +--- 1,314 ---- ++ /* GNU Objective C Runtime Thread Interface - SGI IRIX Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */ ++ ++ /* 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 ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include "runtime.h" ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ ulock_t lock; /* Irix lock. */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ static void * __objc_shared_arena_handle = NULL; /* Storage arena locks. */ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ char arena_name[64]; /* Name of IRIX arena. */ ++ ++ DEBUG_PRINTF("__objc_init_thread_system\n"); ++ sprintf(arena_name, "/usr/tmp/objc_%05u", (unsigned)getpid()); ++ usconfig(CONF_INITUSERS, 256); /* Up to 256 threads. */ ++ usconfig(CONF_ARENATYPE, US_SHAREDONLY); /* Arena only for threads. */ ++ if (!(__objc_shared_arena_handle = usinit(arena_name))) /* Init Failed? */ ++ return -1; /* Yes, return error code. */ ++ ++ return 0; ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id = NULL; ++ int sys_id; ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ if ((sys_id = sproc((void *)func, PR_SALL, arg)) >= 0) { ++ thread_id = (objc_thread_t)sys_id; ++ __objc_runtime_threads_alive++; ++ } ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ int sys_priority = 0; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ break; ++ } ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ sginap(0); /* Yield to equal process. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ exit(__objc_thread_exit_status); /* IRIX only has exit. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * NULL which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ return (objc_thread_t)get_pid(); /* Threads are processes. */ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ *((void **)&PRDA->usr_prda) = value; /* Set thread data ptr. */ ++ return 0; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return *((void **)&PRDA->usr_prda); /* Return thread data ptr. */ ++ } ++ ++ /******** ++ * Allocate a mutex. ++ * Return the mutex pointer if successful or NULL if the allocation failed ++ * for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ if (!(mutex->lock = usnewlock(__objc_shared_arena_handle))) ++ err = -1; ++ ++ if (err != 0) { /* System init failed? */ ++ objc_free(mutex); /* Yes, free local memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ usfreelock(mutex->lock, __objc_shared_arena_handle); /* Free IRIX lock. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) { /* Already own lock? */ ++ DEBUG_PRINTF("lock owned by: %d:%d\n", mutex->owner, mutex->depth); ++ return ++mutex->depth; /* Yes, increment depth. */ ++ } ++ ++ DEBUG_PRINTF("lock owned by: %d:%d (attempt by %d)\n", ++ mutex->owner, mutex->depth, thread_id); ++ ++ if (ussetlock(mutex->lock) == 0) /* Did lock acquire fail? */ ++ return -1; /* Yes, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (ustestlock(mutex->lock) == 0) /* Did lock acquire fail? */ ++ return -1; /* Yes, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ ++ DEBUG_PRINTF("unlock by: %d:%d\n", mutex->owner, mutex->depth - 1); ++ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ usunsetlock(mutex->lock); /* Free lock. */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2/objc/thr-mach.c gcc-2.7.2.1-objc-960906/objc/thr-mach.c +*** gcc-2.7.2/objc/thr-mach.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-mach.c Fri Sep 6 10:33:36 1996 +*************** +*** 0 **** +--- 1,465 ---- ++ /* GNU Objective C Runtime Thread Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ ++ Author: Galen C. Hunt (gchunt@cs.rochester.edu) ++ Modified for Mach threads by: Bill Bumgarner ++ Condition functions added by: Mircea Oancea ++ ++ 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 ++ #include ++ #include ++ #include "runtime.h" ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ struct mutex lock; /* cthread mutex */ ++ }; ++ ++ struct objc_condition ++ { ++ struct condition condition; /* cthread condition */ ++ }; ++ ++ /******** ++ * obtain the maximum thread priority that can set for t. Under the ++ * mach threading model, it is possible for the developer to adjust the ++ * maximum priority downward only-- cannot be raised without superuser ++ * priviledges. Once lowered, it cannot be raised. ++ */ ++ static int __mach_get_max_thread_priority(cthread_t t, int *base) { ++ thread_t threadP; ++ kern_return_t error; ++ struct thread_sched_info info; ++ unsigned int info_count=THREAD_SCHED_INFO_COUNT; ++ ++ if (t == NULL) ++ return -1; ++ ++ threadP = cthread_thread(t); /* get thread underlying */ ++ ++ error=thread_info(threadP, THREAD_SCHED_INFO, ++ (thread_info_t)&info, &info_count); ++ ++ if (error != KERN_SUCCESS) ++ return -1; ++ ++ if (base != NULL) ++ *base = info.base_priority; ++ ++ return info.max_priority; ++ } ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ DEBUG_PRINTF("__objc_init_thread_system\n"); ++ return 0; /* Succeeded. */ ++ } ++ ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id = NULL; /* Detached thread id. */ ++ cthread_t new_thread_handle; /* cthread handle. */ ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ /* create thread */ ++ new_thread_handle = cthread_fork((cthread_fn_t)func, arg); ++ ++ if(new_thread_handle) { ++ /* this is not terribly portable */ ++ thread_id = *(objc_thread_t *)&new_thread_handle; ++ cthread_detach(new_thread_handle); /* fully detach thread */ ++ __objc_runtime_threads_alive++; /* increment thread count */ ++ } ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ objc_thread_t *t = objc_thread_id(); ++ cthread_t cT = (cthread_t) t; ++ int maxPriority = __mach_get_max_thread_priority(cT, NULL); ++ int sys_priority = 0; ++ ++ if (maxPriority == -1) ++ return -1; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_priority = maxPriority; ++ break; ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_priority = (maxPriority * 2) / 3; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_priority = maxPriority / 3; ++ break; ++ default: ++ return -1; ++ } ++ ++ if (sys_priority == 0) ++ return -1; ++ ++ if (cthread_priority(cT, sys_priority, 0) == KERN_SUCCESS) ++ return 0; /* Changed priority. End. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority [well, whatever it is closest to]. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ objc_thread_t *t = objc_thread_id(); ++ cthread_t cT = (cthread_t) t; /* see objc_thread_id() */ ++ int basePriority; ++ int maxPriority; ++ int sys_priority = 0; ++ ++ int interactiveT, backgroundT, lowT; /* threasholds */ ++ ++ maxPriority = __mach_get_max_thread_priority(cT, &basePriority); ++ ++ if(maxPriority == -1) ++ return -1; ++ ++ if (basePriority > ( (maxPriority * 2) / 3)) ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; /* interactive priority ++ */ ++ if (basePriority > ( maxPriority / 3)) ++ return OBJC_THREAD_BACKGROUND_PRIORITY; /* background priority ++ */ ++ return OBJC_THREAD_LOW_PRIORITY; /* everything else is low */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ cthread_yield(); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ cthread_exit(&__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * NULL which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ cthread_t self = cthread_self(); ++ return (objc_thread_t)self; ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ ++ int ++ objc_thread_set_data(void *value) ++ { ++ cthread_set_data(cthread_self(), (any_t) value); ++ return 0; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return (void *) cthread_data(cthread_self()); ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if the ++ * allocation failed for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ err = mutex_init(&(mutex->lock)); ++ ++ if (err != 0) { /* System init failed? */ ++ objc_free(mutex); /* Yes, free local memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = (objc_thread_t) -1; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallocate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ mutex_unlock(&(mutex->lock)); /* Must unlock system mutex.*/ ++ mutex_clear(&(mutex->lock)); /* Free system mutex. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ mutex_lock(&(mutex->lock)); /* Lock cthread mutex. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (mutex_try_lock(&(mutex->lock)) == 0) /* Lock cthread mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/ ++ ++ mutex_unlock(&(mutex->lock)); /* unlock cthread mutex. */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /******** ++ * Allocate a condition. Return the condition pointer if successful or NULL ++ * if the allocation failed for any reason. ++ */ ++ objc_condition_t ++ objc_condition_allocate(void) ++ { ++ objc_condition_t condition; ++ ++ if (!(condition = (objc_condition_t)objc_malloc( ++ sizeof(struct objc_condition)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ condition_init(&(condition->condition)); ++ ++ return condition; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a condition. Note that this includes an implicit ++ * condition_broadcast to insure that waiting threads have the opportunity ++ * to wake. It is legal to dealloc a condition only if no other ++ * thread is/will be using it. Here we do NOT check for other threads ++ * waiting but just wake them up. ++ */ ++ int ++ objc_condition_deallocate(objc_condition_t condition) ++ { ++ condition_broadcast(&(condition->condition)); ++ condition_clear(&(condition->condition)); ++ objc_free(condition); ++ return 0; ++ } ++ ++ /******** ++ * Wait on the condition unlocking the mutex until objc_condition_signal() ++ * or objc_condition_broadcast() are called for the same condition. The ++ * given mutex *must* have the depth set to 1 so that it can be unlocked ++ * here, so that someone else can lock it and signal/broadcast the condition. ++ * The mutex is used to lock access to the shared data that make up the ++ * "condition" predicate. ++ */ ++ int ++ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex || !condition) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Locked more than once ? */ ++ return -1; /* YES, return error */ ++ /* mutex will be unlocked */ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/ ++ ++ condition_wait(&(condition->condition), ++ &(mutex->lock)); /* unlock, wait ..., lock */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ mutex->depth = 1; /* Increment depth to end. */ ++ return 0; /* Return success. */ ++ } ++ ++ /******** ++ * Wake up all threads waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_broadcast(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ condition_broadcast(&(condition->condition)); ++ return 0; ++ } ++ ++ /******** ++ * Wake up one thread waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_signal(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ condition_signal(&(condition->condition)); ++ return 0; ++ } ++ +diff -rcP gcc-2.7.2/objc/thr-os2.c gcc-2.7.2.1-objc-960906/objc/thr-os2.c +*** gcc-2.7.2/objc/thr-os2.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-os2.c Fri Sep 6 10:33:36 1996 +*************** +*** 0 **** +--- 1,342 ---- ++ /* GNU Objective C Runtime Thread Interface - OS/2 emx Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ ++ Author: Thomas Baier (baier@ci.tuwien.ac.at) ++ ++ 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 ++ #include "runtime.h" ++ ++ #define INCL_DOSSEMAPHORES ++ #define INCL_DOSPROCESS ++ ++ /* ++ * conflicts with objc.h: SEL, BOOL, id ++ * solution: prefixing those with _OS2_ before including ++ */ ++ #define SEL _OS2_SEL ++ #define BOOL _OS2_BOOL ++ #define id _OS2_id ++ #include ++ #undef id ++ #undef SEL ++ #undef BOOL ++ ++ #include ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ HMTX handle; /* OS/2 mutex HANDLE. */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ /* none needed for OS/2 */ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ DEBUG_PRINTF("__objc_init_thread_system (os2-emx)\n"); ++ ++ /* no initialization of thread subsystem */ ++ return 0; /* Yes, return success. */ ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ /* no termination code for thread subsystem */ ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ int thread_id = 0; /* id of the newly created thread */ ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ /* create a thread calling "func", args "arg", stack size 32768 bytes */ ++ if ((thread_id = _beginthread (func,NULL,32768,arg)) < 0) ++ thread_id = 0; ++ else ++ __objc_runtime_threads_alive++; ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ return (objc_thread_t)thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ ULONG sys_class = 0; ++ ULONG sys_priority = 0; ++ ++ /* OBJC_THREAD_INTERACTIVE_PRIORITY -> PRTYC_FOREGROUNDSERVER ++ * OBJC_THREAD_BACKGROUND_PRIORITY -> PRTYC_REGULSR ++ * OBJC_THREAD_LOW_PRIORITY -> PRTYC_IDLETIME */ ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_class = PRTYC_REGULAR; ++ sys_priority = 10; ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_class = PRTYC_IDLETIME; ++ sys_priority = 25; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_class = PRTYC_IDLETIME; ++ sys_priority = 0; ++ break; ++ } ++ if (!DosSetPriority (PRTYS_THREAD,sys_class,sys_priority,*_threadid)) ++ return 0; /* Changed priority. End. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ PTIB ptib; ++ PPIB ppib; ++ ++ DosGetInfoBlocks (&ptib,&ppib); /* get information about current thread */ ++ ++ switch (ptib->tib_ptib2->tib2_ulpri) { ++ case PRTYC_IDLETIME: ++ case PRTYC_REGULAR: ++ case PRTYC_TIMECRITICAL: ++ case PRTYC_FOREGROUNDSERVER: ++ default: ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; ++ } ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ DosSleep (0); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ _endthread (); /* terminate the thread, NEVER use DosExit () */ ++ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * -1 which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ return (objc_thread_t) *_threadid; /* Return thread id. */ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ *_threadstore () = value; ++ ++ return 0; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return *_threadstore (); ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if ++ * the allocation fails for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ if (DosCreateMutexSem (NULL,&(mutex->handle),0L,0) > 0) { ++ objc_free(mutex); ++ return NULL; ++ } ++ ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ DosCloseMutexSem (mutex->handle); ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (DosRequestMutexSem (mutex->handle,-1L) != 0) ++ return -1; ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ ++ return ++mutex->depth; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (DosRequestMutexSem (mutex->handle,0L) != 0) ++ return -1; ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return ++mutex->depth; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ if (DosReleaseMutexSem(mutex->handle) != 0) ++ return -1; /* Failed, abort. */ ++ ++ return 0; /* No, return success. */ ++ } +diff -rcP gcc-2.7.2/objc/thr-posix.c gcc-2.7.2.1-objc-960906/objc/thr-posix.c +*** gcc-2.7.2/objc/thr-posix.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-posix.c Fri Sep 6 10:33:36 1996 +*************** +*** 0 **** +--- 1,323 ---- ++ /* GNU Objective C Runtime Thread Interface for POSIX compliant threads ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ ++ Author: Galen C. Hunt (gchunt@cs.rochester.edu) ++ Modified for Linux & Pthreads: Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de) ++ ++ 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 ++ #include "runtime.h" ++ #include ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ pthread_mutex_t lock; /* pthread mutex. */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ static pthread_key_t __objc_thread_data_key; /* Data key for thread data.*/ ++ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ if (pthread_key_create(&__objc_thread_data_key, NULL) == 0) ++ return 0; /* Yes, return success. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id = NULL; /* Detached thread id. */ ++ pthread_t new_thread_handle; /* DCE thread handle. */ ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ if (pthread_create(&new_thread_handle, NULL, ++ (void *)func, arg) == 0) { ++ thread_id = (objc_thread_t) new_thread_handle; ++ pthread_detach(new_thread_handle); /* Fully detach thread. */ ++ __objc_runtime_threads_alive++; ++ } ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ #if 0 /* no get/set priority in Linux pthreads */ ++ ++ int sys_priority = 0; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2; ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; ++ break; ++ } ++ ++ if (pthread_setprio(pthread_self(), sys_priority) >= 0) ++ return 0; /* Changed priority. End. */ ++ ++ #endif ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ #if 0 /* no get/set priority in Linux pthreads */ ++ int sys_priority; /* DCE thread priority. */ ++ ++ if ((sys_priority = pthread_getprio(pthread_self())) >= 0) { ++ if (sys_priority >= PRI_FG_MIN_NP && sys_priority <= PRI_FG_MAX_NP) ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; ++ if (sys_priority >= PRI_BG_MIN_NP && sys_priority <= PRI_BG_MAX_NP) ++ return OBJC_THREAD_BACKGROUND_PRIORITY; ++ return OBJC_THREAD_LOW_PRIORITY; ++ } ++ #endif ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ pthread_yield(); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ pthread_exit(&__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * -1 which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ pthread_t self = pthread_self(); ++ ++ return (objc_thread_t) self; /* Return thread handle. */ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ if (pthread_setspecific(__objc_thread_data_key, (void *)value) == 0) ++ return 0; /* Return thread data. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return pthread_getspecific(__objc_thread_data_key); ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if ++ * the allocation fails for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ err = pthread_mutex_init(&mutex->lock, NULL); ++ ++ if (err != 0) { /* System init failed? */ ++ objc_free(mutex); /* Yes, free local memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ pthread_mutex_unlock(&mutex->lock); /* Must unlock system mutex.*/ ++ pthread_mutex_destroy(&mutex->lock); /* Free system mutex. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (pthread_mutex_lock(&mutex->lock) != 0) /* Lock DCE system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (pthread_mutex_trylock(&mutex->lock) != 1) /* Lock DCE system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ if (pthread_mutex_unlock(&mutex->lock) != 0) /* Unlock system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ return 0; /* No, return success. */ ++ } +diff -rcP gcc-2.7.2/objc/thr-pthreads.c gcc-2.7.2.1-objc-960906/objc/thr-pthreads.c +*** gcc-2.7.2/objc/thr-pthreads.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-pthreads.c Fri Sep 6 10:33:37 1996 +*************** +*** 0 **** +--- 1,422 ---- ++ /* GNU Objective C Runtime Thread Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ ++ This implementation is for the PCThreads package under Linux. ++ ++ Author: Scott Christley ++ Condition functions added by: Mircea Oancea ++ ++ 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 ++ #include ++ #include "runtime.h" ++ ++ /* Key structure for maintiain thread specific storage */ ++ static pthread_key_t _objc_thread_storage; ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ pthread_mutex_t mutex; /* PCThread mutex */ ++ }; ++ ++ struct objc_condition ++ { ++ pthread_cond_t condition; /* cthread condition */ ++ }; ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ /* Initialize the thread storage key */ ++ return pthread_key_create(&_objc_thread_storage, NULL); ++ } ++ ++ /******** ++ * Finalize the threads subsystem. Returns 0 if successful, or -1 if not ++ */ ++ int ++ __objc_fini_thread_system(void) ++ { ++ /* Destroy the thread storage key */ ++ /* Not implemented yet */ ++ /* return pthread_key_delete(&_objc_thread_storage); */ ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id; ++ pthread_t new_thread_handle; ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) ) ++ { ++ thread_id = *(objc_thread_t *)&new_thread_handle; ++ __objc_runtime_threads_alive++; ++ } ++ else ++ thread_id = NULL; ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ /* Not implemented yet */ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ /* Not implemented yet */ ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; /* Highest priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ pthread_yield(NULL); ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ pthread_exit(&__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * NULL which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ pthread_t self = pthread_self(); ++ ++ return *(objc_thread_t *)&self; /* Return thread handle. */ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ return pthread_setspecific(_objc_thread_storage, value); ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ void *value = NULL; ++ ++ if ( !(pthread_getspecific(_objc_thread_storage, &value)) ) ++ return value; ++ ++ return NULL; ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if the ++ * allocation failed for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ /* Create PCThread mutex */ ++ if ( pthread_mutex_init(&(mutex->mutex), NULL) ) ++ { ++ /* Failed */ ++ objc_free(mutex); ++ return NULL; ++ } ++ ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallocate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ /* Destroy PCThread mutex */ ++ pthread_mutex_destroy(&(mutex->mutex)); ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ int status; ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ { ++ return ++mutex->depth; /* Yes, increment depth. */ ++ } ++ ++ /* Lock the PCThread mutex */ ++ status = pthread_mutex_lock(&(mutex->mutex)); ++ if (status) ++ { ++ return status; /* Failed */ ++ } ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ int status; ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ /* Lock the PCThread mutex */ ++ status = pthread_mutex_trylock(&(mutex->mutex)); ++ if (status) ++ return status; /* Failed */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ int status; ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ /* Unlock the PCThread mutex */ ++ status = pthread_mutex_unlock(&(mutex->mutex)); ++ if (status) ++ return status; /* Failed */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /******** ++ * Allocate a condition. Return the condition pointer if successful or NULL ++ * if the allocation failed for any reason. ++ */ ++ objc_condition_t ++ objc_condition_allocate(void) ++ { ++ objc_condition_t condition; ++ ++ if (!(condition = (objc_condition_t)objc_malloc( ++ sizeof(struct objc_condition)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ if ( pthread_cond_init(&(condition->condition), NULL) ) { ++ objc_free(condition); ++ return NULL; ++ } ++ ++ return condition; /* Return condition handle. */ ++ } ++ ++ /******** ++ * Deallocate a condition. Note that this includes an implicit ++ * condition_broadcast to insure that waiting threads have the opportunity ++ * to wake. It is legal to dealloc a condition only if no other ++ * thread is/will be using it. Here we do NOT check for other threads ++ * waiting but just wake them up. ++ */ ++ int ++ objc_condition_deallocate(objc_condition_t condition) ++ { ++ pthread_cond_broadcast(&(condition->condition)); ++ pthread_cond_destroy(&(condition->condition)); ++ objc_free(condition); ++ return 0; ++ } ++ ++ /******** ++ * Wait on the condition unlocking the mutex until objc_condition_signal() ++ * or objc_condition_broadcast() are called for the same condition. The ++ * given mutex *must* have the depth set to 1 so that it can be unlocked ++ * here, so that someone else can lock it and signal/broadcast the condition. ++ * The mutex is used to lock access to the shared data that make up the ++ * "condition" predicate. ++ */ ++ int ++ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex || !condition) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Locked more than once ? */ ++ return -1; /* YES, return error */ ++ /* mutex will be unlocked */ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/ ++ ++ pthread_cond_wait(&(condition->condition), ++ &(mutex->mutex)); /* unlock, wait ..., lock */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ mutex->depth = 1; /* Increment depth to end. */ ++ return 0; /* Return success. */ ++ } ++ ++ /******** ++ * Wake up all threads waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_broadcast(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ pthread_cond_broadcast(&(condition->condition)); ++ return 0; ++ } ++ ++ /******** ++ * Wake up one thread waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_signal(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ pthread_cond_signal(&(condition->condition)); ++ return 0; ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2/objc/thr-single.c gcc-2.7.2.1-objc-960906/objc/thr-single.c +*** gcc-2.7.2/objc/thr-single.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-single.c Fri Sep 6 10:33:37 1996 +*************** +*** 0 **** +--- 1,240 ---- ++ /* GNU Objective C Runtime Thread Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */ ++ ++ /* 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 ++ #include "runtime.h" ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ }; ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ DEBUG_PRINTF("__objc_init_thread_system\n"); ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ return NULL; /* We can't start threads. */ ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; /* Highest priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ return; ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ exit(__objc_thread_exit_status); ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * NULL which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ return (objc_thread_t)1; /* No thread support, use 1.*/ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ ++ static void *thread_local_storage = NULL; ++ ++ int ++ objc_thread_set_data(void *value) ++ { ++ thread_local_storage = value; ++ return 0; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return thread_local_storage; ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if the ++ * allocation failed for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallocate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2/objc/thr-solaris.c gcc-2.7.2.1-objc-960906/objc/thr-solaris.c +*** gcc-2.7.2/objc/thr-solaris.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-solaris.c Fri Sep 6 10:33:37 1996 +*************** +*** 0 **** +--- 1,431 ---- ++ /* GNU Objective C Runtime Thread Interface ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.edu) ++ Conditions added by Mircea Oancea (mircea@first.elcom.pub.ro) ++ ++ 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 ++ #include "runtime.h" ++ ++ #include ++ #include ++ #include ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ mutex_t lock; /* System mutex. */ ++ }; ++ ++ struct objc_condition ++ { ++ cond_t condition; /* solaris condition */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ static thread_key_t __objc_thread_data_key; /* Data key for thread data.*/ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ DEBUG_PRINTF("__objc_init_thread_system\n"); ++ ++ if (thr_keycreate(&__objc_thread_data_key, NULL) == 0) ++ return 0; /* Yes, return success. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return -1 if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id = NULL; /* Detached thread id. */ ++ thread_t new_thread_id = 0; /* Solaris thread id type. */ ++ int errn; ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ if (thr_create(NULL, 0, (void *)func, arg, ++ THR_DETACHED | THR_NEW_LWP, ++ &new_thread_id) == 0) { /* Created new thread? */ ++ thread_id = (objc_thread_t)new_thread_id; /* Yes, remember its id. */ ++ __objc_runtime_threads_alive++; ++ } ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ int sys_priority = 0; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_priority = 300; ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_priority = 200; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_priority = 1000; ++ break; ++ } ++ ++ if (thr_setprio(thr_self(), sys_priority) == 0) ++ return 0; /* Changed priority. End. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ int sys_priority; /* Solaris thread priority. */ ++ ++ if (thr_getprio(thr_self(), &sys_priority) == 0) { ++ if (sys_priority >= 250) ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; ++ else if (sys_priority >= 150) ++ return OBJC_THREAD_BACKGROUND_PRIORITY; ++ return OBJC_THREAD_LOW_PRIORITY; ++ } ++ ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ thr_yield(); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive++; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ thr_exit(&__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * NULL which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ return (objc_thread_t)thr_self(); ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ if (thr_setspecific(__objc_thread_data_key, value) == 0) ++ return 0; ++ return -1; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ void * value = NULL; ++ ++ if (thr_getspecific(__objc_thread_data_key, &value) == 0) ++ return value; /* Return thread data. */ ++ ++ return NULL; ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if ++ * the allocation fails for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ struct objc_mutex *mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ err = mutex_init(&mutex->lock, USYNC_THREAD, 0); ++ ++ if (err != 0) { /* System init failed? */ ++ objc_free(mutex); /* Yes, free local memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ mutex_destroy(&mutex->lock); /* System deallocate. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (mutex_lock(&mutex->lock) != 0) /* Did lock acquire fail? */ ++ return -1; /* Yes, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (mutex_trylock(&mutex->lock) != 0) /* Did lock acquire fail? */ ++ return -1; /* Yes, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ if (mutex_unlock(&mutex->lock) != 0) /* Did lock release fail? */ ++ return -1; /* Yes, return error value. */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /******** ++ * Allocate a condition. Return the condition pointer if successful or NULL ++ * if the allocation failed for any reason. ++ */ ++ objc_condition_t ++ objc_condition_allocate(void) ++ { ++ objc_condition_t condition; ++ ++ if (!(condition = (objc_condition_t)objc_malloc( ++ sizeof(struct objc_condition)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ cond_init(&(condition->condition), USYNC_THREAD, NULL); ++ ++ return condition; /* Return new condition */ ++ } ++ ++ /******** ++ * Deallocate a condition. Note that this includes an implicit ++ * condition_broadcast to insure that waiting threads have the opportunity ++ * to wake. It is legal to dealloc a condition only if no other ++ * thread is/will be using it. Here we do NOT check for other threads ++ * waiting but just wake them up. ++ */ ++ int ++ objc_condition_deallocate(objc_condition_t condition) ++ { ++ cond_broadcast(&(condition->condition)); /* Wakeup waiting threads */ ++ cond_destroy(&(condition->condition)); /* Kill condition */ ++ objc_free(condition); /* Release struct memory */ ++ return 0; ++ } ++ ++ /******** ++ * Wait on the condition unlocking the mutex until objc_condition_signal() ++ * or objc_condition_broadcast() are called for the same condition. The ++ * given mutex *must* have the depth set to 1 so that it can be unlocked ++ * here, so that someone else can lock it and signal/broadcast the condition. ++ * The mutex is used to lock access to the shared data that make up the ++ * "condition" predicate. ++ */ ++ int ++ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex || !condition) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Locked more than once ? */ ++ return -1; /* YES, return error */ ++ /* mutex will be unlocked */ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/ ++ ++ cond_wait(&(condition->condition), ++ &(mutex->lock)); /* unlock, wait ..., lock */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ mutex->depth = 1; /* Must be here ! */ ++ ++ return 0; /* Return success. */ ++ } ++ ++ /******** ++ * Wake up all threads waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_broadcast(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ cond_broadcast(&(condition->condition)); ++ return 0; ++ } ++ ++ /******** ++ * Wake up one thread waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_signal(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ cond_signal(&(condition->condition)); ++ return 0; ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2/objc/thr-win32.c gcc-2.7.2.1-objc-960906/objc/thr-win32.c +*** gcc-2.7.2/objc/thr-win32.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-win32.c Fri Sep 6 10:33:38 1996 +*************** +*** 0 **** +--- 1,337 ---- ++ /* GNU Objective C Runtime Thread Interface - Win32 Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */ ++ ++ /* 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 ++ #include "runtime.h" ++ ++ #ifndef __OBJC__ ++ #define __OBJC__ ++ #endif ++ #include ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ HANDLE handle; /* Win32 mutex HANDLE. */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ static DWORD __objc_data_tls = (DWORD)-1; /* Win32 Thread Local Index.*/ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ DEBUG_PRINTF("__objc_init_thread_system\n"); ++ ++ if ((__objc_data_tls = TlsAlloc()) != (DWORD)-1) ++ return 0; /* Yes, return success. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ if (__objc_data_tls != (DWORD)-1) { ++ TlsFree(__objc_data_tls); ++ return 0; ++ } ++ return -1; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ DWORD thread_id = 0; /* Detached thread id. */ ++ HANDLE win32_handle; /* Win32 thread handle. */ ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ if ((win32_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, ++ arg, 0, &thread_id))) { ++ __objc_runtime_threads_alive++; ++ } ++ else ++ thread_id = 0; ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ return (objc_thread_t)thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ int sys_priority = 0; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_priority = THREAD_PRIORITY_NORMAL; ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_priority = THREAD_PRIORITY_BELOW_NORMAL; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_priority = THREAD_PRIORITY_LOWEST; ++ break; ++ } ++ if (SetThreadPriority(GetCurrentThread(), sys_priority)) ++ return 0; /* Changed priority. End. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ int sys_priority; ++ ++ sys_priority = GetThreadPriority(GetCurrentThread()); ++ ++ switch (sys_priority) { ++ case THREAD_PRIORITY_HIGHEST: ++ case THREAD_PRIORITY_TIME_CRITICAL: ++ case THREAD_PRIORITY_ABOVE_NORMAL: ++ case THREAD_PRIORITY_NORMAL: ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; ++ ++ default: ++ case THREAD_PRIORITY_BELOW_NORMAL: ++ return OBJC_THREAD_BACKGROUND_PRIORITY; ++ ++ case THREAD_PRIORITY_IDLE: ++ case THREAD_PRIORITY_LOWEST: ++ return OBJC_THREAD_LOW_PRIORITY; ++ } ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ Sleep(0); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ ExitThread(__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * -1 which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ return (objc_thread_t)GetCurrentThreadId(); /* Return thread id. */ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ if (TlsSetValue(__objc_data_tls, value)) ++ return 0; /* Return thread data. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return TlsGetValue(__objc_data_tls); /* Return thread data. */ ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if ++ * the allocation fails for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ if ((mutex->handle = CreateMutex(NULL, 0, NULL)) == NULL) { ++ objc_free(mutex); /* Failed, free memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ CloseHandle(mutex->handle); /* Close Win32 handle. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ int status; ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ status = WaitForSingleObject(mutex->handle, INFINITE); ++ if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED) ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ ++ return ++mutex->depth; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ DWORD status; /* Return status from Win32.*/ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ status = WaitForSingleObject(mutex->handle, 0); ++ if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED) ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return ++mutex->depth; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ if (ReleaseMutex(mutex->handle) == 0) ++ return -1; /* Failed, abort. */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2/objc/thr.c gcc-2.7.2.1-objc-960906/objc/thr.c +*** gcc-2.7.2/objc/thr.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr.c Fri Sep 6 10:33:38 1996 +*************** +*** 0 **** +--- 1,153 ---- ++ /* GNU Objective C Runtime Thread Interface ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */ ++ ++ /* 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 ++ #include "runtime.h" ++ ++ /************************************************************************* ++ * Universal static variables: ++ */ ++ int __objc_thread_exit_status = 0; /* Global exit status. */ ++ ++ /* Flag which lets us know if we ever became multi threaded */ ++ int __objc_is_multi_threaded = 0; ++ /* The hook function called when the runtime becomes multi threaded */ ++ objc_thread_callback _objc_became_multi_threaded = NULL; ++ ++ /***************************************************************************** ++ * Universal Functionality ++ */ ++ ++ /* ++ Use this to set the hook function that will be called when the ++ runtime initially becomes multi threaded. ++ The hook function is only called once, meaning only when the ++ 2nd thread is spawned, not for each and every thread. ++ ++ It returns the previous hook function or NULL if there is none. ++ ++ A program outside of the runtime could set this to some function so ++ it can be informed; for example, the GNUstep Base Library sets it ++ so it can implement the NSBecomingMultiThreaded notification. ++ */ ++ objc_thread_callback objc_set_thread_callback(objc_thread_callback func) ++ { ++ objc_thread_callback temp = _objc_became_multi_threaded; ++ _objc_became_multi_threaded = func; ++ return temp; ++ } ++ ++ /******** ++ * First function called in a thread, starts everything else. ++ */ ++ struct __objc_thread_start_state ++ { ++ SEL selector; ++ id object; ++ id argument; ++ }; ++ ++ static volatile void ++ __objc_thread_detach_function(struct __objc_thread_start_state *istate) ++ { ++ if (istate) { /* Is state valid? */ ++ id (*imp)(id,SEL,id); ++ SEL selector = istate->selector; ++ id object = istate->object; ++ id argument = istate->argument; ++ ++ objc_free(istate); ++ ++ /* Clear out the thread local storage */ ++ objc_thread_set_data(NULL); ++ ++ /* Check to see if we just became multi threaded */ ++ if (!__objc_is_multi_threaded) { ++ __objc_is_multi_threaded = 1; ++ ++ /* Call the hook function */ ++ if (_objc_became_multi_threaded != NULL) ++ (*_objc_became_multi_threaded)(); ++ } ++ ++ if ((imp = (id(*)(id, SEL, id))objc_msg_lookup(object, selector))) { ++ (*imp)(object, selector, argument); ++ } ++ else ++ fprintf(stderr, "__objc_thread_start called with bad selector.\n"); ++ } ++ else { ++ fprintf(stderr, "__objc_thread_start called with NULL state.\n"); ++ } ++ objc_thread_exit(); ++ } ++ ++ /******** ++ * Detach a new thread of execution and return its id. Returns NULL if fails. ++ * Thread is started by sending message with selector to object. Message ++ * takes a single argument. ++ */ ++ objc_thread_t ++ objc_thread_detach(SEL selector, id object, id argument) ++ { ++ struct __objc_thread_start_state *istate; /* Initialial thread state. */ ++ objc_thread_t thread_id = NULL; /* Detached thread id. */ ++ ++ if (!(istate = (struct __objc_thread_start_state *) ++ objc_malloc(sizeof(*istate)))) /* Can we allocate state? */ ++ return NULL; /* No, abort. */ ++ ++ istate->selector = selector; /* Initialize the thread's */ ++ istate->object = object; /* state structure. */ ++ istate->argument = argument; ++ ++ if ((thread_id = objc_thread_create((void *)__objc_thread_detach_function, ++ istate)) == NULL) { ++ objc_free(istate); /* Release state if failed. */ ++ return thread_id; ++ } ++ ++ return thread_id; ++ } ++ ++ #undef objc_mutex_lock() ++ #undef objc_mutex_unlock() ++ ++ int ++ objc_mutex_unlock_x(objc_mutex_t mutex, const char *f, int l) ++ { ++ printf("%16.16s#%4d < unlock", f, l); ++ return objc_mutex_unlock(mutex); ++ } ++ ++ int ++ objc_mutex_lock_x(objc_mutex_t mutex, const char *f, int l) ++ { ++ printf("%16.16s#%4d < lock", f, l); ++ return objc_mutex_lock(mutex); ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2/objc/thr.h gcc-2.7.2.1-objc-960906/objc/thr.h +*** gcc-2.7.2/objc/thr.h Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr.h Fri Sep 6 10:33:38 1996 +*************** +*** 0 **** +--- 1,104 ---- ++ /* Thread and mutex controls for Objective C. ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. ++ ++ 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 __thread_INCLUDE_GNU ++ #define __thread_INCLUDE_GNU ++ ++ #include "objc/objc.h" ++ ++ /************************************************************************* ++ * Universal static variables: ++ */ ++ extern int __objc_thread_exit_status; /* Global exit status. */ ++ ++ /******** ++ * Thread safe implementation types and functions. ++ */ ++ ++ #define OBJC_THREAD_INTERACTIVE_PRIORITY 2 ++ #define OBJC_THREAD_BACKGROUND_PRIORITY 1 ++ #define OBJC_THREAD_LOW_PRIORITY 0 ++ ++ typedef void * objc_thread_t; ++ typedef struct objc_mutex *objc_mutex_t; ++ typedef struct objc_condition *objc_condition_t; ++ ++ objc_mutex_t objc_mutex_allocate(void); ++ int objc_mutex_deallocate(objc_mutex_t mutex); ++ int objc_mutex_lock(objc_mutex_t mutex); ++ int objc_mutex_unlock(objc_mutex_t mutex); ++ int objc_mutex_trylock(objc_mutex_t mutex); ++ ++ objc_condition_t objc_condition_allocate(void); ++ int objc_condition_deallocate(objc_condition_t condition); ++ int objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex); ++ int objc_condition_signal(objc_condition_t condition); ++ int objc_condition_broadcast(objc_condition_t condition); ++ ++ objc_thread_t objc_thread_create(void (*func)(void *arg), void *arg); ++ void objc_thread_yield(void); ++ int objc_thread_exit(void); ++ int objc_thread_set_priority(int priority); ++ int objc_thread_get_priority(void); ++ void * objc_thread_get_data(void); ++ int objc_thread_set_data(void *value); ++ objc_thread_t objc_thread_id(void); ++ ++ objc_thread_t objc_thread_detach(SEL selector, id object, id argument); ++ int objc_mutex_lock_x(objc_mutex_t mutex, const char *f, int l); ++ int objc_mutex_unlock_x(objc_mutex_t mutex, const char *f, int l); ++ ++ /* ++ Use this to set the hook function that will be called when the ++ runtime initially becomes multi threaded. ++ The hook function is only called once, meaning only when the ++ 2nd thread is spawned, not for each and every thread. ++ ++ It returns the previous hook function or NULL if there is none. ++ ++ A program outside of the runtime could set this to some function so ++ it can be informed; for example, the GNUstep Base Library sets it ++ so it can implement the NSBecomingMultiThreaded notification. ++ */ ++ typedef void (*objc_thread_callback)(); ++ objc_thread_callback objc_set_thread_callback(objc_thread_callback func); ++ ++ /* For debugging of locks, uncomment these two macros: */ ++ /* #define objc_mutex_lock(x) objc_mutex_lock_x(x, __FILE__, __LINE__) */ ++ /* #define objc_mutex_unlock(x) objc_mutex_unlock_x(x, __FILE__, __LINE__)*/ ++ ++ #endif /* not __thread_INCLUDE_GNU */ +diff -rcP gcc-2.7.2/objc-act.c gcc-2.7.2.1-objc-960906/objc-act.c +*** gcc-2.7.2/objc-act.c Fri Sep 6 14:28:16 1996 +--- gcc-2.7.2.1-objc-960906/objc-act.c Fri Sep 6 10:27:04 1996 +*************** +*** 6448,6453 **** +--- 6448,6569 ---- + } + + static void ++ encode_aggregate_within (type, curtype, format, left, right) ++ tree type; ++ int curtype; ++ int format; ++ char left; ++ char right; ++ { ++ if (obstack_object_size (&util_obstack) > 0 ++ && *(obstack_next_free (&util_obstack) - 1) == '^') ++ { ++ tree name = TYPE_NAME (type); ++ ++ /* we have a reference; this is a NeXT extension. */ ++ ++ if (obstack_object_size (&util_obstack) - curtype == 1 ++ && format == OBJC_ENCODE_INLINE_DEFS) ++ { ++ /* Output format of struct for first level only. */ ++ tree fields = TYPE_FIELDS (type); ++ ++ if (name && TREE_CODE (name) == IDENTIFIER_NODE) ++ { ++ obstack_1grow (&util_obstack, left); ++ obstack_grow (&util_obstack, ++ IDENTIFIER_POINTER (name), ++ strlen (IDENTIFIER_POINTER (name))); ++ obstack_1grow (&util_obstack, '='); ++ } ++ else ++ { ++ obstack_1grow (&util_obstack, left); ++ obstack_grow (&util_obstack, "?=", 2); ++ } ++ ++ for ( ; fields; fields = TREE_CHAIN (fields)) ++ encode_field_decl (fields, curtype, format); ++ ++ obstack_1grow (&util_obstack, right); ++ } ++ ++ else if (name && TREE_CODE (name) == IDENTIFIER_NODE) ++ { ++ obstack_1grow (&util_obstack, left); ++ obstack_grow (&util_obstack, ++ IDENTIFIER_POINTER (name), ++ strlen (IDENTIFIER_POINTER (name))); ++ obstack_1grow (&util_obstack, right); ++ } ++ ++ else ++ { ++ /* We have an untagged structure or a typedef. */ ++ obstack_1grow (&util_obstack, left); ++ obstack_1grow (&util_obstack, '?'); ++ obstack_1grow (&util_obstack, right); ++ } ++ } ++ ++ else ++ { ++ tree name = TYPE_NAME (type); ++ tree fields = TYPE_FIELDS (type); ++ ++ if (format == OBJC_ENCODE_INLINE_DEFS ++ || generating_instance_variables) ++ { ++ obstack_1grow (&util_obstack, left); ++ if (name && TREE_CODE (name) == IDENTIFIER_NODE) ++ obstack_grow (&util_obstack, ++ IDENTIFIER_POINTER (name), ++ strlen (IDENTIFIER_POINTER (name))); ++ else ++ obstack_1grow (&util_obstack, '?'); ++ ++ obstack_1grow (&util_obstack, '='); ++ ++ for (; fields; fields = TREE_CHAIN (fields)) ++ { ++ if (generating_instance_variables) ++ { ++ tree fname = DECL_NAME (fields); ++ ++ obstack_1grow (&util_obstack, '"'); ++ if (fname && TREE_CODE (fname) == IDENTIFIER_NODE) ++ { ++ obstack_grow (&util_obstack, ++ IDENTIFIER_POINTER (fname), ++ strlen (IDENTIFIER_POINTER (fname))); ++ } ++ ++ obstack_1grow (&util_obstack, '"'); ++ } ++ ++ encode_field_decl (fields, curtype, format); ++ } ++ ++ obstack_1grow (&util_obstack, right); ++ } ++ ++ else ++ { ++ obstack_1grow (&util_obstack, left); ++ if (name && TREE_CODE (name) == IDENTIFIER_NODE) ++ obstack_grow (&util_obstack, ++ IDENTIFIER_POINTER (name), ++ strlen (IDENTIFIER_POINTER (name))); ++ else ++ /* We have an untagged structure or a typedef. */ ++ obstack_1grow (&util_obstack, '?'); ++ ++ obstack_1grow (&util_obstack, right); ++ } ++ } ++ } ++ ++ static void + encode_aggregate (type, curtype, format) + tree type; + int curtype; +*************** +*** 6459,6598 **** + { + case RECORD_TYPE: + { +! if (obstack_object_size (&util_obstack) > 0 +! && *(obstack_next_free (&util_obstack) - 1) == '^') +! { +! tree name = TYPE_NAME (type); +! +! /* We have a reference; this is a NeXT extension. */ +! +! if (obstack_object_size (&util_obstack) - curtype == 1 +! && format == OBJC_ENCODE_INLINE_DEFS) +! { +! /* Output format of struct for first level only. */ +! tree fields = TYPE_FIELDS (type); +! +! if (name && TREE_CODE (name) == IDENTIFIER_NODE) +! { +! obstack_1grow (&util_obstack, '{'); +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (name), +! strlen (IDENTIFIER_POINTER (name))); +! obstack_1grow (&util_obstack, '='); +! } +! +! else +! obstack_grow (&util_obstack, "{?=", 3); +! +! for ( ; fields; fields = TREE_CHAIN (fields)) +! encode_field_decl (fields, curtype, format); +! +! obstack_1grow (&util_obstack, '}'); +! } +! +! else if (name && TREE_CODE (name) == IDENTIFIER_NODE) +! { +! obstack_1grow (&util_obstack, '{'); +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (name), +! strlen (IDENTIFIER_POINTER (name))); +! obstack_1grow (&util_obstack, '}'); +! } +! +! else +! /* We have an untagged structure or a typedef. */ +! obstack_grow (&util_obstack, "{?}", 3); +! } +! +! else +! { +! tree name = TYPE_NAME (type); +! tree fields = TYPE_FIELDS (type); +! +! if (format == OBJC_ENCODE_INLINE_DEFS +! || generating_instance_variables) +! { +! obstack_1grow (&util_obstack, '{'); +! if (name && TREE_CODE (name) == IDENTIFIER_NODE) +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (name), +! strlen (IDENTIFIER_POINTER (name))); +! +! else +! obstack_1grow (&util_obstack, '?'); +! +! obstack_1grow (&util_obstack, '='); +! +! for (; fields; fields = TREE_CHAIN (fields)) +! { +! if (generating_instance_variables) +! { +! tree fname = DECL_NAME (fields); +! +! obstack_1grow (&util_obstack, '"'); +! if (fname && TREE_CODE (fname) == IDENTIFIER_NODE) +! { +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (fname), +! strlen (IDENTIFIER_POINTER (fname))); +! } +! +! obstack_1grow (&util_obstack, '"'); +! } +! +! encode_field_decl (fields, curtype, format); +! } +! +! obstack_1grow (&util_obstack, '}'); +! } +! +! else +! { +! obstack_1grow (&util_obstack, '{'); +! if (name && TREE_CODE (name) == IDENTIFIER_NODE) +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (name), +! strlen (IDENTIFIER_POINTER (name))); +! else +! /* We have an untagged structure or a typedef. */ +! obstack_1grow (&util_obstack, '?'); +! +! obstack_1grow (&util_obstack, '}'); +! } +! } + break; + } +- + case UNION_TYPE: + { +! if (*obstack_next_free (&util_obstack) == '^' +! || format != OBJC_ENCODE_INLINE_DEFS) +! { +! /* We have a reference (this is a NeXT extension) +! or we don't want the details. */ +! if (TYPE_NAME (type) +! && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) +! { +! obstack_1grow (&util_obstack, '('); +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (TYPE_NAME (type)), +! strlen (IDENTIFIER_POINTER (TYPE_NAME (type)))); +! obstack_1grow (&util_obstack, ')'); +! } +! +! else +! /* We have an untagged structure or a typedef. */ +! obstack_grow (&util_obstack, "(?)", 3); +! } +! else +! { +! tree fields = TYPE_FIELDS (type); +! obstack_1grow (&util_obstack, '('); +! for ( ; fields; fields = TREE_CHAIN (fields)) +! encode_field_decl (fields, curtype, format); +! +! obstack_1grow (&util_obstack, ')'); +! } + break; + } + +--- 6575,6586 ---- + { + case RECORD_TYPE: + { +! encode_aggregate_within(type, curtype, format, '{', '}'); + break; + } + case UNION_TYPE: + { +! encode_aggregate_within(type, curtype, format, '(', ')'); + break; + } + +diff -rcP gcc-2.7.2/objc-parse.c gcc-2.7.2.1-objc-960906/objc-parse.c +*** gcc-2.7.2/objc-parse.c Fri Sep 6 14:28:19 1996 +--- gcc-2.7.2.1-objc-960906/objc-parse.c Fri Sep 6 10:27:06 1996 +*************** +*** 1,5 **** + +! /* A Bison parser, made from objc-parse.y with Bison version GNU Bison version 1.22 + */ + + #define YYBISON 1 /* Identify Bison output. */ +--- 1,5 ---- + +! /* A Bison parser, made from objc-parse.y with Bison version GNU Bison version 1.24 + */ + + #define YYBISON 1 /* Identify Bison output. */ +*************** +*** 495,501 **** + 2797, 2804, 2813 + }; + +! static const char * const yytname[] = { "$","error","$illegal.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT", + "BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ATTRIBUTE", +--- 495,501 ---- + 2797, 2804, 2813 + }; + +! static const char * const yytname[] = { "$","error","$undefined.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT", + "BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ATTRIBUTE", +*************** +*** 1586,1599 **** + 52 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/local/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman + + This program 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 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, +--- 1586,1599 ---- + 52 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program 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. + + This program is distributed in the hope that it will be useful, +*************** +*** 1605,1610 **** +--- 1605,1614 ---- + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++ /* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ + + #ifndef alloca + #ifdef __GNUC__ +*************** +*** 1678,1687 **** +--- 1682,1699 ---- + + #ifdef YYPURE + #ifdef YYLSP_NEEDED ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) ++ #else + #define YYLEX yylex(&yylval, &yylloc) ++ #endif ++ #else /* not YYLSP_NEEDED */ ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, YYLEX_PARAM) + #else + #define YYLEX yylex(&yylval) + #endif ++ #endif /* not YYLSP_NEEDED */ + #endif + + /* If nonreentrant, generate the variables here */ +*************** +*** 1729,1742 **** + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (from, to, count) + char *from; + char *to; + int count; +--- 1741,1754 ---- + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (from, to, count) + char *from; + char *to; + int count; +*************** +*** 1754,1760 **** + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +--- 1766,1772 ---- + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +*************** +*** 1767,1773 **** + #endif + #endif + +! #line 184 "/usr/local/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +--- 1779,1785 ---- + #endif + #endif + +! #line 192 "/usr/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +*************** +*** 1900,1911 **** + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +--- 1912,1923 ---- + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +*************** +*** 4718,4724 **** + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 480 "/usr/local/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +--- 4730,4736 ---- + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 487 "/usr/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +diff -rcP gcc-2.7.2/stor-layout.c gcc-2.7.2.1-objc-960906/stor-layout.c +*** gcc-2.7.2/stor-layout.c Fri Sep 6 14:28:56 1996 +--- gcc-2.7.2.1-objc-960906/stor-layout.c Fri Sep 6 10:27:43 1996 +*************** +*** 437,443 **** + That can happen because the width exceeds BIGGEST_ALIGNMENT + or because it exceeds maximum_field_alignment. */ + if (const_size / type_align +! != (const_size + field_size - 1) / type_align) + const_size = CEIL (const_size, type_align) * type_align; + } + #endif +--- 437,443 ---- + That can happen because the width exceeds BIGGEST_ALIGNMENT + or because it exceeds maximum_field_alignment. */ + if (const_size / type_align +! != (const_size + (field_size % type_align) - 1) / type_align) + const_size = CEIL (const_size, type_align) * type_align; + } + #endif +diff -rcP gcc-2.7.2/version.c gcc-2.7.2.1-objc-960906/version.c +*** gcc-2.7.2/version.c Fri Sep 6 14:29:12 1996 +--- gcc-2.7.2.1-objc-960906/version.c Fri Sep 6 10:27:59 1996 +*************** +*** 1 **** +! char *version_string = "2.7.2"; +--- 1 ---- +! char *version_string = "2.7.2.1 Objective-C snapshot 960906"; diff --git a/gcc-2.7.2.1-objc.diff b/gcc-2.7.2.1-objc.diff new file mode 100644 index 000000000..635b15550 --- /dev/null +++ b/gcc-2.7.2.1-objc.diff @@ -0,0 +1,14388 @@ +Changes for GCC version 2.7.2.1 and Objective-C runtime snapshot 960906. + +Go to the directory gcc-2.7.2.1 and perform these steps + + rm objc/list.h + +Then use this command + + patch -p1 + +feeding it the following diffs as input. + +diff -rcP gcc-2.7.2.1/ChangeLog gcc-2.7.2.1-objc-960906/ChangeLog +*** gcc-2.7.2.1/ChangeLog Fri Sep 6 11:18:56 1996 +--- gcc-2.7.2.1-objc-960906/ChangeLog Fri Sep 6 10:23:44 1996 +*************** +*** 1,3 **** +--- 1,333 ---- ++ Thu Sep 5 19:09:27 1996 Ovidiu Predescu ++ ++ * objc-act.c (encode_aggregate_within): New function. ++ (encode_aggregate): Generates encodings for unions similar ++ to those for structs except surrounded by parenthesis instead ++ of braces. ++ ++ Thu Sep 5 10:24:36 1996 Scott Christley ++ ++ Major reorganization of objc error handling. ++ * objc/Object.m (-error:): Call objc_error function instead of ++ using function pointer. ++ * objc/archive.c: Replace call to abort or __objc_fatal functions ++ with call to objc_error function throughout the complete file. ++ * objc/class.c (objc_get_class): Replace call to abort function ++ with call to objc_error function. ++ * objc/encoding.c (objc_sizeof_type, objc_alignof_type): Replace ++ call to abort function with call to objc_error function. ++ (objc_skip_typespec): Likewise. ++ * objc/init.c (init_check_module_version): Replace call to ++ abort function with call to objc_error function. ++ * objc/misc.c (objc_verror): New function. ++ (objc_fatal): Remove function. ++ (objc_set_error_handler): New function. ++ (_objc_error_handler): New global variable. ++ (__alpha__): Remove unneeded code. ++ (objc_error): Allow user specified error handler function to ++ trap and handle the objc error. Added an error code parameter ++ which indicates the specific error that occured. ++ (objc_malloc, objc_atomic_malloc): Replace call to objc_fatal ++ function with call to objc_error function. ++ (objc_valloc, objc_realloc, objc_calloc): Likewise. ++ * objc/objc-api.h: Declare error handling functions and typedef ++ for user specified error handler function. Define error codes ++ used by the runtime library. ++ * objc/runtime.h: Remove error handling declarations. ++ * objc/sendmsg.c (__objc_forward): Replace call to abort function ++ with call to objc_error function. ++ ++ Mon Aug 26 12:36:16 1996 Scott Christley ++ ++ * install.texi: Add instructions for the Objective-C runtime ++ library regarding thread support. ++ ++ Mon Aug 26 11:17:32 1996 Thomas Baier ++ ++ * objc/hash.c (hash_delete): Step through the hash nodes ++ versus using hash_next to increase efficiency. ++ * objc/archive.c (__objc_finish_read_root_object): Use hash ++ table instead of list. ++ ++ Thu Aug 8 08:56:05 1996 Scott Christley ++ ++ Create consistent mechanism for memory allocation and release ++ so that garbage collection routines can be easily subsititued ++ for the ANSI standard malloc, realloc, free, etc. ++ * objc/archive.c: Replace use of __objc_xmalloc and free ++ with objc_malloc and objc_free. ++ * objc/hash.c: Replace use of __objc_xcalloc and free ++ with objc_calloc and objc_free. ++ * objc/init.c: Replace use of free with objc_free. ++ * objc/misc.c (objc_malloc): Renamed from __objc_xmalloc. ++ (objc_realloc): Renamed from __objc_realloc. ++ (objc_atomic_malloc): New function. ++ (objc_valloc): New function. ++ (objc_calloc): Renamed from __objc_calloc. ++ (objc_free): New function. ++ * objc/objc-api.h (_objc_malloc): New function pointer. ++ (_objc_atomic_malloc, _objc_valloc): Likewise. ++ (_objc_realloc, _objc_calloc, _objc_free): Likewise ++ * objc/objc-list.h: Replace use of __obj_xmalloc and free ++ with objc_malloc and objc_free. ++ * objc/objects.c: Likewise. ++ * objc/runtime.h (__objc_xmalloc): Delete. ++ (__objc_xrealloc, __objc_xcalloc): Delete. ++ * objc/sarray.c: Replace use of __objc_xmalloc and free ++ with objc_malloc and objc_free. ++ * objc/sarray.h (__objc_xmalloc, __objc_xrealloc): Delete. ++ * objc/selector.c: Replace use of __objc_xcalloc, __objc_xrealloc, ++ and __objc_xmalloc with objc_calloc, objc_realloc, and objc_malloc. ++ * objc/thr-decosf1.c: Replace use of __objc_xmalloc and free ++ with objc_malloc and objc_free. ++ * objc/thr-irix.c: Likewise. ++ * objc/thr-mach.c: Likewise. ++ * objc/thr-os2.c: Likewise. ++ * objc/thr-posix.c: Likewise. ++ * objc/thr-pthreads.c: Likewise. ++ * objc/thr-single.c: Likewise. ++ * objc/thr-solaris.c: Likewise. ++ * objc/thr-win32.c: Likewise. ++ * objc/thr.c: Likewise. ++ ++ Tue Aug 6 12:42:25 1996 Ovidiu Predescu (ovidiu@xpro.pcnet.ro) ++ ++ * objc/encoding.c (method_get_next_argument): Take into consideration ++ OBJC_FORWARDING_STACK_OFFSET for accessing stack variables. ++ (method_get_nth_argument): Likewise. ++ ++ * objc/encoding.h (method_get_sizeof_arguments): Fix typo. ++ ++ * objc/selector.c (__objc_register_instance_methods_to_class): New ++ function. ++ * objc/runtime.h: Likewise. Add missing function prototypes. ++ ++ * objc/init.c (__objc_exec_class): Initialize subclass to NULL. ++ Call __objc_register_instance_methods_to_class to register ++ instance methods as class methods for root classes. ++ ++ * objc/objc-api.h: On NeXT redefine object_copy and object_dispose ++ to avoid a conflict with those defined in system library. ++ ++ * objc/sendmsg.c: Also check if STRUCT_VALUE is even defined. ++ (search_for_method_in_list): No longer static. ++ ++ Tue Aug 6 09:40:29 1996 Scott Christley ++ ++ Add condition mutex support to the objc runtime. ++ * objc/THREADS: Update information. ++ * objc/thr-mach.c (objc_condition_allocate): New function. ++ (objc_condition_deallocate): New function. ++ (objc_condition_wait): New function. ++ (objc_condition_broadcast): New function. ++ (objc_condition_signal): New function. ++ * objc/thr-pthreads.c (objc_condition_allocate): New function. ++ (objc_condition_deallocate): New function. ++ (objc_condition_wait): New function. ++ (objc_condition_broadcast): New function. ++ (objc_condition_signal): New function. ++ * objc/thr-solaris.c (objc_condition_allocate): New function. ++ (objc_condition_deallocate): New function. ++ (objc_condition_wait): New function. ++ (objc_condition_broadcast): New function. ++ (objc_condition_signal): New function. ++ * objc/thr.h: Prototypes for new functions. ++ ++ * objc/init.c (__objc_runtime_mutex): Eliminate leading underscore ++ from name of objc mutex and thread structures. ++ * objc/runtime.h: Likewise. ++ * objc/thr-decosf1.c: Likewise. ++ * objc/thr-irix.c: Likewise. ++ * objc/thr-mach.c: Likewise. ++ * objc/thr-os2.c: Likewise. ++ * objc/thr-posix.c: Likewise. ++ * objc/thr-pthreads.c: Likewise. ++ * objc/thr-single.c: Likewise. ++ * objc/thr-solaris.c: Likewise. ++ * objc/thr.c: Likewise. ++ * objc/thr.h: Likewise. ++ * objc/thr-win32.c: Likewise. Define __OBJC__ before including ++ Windows header files. ++ ++ * config/i386/next.h (OBJC_MAX_STRUCT_BY_VALUE): New definition. ++ * objc/sendmsg.c (get_imp, objc_msg_lookup): Add logic to determine ++ when structures are passed by value. ++ ++ * objc/selector.c (__sel_register_typed_name): Eliminate compiler ++ warnings with explicit cast. ++ ++ Mon Aug 5 12:40:29 1996 Scott Christley ++ ++ * expr.c (expand_builtin_apply): Use SAVE_NONLOCAL on PPC. ++ ++ * objc/sendmsg.c: Clean up comments, make code fit with 80 columns. ++ * objc/objc.h: Likewise. ++ * objc/objc-api.h: Likewise. ++ * objc/archive.c: Likewise. ++ * objc/class.c: Likewise. ++ * objc/sarray.c: Likewise. ++ * objc/thr-mach.c: Likewise. ++ * objc/thr-posix.c: Likewise. ++ * objc/thr-pthreads.c: Likewise. ++ * objc/thr-win32.c: Likewise. ++ * objc/thr-os2.c: Likewise. ++ * objc/thr-solaris.c: Likewise. ++ * objc/thr.c: Likewise. ++ ++ Fri Jun 28 18:37:20 1996 Stephen L Moshier ++ ++ * objc/sarray.c (ifdef __alpha__): Don't declare `free'. ++ * objc/thr-decosf1.c (objc_thread_id): Use pthread_getunique_np ++ to obtain a thread ID value. ++ (objc_mutex_allocate): Cast mutex->owner to _objc_thread_t. ++ (objc_mutex_deallocate): Likewise. ++ (objc_mutex_unlock): Likewise. ++ (objc_mutex_trylock): Declare thread_id as _objc_thread_t. ++ (objc_mutex_lock): Likewise. ++ (objc_mutex_unlock): Likewise. ++ ++ Wed Jun 19 12:22:58 1996 Scott Christley ++ ++ * objc/sendmsg.c (__objc_double_forward): New function. ++ (get_imp, objc_msg_lookup): Use different forwarding function ++ when returning a floating point value. ++ ++ Wed Jun 5 09:46:22 1996 Scott Christley ++ ++ * objc/Makefile (libobjc.a): Don't delete the library; its contents ++ would be incorrect if only a single file was recompiled. ++ ++ * objc/thr.h (objc_set_thread_callback): New function. ++ (objc_thread_callback): Typedef for the hook function which is ++ called when the runtime first becomes multi-threaded. ++ * objc/thr.c (__objc_thread_detach_function): Clear thread storage. ++ Call the thread hook function when first becoming multi-threaded. ++ (objc_set_thread_callback): New function. ++ ++ * objc/selector.c (__sel_register_typed_name): Implement additional ++ parameter which indicates whether name and type parameters are truly ++ constant or not. Previously runtime assumed they were; now it ++ assumes that they are not. If constant then the actual pointers ++ passed as parameters can be stored in the runtime structures; ++ otherwise, the data must be copied into malloced space. ++ * objc/runtime.h (__sel_register_typed_name): Likewise. ++ * objc/init.c (__sel_register_typed_name): Likewise. ++ ++ Tue Jun 4 18:15:31 1996 Scott Christley ++ ++ * objc/init.c (__objc_init_protocols): Need to unlock mutex. ++ ++ Wed May 22 12:43:49 1996 Scott Christley ++ ++ * objc/sendmsg.c (objc_get_uninstalled_dtable): New function. ++ * objc/objc-api.h (objc_get_uninstalled_dtable): Likewise. ++ ++ * Makefile.in (OBJC_THREAD_FILE): New variable that holds the ++ source file name to be compiled for Objective-C Runtime Library ++ thread support. It is passed directly down to the Objective-C ++ Runtime Library makefile. ++ * configure (objc_thread_file): Set new variable to appropriate ++ values based upon target operating system; default is `thr-single'. ++ * objc/Makefile (OBJC_THREAD_FILE): Add target and dependency. ++ (thr.o): Remove OS specific thread files as dependencies. ++ * objc/thr-decosf1.c: Now compiles as a separate source file, so ++ include in appropriate Objective-C headers. ++ * objc/thr-mach.c: Likewise. ++ * objc/thr-os2.c: Likewise. ++ * objc/thr-posix.c: Likewise. ++ * objc/thr-pthreads.c: Likewise. ++ * objc/thr-irix.c: Likewise. ++ * objc/thr-single.c: Likewise. ++ * objc/thr-solaris.c: Likewise. ++ * objc/thr-win32.c: Likewise. ++ * objc/thr.c: Remove inclusion of source files. ++ * objc/thr.h (__objc_thread_exit_status): Declare global variable. ++ * objc/thr-pthreads.c: New file. ++ ++ Fri May 17 08:12:37 1996 Scott Christley ++ ++ * objc/thr-os2.c, objc/thr-posix.c, objc/thr-mach.c: New files. ++ * objc/THREADS.MACH: New file. ++ ++ * objc/sendmsg.c (nil_method): Deleted from here. ++ * objc/nil_method.c: New file. ++ * Makefile (OBJC_O): Add dependency for nil_method.c. ++ ++ * objc/hash.c (hash_is_key_in_hash): New function. ++ * objc/hash.h: Include objc/objc.h here instead of in objc/hash.c ++ to get BOOL typedef. ++ ++ Tue Apr 16 06:22:00 1996 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++ ++ * objc/thr-decosf1.c (_objc_thread_id): Correct return type from ++ int to _objc_thread_id. ++ ++ Sun Apr 14 07:52:28 1996 Manor Askenazi ++ ++ * objc/encoding.c (objc_skip_typespec): Don't abort for _C_UNDEF. ++ ++ Thu Apr 4 12:17:08 1996 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++ ++ * objc/Makefile: Rename thread* to thr*. ++ * objc/thread.c: Rename thread-* to thr-*. ++ * objc/thr-decosf1.c: Renamed from thread-decosf1.c ++ * objc/thr-irix.c: Renamed from thread-irix.c. ++ * objc/thr-single.c: Renamed from thread-single.c. ++ * objc/thr-solarius.c: Renamed from thread-solaris.c. ++ * objc/thr-win32.c: Renamed from thread-win32.c. ++ * objc/objc-api.h: Include thr.h, not thread.h. ++ * objc/runtime.h, objc/sarray.h: Likewise. ++ ++ Mon Mar 25 08:09:59 1996 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++ ++ * objc/thread-single.c (objc_mutex_unlock): Properly declare thread_id. ++ ++ Tue Mar 5 09:22:20 1996 Scott Christley (scottc@net-community.com) ++ ++ * objc/objc-api.h, objc/runtime.h: Include objc/thread.h. ++ * objc/class.c (__objc_init_class_tables): Surround sarray access ++ with mutex lock/unlock. ++ (__objc_add_class_to_hash, objc_lookup_class): Likewise. ++ (objc_get_class, objc_get_next_class): Likewise. ++ (__objc_resolve_class_links, class_pose_as): Likewise. ++ * objc/init.c (__objc_runtime_mutux, __objc_runtime_thread_alive): ++ New variables. ++ (objc_init_statics, __objc_init_protocols): Surround sarray access ++ with mutex lock/unlock ++ (__objc_exec_class): Likewise. ++ Initialization for thread-safe global variables. ++ Declarations for thread-safe functions and global variables ++ * objc/sendmsg.c (get_imp, __objc_responds_to): ++ Surround sarray access with mutex lock/unlock. ++ (__objc_init_install_dtable): Likewise. ++ (__objc_update_dispatch_table_for_class): Likewise. ++ (__objc_print_dtable_stats): Likewise. ++ * objc/selector.c (sel_get_typed_uid, sel_get_any_typed_uid): Likewise. ++ (sel_get_any_uid, sel_get_name, sel_register_name): Likewise. ++ (sel_register_typed_name): Likewise. ++ * objc/sarray.h (union sversion): New. ++ (struct sarray): Maintain multiple versions. ++ (sarray_remove_garbage): Add prototype. ++ * objc/sarray.c (sarray_{remove,free}_garbage): New functions. ++ (sarray_at_put, sarray_new, sarray_lazy_copy): ++ Modify/copy sarray structure/data in a thread-safe manner ++ (sarray_{realloc,free}): Reallocate/free sarray structure/data in a ++ thread-safe manner. ++ ++ * objc/THREADS, objc/thread.c, objc/thread.h: New files. ++ * objc/thread-{decosf1,irix,solaris,win32,single}.c: New files. ++ * objc/objc-list.h: Renamed from objc/list.h. ++ * objc/Makefile: Changes to compile new files and name renaming. ++ * objc/makefile.dos: Likewise. ++ ++ Mon Jan 15 06:20:38 1996 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ++ ++ * objc/archive.c (objc_{write,read}_type, case _C_STRUCT_B): Fix typo. ++ ++ Mon Dec 18 19:31:23 1995 Adam Fedor ++ ++ * objc/encoding.c (objc_alignof_type): Handle _C_PTR case. ++ + Sat Jun 29 12:33:39 1996 Richard Kenner + + * Version 2.7.2.1 released. +diff -rcP gcc-2.7.2.1/INSTALL gcc-2.7.2.1-objc-960906/INSTALL +*** gcc-2.7.2.1/INSTALL Fri Sep 6 11:19:40 1996 +--- gcc-2.7.2.1-objc-960906/INSTALL Fri Sep 6 10:24:28 1996 +*************** +*** 427,432 **** +--- 427,474 ---- + a C++ run-time library. All I/O functionality, special class + libraries, etc., are available in the libg++ distribution. + ++ 17. GNU C does include a runtime library for Objective-C because it is ++ an integral part of the language; all of the files associated with ++ the library are located in the subdirectory `objc'. The GNU ++ Objective-C Runtime Library does require header files for the ++ target's C library in order to be compiled, and it will also ++ require the header files for the target's thread library if you ++ want thread support. *Note Cross-Compilers and Header Files: ++ Cross Headers, for discussion about header files issues for ++ cross-compilation. ++ ++ When you run `configure', it picks the appropriate Objective-C ++ back-end thread implementation file for the target platform. In ++ some situations, you may wish to choose a different back-end as ++ some platforms support multiple thread implementations, or you may ++ wish to disable thread support completely. This can be done by ++ specifying a value for the OBJC_THREAD_FILE makefile variable on ++ the command line when you run make, for example: ++ ++ make CC="stage2/xgcc -Bstage2/" CFLAGS="-g -O2" OBJC_THREAD_FILE=thr-single ++ ++ Below is a list of the currently available back-ends. ++ ++ * thr-single; disable thread support, should work for all ++ platforms. ++ ++ * thr-decosf1; DEC OSF/1 thread support. ++ ++ * thr-irix; SGI IRIX thread support. ++ ++ * thr-mach; Generic MACH thread support, known to work on ++ NEXTSTEP. ++ ++ * thr-os2; IBM OS/2 thread support. ++ ++ * thr-posix; Generix POSIX thread support. ++ ++ * thr-pthreads; PCThreads on Linux based GNU systems. ++ ++ * thr-solaris; SUN Solaris thread support. ++ ++ * thr-win32; Microsoft Win32 API thread support. ++ + Configurations Supported by GNU CC + ================================== + +diff -rcP gcc-2.7.2.1/Makefile.in gcc-2.7.2.1-objc-960906/Makefile.in +*** gcc-2.7.2.1/Makefile.in Fri Sep 6 11:19:41 1996 +--- gcc-2.7.2.1-objc-960906/Makefile.in Fri Sep 6 10:24:29 1996 +*************** +*** 174,179 **** +--- 174,180 ---- + host_xm_file= ... `configure' substitutes actual host xm- file name here. + lang_specs_files= ... `configure' substitutes actual lang spec file names here. + lang_options_files= ... `configure' puts actual lang options file names here. ++ OBJC_THREAD_FILE= ... `configure' puts actual objc thread file name here. + version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < $(srcdir)/version.c` + mainversion=`sed -e 's/.*\"\([0-9]*\.[0-9]*\).*/\1/' < $(srcdir)/version.c` + +*************** +*** 995,1001 **** + $(MAKE) -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)" + -rm -f libobjc.a + ln objc/libobjc.a . >/dev/null 2>&1 || cp objc/libobjc.a . + -if $(RANLIB_TEST) ; then $(RANLIB) libobjc.a; else true; fi +--- 996,1002 ---- + $(MAKE) -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)" OBJC_THREAD_FILE="$(OBJC_THREAD_FILE)" + -rm -f libobjc.a + ln objc/libobjc.a . >/dev/null 2>&1 || cp objc/libobjc.a . + -if $(RANLIB_TEST) ; then $(RANLIB) libobjc.a; else true; fi +*************** +*** 1008,1014 **** + $(MAKE) -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)" + + # Compile two additional files that are linked with every program + # linked using GCC on systems using COFF or ELF, for the sake of C++ +--- 1009,1015 ---- + $(MAKE) -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)" OBJC_THREAD_FILE="$(OBJC_THREAD_FILE)" + + # Compile two additional files that are linked with every program + # linked using GCC on systems using COFF or ELF, for the sake of C++ +diff -rcP gcc-2.7.2.1/bi-parser.c gcc-2.7.2.1-objc-960906/bi-parser.c +*** gcc-2.7.2.1/bi-parser.c Fri Sep 6 11:19:53 1996 +--- gcc-2.7.2.1-objc-960906/bi-parser.c Fri Sep 6 10:24:41 1996 +*************** +*** 1,5 **** + +! /* A Bison parser, made from bi-parser.y with Bison version GNU Bison version 1.22 + */ + + #define YYBISON 1 /* Identify Bison output. */ +--- 1,5 ---- + +! /* A Bison parser, made from bi-parser.y with Bison version GNU Bison version 1.24 + */ + + #define YYBISON 1 /* Identify Bison output. */ +*************** +*** 123,131 **** + 93, 95, 98, 101, 105, 108, 112 + }; + +! static const char * const yytname[] = { "$","error","$illegal.","DEFOP","STRING", +! "'('","','","')'","top","defs","def","variations","variation","opt_string","list", +! "items","item","" + }; + #endif + +--- 123,131 ---- + 93, 95, 98, 101, 105, 108, 112 + }; + +! static const char * const yytname[] = { "$","error","$undefined.","DEFOP", +! "STRING","'('","','","')'","top","defs","def","variations","variation","opt_string", +! "list","items","item","" + }; + #endif + +*************** +*** 179,192 **** + -1, 12, -1, -1, 16 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/local/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman + + This program 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 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, +--- 179,192 ---- + -1, 12, -1, -1, 16 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program 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. + + This program is distributed in the hope that it will be useful, +*************** +*** 198,203 **** +--- 198,207 ---- + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++ /* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ + + #ifndef alloca + #ifdef __GNUC__ +*************** +*** 271,280 **** +--- 275,292 ---- + + #ifdef YYPURE + #ifdef YYLSP_NEEDED ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) ++ #else + #define YYLEX yylex(&yylval, &yylloc) ++ #endif ++ #else /* not YYLSP_NEEDED */ ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, YYLEX_PARAM) + #else + #define YYLEX yylex(&yylval) + #endif ++ #endif /* not YYLSP_NEEDED */ + #endif + + /* If nonreentrant, generate the variables here */ +*************** +*** 322,335 **** + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (from, to, count) + char *from; + char *to; + int count; +--- 334,347 ---- + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (from, to, count) + char *from; + char *to; + int count; +*************** +*** 347,353 **** + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +--- 359,365 ---- + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +*************** +*** 360,366 **** + #endif + #endif + +! #line 184 "/usr/local/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +--- 372,378 ---- + #endif + #endif + +! #line 192 "/usr/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +*************** +*** 493,504 **** + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +--- 505,516 ---- + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +*************** +*** 716,722 **** + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 480 "/usr/local/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +--- 728,734 ---- + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 487 "/usr/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +diff -rcP gcc-2.7.2.1/c-gperf.h gcc-2.7.2.1-objc-960906/c-gperf.h +*** gcc-2.7.2.1/c-gperf.h Fri Sep 6 11:20:00 1996 +--- gcc-2.7.2.1-objc-960906/c-gperf.h Fri Sep 6 10:24:48 1996 +*************** +*** 1,5 **** + /* C code produced by gperf version 2.5 (GNU C++ version) */ +! /* Command-line: gperf -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ c-parse.gperf */ + struct resword { char *name; short token; enum rid rid; }; + + #define TOTAL_KEYWORDS 79 +--- 1,6 ---- + /* C code produced by gperf version 2.5 (GNU C++ version) */ +! /* Command-line: gperf -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ ./c-parse.gperf */ +! /* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ + struct resword { char *name; short token; enum rid rid; }; + + #define TOTAL_KEYWORDS 79 +*************** +*** 10,16 **** + /* maximum key range = 135, duplicates = 0 */ + + #ifdef __GNUC__ +! __inline + #endif + static unsigned int + hash (str, len) +--- 11,17 ---- + /* maximum key range = 135, duplicates = 0 */ + + #ifdef __GNUC__ +! inline + #endif + static unsigned int + hash (str, len) +*************** +*** 43,167 **** + case 2: + case 1: + hval += asso_values[str[0]]; + } + return hval + asso_values[str[len - 1]]; + } + + static struct resword wordlist[] = + { +! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, +! {"",}, +! {"int", TYPESPEC, RID_INT}, +! {"",}, {"",}, +! {"__typeof__", TYPEOF, NORID}, +! {"__signed__", TYPESPEC, RID_SIGNED}, +! {"__imag__", IMAGPART, NORID}, +! {"switch", SWITCH, NORID}, +! {"__inline__", SCSPEC, RID_INLINE}, +! {"else", ELSE, NORID}, +! {"__iterator__", SCSPEC, RID_ITERATOR}, +! {"__inline", SCSPEC, RID_INLINE}, +! {"__extension__", EXTENSION, NORID}, +! {"struct", STRUCT, NORID}, +! {"__real__", REALPART, NORID}, +! {"__const", TYPE_QUAL, RID_CONST}, +! {"while", WHILE, NORID}, +! {"__const__", TYPE_QUAL, RID_CONST}, +! {"case", CASE, NORID}, +! {"__complex__", TYPESPEC, RID_COMPLEX}, +! {"__iterator", SCSPEC, RID_ITERATOR}, +! {"bycopy", TYPE_QUAL, RID_BYCOPY}, +! {"",}, {"",}, {"",}, +! {"__complex", TYPESPEC, RID_COMPLEX}, +! {"",}, +! {"in", TYPE_QUAL, RID_IN}, +! {"break", BREAK, NORID}, +! {"@defs", DEFS, NORID}, +! {"",}, {"",}, {"",}, +! {"extern", SCSPEC, RID_EXTERN}, +! {"if", IF, NORID}, +! {"typeof", TYPEOF, NORID}, +! {"typedef", SCSPEC, RID_TYPEDEF}, +! {"__typeof", TYPEOF, NORID}, +! {"sizeof", SIZEOF, NORID}, +! {"",}, +! {"return", RETURN, NORID}, +! {"const", TYPE_QUAL, RID_CONST}, +! {"__volatile__", TYPE_QUAL, RID_VOLATILE}, +! {"@private", PRIVATE, NORID}, +! {"@selector", SELECTOR, NORID}, +! {"__volatile", TYPE_QUAL, RID_VOLATILE}, +! {"__asm__", ASM_KEYWORD, NORID}, +! {"",}, {"",}, +! {"continue", CONTINUE, NORID}, +! {"__alignof__", ALIGNOF, NORID}, +! {"__imag", IMAGPART, NORID}, +! {"__attribute__", ATTRIBUTE, NORID}, +! {"",}, {"",}, +! {"__attribute", ATTRIBUTE, NORID}, +! {"for", FOR, NORID}, +! {"",}, +! {"@encode", ENCODE, NORID}, +! {"id", OBJECTNAME, RID_ID}, +! {"static", SCSPEC, RID_STATIC}, +! {"@interface", INTERFACE, NORID}, +! {"",}, +! {"__signed", TYPESPEC, RID_SIGNED}, +! {"",}, +! {"__label__", LABEL, NORID}, +! {"",}, {"",}, +! {"__asm", ASM_KEYWORD, NORID}, +! {"char", TYPESPEC, RID_CHAR}, +! {"",}, +! {"inline", SCSPEC, RID_INLINE}, +! {"out", TYPE_QUAL, RID_OUT}, +! {"register", SCSPEC, RID_REGISTER}, +! {"__real", REALPART, NORID}, +! {"short", TYPESPEC, RID_SHORT}, +! {"",}, +! {"enum", ENUM, NORID}, +! {"inout", TYPE_QUAL, RID_INOUT}, +! {"",}, +! {"oneway", TYPE_QUAL, RID_ONEWAY}, +! {"union", UNION, NORID}, +! {"",}, +! {"__alignof", ALIGNOF, NORID}, +! {"",}, +! {"@implementation", IMPLEMENTATION, NORID}, +! {"",}, +! {"@class", CLASS, NORID}, +! {"",}, +! {"@public", PUBLIC, NORID}, +! {"asm", ASM_KEYWORD, NORID}, +! {"",}, {"",}, {"",}, {"",}, {"",}, +! {"default", DEFAULT, NORID}, +! {"",}, +! {"void", TYPESPEC, RID_VOID}, +! {"",}, +! {"@protected", PROTECTED, NORID}, +! {"@protocol", PROTOCOL, NORID}, +! {"",}, {"",}, {"",}, +! {"volatile", TYPE_QUAL, RID_VOLATILE}, +! {"",}, {"",}, +! {"signed", TYPESPEC, RID_SIGNED}, +! {"float", TYPESPEC, RID_FLOAT}, +! {"@end", END, NORID}, +! {"",}, {"",}, +! {"unsigned", TYPESPEC, RID_UNSIGNED}, +! {"@compatibility_alias", ALIAS, NORID}, +! {"double", TYPESPEC, RID_DOUBLE}, +! {"",}, {"",}, +! {"auto", SCSPEC, RID_AUTO}, +! {"",}, +! {"goto", GOTO, NORID}, +! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, +! {"do", DO, NORID}, +! {"",}, {"",}, {"",}, {"",}, +! {"long", TYPESPEC, RID_LONG}, + }; + + #ifdef __GNUC__ +! __inline + #endif + struct resword * + is_reserved_word (str, len) +--- 44,169 ---- + case 2: + case 1: + hval += asso_values[str[0]]; ++ break; + } + return hval + asso_values[str[len - 1]]; + } + + static struct resword wordlist[] = + { +! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, +! {"",}, +! {"int", TYPESPEC, RID_INT}, +! {"",}, {"",}, +! {"__typeof__", TYPEOF, NORID}, +! {"__signed__", TYPESPEC, RID_SIGNED}, +! {"__imag__", IMAGPART, NORID}, +! {"switch", SWITCH, NORID}, +! {"__inline__", SCSPEC, RID_INLINE}, +! {"else", ELSE, NORID}, +! {"__iterator__", SCSPEC, RID_ITERATOR}, +! {"__inline", SCSPEC, RID_INLINE}, +! {"__extension__", EXTENSION, NORID}, +! {"struct", STRUCT, NORID}, +! {"__real__", REALPART, NORID}, +! {"__const", TYPE_QUAL, RID_CONST}, +! {"while", WHILE, NORID}, +! {"__const__", TYPE_QUAL, RID_CONST}, +! {"case", CASE, NORID}, +! {"__complex__", TYPESPEC, RID_COMPLEX}, +! {"__iterator", SCSPEC, RID_ITERATOR}, +! {"bycopy", TYPE_QUAL, RID_BYCOPY}, +! {"",}, {"",}, {"",}, +! {"__complex", TYPESPEC, RID_COMPLEX}, +! {"",}, +! {"in", TYPE_QUAL, RID_IN}, +! {"break", BREAK, NORID}, +! {"@defs", DEFS, NORID}, +! {"",}, {"",}, {"",}, +! {"extern", SCSPEC, RID_EXTERN}, +! {"if", IF, NORID}, +! {"typeof", TYPEOF, NORID}, +! {"typedef", SCSPEC, RID_TYPEDEF}, +! {"__typeof", TYPEOF, NORID}, +! {"sizeof", SIZEOF, NORID}, +! {"",}, +! {"return", RETURN, NORID}, +! {"const", TYPE_QUAL, RID_CONST}, +! {"__volatile__", TYPE_QUAL, RID_VOLATILE}, +! {"@private", PRIVATE, NORID}, +! {"@selector", SELECTOR, NORID}, +! {"__volatile", TYPE_QUAL, RID_VOLATILE}, +! {"__asm__", ASM_KEYWORD, NORID}, +! {"",}, {"",}, +! {"continue", CONTINUE, NORID}, +! {"__alignof__", ALIGNOF, NORID}, +! {"__imag", IMAGPART, NORID}, +! {"__attribute__", ATTRIBUTE, NORID}, +! {"",}, {"",}, +! {"__attribute", ATTRIBUTE, NORID}, +! {"for", FOR, NORID}, +! {"",}, +! {"@encode", ENCODE, NORID}, +! {"id", OBJECTNAME, RID_ID}, +! {"static", SCSPEC, RID_STATIC}, +! {"@interface", INTERFACE, NORID}, +! {"",}, +! {"__signed", TYPESPEC, RID_SIGNED}, +! {"",}, +! {"__label__", LABEL, NORID}, +! {"",}, {"",}, +! {"__asm", ASM_KEYWORD, NORID}, +! {"char", TYPESPEC, RID_CHAR}, +! {"",}, +! {"inline", SCSPEC, RID_INLINE}, +! {"out", TYPE_QUAL, RID_OUT}, +! {"register", SCSPEC, RID_REGISTER}, +! {"__real", REALPART, NORID}, +! {"short", TYPESPEC, RID_SHORT}, +! {"",}, +! {"enum", ENUM, NORID}, +! {"inout", TYPE_QUAL, RID_INOUT}, +! {"",}, +! {"oneway", TYPE_QUAL, RID_ONEWAY}, +! {"union", UNION, NORID}, +! {"",}, +! {"__alignof", ALIGNOF, NORID}, +! {"",}, +! {"@implementation", IMPLEMENTATION, NORID}, +! {"",}, +! {"@class", CLASS, NORID}, +! {"",}, +! {"@public", PUBLIC, NORID}, +! {"asm", ASM_KEYWORD, NORID}, +! {"",}, {"",}, {"",}, {"",}, {"",}, +! {"default", DEFAULT, NORID}, +! {"",}, +! {"void", TYPESPEC, RID_VOID}, +! {"",}, +! {"@protected", PROTECTED, NORID}, +! {"@protocol", PROTOCOL, NORID}, +! {"",}, {"",}, {"",}, +! {"volatile", TYPE_QUAL, RID_VOLATILE}, +! {"",}, {"",}, +! {"signed", TYPESPEC, RID_SIGNED}, +! {"float", TYPESPEC, RID_FLOAT}, +! {"@end", END, NORID}, +! {"",}, {"",}, +! {"unsigned", TYPESPEC, RID_UNSIGNED}, +! {"@compatibility_alias", ALIAS, NORID}, +! {"double", TYPESPEC, RID_DOUBLE}, +! {"",}, {"",}, +! {"auto", SCSPEC, RID_AUTO}, +! {"",}, +! {"goto", GOTO, NORID}, +! {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, +! {"do", DO, NORID}, +! {"",}, {"",}, {"",}, {"",}, +! {"long", TYPESPEC, RID_LONG}, + }; + + #ifdef __GNUC__ +! inline + #endif + struct resword * + is_reserved_word (str, len) +diff -rcP gcc-2.7.2.1/c-parse.c gcc-2.7.2.1-objc-960906/c-parse.c +*** gcc-2.7.2.1/c-parse.c Fri Sep 6 11:20:03 1996 +--- gcc-2.7.2.1-objc-960906/c-parse.c Fri Sep 6 10:24:51 1996 +*************** +*** 1,5 **** + +! /* A Bison parser, made from c-parse.y with Bison version GNU Bison version 1.22 + */ + + #define YYBISON 1 /* Identify Bison output. */ +--- 1,5 ---- + +! /* A Bison parser, made from c-parse.y with Bison version GNU Bison version 1.24 + */ + + #define YYBISON 1 /* Identify Bison output. */ +*************** +*** 406,412 **** + 2053, 2056, 2061, 2064 + }; + +! static const char * const yytname[] = { "$","error","$illegal.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT", + "BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ATTRIBUTE", +--- 406,412 ---- + 2053, 2056, 2061, 2064 + }; + +! static const char * const yytname[] = { "$","error","$undefined.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT", + "BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ATTRIBUTE", +*************** +*** 1130,1143 **** + 48, 49, 50, 51, 52 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/local/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman + + This program 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 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, +--- 1130,1143 ---- + 48, 49, 50, 51, 52 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program 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. + + This program is distributed in the hope that it will be useful, +*************** +*** 1149,1154 **** +--- 1149,1158 ---- + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++ /* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ + + #ifndef alloca + #ifdef __GNUC__ +*************** +*** 1222,1231 **** +--- 1226,1243 ---- + + #ifdef YYPURE + #ifdef YYLSP_NEEDED ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) ++ #else + #define YYLEX yylex(&yylval, &yylloc) ++ #endif ++ #else /* not YYLSP_NEEDED */ ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, YYLEX_PARAM) + #else + #define YYLEX yylex(&yylval) + #endif ++ #endif /* not YYLSP_NEEDED */ + #endif + + /* If nonreentrant, generate the variables here */ +*************** +*** 1273,1286 **** + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (from, to, count) + char *from; + char *to; + int count; +--- 1285,1298 ---- + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (from, to, count) + char *from; + char *to; + int count; +*************** +*** 1298,1304 **** + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +--- 1310,1316 ---- + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +*************** +*** 1311,1317 **** + #endif + #endif + +! #line 184 "/usr/local/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +--- 1323,1329 ---- + #endif + #endif + +! #line 192 "/usr/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +*************** +*** 1444,1455 **** + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +--- 1456,1467 ---- + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +*************** +*** 3483,3489 **** + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 480 "/usr/local/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +--- 3495,3501 ---- + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 487 "/usr/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +diff -rcP gcc-2.7.2.1/cexp.c gcc-2.7.2.1-objc-960906/cexp.c +*** gcc-2.7.2.1/cexp.c Fri Sep 6 11:20:17 1996 +--- gcc-2.7.2.1-objc-960906/cexp.c Fri Sep 6 10:25:03 1996 +*************** +*** 1,5 **** + +! /* A Bison parser, made from cexp.y with Bison version GNU Bison version 1.22 + */ + + #define YYBISON 1 /* Identify Bison output. */ +--- 1,5 ---- + +! /* A Bison parser, made from cexp.y with Bison version GNU Bison version 1.24 + */ + + #define YYBISON 1 /* Identify Bison output. */ +*************** +*** 241,247 **** + 332, 335, 337, 340, 343, 345, 347, 352, 354, 367 + }; + +! static const char * const yytname[] = { "$","error","$illegal.","INT","CHAR", + "NAME","ERROR","'?'","':'","','","OR","AND","'|'","'^'","'&'","EQUAL","NOTEQUAL", + "'<'","'>'","LEQ","GEQ","LSH","RSH","'+'","'-'","'*'","'/'","'%'","UNARY","'!'", + "'~'","'#'","'('","')'","start","exp1","exp","@1","@2","@3","@4","@5","keywords", +--- 241,247 ---- + 332, 335, 337, 340, 343, 345, 347, 352, 354, 367 + }; + +! static const char * const yytname[] = { "$","error","$undefined.","INT","CHAR", + "NAME","ERROR","'?'","':'","','","OR","AND","'|'","'^'","'&'","EQUAL","NOTEQUAL", + "'<'","'>'","LEQ","GEQ","LSH","RSH","'+'","'-'","'*'","'/'","'%'","UNARY","'!'", + "'~'","'#'","'('","')'","start","exp1","exp","@1","@2","@3","@4","@5","keywords", +*************** +*** 341,354 **** + 26, 27, 23, 24, 25, 26, 27, 0, 9 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/local/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman + + This program 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 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, +--- 341,354 ---- + 26, 27, 23, 24, 25, 26, 27, 0, 9 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program 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. + + This program is distributed in the hope that it will be useful, +*************** +*** 360,365 **** +--- 360,369 ---- + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++ /* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ + + #ifndef alloca + #ifdef __GNUC__ +*************** +*** 433,442 **** +--- 437,454 ---- + + #ifdef YYPURE + #ifdef YYLSP_NEEDED ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) ++ #else + #define YYLEX yylex(&yylval, &yylloc) ++ #endif ++ #else /* not YYLSP_NEEDED */ ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, YYLEX_PARAM) + #else + #define YYLEX yylex(&yylval) + #endif ++ #endif /* not YYLSP_NEEDED */ + #endif + + /* If nonreentrant, generate the variables here */ +*************** +*** 484,497 **** + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (from, to, count) + char *from; + char *to; + int count; +--- 496,509 ---- + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (from, to, count) + char *from; + char *to; + int count; +*************** +*** 509,515 **** + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +--- 521,527 ---- + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +*************** +*** 522,528 **** + #endif + #endif + +! #line 184 "/usr/local/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +--- 534,540 ---- + #endif + #endif + +! #line 192 "/usr/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +*************** +*** 655,666 **** + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +--- 667,678 ---- + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +*************** +*** 1084,1090 **** + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 480 "/usr/local/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +--- 1096,1102 ---- + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 487 "/usr/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +diff -rcP gcc-2.7.2.1/config/i386/next.h gcc-2.7.2.1-objc-960906/config/i386/next.h +*** gcc-2.7.2.1/config/i386/next.h Fri Sep 6 11:24:42 1996 +--- gcc-2.7.2.1-objc-960906/config/i386/next.h Fri Sep 6 10:29:17 1996 +*************** +*** 224,226 **** +--- 224,243 ---- + == void_type_node))) ? (SIZE) : 0) + + /* END Calling Convention CHANGES */ ++ ++ /* OBJC_MAX_STRUCT_BY_VALUE should be defined in the platform specific ++ configuration file. Some platforms, i386 on NeXTSTEP for example, ++ pass small structures as values on the stack versus through a ++ hidden pointer as for larger structures. In order for forwarding ++ to work properly, the ObjC runtime needs to know when the structure ++ is being passed by value or not so it can perform the appropriate ++ forwarding function. The value of OBJC_MAX_STRUCT_BY_VALUE should ++ be the maximum number of bytes for the size of the structure for it ++ to be passed as a value, so a value of 8 indicates that a structure ++ of size 8 gets passed as a value while a structure of size 9 gets ++ passed as a hidden pointer. ++ ++ Leave OBJC_MAX_STRUCT_BY_VALUE undefined for platforms that always pass ++ structures as hidden pointers. */ ++ ++ #define OBJC_MAX_STRUCT_BY_VALUE 7 +diff -rcP gcc-2.7.2.1/configure gcc-2.7.2.1-objc-960906/configure +*** gcc-2.7.2.1/configure Fri Sep 6 11:20:25 1996 +--- gcc-2.7.2.1-objc-960906/configure Fri Sep 6 10:25:12 1996 +*************** +*** 509,514 **** +--- 509,516 ---- + truncate_target= + # Set this if gdb needs a dir command with `dirname $out_file` + gdb_needs_out_file_path= ++ # Set this to the Objective-C runtime thread file to compile ++ objc_thread_file=thr-single + + case $machine in + # Support site-specific machine types. +*************** +*** 597,602 **** +--- 599,605 ---- + then + extra_programs=ld.exe + fi ++ objc_thread_file=thr-win32 + ;; + arm-*-riscix1.[01]*) # Acorn RISC machine (early versions) + tm_file=arm/riscix1-1.h +*************** +*** 874,879 **** +--- 877,883 ---- + xm_file=i386/xm-next.h + tmake_file=i386/t-next + xmake_file=i386/x-next ++ objc_thread_file=thr-mach + ;; + i[345]86-sequent-bsd*) # 80386 from Sequent + cpu_type=i386 +*************** +*** 989,994 **** +--- 993,999 ---- + fixincludes=Makefile.in #On Linux, the headers are ok already. + broken_install=yes + gnu_ld=yes ++ objc_thread_file=thr-posix + ;; + i[345]86-*-linux*aout*) # Intel 80386's running Linux + cpu_type=i386 # with a.out format +*************** +*** 998,1003 **** +--- 1003,1009 ---- + fixincludes=Makefile.in #On Linux, the headers are ok already. + broken_install=yes + gnu_ld=yes ++ objc_thread_file=thr-posix + ;; + i[345]86-*-linux*) # Intel 80386's running Linux + cpu_type=i386 # with ELF format +*************** +*** 1010,1015 **** +--- 1016,1022 ---- + # Don't use it. Linux uses a slightly different one. + # The real one comes with the Linux C library. + #extra_parts="crtbegin.o crtend.o" ++ objc_thread_file=thr-posix + ;; + i[345]86-go32-msdos | i[345]86-*-go32) + cpu_type=i386 +*************** +*** 1092,1097 **** +--- 1099,1105 ---- + xmake_file=x-svr4 + fixincludes=fixinc.svr4 + broken_install=yes ++ objc_thread_file=thr-solaris + ;; + i[345]86-*-sysv4*) # Intel 80386's running system V.4 + cpu_type=i386 +*************** +*** 1148,1153 **** +--- 1156,1162 ---- + then + extra_programs=ld.exe + fi ++ objc_thread_file=thr-win32 + ;; + i860-alliant-*) # Alliant FX/2800 + xm_file=i860/xm-fx2800.h +*************** +*** 1453,1458 **** +--- 1462,1468 ---- + tmake_file=m68k/t-next + xmake_file=m68k/x-next + extra_headers=math-68881.h ++ objc_thread_file=thr-mach + ;; + m68k-sun-sunos3*) + if [ x$nfp = xyes ] +*************** +*** 1531,1536 **** +--- 1541,1547 ---- + fixincludes=Makefile.in #On Linux, the headers are ok already. + extra_headers=math-68881.h + gnu_ld=yes ++ objc_thread_file=thr-posix + ;; + m68k-*-linux*) # Motorola m68k's running Linux + xm_file=m68k/xm-linux.h # with ELF format +*************** +*** 1543,1548 **** +--- 1554,1560 ---- + # Don't use it. Linux uses a slightly different one. + # The real one comes with the Linux C library. + #extra_parts="crtbegin.o crtend.o" ++ objc_thread_file=thr-posix + ;; + m88k-dg-dgux*) + case $machine in +*************** +*** 1629,1634 **** +--- 1641,1647 ---- + tmake_file=mips/t-iris6 + # See comment in mips/iris[56].h files. + use_collect2=yes ++ objc_thread_file=thr-irix + ;; + mips-sgi-irix5cross64) # Irix5 host, Irix 6 target, cross64 + tm_file=mips/cross64.h +*************** +*** 1639,1644 **** +--- 1652,1658 ---- + tmake_file=mips/t-cross64 + # See comment in mips/iris[56].h files. + use_collect2=yes ++ objc_thread_file=thr-irix + ;; + mips-sgi-irix5*) # SGI System V.4., IRIX 5 + if [ x$gas = xyes ] +*************** +*** 1660,1665 **** +--- 1674,1680 ---- + tmake_file=mips/t-mips-gas + # See comment in mips/iris5.h file. + use_collect2=yes ++ objc_thread_file=thr-irix + ;; + mips-sgi-irix4loser*) # Mostly like a MIPS. + if [ x$stabs = xyes ]; then +*************** +*** 1680,1685 **** +--- 1695,1701 ---- + then + use_collect2=yes + fi ++ objc_thread_file=thr-irix + ;; + mips-sgi-irix4*) # Mostly like a MIPS. + if [ x$stabs = xyes ]; then +*************** +*** 1700,1705 **** +--- 1716,1722 ---- + then + use_collect2=yes + fi ++ objc_thread_file=thr-irix + ;; + mips-sgi-*) # Mostly like a MIPS. + if [ x$stabs = xyes ]; then +*************** +*** 2280,2285 **** +--- 2297,2303 ---- + extra_parts="crt1.o crti.o crtn.o gmon.o crtbegin.o crtend.o" + fixincludes=fixinc.svr4 + broken_install=yes ++ objc_thread_file=thr-solaris + ;; + sparc-*-sunos4.0*) + tm_file=sparc/sunos4.h +*************** +*** 2490,2495 **** +--- 2508,2518 ---- + then tmake_file=$cpu_type/t-$cpu_type + fi + ++ if [ x$objc_thread_file = x ] ++ then objc_thread_file=thr-single ++ fi ++ echo "Using \`$objc_thread_file' for Objective-C Runtime thread file." ++ + # Say what files are being used for the output code and MD file. + echo "Using \`$srcdir/config/$out_file' to output insns." + echo "Using \`$srcdir/config/$md_file' as machine description file." +*************** +*** 2982,2987 **** +--- 3005,3011 ---- + echo "s|^build_xm_file=.*$|build_xm_file=${srcdir}/config/${build_xm_file}|" >> Makefile.sed + echo "s|^lang_specs_files=.*$|lang_specs_files=${lang_specs_files}|" >> Makefile.sed + echo "s|^lang_options_files=.*$|lang_options_files=${lang_options_files}|" >> Makefile.sed ++ echo "s|^OBJC_THREAD_FILE=.*$|OBJC_THREAD_FILE=${objc_thread_file}|" >> Makefile.sed + echo "s|^prefix[ ]*=.*|prefix = $prefix|" >> Makefile.sed + echo "s|^gxx_include_dir[ ]*=.*|gxx_include_dir = $gxx_include_dir|" >> Makefile.sed + echo "s|^local_prefix[ ]*=.*|local_prefix = $local_prefix|" >> Makefile.sed +diff -rcP gcc-2.7.2.1/cp/parse.c gcc-2.7.2.1-objc-960906/cp/parse.c +*** gcc-2.7.2.1/cp/parse.c Fri Sep 6 11:28:34 1996 +--- gcc-2.7.2.1-objc-960906/cp/parse.c Fri Sep 6 10:33:05 1996 +*************** +*** 1,5 **** + +! /* A Bison parser, made from parse.y with Bison version GNU Bison version 1.22 + */ + + #define YYBISON 1 /* Identify Bison output. */ +--- 1,5 ---- + +! /* A Bison parser, made from parse.y with Bison version GNU Bison version 1.24 + */ + + #define YYBISON 1 /* Identify Bison output. */ +*************** +*** 669,675 **** + 3875, 3877, 3879, 3881, 3883, 3885, 3887, 3890, 3892 + }; + +! static const char * const yytname[] = { "$","error","$illegal.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT","BREAK","CONTINUE", + "RETURN","GOTO","ASM_KEYWORD","GCC_ASM_KEYWORD","TYPEOF","ALIGNOF","SIGOF","ATTRIBUTE", +--- 669,675 ---- + 3875, 3877, 3879, 3881, 3883, 3885, 3887, 3890, 3892 + }; + +! static const char * const yytname[] = { "$","error","$undefined.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT","BREAK","CONTINUE", + "RETURN","GOTO","ASM_KEYWORD","GCC_ASM_KEYWORD","TYPEOF","ALIGNOF","SIGOF","ATTRIBUTE", +*************** +*** 3157,3170 **** + 80, 81, 82 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/local/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman + + This program 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 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, +--- 3157,3170 ---- + 80, 81, 82 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program 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. + + This program is distributed in the hope that it will be useful, +*************** +*** 3176,3181 **** +--- 3176,3185 ---- + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++ /* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ + + #ifndef alloca + #ifdef __GNUC__ +*************** +*** 3249,3258 **** +--- 3253,3270 ---- + + #ifdef YYPURE + #ifdef YYLSP_NEEDED ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) ++ #else + #define YYLEX yylex(&yylval, &yylloc) ++ #endif ++ #else /* not YYLSP_NEEDED */ ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, YYLEX_PARAM) + #else + #define YYLEX yylex(&yylval) + #endif ++ #endif /* not YYLSP_NEEDED */ + #endif + + /* If nonreentrant, generate the variables here */ +*************** +*** 3300,3313 **** + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (from, to, count) + char *from; + char *to; + int count; +--- 3312,3325 ---- + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (from, to, count) + char *from; + char *to; + int count; +*************** +*** 3325,3331 **** + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +--- 3337,3343 ---- + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +*************** +*** 3338,3344 **** + #endif + #endif + +! #line 184 "/usr/local/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +--- 3350,3356 ---- + #endif + #endif + +! #line 192 "/usr/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +*************** +*** 3471,3482 **** + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +--- 3483,3494 ---- + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +*************** +*** 7546,7552 **** + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 480 "/usr/local/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +--- 7558,7564 ---- + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 487 "/usr/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +diff -rcP gcc-2.7.2.1/cpp.info gcc-2.7.2.1-objc-960906/cpp.info +*** gcc-2.7.2.1/cpp.info Fri Sep 6 11:20:29 1996 +--- gcc-2.7.2.1-objc-960906/cpp.info Fri Sep 6 10:25:16 1996 +*************** +*** 1,4 **** +! This is Info file cpp.info, produced by Makeinfo-1.55 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +--- 1,4 ---- +! This is Info file cpp.info, produced by Makeinfo-1.63 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +diff -rcP gcc-2.7.2.1/cpp.info-1 gcc-2.7.2.1-objc-960906/cpp.info-1 +*** gcc-2.7.2.1/cpp.info-1 Fri Sep 6 11:20:29 1996 +--- gcc-2.7.2.1-objc-960906/cpp.info-1 Fri Sep 6 10:25:17 1996 +*************** +*** 1,4 **** +! This is Info file cpp.info, produced by Makeinfo-1.55 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +--- 1,4 ---- +! This is Info file cpp.info, produced by Makeinfo-1.63 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +diff -rcP gcc-2.7.2.1/cpp.info-2 gcc-2.7.2.1-objc-960906/cpp.info-2 +*** gcc-2.7.2.1/cpp.info-2 Fri Sep 6 11:20:30 1996 +--- gcc-2.7.2.1-objc-960906/cpp.info-2 Fri Sep 6 10:25:18 1996 +*************** +*** 1,4 **** +! This is Info file cpp.info, produced by Makeinfo-1.55 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +--- 1,4 ---- +! This is Info file cpp.info, produced by Makeinfo-1.63 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +diff -rcP gcc-2.7.2.1/cpp.info-3 gcc-2.7.2.1-objc-960906/cpp.info-3 +*** gcc-2.7.2.1/cpp.info-3 Fri Sep 6 11:20:31 1996 +--- gcc-2.7.2.1-objc-960906/cpp.info-3 Fri Sep 6 10:25:18 1996 +*************** +*** 1,4 **** +! This is Info file cpp.info, produced by Makeinfo-1.55 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +--- 1,4 ---- +! This is Info file cpp.info, produced by Makeinfo-1.63 from the input + file cpp.texi. + + This file documents the GNU C Preprocessor. +*************** +*** 430,466 **** + * -Wcomment: Invocation. + * -Wtraditional: Invocation. + * -Wtrigraphs: Invocation. +- * BSD: Nonstandard Predefined. +- * defined: Conditionals-Macros. +- * M68020: Nonstandard Predefined. +- * m68k: Nonstandard Predefined. +- * mc68000: Nonstandard Predefined. +- * ns32000: Nonstandard Predefined. +- * pyr: Nonstandard Predefined. +- * sequent: Nonstandard Predefined. +- * sun: Nonstandard Predefined. +- * system header files: Header Uses. +- * unix: Nonstandard Predefined. +- * vax: Nonstandard Predefined. +- * _AM29000: Nonstandard Predefined. +- * _AM29K: Nonstandard Predefined. + * __BASE_FILE__: Standard Predefined. + * __CHAR_UNSIGNED__: Standard Predefined. + * __cplusplus: Standard Predefined. + * __DATE__: Standard Predefined. + * __FILE__: Standard Predefined. +- * __GNUC_MINOR__: Standard Predefined. + * __GNUC__: Standard Predefined. + * __GNUG__: Standard Predefined. + * __INCLUDE_LEVEL_: Standard Predefined. + * __LINE__: Standard Predefined. + * __OPTIMIZE__: Standard Predefined. + * __REGISTER_PREFIX__: Standard Predefined. +- * __STDC_VERSION__: Standard Predefined. + * __STDC__: Standard Predefined. + * __STRICT_ANSI__: Standard Predefined. + * __TIME__: Standard Predefined. + * __USER_LABEL_PREFIX__: Standard Predefined. + * __VERSION__: Standard Predefined. + + +--- 430,466 ---- + * -Wcomment: Invocation. + * -Wtraditional: Invocation. + * -Wtrigraphs: Invocation. + * __BASE_FILE__: Standard Predefined. + * __CHAR_UNSIGNED__: Standard Predefined. + * __cplusplus: Standard Predefined. + * __DATE__: Standard Predefined. + * __FILE__: Standard Predefined. + * __GNUC__: Standard Predefined. ++ * __GNUC_MINOR__: Standard Predefined. + * __GNUG__: Standard Predefined. + * __INCLUDE_LEVEL_: Standard Predefined. + * __LINE__: Standard Predefined. + * __OPTIMIZE__: Standard Predefined. + * __REGISTER_PREFIX__: Standard Predefined. + * __STDC__: Standard Predefined. ++ * __STDC_VERSION__: Standard Predefined. + * __STRICT_ANSI__: Standard Predefined. + * __TIME__: Standard Predefined. + * __USER_LABEL_PREFIX__: Standard Predefined. + * __VERSION__: Standard Predefined. ++ * _AM29000: Nonstandard Predefined. ++ * _AM29K: Nonstandard Predefined. ++ * BSD: Nonstandard Predefined. ++ * defined: Conditionals-Macros. ++ * M68020: Nonstandard Predefined. ++ * m68k: Nonstandard Predefined. ++ * mc68000: Nonstandard Predefined. ++ * ns32000: Nonstandard Predefined. ++ * pyr: Nonstandard Predefined. ++ * sequent: Nonstandard Predefined. ++ * sun: Nonstandard Predefined. ++ * system header files: Header Uses. ++ * unix: Nonstandard Predefined. ++ * vax: Nonstandard Predefined. + + +diff -rcP gcc-2.7.2.1/expr.c gcc-2.7.2.1-objc-960906/expr.c +*** gcc-2.7.2.1/expr.c Fri Sep 6 11:20:58 1996 +--- gcc-2.7.2.1-objc-960906/expr.c Fri Sep 6 10:25:42 1996 +*************** +*** 8290,8296 **** +--- 8290,8304 ---- + + /* Push a new argument block and copy the arguments. */ + do_pending_stack_adjust (); ++ ++ /* For now use SAVE_NONLOCAL on PPC architectures as it does not ++ have SAVE_BLOCK. This should possibly be changed to check the ++ insn-flag HAVE_save_stack_block? */ ++ #ifdef __PPC__ ++ emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX); ++ #else + emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX); ++ #endif /* __PPC__ */ + + /* Push a block of memory onto the stack to store the memory arguments. + Save the address in a register, and copy the memory arguments. ??? I +*************** +*** 8416,8422 **** +--- 8424,8437 ---- + CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage; + + /* Restore the stack. */ ++ /* For now use SAVE_NONLOCAL on PPC architectures as it does not ++ have SAVE_BLOCK. This should possibly be changed to check the ++ insn-flag HAVE_save_stack_block? */ ++ #ifdef __PPC__ ++ emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX); ++ #else + emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX); ++ #endif /* __PPC__ */ + + /* Return the address of the result block. */ + return copy_addr_to_reg (XEXP (result, 0)); +diff -rcP gcc-2.7.2.1/gcc.info gcc-2.7.2.1-objc-960906/gcc.info +*** gcc-2.7.2.1/gcc.info Fri Sep 6 11:21:20 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info Fri Sep 6 10:26:03 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 32,61 **** +  + Indirect: + gcc.info-1: 1382 +! gcc.info-2: 42854 +! gcc.info-3: 80578 +! gcc.info-4: 127608 +! gcc.info-5: 173792 +! gcc.info-6: 214726 +! gcc.info-7: 235436 +! gcc.info-8: 285158 +! gcc.info-9: 333642 +! gcc.info-10: 382691 +! gcc.info-11: 419654 +! gcc.info-12: 468472 +! gcc.info-13: 517503 +! gcc.info-14: 564845 +! gcc.info-15: 604398 +! gcc.info-16: 654371 +! gcc.info-17: 703324 +! gcc.info-18: 751502 +! gcc.info-19: 797360 +! gcc.info-20: 846162 +! gcc.info-21: 890260 +! gcc.info-22: 933466 +! gcc.info-23: 982355 +! gcc.info-24: 1032258 +! gcc.info-25: 1067513 +  + Tag Table: + (Indirect) +--- 32,61 ---- +  + Indirect: + gcc.info-1: 1382 +! gcc.info-2: 43097 +! gcc.info-3: 80821 +! gcc.info-4: 127851 +! gcc.info-5: 174035 +! gcc.info-6: 214969 +! gcc.info-7: 237409 +! gcc.info-8: 286095 +! gcc.info-9: 334579 +! gcc.info-10: 383628 +! gcc.info-11: 420591 +! gcc.info-12: 469430 +! gcc.info-13: 518461 +! gcc.info-14: 565803 +! gcc.info-15: 605356 +! gcc.info-16: 655329 +! gcc.info-17: 704282 +! gcc.info-18: 752460 +! gcc.info-19: 798318 +! gcc.info-20: 847120 +! gcc.info-21: 891218 +! gcc.info-22: 934424 +! gcc.info-23: 983313 +! gcc.info-24: 1033216 +! gcc.info-25: 1068471 +  + Tag Table: + (Indirect) +*************** +*** 64,297 **** + Node: Contributors22249 + Node: Funding27395 + Node: Look and Feel29892 +! Node: G++ and GCC37258 +! Node: Invoking GCC39475 +! Node: Option Summary42854 +! Node: Overall Options53305 +! Node: Invoking G++57868 +! Node: C Dialect Options59742 +! Node: C++ Dialect Options69842 +! Node: Warning Options80578 +! Node: Debugging Options95513 +! Node: Optimize Options105094 +! Node: Preprocessor Options115596 +! Node: Assembler Options122059 +! Node: Link Options122426 +! Node: Directory Options127608 +! Node: Target Options131100 +! Node: Submodel Options134757 +! Node: M680x0 Options136138 +! Node: VAX Options139647 +! Node: SPARC Options140182 +! Node: Convex Options146602 +! Node: AMD29K Options148783 +! Node: ARM Options151814 +! Node: M88K Options153231 +! Node: RS/6000 and PowerPC Options161178 +! Node: RT Options172088 +! Node: MIPS Options173792 +! Node: i386 Options181418 +! Node: HPPA Options186857 +! Node: Intel 960 Options189953 +! Node: DEC Alpha Options192563 +! Node: Clipper Options194235 +! Node: H8/300 Options194634 +! Node: System V Options195079 +! Node: Code Gen Options195765 +! Node: Environment Variables204274 +! Node: Running Protoize208497 +! Node: Installation214726 +! Node: Configurations235436 +! Node: Other Dir271347 +! Node: Cross-Compiler273063 +! Node: Steps of Cross274894 +! Node: Configure Cross276012 +! Node: Tools and Libraries276649 +! Node: Cross Runtime279092 +! Node: Cross Headers283173 +! Node: Build Cross285158 +! Node: Sun Install287034 +! Node: VMS Install288166 +! Node: Collect2298095 +! Node: Header Dirs300804 +! Node: C Extensions302218 +! Node: Statement Exprs305497 +! Node: Local Labels307391 +! Node: Labels as Values309453 +! Node: Nested Functions311318 +! Node: Constructing Calls315174 +! Node: Naming Types317231 +! Node: Typeof318325 +! Node: Lvalues320190 +! Node: Conditionals322630 +! Node: Long Long323521 +! Node: Complex324965 +! Node: Zero Length326827 +! Node: Variable Length327501 +! Node: Macro Varargs330026 +! Node: Subscripting332129 +! Node: Pointer Arith332612 +! Node: Initializers333177 +! Node: Constructors333642 +! Node: Labeled Elements335336 +! Node: Case Ranges337965 +! Node: Cast to Union338646 +! Node: Function Attributes339724 +! Node: Function Prototypes348987 +! Node: C++ Comments350786 +! Node: Dollar Signs351322 +! Node: Character Escapes352102 +! Node: Alignment352383 +! Node: Variable Attributes353855 +! Node: Type Attributes361763 +! Node: Inline368282 +! Node: Extended Asm372159 +! Node: Asm Labels382691 +! Node: Explicit Reg Vars384010 +! Node: Global Reg Vars385258 +! Node: Local Reg Vars389823 +! Node: Alternate Keywords391415 +! Node: Incomplete Enums392817 +! Node: Function Names393573 +! Node: C++ Extensions394824 +! Node: Naming Results396061 +! Node: Min and Max399375 +! Node: Destructors and Goto400825 +! Node: C++ Interface401375 +! Node: Template Instantiation406598 +! Node: C++ Signatures412330 +! Node: Trouble416674 +! Node: Actual Bugs418385 +! Node: Installation Problems419654 +! Node: Cross-Compiler Problems433440 +! Node: Interoperation434911 +! Node: External Bugs448275 +! Node: Incompatibilities450407 +! Node: Fixed Headers458957 +! Node: Standard Libraries461299 +! Node: Disappointments462546 +! Node: C++ Misunderstandings466771 +! Node: Static Definitions467418 +! Node: Temporaries468472 +! Node: Protoize Caveats470676 +! Node: Non-bugs474632 +! Node: Warnings and Errors483592 +! Node: Bugs485362 +! Node: Bug Criteria486722 +! Node: Bug Lists489152 +! Node: Bug Reporting490545 +! Node: Sending Patches502963 +! Node: Service508350 +! Node: VMS508911 +! Node: Include Files and VMS509304 +! Node: Global Declarations513194 +! Node: VMS Misc517503 +! Node: Portability521829 +! Node: Interface523592 +! Node: Passes528225 +! Node: RTL545568 +! Node: RTL Objects547456 +! Node: Accessors550500 +! Node: Flags555826 +! Node: Machine Modes564845 +! Node: Constants572479 +! Node: Regs and Memory577667 +! Node: Arithmetic589377 +! Node: Comparisons595275 +! Node: Bit Fields599337 +! Node: Conversions600701 +! Node: RTL Declarations603589 +! Node: Side Effects604398 +! Node: Incdec616945 +! Node: Assembler619461 +! Node: Insns620983 +! Node: Calls641836 +! Node: Sharing644431 +! Node: Reading RTL647507 +! Node: Machine Desc648446 +! Node: Patterns650299 +! Node: Example653243 +! Node: RTL Template654371 +! Node: Output Template666569 +! Node: Output Statement670530 +! Node: Constraints674243 +! Node: Simple Constraints675246 +! Node: Multi-Alternative686679 +! Node: Class Preferences689515 +! Node: Modifiers690395 +! Node: Machine Constraints693555 +! Node: No Constraints702203 +! Node: Standard Names703324 +! Node: Pattern Ordering731232 +! Node: Dependent Patterns732458 +! Node: Jump Patterns735273 +! Node: Insn Canonicalizations741089 +! Node: Peephole Definitions744584 +! Node: Expander Definitions751502 +! Node: Insn Splitting758948 +! Node: Insn Attributes765962 +! Node: Defining Attributes767009 +! Node: Expressions769021 +! Node: Tagging Insns775333 +! Node: Attr Example779696 +! Node: Insn Lengths782072 +! Node: Constant Attributes785436 +! Node: Delay Slots786596 +! Node: Function Units789807 +! Node: Target Macros795477 +! Node: Driver797360 +! Node: Run-time Target809090 +! Node: Storage Layout814977 +! Node: Type Layout828925 +! Node: Registers835348 +! Node: Register Basics836328 +! Node: Allocation Order840365 +! Node: Values in Registers841783 +! Node: Leaf Functions846162 +! Node: Stack Registers848637 +! Node: Obsolete Register Macros849470 +! Node: Register Classes852165 +! Node: Stack and Calling871700 +! Node: Frame Layout872136 +! Node: Frame Registers875576 +! Node: Elimination879386 +! Node: Stack Arguments883642 +! Node: Register Arguments890260 +! Node: Scalar Return898935 +! Node: Aggregate Return902898 +! Node: Caller Saves906613 +! Node: Function Entry907763 +! Node: Profiling916691 +! Node: Varargs919595 +! Node: Trampolines927004 +! Node: Library Calls933466 +! Node: Addressing Modes941524 +! Node: Condition Code949112 +! Node: Costs955311 +! Node: Sections963690 +! Node: PIC968479 +! Node: Assembler Format971189 +! Node: File Framework972194 +! Node: Data Output976431 +! Node: Uninitialized Data982355 +! Node: Label Output985062 +! Node: Initialization994456 +! Node: Macros for Initialization1000599 +! Node: Instruction Output1005196 +! Node: Dispatch Tables1013191 +! Node: Alignment Output1015568 +! Node: Debugging Info1017308 +! Node: All Debuggers1017917 +! Node: DBX Options1020331 +! Node: DBX Hooks1025216 +! Node: File Names and DBX1028555 +! Node: SDB and DWARF1030528 +! Node: Cross-compilation1032258 +! Node: Misc1038705 +! Node: Config1055831 +! Node: Fragments1063276 +! Node: Target Fragment1063873 +! Node: Host Fragment1066911 +! Node: Index1067513 +  + End Tag Table +--- 64,297 ---- + Node: Contributors22249 + Node: Funding27395 + Node: Look and Feel29892 +! Node: G++ and GCC37501 +! Node: Invoking GCC39718 +! Node: Option Summary43097 +! Node: Overall Options53548 +! Node: Invoking G++58111 +! Node: C Dialect Options59985 +! Node: C++ Dialect Options70085 +! Node: Warning Options80821 +! Node: Debugging Options95756 +! Node: Optimize Options105337 +! Node: Preprocessor Options115839 +! Node: Assembler Options122302 +! Node: Link Options122669 +! Node: Directory Options127851 +! Node: Target Options131343 +! Node: Submodel Options135000 +! Node: M680x0 Options136381 +! Node: VAX Options139890 +! Node: SPARC Options140425 +! Node: Convex Options146845 +! Node: AMD29K Options149026 +! Node: ARM Options152057 +! Node: M88K Options153474 +! Node: RS/6000 and PowerPC Options161421 +! Node: RT Options172331 +! Node: MIPS Options174035 +! Node: i386 Options181661 +! Node: HPPA Options187100 +! Node: Intel 960 Options190196 +! Node: DEC Alpha Options192806 +! Node: Clipper Options194478 +! Node: H8/300 Options194877 +! Node: System V Options195322 +! Node: Code Gen Options196008 +! Node: Environment Variables204517 +! Node: Running Protoize208740 +! Node: Installation214969 +! Node: Configurations237409 +! Node: Other Dir272284 +! Node: Cross-Compiler274000 +! Node: Steps of Cross275831 +! Node: Configure Cross276949 +! Node: Tools and Libraries277586 +! Node: Cross Runtime280029 +! Node: Cross Headers284110 +! Node: Build Cross286095 +! Node: Sun Install287971 +! Node: VMS Install289103 +! Node: Collect2299032 +! Node: Header Dirs301741 +! Node: C Extensions303155 +! Node: Statement Exprs306434 +! Node: Local Labels308328 +! Node: Labels as Values310390 +! Node: Nested Functions312255 +! Node: Constructing Calls316111 +! Node: Naming Types318168 +! Node: Typeof319262 +! Node: Lvalues321127 +! Node: Conditionals323567 +! Node: Long Long324458 +! Node: Complex325902 +! Node: Zero Length327764 +! Node: Variable Length328438 +! Node: Macro Varargs330963 +! Node: Subscripting333066 +! Node: Pointer Arith333549 +! Node: Initializers334114 +! Node: Constructors334579 +! Node: Labeled Elements336273 +! Node: Case Ranges338902 +! Node: Cast to Union339583 +! Node: Function Attributes340661 +! Node: Function Prototypes349924 +! Node: C++ Comments351723 +! Node: Dollar Signs352259 +! Node: Character Escapes353039 +! Node: Alignment353320 +! Node: Variable Attributes354792 +! Node: Type Attributes362700 +! Node: Inline369219 +! Node: Extended Asm373096 +! Node: Asm Labels383628 +! Node: Explicit Reg Vars384947 +! Node: Global Reg Vars386195 +! Node: Local Reg Vars390760 +! Node: Alternate Keywords392352 +! Node: Incomplete Enums393754 +! Node: Function Names394510 +! Node: C++ Extensions395761 +! Node: Naming Results396998 +! Node: Min and Max400312 +! Node: Destructors and Goto401762 +! Node: C++ Interface402312 +! Node: Template Instantiation407535 +! Node: C++ Signatures413267 +! Node: Trouble417611 +! Node: Actual Bugs419322 +! Node: Installation Problems420591 +! Node: Cross-Compiler Problems434398 +! Node: Interoperation435869 +! Node: External Bugs449233 +! Node: Incompatibilities451365 +! Node: Fixed Headers459915 +! Node: Standard Libraries462257 +! Node: Disappointments463504 +! Node: C++ Misunderstandings467729 +! Node: Static Definitions468376 +! Node: Temporaries469430 +! Node: Protoize Caveats471634 +! Node: Non-bugs475590 +! Node: Warnings and Errors484550 +! Node: Bugs486320 +! Node: Bug Criteria487680 +! Node: Bug Lists490110 +! Node: Bug Reporting491503 +! Node: Sending Patches503921 +! Node: Service509308 +! Node: VMS509869 +! Node: Include Files and VMS510262 +! Node: Global Declarations514152 +! Node: VMS Misc518461 +! Node: Portability522787 +! Node: Interface524550 +! Node: Passes529183 +! Node: RTL546526 +! Node: RTL Objects548414 +! Node: Accessors551458 +! Node: Flags556784 +! Node: Machine Modes565803 +! Node: Constants573437 +! Node: Regs and Memory578625 +! Node: Arithmetic590335 +! Node: Comparisons596233 +! Node: Bit Fields600295 +! Node: Conversions601659 +! Node: RTL Declarations604547 +! Node: Side Effects605356 +! Node: Incdec617903 +! Node: Assembler620419 +! Node: Insns621941 +! Node: Calls642794 +! Node: Sharing645389 +! Node: Reading RTL648465 +! Node: Machine Desc649404 +! Node: Patterns651257 +! Node: Example654201 +! Node: RTL Template655329 +! Node: Output Template667527 +! Node: Output Statement671488 +! Node: Constraints675201 +! Node: Simple Constraints676204 +! Node: Multi-Alternative687637 +! Node: Class Preferences690473 +! Node: Modifiers691353 +! Node: Machine Constraints694513 +! Node: No Constraints703161 +! Node: Standard Names704282 +! Node: Pattern Ordering732190 +! Node: Dependent Patterns733416 +! Node: Jump Patterns736231 +! Node: Insn Canonicalizations742047 +! Node: Peephole Definitions745542 +! Node: Expander Definitions752460 +! Node: Insn Splitting759906 +! Node: Insn Attributes766920 +! Node: Defining Attributes767967 +! Node: Expressions769979 +! Node: Tagging Insns776291 +! Node: Attr Example780654 +! Node: Insn Lengths783030 +! Node: Constant Attributes786394 +! Node: Delay Slots787554 +! Node: Function Units790765 +! Node: Target Macros796435 +! Node: Driver798318 +! Node: Run-time Target810048 +! Node: Storage Layout815935 +! Node: Type Layout829883 +! Node: Registers836306 +! Node: Register Basics837286 +! Node: Allocation Order841323 +! Node: Values in Registers842741 +! Node: Leaf Functions847120 +! Node: Stack Registers849595 +! Node: Obsolete Register Macros850428 +! Node: Register Classes853123 +! Node: Stack and Calling872658 +! Node: Frame Layout873094 +! Node: Frame Registers876534 +! Node: Elimination880344 +! Node: Stack Arguments884600 +! Node: Register Arguments891218 +! Node: Scalar Return899893 +! Node: Aggregate Return903856 +! Node: Caller Saves907571 +! Node: Function Entry908721 +! Node: Profiling917649 +! Node: Varargs920553 +! Node: Trampolines927962 +! Node: Library Calls934424 +! Node: Addressing Modes942482 +! Node: Condition Code950070 +! Node: Costs956269 +! Node: Sections964648 +! Node: PIC969437 +! Node: Assembler Format972147 +! Node: File Framework973152 +! Node: Data Output977389 +! Node: Uninitialized Data983313 +! Node: Label Output986020 +! Node: Initialization995414 +! Node: Macros for Initialization1001557 +! Node: Instruction Output1006154 +! Node: Dispatch Tables1014149 +! Node: Alignment Output1016526 +! Node: Debugging Info1018266 +! Node: All Debuggers1018875 +! Node: DBX Options1021289 +! Node: DBX Hooks1026174 +! Node: File Names and DBX1029513 +! Node: SDB and DWARF1031486 +! Node: Cross-compilation1033216 +! Node: Misc1039663 +! Node: Config1056789 +! Node: Fragments1064234 +! Node: Target Fragment1064831 +! Node: Host Fragment1067869 +! Node: Index1068471 +  + End Tag Table +diff -rcP gcc-2.7.2.1/gcc.info-1 gcc-2.7.2.1-objc-960906/gcc.info-1 +*** gcc-2.7.2.1/gcc.info-1 Fri Sep 6 11:21:21 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-1 Fri Sep 6 10:26:04 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 653,670 **** + reasons only partly related to the general issue of interface copyright. + + Lotus won lawsuits against two small companies, which were thus put +! out of business. Then they sued Borland; they won in the trial court + (no surprise, since it was the same court that had ruled for Lotus twice +! before), but the decision was reversed by the court of appeals, with +! help from the League for Programming Freedom in the form of a +! friend-of-the-court brief. We are now waiting to see if the Supreme +! Court will hear the case. If it does, the League for Programming +! Freedom will again submit a brief. +! +! The battle is not over. Just this summer a company that produced a +! simulator for a CDC computer was shut down by a copyright lawsuit by +! CDC, which charged that the simulator infringed the copyright on the +! manuals for the computer. + + If the monopolists get their way, they will hobble the software + field: +--- 653,675 ---- + reasons only partly related to the general issue of interface copyright. + + Lotus won lawsuits against two small companies, which were thus put +! out of business. Then Lotus sued Borland; Lotus won in the trial court + (no surprise, since it was the same court that had ruled for Lotus twice +! before), but the court of appeals ruled in favor of Borland, which was +! assisted by a friend-of-the-court brief from the League for Programming +! Freedom. +! +! Lotus appealed the case to the Supreme Court, which heard the case +! but was unable to reach a decision. This failure means that the appeals +! court decision stands, in one portion of the United States, and may +! influence the other appeals courts, but it does not set a nationwide +! precedent. The battle is not over, and it is not limited to the United +! States. +! +! The battle is extending into other areas of software as well. In +! 1995 a company that produced a simulator for a CDC computer was shut +! down by a copyright lawsuit, in which CDC charged that the simulator +! infringed the copyright on the manuals for the computer. + + If the monopolists get their way, they will hobble the software + field: +diff -rcP gcc-2.7.2.1/gcc.info-10 gcc-2.7.2.1-objc-960906/gcc.info-10 +*** gcc-2.7.2.1/gcc.info-10 Fri Sep 6 11:21:22 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-10 Fri Sep 6 10:26:05 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-11 gcc-2.7.2.1-objc-960906/gcc.info-11 +*** gcc-2.7.2.1/gcc.info-11 Fri Sep 6 11:21:23 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-11 Fri Sep 6 10:26:05 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 85,95 **** + GNU CC. The fix is to get rid of the file `real-ld' which purify + installs--so that GNU CC won't try to use it. + +! * On Linux SLS 1.01, there is a problem with `libc.a': it does not +! contain the obstack functions. However, GNU CC assumes that the +! obstack functions are in `libc.a' when it is the GNU C library. +! To work around this problem, change the `__GNU_LIBRARY__' +! conditional around line 31 to `#if 1'. + + * On some 386 systems, building the compiler never finishes because + `enquire' hangs due to a hardware problem in the motherboard--it +--- 85,95 ---- + GNU CC. The fix is to get rid of the file `real-ld' which purify + installs--so that GNU CC won't try to use it. + +! * On SLS 1.01, a Linux-based GNU system, there is a problem with +! `libc.a': it does not contain the obstack functions. However, GNU +! CC assumes that the obstack functions are in `libc.a' when it is +! the GNU C library. To work around this problem, change the +! `__GNU_LIBRARY__' conditional around line 31 to `#if 1'. + + * On some 386 systems, building the compiler never finishes because + `enquire' hangs due to a hardware problem in the motherboard--it +diff -rcP gcc-2.7.2.1/gcc.info-12 gcc-2.7.2.1-objc-960906/gcc.info-12 +*** gcc-2.7.2.1/gcc.info-12 Fri Sep 6 11:21:24 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-12 Fri Sep 6 10:26:06 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-13 gcc-2.7.2.1-objc-960906/gcc.info-13 +*** gcc-2.7.2.1/gcc.info-13 Fri Sep 6 11:21:25 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-13 Fri Sep 6 10:26:07 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-14 gcc-2.7.2.1-objc-960906/gcc.info-14 +*** gcc-2.7.2.1/gcc.info-14 Fri Sep 6 11:21:25 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-14 Fri Sep 6 10:26:08 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 909,915 **** + + `(float_extend:M X)' + Represents the result of extending the value X to machine mode M. +! m must be a floating point mode and X a floating point value of a + mode narrower than M. + + `(truncate:M X)' +--- 909,915 ---- + + `(float_extend:M X)' + Represents the result of extending the value X to machine mode M. +! M must be a floating point mode and X a floating point value of a + mode narrower than M. + + `(truncate:M X)' +diff -rcP gcc-2.7.2.1/gcc.info-15 gcc-2.7.2.1-objc-960906/gcc.info-15 +*** gcc-2.7.2.1/gcc.info-15 Fri Sep 6 11:21:26 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-15 Fri Sep 6 10:26:09 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 295,302 **** + `(pre_dec:M X)' + Represents the side effect of decrementing X by a standard amount + and represents also the value that X has after being decremented. +! x must be a `reg' or `mem', but most machines allow only a `reg'. +! m must be the machine mode for pointers on the machine in use. + The amount X is decremented by is the length in bytes of the + machine mode of the containing memory reference of which this + expression serves as the address. Here is an example of its use: +--- 295,302 ---- + `(pre_dec:M X)' + Represents the side effect of decrementing X by a standard amount + and represents also the value that X has after being decremented. +! X must be a `reg' or `mem', but most machines allow only a `reg'. +! M must be the machine mode for pointers on the machine in use. + The amount X is decremented by is the length in bytes of the + machine mode of the containing memory reference of which this + expression serves as the address. Here is an example of its use: +diff -rcP gcc-2.7.2.1/gcc.info-16 gcc-2.7.2.1-objc-960906/gcc.info-16 +*** gcc-2.7.2.1/gcc.info-16 Fri Sep 6 11:21:27 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-16 Fri Sep 6 10:26:10 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-17 gcc-2.7.2.1-objc-960906/gcc.info-17 +*** gcc-2.7.2.1/gcc.info-17 Fri Sep 6 11:21:28 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-17 Fri Sep 6 10:26:10 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 385,391 **** + `sCOND' + Store zero or nonzero in the operand according to the condition + codes. Value stored is nonzero iff the condition COND is true. +! cOND is the name of a comparison operation expression code, such + as `eq', `lt' or `leu'. + + You specify the mode that the operand must have when you write the +--- 385,391 ---- + `sCOND' + Store zero or nonzero in the operand according to the condition + codes. Value stored is nonzero iff the condition COND is true. +! COND is the name of a comparison operation expression code, such + as `eq', `lt' or `leu'. + + You specify the mode that the operand must have when you write the +diff -rcP gcc-2.7.2.1/gcc.info-18 gcc-2.7.2.1-objc-960906/gcc.info-18 +*** gcc-2.7.2.1/gcc.info-18 Fri Sep 6 11:21:29 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-18 Fri Sep 6 10:26:11 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-19 gcc-2.7.2.1-objc-960906/gcc.info-19 +*** gcc-2.7.2.1/gcc.info-19 Fri Sep 6 11:21:29 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-19 Fri Sep 6 10:26:12 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-2 gcc-2.7.2.1-objc-960906/gcc.info-2 +*** gcc-2.7.2.1/gcc.info-2 Fri Sep 6 11:21:30 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-2 Fri Sep 6 10:26:12 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-20 gcc-2.7.2.1-objc-960906/gcc.info-20 +*** gcc-2.7.2.1/gcc.info-20 Fri Sep 6 11:21:31 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-20 Fri Sep 6 10:26:13 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 657,663 **** + `RETURN_ADDR_RTX (COUNT, FRAMEADDR)' + A C expression whose value is RTL representing the value of the + return address for the frame COUNT steps up from the current frame. +! fRAMEADDR is the frame pointer of the COUNT frame, or the frame + pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' + is defined. + +--- 657,663 ---- + `RETURN_ADDR_RTX (COUNT, FRAMEADDR)' + A C expression whose value is RTL representing the value of the + return address for the frame COUNT steps up from the current frame. +! FRAMEADDR is the frame pointer of the COUNT frame, or the frame + pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' + is defined. + +diff -rcP gcc-2.7.2.1/gcc.info-21 gcc-2.7.2.1-objc-960906/gcc.info-21 +*** gcc-2.7.2.1/gcc.info-21 Fri Sep 6 11:21:32 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-21 Fri Sep 6 10:26:14 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 841,847 **** + + `INITIALIZE_TRAMPOLINE (ADDR, FNADDR, STATIC_CHAIN)' + A C statement to initialize the variable parts of a trampoline. +! aDDR is an RTX for the address of the trampoline; FNADDR is an RTX + for the address of the nested function; STATIC_CHAIN is an RTX for + the static chain value that should be passed to the function when + it is called. +--- 841,847 ---- + + `INITIALIZE_TRAMPOLINE (ADDR, FNADDR, STATIC_CHAIN)' + A C statement to initialize the variable parts of a trampoline. +! ADDR is an RTX for the address of the trampoline; FNADDR is an RTX + for the address of the nested function; STATIC_CHAIN is an RTX for + the static chain value that should be passed to the function when + it is called. +diff -rcP gcc-2.7.2.1/gcc.info-22 gcc-2.7.2.1-objc-960906/gcc.info-22 +*** gcc-2.7.2.1/gcc.info-22 Fri Sep 6 11:21:32 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-22 Fri Sep 6 10:26:14 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-23 gcc-2.7.2.1-objc-960906/gcc.info-23 +*** gcc-2.7.2.1/gcc.info-23 Fri Sep 6 11:21:33 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-23 Fri Sep 6 10:26:15 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-24 gcc-2.7.2.1-objc-960906/gcc.info-24 +*** gcc-2.7.2.1/gcc.info-24 Fri Sep 6 11:21:34 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-24 Fri Sep 6 10:26:15 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 100,106 **** + A macro whose definition is a C expression to round the + target-machine floating point value X towards zero to an unsigned + integer value (but still represented as a floating point number). +! x has type `REAL_VALUE_TYPE', and so does the value. + + `REAL_VALUE_ATOF (STRING, MODE)' + A macro for a C expression which converts STRING, an expression of +--- 100,106 ---- + A macro whose definition is a C expression to round the + target-machine floating point value X towards zero to an unsigned + integer value (but still represented as a floating point number). +! X has type `REAL_VALUE_TYPE', and so does the value. + + `REAL_VALUE_ATOF (STRING, MODE)' + A macro for a C expression which converts STRING, an expression of +diff -rcP gcc-2.7.2.1/gcc.info-25 gcc-2.7.2.1-objc-960906/gcc.info-25 +*** gcc-2.7.2.1/gcc.info-25 Fri Sep 6 11:21:36 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-25 Fri Sep 6 10:26:17 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 53,59 **** + * -lgcc, use with -nostdlib: Link Options. + * -nodefaultlibs and unresolved references: Link Options. + * -nostdlib and unresolved references: Link Options. +! * ?: extensions: Conditionals. + * ?: extensions: Lvalues. + * absM2 instruction pattern: Standard Names. + * abs and attributes: Expressions. +--- 53,59 ---- + * -lgcc, use with -nostdlib: Link Options. + * -nodefaultlibs and unresolved references: Link Options. + * -nostdlib and unresolved references: Link Options. +! * ?: extensions <1>: Conditionals. + * ?: extensions: Lvalues. + * absM2 instruction pattern: Standard Names. + * abs and attributes: Expressions. +*************** +*** 62,68 **** + * addr_diff_vec, length of: Insn Lengths. + * addr_vec, length of: Insn Lengths. + * alias attribute: Function Attributes. +! * aligned attribute: Type Attributes. + * aligned attribute: Variable Attributes. + * allocate_stack instruction pattern: Standard Names. + * alloca and SunOs: Installation. +--- 62,68 ---- + * addr_diff_vec, length of: Insn Lengths. + * addr_vec, length of: Insn Lengths. + * alias attribute: Function Attributes. +! * aligned attribute <1>: Type Attributes. + * aligned attribute: Variable Attributes. + * allocate_stack instruction pattern: Standard Names. + * alloca and SunOs: Installation. +*************** +*** 98,109 **** + * code_label and /i: Flags. + * compare, canonicalization of: Insn Canonicalizations. + * cond and attributes: Expressions. +- * constructor function attribute: Function Attributes. + * const_double, RTL sharing: Sharing. + * const_int and attribute tests: Expressions. + * const_int and attributes: Expressions. + * const_int, RTL sharing: Sharing. + * const_string and attributes: Expressions. + * const applied to function: Function Attributes. + * const function attribute: Function Attributes. + * define_insn example: Example. +--- 98,109 ---- + * code_label and /i: Flags. + * compare, canonicalization of: Insn Canonicalizations. + * cond and attributes: Expressions. + * const_double, RTL sharing: Sharing. + * const_int and attribute tests: Expressions. + * const_int and attributes: Expressions. + * const_int, RTL sharing: Sharing. + * const_string and attributes: Expressions. ++ * constructor function attribute: Function Attributes. + * const applied to function: Function Attributes. + * const function attribute: Function Attributes. + * define_insn example: Example. +*************** +*** 122,130 **** + * ffsM2 instruction pattern: Standard Names. + * FIRST_PARM_OFFSET and virtual registers: Regs and Memory. + * fixMN2 instruction pattern: Standard Names. + * fixunsMN2 instruction pattern: Standard Names. + * fixuns_truncMN2 instruction pattern: Standard Names. +- * fix_truncMN2 instruction pattern: Standard Names. + * floatMN2 instruction pattern: Standard Names. + * floatunsMN2 instruction pattern: Standard Names. + * float as function value type: Incompatibilities. +--- 122,130 ---- + * ffsM2 instruction pattern: Standard Names. + * FIRST_PARM_OFFSET and virtual registers: Regs and Memory. + * fixMN2 instruction pattern: Standard Names. ++ * fix_truncMN2 instruction pattern: Standard Names. + * fixunsMN2 instruction pattern: Standard Names. + * fixuns_truncMN2 instruction pattern: Standard Names. + * floatMN2 instruction pattern: Standard Names. + * floatunsMN2 instruction pattern: Standard Names. + * float as function value type: Incompatibilities. +*************** +*** 148,153 **** +--- 148,159 ---- + * HImode, in insn: Insns. + * if_then_else and attributes: Expressions. + * if_then_else usage: Side Effects. ++ * in_struct, in code_label: Flags. ++ * in_struct, in insn: Flags. ++ * in_struct, in label_ref: Flags. ++ * in_struct, in mem: Flags. ++ * in_struct, in reg: Flags. ++ * in_struct, in subreg: Flags. + * indirect_jump instruction pattern: Standard Names. + * inline automatic for C++ member fns: Inline. + * insn and /i: Flags. +*************** +*** 156,168 **** + * insv instruction pattern: Standard Names. + * integrated, in insn: Flags. + * integrated, in reg: Flags. +- * in_struct, in code_label: Flags. +- * in_struct, in insn: Flags. +- * in_struct, in insn: Flags. +- * in_struct, in label_ref: Flags. +- * in_struct, in mem: Flags. +- * in_struct, in reg: Flags. +- * in_struct, in subreg: Flags. + * iorM3 instruction pattern: Standard Names. + * ior and attributes: Expressions. + * ior, canonicalization of: Insn Canonicalizations. +--- 162,167 ---- +*************** +*** 172,178 **** + * le and attributes: Expressions. + * load_multiple instruction pattern: Standard Names. + * long long data types: Long Long. +! * longjmp and automatic variables: Interface. + * longjmp and automatic variables: C Dialect Options. + * longjmp incompatibilities: Incompatibilities. + * longjmp warnings: Warning Options. +--- 171,177 ---- + * le and attributes: Expressions. + * load_multiple instruction pattern: Standard Names. + * long long data types: Long Long. +! * longjmp and automatic variables <1>: Interface. + * longjmp and automatic variables: C Dialect Options. + * longjmp incompatibilities: Incompatibilities. + * longjmp warnings: Warning Options. +*************** +*** 250,257 **** + * section function attribute: Function Attributes. + * section variable attribute: Variable Attributes. + * setjmp incompatibilities: Incompatibilities. +- * signature in C++, advantages: C++ Signatures. + * sign_extract, canonicalization of: Insn Canonicalizations. + * smulM3_highpart instruction pattern: Standard Names. + * sqrtM2 instruction pattern: Standard Names. + * sscanf, and constant strings: Incompatibilities. +--- 249,256 ---- + * section function attribute: Function Attributes. + * section variable attribute: Variable Attributes. + * setjmp incompatibilities: Incompatibilities. + * sign_extract, canonicalization of: Insn Canonicalizations. ++ * signature in C++, advantages: C++ Signatures. + * smulM3_highpart instruction pattern: Standard Names. + * sqrtM2 instruction pattern: Standard Names. + * sscanf, and constant strings: Incompatibilities. +*************** +*** 319,325 **** + * + in constraint: Modifiers. + * /i in RTL dump: Flags. + * /s in RTL dump: Flags. +- * /s in RTL dump: Flags. + * /u in RTL dump: Flags. + * /v in RTL dump: Flags. + * 0 in constraint: Simple Constraints. +--- 318,323 ---- +*************** +*** 327,339 **** + * = in constraint: Modifiers. + * > in constraint: Simple Constraints. + * ? in constraint: Multi-Alternative. + * d in constraint: Simple Constraints. + * E in constraint: Simple Constraints. + * F in constraint: Simple Constraints. + * G in constraint: Simple Constraints. +- * g in constraint: Simple Constraints. + * H in constraint: Simple Constraints. +- * I in constraint: Simple Constraints. + * i in constraint: Simple Constraints. + * m in constraint: Simple Constraints. + * n in constraint: Simple Constraints. +--- 325,336 ---- + * = in constraint: Modifiers. + * > in constraint: Simple Constraints. + * ? in constraint: Multi-Alternative. ++ * _ in variables in macros: Naming Types. + * d in constraint: Simple Constraints. + * E in constraint: Simple Constraints. + * F in constraint: Simple Constraints. + * G in constraint: Simple Constraints. + * H in constraint: Simple Constraints. + * i in constraint: Simple Constraints. + * m in constraint: Simple Constraints. + * n in constraint: Simple Constraints. +*************** +*** 345,376 **** + * s in constraint: Simple Constraints. + * V in constraint: Simple Constraints. + * X in constraint: Simple Constraints. +! * _ in variables in macros: Naming Types. +! * abort: Portability. + * abort: C Dialect Options. +! * abs: Arithmetic. + * abs: C Dialect Options. + * absolute value: Arithmetic. + * access to operands: Accessors. + * accessors: Accessors. + * ACCUMULATE_OUTGOING_ARGS: Stack Arguments. + * ADDITIONAL_REGISTER_NAMES: Instruction Output. + * address: RTL Template. + * address constraints: Simple Constraints. + * address of a label: Labels as Values. +- * addressing modes: Addressing Modes. + * ADDRESS_COST: Costs. + * address_operand: Simple Constraints. +! * addr_diff_vec: Side Effects. +! * addr_vec: Side Effects. + * ADJUST_COST: Costs. + * ADJUST_INSN_LENGTH: Insn Lengths. + * aggregates as return values: Aggregate Return. + * alignment: Alignment. + * Alliant: Interoperation. + * alloca: C Dialect Options. + * ALLOCATE_TRAMPOLINE: Trampolines. +- * ALL_REGS: Register Classes. + * alternate keywords: Alternate Keywords. + * AMD29K options: AMD29K Options. + * analysis, data flow: Passes. +--- 342,384 ---- + * s in constraint: Simple Constraints. + * V in constraint: Simple Constraints. + * X in constraint: Simple Constraints. +! * \: Output Template. +! * __bb_init_func: Profiling. +! * __builtin_apply: Constructing Calls. +! * __builtin_apply_args: Constructing Calls. +! * __builtin_args_info: Varargs. +! * __builtin_classify_type: Varargs. +! * __builtin_next_arg: Varargs. +! * __builtin_return: Constructing Calls. +! * __builtin_saveregs: Varargs. +! * __CTOR_LIST__: Initialization. +! * __DTOR_LIST__: Initialization. +! * __main: Collect2. +! * abort <1>: Portability. + * abort: C Dialect Options. +! * abs <1>: Arithmetic. + * abs: C Dialect Options. + * absolute value: Arithmetic. + * access to operands: Accessors. + * accessors: Accessors. + * ACCUMULATE_OUTGOING_ARGS: Stack Arguments. + * ADDITIONAL_REGISTER_NAMES: Instruction Output. ++ * addr_diff_vec: Side Effects. ++ * addr_vec: Side Effects. + * address: RTL Template. + * address constraints: Simple Constraints. + * address of a label: Labels as Values. + * ADDRESS_COST: Costs. + * address_operand: Simple Constraints. +! * addressing modes: Addressing Modes. + * ADJUST_COST: Costs. + * ADJUST_INSN_LENGTH: Insn Lengths. + * aggregates as return values: Aggregate Return. + * alignment: Alignment. ++ * ALL_REGS: Register Classes. + * Alliant: Interoperation. + * alloca: C Dialect Options. + * ALLOCATE_TRAMPOLINE: Trampolines. + * alternate keywords: Alternate Keywords. + * AMD29K options: AMD29K Options. + * analysis, data flow: Passes. +*************** +*** 378,390 **** + * ANSI support: C Dialect Options. + * apostrophes: Incompatibilities. + * APPLY_RESULT_SIZE: Scalar Return. + * ARGS_GROW_DOWNWARD: Frame Layout. + * argument passing: Interface. + * arguments in frame (88k): M88K Options. + * arguments in registers: Register Arguments. + * arguments on stack: Stack Arguments. +- * ARG_POINTER_REGNUM: Frame Registers. +- * arg_pointer_rtx: Frame Registers. + * arithmetic libraries: Interface. + * arithmetic shift: Arithmetic. + * arithmetic simplifications: Passes. +--- 386,398 ---- + * ANSI support: C Dialect Options. + * apostrophes: Incompatibilities. + * APPLY_RESULT_SIZE: Scalar Return. ++ * ARG_POINTER_REGNUM: Frame Registers. ++ * arg_pointer_rtx: Frame Registers. + * ARGS_GROW_DOWNWARD: Frame Layout. + * argument passing: Interface. + * arguments in frame (88k): M88K Options. + * arguments in registers: Register Arguments. + * arguments on stack: Stack Arguments. + * arithmetic libraries: Interface. + * arithmetic shift: Arithmetic. + * arithmetic simplifications: Passes. +*************** +*** 413,427 **** + * ASM_GLOBALIZE_LABEL: Label Output. + * ASM_IDENTIFY_GCC: File Framework. + * asm_input: Side Effects. +- * asm_noperands: Insns. + * ASM_NO_SKIP_IN_TEXT: Alignment Output. + * ASM_OPEN_PAREN: Data Output. + * ASM_OUTPUT_ADDR_DIFF_ELT: Dispatch Tables. + * ASM_OUTPUT_ADDR_VEC_ELT: Dispatch Tables. + * ASM_OUTPUT_ALIGN: Alignment Output. + * ASM_OUTPUT_ALIGNED_COMMON: Uninitialized Data. + * ASM_OUTPUT_ALIGNED_LOCAL: Uninitialized Data. +- * ASM_OUTPUT_ALIGN_CODE: Alignment Output. + * ASM_OUTPUT_ASCII: Data Output. + * ASM_OUTPUT_BYTE: Data Output. + * ASM_OUTPUT_CASE_END: Dispatch Tables. +--- 421,435 ---- + * ASM_GLOBALIZE_LABEL: Label Output. + * ASM_IDENTIFY_GCC: File Framework. + * asm_input: Side Effects. + * ASM_NO_SKIP_IN_TEXT: Alignment Output. ++ * asm_noperands: Insns. + * ASM_OPEN_PAREN: Data Output. + * ASM_OUTPUT_ADDR_DIFF_ELT: Dispatch Tables. + * ASM_OUTPUT_ADDR_VEC_ELT: Dispatch Tables. + * ASM_OUTPUT_ALIGN: Alignment Output. ++ * ASM_OUTPUT_ALIGN_CODE: Alignment Output. + * ASM_OUTPUT_ALIGNED_COMMON: Uninitialized Data. + * ASM_OUTPUT_ALIGNED_LOCAL: Uninitialized Data. + * ASM_OUTPUT_ASCII: Data Output. + * ASM_OUTPUT_BYTE: Data Output. + * ASM_OUTPUT_CASE_END: Dispatch Tables. +*************** +*** 462,486 **** + * ASM_STABN_OP: DBX Options. + * ASM_STABS_OP: DBX Options. + * ASM_WEAKEN_LABEL: Label Output. + * assembler format: File Framework. + * assembler instructions: Extended Asm. + * assembler instructions in RTL: Assembler. + * assembler names for identifiers: Asm Labels. + * assembler syntax, 88k: M88K Options. + * ASSEMBLER_DIALECT: Instruction Output. +- * assemble_name: Label Output. + * assembly code, invalid: Bug Criteria. + * assigning attribute values to insns: Tagging Insns. + * asterisk in template: Output Statement. + * atof: Cross-compilation. + * attr: Tagging Insns. + * attribute expressions: Expressions. + * attribute of types: Type Attributes. + * attribute of variables: Variable Attributes. + * attribute specifications: Attr Example. + * attribute specifications example: Attr Example. + * attributes, defining: Defining Attributes. +- * attr_flag: Expressions. + * autoincrement addressing, availability: Portability. + * autoincrement/decrement addressing: Simple Constraints. + * autoincrement/decrement analysis: Passes. +--- 470,494 ---- + * ASM_STABN_OP: DBX Options. + * ASM_STABS_OP: DBX Options. + * ASM_WEAKEN_LABEL: Label Output. ++ * assemble_name: Label Output. + * assembler format: File Framework. + * assembler instructions: Extended Asm. + * assembler instructions in RTL: Assembler. + * assembler names for identifiers: Asm Labels. + * assembler syntax, 88k: M88K Options. + * ASSEMBLER_DIALECT: Instruction Output. + * assembly code, invalid: Bug Criteria. + * assigning attribute values to insns: Tagging Insns. + * asterisk in template: Output Statement. + * atof: Cross-compilation. + * attr: Tagging Insns. ++ * attr_flag: Expressions. + * attribute expressions: Expressions. + * attribute of types: Type Attributes. + * attribute of variables: Variable Attributes. + * attribute specifications: Attr Example. + * attribute specifications example: Attr Example. + * attributes, defining: Defining Attributes. + * autoincrement addressing, availability: Portability. + * autoincrement/decrement addressing: Simple Constraints. + * autoincrement/decrement analysis: Passes. +*************** +*** 515,522 **** + * bugs, known: Trouble. + * builtin functions: C Dialect Options. + * byte writes (29k): AMD29K Options. +- * BYTES_BIG_ENDIAN: Storage Layout. + * byte_mode: Machine Modes. + * bzero: Config. + * C compilation options: Invoking GCC. + * C intermediate output, nonexistent: G++ and GCC. +--- 523,530 ---- + * bugs, known: Trouble. + * builtin functions: C Dialect Options. + * byte writes (29k): AMD29K Options. + * byte_mode: Machine Modes. ++ * BYTES_BIG_ENDIAN: Storage Layout. + * bzero: Config. + * C compilation options: Invoking GCC. + * C intermediate output, nonexistent: G++ and GCC. +*************** +*** 539,559 **** + * C++ static data, declaring and defining: Static Definitions. + * C++ subtype polymorphism: C++ Signatures. + * C++ type abstraction: C++ Signatures. + * call: Side Effects. + * call-clobbered register: Register Basics. + * call-saved register: Register Basics. + * call-used register: Register Basics. +- * CALLER_SAVE_PROFITABLE: Caller Saves. +- * calling conventions: Stack and Calling. +- * calling functions in RTL: Calls. + * call_insn: Insns. + * CALL_INSN_FUNCTION_USAGE: Insns. + * CALL_USED_REGISTERS: Register Basics. + * call_used_regs: Register Basics. +! * canonicalization of instructions: Insn Canonicalizations. +! * CANONICALIZE_COMPARISON: Condition Code. + * CAN_DEBUG_WITHOUT_FP: Run-time Target. + * CAN_ELIMINATE: Elimination. + * case labels in initializers: Labeled Elements. + * case ranges: Case Ranges. + * case sensitivity and VMS: VMS Misc. +--- 547,568 ---- + * C++ static data, declaring and defining: Static Definitions. + * C++ subtype polymorphism: C++ Signatures. + * C++ type abstraction: C++ Signatures. ++ * C_INCLUDE_PATH: Environment Variables. + * call: Side Effects. + * call-clobbered register: Register Basics. + * call-saved register: Register Basics. + * call-used register: Register Basics. + * call_insn: Insns. + * CALL_INSN_FUNCTION_USAGE: Insns. + * CALL_USED_REGISTERS: Register Basics. + * call_used_regs: Register Basics. +! * CALLER_SAVE_PROFITABLE: Caller Saves. +! * calling conventions: Stack and Calling. +! * calling functions in RTL: Calls. + * CAN_DEBUG_WITHOUT_FP: Run-time Target. + * CAN_ELIMINATE: Elimination. ++ * canonicalization of instructions: Insn Canonicalizations. ++ * CANONICALIZE_COMPARISON: Condition Code. + * case labels in initializers: Labeled Elements. + * case ranges: Case Ranges. + * case sensitivity and VMS: VMS Misc. +*************** +*** 566,577 **** + * CC: Host Fragment. + * cc0: Regs and Memory. + * cc0_rtx: Regs and Memory. +- * CC1PLUS_SPEC: Driver. + * CC1_SPEC: Driver. +! * CCmode: Machine Modes. + * cc_status: Condition Code. + * CC_STATUS_MDEP: Condition Code. + * CC_STATUS_MDEP_INIT: Condition Code. + * CDImode: Machine Modes. + * change_address: Standard Names. + * CHAR_TYPE_SIZE: Type Layout. +--- 575,586 ---- + * CC: Host Fragment. + * cc0: Regs and Memory. + * cc0_rtx: Regs and Memory. + * CC1_SPEC: Driver. +! * CC1PLUS_SPEC: Driver. + * cc_status: Condition Code. + * CC_STATUS_MDEP: Condition Code. + * CC_STATUS_MDEP_INIT: Condition Code. ++ * CCmode: Machine Modes. + * CDImode: Machine Modes. + * change_address: Standard Names. + * CHAR_TYPE_SIZE: Type Layout. +*************** +*** 579,602 **** + * CHImode: Machine Modes. + * class definitions, register: Register Classes. + * class preference constraints: Class Preferences. +- * classes of RTX codes: Accessors. + * CLASS_LIKELY_SPILLED_P: Register Classes. + * CLASS_MAX_NREGS: Register Classes. + * CLEAR_INSN_CACHE: Trampolines. + * CLIB: Host Fragment. + * clobber: Side Effects. + * code generation conventions: Code Gen Options. + * code generation RTL sequences: Expander Definitions. + * code motion: Passes. +- * codes, RTL expression: RTL Objects. + * code_label: Insns. + * CODE_LABEL_NUMBER: Insns. + * COImode: Machine Modes. + * COLLECT_EXPORT_LIST: Config. + * combiner pass: Regs and Memory. + * command options: Invoking GCC. + * comments, C++ style: C++ Comments. + * common subexpression elimination: Passes. + * compare: Arithmetic. + * compilation in a separate directory: Other Dir. + * compiler bugs, reporting: Bug Reporting. +--- 588,612 ---- + * CHImode: Machine Modes. + * class definitions, register: Register Classes. + * class preference constraints: Class Preferences. + * CLASS_LIKELY_SPILLED_P: Register Classes. + * CLASS_MAX_NREGS: Register Classes. ++ * classes of RTX codes: Accessors. + * CLEAR_INSN_CACHE: Trampolines. + * CLIB: Host Fragment. + * clobber: Side Effects. + * code generation conventions: Code Gen Options. + * code generation RTL sequences: Expander Definitions. + * code motion: Passes. + * code_label: Insns. + * CODE_LABEL_NUMBER: Insns. ++ * codes, RTL expression: RTL Objects. + * COImode: Machine Modes. + * COLLECT_EXPORT_LIST: Config. + * combiner pass: Regs and Memory. + * command options: Invoking GCC. + * comments, C++ style: C++ Comments. + * common subexpression elimination: Passes. ++ * COMP_TYPE_ATTRIBUTES: Misc. + * compare: Arithmetic. + * compilation in a separate directory: Other Dir. + * compiler bugs, reporting: Bug Reporting. +*************** +*** 610,616 **** + * compound expressions as lvalues: Lvalues. + * computed gotos: Labels as Values. + * computing the length of an insn: Insn Lengths. +- * COMP_TYPE_ATTRIBUTES: Misc. + * cond: Comparisons. + * condition code register: Regs and Memory. + * condition code status: Condition Code. +--- 620,625 ---- +*************** +*** 623,642 **** + * configurations supported by GNU CC: Configurations. + * conflicting types: Disappointments. + * const0_rtx: Constants. +- * CONST0_RTX: Constants. + * const1_rtx: Constants. +- * CONST1_RTX: Constants. +- * CONST2_RTX: Constants. + * const2_rtx: Constants. + * constant attributes: Constant Attributes. + * constant folding: Passes. + * constant folding and floating point: Cross-compilation. + * constant propagation: Passes. +- * constants in constraints: Simple Constraints. + * CONSTANT_ADDRESS_P: Addressing Modes. + * CONSTANT_ALIGNMENT: Storage Layout. + * CONSTANT_P: Addressing Modes. + * CONSTANT_POOL_ADDRESS_P: Flags. + * constm1_rtx: Constants. + * constraint modifier characters: Modifiers. + * constraint, matching: Simple Constraints. +--- 632,659 ---- + * configurations supported by GNU CC: Configurations. + * conflicting types: Disappointments. + * const0_rtx: Constants. + * const1_rtx: Constants. + * const2_rtx: Constants. ++ * CONST_CALL_P: Flags. ++ * CONST_COSTS: Costs. ++ * const_double: Constants. ++ * CONST_DOUBLE_CHAIN: Constants. ++ * CONST_DOUBLE_LOW: Constants. ++ * CONST_DOUBLE_MEM: Constants. ++ * CONST_DOUBLE_OK_FOR_LETTER_P: Register Classes. ++ * const_int: Constants. ++ * CONST_OK_FOR_LETTER_P: Register Classes. ++ * const_string: Constants. ++ * const_true_rtx: Constants. + * constant attributes: Constant Attributes. + * constant folding: Passes. + * constant folding and floating point: Cross-compilation. + * constant propagation: Passes. + * CONSTANT_ADDRESS_P: Addressing Modes. + * CONSTANT_ALIGNMENT: Storage Layout. + * CONSTANT_P: Addressing Modes. + * CONSTANT_POOL_ADDRESS_P: Flags. ++ * constants in constraints: Simple Constraints. + * constm1_rtx: Constants. + * constraint modifier characters: Modifiers. + * constraint, matching: Simple Constraints. +*************** +*** 647,663 **** + * constructors vs goto: Destructors and Goto. + * constructors, automatic calls: Collect2. + * constructors, output of: Initialization. +- * CONST_CALL_P: Flags. +- * CONST_COSTS: Costs. +- * const_double: Constants. +- * CONST_DOUBLE_CHAIN: Constants. +- * CONST_DOUBLE_LOW: Constants. +- * CONST_DOUBLE_MEM: Constants. +- * CONST_DOUBLE_OK_FOR_LETTER_P: Register Classes. +- * const_int: Constants. +- * CONST_OK_FOR_LETTER_P: Register Classes. +- * const_string: Constants. +- * const_true_rtx: Constants. + * contributors: Contributors. + * controlling register usage: Register Basics. + * controlling the compilation driver: Driver. +--- 664,669 ---- +*************** +*** 686,692 **** + * current_function_outgoing_args_size: Stack Arguments. + * current_function_pops_args: Function Entry. + * current_function_pretend_args_size: Function Entry. +- * C_INCLUDE_PATH: Environment Variables. + * data flow analysis: Passes. + * DATA_ALIGNMENT: Storage Layout. + * data_section: Sections. +--- 692,697 ---- +*************** +*** 706,713 **** + * DBX_OUTPUT_FUNCTION_END: DBX Hooks. + * DBX_OUTPUT_LBRAC: DBX Hooks. + * DBX_OUTPUT_MAIN_SOURCE_DIRECTORY: File Names and DBX. +- * DBX_OUTPUT_MAIN_SOURCE_FILENAME: File Names and DBX. + * DBX_OUTPUT_MAIN_SOURCE_FILE_END: File Names and DBX. + * DBX_OUTPUT_RBRAC: DBX Hooks. + * DBX_OUTPUT_SOURCE_FILENAME: File Names and DBX. + * DBX_OUTPUT_STANDARD_TYPES: DBX Hooks. +--- 711,718 ---- + * DBX_OUTPUT_FUNCTION_END: DBX Hooks. + * DBX_OUTPUT_LBRAC: DBX Hooks. + * DBX_OUTPUT_MAIN_SOURCE_DIRECTORY: File Names and DBX. + * DBX_OUTPUT_MAIN_SOURCE_FILE_END: File Names and DBX. ++ * DBX_OUTPUT_MAIN_SOURCE_FILENAME: File Names and DBX. + * DBX_OUTPUT_RBRAC: DBX Hooks. + * DBX_OUTPUT_SOURCE_FILENAME: File Names and DBX. + * DBX_OUTPUT_STANDARD_TYPES: DBX Hooks. +*************** +*** 724,736 **** + * dead_or_set_p: Peephole Definitions. + * deallocating variable length arrays: Variable Length. + * death notes: Obsolete Register Macros. + * DEBUGGER_ARG_OFFSET: All Debuggers. + * DEBUGGER_AUTO_OFFSET: All Debuggers. + * debugging information generation: Passes. + * debugging information options: Debugging Options. + * debugging, 88k OCS: M88K Options. +- * debug_rtx: Bug Reporting. +- * DEBUG_SYMS_TEXT: DBX Options. + * declaration scope: Incompatibilities. + * declarations inside expressions: Statement Exprs. + * declarations, RTL: RTL Declarations. +--- 729,741 ---- + * dead_or_set_p: Peephole Definitions. + * deallocating variable length arrays: Variable Length. + * death notes: Obsolete Register Macros. ++ * debug_rtx: Bug Reporting. ++ * DEBUG_SYMS_TEXT: DBX Options. + * DEBUGGER_ARG_OFFSET: All Debuggers. + * DEBUGGER_AUTO_OFFSET: All Debuggers. + * debugging information generation: Passes. + * debugging information options: Debugging Options. + * debugging, 88k OCS: M88K Options. + * declaration scope: Incompatibilities. + * declarations inside expressions: Statement Exprs. + * declarations, RTL: RTL Declarations. +*************** +*** 757,764 **** + * defining RTL sequences for code generation: Expander Definitions. + * defining static data in C++: Static Definitions. + * delay slots, defining: Delay Slots. +- * delayed branch scheduling: Passes. + * DELAY_SLOTS_FOR_EPILOGUE: Function Entry. + * dependencies for make as output: Environment Variables. + * dependencies, make: Preprocessor Options. + * DEPENDENCIES_OUTPUT: Environment Variables. +--- 762,769 ---- + * defining RTL sequences for code generation: Expander Definitions. + * defining static data in C++: Static Definitions. + * delay slots, defining: Delay Slots. + * DELAY_SLOTS_FOR_EPILOGUE: Function Entry. ++ * delayed branch scheduling: Passes. + * dependencies for make as output: Environment Variables. + * dependencies, make: Preprocessor Options. + * DEPENDENCIES_OUTPUT: Environment Variables. +*************** +*** 770,785 **** + * dialect options: C Dialect Options. + * digits in constraint: Simple Constraints. + * DImode: Machine Modes. +- * directory options: Directory Options. + * DIR_SEPARATOR: Config. + * disabling certain registers: Register Basics. + * dispatch table: Dispatch Tables. + * div: Arithmetic. + * DIVDI3_LIBCALL: Library Calls. + * divide instruction, 88k: M88K Options. + * division: Arithmetic. +- * division: Arithmetic. +- * division: Arithmetic. + * DIVSI3_LIBCALL: Library Calls. + * dollar signs in identifier names: Dollar Signs. + * DOLLARS_IN_IDENTIFIERS: Misc. +--- 775,788 ---- + * dialect options: C Dialect Options. + * digits in constraint: Simple Constraints. + * DImode: Machine Modes. + * DIR_SEPARATOR: Config. ++ * directory options: Directory Options. + * disabling certain registers: Register Basics. + * dispatch table: Dispatch Tables. + * div: Arithmetic. + * DIVDI3_LIBCALL: Library Calls. + * divide instruction, 88k: M88K Options. + * division: Arithmetic. + * DIVSI3_LIBCALL: Library Calls. + * dollar signs in identifier names: Dollar Signs. + * DOLLARS_IN_IDENTIFIERS: Misc. +*************** +*** 807,814 **** + * environment variables: Environment Variables. + * epilogue: Function Entry. + * eq: Comparisons. +- * equal: Comparisons. + * eq_attr: Expressions. + * error messages: Warnings and Errors. + * escape sequences, traditional: C Dialect Options. + * exclamation point: Multi-Alternative. +--- 810,817 ---- + * environment variables: Environment Variables. + * epilogue: Function Entry. + * eq: Comparisons. + * eq_attr: Expressions. ++ * equal: Comparisons. + * error messages: Warnings and Errors. + * escape sequences, traditional: C Dialect Options. + * exclamation point: Multi-Alternative. +*************** +*** 818,835 **** + * exit status and VMS: VMS Misc. + * EXIT_BODY: Misc. + * EXIT_IGNORE_STACK: Function Entry. +- * expander definitions: Expander Definitions. + * EXPAND_BUILTIN_SAVEREGS: Varargs. + * explicit register variables: Explicit Reg Vars. + * expression codes: RTL Objects. + * expressions containing statements: Statement Exprs. + * expressions, compound, as lvalues: Lvalues. + * expressions, conditional, as lvalues: Lvalues. + * expressions, constructor: Constructors. +- * expr_list: Insns. + * extended asm: Extended Asm. + * extensible constraints: Simple Constraints. +! * extensions, ?:: Conditionals. + * extensions, ?:: Lvalues. + * extensions, C language: C Extensions. + * extensions, C++ language: C++ Extensions. +--- 821,838 ---- + * exit status and VMS: VMS Misc. + * EXIT_BODY: Misc. + * EXIT_IGNORE_STACK: Function Entry. + * EXPAND_BUILTIN_SAVEREGS: Varargs. ++ * expander definitions: Expander Definitions. + * explicit register variables: Explicit Reg Vars. ++ * expr_list: Insns. + * expression codes: RTL Objects. + * expressions containing statements: Statement Exprs. + * expressions, compound, as lvalues: Lvalues. + * expressions, conditional, as lvalues: Lvalues. + * expressions, constructor: Constructors. + * extended asm: Extended Asm. + * extensible constraints: Simple Constraints. +! * extensions, ?: <1>: Conditionals. + * extensions, ?:: Lvalues. + * extensions, C language: C Extensions. + * extensions, C++ language: C++ Extensions. +*************** +*** 838,876 **** + * EXTRA_CC_MODES: Condition Code. + * EXTRA_CC_NAMES: Condition Code. + * EXTRA_CONSTRAINT: Register Classes. +- * EXTRA_SECTIONS: Sections. + * EXTRA_SECTION_FUNCTIONS: Sections. + * fabs: C Dialect Options. + * FAIL: Expander Definitions. + * fatal signal: Bug Criteria. + * FATAL_EXIT_CODE: Config. + * features, optional, in system conventions: Run-time Target. + * ffs: C Dialect Options. +- * ffs: Arithmetic. + * file name suffix: Overall Options. + * file names: Link Options. + * files and passes of the compiler: Passes. + * final pass: Passes. +- * FINALIZE_PIC: PIC. + * FINAL_PRESCAN_INSN: Instruction Output. + * FINAL_REG_PARM_STACK_SPACE: Stack Arguments. + * final_scan_insn: Function Entry. + * final_sequence: Instruction Output. + * FIRST_INSN_ADDRESS: Insn Lengths. + * FIRST_PARM_OFFSET: Frame Layout. + * FIRST_PSEUDO_REGISTER: Register Basics. + * FIRST_STACK_REG: Stack Registers. + * FIRST_VIRTUAL_REGISTER: Regs and Memory. + * fix: Conversions. +- * fix: Conversions. + * fixed register: Register Basics. + * FIXED_REGISTERS: Register Basics. + * fixed_regs: Register Basics. + * FIXUNS_TRUNC_LIKE_FIX_TRUNC: Misc. + * flags in RTL expression: Flags. + * float: Conversions. +- * FLOATIFY: Library Calls. +- * floating point and cross compilation: Cross-compilation. + * FLOAT_ARG_TYPE: Library Calls. + * float_extend: Conversions. + * FLOAT_STORE_FLAG_VALUE: Misc. +--- 841,876 ---- + * EXTRA_CC_MODES: Condition Code. + * EXTRA_CC_NAMES: Condition Code. + * EXTRA_CONSTRAINT: Register Classes. + * EXTRA_SECTION_FUNCTIONS: Sections. ++ * EXTRA_SECTIONS: Sections. + * fabs: C Dialect Options. + * FAIL: Expander Definitions. + * fatal signal: Bug Criteria. + * FATAL_EXIT_CODE: Config. + * features, optional, in system conventions: Run-time Target. ++ * ffs <1>: Arithmetic. + * ffs: C Dialect Options. + * file name suffix: Overall Options. + * file names: Link Options. + * files and passes of the compiler: Passes. + * final pass: Passes. + * FINAL_PRESCAN_INSN: Instruction Output. + * FINAL_REG_PARM_STACK_SPACE: Stack Arguments. + * final_scan_insn: Function Entry. + * final_sequence: Instruction Output. ++ * FINALIZE_PIC: PIC. + * FIRST_INSN_ADDRESS: Insn Lengths. + * FIRST_PARM_OFFSET: Frame Layout. + * FIRST_PSEUDO_REGISTER: Register Basics. + * FIRST_STACK_REG: Stack Registers. + * FIRST_VIRTUAL_REGISTER: Regs and Memory. + * fix: Conversions. + * fixed register: Register Basics. + * FIXED_REGISTERS: Register Basics. + * fixed_regs: Register Basics. + * FIXUNS_TRUNC_LIKE_FIX_TRUNC: Misc. + * flags in RTL expression: Flags. + * float: Conversions. + * FLOAT_ARG_TYPE: Library Calls. + * float_extend: Conversions. + * FLOAT_STORE_FLAG_VALUE: Misc. +*************** +*** 878,883 **** +--- 878,885 ---- + * FLOAT_TYPE_SIZE: Type Layout. + * FLOAT_VALUE_TYPE: Library Calls. + * FLOAT_WORDS_BIG_ENDIAN: Storage Layout. ++ * FLOATIFY: Library Calls. ++ * floating point and cross compilation: Cross-compilation. + * force_reg: Standard Names. + * forwarding calls: Constructing Calls. + * frame layout: Frame Layout. +*************** +*** 894,910 **** + * function units, for scheduling: Function Units. + * function, size of pointer to: Pointer Arith. + * function-call insns: Calls. +- * functions in arbitrary sections: Function Attributes. +- * functions that are passed arguments in registers on the 386: Function Attributes. +- * functions that are passed arguments in registers on the 386: Function Attributes. +- * functions that do not pop the argument stack on the 386: Function Attributes. +- * functions that do pop the argument stack on the 386: Function Attributes. +- * functions that have no side effects: Function Attributes. +- * functions that never return: Function Attributes. +- * functions that pop the argument stack on the 386: Function Attributes. +- * functions that pop the argument stack on the 386: Function Attributes. +- * functions with printf or scanf style arguments: Function Attributes. +- * functions, leaf: Leaf Functions. + * FUNCTION_ARG: Register Arguments. + * FUNCTION_ARG_ADVANCE: Register Arguments. + * FUNCTION_ARG_BOUNDARY: Register Arguments. +--- 896,901 ---- +*************** +*** 924,943 **** + * FUNCTION_PROLOGUE: Function Entry. + * FUNCTION_VALUE: Scalar Return. + * FUNCTION_VALUE_REGNO_P: Scalar Return. +! * G++: G++ and GCC. + * g++: Invoking G++. + * GCC: G++ and GCC. + * GCC_EXEC_PREFIX: Environment Variables. + * ge: Comparisons. + * gencodes: Passes. + * genconfig: Passes. +- * generalized lvalues: Lvalues. + * general_operand: RTL Template. + * GENERAL_REGS: Register Classes. + * generating assembler output: Output Statement. + * generating insns: RTL Template. + * genflags: Passes. +- * GEN_ERRNO_RTX: Library Calls. + * get_attr: Expressions. + * get_attr_length: Insn Lengths. + * GET_CLASS_NARROWEST_MODE: Machine Modes. +--- 915,943 ---- + * FUNCTION_PROLOGUE: Function Entry. + * FUNCTION_VALUE: Scalar Return. + * FUNCTION_VALUE_REGNO_P: Scalar Return. +! * functions in arbitrary sections: Function Attributes. +! * functions that are passed arguments in registers on the 386: Function Attributes. +! * functions that do not pop the argument stack on the 386: Function Attributes. +! * functions that do pop the argument stack on the 386: Function Attributes. +! * functions that have no side effects: Function Attributes. +! * functions that never return: Function Attributes. +! * functions that pop the argument stack on the 386: Function Attributes. +! * functions with printf or scanf style arguments: Function Attributes. +! * functions, leaf: Leaf Functions. + * g++: Invoking G++. ++ * G++: G++ and GCC. + * GCC: G++ and GCC. + * GCC_EXEC_PREFIX: Environment Variables. + * ge: Comparisons. ++ * GEN_ERRNO_RTX: Library Calls. + * gencodes: Passes. + * genconfig: Passes. + * general_operand: RTL Template. + * GENERAL_REGS: Register Classes. ++ * generalized lvalues: Lvalues. + * generating assembler output: Output Statement. + * generating insns: RTL Template. + * genflags: Passes. + * get_attr: Expressions. + * get_attr_length: Insn Lengths. + * GET_CLASS_NARROWEST_MODE: Machine Modes. +*************** +*** 969,990 **** + * GLOBALVALUEREF: Global Declarations. + * GNU CC and portability: Portability. + * GNU CC command options: Invoking GCC. +- * goto with computed label: Labels as Values. + * GO_IF_LEGITIMATE_ADDRESS: Addressing Modes. + * GO_IF_MODE_DEPENDENT_ADDRESS: Addressing Modes. + * gp-relative references (MIPS): MIPS Options. + * greater than: Comparisons. +- * greater than: Comparisons. +- * greater than: Comparisons. + * grouping options: Invoking GCC. + * gt: Comparisons. + * gtu: Comparisons. + * HANDLE_PRAGMA: Misc. + * hard registers: Regs and Memory. +- * hardware models and configurations, specifying: Submodel Options. + * HARD_FRAME_POINTER_REGNUM: Frame Registers. + * HARD_REGNO_MODE_OK: Values in Registers. + * HARD_REGNO_NREGS: Values in Registers. + * HAS_INIT_SECTION: Macros for Initialization. + * HAVE_ATEXIT: Misc. + * HAVE_POST_DECREMENT: Addressing Modes. +--- 969,988 ---- + * GLOBALVALUEREF: Global Declarations. + * GNU CC and portability: Portability. + * GNU CC command options: Invoking GCC. + * GO_IF_LEGITIMATE_ADDRESS: Addressing Modes. + * GO_IF_MODE_DEPENDENT_ADDRESS: Addressing Modes. ++ * goto with computed label: Labels as Values. + * gp-relative references (MIPS): MIPS Options. + * greater than: Comparisons. + * grouping options: Invoking GCC. + * gt: Comparisons. + * gtu: Comparisons. + * HANDLE_PRAGMA: Misc. + * hard registers: Regs and Memory. + * HARD_FRAME_POINTER_REGNUM: Frame Registers. + * HARD_REGNO_MODE_OK: Values in Registers. + * HARD_REGNO_NREGS: Values in Registers. ++ * hardware models and configurations, specifying: Submodel Options. + * HAS_INIT_SECTION: Macros for Initialization. + * HAVE_ATEXIT: Misc. + * HAVE_POST_DECREMENT: Addressing Modes. +*************** +*** 1019,1024 **** +--- 1017,1025 ---- + * implicit argument: return value: Naming Results. + * IMPLICIT_FIX_EXPR: Misc. + * implied #pragma implementation: C++ Interface. ++ * in_data: Sections. ++ * in_struct: Flags. ++ * in_text: Sections. + * include files and VMS: Include Files and VMS. + * INCLUDE_DEFAULTS: Driver. + * inclusive-or, bitwise: Arithmetic. +*************** +*** 1026,1044 **** + * incompatibilities of GNU CC: Incompatibilities. + * increment operators: Bug Criteria. + * INDEX_REG_CLASS: Register Classes. +- * initialization routines: Initialization. +- * initializations in expressions: Constructors. +- * initializers with labeled elements: Labeled Elements. +- * initializers, non-constant: Initializers. +- * INITIALIZE_TRAMPOLINE: Trampolines. +- * INITIAL_ELIMINATION_OFFSET: Elimination. +- * INITIAL_FRAME_POINTER_OFFSET: Elimination. + * INIT_CUMULATIVE_ARGS: Register Arguments. + * INIT_CUMULATIVE_INCOMING_ARGS: Register Arguments. + * INIT_ENVIRONMENT: Driver. +! * INIT_SECTION_ASM_OP: Macros for Initialization. + * INIT_SECTION_ASM_OP: Sections. + * INIT_TARGET_OPTABS: Library Calls. + * inline functions: Inline. + * inline functions, omission of: Inline. + * inline, automatic: Passes. +--- 1027,1045 ---- + * incompatibilities of GNU CC: Incompatibilities. + * increment operators: Bug Criteria. + * INDEX_REG_CLASS: Register Classes. + * INIT_CUMULATIVE_ARGS: Register Arguments. + * INIT_CUMULATIVE_INCOMING_ARGS: Register Arguments. + * INIT_ENVIRONMENT: Driver. +! * INIT_SECTION_ASM_OP <1>: Macros for Initialization. + * INIT_SECTION_ASM_OP: Sections. + * INIT_TARGET_OPTABS: Library Calls. ++ * INITIAL_ELIMINATION_OFFSET: Elimination. ++ * INITIAL_FRAME_POINTER_OFFSET: Elimination. ++ * initialization routines: Initialization. ++ * initializations in expressions: Constructors. ++ * INITIALIZE_TRAMPOLINE: Trampolines. ++ * initializers with labeled elements: Labeled Elements. ++ * initializers, non-constant: Initializers. + * inline functions: Inline. + * inline functions, omission of: Inline. + * inline, automatic: Passes. +*************** +*** 1049,1057 **** + * insn lengths, computing: Insn Lengths. + * insn splitting: Insn Splitting. + * insn-attr.h: Defining Attributes. +- * insns: Insns. +- * insns, generating: RTL Template. +- * insns, recognizing: RTL Template. + * INSN_ANNULLED_BRANCH_P: Flags. + * INSN_CACHE_DEPTH: Trampolines. + * INSN_CACHE_LINE_WIDTH: Trampolines. +--- 1050,1055 ---- +*************** +*** 1064,1069 **** +--- 1062,1070 ---- + * INSN_REFERENCES_ARE_DELAYED: Misc. + * INSN_SETS_ARE_DELAYED: Misc. + * INSN_UID: Insns. ++ * insns: Insns. ++ * insns, generating: RTL Template. ++ * insns, recognizing: RTL Template. + * INSTALL: Host Fragment. + * installation trouble: Trouble. + * installing GNU CC: Installation. +*************** +*** 1074,1083 **** + * instruction patterns: Patterns. + * instruction recognizer: Passes. + * instruction scheduling: Passes. +- * instruction scheduling: Passes. + * instruction splitting: Insn Splitting. +! * integrated: Flags. + * INTEGRATE_THRESHOLD: Misc. + * integrating function code: Inline. + * Intel 386 Options: i386 Options. + * Interdependence of Patterns: Dependent Patterns. +--- 1075,1084 ---- + * instruction patterns: Patterns. + * instruction recognizer: Passes. + * instruction scheduling: Passes. + * instruction splitting: Insn Splitting. +! * INT_TYPE_SIZE: Type Layout. + * INTEGRATE_THRESHOLD: Misc. ++ * integrated: Flags. + * integrating function code: Inline. + * Intel 386 Options: i386 Options. + * Interdependence of Patterns: Dependent Patterns. +*************** +*** 1086,1103 **** + * intermediate C version, nonexistent: G++ and GCC. + * INTIFY: Library Calls. + * introduction: Top. +- * INT_TYPE_SIZE: Type Layout. + * invalid assembly code: Bug Criteria. + * invalid input: Bug Criteria. + * INVOKE__main: Macros for Initialization. + * invoking g++: Invoking G++. +- * in_data: Sections. +- * in_struct: Flags. +- * in_text: Sections. + * ior: Arithmetic. + * isinf: Cross-compilation. + * isnan: Cross-compilation. +- * IS_ASM_LOGICAL_LINE_SEPARATOR: Data Output. + * jump instruction patterns: Jump Patterns. + * jump instructions and set: Side Effects. + * jump optimization: Passes. +--- 1087,1100 ---- + * intermediate C version, nonexistent: G++ and GCC. + * INTIFY: Library Calls. + * introduction: Top. + * invalid assembly code: Bug Criteria. + * invalid input: Bug Criteria. + * INVOKE__main: Macros for Initialization. + * invoking g++: Invoking G++. + * ior: Arithmetic. ++ * IS_ASM_LOGICAL_LINE_SEPARATOR: Data Output. + * isinf: Cross-compilation. + * isnan: Cross-compilation. + * jump instruction patterns: Jump Patterns. + * jump instructions and set: Side Effects. + * jump optimization: Passes. +*************** +*** 1108,1135 **** + * kernel and user registers (29k): AMD29K Options. + * keywords, alternate: Alternate Keywords. + * known causes of trouble: Trouble. +- * labeled elements in initializers: Labeled Elements. +- * labels as values: Labels as Values. + * LABEL_NUSES: Insns. + * LABEL_OUTSIDE_LOOP_P: Flags. + * LABEL_PRESERVE_P: Flags. + * label_ref: Constants. + * labs: C Dialect Options. + * language dialect options: C Dialect Options. + * large bit shifts (88k): M88K Options. + * large return values: Aggregate Return. + * LAST_STACK_REG: Stack Registers. + * LAST_VIRTUAL_REGISTER: Regs and Memory. +- * LDD_SUFFIX: Macros for Initialization. +- * ldexp: Cross-compilation. + * LD_FINI_SWITCH: Macros for Initialization. + * LD_INIT_SWITCH: Macros for Initialization. + * le: Comparisons. + * leaf functions: Leaf Functions. + * leaf_function: Leaf Functions. + * leaf_function_p: Standard Names. +- * LEAF_REGISTERS: Leaf Functions. + * LEAF_REG_REMAP: Leaf Functions. + * left rotate: Arithmetic. + * left shift: Arithmetic. + * LEGITIMATE_CONSTANT_P: Addressing Modes. +--- 1105,1132 ---- + * kernel and user registers (29k): AMD29K Options. + * keywords, alternate: Alternate Keywords. + * known causes of trouble: Trouble. + * LABEL_NUSES: Insns. + * LABEL_OUTSIDE_LOOP_P: Flags. + * LABEL_PRESERVE_P: Flags. + * label_ref: Constants. ++ * labeled elements in initializers: Labeled Elements. ++ * labels as values: Labels as Values. + * labs: C Dialect Options. + * language dialect options: C Dialect Options. + * large bit shifts (88k): M88K Options. + * large return values: Aggregate Return. + * LAST_STACK_REG: Stack Registers. + * LAST_VIRTUAL_REGISTER: Regs and Memory. + * LD_FINI_SWITCH: Macros for Initialization. + * LD_INIT_SWITCH: Macros for Initialization. ++ * LDD_SUFFIX: Macros for Initialization. ++ * ldexp: Cross-compilation. + * le: Comparisons. + * leaf functions: Leaf Functions. + * leaf_function: Leaf Functions. + * leaf_function_p: Standard Names. + * LEAF_REG_REMAP: Leaf Functions. ++ * LEAF_REGISTERS: Leaf Functions. + * left rotate: Arithmetic. + * left shift: Arithmetic. + * LEGITIMATE_CONSTANT_P: Addressing Modes. +*************** +*** 1140,1145 **** +--- 1137,1143 ---- + * less than or equal: Comparisons. + * leu: Comparisons. + * LIB2FUNCS_EXTRA: Target Fragment. ++ * LIB_SPEC: Driver. + * LIBCALL_VALUE: Scalar Return. + * LIBGCC1: Target Fragment. + * LIBGCC2_CFLAGS: Target Fragment. +*************** +*** 1149,1160 **** + * Libraries: Link Options. + * library subroutine names: Library Calls. + * LIBRARY_PATH: Environment Variables. +- * LIB_SPEC: Driver. + * LIMIT_RELOAD_CLASS: Register Classes. + * link options: Link Options. + * LINK_LIBGCC_SPECIAL: Driver. + * LINK_LIBGCC_SPECIAL_1: Driver. + * LINK_SPEC: Driver. + * load address instruction: Simple Constraints. + * LOAD_EXTEND_OP: Misc. + * local labels: Local Labels. +--- 1147,1158 ---- + * Libraries: Link Options. + * library subroutine names: Library Calls. + * LIBRARY_PATH: Environment Variables. + * LIMIT_RELOAD_CLASS: Register Classes. + * link options: Link Options. + * LINK_LIBGCC_SPECIAL: Driver. + * LINK_LIBGCC_SPECIAL_1: Driver. + * LINK_SPEC: Driver. ++ * lo_sum: Arithmetic. + * load address instruction: Simple Constraints. + * LOAD_EXTEND_OP: Misc. + * local labels: Local Labels. +*************** +*** 1163,1177 **** + * local variables, specifying registers: Local Reg Vars. + * LOCAL_INCLUDE_DIR: Driver. + * LOCAL_LABEL_PREFIX: Instruction Output. +- * logical-and, bitwise: Arithmetic. + * LOG_LINKS: Insns. +! * longjmp: Global Reg Vars. +! * LONGJMP_RESTORE_FROM_STACK: Elimination. + * LONG_DOUBLE_TYPE_SIZE: Type Layout. + * LONG_LONG_TYPE_SIZE: Type Layout. + * LONG_TYPE_SIZE: Type Layout. + * loop optimization: Passes. +- * lo_sum: Arithmetic. + * lshiftrt: Arithmetic. + * lt: Comparisons. + * ltu: Comparisons. +--- 1161,1174 ---- + * local variables, specifying registers: Local Reg Vars. + * LOCAL_INCLUDE_DIR: Driver. + * LOCAL_LABEL_PREFIX: Instruction Output. + * LOG_LINKS: Insns. +! * logical-and, bitwise: Arithmetic. + * LONG_DOUBLE_TYPE_SIZE: Type Layout. + * LONG_LONG_TYPE_SIZE: Type Layout. + * LONG_TYPE_SIZE: Type Layout. ++ * longjmp: Global Reg Vars. ++ * LONGJMP_RESTORE_FROM_STACK: Elimination. + * loop optimization: Passes. + * lshiftrt: Arithmetic. + * lt: Comparisons. + * ltu: Comparisons. +*************** +*** 1194,1213 **** + * macros, target description: Target Macros. + * macros, types of arguments: Typeof. + * make: Preprocessor Options. +- * makefile fragment: Fragments. + * make_safe_from: Expander Definitions. +! * matching constraint: Simple Constraints. +! * matching operands: Output Template. + * match_dup: RTL Template. + * match_operand: RTL Template. + * match_operator: RTL Template. +- * match_op_dup: RTL Template. +- * match_parallel: RTL Template. + * match_par_dup: RTL Template. + * match_scratch: RTL Template. + * math libraries: Interface. + * math, in RTL: Arithmetic. +- * maximum operator: Min and Max. + * MAX_BITS_PER_WORD: Storage Layout. + * MAX_CHAR_TYPE_SIZE: Type Layout. + * MAX_FIXED_MODE_SIZE: Storage Layout. +--- 1191,1209 ---- + * macros, target description: Target Macros. + * macros, types of arguments: Typeof. + * make: Preprocessor Options. + * make_safe_from: Expander Definitions. +! * makefile fragment: Fragments. + * match_dup: RTL Template. ++ * match_op_dup: RTL Template. + * match_operand: RTL Template. + * match_operator: RTL Template. + * match_par_dup: RTL Template. ++ * match_parallel: RTL Template. + * match_scratch: RTL Template. ++ * matching constraint: Simple Constraints. ++ * matching operands: Output Template. + * math libraries: Interface. + * math, in RTL: Arithmetic. + * MAX_BITS_PER_WORD: Storage Layout. + * MAX_CHAR_TYPE_SIZE: Type Layout. + * MAX_FIXED_MODE_SIZE: Storage Layout. +*************** +*** 1217,1222 **** +--- 1213,1219 ---- + * MAX_OFILE_ALIGNMENT: Storage Layout. + * MAX_REGS_PER_ADDRESS: Addressing Modes. + * MAX_WCHAR_TYPE_SIZE: Type Layout. ++ * maximum operator: Min and Max. + * MAYBE_REG_PARM_STACK_SPACE: Stack Arguments. + * mcount: Profiling. + * MD_CALL_PROTOTYPES: Config. +*************** +*** 1224,1229 **** +--- 1221,1228 ---- + * MD_STARTFILE_PREFIX: Driver. + * MD_STARTFILE_PREFIX_1: Driver. + * mem: Regs and Memory. ++ * MEM_IN_STRUCT_P: Flags. ++ * MEM_VOLATILE_P: Flags. + * member fns, automatically inline: Inline. + * memcmp: C Dialect Options. + * memcpy: C Dialect Options. +*************** +*** 1231,1250 **** + * memory reference, nonoffsettable: Simple Constraints. + * memory references in constraints: Simple Constraints. + * MEMORY_MOVE_COST: Costs. +- * MEM_IN_STRUCT_P: Flags. +- * MEM_VOLATILE_P: Flags. + * messages, warning: Warning Options. + * messages, warning and error: Warnings and Errors. + * middle-operands, omitted: Conditionals. + * minimum operator: Min and Max. + * minus: Arithmetic. +- * MIN_UNITS_PER_WORD: Storage Layout. + * MIPS options: MIPS Options. + * misunderstandings in C++: C++ Misunderstandings. + * mod: Arithmetic. + * MODDI3_LIBCALL: Library Calls. + * mode classes: Machine Modes. +- * MODES_TIEABLE_P: Values in Registers. + * MODE_CC: Machine Modes. + * MODE_COMPLEX_FLOAT: Machine Modes. + * MODE_COMPLEX_INT: Machine Modes. +--- 1230,1246 ---- + * memory reference, nonoffsettable: Simple Constraints. + * memory references in constraints: Simple Constraints. + * MEMORY_MOVE_COST: Costs. + * messages, warning: Warning Options. + * messages, warning and error: Warnings and Errors. + * middle-operands, omitted: Conditionals. ++ * MIN_UNITS_PER_WORD: Storage Layout. + * minimum operator: Min and Max. + * minus: Arithmetic. + * MIPS options: MIPS Options. + * misunderstandings in C++: C++ Misunderstandings. + * mod: Arithmetic. + * MODDI3_LIBCALL: Library Calls. + * mode classes: Machine Modes. + * MODE_CC: Machine Modes. + * MODE_COMPLEX_FLOAT: Machine Modes. + * MODE_COMPLEX_INT: Machine Modes. +*************** +*** 1253,1258 **** +--- 1249,1255 ---- + * MODE_INT: Machine Modes. + * MODE_PARTIAL_INT: Machine Modes. + * MODE_RANDOM: Machine Modes. ++ * MODES_TIEABLE_P: Values in Registers. + * modifiers in constraints: Modifiers. + * MODSI3_LIBCALL: Library Calls. + * MOVE_MAX: Misc. +*************** +*** 1268,1273 **** +--- 1265,1271 ---- + * multiple alternative constraints: Multi-Alternative. + * multiplication: Arithmetic. + * multiprecision arithmetic: Long Long. ++ * N_REG_CLASSES: Register Classes. + * name augmentation: VMS Misc. + * named patterns and conditions: Patterns. + * named return value in C++: Naming Results. +*************** +*** 1286,1297 **** + * nil: RTL Objects. + * no constraints: No Constraints. + * no-op move instructions: Passes. + * non-constant initializers: Initializers. + * non-static inline function: Inline. + * nongcc_SI_type: Library Calls. + * nongcc_word_type: Library Calls. + * nonoffsettable memory reference: Simple Constraints. +- * NON_SAVING_SETJMP: Register Basics. + * not: Arithmetic. + * not equal: Comparisons. + * not using constraints: No Constraints. +--- 1284,1306 ---- + * nil: RTL Objects. + * no constraints: No Constraints. + * no-op move instructions: Passes. ++ * NO_BUILTIN_PTRDIFF_TYPE: Driver. ++ * NO_BUILTIN_SIZE_TYPE: Driver. ++ * NO_DOLLAR_IN_LABEL: Misc. ++ * NO_DOT_IN_LABEL: Misc. ++ * NO_FUNCTION_CSE: Costs. ++ * NO_IMPLICIT_EXTERN_C: Misc. ++ * NO_MD_PROTOTYPES: Config. ++ * NO_RECURSIVE_FUNCTION_CSE: Costs. ++ * NO_REGS: Register Classes. ++ * NO_STAB_H: Config. ++ * NO_SYS_SIGLIST: Config. + * non-constant initializers: Initializers. + * non-static inline function: Inline. ++ * NON_SAVING_SETJMP: Register Basics. + * nongcc_SI_type: Library Calls. + * nongcc_word_type: Library Calls. + * nonoffsettable memory reference: Simple Constraints. + * not: Arithmetic. + * not equal: Comparisons. + * not using constraints: No Constraints. +*************** +*** 1308,1335 **** + * NOTE_LINE_NUMBER: Insns. + * NOTE_SOURCE_FILE: Insns. + * NOTICE_UPDATE_CC: Condition Code. +- * NO_BUILTIN_PTRDIFF_TYPE: Driver. +- * NO_BUILTIN_SIZE_TYPE: Driver. +- * NO_DOLLAR_IN_LABEL: Misc. +- * NO_DOT_IN_LABEL: Misc. +- * NO_FUNCTION_CSE: Costs. +- * NO_IMPLICIT_EXTERN_C: Misc. +- * NO_MD_PROTOTYPES: Config. +- * NO_RECURSIVE_FUNCTION_CSE: Costs. +- * NO_REGS: Register Classes. +- * NO_STAB_H: Config. +- * NO_SYS_SIGLIST: Config. + * NUM_MACHINE_MODES: Machine Modes. +- * N_REG_CLASSES: Register Classes. + * OBJC_GEN_METHOD_LABEL: Label Output. + * OBJC_INCLUDE_PATH: Environment Variables. + * OBJC_INT_SELECTORS: Type Layout. + * OBJC_PROLOGUE: File Framework. + * OBJC_SELECTORS_WITHOUT_LABELS: Type Layout. +- * Objective C: G++ and GCC. + * OBJECT_FORMAT_COFF: Macros for Initialization. + * OBJECT_FORMAT_ROSE: Macros for Initialization. + * OBJECT_SUFFIX: Config. + * OBSTACK_CHUNK_ALLOC: Config. + * OBSTACK_CHUNK_FREE: Config. + * OBSTACK_CHUNK_SIZE: Config. +--- 1317,1332 ---- + * NOTE_LINE_NUMBER: Insns. + * NOTE_SOURCE_FILE: Insns. + * NOTICE_UPDATE_CC: Condition Code. + * NUM_MACHINE_MODES: Machine Modes. + * OBJC_GEN_METHOD_LABEL: Label Output. + * OBJC_INCLUDE_PATH: Environment Variables. + * OBJC_INT_SELECTORS: Type Layout. + * OBJC_PROLOGUE: File Framework. + * OBJC_SELECTORS_WITHOUT_LABELS: Type Layout. + * OBJECT_FORMAT_COFF: Macros for Initialization. + * OBJECT_FORMAT_ROSE: Macros for Initialization. + * OBJECT_SUFFIX: Config. ++ * Objective C: G++ and GCC. + * OBSTACK_CHUNK_ALLOC: Config. + * OBSTACK_CHUNK_FREE: Config. + * OBSTACK_CHUNK_SIZE: Config. +*************** +*** 1364,1374 **** + * order of evaluation, side effects: Non-bugs. + * order of options: Invoking GCC. + * order of register allocation: Allocation Order. +- * Ordering of Patterns: Pattern Ordering. + * ORDER_REGS_FOR_LOCAL_ALLOC: Allocation Order. + * other directory, compilation in: Other Dir. +- * OUTGOING_REGNO: Register Basics. + * OUTGOING_REG_PARM_STACK_SPACE: Stack Arguments. + * output file option: Overall Options. + * output of assembler code: File Framework. + * output statements: Output Statement. +--- 1361,1371 ---- + * order of evaluation, side effects: Non-bugs. + * order of options: Invoking GCC. + * order of register allocation: Allocation Order. + * ORDER_REGS_FOR_LOCAL_ALLOC: Allocation Order. ++ * Ordering of Patterns: Pattern Ordering. + * other directory, compilation in: Other Dir. + * OUTGOING_REG_PARM_STACK_SPACE: Stack Arguments. ++ * OUTGOING_REGNO: Register Basics. + * output file option: Overall Options. + * output of assembler code: File Framework. + * output statements: Output Statement. +*************** +*** 1383,1390 **** + * parameter forward declaration: Variable Length. + * parameters, miscellaneous: Misc. + * PARM_BOUNDARY: Storage Layout. +- * parser generator, Bison: Installation. + * PARSE_LDD_OUTPUT: Macros for Initialization. + * parsing pass: Passes. + * passes and files of the compiler: Passes. + * passing arguments: Interface. +--- 1380,1387 ---- + * parameter forward declaration: Variable Length. + * parameters, miscellaneous: Misc. + * PARM_BOUNDARY: Storage Layout. + * PARSE_LDD_OUTPUT: Macros for Initialization. ++ * parser generator, Bison: Installation. + * parsing pass: Passes. + * passes and files of the compiler: Passes. + * passing arguments: Interface. +*************** +*** 1395,1418 **** + * Pattern Ordering: Pattern Ordering. + * patterns: Patterns. + * pc: Regs and Memory. + * PCC_BITFIELD_TYPE_MATTERS: Storage Layout. + * PCC_STATIC_STRUCT_RETURN: Aggregate Return. +- * pc_rtx: Regs and Memory. + * PDImode: Machine Modes. + * peephole optimization: Passes. + * peephole optimization, RTL representation: Side Effects. + * peephole optimizer definitions: Peephole Definitions. + * percent sign: Output Template. + * perform_...: Library Calls. + * PIC: Code Gen Options. +- * PIC: PIC. +- * PIC_OFFSET_TABLE_REGNUM: PIC. + * PIC_OFFSET_TABLE_REG_CALL_CLOBBERED: PIC. + * plus: Arithmetic. + * Pmode: Misc. + * pointer arguments: Function Attributes. +- * POINTERS_EXTEND_UNSIGNED: Storage Layout. + * POINTER_SIZE: Storage Layout. + * portability: Portability. + * portions of temporary objects, pointers to: Temporaries. + * position independent code: PIC. +--- 1392,1415 ---- + * Pattern Ordering: Pattern Ordering. + * patterns: Patterns. + * pc: Regs and Memory. ++ * pc_rtx: Regs and Memory. + * PCC_BITFIELD_TYPE_MATTERS: Storage Layout. + * PCC_STATIC_STRUCT_RETURN: Aggregate Return. + * PDImode: Machine Modes. + * peephole optimization: Passes. + * peephole optimization, RTL representation: Side Effects. + * peephole optimizer definitions: Peephole Definitions. + * percent sign: Output Template. + * perform_...: Library Calls. ++ * PIC <1>: PIC. + * PIC: Code Gen Options. + * PIC_OFFSET_TABLE_REG_CALL_CLOBBERED: PIC. ++ * PIC_OFFSET_TABLE_REGNUM: PIC. + * plus: Arithmetic. + * Pmode: Misc. + * pointer arguments: Function Attributes. + * POINTER_SIZE: Storage Layout. ++ * POINTERS_EXTEND_UNSIGNED: Storage Layout. + * portability: Portability. + * portions of temporary objects, pointers to: Temporaries. + * position independent code: PIC. +*************** +*** 1423,1428 **** +--- 1420,1427 ---- + * pragma, reason for not using: Function Attributes. + * pragmas in C++, effect on inlining: C++ Interface. + * pragmas, interface and implementation: C++ Interface. ++ * pre_dec: Incdec. ++ * pre_inc: Incdec. + * predefined macros: Run-time Target. + * PREDICATE_CODES: Misc. + * PREFERRED_DEBUGGING_TYPE: All Debuggers. +*************** +*** 1435,1442 **** + * prev_active_insn: Peephole Definitions. + * prev_cc0_setter: Jump Patterns. + * PREV_INSN: Insns. +- * pre_dec: Incdec. +- * pre_inc: Incdec. + * PRINT_OPERAND: Instruction Output. + * PRINT_OPERAND_ADDRESS: Instruction Output. + * PRINT_OPERAND_PUNCT_VALID_P: Instruction Output. +--- 1434,1439 ---- +*************** +*** 1457,1467 **** + * PTRDIFF_TYPE: Type Layout. + * push address instruction: Simple Constraints. + * PUSH_ROUNDING: Stack Arguments. +- * putenv: Config. + * PUT_CODE: RTL Objects. + * PUT_MODE: Machine Modes. + * PUT_REG_NOTE_KIND: Insns. + * PUT_SDB_...: SDB and DWARF. + * QImode: Machine Modes. + * question mark: Multi-Alternative. + * quotient: Arithmetic. +--- 1454,1464 ---- + * PTRDIFF_TYPE: Type Layout. + * push address instruction: Simple Constraints. + * PUSH_ROUNDING: Stack Arguments. + * PUT_CODE: RTL Objects. + * PUT_MODE: Machine Modes. + * PUT_REG_NOTE_KIND: Insns. + * PUT_SDB_...: SDB and DWARF. ++ * putenv: Config. + * QImode: Machine Modes. + * question mark: Multi-Alternative. + * quotient: Arithmetic. +*************** +*** 1472,1479 **** + * REAL_ARITHMETIC: Cross-compilation. + * REAL_INFINITY: Cross-compilation. + * REAL_NM_FILE_NAME: Macros for Initialization. +- * REAL_VALUES_EQUAL: Cross-compilation. +- * REAL_VALUES_LESS: Cross-compilation. + * REAL_VALUE_ATOF: Cross-compilation. + * REAL_VALUE_FIX: Cross-compilation. + * REAL_VALUE_FROM_INT: Cross-compilation. +--- 1469,1474 ---- +*************** +*** 1491,1527 **** + * REAL_VALUE_TYPE: Cross-compilation. + * REAL_VALUE_UNSIGNED_FIX: Cross-compilation. + * REAL_VALUE_UNSIGNED_RNDZINT: Cross-compilation. +! * recognizing insns: RTL Template. + * recog_operand: Instruction Output. + * reg: Regs and Memory. +- * register allocation: Passes. +- * register allocation order: Allocation Order. +- * register allocation, stupid: Passes. +- * register class definitions: Register Classes. +- * register class preference constraints: Class Preferences. +- * register class preference pass: Passes. +- * register pairs: Values in Registers. +- * register positions in frame (88k): M88K Options. +- * register positions in frame (88k): M88K Options. +- * Register Transfer Language (RTL): RTL. +- * register usage: Registers. +- * register use analysis: Passes. +- * register variable after longjmp: Global Reg Vars. +- * register-to-stack conversion: Passes. +- * registers: Extended Asm. +- * registers arguments: Register Arguments. +- * registers for local variables: Local Reg Vars. +- * registers in constraints: Simple Constraints. +- * registers, global allocation: Explicit Reg Vars. +- * registers, global variables in: Global Reg Vars. +- * REGISTER_MOVE_COST: Costs. +- * REGISTER_NAMES: Instruction Output. +- * register_operand: RTL Template. +- * REGISTER_PREFIX: Instruction Output. +- * REGNO_OK_FOR_BASE_P: Register Classes. +- * REGNO_OK_FOR_INDEX_P: Register Classes. +- * REGNO_REG_CLASS: Register Classes. +- * regs_ever_live: Function Entry. + * REG_ALLOC_ORDER: Allocation Order. + * REG_CC_SETTER: Insns. + * REG_CC_USER: Insns. +--- 1486,1496 ---- + * REAL_VALUE_TYPE: Cross-compilation. + * REAL_VALUE_UNSIGNED_FIX: Cross-compilation. + * REAL_VALUE_UNSIGNED_RNDZINT: Cross-compilation. +! * REAL_VALUES_EQUAL: Cross-compilation. +! * REAL_VALUES_LESS: Cross-compilation. + * recog_operand: Instruction Output. ++ * recognizing insns: RTL Template. + * reg: Regs and Memory. + * REG_ALLOC_ORDER: Allocation Order. + * REG_CC_SETTER: Insns. + * REG_CC_USER: Insns. +*************** +*** 1539,1548 **** + * REG_LIBCALL: Insns. + * REG_LOOP_TEST_P: Flags. + * reg_names: Instruction Output. + * REG_NONNEG: Insns. +- * REG_NOTES: Insns. + * REG_NOTE_KIND: Insns. +! * REG_NO_CONFLICT: Insns. + * REG_OK_FOR_BASE_P: Addressing Modes. + * REG_OK_FOR_INDEX_P: Addressing Modes. + * REG_OK_STRICT: Addressing Modes. +--- 1508,1517 ---- + * REG_LIBCALL: Insns. + * REG_LOOP_TEST_P: Flags. + * reg_names: Instruction Output. ++ * REG_NO_CONFLICT: Insns. + * REG_NONNEG: Insns. + * REG_NOTE_KIND: Insns. +! * REG_NOTES: Insns. + * REG_OK_FOR_BASE_P: Addressing Modes. + * REG_OK_FOR_INDEX_P: Addressing Modes. + * REG_OK_STRICT: Addressing Modes. +*************** +*** 1551,1562 **** + * REG_UNUSED: Insns. + * REG_USERVAR_P: Flags. + * REG_WAS_0: Insns. + * relative costs: Costs. + * RELATIVE_PREFIX_NOT_LINKDIR: Driver. + * reload pass: Regs and Memory. +- * reloading: Passes. + * reload_completed: Standard Names. + * reload_in_progress: Standard Names. + * remainder: Arithmetic. + * reordering, warning: Warning Options. + * reporting bugs: Bugs. +--- 1520,1558 ---- + * REG_UNUSED: Insns. + * REG_USERVAR_P: Flags. + * REG_WAS_0: Insns. ++ * register allocation: Passes. ++ * register allocation order: Allocation Order. ++ * register allocation, stupid: Passes. ++ * register class definitions: Register Classes. ++ * register class preference constraints: Class Preferences. ++ * register class preference pass: Passes. ++ * register pairs: Values in Registers. ++ * register positions in frame (88k): M88K Options. ++ * Register Transfer Language (RTL): RTL. ++ * register usage: Registers. ++ * register use analysis: Passes. ++ * register variable after longjmp: Global Reg Vars. ++ * register-to-stack conversion: Passes. ++ * REGISTER_MOVE_COST: Costs. ++ * REGISTER_NAMES: Instruction Output. ++ * register_operand: RTL Template. ++ * REGISTER_PREFIX: Instruction Output. ++ * registers: Extended Asm. ++ * registers arguments: Register Arguments. ++ * registers for local variables: Local Reg Vars. ++ * registers in constraints: Simple Constraints. ++ * registers, global allocation: Explicit Reg Vars. ++ * registers, global variables in: Global Reg Vars. ++ * REGNO_OK_FOR_BASE_P: Register Classes. ++ * REGNO_OK_FOR_INDEX_P: Register Classes. ++ * REGNO_REG_CLASS: Register Classes. ++ * regs_ever_live: Function Entry. + * relative costs: Costs. + * RELATIVE_PREFIX_NOT_LINKDIR: Driver. + * reload pass: Regs and Memory. + * reload_completed: Standard Names. + * reload_in_progress: Standard Names. ++ * reloading: Passes. + * remainder: Arithmetic. + * reordering, warning: Warning Options. + * reporting bugs: Bugs. +*************** +*** 1568,1584 **** + * return value of main: VMS Misc. + * return value, named, in C++: Naming Results. + * return values in registers: Scalar Return. +- * returning aggregate values: Aggregate Return. +- * returning structures and unions: Interface. + * RETURN_ADDR_IN_PREVIOUS_FRAME: Frame Layout. + * RETURN_ADDR_RTX: Frame Layout. + * RETURN_IN_MEMORY: Aggregate Return. + * RETURN_POPS_ARGS: Stack Arguments. + * REVERSIBLE_CC_MODE: Condition Code. + * right rotate: Arithmetic. + * right shift: Arithmetic. + * rotate: Arithmetic. +- * rotate: Arithmetic. + * rotatert: Arithmetic. + * ROUND_TYPE_ALIGN: Storage Layout. + * ROUND_TYPE_SIZE: Storage Layout. +--- 1564,1579 ---- + * return value of main: VMS Misc. + * return value, named, in C++: Naming Results. + * return values in registers: Scalar Return. + * RETURN_ADDR_IN_PREVIOUS_FRAME: Frame Layout. + * RETURN_ADDR_RTX: Frame Layout. + * RETURN_IN_MEMORY: Aggregate Return. + * RETURN_POPS_ARGS: Stack Arguments. ++ * returning aggregate values: Aggregate Return. ++ * returning structures and unions: Interface. + * REVERSIBLE_CC_MODE: Condition Code. + * right rotate: Arithmetic. + * right shift: Arithmetic. + * rotate: Arithmetic. + * rotatert: Arithmetic. + * ROUND_TYPE_ALIGN: Storage Layout. + * ROUND_TYPE_SIZE: Storage Layout. +*************** +*** 1624,1633 **** + * saveable_obstack: Addressing Modes. + * scalars, returned as values: Scalar Return. + * SCCS_DIRECTIVE: Misc. + * scheduling, delayed branch: Passes. + * scheduling, instruction: Passes. +- * scheduling, instruction: Passes. +- * SCHED_GROUP_P: Flags. + * SCmode: Machine Modes. + * scope of a variable length array: Variable Length. + * scope of declaration: Disappointments. +--- 1619,1627 ---- + * saveable_obstack: Addressing Modes. + * scalars, returned as values: Scalar Return. + * SCCS_DIRECTIVE: Misc. ++ * SCHED_GROUP_P: Flags. + * scheduling, delayed branch: Passes. + * scheduling, instruction: Passes. + * SCmode: Machine Modes. + * scope of a variable length array: Variable Length. + * scope of declaration: Disappointments. +*************** +*** 1654,1667 **** + * sequence: Side Effects. + * sequential consistency on 88k: M88K Options. + * set: Side Effects. +- * setjmp: Global Reg Vars. +- * SETUP_FRAME_ADDRESSES: Frame Layout. +- * SETUP_INCOMING_VARARGS: Varargs. + * set_attr: Tagging Insns. + * set_attr_alternative: Tagging Insns. + * SET_DEFAULT_TYPE_ATTRIBUTES: Misc. + * SET_DEST: Side Effects. + * SET_SRC: Side Effects. + * SFmode: Machine Modes. + * shared strings: Incompatibilities. + * shared VMS run time system: VMS Misc. +--- 1648,1661 ---- + * sequence: Side Effects. + * sequential consistency on 88k: M88K Options. + * set: Side Effects. + * set_attr: Tagging Insns. + * set_attr_alternative: Tagging Insns. + * SET_DEFAULT_TYPE_ATTRIBUTES: Misc. + * SET_DEST: Side Effects. + * SET_SRC: Side Effects. ++ * setjmp: Global Reg Vars. ++ * SETUP_FRAME_ADDRESSES: Frame Layout. ++ * SETUP_INCOMING_VARARGS: Varargs. + * SFmode: Machine Modes. + * shared strings: Incompatibilities. + * shared VMS run time system: VMS Misc. +*************** +*** 1673,1678 **** +--- 1667,1674 ---- + * side effect in ?:: Conditionals. + * side effects, macro argument: Statement Exprs. + * side effects, order of evaluation: Non-bugs. ++ * sign_extend: Conversions. ++ * sign_extract: Bit Fields. + * signature: C++ Signatures. + * signature member function default implementation: C++ Signatures. + * signatures, C++: C++ Signatures. +*************** +*** 1680,1699 **** + * signed maximum: Arithmetic. + * signed minimum: Arithmetic. + * SIGNED_CHAR_SPEC: Driver. +- * sign_extend: Conversions. +- * sign_extract: Bit Fields. + * SImode: Machine Modes. + * simple constraints: Simple Constraints. + * simplifications, arithmetic: Passes. + * sin: C Dialect Options. +- * sizeof: Typeof. + * SIZE_TYPE: Type Layout. + * SLOW_BYTE_ACCESS: Costs. + * SLOW_UNALIGNED_ACCESS: Costs. + * SLOW_ZERO_EXTEND: Costs. + * smaller data references (88k): M88K Options. + * smaller data references (MIPS): MIPS Options. +- * SMALL_REGISTER_CLASSES: Register Classes. + * smax: Arithmetic. + * smin: Arithmetic. + * SPARC options: SPARC Options. +--- 1676,1693 ---- + * signed maximum: Arithmetic. + * signed minimum: Arithmetic. + * SIGNED_CHAR_SPEC: Driver. + * SImode: Machine Modes. + * simple constraints: Simple Constraints. + * simplifications, arithmetic: Passes. + * sin: C Dialect Options. + * SIZE_TYPE: Type Layout. ++ * sizeof: Typeof. + * SLOW_BYTE_ACCESS: Costs. + * SLOW_UNALIGNED_ACCESS: Costs. + * SLOW_ZERO_EXTEND: Costs. ++ * SMALL_REGISTER_CLASSES: Register Classes. + * smaller data references (88k): M88K Options. + * smaller data references (MIPS): MIPS Options. + * smax: Arithmetic. + * smin: Arithmetic. + * SPARC options: SPARC Options. +*************** +*** 1704,1710 **** + * specifying registers for local variables: Local Reg Vars. + * speed of instructions: Costs. + * splitting instructions: Insn Splitting. +! * sqrt: Arithmetic. + * sqrt: C Dialect Options. + * square root: Arithmetic. + * stack arguments: Stack Arguments. +--- 1698,1704 ---- + * specifying registers for local variables: Local Reg Vars. + * speed of instructions: Costs. + * splitting instructions: Insn Splitting. +! * sqrt <1>: Arithmetic. + * sqrt: C Dialect Options. + * square root: Arithmetic. + * stack arguments: Stack Arguments. +*************** +*** 1733,1743 **** + * STATIC_CHAIN_INCOMING_REGNUM: Frame Registers. + * STATIC_CHAIN_REGNUM: Frame Registers. + * storage layout: Storage Layout. +- * storem bug (29k): AMD29K Options. + * STORE_FLAG_VALUE: Misc. + * strcmp: C Dialect Options. + * strcpy: C Dialect Options. +- * strcpy: Storage Layout. + * strength-reduction: Passes. + * STRICT_ALIGNMENT: Storage Layout. + * STRICT_ARGUMENT_NAMING: Varargs. +--- 1727,1737 ---- + * STATIC_CHAIN_INCOMING_REGNUM: Frame Registers. + * STATIC_CHAIN_REGNUM: Frame Registers. + * storage layout: Storage Layout. + * STORE_FLAG_VALUE: Misc. ++ * storem bug (29k): AMD29K Options. + * strcmp: C Dialect Options. ++ * strcpy <1>: Storage Layout. + * strcpy: C Dialect Options. + * strength-reduction: Passes. + * STRICT_ALIGNMENT: Storage Layout. + * STRICT_ARGUMENT_NAMING: Varargs. +*************** +*** 1746,1761 **** + * string constants vs newline: C Dialect Options. + * STRIP_NAME_ENCODING: Sections. + * strlen: C Dialect Options. + * structure passing (88k): M88K Options. + * structure value address: Aggregate Return. + * structures: Incompatibilities. + * structures, constructor expression: Constructors. + * structures, returning: Interface. +- * STRUCTURE_SIZE_BOUNDARY: Storage Layout. +- * STRUCT_VALUE: Aggregate Return. +- * STRUCT_VALUE_INCOMING: Aggregate Return. +- * STRUCT_VALUE_INCOMING_REGNUM: Aggregate Return. +- * STRUCT_VALUE_REGNUM: Aggregate Return. + * stupid register allocation: Passes. + * submodel options: Submodel Options. + * subreg: Regs and Memory. +--- 1740,1755 ---- + * string constants vs newline: C Dialect Options. + * STRIP_NAME_ENCODING: Sections. + * strlen: C Dialect Options. ++ * STRUCT_VALUE: Aggregate Return. ++ * STRUCT_VALUE_INCOMING: Aggregate Return. ++ * STRUCT_VALUE_INCOMING_REGNUM: Aggregate Return. ++ * STRUCT_VALUE_REGNUM: Aggregate Return. + * structure passing (88k): M88K Options. + * structure value address: Aggregate Return. ++ * STRUCTURE_SIZE_BOUNDARY: Storage Layout. + * structures: Incompatibilities. + * structures, constructor expression: Constructors. + * structures, returning: Interface. + * stupid register allocation: Passes. + * submodel options: Submodel Options. + * subreg: Regs and Memory. +*************** +*** 1773,1788 **** + * suppressing warnings: Warning Options. + * surprises in C++: C++ Misunderstandings. + * SVr4: M88K Options. +- * SWITCHES_NEED_SPACES: Driver. + * SWITCH_TAKES_ARG: Driver. +! * symbolic label: Sharing. + * symbol_ref: Constants. + * SYMBOL_REF_FLAG: Flags. + * SYMBOL_REF_USED: Flags. + * syntax checking: Warning Options. + * synthesized methods, warning: Warning Options. +- * SYSTEM_INCLUDE_DIR: Driver. + * sys_siglist: Config. + * tagging insns: Tagging Insns. + * tail recursion optimization: Passes. + * target description macros: Target Macros. +--- 1767,1782 ---- + * suppressing warnings: Warning Options. + * surprises in C++: C++ Misunderstandings. + * SVr4: M88K Options. + * SWITCH_TAKES_ARG: Driver. +! * SWITCHES_NEED_SPACES: Driver. + * symbol_ref: Constants. + * SYMBOL_REF_FLAG: Flags. + * SYMBOL_REF_USED: Flags. ++ * symbolic label: Sharing. + * syntax checking: Warning Options. + * synthesized methods, warning: Warning Options. + * sys_siglist: Config. ++ * SYSTEM_INCLUDE_DIR: Driver. + * tagging insns: Tagging Insns. + * tail recursion optimization: Passes. + * target description macros: Target Macros. +*************** +*** 1818,1828 **** + * top level of compiler: Passes. + * traditional C language: C Dialect Options. + * TRADITIONAL_RETURN_FLOAT: Scalar Return. +- * trampolines for nested functions: Trampolines. + * TRAMPOLINE_ALIGNMENT: Trampolines. + * TRAMPOLINE_SECTION: Trampolines. + * TRAMPOLINE_SIZE: Trampolines. + * TRAMPOLINE_TEMPLATE: Trampolines. + * TRANSFER_FROM_TRAMPOLINE: Trampolines. + * TRULY_NOOP_TRUNCATION: Misc. + * truncate: Conversions. +--- 1812,1822 ---- + * top level of compiler: Passes. + * traditional C language: C Dialect Options. + * TRADITIONAL_RETURN_FLOAT: Scalar Return. + * TRAMPOLINE_ALIGNMENT: Trampolines. + * TRAMPOLINE_SECTION: Trampolines. + * TRAMPOLINE_SIZE: Trampolines. + * TRAMPOLINE_TEMPLATE: Trampolines. ++ * trampolines for nested functions: Trampolines. + * TRANSFER_FROM_TRAMPOLINE: Trampolines. + * TRULY_NOOP_TRUNCATION: Misc. + * truncate: Conversions. +*************** +*** 1856,1863 **** + * unshare_all_rtl: Sharing. + * unsigned division: Arithmetic. + * unsigned greater than: Comparisons. +- * unsigned greater than: Comparisons. +- * unsigned less than: Comparisons. + * unsigned less than: Comparisons. + * unsigned minimum and maximum: Arithmetic. + * unsigned_fix: Conversions. +--- 1850,1855 ---- +*************** +*** 1865,1874 **** + * unspec: Side Effects. + * unspec_volatile: Side Effects. + * use: Side Effects. +- * used: Flags. +- * USER_LABEL_PREFIX: Instruction Output. + * USE_C_ALLOCA: Config. + * USE_PROTOTYPES: Config. + * USG: Config. + * VALID_MACHINE_DECL_ATTRIBUTE: Misc. + * VALID_MACHINE_TYPE_ATTRIBUTE: Misc. +--- 1857,1866 ---- + * unspec: Side Effects. + * unspec_volatile: Side Effects. + * use: Side Effects. + * USE_C_ALLOCA: Config. + * USE_PROTOTYPES: Config. ++ * used: Flags. ++ * USER_LABEL_PREFIX: Instruction Output. + * USG: Config. + * VALID_MACHINE_DECL_ATTRIBUTE: Misc. + * VALID_MACHINE_TYPE_ATTRIBUTE: Misc. +*************** +*** 1910,1919 **** + * WCHAR_TYPE_SIZE: Type Layout. + * which_alternative: Output Statement. + * whitespace: Incompatibilities. +- * WORDS_BIG_ENDIAN: Storage Layout. + * word_mode: Machine Modes. + * WORD_REGISTER_OPERATIONS: Misc. + * WORD_SWITCH_TAKES_ARG: Driver. + * XCmode: Machine Modes. + * XCOFF_DEBUGGING_INFO: DBX Options. + * XEXP: Accessors. +--- 1902,1911 ---- + * WCHAR_TYPE_SIZE: Type Layout. + * which_alternative: Output Statement. + * whitespace: Incompatibilities. + * word_mode: Machine Modes. + * WORD_REGISTER_OPERATIONS: Misc. + * WORD_SWITCH_TAKES_ARG: Driver. ++ * WORDS_BIG_ENDIAN: Storage Layout. + * XCmode: Machine Modes. + * XCOFF_DEBUGGING_INFO: DBX Options. + * XEXP: Accessors. +*************** +*** 1929,1945 **** + * zero-length arrays: Zero Length. + * zero_extend: Conversions. + * zero_extract: Bit Fields. +- * \: Output Template. +- * __bb_init_func: Profiling. +- * __builtin_apply: Constructing Calls. +- * __builtin_apply_args: Constructing Calls. +- * __builtin_args_info: Varargs. +- * __builtin_classify_type: Varargs. +- * __builtin_next_arg: Varargs. +- * __builtin_return: Constructing Calls. +- * __builtin_saveregs: Varargs. +- * __CTOR_LIST__: Initialization. +- * __DTOR_LIST__: Initialization. +- * __main: Collect2. + + +--- 1921,1925 ---- +diff -rcP gcc-2.7.2.1/gcc.info-3 gcc-2.7.2.1-objc-960906/gcc.info-3 +*** gcc-2.7.2.1/gcc.info-3 Fri Sep 6 11:21:36 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-3 Fri Sep 6 10:26:18 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-4 gcc-2.7.2.1-objc-960906/gcc.info-4 +*** gcc-2.7.2.1/gcc.info-4 Fri Sep 6 11:21:37 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-4 Fri Sep 6 10:26:18 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-5 gcc-2.7.2.1-objc-960906/gcc.info-5 +*** gcc-2.7.2.1/gcc.info-5 Fri Sep 6 11:21:38 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-5 Fri Sep 6 10:26:19 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-6 gcc-2.7.2.1-objc-960906/gcc.info-6 +*** gcc-2.7.2.1/gcc.info-6 Fri Sep 6 11:21:38 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-6 Fri Sep 6 10:26:19 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 465,468 **** +--- 465,510 ---- + does not distribute a C runtime library, it also does not include + a C++ run-time library. All I/O functionality, special class + libraries, etc., are available in the libg++ distribution. ++ ++ 17. GNU C does include a runtime library for Objective-C because it is ++ an integral part of the language; all of the files associated with ++ the library are located in the subdirectory `objc'. The GNU ++ Objective-C Runtime Library does require header files for the ++ target's C library in order to be compiled, and it will also ++ require the header files for the target's thread library if you ++ want thread support. *Note Cross-Compilers and Header Files: ++ Cross Headers, for discussion about header files issues for ++ cross-compilation. ++ ++ When you run `configure', it picks the appropriate Objective-C ++ back-end thread implementation file for the target platform. In ++ some situations, you may wish to choose a different back-end as ++ some platforms support multiple thread implementations, or you may ++ wish to disable thread support completely. This can be done by ++ specifying a value for the OBJC_THREAD_FILE makefile variable on ++ the command line when you run make, for example: ++ ++ make CC="stage2/xgcc -Bstage2/" CFLAGS="-g -O2" OBJC_THREAD_FILE=thr-single ++ ++ Below is a list of the currently available back-ends. ++ ++ * thr-single; disable thread support, should work for all ++ platforms. ++ ++ * thr-decosf1; DEC OSF/1 thread support. ++ ++ * thr-irix; SGI IRIX thread support. ++ ++ * thr-mach; Generic MACH thread support, known to work on ++ NEXTSTEP. ++ ++ * thr-os2; IBM OS/2 thread support. ++ ++ * thr-posix; Generix POSIX thread support. ++ ++ * thr-pthreads; PCThreads on Linux based GNU systems. ++ ++ * thr-solaris; SUN Solaris thread support. ++ ++ * thr-win32; Microsoft Win32 API thread support. + +diff -rcP gcc-2.7.2.1/gcc.info-7 gcc-2.7.2.1-objc-960906/gcc.info-7 +*** gcc-2.7.2.1/gcc.info-7 Fri Sep 6 11:21:39 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-7 Fri Sep 6 10:26:20 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +*************** +*** 262,337 **** + Structures are no longer a multiple of 2 bytes. + + `hppa*-*-*' +! There are two variants of this CPU, called 1.0 and 1.1, which have +! different machine descriptions. You must use the right one for +! your machine. All 7NN machines and 8N7 machines use 1.1, while +! all other 8NN machines use 1.0. +! +! The easiest way to handle this problem is to use `configure hpNNN' +! or `configure hpNNN-hpux', where NNN is the model number of the +! machine. Then `configure' will figure out if the machine is a 1.0 +! or 1.1. Use `uname -a' to find out the model number of your +! machine. + + `-g' does not work on HP-UX, since that system uses a peculiar + debugging format which GNU CC does not know about. However, `-g' + will work if you also use GAS and GDB in conjunction with GCC. We + highly recommend using GAS for all HP-PA configurations. + +! You should be using GAS-2.3 (or later) along with GDB-4.12 (or + later). These can be retrieved from all the traditional GNU ftp + archive sites. + +! Build GAS and install the resulting binary as: + +! /usr/local/lib/gcc-lib/CONFIGURATION/GCCVERSION/as +! +! where CONFIGURATION is the configuration name (perhaps +! `hpNNN-hpux') and GCCVERSION is the GNU CC version number. Do +! this *before* starting the build process, otherwise you will get +! errors from the HPUX assembler while building `libgcc2.a'. The +! command +! +! make install-dir +! +! will create the necessary directory hierarchy so you can install +! GAS before building GCC. +! +! To enable debugging, configure GNU CC with the `--with-gnu-as' +! option before building. +! +! It has been reported that GNU CC produces invalid assembly code for +! 1.1 machines running HP-UX 8.02 when using the HP assembler. +! Typically the errors look like this: +! as: bug.s @line#15 [err#1060] +! Argument 0 or 2 in FARG upper +! - lookahead = ARGW1=FR,RTNVAL=GR +! as: foo.s @line#28 [err#1060] +! Argument 0 or 2 in FARG upper +! - lookahead = ARGW1=FR +! +! You can check the version of HP-UX you are running by executing +! the command `uname -r'. If you are indeed running HP-UX 8.02 on +! a PA and using the HP assembler then configure GCC with +! "hpNNN-hpux8.02". + + `i370-*-*' + This port is very preliminary and has many known bugs. We hope to + have a higher-quality port for this machine soon. + + `i386-*-linuxoldld' +! Use this configuration to generate a.out binaries on Linux if you +! do not have gas/binutils version 2.5.2 or later installed. This is +! an obsolete configuration. + + `i386-*-linuxaout' +! Use this configuration to generate a.out binaries on Linux. This +! configuration is being superseded. You must use gas/binutils +! version 2.5.2 or later. + + `i386-*-linux' +! Use this configuration to generate ELF binaries on Linux. You must +! use gas/binutils version 2.5.2 or later. + + `i386-*-sco' + Compilation with RCC is recommended. Also, it may be a good idea +--- 262,308 ---- + Structures are no longer a multiple of 2 bytes. + + `hppa*-*-*' +! There are several variants of the HP-PA processor which run a +! variety of operating systems. GNU CC must be configured to use +! the correct processor type and operating system, or GNU CC will +! not function correctly. The easiest way to handle this problem is +! to *not* specify a target when configuring GNU CC, the `configure' +! script will try to automatically determine the right processor +! type and operating system. + + `-g' does not work on HP-UX, since that system uses a peculiar + debugging format which GNU CC does not know about. However, `-g' + will work if you also use GAS and GDB in conjunction with GCC. We + highly recommend using GAS for all HP-PA configurations. + +! You should be using GAS-2.6 (or later) along with GDB-4.16 (or + later). These can be retrieved from all the traditional GNU ftp + archive sites. + +! GAS will need to be installed into a directory before `/bin', +! `/usr/bin', and `/usr/ccs/bin' in your search path. You should +! install GAS before you build GNU CC. + +! To enable debugging, you must configure GNU CC with the +! `--with-gnu-as' option before building. + + `i370-*-*' + This port is very preliminary and has many known bugs. We hope to + have a higher-quality port for this machine soon. + + `i386-*-linuxoldld' +! Use this configuration to generate a.out binaries on Linux-based +! GNU systems, if you do not have gas/binutils version 2.5.2 or later +! installed. This is an obsolete configuration. + + `i386-*-linuxaout' +! Use this configuration to generate a.out binaries on Linux-based +! GNU systems. This configuration is being superseded. You must use +! gas/binutils version 2.5.2 or later. + + `i386-*-linux' +! Use this configuration to generate ELF binaries on Linux-based GNU +! systems. You must use gas/binutils version 2.5.2 or later. + + `i386-*-sco' + Compilation with RCC is recommended. Also, it may be a good idea +diff -rcP gcc-2.7.2.1/gcc.info-8 gcc-2.7.2.1-objc-960906/gcc.info-8 +*** gcc-2.7.2.1/gcc.info-8 Fri Sep 6 11:21:40 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-8 Fri Sep 6 10:26:21 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/gcc.info-9 gcc-2.7.2.1-objc-960906/gcc.info-9 +*** gcc-2.7.2.1/gcc.info-9 Fri Sep 6 11:21:41 1996 +--- gcc-2.7.2.1-objc-960906/gcc.info-9 Fri Sep 6 10:26:22 1996 +*************** +*** 1,4 **** +! This is Info file gcc.info, produced by Makeinfo-1.55 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +--- 1,4 ---- +! This is Info file gcc.info, produced by Makeinfo-1.63 from the input + file gcc.texi. + + This file documents the use and the internals of the GNU compiler. +diff -rcP gcc-2.7.2.1/install.texi gcc-2.7.2.1-objc-960906/install.texi +*** gcc-2.7.2.1/install.texi Fri Sep 6 11:21:58 1996 +--- gcc-2.7.2.1-objc-960906/install.texi Fri Sep 6 10:26:38 1996 +*************** +*** 497,502 **** +--- 497,540 ---- + distribute a C runtime library, it also does not include a C++ run-time + library. All I/O functionality, special class libraries, etc., are + available in the libg++ distribution. ++ ++ @item ++ GNU C does include a runtime library for Objective-C because it is an ++ integral part of the language; all of the files associated with the ++ library are located in the subdirectory @file{objc}. The GNU ++ Objective-C Runtime Library does require header files for the target's C ++ library in order to be compiled, and it will also require the header ++ files for the target's thread library if you want thread support. ++ @xref{Cross Headers, Cross-Compilers and Header Files, Cross-Compilers ++ and Header Files}, for discussion about header files issues for ++ cross-compilation. ++ ++ When you run @file{configure}, it picks the appropriate Objective-C ++ back-end thread implementation file for the target platform. In some ++ situations, you may wish to choose a different back-end as some ++ platforms support multiple thread implementations, or you may wish to ++ disable thread support completely. This can be done by specifying a ++ value for the @var{OBJC_THREAD_FILE} makefile variable on the command ++ line when you run make, for example: ++ ++ @smallexample ++ make CC="stage2/xgcc -Bstage2/" CFLAGS="-g -O2" OBJC_THREAD_FILE=thr-single ++ @end smallexample ++ ++ @noindent ++ Below is a list of the currently available back-ends. ++ ++ @itemize @bullet ++ @item thr-single; disable thread support, should work for all platforms. ++ @item thr-decosf1; DEC OSF/1 thread support. ++ @item thr-irix; SGI IRIX thread support. ++ @item thr-mach; Generic MACH thread support, known to work on NEXTSTEP. ++ @item thr-os2; IBM OS/2 thread support. ++ @item thr-posix; Generix POSIX thread support. ++ @item thr-pthreads; PCThreads on Linux based GNU systems. ++ @item thr-solaris; SUN Solaris thread support. ++ @item thr-win32; Microsoft Win32 API thread support. ++ @end itemize + @end enumerate + + @node Configurations +diff -rcP gcc-2.7.2.1/objc/Makefile gcc-2.7.2.1-objc-960906/objc/Makefile +*** gcc-2.7.2.1/objc/Makefile Fri Sep 6 11:28:53 1996 +--- gcc-2.7.2.1-objc-960906/objc/Makefile Fri Sep 6 10:33:25 1996 +*************** +*** 1,5 **** + # GNU Objective C Runtime Makefile +! # Copyright (C) 1993, 1995 Free Software Foundation, Inc. + # + # This file is part of GNU CC. + # +--- 1,5 ---- + # GNU Objective C Runtime Makefile +! # Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + # + # This file is part of GNU CC. + # +*************** +*** 25,30 **** +--- 25,31 ---- + # srcdir=$$srcdir1 tooldir=$(tooldir) AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" \ + # GCC_FOR_TARGET="$$thisdir1/xgcc -B$$thisdir1/" \ + # GCC_CFLAGS="$(GCC_CFLAGS)" incinstalldir=$$thisdir1/include ++ # OBJC_THREAD_FILE="$(OBJC_THREAD_FILE)" + # Two targets are used by ../Makefile: `all' and `mostlyclean'. + + SHELL=/bin/sh +*************** +*** 56,71 **** + 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: +--- 57,72 ---- + 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 \ +! nil_method.o thr.o $(OBJC_THREAD_FILE).o + + libobjc.a: $(OBJC_O) + $(AR) rc libobjc.a $? + # ranlib is run in the parent directory's makefile. + +! OBJC_H = hash.h objc-list.h sarray.h objc.h \ + objc-api.h \ +! NXConstStr.h Object.h Protocol.h encoding.h typedstream.h thr.h + + # copy objc headers to installation include directory + copy-headers: +*************** +*** 98,100 **** +--- 99,104 ---- + NXConstStr.o: NXConstStr.m + Object.o: Object.m + Protocol.o: Protocol.m ++ thr.o: thr.h thr.c ++ $(OBJC_THREAD_FILE).o: $(OBJC_THREAD_FILE).c ++ nil_method.o: nil_method.c +diff -rcP gcc-2.7.2.1/objc/Object.m gcc-2.7.2.1-objc-960906/objc/Object.m +*** gcc-2.7.2.1/objc/Object.m Fri Sep 6 11:28:54 1996 +--- gcc-2.7.2.1-objc-960906/objc/Object.m Fri Sep 6 10:33:26 1996 +*************** +*** 29,36 **** + #include "objc/Protocol.h" + #include "objc/objc-api.h" + +- extern void (*_objc_error)(id object, const char *format, va_list); +- + extern int errno; + + #define MAX_CLASS_NAME_LEN 256 +--- 29,34 ---- +*************** +*** 337,343 **** + object_is_instance(self)?"instance":"class", + (aString!=NULL)?aString:""); + va_start(ap, aString); +! (*_objc_error)(self, fmt, ap); + va_end(ap); + return nil; + #undef FMT +--- 335,341 ---- + object_is_instance(self)?"instance":"class", + (aString!=NULL)?aString:""); + va_start(ap, aString); +! objc_error(self, OBJC_ERR_UNKNOWN, fmt, ap); + va_end(ap); + return nil; + #undef FMT +diff -rcP gcc-2.7.2.1/objc/README.threads gcc-2.7.2.1-objc-960906/objc/README.threads +*** gcc-2.7.2.1/objc/README.threads Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/README.threads Fri Sep 6 10:33:27 1996 +*************** +*** 0 **** +--- 1,50 ---- ++ ============================================================================== ++ README - Wed Nov 29 15:16:24 EST 1995 ++ ------------------------------------------------------------------------------ ++ ++ Limited documentation is available in the THREADS file. ++ ++ This version has been tested on Sun Solaris, SGI Irix, and Windows NT. ++ It should also work on any single threaded system. ++ ++ Thanks go to the following people for help test and debug the library: ++ ++ Scott Christley, scottc@ocbi.com ++ Andrew McCallum, mccallum@cs.rochester.edu ++ ++ galen ++ gchunt@cs.rochester.edu ++ ++ Any questions, bug reports, etc should be directed to: ++ ++ Scott Christley, scottc@ocbi.com ++ ++ Please do not bug Galen with email as he no longer supports the code. ++ ++ ============================================================================== ++ Changes from prior releases (in revered chronological order): ++ ------------------------------------------------------------------------------ ++ ++ * Fixed bug in copy part of sarray_realloc. I had an < which should ++ have been <=. (Bug report from Scott). ++ ++ ------------------------------------------------------------------------------ ++ ++ * Support for DEC OSF/1 is definitely broken. My programs always ++ seg-fault when I link with libpthreads.a. ++ ++ * Thread id's are no longer int's, but are instead of type ++ _objc_thread_t which is typedef'ed from a void *. An invalid thread ++ id is denoted by NULL and not -1 as before. ++ ++ ------------------------------------------------------------------------------ ++ ++ * Renamed thread-winnt.c to thread-win32.c to better reflect support ++ for the API on both Windows NT and Windows 95 platforms. ++ (Who knows, maybe even Win32s :-). ++ ++ * Fixed bugs in Win32 support as per report from Scott Christley. ++ ++ * Fixed bug in sarray_get as per report from Scott Christley. ++ ++ +diff -rcP gcc-2.7.2.1/objc/THREADS gcc-2.7.2.1-objc-960906/objc/THREADS +*** gcc-2.7.2.1/objc/THREADS Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/THREADS Fri Sep 6 10:33:28 1996 +*************** +*** 0 **** +--- 1,336 ---- ++ This file describes in little detail the modifications to the ++ Objective-C runtime needed to make it thread safe. ++ ++ First off, kudos to Galen Hunt who is the author of this great work. ++ ++ If you have an comments or just want to know where to ++ send me money to express your undying graditude for threading the ++ Objective-C runtime you can reach Galen at: ++ ++ gchunt@cs.rochester.edu ++ ++ Any questions, comments, bug reports, etc. should send email either to the ++ GCC bug account or to: ++ ++ Scott Christley ++ ++ * Sarray Threading: ++ ++ The most critical component of the Objective-C runtime is the sparse array ++ structure (sarray). Sarrays store object selectors and implementations. ++ Following in the tradition of the Objective-C runtime, my threading ++ support assumes that fast message dispatching is far more important ++ than *ANY* and *ALL* other operations. The message dispatching thus ++ uses *NO* locks on any kind. In fact, if you look in sarray.h, you ++ will notice that the message dispatching has not been modified. ++ Instead, I have modified the sarray management functions so that all ++ updates to the sarray data structure can be made in parallel will ++ message dispatching. ++ ++ To support concurrent message dispatching, no dynamically allocated ++ sarray data structures are freed while more than one thread is ++ operational. Sarray data structures that are no longer in use are ++ kept in a linked list of garbage and are released whenever the program ++ is operating with a single thread. The programmer can also flush the ++ garbage list by calling sarray_remove_garbage when the programmer can ++ ensure that no message dispatching is taking place concurrently. The ++ amount of un-reclaimed sarray garbage should normally be extremely ++ small in a real program as sarray structures are freed only when using ++ the "poseAs" functionality and early in program initialization, which ++ normally occurs while the program is single threaded. ++ ++ ****************************************************************************** ++ * Static Variables: ++ ++ The following variables are either statically or globally defined. This list ++ does not include variables which are internal to implementation dependent ++ versions of thread-*.c. ++ ++ The following threading designations are used: ++ SAFE : Implicitly thread safe. ++ SINGLE : Must only be used in single thread mode. ++ MUTEX : Protected by single global mutex objc_runtime_mutex. ++ UNUSED : Not used in the runtime. ++ ++ Variable Name: Usage: Defined: Also used in: ++ =========================== ====== ============ ===================== ++ __objc_class_hash MUTEX class.c ++ __objc_class_links_resolved UNUSED class.c runtime.h ++ __objc_class_number MUTEX class.c ++ __objc_dangling_categories UNUSED init.c ++ __objc_module_list MUTEX init.c ++ __objc_selector_array MUTEX selector.c ++ __objc_selector_hash MUTEX selector.c ++ __objc_selector_max_index MUTEX selector.c sendmsg.c runtime.h ++ __objc_selector_names MUTEX selector.c ++ __objc_thread_exit_status SAFE thread.c ++ __objc_uninstalled_dtable MUTEX sendmsg.c selector.c ++ _objc_load_callback SAFE init.c objc-api.h ++ _objc_lookup_class SAFE class.c objc-api.h ++ _objc_object_alloc SINGLE objects.c objc-api.h ++ _objc_object_copy SINGLE objects.c objc-api.h ++ _objc_object_dispose SINGLE objects.c objc-api.h ++ frwd_sel SAFE2 sendmsg.c ++ idxsize MUTEX sarray.c sendmsg.c sarray.h ++ initialize_sel SAFE2 sendmsg.c ++ narrays MUTEX sarray.c sendmsg.c sarray.h ++ nbuckets MUTEX sarray.c sendmsg.c sarray.h ++ nindices MUTEX sarray.c sarray.h ++ previous_constructors SAFE1 init.c ++ proto_class SAFE1 init.c ++ unclaimed_categories MUTEX init.c ++ unclaimed_proto_list MUTEX init.c ++ uninitialized_statics MUTEX init.c ++ ++ Notes: ++ 1) Initialized once in unithread mode. ++ 2) Initialized value will always be same, guaranteed by lock on selector ++ hash table. ++ ++ ++ ****************************************************************************** ++ * Frontend/Backend design: ++ ++ The design of the Objective-C runtime thread and mutex functions utilizes a ++ frontend/backend implementation. ++ ++ The frontend, as characterized by the files thr.h and thr.c, is a set ++ of platform independent structures and functions which represent the ++ user interface. Objective-C programs should use these structures and ++ functions for their thread and mutex work if they wish to maintain a ++ high degree of portability across platforms. ++ ++ The backend is composed of a file with the necessary code to map the ObjC ++ thread and mutex to a platform specific implementation. For example, the ++ file thr-solaris.c contains the implementation for Solaris. When you ++ configure GCC, it attempts to pick an appropriate backend file for the ++ target platform; however, you can override this choice by assign the ++ OBJC_THREAD_FILE make variable to the basename of the backend file. This ++ is especially useful on platforms which have multiple thread libraries. ++ For example: ++ ++ make OBJC_THREAD_FILE=thr-posix ++ ++ would indicate that the generic posix backend file, thr-posix.c, should be ++ compiled with the ObjC runtime library. If your platform does not support ++ threads then you should specify the OBJC_THREAD_FILE=thr-single backend file ++ to compile the ObjC runtime library without thread or mutex support; note ++ that programs which rely upon the ObjC thread and mutex functions will ++ compile and link correctly but attempting to create a thread or mutex will ++ result in an error. ++ ++ ++ ****************************************************************************** ++ * Threads: ++ ++ The thread system attempts to create multiple threads using whatever ++ operating system or library thread support is available. It does ++ assume that all system functions are thread safe. Notably this means ++ that the system implementation of malloc and free must be thread safe. ++ If a system has multiple processors, the threads are configured for ++ full parallel processing. ++ ++ ***** ++ * Frontend thread functions ++ * User programs should use these thread functions. ++ ++ objc_thread_detach(SEL selector, id object, id argument), objc_thread_t ++ Creates and detaches a new thread. The new thread starts by ++ sending the given selector with a single argument to the ++ given object. ++ ++ objc_thread_set_priority(int priority), int ++ Sets a thread's relative priority within the program. Valid ++ options are: ++ ++ OBJC_THREAD_INTERACTIVE_PRIORITY ++ OBJC_THREAD_BACKGROUND_PRIORITY ++ OBJC_THREAD_LOW_PRIORITY ++ ++ objc_thread_get_priority(void), int ++ Query a thread's priority. ++ ++ objc_thread_yield(void), void ++ Yields processor to another thread with equal or higher ++ priority. It is up to the system scheduler to determine if ++ the processor is taken or not. ++ ++ objc_thread_exit(void), int ++ Terminates a thread. If this is the last thread executing ++ then the program will terminate. ++ ++ objc_thread_id(void), int ++ Returns the current thread's id. ++ ++ objc_thread_set_data(void *value), int ++ Set a pointer to the thread's local storage. Local storage is ++ thread specific. ++ ++ objc_thread_get_data(void), void * ++ Returns the pointer to the thread's local storage. ++ ++ ***** ++ * Backend thread functions ++ * User programs should *NOT* directly call these functions. ++ ++ __objc_init_thread_system(void), int ++ Initialize the thread subsystem. Called once by __objc_exec_class. ++ Return -1 if error otherwise return 0. ++ ++ __objc_fini_thread_system(void), int ++ Closes the thread subsystem, not currently guaranteed to be called. ++ Return -1 if error otherwise return 0. ++ ++ __objc_thread_create(void (*func)(void *arg), void *arg), objc_thread_t ++ Spawns a new thread executing func, called by objc_thread_detach. ++ Return NULL if error otherwise return thread id. ++ ++ __objc_thread_set_priority(int priority), int ++ Set the thread's priority, called by objc_thread_set_priority. ++ Return -1 if error otherwise return 0. ++ ++ __objc_thread_get_priority(void), int ++ Query a thread's priority, called by objc_thread_get_priority. ++ Return -1 if error otherwise return the priority. ++ ++ __objc_thread_yield(void), void ++ Yields the processor, called by objc_thread_yield. ++ ++ __objc_thread_exit(void), int ++ Terminates the thread, called by objc_thread_exit. ++ Return -1 if error otherwise function does not return. ++ ++ __objc_thread_id(void), objc_thread_t ++ Returns the current thread's id, called by objc_thread_id. ++ Return -1 if error otherwise return thread id. ++ ++ __objc_thread_set_data(void *value), int ++ Set pointer for thread local storage, called by objc_thread_set_data. ++ Returns -1 if error otherwise return 0. ++ ++ __objc_thread_get_data(void), void * ++ Returns the pointer to the thread's local storage. ++ Returns NULL if error, called by objc_thread_get_data. ++ ++ ++ ****************************************************************************** ++ * Mutexs: ++ ++ Mutexs can be locked recursively. Each locked mutex remembers ++ its owner (by thread id) and how many times it has been locked. The ++ last unlock on a mutex removes the system lock and allows other ++ threads to access the mutex. ++ ++ ***** ++ * Frontend thread functions ++ * User programs should use these thread functions. ++ ++ objc_mutex_allocate(void), objc_mutex_t ++ Allocates a new mutex. Mutex is initially unlocked. ++ ++ objc_mutex_deallocate(objc_mutex_t mutex), int ++ Free a mutex. Before freeing the mutex, makes sure that no ++ one else is using it. ++ ++ objc_mutex_lock(objc_mutex_t mutex), int ++ Locks a mutex. As mentioned earlier, the same thread may call ++ this routine repeatedly. ++ ++ objc_mutex_trylock(objc_mutex_t mutex), int ++ Attempts to lock a mutex. Returns -1 if failed. If lock on ++ mutex can be acquired then function operates exactly as ++ objc_mutex_lock. ++ ++ objc_mutex_unlock(objc_mutex_t mutex), int ++ Unlocks the mutex by one level. Other threads may not acquire ++ the mutex until this thread has released all locks on it. ++ ++ ***** ++ * Backend thread functions ++ * User programs should *NOT* directly call these functions. ++ ++ __objc_mutex_allocate(void), objc_mutex_t ++ Allocates a new mutex, called by objc_mutex_allocate. ++ Return NULL if error otherwise return mutex pointer. ++ ++ __objc_mutex_deallocate(objc_mutex_t mutex), int ++ Free a mutex, called by objc_mutex_deallocate. ++ Return -1 if error otherwise return 0. ++ ++ __objc_mutex_lock(objc_mutex_t mutex), int ++ Locks a mutex, called by objc_mutex_lock. ++ Return -1 if error otherwise return 0. ++ ++ __objc_mutex_trylock(objc_mutex_t mutex), int ++ Attempts to lock a mutex, called by objc_mutex_trylock. ++ Return -1 if failed to acquire lock or error otherwise return 0. ++ ++ __objc_mutex_unlock(objc_mutex_t mutex), int ++ Unlocks the mutex, called by objc_mutex_unlock. ++ Return -1 if error otherwise return 0. ++ ++ ****************************************************************************** ++ * Condition Mutexs: ++ ++ Mutexs can be locked recursively. Each locked mutex remembers ++ its owner (by thread id) and how many times it has been locked. The ++ last unlock on a mutex removes the system lock and allows other ++ threads to access the mutex. ++ ++ ***** ++ * Frontend thread functions ++ * User programs should use these thread functions. ++ ++ objc_condition_allocate(void), objc_condition_t ++ Allocate a condition mutex. ++ Return NULL if error otherwise return condition pointer. ++ ++ objc_condition_deallocate(objc_condition_t condition), int ++ Deallocate a condition. Note that this includes an implicit ++ condition_broadcast to insure that waiting threads have the ++ opportunity to wake. It is legal to dealloc a condition only ++ if no other thread is/will be using it. Does NOT check for ++ other threads waiting but just wakes them up. ++ ++ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int ++ Wait on the condition unlocking the mutex until objc_condition_signal() ++ or objc_condition_broadcast() are called for the same condition. The ++ given mutex *must* have the depth 1 so that it can be unlocked ++ here, for someone else can lock it and signal/broadcast the condition. ++ The mutex is used to lock access to the shared data that make up the ++ "condition" predicate. ++ ++ objc_condition_broadcast(objc_condition_t condition), int ++ Wake up all threads waiting on this condition. It is recommended that ++ the called would lock the same mutex as the threads in ++ objc_condition_wait before changing the "condition predicate" ++ and make this call and unlock it right away after this call. ++ ++ objc_condition_signal(objc_condition_t condition), int ++ Wake up one thread waiting on this condition. ++ ++ ***** ++ * Backend thread functions ++ * User programs should *NOT* directly call these functions. ++ ++ __objc_condition_allocate(void), objc_condition_t ++ Allocate a condition mutex, called by objc_condition_allocate. ++ Return NULL if error otherwise return condition pointer. ++ ++ __objc_condition_deallocate(objc_condition_t condition), int ++ Deallocate a condition, called by objc_condition_deallocate. ++ Return -1 if error otherwise return 0. ++ ++ __objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int ++ Wait on the condition, called by objc_condition_wait. ++ Return -1 if error otherwise return 0 when condition is met. ++ ++ __objc_condition_broadcast(objc_condition_t condition), int ++ Wake up all threads waiting on this condition. ++ Called by objc_condition_broadcast. ++ Return -1 if error otherwise return 0. ++ ++ __objc_condition_signal(objc_condition_t condition), int ++ Wake up one thread waiting on this condition. ++ Called by objc_condition_signal. ++ Return -1 if error otherwise return 0. +\ No newline at end of file +diff -rcP gcc-2.7.2.1/objc/THREADS.MACH gcc-2.7.2.1-objc-960906/objc/THREADS.MACH +*** gcc-2.7.2.1/objc/THREADS.MACH Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/THREADS.MACH Fri Sep 6 10:33:28 1996 +*************** +*** 0 **** +--- 1,23 ---- ++ This readme refers to the file thr-mach.c. ++ ++ Under mach, thread priorities are kinda strange-- any given thread has ++ a MAXIMUM priority and a BASE priority. The BASE priority is the ++ current priority of the thread and the MAXIMUM is the maximum possible ++ priority the thread can assume. The developer can lower, but never ++ raise the maximum priority. ++ ++ The gcc concept of thread priorities is that they run at one of three ++ levels; interactive, background, and low. ++ ++ Under mach, this is translated to: ++ ++ interactive -- set priority to maximum ++ background -- set priority to 2/3 of maximum ++ low -- set priority to 1/3 of maximum ++ ++ This means that it is possible for a thread with the priority of ++ interactive to actually run at a lower priority than another thread ++ with a background, or even low, priority if the developer has modified ++ the maximum priority. ++ ++ +diff -rcP gcc-2.7.2.1/objc/archive.c gcc-2.7.2.1-objc-960906/objc/archive.c +*** gcc-2.7.2.1/objc/archive.c Fri Sep 6 11:28:56 1996 +--- gcc-2.7.2.1-objc-960906/objc/archive.c Fri Sep 6 10:33:28 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime archiving +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime archiving +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 37,47 **** + #define PTR2LONG(P) (((char*)(P))-(char*)0) + #define LONG2PTR(L) (((char*)0)+(L)) + +- #define __objc_fatal(format, args...) \ +- { fprintf(stderr, "archiving: "); \ +- fprintf(stderr, format, ## args); \ +- fprintf(stderr, "\n"); abort(); } +- + /* Declare some functions... */ + + static int +--- 37,42 ---- +*************** +*** 141,147 **** + } + + int +! objc_write_unsigned_short (struct objc_typed_stream* stream, unsigned short value) + { + unsigned char buf[sizeof (unsigned short)+1]; + int len = __objc_code_unsigned_short (buf, value); +--- 136,143 ---- + } + + int +! objc_write_unsigned_short (struct objc_typed_stream* stream, +! unsigned short value) + { + unsigned char buf[sizeof (unsigned short)+1]; + int len = __objc_code_unsigned_short (buf, value); +*************** +*** 252,258 **** + } + + int +! objc_write_unsigned_long (struct objc_typed_stream* stream, unsigned long value) + { + unsigned char buf[sizeof(unsigned long)+1]; + int len = __objc_code_unsigned_long (buf, value); +--- 248,255 ---- + } + + int +! objc_write_unsigned_long (struct objc_typed_stream* stream, +! unsigned long value) + { + unsigned char buf[sizeof(unsigned long)+1]; + int len = __objc_code_unsigned_long (buf, value); +*************** +*** 315,321 **** + } + + static int +! objc_write_register_common (struct objc_typed_stream* stream, unsigned long key) + { + unsigned char buf[sizeof (unsigned long)+2]; + int len = __objc_code_unsigned_long (buf+1, key); +--- 312,319 ---- + } + + static int +! objc_write_register_common (struct objc_typed_stream* stream, +! unsigned long key) + { + unsigned char buf[sizeof (unsigned long)+2]; + int len = __objc_code_unsigned_long (buf+1, key); +*************** +*** 359,365 **** + return (*stream->write)(stream->physical, &buf, 1); + } + else +! abort(); + } + + __inline__ int +--- 357,364 ---- + return (*stream->write)(stream->physical, &buf, 1); + } + else +! objc_error(nil, OBJC_ERR_BAD_OPCODE, +! "__objc_write_extension: bad opcode %c\n", code); + } + + __inline__ int +*************** +*** 394,400 **** + { + int len; + if (stream->writing_root_p) +! __objc_fatal ("objc_write_root_object called recursively") + else + { + stream->writing_root_p = 1; +--- 393,400 ---- + { + int len; + if (stream->writing_root_p) +! objc_error (nil, OBJC_ERR_RECURSE_ROOT, +! "objc_write_root_object called recursively"); + else + { + stream->writing_root_p = 1; +*************** +*** 488,494 **** + else + { + int length; +! hash_add (&stream->stream_table, LONG2PTR(key=PTR2LONG(sel_name)), (char*)sel_name); + if ((length = objc_write_register_common (stream, key))) + return __objc_write_selector (stream, selector); + return length; +--- 488,495 ---- + else + { + int length; +! hash_add (&stream->stream_table, +! LONG2PTR(key=PTR2LONG(sel_name)), (char*)sel_name); + if ((length = objc_write_register_common (stream, key))) + return __objc_write_selector (stream, selector); + return length; +*************** +*** 520,527 **** + } + + else +! __objc_fatal("expected 8bit signed int, got %dbit int", +! (int)(buf&_B_NUMBER)*8); + } + return len; + } +--- 521,529 ---- + } + + else +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected 8bit signed int, got %dbit int", +! (int)(buf&_B_NUMBER)*8); + } + return len; + } +*************** +*** 541,548 **** + len = (*stream->read)(stream->physical, val, 1); + + else +! __objc_fatal("expected 8bit unsigned int, got %dbit int", +! (int)(buf&_B_NUMBER)*8); + } + return len; + } +--- 543,551 ---- + len = (*stream->read)(stream->physical, val, 1); + + else +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected 8bit unsigned int, got %dbit int", +! (int)(buf&_B_NUMBER)*8); + } + return len; + } +*************** +*** 562,568 **** + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (short)) +! __objc_fatal("expected short, got bigger (%dbits)", nbytes*8); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +--- 565,572 ---- + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (short)) +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected short, got bigger (%dbits)", nbytes*8); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +*************** +*** 590,596 **** + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (short)) +! __objc_fatal("expected short, got int or bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +--- 594,601 ---- + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (short)) +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected short, got int or bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +*************** +*** 616,622 **** + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (int)) +! __objc_fatal("expected int, got bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +--- 621,627 ---- + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (int)) +! objc_error(nil, OBJC_ERR_BAD_DATA, "expected int, got bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +*************** +*** 643,649 **** + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (long)) +! __objc_fatal("expected long, got bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +--- 648,654 ---- + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (long)) +! objc_error(nil, OBJC_ERR_BAD_DATA, "expected long, got bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) +*************** +*** 663,669 **** + unsigned char buf[sizeof(unsigned int)+1]; + + if (nbytes > sizeof (int)) +! __objc_fatal("expected int, got bigger"); + + len = (*stream->read)(stream->physical, buf, nbytes); + (*val) = 0; +--- 668,674 ---- + unsigned char buf[sizeof(unsigned int)+1]; + + if (nbytes > sizeof (int)) +! objc_error(nil, OBJC_ERR_BAD_DATA, "expected int, got bigger"); + + len = (*stream->read)(stream->physical, buf, nbytes); + (*val) = 0; +*************** +*** 699,705 **** + unsigned char buf[sizeof(unsigned long)+1]; + + if (nbytes > sizeof (long)) +! __objc_fatal("expected long, got bigger"); + + len = (*stream->read)(stream->physical, buf, nbytes); + (*val) = 0; +--- 704,710 ---- + unsigned char buf[sizeof(unsigned long)+1]; + + if (nbytes > sizeof (long)) +! objc_error(nil, OBJC_ERR_BAD_DATA, "expected long, got bigger"); + + len = (*stream->read)(stream->physical, buf, nbytes); + (*val) = 0; +*************** +*** 747,753 **** + case _B_SSTR: + { + int length = buf[0]&_B_VALUE; +! (*string) = (char*)__objc_xmalloc(length+1); + if (key) + hash_add (&stream->stream_table, LONG2PTR(key), *string); + len = (*stream->read)(stream->physical, *string, length); +--- 752,758 ---- + case _B_SSTR: + { + int length = buf[0]&_B_VALUE; +! (*string) = (char*)objc_malloc(length+1); + if (key) + hash_add (&stream->stream_table, LONG2PTR(key), *string); + len = (*stream->read)(stream->physical, *string, length); +*************** +*** 760,766 **** + char *tmp; + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + tmp = hash_value_for_key (stream->stream_table, LONG2PTR (key)); +! *string = __objc_xmalloc (strlen(tmp) + 1); + strcpy (*string, tmp); + } + break; +--- 765,771 ---- + char *tmp; + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + tmp = hash_value_for_key (stream->stream_table, LONG2PTR (key)); +! *string = objc_malloc (strlen(tmp) + 1); + strcpy (*string, tmp); + } + break; +*************** +*** 770,776 **** + unsigned int nbytes = buf[0]&_B_VALUE; + len = __objc_read_nbyte_uint(stream, nbytes, &nbytes); + if (len) { +! (*string) = (char*)__objc_xmalloc(nbytes+1); + if (key) + hash_add (&stream->stream_table, LONG2PTR(key), *string); + len = (*stream->read)(stream->physical, *string, nbytes); +--- 775,781 ---- + unsigned int nbytes = buf[0]&_B_VALUE; + len = __objc_read_nbyte_uint(stream, nbytes, &nbytes); + if (len) { +! (*string) = (char*)objc_malloc(nbytes+1); + if (key) + hash_add (&stream->stream_table, LONG2PTR(key), *string); + len = (*stream->read)(stream->physical, *string, nbytes); +*************** +*** 780,786 **** + break; + + default: +! __objc_fatal("expected string, got opcode %c\n", (buf[0]&_B_CODE)); + } + } + +--- 785,792 ---- + break; + + default: +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected string, got opcode %c\n", (buf[0]&_B_CODE)); + } + } + +*************** +*** 825,837 **** + /* check null-byte */ + len = (*stream->read)(stream->physical, buf, 1); + if (buf[0] != '\0') +! __objc_fatal("expected null-byte, got opcode %c", buf[0]); + } + + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! __objc_fatal("cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + (*object) = hash_value_for_key (stream->object_table, LONG2PTR(key)); + } +--- 831,844 ---- + /* check null-byte */ + len = (*stream->read)(stream->physical, buf, 1); + if (buf[0] != '\0') +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected null-byte, got opcode %c", buf[0]); + } + + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + (*object) = hash_value_for_key (stream->object_table, LONG2PTR(key)); + } +*************** +*** 840,859 **** + { + struct objc_list* other; + len = objc_read_unsigned_long (stream, &key); +! other = (struct objc_list*)hash_value_for_key (stream->object_refs, LONG2PTR(key)); +! hash_add (&stream->object_refs, LONG2PTR(key), (void*)list_cons(object, other)); + } + + else if (buf[0] == (_B_EXT | _BX_OBJROOT)) /* a root object */ + { + if (key) +! __objc_fatal("cannot register root object..."); + len = objc_read_object (stream, object); + __objc_finish_read_root_object (stream); + } + + else +! __objc_fatal("expected object, got opcode %c", buf[0]); + } + return len; + } +--- 847,870 ---- + { + struct objc_list* other; + len = objc_read_unsigned_long (stream, &key); +! other = (struct objc_list*)hash_value_for_key (stream->object_refs, +! LONG2PTR(key)); +! hash_add (&stream->object_refs, LONG2PTR(key), +! (void*)list_cons(object, other)); + } + + else if (buf[0] == (_B_EXT | _BX_OBJROOT)) /* a root object */ + { + if (key) +! objc_error(nil, OBJC_ERR_BAD_KEY, +! "cannot register root object..."); + len = objc_read_object (stream, object); + __objc_finish_read_root_object (stream); + } + + else +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected object, got opcode %c", buf[0]); + } + return len; + } +*************** +*** 881,887 **** + /* get class */ + len = objc_read_string (stream, &class_name); + (*class) = objc_get_class(class_name); +! free (class_name); + + /* register */ + if (key) +--- 892,898 ---- + /* get class */ + len = objc_read_string (stream, &class_name); + (*class) = objc_get_class(class_name); +! objc_free(class_name); + + /* register */ + if (key) +*************** +*** 894,908 **** + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! __objc_fatal("cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + (*class) = hash_value_for_key (stream->stream_table, LONG2PTR(key)); + if (!*class) +! __objc_fatal("cannot find class for key %lu", key); + } + + else +! __objc_fatal("expected class, got opcode %c", buf[0]); + } + return len; + } +--- 905,921 ---- + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + (*class) = hash_value_for_key (stream->stream_table, LONG2PTR(key)); + if (!*class) +! objc_error(nil, OBJC_ERR_BAD_CLASS, +! "cannot find class for key %lu", key); + } + + else +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected class, got opcode %c", buf[0]); + } + return len; + } +*************** +*** 936,942 **** + } + else + (*selector) = sel_get_any_uid(selector_name); +! free (selector_name); + + /* register */ + if (key) +--- 949,955 ---- + } + else + (*selector) = sel_get_any_uid(selector_name); +! objc_free(selector_name); + + /* register */ + if (key) +*************** +*** 946,958 **** + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! __objc_fatal("cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); +! (*selector) = hash_value_for_key (stream->stream_table, LONG2PTR(key)); + } + + else +! __objc_fatal("expected selector, got opcode %c", buf[0]); + } + return len; + } +--- 959,973 ---- + else if ((buf[0]&_B_CODE) == _B_UCOMM) + { + if (key) +! objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); +! (*selector) = hash_value_for_key (stream->stream_table, +! LONG2PTR(key)); + } + + else +! objc_error(nil, OBJC_ERR_BAD_DATA, +! "expected selector, got opcode %c", buf[0]); + } + return len; + } +*************** +*** 1019,1031 **** + break; + + case _C_ATOM: +! return objc_write_string_atomic (stream, *(char**)data, strlen(*(char**)data)); + break; + + case _C_ARY_B: + { + int len = atoi(type+1); +! while (isdigit(*++type)); + return objc_write_array (stream, type, len, data); + } + break; +--- 1034,1048 ---- + break; + + case _C_ATOM: +! return objc_write_string_atomic (stream, *(char**)data, +! strlen(*(char**)data)); + break; + + case _C_ARY_B: + { + int len = atoi(type+1); +! while (isdigit(*++type)) +! ; + return objc_write_array (stream, type, len, data); + } + break; +*************** +*** 1034,1041 **** + { + int acc_size = 0; + int align; +! while (*type != _C_STRUCT_E && *type++ != '='); /* skip "=" */ +! while (*type != _C_STRUCT_E); + { + align = objc_alignof_type (type); /* padd to alignment */ + acc_size += ROUND (acc_size, align); +--- 1051,1059 ---- + { + int acc_size = 0; + int align; +! while (*type != _C_STRUCT_E && *type++ != '=') +! ; /* skip "=" */ +! while (*type != _C_STRUCT_E) + { + align = objc_alignof_type (type); /* padd to alignment */ + acc_size += ROUND (acc_size, align); +*************** +*** 1047,1054 **** + } + + default: +! fprintf(stderr, "objc_write_type: cannot parse typespec: %s\n", type); +! abort(); + } + } + +--- 1065,1072 ---- + } + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, +! "objc_write_type: cannot parse typespec: %s\n", type); + } + } + +*************** +*** 1116,1122 **** + case _C_ARY_B: + { + int len = atoi(type+1); +! while (isdigit(*++type)); + return objc_read_array (stream, type, len, data); + } + break; +--- 1134,1141 ---- + case _C_ARY_B: + { + int len = atoi(type+1); +! while (isdigit(*++type)) +! ; + return objc_read_array (stream, type, len, data); + } + break; +*************** +*** 1125,1132 **** + { + int acc_size = 0; + int align; +! while (*type != _C_STRUCT_E && *type++ != '='); /* skip "=" */ +! while (*type != _C_STRUCT_E); + { + align = objc_alignof_type (type); /* padd to alignment */ + acc_size += ROUND (acc_size, align); +--- 1144,1152 ---- + { + int acc_size = 0; + int align; +! while (*type != _C_STRUCT_E && *type++ != '=') +! ; /* skip "=" */ +! while (*type != _C_STRUCT_E) + { + align = objc_alignof_type (type); /* padd to alignment */ + acc_size += ROUND (acc_size, align); +*************** +*** 1138,1145 **** + } + + default: +! fprintf(stderr, "objc_read_type: cannot parse typespec: %s\n", type); +! abort(); + } + } + +--- 1158,1165 ---- + } + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, +! "objc_read_type: cannot parse typespec: %s\n", type); + } + } + +*************** +*** 1229,1245 **** + { + int len = atoi(c+1); + const char* t = c; +! while (isdigit(*++t)); + res = objc_write_array (stream, t, len, va_arg(args, void*)); + t = objc_skip_typespec (t); + if (*t != _C_ARY_E) +! __objc_fatal("expected `]', got: %s", t); + } + break; + + default: +! fprintf(stderr, "objc_write_types: cannot parse typespec: %s\n", type); +! abort(); + } + } + va_end(args); +--- 1249,1266 ---- + { + int len = atoi(c+1); + const char* t = c; +! while (isdigit(*++t)) +! ; + res = objc_write_array (stream, t, len, va_arg(args, void*)); + t = objc_skip_typespec (t); + if (*t != _C_ARY_E) +! objc_error(nil, OBJC_ERR_BAD_TYPE, "expected `]', got: %s", t); + } + break; + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, +! "objc_write_types: cannot parse typespec: %s\n", type); + } + } + va_end(args); +*************** +*** 1320,1336 **** + { + int len = atoi(c+1); + const char* t = c; +! while (isdigit(*++t)); + res = objc_read_array (stream, t, len, va_arg(args, void*)); + t = objc_skip_typespec (t); + if (*t != _C_ARY_E) +! __objc_fatal("expected `]', got: %s", t); + } + break; + + default: +! fprintf(stderr, "objc_read_types: cannot parse typespec: %s\n", type); +! abort(); + } + } + va_end(args); +--- 1341,1358 ---- + { + int len = atoi(c+1); + const char* t = c; +! while (isdigit(*++t)) +! ; + res = objc_read_array (stream, t, len, va_arg(args, void*)); + t = objc_skip_typespec (t); + if (*t != _C_ARY_E) +! objc_error(nil, OBJC_ERR_BAD_TYPE, "expected `]', got: %s", t); + } + break; + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, +! "objc_read_types: cannot parse typespec: %s\n", type); + } + } + va_end(args); +*************** +*** 1379,1390 **** + return 1; + } + +- static void +- __objc_free (void* p) +- { +- free (p); +- } +- + static int + __objc_fread(FILE* file, char* data, int len) + { +--- 1401,1406 ---- +*************** +*** 1406,1418 **** + static int + __objc_no_write(FILE* file, char* data, int len) + { +! __objc_fatal ("TypedStream not open for writing"); + } + + static int + __objc_no_read(FILE* file, char* data, int len) + { +! __objc_fatal ("TypedStream not open for reading"); + } + + static int +--- 1422,1434 ---- + static int + __objc_no_write(FILE* file, char* data, int len) + { +! objc_error (nil, OBJC_ERR_NO_WRITE, "TypedStream not open for writing"); + } + + static int + __objc_no_read(FILE* file, char* data, int len) + { +! objc_error (nil, OBJC_ERR_NO_READ, "TypedStream not open for reading"); + } + + static int +*************** +*** 1422,1431 **** + int pos = 0; + do + (*stream->read)(stream->physical, buffer+pos, 1); +! while (buffer[pos++] != '\0'); + sscanf (buffer, "GNU TypedStream %d", &stream->version); + if (stream->version != OBJC_TYPED_STREAM_VERSION) +! __objc_fatal ("cannot handle TypedStream version %d", stream->version); + return 1; + } + +--- 1438,1449 ---- + int pos = 0; + do + (*stream->read)(stream->physical, buffer+pos, 1); +! while (buffer[pos++] != '\0') +! ; + sscanf (buffer, "GNU TypedStream %d", &stream->version); + if (stream->version != OBJC_TYPED_STREAM_VERSION) +! objc_error (nil, OBJC_ERR_STREAM_VERSION, +! "cannot handle TypedStream version %d", stream->version); + return 1; + } + +*************** +*** 1450,1460 **** + static void __objc_finish_read_root_object(struct objc_typed_stream* stream) + { + node_ptr node; +- struct objc_list* free_list; + SEL awake_sel = sel_get_any_uid ("awake"); + + /* resolve object forward references */ +- free_list = list_cons(NULL, NULL); + for (node = hash_next (stream->object_refs, NULL); node; + node = hash_next (stream->object_refs, node)) + { +--- 1468,1479 ---- + static void __objc_finish_read_root_object(struct objc_typed_stream* stream) + { + node_ptr node; + SEL awake_sel = sel_get_any_uid ("awake"); ++ cache_ptr free_list = hash_new (64, ++ (hash_func_type) hash_ptr, ++ (compare_func_type) compare_ptrs); + + /* resolve object forward references */ + for (node = hash_next (stream->object_refs, NULL); node; + node = hash_next (stream->object_refs, node)) + { +*************** +*** 1464,1476 **** + while(reflist) + { + *((id*)reflist->head) = object; +! if (list_find(&free_list, reflist) == NULL) +! free_list = list_cons (reflist, free_list); + reflist = reflist->tail; + } + } +! list_mapcar (free_list, __objc_free); +! list_free (free_list); + + /* empty object reference table */ + hash_delete (stream->object_refs); +--- 1483,1501 ---- + while(reflist) + { + *((id*)reflist->head) = object; +! if (hash_value_for_key (free_list,reflist) == NULL) +! hash_add (&free_list,reflist,reflist); +! + reflist = reflist->tail; + } + } +! +! /* apply __objc_free to all objects stored in free_list */ +! for (node = hash_next (free_list, NULL); node; +! node = hash_next (free_list, node)) +! objc_free ((void *) node->key); +! +! hash_delete (free_list); + + /* empty object reference table */ + hash_delete (stream->object_refs); +*************** +*** 1503,1509 **** + TypedStream* + objc_open_typed_stream (FILE* physical, int mode) + { +! TypedStream* s = (TypedStream*)__objc_xmalloc(sizeof(TypedStream)); + + s->mode = mode; + s->physical = physical; +--- 1528,1534 ---- + TypedStream* + objc_open_typed_stream (FILE* physical, int mode) + { +! TypedStream* s = (TypedStream*)objc_malloc(sizeof(TypedStream)); + + s->mode = mode; + s->physical = physical; +*************** +*** 1590,1596 **** + if (stream->type == (OBJC_MANAGED_STREAM | OBJC_FILE_STREAM)) + fclose ((FILE*)stream->physical); + +! free (stream); + } + + BOOL +--- 1615,1621 ---- + if (stream->type == (OBJC_MANAGED_STREAM | OBJC_FILE_STREAM)) + fclose ((FILE*)stream->physical); + +! objc_free(stream); + } + + BOOL +diff -rcP gcc-2.7.2.1/objc/class.c gcc-2.7.2.1-objc-960906/objc/class.c +*** gcc-2.7.2.1/objc/class.c Fri Sep 6 11:28:56 1996 +--- gcc-2.7.2.1-objc-960906/objc/class.c Fri Sep 6 10:33:29 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime class related functions +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup and Dennis Glatting. + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime class related functions +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup and Dennis Glatting. + + This file is part of GNU CC. +*************** +*** 27,42 **** + #include "sarray.h" + + /* The table of classname->class. Used for objc_lookup_class and friends */ +! static cache_ptr __objc_class_hash = 0; + + /* 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; + + + /* True when class links has been resolved */ +! BOOL __objc_class_links_resolved = NO; + + + /* Initial number of buckets size of class hash table. */ +--- 27,42 ---- + #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. */ +*************** +*** 49,58 **** +--- 49,62 ---- + 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 +*************** +*** 62,67 **** +--- 66,73 ---- + { + Class h_class; + ++ objc_mutex_lock(__objc_runtime_mutex); ++ + /* make sure the table is there */ + assert(__objc_class_hash); + +*************** +*** 82,87 **** +--- 88,95 ---- + ++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 +*************** +*** 91,101 **** +--- 99,113 ---- + { + 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; + +*************** +*** 113,123 **** +--- 125,139 ---- + { + 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; + +*************** +*** 127,134 **** + if(class) + return class; + +! fprintf(stderr, "objc runtime: cannot find class %s\n", name); +! abort(); + } + + MetaClass +--- 143,150 ---- + if(class) + return class; + +! objc_error(nil, OBJC_ERR_BAD_CLASS, +! "objc runtime: cannot find class %s\n", name); + } + + MetaClass +*************** +*** 149,159 **** +--- 165,180 ---- + 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; +*************** +*** 169,174 **** +--- 190,197 ---- + + 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)) +*************** +*** 234,239 **** +--- 257,264 ---- + sub_class->class_pointer->super_class = class1->class_pointer; + } + } ++ ++ objc_mutex_unlock(__objc_runtime_mutex); + } + + +*************** +*** 281,287 **** + 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); + } +--- 306,313 ---- + 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); + } +*************** +*** 307,312 **** +--- 333,340 ---- + 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)) + { +*************** +*** 316,321 **** +--- 344,351 ---- + 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)); +diff -rcP gcc-2.7.2.1/objc/encoding.c gcc-2.7.2.1-objc-960906/objc/encoding.c +*** gcc-2.7.2.1/objc/encoding.c Fri Sep 6 11:28:57 1996 +--- gcc-2.7.2.1-objc-960906/objc/encoding.c Fri Sep 6 10:33:29 1996 +*************** +*** 1,5 **** + /* Encoding of types for Objective C. +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* Encoding of types for Objective C. +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 25,32 **** +--- 25,37 ---- + 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 "encoding.h" + ++ #ifndef OBJC_FORWARDING_STACK_OFFSET ++ # define OBJC_FORWARDING_STACK_OFFSET 0 ++ #endif ++ + #define MAX(X, Y) \ + ({ typeof(X) __x = (X), __y = (Y); \ + (__x > __y ? __x : __y); }) +*************** +*** 153,159 **** + } + + default: +! abort(); + } + } + +--- 158,164 ---- + } + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type); + } + } + +*************** +*** 218,223 **** +--- 223,229 ---- + return __alignof__(double); + break; + ++ case _C_PTR: + case _C_ATOM: + case _C_CHARPTR: + return __alignof__(char*); +*************** +*** 250,256 **** + } + + default: +! abort(); + } + } + +--- 256,262 ---- + } + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type); + } + } + +*************** +*** 341,346 **** +--- 347,353 ---- + case _C_FLT: + case _C_DBL: + case _C_VOID: ++ case _C_UNDEF: + return ++type; + break; + +*************** +*** 352,358 **** + if (*type == _C_ARY_E) + return ++type; + else +! abort(); + + case _C_STRUCT_B: + /* skip name, and elements until closing '}' */ +--- 359,365 ---- + if (*type == _C_ARY_E) + return ++type; + else +! objc_error(nil, OBJC_ERR_BAD_TYPE, "bad array type %s\n", type); + + case _C_STRUCT_B: + /* skip name, and elements until closing '}' */ +*************** +*** 374,380 **** + return objc_skip_typespec (++type); + + default: +! abort(); + } + } + +--- 381,387 ---- + return objc_skip_typespec (++type); + + default: +! objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type); + } + } + +*************** +*** 467,475 **** + t = objc_skip_typespec (t); + + if (*t == '+') +! return argframe->arg_regs + atoi (++t); + else +! return argframe->arg_ptr + atoi (t); + } + + /* +--- 474,482 ---- + t = objc_skip_typespec (t); + + if (*t == '+') +! return argframe->arg_regs + atoi (++t) - OBJC_FORWARDING_STACK_OFFSET; + else +! return argframe->arg_ptr + atoi (t) - OBJC_FORWARDING_STACK_OFFSET; + } + + /* +*************** +*** 510,518 **** + t = objc_skip_typespec (t); + + if (*t == '+') +! return argframe->arg_regs + atoi (++t); + else +! return argframe->arg_ptr + atoi (t); + } + + unsigned +--- 517,525 ---- + t = objc_skip_typespec (t); + + if (*t == '+') +! return argframe->arg_regs + atoi (++t) - OBJC_FORWARDING_STACK_OFFSET; + else +! return argframe->arg_ptr + atoi (t) - OBJC_FORWARDING_STACK_OFFSET; + } + + unsigned +diff -rcP gcc-2.7.2.1/objc/encoding.h gcc-2.7.2.1-objc-960906/objc/encoding.h +*** gcc-2.7.2.1/objc/encoding.h Fri Sep 6 11:28:57 1996 +--- gcc-2.7.2.1-objc-960906/objc/encoding.h Fri Sep 6 10:33:29 1996 +*************** +*** 57,63 **** + 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_size_of_arguments (struct objc_method*); + + char* method_get_first_argument (struct objc_method*, + arglist_t argframe, +--- 57,63 ---- + 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, +diff -rcP gcc-2.7.2.1/objc/hash.c gcc-2.7.2.1-objc-960906/objc/hash.c +*** gcc-2.7.2.1/objc/hash.c Fri Sep 6 11:28:57 1996 +--- gcc-2.7.2.1-objc-960906/objc/hash.c Fri Sep 6 10:33:30 1996 +*************** +*** 1,5 **** + /* Hash tables for Objective C internal structures +! Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU CC. + +--- 1,5 ---- + /* Hash tables for Objective C internal structures +! Copyright (C) 1993, 1996 Free Software Foundation, Inc. + + This file is part of GNU CC. + +*************** +*** 27,33 **** + #include "assert.h" + + #include "objc/hash.h" +- #include "objc/objc.h" + + #include "runtime.h" /* for DEBUG_PRINTF */ + +--- 27,32 ---- +*************** +*** 40,47 **** + #define EXPANSION(cache) \ + ((cache)->size * 2) + +- void *__objc_xcalloc (size_t, size_t); +- + cache_ptr + hash_new (unsigned int size, hash_func_type hash_func, + compare_func_type compare_func) +--- 39,44 ---- +*************** +*** 54,66 **** + + /* Allocate the cache structure. calloc insures + its initialization for default values. */ +! cache = (cache_ptr) __objc_xcalloc (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_xcalloc (size, sizeof (node_ptr)); + assert (cache->node_table); + + cache->size = size; +--- 51,63 ---- + + /* 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; +*************** +*** 83,97 **** + hash_delete (cache_ptr cache) + { + node_ptr node; +! + + /* Purge all key/value pairs from the table. */ +! while ((node = hash_next (cache, NULL))) +! hash_remove (cache, node->key); + + /* Release the array of nodes and the cache itself. */ +! free (cache->node_table); +! free (cache); + } + + +--- 80,107 ---- + 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); + } + + +*************** +*** 99,105 **** + hash_add (cache_ptr *cachep, const void *key, void *value) + { + size_t indx = (*(*cachep)->hash_func)(*cachep, key); +! node_ptr node = (node_ptr) __objc_xcalloc (1, sizeof (struct cache_node)); + + + assert (node); +--- 109,115 ---- + 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); +*************** +*** 172,178 **** + /* 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; +! free (node); + } else { + + /* Otherwise, find the hash entry. */ +--- 182,188 ---- + /* 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. */ +*************** +*** 183,189 **** + + if ((*cache->compare_func)(node->key, key)) { + prev->next = node->next, removed = YES; +! free (node); + } else + prev = node, node = node->next; + } while (!removed && node); +--- 193,199 ---- + + 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); +*************** +*** 251,254 **** +--- 261,283 ---- + } 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; + } +diff -rcP gcc-2.7.2.1/objc/hash.h gcc-2.7.2.1-objc-960906/objc/hash.h +*** gcc-2.7.2.1/objc/hash.h Fri Sep 6 11:28:58 1996 +--- gcc-2.7.2.1-objc-960906/objc/hash.h Fri Sep 6 10:33:30 1996 +*************** +*** 1,5 **** + /* Hash tables for Objective C method dispatch. +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + + This file is part of GNU CC. + +--- 1,5 ---- + /* Hash tables for Objective C method dispatch. +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + + This file is part of GNU CC. + +*************** +*** 29,34 **** +--- 29,35 ---- + #define __hash_INCLUDE_GNU + + #include ++ #include + + /* + * This data structure is used to hold items +*************** +*** 140,145 **** +--- 141,149 ---- + + 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); + + /************************************************ + +diff -rcP gcc-2.7.2.1/objc/init.c gcc-2.7.2.1-objc-960906/objc/init.c +*** gcc-2.7.2.1/objc/init.c Fri Sep 6 11:28:58 1996 +--- gcc-2.7.2.1-objc-960906/objc/init.c Fri Sep 6 10:33:30 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime initialization +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime initialization +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 31,43 **** + #define PROTOCOL_VERSION 2 + + /* This list contains all modules currently loaded into the runtime */ +! static struct objc_list* __objc_module_list = 0; + + /* This list contains all proto_list's not yet assigned class links */ +! static struct objc_list* unclaimed_proto_list = 0; + + /* List of unresolved static instances. */ +! static struct objc_list *uninitialized_statics; + + /* Check compiler vs runtime version */ + static void init_check_module_version (Module_t); +--- 31,49 ---- + #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; +! +! /* 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); +*************** +*** 52,65 **** + 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) = 0; + + /* Is all categories/classes resolved? */ +! BOOL __objc_dangling_categories = NO; + + extern SEL + __sel_register_typed_name (const char *name, const char *types, +! struct objc_selector *orig); + + /* Run through the statics list, removing modules as soon as all its statics + have been initialized. */ +--- 58,71 ---- + 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) = 0; /* !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); + + /* Run through the statics list, removing modules as soon as all its statics + have been initialized. */ +*************** +*** 69,74 **** +--- 75,82 ---- + 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; +*************** +*** 109,119 **** + /* Remove this module from the uninitialized list. */ + struct objc_list *this = *cell; + *cell = this->tail; +! free (this); + } + else + cell = &(*cell)->tail; + } + } /* objc_init_statics */ + + /* This function is called by constructor functions generated for each +--- 117,129 ---- + /* 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 +*************** +*** 150,155 **** +--- 160,170 ---- + /* 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(); +*************** +*** 157,162 **** +--- 172,178 ---- + } + + /* 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. */ +*************** +*** 167,174 **** + const char *name, *type; + name = (char*)selectors[i].sel_id; + type = (char*)selectors[i].sel_types; + __sel_register_typed_name (name, type, +! (struct objc_selector*)&(selectors[i])); + } + } + +--- 183,193 ---- + 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); + } + } + +*************** +*** 183,188 **** +--- 202,211 ---- + 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); + +*************** +*** 190,195 **** +--- 213,222 ---- + __objc_register_selectors_from_class (class); + __objc_register_selectors_from_class ((Class) class->class_pointer); + ++ /* Register the instance methods as class methods, this is ++ only done for root classes. */ ++ __objc_register_instance_methods_to_class(class); ++ + /* Install the fake dispatch tables */ + __objc_install_premature_dtable(class); + __objc_install_premature_dtable(class->class_pointer); +*************** +*** 230,235 **** +--- 257,266 ---- + __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 (_objc_load_callback) + _objc_load_callback(class, category); + } +*************** +*** 275,280 **** +--- 306,315 ---- + __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 (_objc_load_callback) + _objc_load_callback(class, category); + } +*************** +*** 287,292 **** +--- 322,328 ---- + unclaimed_proto_list = 0; + } + ++ objc_mutex_unlock(__objc_runtime_mutex); + } + + /* Sanity check the version of gcc used to compile `module'*/ +*************** +*** 294,308 **** + { + if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module))) + { +! fprintf (stderr, "Module %s version %d doesn't match runtime %d\n", +! module->name, (int)module->version, OBJC_VERSION); + if(module->version > OBJC_VERSION) +! fprintf (stderr, "Runtime (libobjc.a) is out of date\n"); + else if (module->version < OBJC_VERSION) +! fprintf (stderr, "Compiler (gcc) is out of date\n"); + else +! fprintf (stderr, "Objective C internal error -- bad Module size\n"); +! abort (); + } + } + +--- 330,346 ---- + { + 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); + } + } + +*************** +*** 315,326 **** +--- 353,367 ---- + 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; + } + +*************** +*** 341,353 **** + } + else if (protos->list[i]->class_pointer != proto_class) + { +! fprintf (stderr, +! "Version %d doesn't match runtime protocol version %d\n", +! (int)((char*)protos->list[i]->class_pointer-(char*)0), +! PROTOCOL_VERSION); +! abort (); + } + } + } + + static void __objc_class_add_protocols (Class class, +--- 382,395 ---- + } + 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, +diff -rcP gcc-2.7.2.1/objc/makefile.dos gcc-2.7.2.1-objc-960906/objc/makefile.dos +*** gcc-2.7.2.1/objc/makefile.dos Fri Sep 6 11:28:59 1996 +--- gcc-2.7.2.1-objc-960906/objc/makefile.dos Fri Sep 6 10:33:31 1996 +*************** +*** 1,5 **** + # GNU Objective C Runtime Makefile for compiling with djgpp +! # Copyright (C) 1993, 1994 Free Software Foundation, Inc. + # + # This file is part of GNU CC. + # +--- 1,5 ---- + # 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. + # +*************** +*** 37,53 **** + -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 + + libobjc.a: $(OBJC_O) + -rm -f libobjc.a + ar rc libobjc.a $(OBJC_O) + ranlib libobjc.a + +! OBJC_H = hash.h list.h sarray.h objc.h \ + objc-api.h \ + object.h protocol.h mutex.h \ +! typedstream.h + + mostlyclean: + -rm -f *.o libobjc.a xforward fflags +--- 37,53 ---- + -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 +diff -rcP gcc-2.7.2.1/objc/misc.c gcc-2.7.2.1-objc-960906/objc/misc.c +*** gcc-2.7.2.1/objc/misc.c Fri Sep 6 11:28:59 1996 +--- gcc-2.7.2.1-objc-960906/objc/misc.c Fri Sep 6 10:33:31 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime Miscellaneous +! Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. + + Author: Kresten Krab Thorup + +--- 1,5 ---- + /* GNU Objective C Runtime Miscellaneous +! Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. + + Author: Kresten Krab Thorup + +*************** +*** 26,80 **** + however invalidate any other reasons why the executable file might be + covered by the GNU General Public License. */ + +- #ifdef __alpha__ + #include +- extern int write (int, const char*, int); +- extern size_t strlen (const char*); +- #endif +- + #include "runtime.h" + +! void objc_error(id object, const char* fmt, va_list); + +! void (*_objc_error)(id, const char*, va_list) = objc_error; + + void +! objc_error(id object, const char* fmt, va_list ap) + { +! vfprintf (stderr, fmt, ap); +! abort (); + } + +! volatile void +! objc_fatal(const char* msg) + { +! write(2, msg, (int)strlen((const char*)msg)); +! abort(); + } + +! void* +! __objc_xmalloc(size_t size) + { +! void* res = (void*) malloc(size); + if(!res) +! objc_fatal("Virtual memory exhausted\n"); + return res; + } + +! void* +! __objc_xrealloc(void* mem, size_t size) + { +! void* res = (void*) realloc(mem, size); + if(!res) +! objc_fatal("Virtual memory exhausted\n"); + return res; + } + +! void* +! __objc_xcalloc(size_t nelem, size_t size) + { +! void* res = (void*)calloc(nelem, size); + if(!res) +! objc_fatal("Virtual memory exhausted\n"); + return res; + } +--- 26,152 ---- + however invalidate any other reasons why the executable file might be + covered by the GNU General Public License. */ + + #include + #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; +diff -rcP gcc-2.7.2.1/objc/nil_method.c gcc-2.7.2.1-objc-960906/objc/nil_method.c +*** gcc-2.7.2.1/objc/nil_method.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/nil_method.c Fri Sep 6 10:33:32 1996 +*************** +*** 0 **** +--- 1,40 ---- ++ /* GNU Objective C Runtime nil receiver function ++ 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. */ ++ ++ /* This is the nil method, the function that is called when the receiver ++ of a method is nil */ ++ ++ #include "runtime.h" ++ ++ id ++ nil_method(id receiver, SEL op, ...) ++ { ++ return receiver; ++ } ++ ++ ++ ++ +diff -rcP gcc-2.7.2.1/objc/objc-api.h gcc-2.7.2.1-objc-960906/objc/objc-api.h +*** gcc-2.7.2.1/objc/objc-api.h Fri Sep 6 11:28:59 1996 +--- gcc-2.7.2.1-objc-960906/objc/objc-api.h Fri Sep 6 10:33:32 1996 +*************** +*** 1,5 **** + /* GNU Objective-C Runtime API. +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + + This file is part of GNU CC. + +--- 1,5 ---- + /* GNU Objective-C Runtime API. +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + + This file is part of GNU CC. + +*************** +*** 29,35 **** +--- 29,37 ---- + + #include "objc/objc.h" + #include "objc/hash.h" ++ #include "objc/thr.h" + #include ++ #include + + /* For functions which return Method_t */ + #define METHOD_NULL (Method_t)0 +*************** +*** 73,78 **** +--- 75,131 ---- + #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 */ + + /* + ** Set this variable nonzero to print a line describing each +*************** +*** 135,141 **** + + 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; +--- 188,195 ---- + + 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; +*************** +*** 308,319 **** + */ + extern void (*_objc_load_callback)(Class class, Category* category); + + extern id (*_objc_object_alloc)(Class class); +- + extern id (*_objc_object_copy)(id object); +- + extern id (*_objc_object_dispose)(id object); + + Method_t class_get_class_method(MetaClass class, SEL aSel); + + Method_t class_get_instance_method(Class class, SEL aSel); +--- 362,415 ---- + */ + 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); +*************** +*** 405,410 **** +--- 501,512 ---- + + 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); +*************** +*** 470,475 **** +--- 572,580 ---- + { + return CLS_ISMETA((Class)object); + } ++ ++ struct sarray* ++ objc_get_uninstalled_dtable(); + + #endif /* not __objc_api_INCLUDE_GNU */ + +diff -rcP gcc-2.7.2.1/objc/objc-list.h gcc-2.7.2.1-objc-960906/objc/objc-list.h +*** gcc-2.7.2.1/objc/objc-list.h Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/objc-list.h Fri Sep 6 10:33:32 1996 +*************** +*** 0 **** +--- 1,148 ---- ++ /* Generic single linked list to keep various information ++ Copyright (C) 1993, 1994, 1996 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 ++ ++ 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_malloc(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 */ ++ objc_free(tail); /* free next */ ++ } ++ else /* only one element in list */ ++ { ++ objc_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); ++ objc_free(list); ++ } ++ } ++ #endif __GNU_OBJC_LIST_H +diff -rcP gcc-2.7.2.1/objc/objc.h gcc-2.7.2.1-objc-960906/objc/objc.h +*** gcc-2.7.2.1/objc/objc.h Fri Sep 6 11:29:00 1996 +--- gcc-2.7.2.1-objc-960906/objc/objc.h Fri Sep 6 10:33:33 1996 +*************** +*** 103,111 **** + 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 +--- 103,111 ---- + 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 +diff -rcP gcc-2.7.2.1/objc/objects.c gcc-2.7.2.1-objc-960906/objc/objects.c +*** gcc-2.7.2.1/objc/objects.c Fri Sep 6 11:29:00 1996 +--- gcc-2.7.2.1-objc-960906/objc/objects.c Fri Sep 6 10:33:33 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime class related functions +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* 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. +*************** +*** 31,39 **** + id __objc_object_dispose(id); + id __objc_object_copy(id); + +! id (*_objc_object_alloc)(Class) = __objc_object_alloc; +! id (*_objc_object_dispose)(id) = __objc_object_dispose; +! id (*_objc_object_copy)(id) = __objc_object_copy; + + id + class_create_instance(Class class) +--- 31,39 ---- + 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) +*************** +*** 66,84 **** + if (_objc_object_dispose) + (*_objc_object_dispose)(object); + else +! free(object); + } + return nil; + } + + id __objc_object_alloc(Class class) + { +! return (id)__objc_xmalloc(class->instance_size); + } + + id __objc_object_dispose(id object) + { +! free(object); + return 0; + } + +--- 66,84 ---- + 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; + } + +diff -rcP gcc-2.7.2.1/objc/runtime.h gcc-2.7.2.1-objc-960906/objc/runtime.h +*** gcc-2.7.2.1/objc/runtime.h Fri Sep 6 11:29:00 1996 +--- gcc-2.7.2.1-objc-960906/objc/runtime.h Fri Sep 6 10:33:33 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime internal declarations +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime internal declarations +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 37,44 **** + #include "objc/objc.h" /* core data types */ + #include "objc/objc-api.h" /* runtime api functions */ + + #include "objc/hash.h" /* hash structures */ +! #include "objc/list.h" /* linear lists */ + + extern void __objc_add_class_to_hash(Class); /* (objc-class.c) */ + extern void __objc_init_selector_tables(); /* (objc-sel.c) */ +--- 37,46 ---- + #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(); /* (objc-sel.c) */ +*************** +*** 48,57 **** + extern void __objc_resolve_class_links(); /* (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 void class_add_method_list(Class, MethodList_t); + +! extern void objc_error(id object, const char* fmt, va_list); +! extern void (*_objc_error)(id, const char*, va_list); + + /* True when class links has been resolved */ + extern BOOL __objc_class_links_resolved; +--- 50,64 ---- + extern void __objc_resolve_class_links(); /* (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 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; +*************** +*** 59,64 **** +--- 66,77 ---- + /* 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 +*************** +*** 67,73 **** + + BOOL __objc_responds_to (id object, SEL sel); /* for internal use only! */ + SEL __sel_register_typed_name (const char*, const char*, +! struct objc_selector*); + + #endif /* not __objc_runtime_INCLUDE_GNU */ + +--- 80,86 ---- + + 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 */ + +diff -rcP gcc-2.7.2.1/objc/sarray.c gcc-2.7.2.1-objc-960906/objc/sarray.c +*** gcc-2.7.2.1/objc/sarray.c Fri Sep 6 11:29:01 1996 +--- gcc-2.7.2.1-objc-960906/objc/sarray.c Fri Sep 6 10:33:34 1996 +*************** +*** 1,5 **** + /* Sparse Arrays for Objective C dispatch tables +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + + This file is part of GNU CC. + +--- 1,5 ---- + /* Sparse Arrays for Objective C dispatch tables +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + + This file is part of GNU CC. + +*************** +*** 25,37 **** + the executable file might be covered by the GNU General Public License. */ + + #include "objc/sarray.h" + #include + #include "assert.h" + +! int nbuckets = 0; +! int nindices = 0; +! int narrays = 0; +! int idxsize = 0; + + #ifdef OBJC_SPARSE2 + const char* __objc_sparse2_id = "2 level sparse indices"; +--- 25,40 ---- + the executable file might be covered by the GNU General Public License. */ + + #include "objc/sarray.h" ++ #include "objc/runtime.h" + #include + #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"; +*************** +*** 43,58 **** + + #ifdef __alpha__ + const void *memcpy (void*, const void*, size_t); +- void free (const void*); + #endif + + void + sarray_at_put(struct sarray* array, sidx index, void* element) + { + #ifdef OBJC_SPARSE3 + struct sindex** the_index; + #endif + struct sbucket** the_bucket; + #ifdef OBJC_SPARSE3 + size_t ioffset; + #endif +--- 46,107 ---- + + #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 +*************** +*** 96,117 **** + if ((*the_index) == array->empty_index) { + + /* The index was previously empty, allocate a new */ +! *the_index = (struct sindex*)__objc_xmalloc(sizeof(struct sindex)); +! memcpy(*the_index, array->empty_index, sizeof(struct sindex)); +! (*the_index)->version = array->version; + the_bucket = &((*the_index)->buckets[boffset]); +- nindices += 1; + +! } else if ((*the_index)->version != array->version) { + + /* This index must be lazy copied */ + struct sindex* old_index = *the_index; +! *the_index = (struct sindex*)__objc_xmalloc(sizeof(struct sindex)); +! memcpy( *the_index,old_index, sizeof(struct sindex)); +! (*the_index)->version = array->version; + the_bucket = &((*the_index)->buckets[boffset]); +- nindices += 1; + + } + + #endif /* OBJC_SPARSE3 */ +--- 145,168 ---- + 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 */ +*************** +*** 122,139 **** + + /* The bucket was previously empty (or something like that), */ + /* allocate a new. This is the effect of `lazy' allocation */ +! *the_bucket = (struct sbucket*)__objc_xmalloc(sizeof(struct sbucket)); +! memcpy((void *) *the_bucket, (const void*)array->empty_bucket, sizeof(struct sbucket)); +! (*the_bucket)->version = array->version; + nbuckets += 1; + +! } else if ((*the_bucket)->version != array->version) { + + /* Perform lazy copy. */ + struct sbucket* old_bucket = *the_bucket; +! *the_bucket = (struct sbucket*)__objc_xmalloc(sizeof(struct sbucket)); +! memcpy( *the_bucket,old_bucket, sizeof(struct sbucket)); +! (*the_bucket)->version = array->version; + nbuckets += 1; + + } +--- 173,195 ---- + + /* 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; + + } +*************** +*** 151,192 **** + struct sarray* + sarray_new (int size, void* default_element) + { + #ifdef OBJC_SPARSE3 + size_t num_indices = ((size-1)/(INDEX_CAPACITY))+1; + #else /* OBJC_SPARSE2 */ + size_t num_indices = ((size-1)/BUCKET_SIZE)+1; + #endif + int counter; +- struct sarray* arr; + + assert(size > 0); + + /* Allocate core array */ +! arr = (struct sarray*) __objc_xmalloc(sizeof(struct sarray)); +! arr->version = 0; +! narrays += 1; + + /* Initialize members */ + #ifdef OBJC_SPARSE3 + arr->capacity = num_indices*INDEX_CAPACITY; +! arr->indices = (struct sindex**) +! __objc_xmalloc(sizeof(struct sindex*)*num_indices); +! idxsize += num_indices; + +! arr->empty_index = (struct sindex*) __objc_xmalloc(sizeof(struct sindex)); +! arr->empty_index->version = 0; + nindices += 1; + + #else /* OBJC_SPARSE2 */ + arr->capacity = num_indices*BUCKET_SIZE; +! arr->buckets = (struct sbucket**) +! __objc_xmalloc(sizeof(struct sbucket*)*num_indices); + idxsize += num_indices; + + #endif + +! arr->empty_bucket = (struct sbucket*) __objc_xmalloc(sizeof(struct sbucket)); +! arr->empty_bucket->version = 0; + nbuckets += 1; + + arr->ref_count = 1; +--- 207,254 ---- + 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; +*************** +*** 200,219 **** + arr->empty_index->buckets[counter] = arr->empty_bucket; + + for (counter=0; counterindices[counter] = arr->empty_index; + + #else /* OBJC_SPARSE2 */ + + for (counter=0; counterbuckets[counter] = arr->empty_bucket; + + #endif +! + return arr; + } + + +! /* Reallocate the sparse array to hold `newsize' entries */ + + void + sarray_realloc(struct sarray* array, int newsize) +--- 262,289 ---- + arr->empty_index->buckets[counter] = arr->empty_bucket; + + for (counter=0; counterempty_index; + + #else /* OBJC_SPARSE2 */ + + for (counter=0; counterempty_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) +*************** +*** 223,233 **** +--- 293,309 ---- + 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; +*************** +*** 235,321 **** + 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... */ + +! if(rounded_size < array->capacity) + { +- /* update capacity */ +- array->capacity = rounded_size; + +- /* free buckets above new_max_index */ +- for(counter = old_max_index; counter > new_max_index; counter-- ) { + #ifdef OBJC_SPARSE3 +! struct sindex* idx = array->indices[counter]; +! if((idx != array->empty_index) && (idx->version == array->version)) { +! int c2; +! for(c2=0; c2buckets[c2]; +! if((bkt != array->empty_bucket) && (bkt->version == array->version)) +! { +! free(bkt); +! nbuckets -= 1; +! } +! } +! free(idx); +! nindices -= 1; +! } + #else /* OBJC_SPARSE2 */ +! struct sbucket* bkt = array->buckets[counter]; +! if ((bkt != array->empty_bucket) && (bkt->version == array->version)) +! { +! free(bkt); +! nbuckets -= 1; +! } + #endif +! } +! +! #ifdef OBJC_SPARSE3 +! /* realloc to free the space above new_max_index */ +! array->indices = (struct sindex**) +! __objc_xrealloc(array->indices, +! (new_max_index+1)*sizeof(struct sindex*)); +! #else /* OBJC_SPARSE2 */ +! array->buckets = (struct sbucket**) +! __objc_xrealloc(array->buckets, +! (new_max_index+1)*sizeof(struct sbucket*)); +! #endif +! idxsize -= (old_max_index-new_max_index); +! +! return; +! } +! +! /* We are asked to extend the array -- reallocate the bucket table, */ +! /* and insert empty_bucket in newly allocated places. */ +! if(rounded_size > array->capacity) +! { + /* update capacity */ + array->capacity = rounded_size; + + #ifdef OBJC_SPARSE3 +! /* realloc to make room in table above old_max_index */ +! array->indices = (struct sindex**) +! __objc_xrealloc(array->indices, +! (new_max_index+1)*sizeof(struct sindex*)); + + /* reset entries above old_max_index to empty_bucket */ + for(counter = old_max_index+1; counter <= new_max_index; counter++) +! array->indices[counter] = array->empty_index; +! + #else /* OBJC_SPARSE2 */ +- +- /* realloc to make room in table above old_max_index */ +- array->buckets = (struct sbucket**) +- __objc_xrealloc(array->buckets, +- (new_max_index+1)*sizeof(struct sbucket*)); +- + /* reset entries above old_max_index to empty_bucket */ + for(counter = old_max_index+1; counter <= new_max_index; counter++) +! array->buckets[counter] = array->empty_bucket; + + #endif + idxsize += (new_max_index-old_max_index); + return; + } +--- 311,382 ---- + 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; + } +*************** +*** 326,335 **** +--- 387,399 ---- + + 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; + +*************** +*** 338,368 **** + if(--(array->ref_count) != 0) /* There exists copies of me */ + return; + + 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 = array->indices[counter]; +! if((idx != array->empty_index) && (idx->version == array->version)) { + int c2; + for(c2=0; c2buckets[c2]; +! if((bkt != array->empty_bucket) && (bkt->version == array->version)) + { +! free(bkt); + nbuckets -= 1; + } + } +! free(idx); + nindices -= 1; + } + #else /* OBJC_SPARSE2 */ + struct sbucket* bkt = array->buckets[counter]; +! if ((bkt != array->empty_bucket) && (bkt->version == array->version)) + { +! free(bkt); + nbuckets -= 1; + } + #endif +--- 402,441 ---- + 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; c2buckets[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 +*************** +*** 370,402 **** + + #ifdef OBJC_SPARSE3 + /* free empty_index */ +! if(array->empty_index->version == array->version) { +! free(array->empty_index); + nindices -= 1; + } + #endif + + /* free empty_bucket */ +! if(array->empty_bucket->version == array->version) { +! free(array->empty_bucket); + nbuckets -= 1; + } + + #ifdef OBJC_SPARSE3 + /* free bucket table */ +! free(array->indices); +! idxsize -= (old_max_index+1); + + #else + /* free bucket table */ +! free(array->buckets); +! idxsize -= (old_max_index+1); + + #endif +! + /* free array */ +! free(array); +! narrays -= 1; + } + + /* This is a lazy copy. Only the core of the structure is actually */ +--- 443,474 ---- + + #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 */ +*************** +*** 405,441 **** + struct sarray* + sarray_lazy_copy(struct sarray* oarr) + { + #ifdef OBJC_SPARSE3 + size_t num_indices = ((oarr->capacity-1)/INDEX_CAPACITY)+1; + #else /* OBJC_SPARSE2 */ + size_t num_indices = ((oarr->capacity-1)/BUCKET_SIZE)+1; + #endif +- struct sarray* arr; + + /* Allocate core array */ +! arr = (struct sarray*) __objc_xmalloc(sizeof(struct sarray)); +! memcpy( arr,oarr, sizeof(struct sarray)); +! arr->version = oarr->version + 1; +! arr->is_copy_of = oarr; +! oarr->ref_count += 1; + arr->ref_count = 1; + + #ifdef OBJC_SPARSE3 + /* Copy bucket table */ +! arr->indices = (struct sindex**) +! __objc_xmalloc(sizeof(struct sindex*)*num_indices); +! memcpy( arr->indices,oarr->indices, + sizeof(struct sindex*)*num_indices); + #else + /* Copy bucket table */ +! arr->buckets = (struct sbucket**) +! __objc_xmalloc(sizeof(struct sbucket*)*num_indices); +! memcpy( arr->buckets,oarr->buckets, + sizeof(struct sbucket*)*num_indices); + #endif + + idxsize += num_indices; + narrays += 1; +! + return arr; + } +--- 477,522 ---- + 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; + } +diff -rcP gcc-2.7.2.1/objc/sarray.h gcc-2.7.2.1-objc-960906/objc/sarray.h +*** gcc-2.7.2.1/objc/sarray.h Fri Sep 6 11:29:01 1996 +--- gcc-2.7.2.1-objc-960906/objc/sarray.h Fri Sep 6 10:33:34 1996 +*************** +*** 1,5 **** + /* Sparse Arrays for Objective C dispatch tables +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + + Author: Kresten Krab Thorup + +--- 1,5 ---- + /* Sparse Arrays for Objective C dispatch tables +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + + Author: Kresten Krab Thorup + +*************** +*** 42,47 **** +--- 42,49 ---- + + #include + ++ #include "objc/thr.h" ++ + extern int nbuckets; /* for stats */ + extern int nindices; + extern int narrays; +*************** +*** 108,126 **** + + #endif /* not PRECOMPUTE_SELECTORS */ + +! void * __objc_xrealloc (void *optr, size_t size); +! void * __objc_xmalloc (size_t size); + + struct sbucket { + void* elems[BUCKET_SIZE]; /* elements stored in array */ +! short version; /* used for copy-on-write */ + }; + + #ifdef OBJC_SPARSE3 + + struct sindex { + struct sbucket* buckets[INDEX_SIZE]; +! short version; + }; + + #endif /* OBJC_SPARSE3 */ +--- 110,130 ---- + + #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 */ +*************** +*** 133,139 **** + struct sbucket** buckets; + #endif /* OBJC_SPARSE2 */ + struct sbucket* empty_bucket; +! short version; + short ref_count; + struct sarray* is_copy_of; + size_t capacity; +--- 137,143 ---- + 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; +*************** +*** 142,151 **** + struct sarray* sarray_new(int, void* default_element); + void sarray_free(struct sarray*); + struct sarray* sarray_lazy_copy(struct sarray*); +- struct sarray* sarray_hard_copy(struct sarray*); /* ... like the name? */ + 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); + + + #ifdef PRECOMPUTE_SELECTORS +--- 146,157 ---- + 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 +diff -rcP gcc-2.7.2.1/objc/selector.c gcc-2.7.2.1-objc-960906/objc/selector.c +*** gcc-2.7.2.1/objc/selector.c Fri Sep 6 11:29:02 1996 +--- gcc-2.7.2.1-objc-960906/objc/selector.c Fri Sep 6 10:33:34 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime selector related functions +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime selector related functions +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 31,44 **** + #define SELECTOR_HASH_SIZE 128 + + /* Tables mapping selector names to uid and opposite */ +! static struct sarray* __objc_selector_array = 0; /* uid -> sel */ +! static struct sarray* __objc_selector_names = 0; /* uid -> name */ +! static cache_ptr __objc_selector_hash = 0; /* name -> uid */ + + static void register_selectors_from_list(MethodList_t); + + /* Number of selectors stored in each of the above tables */ +! int __objc_selector_max_index = 0; + + void __objc_init_selector_tables() + { +--- 31,44 ---- + #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() + { +*************** +*** 88,93 **** +--- 88,153 ---- + } + + ++ /* 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 for this method list */ ++ for (i = 0; i < method_list->method_count; i++) ++ if (!search_for_method_in_list ++ (class_method_list, ++ method_list->method_list[i].method_name)) ++ { ++ /* This instance method isn't a class method. ++ Add it into the new_list. */ ++ *curr_method = method_list->method_list[i]; ++ ++ /* 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; ++ } ++ } ++ ++ + /* Returns YES iff t1 and t2 have same method types, but we ignore + the argframe layout */ + BOOL +*************** +*** 122,130 **** + struct objc_list *l; + sidx i; + + i = (sidx) hash_value_for_key (__objc_selector_hash, name); + if (i == 0) +! return 0; + + for (l = (struct objc_list*)sarray_get (__objc_selector_array, i); + l; l = l->tail) +--- 182,195 ---- + 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 (__objc_selector_array, i); + l; l = l->tail) +*************** +*** 134,148 **** +--- 199,216 ---- + { + 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; + } + +*************** +*** 154,171 **** + sidx i; + SEL s; + + i = (sidx) hash_value_for_key (__objc_selector_hash, name); + if (i == 0) +! return 0; + + for (l = (struct objc_list*)sarray_get (__objc_selector_array, i); + l; l = l->tail) + { + s = (SEL) l->head; + if (s->sel_types) +! return s; + } + + return s; + } + +--- 222,248 ---- + sidx i; + SEL s; + ++ 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 (__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; + } + +*************** +*** 176,186 **** + struct objc_list *l; + sidx i; + + i = (sidx) hash_value_for_key (__objc_selector_hash, name); + if (soffset_decode (i) == 0) +! return 0; + + l = (struct objc_list*)sarray_get (__objc_selector_array, i); + if (l == 0) + return 0; + +--- 253,270 ---- + 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 (__objc_selector_array, i); ++ objc_mutex_unlock(__objc_runtime_mutex); ++ + if (l == 0) + return 0; + +*************** +*** 199,209 **** + const char* + sel_get_name (SEL selector) + { + if ((soffset_decode((sidx)selector->sel_id) > 0) + && (soffset_decode((sidx)selector->sel_id) <= __objc_selector_max_index)) +! return sarray_get (__objc_selector_names, (sidx) selector->sel_id); + else +! return 0; + } + + BOOL +--- 283,298 ---- + 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 (__objc_selector_names, (sidx) selector->sel_id); + else +! ret = 0; +! objc_mutex_unlock(__objc_runtime_mutex); +! return ret; + } + + BOOL +*************** +*** 227,236 **** + 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). */ + SEL + __sel_register_typed_name (const char *name, const char *types, +! struct objc_selector *orig) + { + struct objc_selector* j; + sidx i; +--- 316,330 ---- + 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; +*************** +*** 270,279 **** + if (orig) + j = orig; + else +! j = __objc_xmalloc (sizeof (struct objc_selector)); + + j->sel_id = (void*)i; +! j->sel_types = (const char*)types; + l = (struct objc_list*)sarray_get (__objc_selector_array, i); + } + else +--- 364,379 ---- + 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 (__objc_selector_array, i); + } + else +*************** +*** 283,292 **** + if (orig) + j = orig; + else +! j = __objc_xmalloc (sizeof (struct objc_selector)); + + j->sel_id = (void*)i; +! j->sel_types = (const char*)types; + l = 0; + } + +--- 383,398 ---- + 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; + } + +*************** +*** 295,305 **** + + { + int is_new = (l == 0); + l = list_cons ((void*)j, l); +! sarray_at_put_safe (__objc_selector_names, i, (void *) name); + sarray_at_put_safe (__objc_selector_array, i, (void *) l); + if (is_new) +! hash_add (&__objc_selector_hash, (void *) name, (void *) i); + } + + sarray_realloc(__objc_uninstalled_dtable, __objc_selector_max_index+1); +--- 401,421 ---- + + { + 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); +*************** +*** 310,321 **** + SEL + sel_register_name (const char *name) + { +! return __sel_register_typed_name (name, 0, 0); + } + + SEL + sel_register_typed_name (const char *name, const char *type) + { +! return __sel_register_typed_name (name, type, 0); + } + +--- 426,453 ---- + 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; + } + +diff -rcP gcc-2.7.2.1/objc/sendmsg.c gcc-2.7.2.1-objc-960906/objc/sendmsg.c +*** gcc-2.7.2.1/objc/sendmsg.c Fri Sep 6 11:29:02 1996 +--- gcc-2.7.2.1-objc-960906/objc/sendmsg.c Fri Sep 6 10:33:35 1996 +*************** +*** 1,5 **** + /* GNU Objective C Runtime message lookup +! Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +--- 1,5 ---- + /* GNU Objective C Runtime message lookup +! Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup + + This file is part of GNU CC. +*************** +*** 33,46 **** + #define gen_rtx(args...) 1 + #define rtx int + +! #if STRUCT_VALUE == 0 + #define INVISIBLE_STRUCT_RETURN 1 + #else + #define INVISIBLE_STRUCT_RETURN 0 + #endif + + /* The uninstalled dispatch table */ +! struct sarray* __objc_uninstalled_dtable = 0; + + /* Send +initialize to class */ + static void __objc_send_initialize(Class); +--- 33,46 ---- + #define gen_rtx(args...) 1 + #define rtx int + +! #if !defined(STRUCT_VALUE) || STRUCT_VALUE == 0 + #define INVISIBLE_STRUCT_RETURN 1 + #else + #define INVISIBLE_STRUCT_RETURN 0 + #endif + + /* The uninstalled dispatch table */ +! struct sarray* __objc_uninstalled_dtable = 0; /* !T:MUTEX */ + + /* Send +initialize to class */ + static void __objc_send_initialize(Class); +*************** +*** 49,54 **** +--- 49,62 ---- + + /* Forward declare some functions */ + static void __objc_init_install_dtable(id, SEL); ++ ++ /* Various forwarding functions that are used based upon the ++ return type for the selector. ++ __objc_block_forward for structures. ++ __objc_double_forward for floats/doubles. ++ __objc_word_forward for pointers or types that fit in registers. ++ */ ++ static double __objc_double_forward(id, SEL, ...); + static id __objc_word_forward(id, SEL, ...); + typedef struct { id many[8]; } __big; + #if INVISIBLE_STRUCT_RETURN +*************** +*** 57,71 **** + static id + #endif + __objc_block_forward(id, SEL, ...); + static Method_t search_for_method_in_hierarchy (Class class, SEL sel); +! static Method_t search_for_method_in_list(MethodList_t list, SEL op); + id nil_method(id, SEL, ...); + +! id +! nil_method(id receiver, SEL op, ...) +! { +! return receiver; +! } + + /* Given a class and selector, return the selector's implementation. */ + __inline__ +--- 65,89 ---- + static id + #endif + __objc_block_forward(id, SEL, ...); ++ + static Method_t search_for_method_in_hierarchy (Class class, SEL sel); +! Method_t search_for_method_in_list(MethodList_t list, SEL op); + id nil_method(id, SEL, ...); + +! /* OBJC_MAX_STRUCT_BY_VALUE should be defined in the platform specific +! configuration file. Some platforms, i386 on NeXTSTEP for example, +! pass small structures as values on the stack versus through a +! hidden pointer as for larger structures. In order for forwarding +! to work properly, the ObjC runtime needs to know when the structure +! is being passed by value or not so it can perform the appropriate +! forwarding function. The value of OBJC_MAX_STRUCT_BY_VALUE should +! be the maximum number of bytes for the size of the structure for it +! to be passed as a value, so a value of 8 indicates that a structure +! of size 8 gets passed as a value while a structure of size 9 gets +! passed as a hidden pointer. +! +! Leave OBJC_MAX_STRUCT_BY_VALUE undefined for platforms that always pass +! structures as hidden pointers. */ + + /* Given a class and selector, return the selector's implementation. */ + __inline__ +*************** +*** 76,89 **** + void* res = sarray_get (class->dtable, (size_t) sel->sel_id); + if(res == __objc_init_install_dtable) + { + __objc_install_dispatch_table_for_class (class); + res = sarray_get (class->dtable, (size_t) sel->sel_id); + } + if (res == 0) + { + const char *t = sel->sel_types; +! if (t && (*t == '[' || *t == '(' || *t == '{')) + res = (IMP)__objc_block_forward; + else + res = (IMP)__objc_word_forward; + } +--- 94,115 ---- + void* res = sarray_get (class->dtable, (size_t) sel->sel_id); + if(res == __objc_init_install_dtable) + { ++ objc_mutex_lock(__objc_runtime_mutex); + __objc_install_dispatch_table_for_class (class); ++ objc_mutex_unlock(__objc_runtime_mutex); + res = sarray_get (class->dtable, (size_t) sel->sel_id); + } + if (res == 0) + { + const char *t = sel->sel_types; +! if (t && (*t == '[' || *t == '(' || *t == '{') +! #ifdef OBJC_MAX_STRUCT_BY_VALUE +! && (objc_sizeof_type(t) >= OBJC_MAX_STRUCT_BY_VALUE) +! #endif +! ) + res = (IMP)__objc_block_forward; ++ else if (t && (*t == 'f' || *t == 'd')) ++ res = (IMP)__objc_double_forward; + else + res = (IMP)__objc_word_forward; + } +*************** +*** 96,102 **** +--- 122,130 ---- + void* res = sarray_get (object->class_pointer->dtable, (size_t) sel->sel_id); + if(res == __objc_init_install_dtable) + { ++ objc_mutex_lock(__objc_runtime_mutex); + __objc_install_dispatch_table_for_class (object->class_pointer); ++ objc_mutex_unlock(__objc_runtime_mutex); + res = sarray_get (object->class_pointer->dtable, (size_t) sel->sel_id); + } + return (res != 0); +*************** +*** 116,123 **** + if (result == 0) + { + const char *t = op->sel_types; +! if (t && (*t == '[' || *t == '(' || *t == '{')) + result = (IMP)__objc_block_forward; + else + result = (IMP)__objc_word_forward; + } +--- 144,157 ---- + if (result == 0) + { + const char *t = op->sel_types; +! if (t && (*t == '[' || *t == '(' || *t == '{') +! #ifdef OBJC_MAX_STRUCT_BY_VALUE +! && (objc_sizeof_type(t) >= OBJC_MAX_STRUCT_BY_VALUE) +! #endif +! ) + result = (IMP)__objc_block_forward; ++ else if (t && (*t == 'f' || *t == 'd')) ++ result = (IMP)__objc_double_forward; + else + result = (IMP)__objc_word_forward; + } +*************** +*** 172,177 **** +--- 206,213 ---- + if(receiver->class_pointer->dtable != __objc_uninstalled_dtable) + goto already_initialized; + ++ objc_mutex_lock(__objc_runtime_mutex); ++ + if(CLS_ISCLASS(receiver->class_pointer)) + { + /* receiver is an ordinary object */ +*************** +*** 198,203 **** +--- 234,240 ---- + else + CLS_SETINITIALIZED((Class)receiver); + } ++ objc_mutex_unlock(__objc_runtime_mutex); + + already_initialized: + +*************** +*** 269,274 **** +--- 306,312 ---- + } + } + ++ /* Assumes that __objc_runtime_mutex is locked down. */ + static void + __objc_install_dispatch_table_for_class (Class class) + { +*************** +*** 289,295 **** +--- 327,335 ---- + /* Allocate dtable if necessary */ + if (super == 0) + { ++ objc_mutex_lock(__objc_runtime_mutex); + class->dtable = sarray_new (__objc_selector_max_index, 0); ++ objc_mutex_unlock(__objc_runtime_mutex); + } + else + class->dtable = sarray_lazy_copy (super->dtable); +*************** +*** 311,335 **** + void __objc_update_dispatch_table_for_class (Class class) + { + Class next; + + /* not yet installed -- skip it */ + if (class->dtable == __objc_uninstalled_dtable) + return; + +! sarray_free (class->dtable); /* release memory */ + __objc_install_premature_dtable (class); /* someone might require it... */ +! __objc_install_dispatch_table_for_class (class); /* could have been lazy... */ + + if (class->subclass_list) /* Traverse subclasses */ + for (next = class->subclass_list; next; next = next->sibling_class) + __objc_update_dispatch_table_for_class (next); + + } + + + /* This function adds a method list to a class. This function is + typically called by another function specific to the run-time. As +! such this function does not worry about thread safe issued. + + This one is only called for categories. Class objects have their + methods installed right away, and their selectors are made into +--- 351,382 ---- + void __objc_update_dispatch_table_for_class (Class class) + { + Class next; ++ struct sarray *arr; + + /* not yet installed -- skip it */ + if (class->dtable == __objc_uninstalled_dtable) + return; + +! objc_mutex_lock(__objc_runtime_mutex); +! +! arr = class->dtable; + __objc_install_premature_dtable (class); /* someone might require it... */ +! sarray_free (arr); /* release memory */ +! +! /* could have been lazy... */ +! __objc_install_dispatch_table_for_class (class); + + if (class->subclass_list) /* Traverse subclasses */ + for (next = class->subclass_list; next; next = next->sibling_class) + __objc_update_dispatch_table_for_class (next); + ++ objc_mutex_unlock(__objc_runtime_mutex); + } + + + /* This function adds a method list to a class. This function is + typically called by another function specific to the run-time. As +! such this function does not worry about thread safe issues. + + This one is only called for categories. Class objects have their + methods installed right away, and their selectors are made into +*************** +*** 338,344 **** + class_add_method_list (Class class, MethodList_t list) + { + int i; +! static SEL initialize_sel = 0; + if (!initialize_sel) + initialize_sel = sel_register_name ("initialize"); + +--- 385,392 ---- + class_add_method_list (Class class, MethodList_t list) + { + int i; +! static SEL initialize_sel = 0; /* !T:SAFE2 */ +! + if (!initialize_sel) + initialize_sel = sel_register_name ("initialize"); + +*************** +*** 414,420 **** + /* Given a linked list of method and a method's name. Search for the named + method's method structure. Return a pointer to the method's method + structure if found. NULL otherwise. */ +! static Method_t + search_for_method_in_list (MethodList_t list, SEL op) + { + MethodList_t method_list = list; +--- 462,468 ---- + /* Given a linked list of method and a method's name. Search for the named + method's method structure. Return a pointer to the method's method + structure if found. NULL otherwise. */ +! Method_t + search_for_method_in_list (MethodList_t list, SEL op) + { + MethodList_t method_list = list; +*************** +*** 447,452 **** +--- 495,501 ---- + + static retval_t __objc_forward (id object, SEL sel, arglist_t args); + ++ /* Forwarding pointers/integers through the normal registers */ + static id + __objc_word_forward (id rcv, SEL op, ...) + { +*************** +*** 460,465 **** +--- 509,529 ---- + return res; + } + ++ /* Specific routine for forwarding floats/double because of ++ architectural differences on some processors. i386s for ++ example which uses a floating point stack versus general ++ registers for floating point numbers. This forward routine ++ makes sure that GCC restores the proper return values */ ++ static double ++ __objc_double_forward (id rcv, SEL op, ...) ++ { ++ void *args, *res; ++ ++ args = __builtin_apply_args (); ++ res = __objc_forward (rcv, op, args); ++ __builtin_return (res); ++ } ++ + #if INVISIBLE_STRUCT_RETURN + static __big + #else +*************** +*** 482,488 **** + __objc_forward (id object, SEL sel, arglist_t args) + { + IMP imp; +! static SEL frwd_sel = 0; + SEL err_sel; + + /* first try if the object understands forward:: */ +--- 546,552 ---- + __objc_forward (id object, SEL sel, arglist_t args) + { + IMP imp; +! static SEL frwd_sel = 0; /* !T:SAFE2 */ + SEL err_sel; + + /* first try if the object understands forward:: */ +*************** +*** 526,539 **** + + /* The object doesn't respond to doesNotRecognize: or error:; Therefore, + a default action is taken. */ +! fprintf (stderr, "fatal: %s\n", msg); +! abort (); + } + } + + void __objc_print_dtable_stats() + { + int total = 0; + printf("memory usage: (%s)\n", + #ifdef OBJC_SPARSE2 + "2-level sparse arrays" +--- 590,605 ---- + + /* The object doesn't respond to doesNotRecognize: or error:; Therefore, + a default action is taken. */ +! objc_error (object, OBJC_ERR_UNIMPLEMENTED, "%s\n", msg); + } + } + + void __objc_print_dtable_stats() + { + int total = 0; ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ + printf("memory usage: (%s)\n", + #ifdef OBJC_SPARSE2 + "2-level sparse arrays" +*************** +*** 542,550 **** + #endif + ); + +! printf("arrays: %d = %ld bytes\n", narrays, (int)narrays*sizeof(struct sarray)); + total += narrays*sizeof(struct sarray); +! printf("buckets: %d = %ld bytes\n", nbuckets, (int)nbuckets*sizeof(struct sbucket)); + total += nbuckets*sizeof(struct sbucket); + + printf("idxtables: %d = %ld bytes\n", idxsize, (int)idxsize*sizeof(void*)); +--- 608,618 ---- + #endif + ); + +! printf("arrays: %d = %ld bytes\n", narrays, +! (int)narrays*sizeof(struct sarray)); + total += narrays*sizeof(struct sarray); +! printf("buckets: %d = %ld bytes\n", nbuckets, +! (int)nbuckets*sizeof(struct sbucket)); + total += nbuckets*sizeof(struct sbucket); + + printf("idxtables: %d = %ld bytes\n", idxsize, (int)idxsize*sizeof(void*)); +*************** +*** 552,558 **** + printf("-----------------------------------\n"); + printf("total: %d bytes\n", total); + printf("===================================\n"); +- } +- + + +--- 620,633 ---- + printf("-----------------------------------\n"); + printf("total: %d bytes\n", total); + printf("===================================\n"); + ++ objc_mutex_unlock(__objc_runtime_mutex); ++ } + ++ /* Returns the dispatch table */ ++ __inline__ ++ struct sarray* ++ objc_get_uninstalled_dtable() ++ { ++ return __objc_uninstalled_dtable; ++ } +diff -rcP gcc-2.7.2.1/objc/thr-decosf1.c gcc-2.7.2.1-objc-960906/objc/thr-decosf1.c +*** gcc-2.7.2.1/objc/thr-decosf1.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-decosf1.c Fri Sep 6 10:33:35 1996 +*************** +*** 0 **** +--- 1,326 ---- ++ /* GNU Objective C Runtime Thread Interface ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */ ++ ++ /* 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 ++ #include ++ #include "runtime.h" ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ pthread_mutex_t lock; /* pthread mutex. */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ static pthread_key_t __objc_thread_data_key; /* Data key for thread data.*/ ++ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ printf("__objc_init_thread_system\n"); ++ ++ if (pthread_keycreate(&__objc_thread_data_key, NULL) == 0) ++ return 0; /* Yes, return success. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id = NULL; /* Detached thread id. */ ++ pthread_t new_thread_handle; /* DCE thread handle. */ ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ if (pthread_create(&new_thread_handle, pthread_attr_default, ++ (void *)func, arg) == 0) { ++ /* ??? May not work! (64bit)*/ ++ thread_id = *(objc_thread_t *)&new_thread_handle; ++ pthread_detach(&new_thread_handle); /* Fully detach thread. */ ++ __objc_runtime_threads_alive++; ++ } ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ int sys_priority = 0; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2; ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; ++ break; ++ } ++ ++ if (pthread_setprio(pthread_self(), sys_priority) >= 0) ++ return 0; /* Changed priority. End. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ int sys_priority; /* DCE thread priority. */ ++ ++ if ((sys_priority = pthread_getprio(pthread_self())) >= 0) { ++ if (sys_priority >= PRI_FG_MIN_NP && sys_priority <= PRI_FG_MAX_NP) ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; ++ if (sys_priority >= PRI_BG_MIN_NP && sys_priority <= PRI_BG_MAX_NP) ++ return OBJC_THREAD_BACKGROUND_PRIORITY; ++ return OBJC_THREAD_LOW_PRIORITY; ++ } ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ pthread_yield(); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ pthread_exit(&__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * -1 which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ pthread_t self = pthread_self(); ++ ++ return (objc_thread_t) pthread_getuniqe_np (&self); ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ if (pthread_setspecific(__objc_thread_data_key, (void *)value) == 0) ++ return 0; /* Return thread data. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ void * value = NULL; ++ ++ if (pthread_getspecific(__objc_thread_data_key, (void *)&value) == 0) ++ return value; /* Return thread data. */ ++ ++ return NULL; ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if ++ * the allocation fails for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ err = pthread_mutex_init(&mutex->lock, pthread_mutexattr_default); ++ ++ if (err != 0) { /* System init failed? */ ++ objc_free(mutex); /* Yes, free local memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = (objc_thread_t) -1; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ pthread_mutex_unlock(&mutex->lock); /* Must unlock system mutex.*/ ++ pthread_mutex_destroy(&mutex->lock); /* Free system mutex. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (pthread_mutex_lock(&mutex->lock) != 0) /* Lock DCE system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (pthread_mutex_trylock(&mutex->lock) != 1) /* Lock DCE system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/ ++ ++ if (pthread_mutex_unlock(&mutex->lock) != 0) /* Unlock system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2.1/objc/thr-irix.c gcc-2.7.2.1-objc-960906/objc/thr-irix.c +*** gcc-2.7.2.1/objc/thr-irix.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-irix.c Fri Sep 6 10:33:35 1996 +*************** +*** 0 **** +--- 1,314 ---- ++ /* GNU Objective C Runtime Thread Interface - SGI IRIX Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */ ++ ++ /* 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 ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include "runtime.h" ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ ulock_t lock; /* Irix lock. */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ static void * __objc_shared_arena_handle = NULL; /* Storage arena locks. */ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ char arena_name[64]; /* Name of IRIX arena. */ ++ ++ DEBUG_PRINTF("__objc_init_thread_system\n"); ++ sprintf(arena_name, "/usr/tmp/objc_%05u", (unsigned)getpid()); ++ usconfig(CONF_INITUSERS, 256); /* Up to 256 threads. */ ++ usconfig(CONF_ARENATYPE, US_SHAREDONLY); /* Arena only for threads. */ ++ if (!(__objc_shared_arena_handle = usinit(arena_name))) /* Init Failed? */ ++ return -1; /* Yes, return error code. */ ++ ++ return 0; ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id = NULL; ++ int sys_id; ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ if ((sys_id = sproc((void *)func, PR_SALL, arg)) >= 0) { ++ thread_id = (objc_thread_t)sys_id; ++ __objc_runtime_threads_alive++; ++ } ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ int sys_priority = 0; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ break; ++ } ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ sginap(0); /* Yield to equal process. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ exit(__objc_thread_exit_status); /* IRIX only has exit. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * NULL which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ return (objc_thread_t)get_pid(); /* Threads are processes. */ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ *((void **)&PRDA->usr_prda) = value; /* Set thread data ptr. */ ++ return 0; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return *((void **)&PRDA->usr_prda); /* Return thread data ptr. */ ++ } ++ ++ /******** ++ * Allocate a mutex. ++ * Return the mutex pointer if successful or NULL if the allocation failed ++ * for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ if (!(mutex->lock = usnewlock(__objc_shared_arena_handle))) ++ err = -1; ++ ++ if (err != 0) { /* System init failed? */ ++ objc_free(mutex); /* Yes, free local memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ usfreelock(mutex->lock, __objc_shared_arena_handle); /* Free IRIX lock. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) { /* Already own lock? */ ++ DEBUG_PRINTF("lock owned by: %d:%d\n", mutex->owner, mutex->depth); ++ return ++mutex->depth; /* Yes, increment depth. */ ++ } ++ ++ DEBUG_PRINTF("lock owned by: %d:%d (attempt by %d)\n", ++ mutex->owner, mutex->depth, thread_id); ++ ++ if (ussetlock(mutex->lock) == 0) /* Did lock acquire fail? */ ++ return -1; /* Yes, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (ustestlock(mutex->lock) == 0) /* Did lock acquire fail? */ ++ return -1; /* Yes, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ ++ DEBUG_PRINTF("unlock by: %d:%d\n", mutex->owner, mutex->depth - 1); ++ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ usunsetlock(mutex->lock); /* Free lock. */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2.1/objc/thr-mach.c gcc-2.7.2.1-objc-960906/objc/thr-mach.c +*** gcc-2.7.2.1/objc/thr-mach.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-mach.c Fri Sep 6 10:33:36 1996 +*************** +*** 0 **** +--- 1,465 ---- ++ /* GNU Objective C Runtime Thread Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ ++ Author: Galen C. Hunt (gchunt@cs.rochester.edu) ++ Modified for Mach threads by: Bill Bumgarner ++ Condition functions added by: Mircea Oancea ++ ++ 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 ++ #include ++ #include ++ #include "runtime.h" ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ struct mutex lock; /* cthread mutex */ ++ }; ++ ++ struct objc_condition ++ { ++ struct condition condition; /* cthread condition */ ++ }; ++ ++ /******** ++ * obtain the maximum thread priority that can set for t. Under the ++ * mach threading model, it is possible for the developer to adjust the ++ * maximum priority downward only-- cannot be raised without superuser ++ * priviledges. Once lowered, it cannot be raised. ++ */ ++ static int __mach_get_max_thread_priority(cthread_t t, int *base) { ++ thread_t threadP; ++ kern_return_t error; ++ struct thread_sched_info info; ++ unsigned int info_count=THREAD_SCHED_INFO_COUNT; ++ ++ if (t == NULL) ++ return -1; ++ ++ threadP = cthread_thread(t); /* get thread underlying */ ++ ++ error=thread_info(threadP, THREAD_SCHED_INFO, ++ (thread_info_t)&info, &info_count); ++ ++ if (error != KERN_SUCCESS) ++ return -1; ++ ++ if (base != NULL) ++ *base = info.base_priority; ++ ++ return info.max_priority; ++ } ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ DEBUG_PRINTF("__objc_init_thread_system\n"); ++ return 0; /* Succeeded. */ ++ } ++ ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id = NULL; /* Detached thread id. */ ++ cthread_t new_thread_handle; /* cthread handle. */ ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ /* create thread */ ++ new_thread_handle = cthread_fork((cthread_fn_t)func, arg); ++ ++ if(new_thread_handle) { ++ /* this is not terribly portable */ ++ thread_id = *(objc_thread_t *)&new_thread_handle; ++ cthread_detach(new_thread_handle); /* fully detach thread */ ++ __objc_runtime_threads_alive++; /* increment thread count */ ++ } ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ objc_thread_t *t = objc_thread_id(); ++ cthread_t cT = (cthread_t) t; ++ int maxPriority = __mach_get_max_thread_priority(cT, NULL); ++ int sys_priority = 0; ++ ++ if (maxPriority == -1) ++ return -1; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_priority = maxPriority; ++ break; ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_priority = (maxPriority * 2) / 3; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_priority = maxPriority / 3; ++ break; ++ default: ++ return -1; ++ } ++ ++ if (sys_priority == 0) ++ return -1; ++ ++ if (cthread_priority(cT, sys_priority, 0) == KERN_SUCCESS) ++ return 0; /* Changed priority. End. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority [well, whatever it is closest to]. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ objc_thread_t *t = objc_thread_id(); ++ cthread_t cT = (cthread_t) t; /* see objc_thread_id() */ ++ int basePriority; ++ int maxPriority; ++ int sys_priority = 0; ++ ++ int interactiveT, backgroundT, lowT; /* threasholds */ ++ ++ maxPriority = __mach_get_max_thread_priority(cT, &basePriority); ++ ++ if(maxPriority == -1) ++ return -1; ++ ++ if (basePriority > ( (maxPriority * 2) / 3)) ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; /* interactive priority ++ */ ++ if (basePriority > ( maxPriority / 3)) ++ return OBJC_THREAD_BACKGROUND_PRIORITY; /* background priority ++ */ ++ return OBJC_THREAD_LOW_PRIORITY; /* everything else is low */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ cthread_yield(); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ cthread_exit(&__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * NULL which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ cthread_t self = cthread_self(); ++ return (objc_thread_t)self; ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ ++ int ++ objc_thread_set_data(void *value) ++ { ++ cthread_set_data(cthread_self(), (any_t) value); ++ return 0; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return (void *) cthread_data(cthread_self()); ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if the ++ * allocation failed for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ err = mutex_init(&(mutex->lock)); ++ ++ if (err != 0) { /* System init failed? */ ++ objc_free(mutex); /* Yes, free local memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = (objc_thread_t) -1; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallocate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ mutex_unlock(&(mutex->lock)); /* Must unlock system mutex.*/ ++ mutex_clear(&(mutex->lock)); /* Free system mutex. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ mutex_lock(&(mutex->lock)); /* Lock cthread mutex. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (mutex_try_lock(&(mutex->lock)) == 0) /* Lock cthread mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/ ++ ++ mutex_unlock(&(mutex->lock)); /* unlock cthread mutex. */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /******** ++ * Allocate a condition. Return the condition pointer if successful or NULL ++ * if the allocation failed for any reason. ++ */ ++ objc_condition_t ++ objc_condition_allocate(void) ++ { ++ objc_condition_t condition; ++ ++ if (!(condition = (objc_condition_t)objc_malloc( ++ sizeof(struct objc_condition)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ condition_init(&(condition->condition)); ++ ++ return condition; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a condition. Note that this includes an implicit ++ * condition_broadcast to insure that waiting threads have the opportunity ++ * to wake. It is legal to dealloc a condition only if no other ++ * thread is/will be using it. Here we do NOT check for other threads ++ * waiting but just wake them up. ++ */ ++ int ++ objc_condition_deallocate(objc_condition_t condition) ++ { ++ condition_broadcast(&(condition->condition)); ++ condition_clear(&(condition->condition)); ++ objc_free(condition); ++ return 0; ++ } ++ ++ /******** ++ * Wait on the condition unlocking the mutex until objc_condition_signal() ++ * or objc_condition_broadcast() are called for the same condition. The ++ * given mutex *must* have the depth set to 1 so that it can be unlocked ++ * here, so that someone else can lock it and signal/broadcast the condition. ++ * The mutex is used to lock access to the shared data that make up the ++ * "condition" predicate. ++ */ ++ int ++ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex || !condition) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Locked more than once ? */ ++ return -1; /* YES, return error */ ++ /* mutex will be unlocked */ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/ ++ ++ condition_wait(&(condition->condition), ++ &(mutex->lock)); /* unlock, wait ..., lock */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ mutex->depth = 1; /* Increment depth to end. */ ++ return 0; /* Return success. */ ++ } ++ ++ /******** ++ * Wake up all threads waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_broadcast(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ condition_broadcast(&(condition->condition)); ++ return 0; ++ } ++ ++ /******** ++ * Wake up one thread waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_signal(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ condition_signal(&(condition->condition)); ++ return 0; ++ } ++ +diff -rcP gcc-2.7.2.1/objc/thr-os2.c gcc-2.7.2.1-objc-960906/objc/thr-os2.c +*** gcc-2.7.2.1/objc/thr-os2.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-os2.c Fri Sep 6 10:33:36 1996 +*************** +*** 0 **** +--- 1,342 ---- ++ /* GNU Objective C Runtime Thread Interface - OS/2 emx Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ ++ Author: Thomas Baier (baier@ci.tuwien.ac.at) ++ ++ 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 ++ #include "runtime.h" ++ ++ #define INCL_DOSSEMAPHORES ++ #define INCL_DOSPROCESS ++ ++ /* ++ * conflicts with objc.h: SEL, BOOL, id ++ * solution: prefixing those with _OS2_ before including ++ */ ++ #define SEL _OS2_SEL ++ #define BOOL _OS2_BOOL ++ #define id _OS2_id ++ #include ++ #undef id ++ #undef SEL ++ #undef BOOL ++ ++ #include ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ HMTX handle; /* OS/2 mutex HANDLE. */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ /* none needed for OS/2 */ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ DEBUG_PRINTF("__objc_init_thread_system (os2-emx)\n"); ++ ++ /* no initialization of thread subsystem */ ++ return 0; /* Yes, return success. */ ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ /* no termination code for thread subsystem */ ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ int thread_id = 0; /* id of the newly created thread */ ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ /* create a thread calling "func", args "arg", stack size 32768 bytes */ ++ if ((thread_id = _beginthread (func,NULL,32768,arg)) < 0) ++ thread_id = 0; ++ else ++ __objc_runtime_threads_alive++; ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ return (objc_thread_t)thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ ULONG sys_class = 0; ++ ULONG sys_priority = 0; ++ ++ /* OBJC_THREAD_INTERACTIVE_PRIORITY -> PRTYC_FOREGROUNDSERVER ++ * OBJC_THREAD_BACKGROUND_PRIORITY -> PRTYC_REGULSR ++ * OBJC_THREAD_LOW_PRIORITY -> PRTYC_IDLETIME */ ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_class = PRTYC_REGULAR; ++ sys_priority = 10; ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_class = PRTYC_IDLETIME; ++ sys_priority = 25; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_class = PRTYC_IDLETIME; ++ sys_priority = 0; ++ break; ++ } ++ if (!DosSetPriority (PRTYS_THREAD,sys_class,sys_priority,*_threadid)) ++ return 0; /* Changed priority. End. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ PTIB ptib; ++ PPIB ppib; ++ ++ DosGetInfoBlocks (&ptib,&ppib); /* get information about current thread */ ++ ++ switch (ptib->tib_ptib2->tib2_ulpri) { ++ case PRTYC_IDLETIME: ++ case PRTYC_REGULAR: ++ case PRTYC_TIMECRITICAL: ++ case PRTYC_FOREGROUNDSERVER: ++ default: ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; ++ } ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ DosSleep (0); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ _endthread (); /* terminate the thread, NEVER use DosExit () */ ++ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * -1 which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ return (objc_thread_t) *_threadid; /* Return thread id. */ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ *_threadstore () = value; ++ ++ return 0; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return *_threadstore (); ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if ++ * the allocation fails for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ if (DosCreateMutexSem (NULL,&(mutex->handle),0L,0) > 0) { ++ objc_free(mutex); ++ return NULL; ++ } ++ ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ DosCloseMutexSem (mutex->handle); ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (DosRequestMutexSem (mutex->handle,-1L) != 0) ++ return -1; ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ ++ return ++mutex->depth; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (DosRequestMutexSem (mutex->handle,0L) != 0) ++ return -1; ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return ++mutex->depth; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ if (DosReleaseMutexSem(mutex->handle) != 0) ++ return -1; /* Failed, abort. */ ++ ++ return 0; /* No, return success. */ ++ } +diff -rcP gcc-2.7.2.1/objc/thr-posix.c gcc-2.7.2.1-objc-960906/objc/thr-posix.c +*** gcc-2.7.2.1/objc/thr-posix.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-posix.c Fri Sep 6 10:33:36 1996 +*************** +*** 0 **** +--- 1,323 ---- ++ /* GNU Objective C Runtime Thread Interface for POSIX compliant threads ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ ++ Author: Galen C. Hunt (gchunt@cs.rochester.edu) ++ Modified for Linux & Pthreads: Kai-Uwe Sattler (kus@iti.cs.uni-magdeburg.de) ++ ++ 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 ++ #include "runtime.h" ++ #include ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ pthread_mutex_t lock; /* pthread mutex. */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ static pthread_key_t __objc_thread_data_key; /* Data key for thread data.*/ ++ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ if (pthread_key_create(&__objc_thread_data_key, NULL) == 0) ++ return 0; /* Yes, return success. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id = NULL; /* Detached thread id. */ ++ pthread_t new_thread_handle; /* DCE thread handle. */ ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ if (pthread_create(&new_thread_handle, NULL, ++ (void *)func, arg) == 0) { ++ thread_id = (objc_thread_t) new_thread_handle; ++ pthread_detach(new_thread_handle); /* Fully detach thread. */ ++ __objc_runtime_threads_alive++; ++ } ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ #if 0 /* no get/set priority in Linux pthreads */ ++ ++ int sys_priority = 0; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2; ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; ++ break; ++ } ++ ++ if (pthread_setprio(pthread_self(), sys_priority) >= 0) ++ return 0; /* Changed priority. End. */ ++ ++ #endif ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ #if 0 /* no get/set priority in Linux pthreads */ ++ int sys_priority; /* DCE thread priority. */ ++ ++ if ((sys_priority = pthread_getprio(pthread_self())) >= 0) { ++ if (sys_priority >= PRI_FG_MIN_NP && sys_priority <= PRI_FG_MAX_NP) ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; ++ if (sys_priority >= PRI_BG_MIN_NP && sys_priority <= PRI_BG_MAX_NP) ++ return OBJC_THREAD_BACKGROUND_PRIORITY; ++ return OBJC_THREAD_LOW_PRIORITY; ++ } ++ #endif ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ pthread_yield(); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ pthread_exit(&__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * -1 which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ pthread_t self = pthread_self(); ++ ++ return (objc_thread_t) self; /* Return thread handle. */ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ if (pthread_setspecific(__objc_thread_data_key, (void *)value) == 0) ++ return 0; /* Return thread data. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return pthread_getspecific(__objc_thread_data_key); ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if ++ * the allocation fails for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ err = pthread_mutex_init(&mutex->lock, NULL); ++ ++ if (err != 0) { /* System init failed? */ ++ objc_free(mutex); /* Yes, free local memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ pthread_mutex_unlock(&mutex->lock); /* Must unlock system mutex.*/ ++ pthread_mutex_destroy(&mutex->lock); /* Free system mutex. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (pthread_mutex_lock(&mutex->lock) != 0) /* Lock DCE system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (pthread_mutex_trylock(&mutex->lock) != 1) /* Lock DCE system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ if (pthread_mutex_unlock(&mutex->lock) != 0) /* Unlock system mutex. */ ++ return -1; /* Failed, abort. */ ++ ++ return 0; /* No, return success. */ ++ } +diff -rcP gcc-2.7.2.1/objc/thr-pthreads.c gcc-2.7.2.1-objc-960906/objc/thr-pthreads.c +*** gcc-2.7.2.1/objc/thr-pthreads.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-pthreads.c Fri Sep 6 10:33:37 1996 +*************** +*** 0 **** +--- 1,422 ---- ++ /* GNU Objective C Runtime Thread Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ ++ This implementation is for the PCThreads package under Linux. ++ ++ Author: Scott Christley ++ Condition functions added by: Mircea Oancea ++ ++ 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 ++ #include ++ #include "runtime.h" ++ ++ /* Key structure for maintiain thread specific storage */ ++ static pthread_key_t _objc_thread_storage; ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ pthread_mutex_t mutex; /* PCThread mutex */ ++ }; ++ ++ struct objc_condition ++ { ++ pthread_cond_t condition; /* cthread condition */ ++ }; ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ /* Initialize the thread storage key */ ++ return pthread_key_create(&_objc_thread_storage, NULL); ++ } ++ ++ /******** ++ * Finalize the threads subsystem. Returns 0 if successful, or -1 if not ++ */ ++ int ++ __objc_fini_thread_system(void) ++ { ++ /* Destroy the thread storage key */ ++ /* Not implemented yet */ ++ /* return pthread_key_delete(&_objc_thread_storage); */ ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id; ++ pthread_t new_thread_handle; ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) ) ++ { ++ thread_id = *(objc_thread_t *)&new_thread_handle; ++ __objc_runtime_threads_alive++; ++ } ++ else ++ thread_id = NULL; ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ /* Not implemented yet */ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ /* Not implemented yet */ ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; /* Highest priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ pthread_yield(NULL); ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ pthread_exit(&__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * NULL which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ pthread_t self = pthread_self(); ++ ++ return *(objc_thread_t *)&self; /* Return thread handle. */ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ return pthread_setspecific(_objc_thread_storage, value); ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ void *value = NULL; ++ ++ if ( !(pthread_getspecific(_objc_thread_storage, &value)) ) ++ return value; ++ ++ return NULL; ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if the ++ * allocation failed for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ /* Create PCThread mutex */ ++ if ( pthread_mutex_init(&(mutex->mutex), NULL) ) ++ { ++ /* Failed */ ++ objc_free(mutex); ++ return NULL; ++ } ++ ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallocate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ /* Destroy PCThread mutex */ ++ pthread_mutex_destroy(&(mutex->mutex)); ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ int status; ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ { ++ return ++mutex->depth; /* Yes, increment depth. */ ++ } ++ ++ /* Lock the PCThread mutex */ ++ status = pthread_mutex_lock(&(mutex->mutex)); ++ if (status) ++ { ++ return status; /* Failed */ ++ } ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ int status; ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ /* Lock the PCThread mutex */ ++ status = pthread_mutex_trylock(&(mutex->mutex)); ++ if (status) ++ return status; /* Failed */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ int status; ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ /* Unlock the PCThread mutex */ ++ status = pthread_mutex_unlock(&(mutex->mutex)); ++ if (status) ++ return status; /* Failed */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /******** ++ * Allocate a condition. Return the condition pointer if successful or NULL ++ * if the allocation failed for any reason. ++ */ ++ objc_condition_t ++ objc_condition_allocate(void) ++ { ++ objc_condition_t condition; ++ ++ if (!(condition = (objc_condition_t)objc_malloc( ++ sizeof(struct objc_condition)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ if ( pthread_cond_init(&(condition->condition), NULL) ) { ++ objc_free(condition); ++ return NULL; ++ } ++ ++ return condition; /* Return condition handle. */ ++ } ++ ++ /******** ++ * Deallocate a condition. Note that this includes an implicit ++ * condition_broadcast to insure that waiting threads have the opportunity ++ * to wake. It is legal to dealloc a condition only if no other ++ * thread is/will be using it. Here we do NOT check for other threads ++ * waiting but just wake them up. ++ */ ++ int ++ objc_condition_deallocate(objc_condition_t condition) ++ { ++ pthread_cond_broadcast(&(condition->condition)); ++ pthread_cond_destroy(&(condition->condition)); ++ objc_free(condition); ++ return 0; ++ } ++ ++ /******** ++ * Wait on the condition unlocking the mutex until objc_condition_signal() ++ * or objc_condition_broadcast() are called for the same condition. The ++ * given mutex *must* have the depth set to 1 so that it can be unlocked ++ * here, so that someone else can lock it and signal/broadcast the condition. ++ * The mutex is used to lock access to the shared data that make up the ++ * "condition" predicate. ++ */ ++ int ++ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex || !condition) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Locked more than once ? */ ++ return -1; /* YES, return error */ ++ /* mutex will be unlocked */ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/ ++ ++ pthread_cond_wait(&(condition->condition), ++ &(mutex->mutex)); /* unlock, wait ..., lock */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ mutex->depth = 1; /* Increment depth to end. */ ++ return 0; /* Return success. */ ++ } ++ ++ /******** ++ * Wake up all threads waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_broadcast(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ pthread_cond_broadcast(&(condition->condition)); ++ return 0; ++ } ++ ++ /******** ++ * Wake up one thread waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_signal(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ pthread_cond_signal(&(condition->condition)); ++ return 0; ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2.1/objc/thr-single.c gcc-2.7.2.1-objc-960906/objc/thr-single.c +*** gcc-2.7.2.1/objc/thr-single.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-single.c Fri Sep 6 10:33:37 1996 +*************** +*** 0 **** +--- 1,240 ---- ++ /* GNU Objective C Runtime Thread Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */ ++ ++ /* 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 ++ #include "runtime.h" ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ }; ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ DEBUG_PRINTF("__objc_init_thread_system\n"); ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ return NULL; /* We can't start threads. */ ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; /* Highest priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ return; ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ exit(__objc_thread_exit_status); ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * NULL which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ return (objc_thread_t)1; /* No thread support, use 1.*/ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ ++ static void *thread_local_storage = NULL; ++ ++ int ++ objc_thread_set_data(void *value) ++ { ++ thread_local_storage = value; ++ return 0; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return thread_local_storage; ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if the ++ * allocation failed for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallocate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2.1/objc/thr-solaris.c gcc-2.7.2.1-objc-960906/objc/thr-solaris.c +*** gcc-2.7.2.1/objc/thr-solaris.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-solaris.c Fri Sep 6 10:33:37 1996 +*************** +*** 0 **** +--- 1,431 ---- ++ /* GNU Objective C Runtime Thread Interface ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.edu) ++ Conditions added by Mircea Oancea (mircea@first.elcom.pub.ro) ++ ++ 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 ++ #include "runtime.h" ++ ++ #include ++ #include ++ #include ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ mutex_t lock; /* System mutex. */ ++ }; ++ ++ struct objc_condition ++ { ++ cond_t condition; /* solaris condition */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ static thread_key_t __objc_thread_data_key; /* Data key for thread data.*/ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ DEBUG_PRINTF("__objc_init_thread_system\n"); ++ ++ if (thr_keycreate(&__objc_thread_data_key, NULL) == 0) ++ return 0; /* Yes, return success. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ return 0; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return -1 if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ objc_thread_t thread_id = NULL; /* Detached thread id. */ ++ thread_t new_thread_id = 0; /* Solaris thread id type. */ ++ int errn; ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ if (thr_create(NULL, 0, (void *)func, arg, ++ THR_DETACHED | THR_NEW_LWP, ++ &new_thread_id) == 0) { /* Created new thread? */ ++ thread_id = (objc_thread_t)new_thread_id; /* Yes, remember its id. */ ++ __objc_runtime_threads_alive++; ++ } ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ return thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ int sys_priority = 0; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_priority = 300; ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_priority = 200; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_priority = 1000; ++ break; ++ } ++ ++ if (thr_setprio(thr_self(), sys_priority) == 0) ++ return 0; /* Changed priority. End. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ int sys_priority; /* Solaris thread priority. */ ++ ++ if (thr_getprio(thr_self(), &sys_priority) == 0) { ++ if (sys_priority >= 250) ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; ++ else if (sys_priority >= 150) ++ return OBJC_THREAD_BACKGROUND_PRIORITY; ++ return OBJC_THREAD_LOW_PRIORITY; ++ } ++ ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ thr_yield(); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive++; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ thr_exit(&__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * NULL which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ return (objc_thread_t)thr_self(); ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ if (thr_setspecific(__objc_thread_data_key, value) == 0) ++ return 0; ++ return -1; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ void * value = NULL; ++ ++ if (thr_getspecific(__objc_thread_data_key, &value) == 0) ++ return value; /* Return thread data. */ ++ ++ return NULL; ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if ++ * the allocation fails for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ struct objc_mutex *mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ err = mutex_init(&mutex->lock, USYNC_THREAD, 0); ++ ++ if (err != 0) { /* System init failed? */ ++ objc_free(mutex); /* Yes, free local memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ mutex_destroy(&mutex->lock); /* System deallocate. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (mutex_lock(&mutex->lock) != 0) /* Did lock acquire fail? */ ++ return -1; /* Yes, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ if (mutex_trylock(&mutex->lock) != 0) /* Did lock acquire fail? */ ++ return -1; /* Yes, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return mutex->depth = 1; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ if (mutex_unlock(&mutex->lock) != 0) /* Did lock release fail? */ ++ return -1; /* Yes, return error value. */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /******** ++ * Allocate a condition. Return the condition pointer if successful or NULL ++ * if the allocation failed for any reason. ++ */ ++ objc_condition_t ++ objc_condition_allocate(void) ++ { ++ objc_condition_t condition; ++ ++ if (!(condition = (objc_condition_t)objc_malloc( ++ sizeof(struct objc_condition)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ cond_init(&(condition->condition), USYNC_THREAD, NULL); ++ ++ return condition; /* Return new condition */ ++ } ++ ++ /******** ++ * Deallocate a condition. Note that this includes an implicit ++ * condition_broadcast to insure that waiting threads have the opportunity ++ * to wake. It is legal to dealloc a condition only if no other ++ * thread is/will be using it. Here we do NOT check for other threads ++ * waiting but just wake them up. ++ */ ++ int ++ objc_condition_deallocate(objc_condition_t condition) ++ { ++ cond_broadcast(&(condition->condition)); /* Wakeup waiting threads */ ++ cond_destroy(&(condition->condition)); /* Kill condition */ ++ objc_free(condition); /* Release struct memory */ ++ return 0; ++ } ++ ++ /******** ++ * Wait on the condition unlocking the mutex until objc_condition_signal() ++ * or objc_condition_broadcast() are called for the same condition. The ++ * given mutex *must* have the depth set to 1 so that it can be unlocked ++ * here, so that someone else can lock it and signal/broadcast the condition. ++ * The mutex is used to lock access to the shared data that make up the ++ * "condition" predicate. ++ */ ++ int ++ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex || !condition) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Locked more than once ? */ ++ return -1; /* YES, return error */ ++ /* mutex will be unlocked */ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/ ++ ++ cond_wait(&(condition->condition), ++ &(mutex->lock)); /* unlock, wait ..., lock */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ mutex->depth = 1; /* Must be here ! */ ++ ++ return 0; /* Return success. */ ++ } ++ ++ /******** ++ * Wake up all threads waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_broadcast(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ cond_broadcast(&(condition->condition)); ++ return 0; ++ } ++ ++ /******** ++ * Wake up one thread waiting on this condition. It is recommended that ++ * the called would lock the same mutex as the threads in objc_condition_wait ++ * before changing the "condition predicate" and make this call and unlock it ++ * right away after this call. ++ */ ++ int ++ objc_condition_signal(objc_condition_t condition) ++ { ++ if (!condition) ++ return -1; ++ cond_signal(&(condition->condition)); ++ return 0; ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2.1/objc/thr-win32.c gcc-2.7.2.1-objc-960906/objc/thr-win32.c +*** gcc-2.7.2.1/objc/thr-win32.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr-win32.c Fri Sep 6 10:33:38 1996 +*************** +*** 0 **** +--- 1,337 ---- ++ /* GNU Objective C Runtime Thread Interface - Win32 Implementation ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */ ++ ++ /* 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 ++ #include "runtime.h" ++ ++ #ifndef __OBJC__ ++ #define __OBJC__ ++ #endif ++ #include ++ ++ /******** ++ * This structure represents a single mutual exclusion lock. Lock semantics ++ * are detailed with the subsequent functions. We use whatever lock is ++ * provided by the system. We augment it with depth and current owner id ++ * fields to implement and re-entrant lock. ++ */ ++ struct objc_mutex ++ { ++ volatile objc_thread_t owner; /* Id of thread that owns. */ ++ volatile int depth; /* # of acquires. */ ++ HANDLE handle; /* Win32 mutex HANDLE. */ ++ }; ++ ++ /***************************************************************************** ++ * Static variables. ++ */ ++ static DWORD __objc_data_tls = (DWORD)-1; /* Win32 Thread Local Index.*/ ++ ++ /******** ++ * Initialize the threads subsystem. Returns 0 if successful, or -1 if no ++ * thread support is available. ++ */ ++ int ++ __objc_init_thread_system(void) ++ { ++ DEBUG_PRINTF("__objc_init_thread_system\n"); ++ ++ if ((__objc_data_tls = TlsAlloc()) != (DWORD)-1) ++ return 0; /* Yes, return success. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ int ++ __objc_fini_thread_system(void) ++ { ++ if (__objc_data_tls != (DWORD)-1) { ++ TlsFree(__objc_data_tls); ++ return 0; ++ } ++ return -1; ++ } ++ ++ /******** ++ * Create a new thread of execution and return its id. Return NULL if fails. ++ * The new thread starts in "func" with the given argument. ++ */ ++ objc_thread_t ++ objc_thread_create(void (*func)(void *arg), void *arg) ++ { ++ DWORD thread_id = 0; /* Detached thread id. */ ++ HANDLE win32_handle; /* Win32 thread handle. */ ++ ++ objc_mutex_lock(__objc_runtime_mutex); ++ ++ if ((win32_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, ++ arg, 0, &thread_id))) { ++ __objc_runtime_threads_alive++; ++ } ++ else ++ thread_id = 0; ++ ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ return (objc_thread_t)thread_id; ++ } ++ ++ /******** ++ * Set the current thread's priority. ++ */ ++ int ++ objc_thread_set_priority(int priority) ++ { ++ int sys_priority = 0; ++ ++ switch (priority) { ++ case OBJC_THREAD_INTERACTIVE_PRIORITY: ++ sys_priority = THREAD_PRIORITY_NORMAL; ++ break; ++ default: ++ case OBJC_THREAD_BACKGROUND_PRIORITY: ++ sys_priority = THREAD_PRIORITY_BELOW_NORMAL; ++ break; ++ case OBJC_THREAD_LOW_PRIORITY: ++ sys_priority = THREAD_PRIORITY_LOWEST; ++ break; ++ } ++ if (SetThreadPriority(GetCurrentThread(), sys_priority)) ++ return 0; /* Changed priority. End. */ ++ ++ return -1; /* Failed. */ ++ } ++ ++ /******** ++ * Return the current thread's priority. ++ */ ++ int ++ objc_thread_get_priority(void) ++ { ++ int sys_priority; ++ ++ sys_priority = GetThreadPriority(GetCurrentThread()); ++ ++ switch (sys_priority) { ++ case THREAD_PRIORITY_HIGHEST: ++ case THREAD_PRIORITY_TIME_CRITICAL: ++ case THREAD_PRIORITY_ABOVE_NORMAL: ++ case THREAD_PRIORITY_NORMAL: ++ return OBJC_THREAD_INTERACTIVE_PRIORITY; ++ ++ default: ++ case THREAD_PRIORITY_BELOW_NORMAL: ++ return OBJC_THREAD_BACKGROUND_PRIORITY; ++ ++ case THREAD_PRIORITY_IDLE: ++ case THREAD_PRIORITY_LOWEST: ++ return OBJC_THREAD_LOW_PRIORITY; ++ } ++ return -1; /* Couldn't get priority. */ ++ } ++ ++ /******** ++ * Yield our process time to another thread. Any BUSY waiting that is done ++ * by a thread should use this function to make sure that other threads can ++ * make progress even on a lazy uniprocessor system. ++ */ ++ void ++ objc_thread_yield(void) ++ { ++ Sleep(0); /* Yield to equal thread. */ ++ } ++ ++ /******** ++ * Terminate the current tread. Doesn't return anything. Doesn't return. ++ * Actually, if it failed returns -1. ++ */ ++ int ++ objc_thread_exit(void) ++ { ++ objc_mutex_lock(__objc_runtime_mutex); ++ __objc_runtime_threads_alive--; ++ objc_mutex_unlock(__objc_runtime_mutex); ++ ++ ExitThread(__objc_thread_exit_status); /* Terminate thread. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns an integer value which uniquely describes a thread. Must not be ++ * -1 which is reserved as a marker for "no thread". ++ */ ++ objc_thread_t ++ objc_thread_id(void) ++ { ++ return (objc_thread_t)GetCurrentThreadId(); /* Return thread id. */ ++ } ++ ++ /******** ++ * Sets the thread's local storage pointer. Returns 0 if successful or -1 ++ * if failed. ++ */ ++ int ++ objc_thread_set_data(void *value) ++ { ++ if (TlsSetValue(__objc_data_tls, value)) ++ return 0; /* Return thread data. */ ++ return -1; ++ } ++ ++ /******** ++ * Returns the thread's local storage pointer. Returns NULL on failure. ++ */ ++ void * ++ objc_thread_get_data(void) ++ { ++ return TlsGetValue(__objc_data_tls); /* Return thread data. */ ++ } ++ ++ /******** ++ * Allocate a mutex. Return the mutex pointer if successful or NULL if ++ * the allocation fails for any reason. ++ */ ++ objc_mutex_t ++ objc_mutex_allocate(void) ++ { ++ objc_mutex_t mutex; ++ int err = 0; ++ ++ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) ++ return NULL; /* Abort if malloc failed. */ ++ ++ if ((mutex->handle = CreateMutex(NULL, 0, NULL)) == NULL) { ++ objc_free(mutex); /* Failed, free memory. */ ++ return NULL; /* Abort. */ ++ } ++ mutex->owner = NULL; /* No owner. */ ++ mutex->depth = 0; /* No locks. */ ++ return mutex; /* Return mutex handle. */ ++ } ++ ++ /******** ++ * Deallocate a mutex. Note that this includes an implicit mutex_lock to ++ * insure that no one else is using the lock. It is legal to deallocate ++ * a lock if we have a lock on it, but illegal to deallotcate a lock held ++ * by anyone else. ++ * Returns the number of locks on the thread. (1 for deallocate). ++ */ ++ int ++ objc_mutex_deallocate(objc_mutex_t mutex) ++ { ++ int depth; /* # of locks on mutex. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ depth = objc_mutex_lock(mutex); /* Must have lock. */ ++ ++ CloseHandle(mutex->handle); /* Close Win32 handle. */ ++ ++ objc_free(mutex); /* Free memory. */ ++ return depth; /* Return last depth. */ ++ } ++ ++ /******** ++ * Grab a lock on a mutex. If this thread already has a lock on this mutex ++ * then we increment the lock count. If another thread has a lock on the ++ * mutex we block and wait for the thread to release the lock. ++ * Returns the lock count on the mutex held by this thread. ++ */ ++ int ++ objc_mutex_lock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ int status; ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ status = WaitForSingleObject(mutex->handle, INFINITE); ++ if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED) ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ ++ return ++mutex->depth; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Try to grab a lock on a mutex. If this thread already has a lock on ++ * this mutex then we increment the lock count and return it. If another ++ * thread has a lock on the mutex returns -1. ++ */ ++ int ++ objc_mutex_trylock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ DWORD status; /* Return status from Win32.*/ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner == thread_id) /* Already own lock? */ ++ return ++mutex->depth; /* Yes, increment depth. */ ++ ++ status = WaitForSingleObject(mutex->handle, 0); ++ if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED) ++ return -1; /* Failed, abort. */ ++ ++ mutex->owner = thread_id; /* Mark thread as owner. */ ++ return ++mutex->depth; /* Increment depth to end. */ ++ } ++ ++ /******** ++ * Decrements the lock count on this mutex by one. If the lock count reaches ++ * zero, release the lock on the mutex. Returns the lock count on the mutex. ++ * It is an error to attempt to unlock a mutex which this thread doesn't hold ++ * in which case return -1 and the mutex is unaffected. ++ * Will also return -1 if the mutex free fails. ++ */ ++ int ++ objc_mutex_unlock(objc_mutex_t mutex) ++ { ++ objc_thread_t thread_id; /* Cache our thread id. */ ++ ++ if (!mutex) /* Is argument bad? */ ++ return -1; /* Yes, abort. */ ++ thread_id = objc_thread_id(); /* Get this thread's id. */ ++ if (mutex->owner != thread_id) /* Does some else own lock? */ ++ return -1; /* Yes, abort. */ ++ if (mutex->depth > 1) /* Released last lock? */ ++ return --mutex->depth; /* No, Decrement depth, end.*/ ++ mutex->depth = 0; /* Yes, reset depth to 0. */ ++ mutex->owner = NULL; /* Set owner to "no thread".*/ ++ ++ if (ReleaseMutex(mutex->handle) == 0) ++ return -1; /* Failed, abort. */ ++ ++ return 0; /* No, return success. */ ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2.1/objc/thr.c gcc-2.7.2.1-objc-960906/objc/thr.c +*** gcc-2.7.2.1/objc/thr.c Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr.c Fri Sep 6 10:33:38 1996 +*************** +*** 0 **** +--- 1,153 ---- ++ /* GNU Objective C Runtime Thread Interface ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. */ ++ ++ /* 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 ++ #include "runtime.h" ++ ++ /************************************************************************* ++ * Universal static variables: ++ */ ++ int __objc_thread_exit_status = 0; /* Global exit status. */ ++ ++ /* Flag which lets us know if we ever became multi threaded */ ++ int __objc_is_multi_threaded = 0; ++ /* The hook function called when the runtime becomes multi threaded */ ++ objc_thread_callback _objc_became_multi_threaded = NULL; ++ ++ /***************************************************************************** ++ * Universal Functionality ++ */ ++ ++ /* ++ Use this to set the hook function that will be called when the ++ runtime initially becomes multi threaded. ++ The hook function is only called once, meaning only when the ++ 2nd thread is spawned, not for each and every thread. ++ ++ It returns the previous hook function or NULL if there is none. ++ ++ A program outside of the runtime could set this to some function so ++ it can be informed; for example, the GNUstep Base Library sets it ++ so it can implement the NSBecomingMultiThreaded notification. ++ */ ++ objc_thread_callback objc_set_thread_callback(objc_thread_callback func) ++ { ++ objc_thread_callback temp = _objc_became_multi_threaded; ++ _objc_became_multi_threaded = func; ++ return temp; ++ } ++ ++ /******** ++ * First function called in a thread, starts everything else. ++ */ ++ struct __objc_thread_start_state ++ { ++ SEL selector; ++ id object; ++ id argument; ++ }; ++ ++ static volatile void ++ __objc_thread_detach_function(struct __objc_thread_start_state *istate) ++ { ++ if (istate) { /* Is state valid? */ ++ id (*imp)(id,SEL,id); ++ SEL selector = istate->selector; ++ id object = istate->object; ++ id argument = istate->argument; ++ ++ objc_free(istate); ++ ++ /* Clear out the thread local storage */ ++ objc_thread_set_data(NULL); ++ ++ /* Check to see if we just became multi threaded */ ++ if (!__objc_is_multi_threaded) { ++ __objc_is_multi_threaded = 1; ++ ++ /* Call the hook function */ ++ if (_objc_became_multi_threaded != NULL) ++ (*_objc_became_multi_threaded)(); ++ } ++ ++ if ((imp = (id(*)(id, SEL, id))objc_msg_lookup(object, selector))) { ++ (*imp)(object, selector, argument); ++ } ++ else ++ fprintf(stderr, "__objc_thread_start called with bad selector.\n"); ++ } ++ else { ++ fprintf(stderr, "__objc_thread_start called with NULL state.\n"); ++ } ++ objc_thread_exit(); ++ } ++ ++ /******** ++ * Detach a new thread of execution and return its id. Returns NULL if fails. ++ * Thread is started by sending message with selector to object. Message ++ * takes a single argument. ++ */ ++ objc_thread_t ++ objc_thread_detach(SEL selector, id object, id argument) ++ { ++ struct __objc_thread_start_state *istate; /* Initialial thread state. */ ++ objc_thread_t thread_id = NULL; /* Detached thread id. */ ++ ++ if (!(istate = (struct __objc_thread_start_state *) ++ objc_malloc(sizeof(*istate)))) /* Can we allocate state? */ ++ return NULL; /* No, abort. */ ++ ++ istate->selector = selector; /* Initialize the thread's */ ++ istate->object = object; /* state structure. */ ++ istate->argument = argument; ++ ++ if ((thread_id = objc_thread_create((void *)__objc_thread_detach_function, ++ istate)) == NULL) { ++ objc_free(istate); /* Release state if failed. */ ++ return thread_id; ++ } ++ ++ return thread_id; ++ } ++ ++ #undef objc_mutex_lock() ++ #undef objc_mutex_unlock() ++ ++ int ++ objc_mutex_unlock_x(objc_mutex_t mutex, const char *f, int l) ++ { ++ printf("%16.16s#%4d < unlock", f, l); ++ return objc_mutex_unlock(mutex); ++ } ++ ++ int ++ objc_mutex_lock_x(objc_mutex_t mutex, const char *f, int l) ++ { ++ printf("%16.16s#%4d < lock", f, l); ++ return objc_mutex_lock(mutex); ++ } ++ ++ /* End of File */ +diff -rcP gcc-2.7.2.1/objc/thr.h gcc-2.7.2.1-objc-960906/objc/thr.h +*** gcc-2.7.2.1/objc/thr.h Wed Dec 31 19:00:00 1969 +--- gcc-2.7.2.1-objc-960906/objc/thr.h Fri Sep 6 10:33:38 1996 +*************** +*** 0 **** +--- 1,104 ---- ++ /* Thread and mutex controls for Objective C. ++ Copyright (C) 1996 Free Software Foundation, Inc. ++ Contributed by Galen C. Hunt (gchunt@cs.rochester.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. ++ ++ 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 __thread_INCLUDE_GNU ++ #define __thread_INCLUDE_GNU ++ ++ #include "objc/objc.h" ++ ++ /************************************************************************* ++ * Universal static variables: ++ */ ++ extern int __objc_thread_exit_status; /* Global exit status. */ ++ ++ /******** ++ * Thread safe implementation types and functions. ++ */ ++ ++ #define OBJC_THREAD_INTERACTIVE_PRIORITY 2 ++ #define OBJC_THREAD_BACKGROUND_PRIORITY 1 ++ #define OBJC_THREAD_LOW_PRIORITY 0 ++ ++ typedef void * objc_thread_t; ++ typedef struct objc_mutex *objc_mutex_t; ++ typedef struct objc_condition *objc_condition_t; ++ ++ objc_mutex_t objc_mutex_allocate(void); ++ int objc_mutex_deallocate(objc_mutex_t mutex); ++ int objc_mutex_lock(objc_mutex_t mutex); ++ int objc_mutex_unlock(objc_mutex_t mutex); ++ int objc_mutex_trylock(objc_mutex_t mutex); ++ ++ objc_condition_t objc_condition_allocate(void); ++ int objc_condition_deallocate(objc_condition_t condition); ++ int objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex); ++ int objc_condition_signal(objc_condition_t condition); ++ int objc_condition_broadcast(objc_condition_t condition); ++ ++ objc_thread_t objc_thread_create(void (*func)(void *arg), void *arg); ++ void objc_thread_yield(void); ++ int objc_thread_exit(void); ++ int objc_thread_set_priority(int priority); ++ int objc_thread_get_priority(void); ++ void * objc_thread_get_data(void); ++ int objc_thread_set_data(void *value); ++ objc_thread_t objc_thread_id(void); ++ ++ objc_thread_t objc_thread_detach(SEL selector, id object, id argument); ++ int objc_mutex_lock_x(objc_mutex_t mutex, const char *f, int l); ++ int objc_mutex_unlock_x(objc_mutex_t mutex, const char *f, int l); ++ ++ /* ++ Use this to set the hook function that will be called when the ++ runtime initially becomes multi threaded. ++ The hook function is only called once, meaning only when the ++ 2nd thread is spawned, not for each and every thread. ++ ++ It returns the previous hook function or NULL if there is none. ++ ++ A program outside of the runtime could set this to some function so ++ it can be informed; for example, the GNUstep Base Library sets it ++ so it can implement the NSBecomingMultiThreaded notification. ++ */ ++ typedef void (*objc_thread_callback)(); ++ objc_thread_callback objc_set_thread_callback(objc_thread_callback func); ++ ++ /* For debugging of locks, uncomment these two macros: */ ++ /* #define objc_mutex_lock(x) objc_mutex_lock_x(x, __FILE__, __LINE__) */ ++ /* #define objc_mutex_unlock(x) objc_mutex_unlock_x(x, __FILE__, __LINE__)*/ ++ ++ #endif /* not __thread_INCLUDE_GNU */ +diff -rcP gcc-2.7.2.1/objc-act.c gcc-2.7.2.1-objc-960906/objc-act.c +*** gcc-2.7.2.1/objc-act.c Fri Sep 6 11:22:22 1996 +--- gcc-2.7.2.1-objc-960906/objc-act.c Fri Sep 6 10:27:04 1996 +*************** +*** 6448,6453 **** +--- 6448,6569 ---- + } + + static void ++ encode_aggregate_within (type, curtype, format, left, right) ++ tree type; ++ int curtype; ++ int format; ++ char left; ++ char right; ++ { ++ if (obstack_object_size (&util_obstack) > 0 ++ && *(obstack_next_free (&util_obstack) - 1) == '^') ++ { ++ tree name = TYPE_NAME (type); ++ ++ /* we have a reference; this is a NeXT extension. */ ++ ++ if (obstack_object_size (&util_obstack) - curtype == 1 ++ && format == OBJC_ENCODE_INLINE_DEFS) ++ { ++ /* Output format of struct for first level only. */ ++ tree fields = TYPE_FIELDS (type); ++ ++ if (name && TREE_CODE (name) == IDENTIFIER_NODE) ++ { ++ obstack_1grow (&util_obstack, left); ++ obstack_grow (&util_obstack, ++ IDENTIFIER_POINTER (name), ++ strlen (IDENTIFIER_POINTER (name))); ++ obstack_1grow (&util_obstack, '='); ++ } ++ else ++ { ++ obstack_1grow (&util_obstack, left); ++ obstack_grow (&util_obstack, "?=", 2); ++ } ++ ++ for ( ; fields; fields = TREE_CHAIN (fields)) ++ encode_field_decl (fields, curtype, format); ++ ++ obstack_1grow (&util_obstack, right); ++ } ++ ++ else if (name && TREE_CODE (name) == IDENTIFIER_NODE) ++ { ++ obstack_1grow (&util_obstack, left); ++ obstack_grow (&util_obstack, ++ IDENTIFIER_POINTER (name), ++ strlen (IDENTIFIER_POINTER (name))); ++ obstack_1grow (&util_obstack, right); ++ } ++ ++ else ++ { ++ /* We have an untagged structure or a typedef. */ ++ obstack_1grow (&util_obstack, left); ++ obstack_1grow (&util_obstack, '?'); ++ obstack_1grow (&util_obstack, right); ++ } ++ } ++ ++ else ++ { ++ tree name = TYPE_NAME (type); ++ tree fields = TYPE_FIELDS (type); ++ ++ if (format == OBJC_ENCODE_INLINE_DEFS ++ || generating_instance_variables) ++ { ++ obstack_1grow (&util_obstack, left); ++ if (name && TREE_CODE (name) == IDENTIFIER_NODE) ++ obstack_grow (&util_obstack, ++ IDENTIFIER_POINTER (name), ++ strlen (IDENTIFIER_POINTER (name))); ++ else ++ obstack_1grow (&util_obstack, '?'); ++ ++ obstack_1grow (&util_obstack, '='); ++ ++ for (; fields; fields = TREE_CHAIN (fields)) ++ { ++ if (generating_instance_variables) ++ { ++ tree fname = DECL_NAME (fields); ++ ++ obstack_1grow (&util_obstack, '"'); ++ if (fname && TREE_CODE (fname) == IDENTIFIER_NODE) ++ { ++ obstack_grow (&util_obstack, ++ IDENTIFIER_POINTER (fname), ++ strlen (IDENTIFIER_POINTER (fname))); ++ } ++ ++ obstack_1grow (&util_obstack, '"'); ++ } ++ ++ encode_field_decl (fields, curtype, format); ++ } ++ ++ obstack_1grow (&util_obstack, right); ++ } ++ ++ else ++ { ++ obstack_1grow (&util_obstack, left); ++ if (name && TREE_CODE (name) == IDENTIFIER_NODE) ++ obstack_grow (&util_obstack, ++ IDENTIFIER_POINTER (name), ++ strlen (IDENTIFIER_POINTER (name))); ++ else ++ /* We have an untagged structure or a typedef. */ ++ obstack_1grow (&util_obstack, '?'); ++ ++ obstack_1grow (&util_obstack, right); ++ } ++ } ++ } ++ ++ static void + encode_aggregate (type, curtype, format) + tree type; + int curtype; +*************** +*** 6459,6598 **** + { + case RECORD_TYPE: + { +! if (obstack_object_size (&util_obstack) > 0 +! && *(obstack_next_free (&util_obstack) - 1) == '^') +! { +! tree name = TYPE_NAME (type); +! +! /* We have a reference; this is a NeXT extension. */ +! +! if (obstack_object_size (&util_obstack) - curtype == 1 +! && format == OBJC_ENCODE_INLINE_DEFS) +! { +! /* Output format of struct for first level only. */ +! tree fields = TYPE_FIELDS (type); +! +! if (name && TREE_CODE (name) == IDENTIFIER_NODE) +! { +! obstack_1grow (&util_obstack, '{'); +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (name), +! strlen (IDENTIFIER_POINTER (name))); +! obstack_1grow (&util_obstack, '='); +! } +! +! else +! obstack_grow (&util_obstack, "{?=", 3); +! +! for ( ; fields; fields = TREE_CHAIN (fields)) +! encode_field_decl (fields, curtype, format); +! +! obstack_1grow (&util_obstack, '}'); +! } +! +! else if (name && TREE_CODE (name) == IDENTIFIER_NODE) +! { +! obstack_1grow (&util_obstack, '{'); +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (name), +! strlen (IDENTIFIER_POINTER (name))); +! obstack_1grow (&util_obstack, '}'); +! } +! +! else +! /* We have an untagged structure or a typedef. */ +! obstack_grow (&util_obstack, "{?}", 3); +! } +! +! else +! { +! tree name = TYPE_NAME (type); +! tree fields = TYPE_FIELDS (type); +! +! if (format == OBJC_ENCODE_INLINE_DEFS +! || generating_instance_variables) +! { +! obstack_1grow (&util_obstack, '{'); +! if (name && TREE_CODE (name) == IDENTIFIER_NODE) +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (name), +! strlen (IDENTIFIER_POINTER (name))); +! +! else +! obstack_1grow (&util_obstack, '?'); +! +! obstack_1grow (&util_obstack, '='); +! +! for (; fields; fields = TREE_CHAIN (fields)) +! { +! if (generating_instance_variables) +! { +! tree fname = DECL_NAME (fields); +! +! obstack_1grow (&util_obstack, '"'); +! if (fname && TREE_CODE (fname) == IDENTIFIER_NODE) +! { +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (fname), +! strlen (IDENTIFIER_POINTER (fname))); +! } +! +! obstack_1grow (&util_obstack, '"'); +! } +! +! encode_field_decl (fields, curtype, format); +! } +! +! obstack_1grow (&util_obstack, '}'); +! } +! +! else +! { +! obstack_1grow (&util_obstack, '{'); +! if (name && TREE_CODE (name) == IDENTIFIER_NODE) +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (name), +! strlen (IDENTIFIER_POINTER (name))); +! else +! /* We have an untagged structure or a typedef. */ +! obstack_1grow (&util_obstack, '?'); +! +! obstack_1grow (&util_obstack, '}'); +! } +! } + break; + } +- + case UNION_TYPE: + { +! if (*obstack_next_free (&util_obstack) == '^' +! || format != OBJC_ENCODE_INLINE_DEFS) +! { +! /* We have a reference (this is a NeXT extension) +! or we don't want the details. */ +! if (TYPE_NAME (type) +! && TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) +! { +! obstack_1grow (&util_obstack, '('); +! obstack_grow (&util_obstack, +! IDENTIFIER_POINTER (TYPE_NAME (type)), +! strlen (IDENTIFIER_POINTER (TYPE_NAME (type)))); +! obstack_1grow (&util_obstack, ')'); +! } +! +! else +! /* We have an untagged structure or a typedef. */ +! obstack_grow (&util_obstack, "(?)", 3); +! } +! else +! { +! tree fields = TYPE_FIELDS (type); +! obstack_1grow (&util_obstack, '('); +! for ( ; fields; fields = TREE_CHAIN (fields)) +! encode_field_decl (fields, curtype, format); +! +! obstack_1grow (&util_obstack, ')'); +! } + break; + } + +--- 6575,6586 ---- + { + case RECORD_TYPE: + { +! encode_aggregate_within(type, curtype, format, '{', '}'); + break; + } + case UNION_TYPE: + { +! encode_aggregate_within(type, curtype, format, '(', ')'); + break; + } + +diff -rcP gcc-2.7.2.1/objc-parse.c gcc-2.7.2.1-objc-960906/objc-parse.c +*** gcc-2.7.2.1/objc-parse.c Fri Sep 6 11:22:25 1996 +--- gcc-2.7.2.1-objc-960906/objc-parse.c Fri Sep 6 10:27:06 1996 +*************** +*** 1,5 **** + +! /* A Bison parser, made from objc-parse.y with Bison version GNU Bison version 1.22 + */ + + #define YYBISON 1 /* Identify Bison output. */ +--- 1,5 ---- + +! /* A Bison parser, made from objc-parse.y with Bison version GNU Bison version 1.24 + */ + + #define YYBISON 1 /* Identify Bison output. */ +*************** +*** 495,501 **** + 2797, 2804, 2813 + }; + +! static const char * const yytname[] = { "$","error","$illegal.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT", + "BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ATTRIBUTE", +--- 495,501 ---- + 2797, 2804, 2813 + }; + +! static const char * const yytname[] = { "$","error","$undefined.","IDENTIFIER", + "TYPENAME","SCSPEC","TYPESPEC","TYPE_QUAL","CONSTANT","STRING","ELLIPSIS","SIZEOF", + "ENUM","STRUCT","UNION","IF","ELSE","WHILE","DO","FOR","SWITCH","CASE","DEFAULT", + "BREAK","CONTINUE","RETURN","GOTO","ASM_KEYWORD","TYPEOF","ALIGNOF","ATTRIBUTE", +*************** +*** 1586,1599 **** + 52 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/local/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman + + This program 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 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, +--- 1586,1599 ---- + 52 + }; + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +! #line 3 "/usr/lib/bison.simple" + + /* Skeleton output parser for bison, +! Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program 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. + + This program is distributed in the hope that it will be useful, +*************** +*** 1605,1610 **** +--- 1605,1614 ---- + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++ /* As a special exception, when this file is copied by Bison into a ++ Bison output file, you may use that output file without restriction. ++ This special exception was added by the Free Software Foundation ++ in version 1.24 of Bison. */ + + #ifndef alloca + #ifdef __GNUC__ +*************** +*** 1678,1687 **** +--- 1682,1699 ---- + + #ifdef YYPURE + #ifdef YYLSP_NEEDED ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) ++ #else + #define YYLEX yylex(&yylval, &yylloc) ++ #endif ++ #else /* not YYLSP_NEEDED */ ++ #ifdef YYLEX_PARAM ++ #define YYLEX yylex(&yylval, YYLEX_PARAM) + #else + #define YYLEX yylex(&yylval) + #endif ++ #endif /* not YYLSP_NEEDED */ + #endif + + /* If nonreentrant, generate the variables here */ +*************** +*** 1729,1742 **** + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (from, to, count) + char *from; + char *to; + int count; +--- 1741,1754 ---- + #endif + + #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +! #define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT) + #else /* not GNU C or C++ */ + #ifndef __cplusplus + + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (from, to, count) + char *from; + char *to; + int count; +*************** +*** 1754,1760 **** + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_bcopy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +--- 1766,1772 ---- + /* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ + static void +! __yy_memcpy (char *from, char *to, int count) + { + register char *f = from; + register char *t = to; +*************** +*** 1767,1773 **** + #endif + #endif + +! #line 184 "/usr/local/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +--- 1779,1785 ---- + #endif + #endif + +! #line 192 "/usr/lib/bison.simple" + + /* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. +*************** +*** 1900,1911 **** + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +--- 1912,1923 ---- + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); +! __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); +! __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); + #ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); +! __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + #endif + #endif /* no yyoverflow */ + +*************** +*** 4718,4724 **** + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 480 "/usr/local/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +--- 4730,4736 ---- + break;} + } + /* the action file gets copied in in place of this dollarsign */ +! #line 487 "/usr/lib/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +diff -rcP gcc-2.7.2.1/version.c gcc-2.7.2.1-objc-960906/version.c +*** gcc-2.7.2.1/version.c Fri Sep 6 11:23:19 1996 +--- gcc-2.7.2.1-objc-960906/version.c Fri Sep 6 10:27:59 1996 +*************** +*** 1 **** +! char *version_string = "2.7.2.1"; +--- 1 ---- +! char *version_string = "2.7.2.1 Objective-C snapshot 960906";