This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Objective-C garbage collector patch revised



I submit again the patch that adds support for the Boehm's garbage collector to
the Objective-C runtime. This version of the patch also contains some important
changes in the way the size and alignment of structures is computed. I made
this change in order to support Objective-C on AIX 4.1. The patch was tested on
i586-linux, sparc-solaris2 and powerpc-aix4.

Please let me know when/if it will go in.

Thanks,
Ovidiu

--
Ovidiu Predescu
Software Design Engineer
California Language Laboratory - Hewlett Packard


diff -rcP egcs/gcc/Makefile.in egcs-1.1-objc-gc/gcc/Makefile.in
*** egcs/gcc/Makefile.in	Fri Jul  3 12:41:38 1998
--- egcs-1.1-objc-gc/gcc/Makefile.in	Fri Jul  3 13:33:05 1998
***************
*** 244,249 ****
--- 244,250 ----
  lang_specs_files=@lang_specs_files@
  lang_options_files=@lang_options_files@
  GCC_THREAD_FILE=@thread_file@
+ OBJC_BOEHM_GC=@objc_boehm_gc@
  GTHREAD_FLAGS=@gthread_flags@
  # Be prepared for gcc2 merges.
  gcc_version=@gcc_version@
***************
*** 2559,2565 ****
  		-e '1,/^## All variables above are.*##/ d' >> site.exp
  	-@rm -f ./tmp?
  
! CHECK_TARGETS = check-gcc check-g++ check-g77
  
  check: $(CHECK_TARGETS)
  
--- 2560,2566 ----
  		-e '1,/^## All variables above are.*##/ d' >> site.exp
  	-@rm -f ./tmp?
  
! CHECK_TARGETS = check-gcc check-g++ check-g77 check-objc
  
  check: $(CHECK_TARGETS)
  
***************
*** 2601,2606 ****
--- 2602,2617 ----
  	   TCL_LIBRARY=$${srcdir}/../tcl/library ; \
  	   export TCL_LIBRARY ; fi ; \
  	$(RUNTEST) --tool g77 $(RUNTESTFLAGS)
+ 
+ check-objc: testsuite/site.exp
+ 	-rootme=`pwd`; export rootme; \
+ 	srcdir=`cd ${srcdir}; pwd` ; export srcdir ; \
+ 	cd testsuite; \
+ 	EXPECT=${EXPECT} ; export EXPECT ; \
+ 	if [ -f $${rootme}/../expect/expect ] ; then  \
+ 	   TCL_LIBRARY=$${srcdir}/../tcl/library ; \
+ 	    export TCL_LIBRARY ; fi ; \
+ 	$(RUNTEST) --tool objc $(RUNTESTFLAGS)
  
  # These exist for maintenance purposes.
  
diff -rcP egcs/gcc/configure.in egcs-1.1-objc-gc/gcc/configure.in
*** egcs/gcc/configure.in	Fri Jul  3 12:42:19 1998
--- egcs-1.1-objc-gc/gcc/configure.in	Fri Jul  3 13:33:51 1998
***************
*** 138,143 ****
--- 138,153 ----
  		;;
  esac
  
+ AC_ARG_ENABLE(objc-gc,
+ [  --enable-objc-gc	  enable the use of Boehm's garbage collector with
+ 			  the GNU Objective-C runtime.],
+ if [[[ x$enable_objc_gc = xno ]]]; then
+ 	objc_boehm_gc=''
+ else
+ 	objc_boehm_gc=1
+ fi,
+ objc_boehm_gc='')
+ 
  # Determine the host, build, and target systems
  AC_CANONICAL_SYSTEM
  
***************
*** 3577,3582 ****
--- 3587,3593 ----
  AC_SUBST(lang_specs_files)
  AC_SUBST(lang_options_files)
  AC_SUBST(thread_file)
+ AC_SUBST(objc_boehm_gc)
  AC_SUBST(gcc_version)
  AC_SUBST(gcc_version_trigger)
  AC_SUBST(local_prefix)
diff -rcP egcs/gcc/objc/Make-lang.in egcs-1.1-objc-gc/gcc/objc/Make-lang.in
*** egcs/gcc/objc/Make-lang.in	Sat May 16 02:38:03 1998
--- egcs-1.1-objc-gc/gcc/objc/Make-lang.in	Fri Jul  3 15:55:07 1998
***************
*** 119,124 ****
--- 119,125 ----
  	objc/NXConstStr.o objc/Object.o \
  	objc/Protocol.o objc/nil_method.o \
  	objc/thr.o objc/linking.o \
+ 	objc/gc.o \
  	objc/$(OBJC_THREAD_FILE).o
  
  objc/hash.o: $(srcdir)/objc/hash.c $(GCC_PASSES)
***************
*** 172,182 ****
  objc/linking.o: $(srcdir)/objc/linking.m $(GCC_PASSES)
  	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
  	-fgnu-runtime -c $(srcdir)/objc/linking.m -o $@
! 
  objc/libobjc_entry.o: $(srcdir)/objc/libobjc_entry.c $(GCC_PASSES)
  	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
  	-c $(srcdir)/objc/libobjc_entry.c -o $@
  
  $(OBJC_O): $(GCC_PASSES) cc1obj$(exeext)
  
  # Build the Objective C runtime library.
--- 173,246 ----
  objc/linking.o: $(srcdir)/objc/linking.m $(GCC_PASSES)
  	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
  	-fgnu-runtime -c $(srcdir)/objc/linking.m -o $@
! objc/gc.o: $(srcdir)/objc/gc.c $(GCC_PASSES)
! 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
! 	-fgnu-runtime -c $(srcdir)/objc/gc.c -o $@
  objc/libobjc_entry.o: $(srcdir)/objc/libobjc_entry.c $(GCC_PASSES)
  	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
  	-c $(srcdir)/objc/libobjc_entry.c -o $@
  
+ 
+ 
+ objc/hash_gc.o: $(srcdir)/objc/hash.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/hash.c -o $@
+ objc/sarray_gc.o: $(srcdir)/objc/sarray.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/sarray.c -o $@
+ objc/class_gc.o: $(srcdir)/objc/class.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/class.c -o $@
+ objc/sendmsg_gc.o: $(srcdir)/objc/sendmsg.c $(GCC_PASSES) objc/runtime-info.h
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) -Iobjc \
+ 	-c $(srcdir)/objc/sendmsg.c -o $@
+ objc/init_gc.o: $(srcdir)/objc/init.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/init.c -o $@
+ objc/archive_gc.o: $(srcdir)/objc/archive.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/archive.c -o $@
+ objc/encoding_gc.o: $(srcdir)/objc/encoding.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/encoding.c -o $@
+ objc/selector_gc.o: $(srcdir)/objc/selector.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/selector.c -o $@
+ objc/objects_gc.o: $(srcdir)/objc/objects.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/objects.c -o $@
+ objc/misc_gc.o: $(srcdir)/objc/misc.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/misc.c -o $@
+ objc/NXConstStr_gc.o: $(srcdir)/objc/NXConstStr.m $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-fgnu-runtime -c $(srcdir)/objc/NXConstStr.m -o $@
+ objc/Object_gc.o: $(srcdir)/objc/Object.m $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-fgnu-runtime -c $(srcdir)/objc/Object.m -o $@
+ objc/Protocol_gc.o: $(srcdir)/objc/Protocol.m $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-fgnu-runtime -c $(srcdir)/objc/Protocol.m -o $@
+ objc/thr_gc.o: $(srcdir)/objc/thr.h $(srcdir)/objc/thr.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/thr.c -o $@
+ objc/$(OBJC_THREAD_FILE)_gc.o: $(srcdir)/objc/$(OBJC_THREAD_FILE).c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/$(OBJC_THREAD_FILE).c -o $@
+ objc/nil_method_gc.o: $(srcdir)/objc/nil_method.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/nil_method.c -o $@
+ objc/linking_gc.o: $(srcdir)/objc/linking.m $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-fgnu-runtime -c $(srcdir)/objc/linking.m -o $@
+ objc/gc_gc.o: $(srcdir)/objc/gc.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-fgnu-runtime -c $(srcdir)/objc/gc.c -o $@
+ objc/libobjc_entry_gc.o: $(srcdir)/objc/libobjc_entry.c $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \
+ 	-c $(srcdir)/objc/libobjc_entry.c -o $@
+ 
+ 
  $(OBJC_O): $(GCC_PASSES) cc1obj$(exeext)
  
  # Build the Objective C runtime library.
***************
*** 185,190 ****
--- 249,265 ----
  	-rm -f libobjc.a
  	$(AR) $(AR_FLAGS) libobjc.a $(OBJC_O)
  	-if $(RANLIB_TEST) ; then $(RANLIB) libobjc.a; else true; fi
+ 	-if [ "$(OBJC_BOEHM_GC)" != "" ]; then \
+ 	  make libobjc_gc.a GCC_CFLAGS="$(GCC_CFLAGS) -DOBJC_WITH_GC=1" \
+ 		OBJC_O=`echo $(OBJC_O) | sed 's/.o /_gc.o /g'`; \
+ 	fi
+ 
+ # Build the garbage collected Objective C runtime library.
+ libobjc_gc.a: cc1obj specs stmp-int-hdrs libgcc2.ready \
+ 	$(USE_COLLECT2) $(EXTRA_PARTS) $(OBJC_O)
+ 	-rm -f libobjc_gc.a
+ 	$(AR) $(AR_FLAGS) libobjc_gc.a $(OBJC_O)
+ 	-if $(RANLIB_TEST) ; then $(RANLIB) libobjc_gc.a; else true; fi
  
  libobjc_s.a: libobjc.a
  	mv libobjc.a libobjc_s.a
***************
*** 236,241 ****
--- 311,323 ----
  	    (cd $(libsubdir); $(RANLIB) libobjc.a); else true; fi; \
  	  chmod a-x $(libsubdir)/libobjc.a; \
  	else true; fi
+ 	-if [ -f libobjc_gc.a ] ; then \
+ 	  rm -f $(libsubdir)/libobjc_gc.a; \
+ 	  $(INSTALL_DATA) libobjc_gc.a $(libsubdir)/libobjc_gc.a; \
+ 	  if $(RANLIB_TEST) ; then \
+ 	    (cd $(libsubdir); $(RANLIB) libobjc_gc.a); else true; fi; \
+ 	  chmod a-x $(libsubdir)/libobjc_gc.a; \
+ 	else true; fi
  	-if [ -f libobjc_s.a ] ; then \
  	  rm -f $(libsubdir)/libobjc_s.a; \
  	  $(INSTALL_DATA) libobjc_s.a $(libsubdir)/libobjc_s.a; \
***************
*** 263,269 ****
  	-rm -f tmp-objc-prs.y
  	-rm -f objc/*$(objext) objc/xforward objc/fflags
  	-rm -f objc/runtime-info.h
! 	-rm -f libobjc.a libobjc_s.a libobjc.dll
  	-rm -f libobjc.base libobjc.exp
  objc.clean: objc.mostlyclean
  	-rm -rf objc-headers
--- 345,351 ----
  	-rm -f tmp-objc-prs.y
  	-rm -f objc/*$(objext) objc/xforward objc/fflags
  	-rm -f objc/runtime-info.h
! 	-rm -f libobjc.a libobjc_gc.a libobjc_s.a libobjc.dll
  	-rm -f libobjc.base libobjc.exp
  objc.clean: objc.mostlyclean
  	-rm -rf objc-headers
***************
*** 282,300 ****
  objc.stage1: stage1-start
  	-mv objc/*$(objext) stage1/objc
  	-mv cc1obj$(exeext) stage1
! 	-mv libobjc.a stage1
  objc.stage2: stage2-start
  	-mv objc/*$(objext) stage2/objc
  	-mv cc1obj$(exeext) stage2
! 	-mv libobjc.a stage2
  objc.stage3: stage3-start
  	-mv objc/*$(objext) stage3/objc
  	-mv cc1obj$(exeext) stage3
! 	-mv libobjc.a stage3
  objc.stage4: stage4-start
  	-mv objc/*$(objext) stage4/objc
  	-mv cc1obj$(exeext) stage4
! 	-mv libobjc.a stage4
  
  #
  # Maintenance hooks:
--- 364,382 ----
  objc.stage1: stage1-start
  	-mv objc/*$(objext) stage1/objc
  	-mv cc1obj$(exeext) stage1
! 	-mv libobjc.a libobjc_gc.a stage1
  objc.stage2: stage2-start
  	-mv objc/*$(objext) stage2/objc
  	-mv cc1obj$(exeext) stage2
! 	-mv libobjc.a libobjc_gc.a stage2
  objc.stage3: stage3-start
  	-mv objc/*$(objext) stage3/objc
  	-mv cc1obj$(exeext) stage3
! 	-mv libobjc.a libobjc_gc.a stage3
  objc.stage4: stage4-start
  	-mv objc/*$(objext) stage4/objc
  	-mv cc1obj$(exeext) stage4
! 	-mv libobjc.a libobjc_gc.a stage4
  
  #
  # Maintenance hooks:
diff -rcP egcs/gcc/objc/Makefile.in egcs-1.1-objc-gc/gcc/objc/Makefile.in
*** egcs/gcc/objc/Makefile.in	Sat May 16 02:38:03 1998
--- egcs-1.1-objc-gc/gcc/objc/Makefile.in	Mon Jul  6 14:00:25 1998
***************
*** 81,88 ****
  Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure
  	cd ..; $(SHELL) config.status
  
  mostlyclean:
! 	-rm -f *.o libobjc.a xforward fflags
  clean: mostlyclean
  distclean: mostlyclean
  extraclean: mostlyclean
--- 81,103 ----
  Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure
  	cd ..; $(SHELL) config.status
  
+ doc: info dvi html
+ info: objc-features.info
+ dvi: objc-features.dvi
+ html: objc-features_toc.html
+ 
+ objc-features.info: $(srcdir)/objc-features.texi
+ 	makeinfo $(srcdir)/objc-features.texi
+ 
+ objc-features.dvi: $(srcdir)/objc-features.texi
+ 	texi2dvi $(srcdir)/objc-features.texi
+ 
+ objc-features_toc.html: objc-features.texi
+ 	texi2html -split_node $(srcdir)/objc-features.texi
+ 
  mostlyclean:
! 	-rm -f *.o libobjc* xforward fflags *.aux *.cp *.dvi *.fn *.info \
! 		*.ky *.log *.pg *.toc *.tp *.vr *.html
  clean: mostlyclean
  distclean: mostlyclean
  extraclean: mostlyclean
diff -rcP egcs/gcc/objc/encoding.c egcs-1.1-objc-gc/gcc/objc/encoding.c
*** egcs/gcc/objc/encoding.c	Sat May 16 02:38:13 1998
--- egcs-1.1-objc-gc/gcc/objc/encoding.c	Thu Jul 30 20:09:07 1998
***************
*** 1,6 ****
--- 1,7 ----
  /* Encoding of types for Objective C.
     Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
     Contributed by Kresten Krab Thorup
+    Bitfield support by Ovidiu Predescu
  
  This file is part of GNU CC.
  
***************
*** 25,30 ****
--- 26,33 ----
     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 "objc-api.h"
  #include "encoding.h"
  
  #define MAX(X, Y)                    \
***************
*** 40,45 ****
--- 43,64 ----
       __a*((__v+__a-1)/__a); })
  
  
+ /* Various hacks for objc_layout_record. These are used by the target
+    macros. */
+ 
+ #define TREE_CODE(TYPE) *TYPE
+ #define RECORD_TYPE     _C_STRUCT_B
+ #define UNION_TYPE      _C_UNION_B
+ #define QUAL_UNION_TYPE _C_UNION_B
+ 
+ #define TYPE_FIELDS(TYPE)     objc_skip_typespec (TYPE)
+ 
+ #define DECL_MODE(TYPE)         *(TYPE)
+ 
+ #define DFmode          _C_DBL
+ 
+ 
+ 
  static inline int
  atoi (const char* str)
  {
***************
*** 56,63 ****
  */
  
  int
! objc_sizeof_type(const char* type)
  {
    switch(*type) {
    case _C_ID:
      return sizeof(id);
--- 75,89 ----
  */
  
  int
! objc_sizeof_type (const char* type)
  {
+   /* Skip the variable name if any */
+   if (*type == '"')
+     {
+       for (type++; *type++ != '"';)
+ 	/* do nothing */;
+     }
+ 
    switch(*type) {
    case _C_ID:
      return sizeof(id);
***************
*** 103,108 ****
--- 129,142 ----
      return sizeof(unsigned long);
      break;
  
+   case _C_LNG_LNG:
+     return sizeof(long long);
+     break;
+ 
+   case _C_ULNG_LNG:
+     return sizeof(unsigned long long);
+     break;
+ 
    case _C_FLT:
      return sizeof(float);
      break;
***************
*** 128,146 ****
      }
      break; 
  
    case _C_STRUCT_B:
      {
!       int acc_size = 0;
!       int align;
!       while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
!       while (*type != _C_STRUCT_E)
! 	{
! 	  align = objc_alignof_type (type);       /* padd to alignment */
! 	  acc_size = ROUND (acc_size, align);
! 	  acc_size += objc_sizeof_type (type);   /* add component size */
! 	  type = objc_skip_typespec (type);	         /* skip component */
! 	}
!       return acc_size;
      }
  
    case _C_UNION_B:
--- 162,193 ----
      }
      break; 
  
+   case _C_BFLD:
+     {
+       /* The new encoding of bitfields is: b 'position' 'type' 'size' */
+       int position, size;
+       int startByte, endByte;
+ 
+       position = atoi (type + 1);
+       while (isdigit (*++type));
+       size = atoi (type + 1);
+ 
+       startByte = position / BITS_PER_UNIT;
+       endByte = (position + size) / BITS_PER_UNIT;
+       return endByte - startByte;
+     }
+ 
    case _C_STRUCT_B:
      {
!       struct objc_struct_layout layout;
!       unsigned int size;
! 
!       objc_layout_structure (type, &layout);
!       while (objc_layout_structure_next_member (&layout))
!         /* do nothing */ ;
!       objc_layout_finish_structure (&layout, &size, NULL);
! 
!       return size;
      }
  
    case _C_UNION_B:
***************
*** 149,154 ****
--- 196,207 ----
        while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
        while (*type != _C_UNION_E)
  	{
+ 	  /* Skip the variable name if any */
+ 	  if (*type == '"')
+ 	    {
+ 	      for (type++; *type++ != '"';)
+ 		/* do nothing */;
+ 	    }
  	  max_size = MAX (max_size, objc_sizeof_type (type));
  	  type = objc_skip_typespec (type);
  	}
***************
*** 171,176 ****
--- 224,235 ----
  int
  objc_alignof_type(const char* type)
  {
+   /* Skip the variable name if any */
+   if (*type == '"')
+     {
+       for (type++; *type++ != '"';)
+ 	/* do nothing */;
+     }
    switch(*type) {
    case _C_ID:
      return __alignof__(id);
***************
*** 216,221 ****
--- 275,288 ----
      return __alignof__(unsigned long);
      break;
  
+   case _C_LNG_LNG:
+     return __alignof__(long long);
+     break;
+ 
+   case _C_ULNG_LNG:
+     return __alignof__(unsigned long long);
+     break;
+ 
    case _C_FLT:
      return __alignof__(float);
      break;
***************
*** 233,247 ****
    case _C_ARY_B:
      while (isdigit(*++type)) /* do nothing */;
      return objc_alignof_type (type);
!       
    case _C_STRUCT_B:
      {
!       struct { int x; double y; } fooalign;
!       while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */;
!       if (*type != _C_STRUCT_E)
! 	return MAX (objc_alignof_type (type), __alignof__ (fooalign));
!       else
! 	return __alignof__ (fooalign);
      }
  
    case _C_UNION_B:
--- 300,317 ----
    case _C_ARY_B:
      while (isdigit(*++type)) /* do nothing */;
      return objc_alignof_type (type);
! 
    case _C_STRUCT_B:
      {
!       struct objc_struct_layout layout;
!       unsigned int align;
! 
!       objc_layout_structure (type, &layout);
!       while (objc_layout_structure_next_member (&layout))
!         /* do nothing */;
!       objc_layout_finish_structure (&layout, NULL, &align);
! 
!       return align;
      }
  
    case _C_UNION_B:
***************
*** 250,261 ****
        while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
        while (*type != _C_UNION_E)
  	{
  	  maxalign = MAX (maxalign, objc_alignof_type (type));
  	  type = objc_skip_typespec (type);
  	}
        return maxalign;
      }
!     
    default:
      {
        objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
--- 320,337 ----
        while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
        while (*type != _C_UNION_E)
  	{
+ 	  /* Skip the variable name if any */
+ 	  if (*type == '"')
+ 	    {
+ 	      for (type++; *type++ != '"';)
+ 		/* do nothing */;
+ 	    }
  	  maxalign = MAX (maxalign, objc_alignof_type (type));
  	  type = objc_skip_typespec (type);
  	}
        return maxalign;
      }
! 
    default:
      {
        objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
***************
*** 271,278 ****
  int
  objc_aligned_size (const char* type)
  {
!   int size = objc_sizeof_type (type);
!   int align = objc_alignof_type (type);
    return ROUND (size, align);
  }
  
--- 347,364 ----
  int
  objc_aligned_size (const char* type)
  {
!   int size, align;
! 
!   /* Skip the variable name */
!   if (*type == '"')
!     {
!       for (type++; *type++ != '"';)
! 	/* do nothing */;
!     }
! 
!   size = objc_sizeof_type (type);
!   align = objc_alignof_type (type);
! 
    return ROUND (size, align);
  }
  
***************
*** 284,291 ****
  int 
  objc_promoted_size (const char* type)
  {
!   int size = objc_sizeof_type (type);
!   int wordsize = sizeof (void*);
  
    return ROUND (size, wordsize);
  }
--- 370,386 ----
  int 
  objc_promoted_size (const char* type)
  {
!   int size, wordsize;
! 
!   /* Skip the variable name */
!   if (*type == '"')
!     {
!       for (type++; *type++ != '"';)
! 	/* do nothing */;
!     }
! 
!   size = objc_sizeof_type (type);
!   wordsize = sizeof (void*);
  
    return ROUND (size, wordsize);
  }
***************
*** 303,309 ****
  	 || *type == _C_INOUT
  	 || *type == _C_OUT 
  	 || *type == _C_BYCOPY
! 	 || *type == _C_ONEWAY)
      {
        type += 1;
      }
--- 398,405 ----
  	 || *type == _C_INOUT
  	 || *type == _C_OUT 
  	 || *type == _C_BYCOPY
! 	 || *type == _C_ONEWAY
! 	 || *type == _C_GCINVISIBLE)
      {
        type += 1;
      }
***************
*** 319,324 ****
--- 415,427 ----
  const char* 
  objc_skip_typespec (const char* type)
  {
+   /* Skip the variable name if any */
+   if (*type == '"')
+     {
+       for (type++; *type++ != '"';)
+ 	/* do nothing */;
+     }
+ 
    type = objc_skip_type_qualifiers (type);
    
    switch (*type) {
***************
*** 348,353 ****
--- 451,458 ----
    case _C_UINT:
    case _C_LNG:
    case _C_ULNG:
+   case _C_LNG_LNG:
+   case _C_ULNG_LNG:
    case _C_FLT:
    case _C_DBL:
    case _C_VOID:
***************
*** 368,373 ****
--- 473,484 ----
  	return 0;
        }
  
+   case _C_BFLD:
+     /* The new encoding of bitfields is: b 'position' 'type' 'size' */
+     while (isdigit (*++type));	/* skip position */
+     while (isdigit (*++type));	/* skip type and size */
+     return type;
+ 
    case _C_STRUCT_B:
      /* skip name, and elements until closing '}'  */
      
***************
*** 541,554 ****
    while (flag)
      switch (*type++)
        {
!       case _C_CONST:  res |= _F_CONST; break;
!       case _C_IN:     res |= _F_IN; break;
!       case _C_INOUT:  res |= _F_INOUT; break;
!       case _C_OUT:    res |= _F_OUT; break;
!       case _C_BYCOPY: res |= _F_BYCOPY; break;
!       case _C_ONEWAY: res |= _F_ONEWAY; break;
        default: flag = NO;
      }
  
    return res;
  }
--- 652,912 ----
    while (flag)
      switch (*type++)
        {
!       case _C_CONST:	res |= _F_CONST; break;
!       case _C_IN:	res |= _F_IN; break;
!       case _C_INOUT:	res |= _F_INOUT; break;
!       case _C_OUT:	res |= _F_OUT; break;
!       case _C_BYCOPY:	res |= _F_BYCOPY; break;
!       case _C_ONEWAY:	res |= _F_ONEWAY; break;
!       case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
        default: flag = NO;
      }
  
    return res;
+ }
+ 
+ 
+ /* The following three functions can be used to determine how a
+    structure is laid out by the compiler. For example:
+ 
+   struct objc_struct_layout layout;
+   int i;
+ 
+   objc_layout_structure (type, &layout);
+   while (objc_layout_structure_next_member (&layout))
+     {
+       int position, align;
+       const char *type;
+ 
+       objc_layout_structure_get_info (&layout, &position, &align, &type);
+       printf ("element %d has offset %d, alignment %d\n",
+               i++, position, align);
+     }
+ 
+   These functions are used by objc_sizeof_type and objc_alignof_type
+   functions to compute the size and alignment of structures. The
+   previous method of computing the size and alignment of a structure
+   was not working on some architectures, particulary on AIX, and in
+   the presence of bitfields inside the structure. */
+ void
+ objc_layout_structure (const char *type,
+                            struct objc_struct_layout *layout)
+ {
+   const char *ntype;
+ 
+   if (*type++ != _C_STRUCT_B)
+     {
+       objc_error(nil, OBJC_ERR_BAD_TYPE,
+                  "record type expected in objc_layout_structure, got %s\n",
+                  type);
+     }
+ 
+   layout->original_type = type;
+ 
+   /* Skip "<name>=" if any. Avoid embedded structures and unions. */
+   ntype = type;
+   while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
+          && *ntype++ != '=')
+     /* do nothing */;
+ 
+   /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
+   if (*(ntype - 1) == '=')
+     type = ntype;
+ 
+   layout->type = type;
+   layout->prev_type = NULL;
+   layout->record_size = 0;
+   layout->record_align = BITS_PER_UNIT;
+ 
+ #ifdef STRUCTURE_SIZE_BOUNDARY
+   layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
+ #endif
+ }
+ 
+ 
+ BOOL
+ objc_layout_structure_next_member (struct objc_struct_layout *layout)
+ {
+   register int known_align = layout->record_size;
+   register int desired_align = 0;
+ 
+   /* The following are used only if the field is a bitfield */
+   register const char *bfld_type;
+   register int bfld_type_size, bfld_type_align, bfld_field_size;
+ 
+   /* The current type without the type qualifiers */
+   const char *type;
+ 
+ #if 1
+   if (layout->prev_type == NULL)
+     {
+       layout->prev_type = layout->type;
+       layout->type = objc_skip_typespec (layout->prev_type);
+       return YES;
+     }
+ #endif
+ 
+   /* Add the size of the previous field to the size of the record.  */
+   if (layout->prev_type)
+     {
+       type = objc_skip_type_qualifiers (layout->prev_type);
+ 
+       if (*type != _C_BFLD)
+         layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
+       else {
+         desired_align = 1;
+         /* Get the bitfield's type */
+         for (bfld_type = type + 1;
+              isdigit(*bfld_type);
+              bfld_type++)
+           /* do nothing */;
+ 
+         bfld_type_size = objc_sizeof_type (bfld_type) * BITS_PER_UNIT;
+         bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
+         bfld_field_size = atoi (objc_skip_typespec (bfld_type));
+         layout->record_size += bfld_field_size;
+       }
+     }
+ 
+   if (*layout->type == _C_STRUCT_E)
+     return NO;
+ 
+   /* Skip the variable name if any */
+   if (*layout->type == '"')
+     {
+       for (layout->type++; *layout->type++ != '"';)
+         /* do nothing */;
+     }
+ 
+   type = objc_skip_type_qualifiers (layout->type);
+ 
+   if (*type != _C_BFLD)
+     desired_align = objc_alignof_type(type) * BITS_PER_UNIT;
+   else
+     {
+       desired_align = 1;
+       /* Skip the bitfield's offset */
+       for (bfld_type = type + 1; isdigit(*bfld_type); bfld_type++)
+         /* do nothing */;
+ 
+       bfld_type_size = objc_sizeof_type (bfld_type) * BITS_PER_UNIT;
+       bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
+       bfld_field_size = atoi (objc_skip_typespec (bfld_type));
+     }
+ 
+ #ifdef BIGGEST_FIELD_ALIGNMENT
+   desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
+ #endif
+ #ifdef ADJUST_FIELD_ALIGN
+   desired_align = ADJUST_FIELD_ALIGN (type, desired_align);
+ #endif
+ 
+   /* Record must have at least as much alignment as any field.
+      Otherwise, the alignment of the field within the record
+      is meaningless.  */
+ #ifndef PCC_BITFIELD_TYPE_MATTERS
+   layout->record_align = MAX (layout->record_align, desired_align);
+ #else
+   if (*type == _C_BFLD)
+     {
+       /* For these machines, a zero-length field does not
+          affect the alignment of the structure as a whole.
+          It does, however, affect the alignment of the next field
+          within the structure.  */
+       if (bfld_field_size)
+         layout->record_align = MAX (layout->record_align, desired_align);
+       else
+         desired_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
+ 
+       /* A named bit field of declared type `int'
+          forces the entire structure to have `int' alignment.
+          Q1: How is encoded this thing and how to check for it?
+          Q2: How to determine maximum_field_alignment at runtime? */
+ 
+ /*	  if (DECL_NAME (field) != 0) */
+       {
+         int type_align = bfld_type_align;
+ #if 0
+         if (maximum_field_alignment != 0)
+           type_align = MIN (type_align, maximum_field_alignment);
+         else if (DECL_PACKED (field))
+           type_align = MIN (type_align, BITS_PER_UNIT);
+ #endif
+ 
+         layout->record_align = MAX (layout->record_align, type_align);
+       }
+     }
+   else
+     layout->record_align = MAX (layout->record_align, desired_align);
+ #endif
+ 
+   /* Does this field automatically have alignment it needs
+      by virtue of the fields that precede it and the record's
+      own alignment?  */
+ 
+   if (*type == _C_BFLD)
+     layout->record_size = atoi (type + 1);
+   else if (layout->record_size % desired_align != 0)
+     {
+       /* No, we need to skip space before this field.
+          Bump the cumulative size to multiple of field alignment.  */
+       layout->record_size = ROUND (layout->record_size, desired_align);
+     }
+   
+   /* Jump to the next field in record. */
+ 
+   layout->prev_type = layout->type;
+   layout->type = objc_skip_typespec (layout->type);      /* skip component */
+ 
+   return YES;
+ }
+ 
+ 
+ void objc_layout_finish_structure (struct objc_struct_layout *layout,
+                                    unsigned int *size,
+                                    unsigned int *align)
+ {
+   if (layout->type && *layout->type == _C_STRUCT_E)
+     {
+       /* Work out the alignment of the record as one expression and store
+          in the record type.  Round it up to a multiple of the record's
+          alignment. */
+ 
+ #ifdef ROUND_TYPE_ALIGN
+       layout->record_align = ROUND_TYPE_ALIGN (layout->original_type,
+                                                1,
+                                                layout->record_align);
+ #else
+       layout->record_align = MAX (1, layout->record_align);
+ #endif
+ 
+ #ifdef ROUND_TYPE_SIZE
+       layout->record_size = ROUND_TYPE_SIZE (layout->original_type,
+                                              layout->record_size,
+                                              layout->record_align);
+ #else
+       /* Round the size up to be a multiple of the required alignment */
+       layout->record_size = ROUND (layout->record_size, layout->record_align);
+ #endif
+ 
+       layout->type = NULL;
+     }
+   if (size)
+     *size = layout->record_size / BITS_PER_UNIT;
+   if (align)
+     *align = layout->record_align / BITS_PER_UNIT;
+ }
+ 
+ 
+ void objc_layout_structure_get_info (struct objc_struct_layout *layout,
+                                      unsigned int *offset,
+                                      unsigned int *align,
+                                      const char **type)
+ {
+   if (offset)
+     *offset = layout->record_size / BITS_PER_UNIT;
+   if (align)
+     *align = layout->record_align / BITS_PER_UNIT;
+   if (type)
+     *type = layout->prev_type;
  }
diff -rcP egcs/gcc/objc/encoding.h egcs-1.1-objc-gc/gcc/objc/encoding.h
*** egcs/gcc/objc/encoding.h	Sat May 16 02:38:13 1998
--- egcs-1.1-objc-gc/gcc/objc/encoding.h	Fri Jul 24 08:01:14 1998
***************
*** 32,57 ****
  #include <ctype.h>
  #include "objc/objc-api.h"
  
! #define _C_CONST    'r'
! #define _C_IN       'n'
! #define _C_INOUT    'N'
! #define _C_OUT      'o'
! #define _C_BYCOPY   'O'
! #define _C_ONEWAY   'V'
! 
! #define _F_CONST    0x01
! #define _F_IN       0x01
! #define _F_OUT      0x02
! #define _F_INOUT    0x03
! #define _F_BYCOPY   0x04
! #define _F_ONEWAY   0x08
! 
  
  int objc_aligned_size (const char* type);
  int objc_sizeof_type (const char* type);
  int objc_alignof_type (const char* type);
  int objc_aligned_size (const char* type);
  int objc_promoted_size (const char* type);
  const char* objc_skip_type_qualifiers (const char* type);
  const char* objc_skip_typespec (const char* type);
  const char* objc_skip_offset (const char* type);
--- 32,59 ----
  #include <ctype.h>
  #include "objc/objc-api.h"
  
! #define _C_CONST	'r'
! #define _C_IN		'n'
! #define _C_INOUT	'N'
! #define _C_OUT      	'o'
! #define _C_BYCOPY	'O'
! #define _C_ONEWAY	'V'
! #define _C_GCINVISIBLE	'!'
! 
! #define _F_CONST	0x01
! #define _F_IN		0x01
! #define _F_OUT		0x02
! #define _F_INOUT	0x03
! #define _F_BYCOPY	0x04
! #define _F_ONEWAY	0x08
! #define _F_GCINVISIBLE	0x10
  
  int objc_aligned_size (const char* type);
  int objc_sizeof_type (const char* type);
  int objc_alignof_type (const char* type);
  int objc_aligned_size (const char* type);
  int objc_promoted_size (const char* type);
+ 
  const char* objc_skip_type_qualifiers (const char* type);
  const char* objc_skip_typespec (const char* type);
  const char* objc_skip_offset (const char* type);
***************
*** 71,75 ****
--- 73,97 ----
  
  unsigned objc_get_type_qualifiers (const char* type);
  
+ 
+ struct objc_struct_layout 
+ {
+   const char *original_type;
+   const char *type;
+   const char *prev_type;
+   unsigned int record_size;
+   unsigned int record_align;
+ };
+ 
+ void objc_layout_structure (const char *type,
+                             struct objc_struct_layout *layout);
+ BOOL  objc_layout_structure_next_member (struct objc_struct_layout *layout);
+ void objc_layout_finish_structure (struct objc_struct_layout *layout,
+                                    unsigned int *size,
+                                    unsigned int *align);
+ void objc_layout_structure_get_info (struct objc_struct_layout *layout,
+                                      unsigned int *offset,
+                                      unsigned int *align,
+                                      const char **type);
  
  #endif /* __encoding_INCLUDE_GNU */
diff -rcP egcs/gcc/objc/gc.c egcs-1.1-objc-gc/gcc/objc/gc.c
*** egcs/gcc/objc/gc.c	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/objc/gc.c	Thu Jul 30 18:58:36 1998
***************
*** 0 ****
--- 1,458 ----
+ /* Basic data types for Objective C.
+    Copyright (C) 1998 Free Software Foundation, Inc.
+    Contributed by Ovidiu Predescu.
+ 
+ This file is part of GNU CC.
+ 
+ GNU CC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+ 
+ GNU CC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GNU CC; see the file COPYING.  If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.  */
+ 
+ /* As a special exception, if you link this library with files
+    compiled with GCC to produce an executable, this does not cause
+    the resulting executable to be covered by the GNU General Public License.
+    This exception does not however invalidate any other reasons why
+    the executable file might be covered by the GNU General Public License.  */
+ 
+ #include "../tconfig.h"
+ #include "objc.h"
+ #include "encoding.h"
+ 
+ #include <assert.h>
+ #include <string.h>
+ 
+ #if OBJC_WITH_GC
+ 
+ #include <gc.h>
+ 
+ /* gc_typed.h uses the following but doesn't declare them */
+ typedef GC_word word;
+ typedef GC_signed_word signed_word;
+ 
+ #if BITS_PER_WORD == 32
+ # define LOGWL	5
+ # define modWORDSZ(n) ((n) & 0x1f)        /* n mod size of word	    */
+ #endif
+ 
+ #if BITS_PER_WORD == 64
+ # define LOGWL 6
+ # define modWORDSZ(n) ((n) & 0x3f)        /* n mod size of word	    */
+ #endif
+ 
+ #define divWORDSZ(n) ((n) >> LOGWL)	   /* divide n by size of word      */
+ 
+ #include <gc_typed.h>
+ 
+ /* The following functions set up in `mask` the corresponding pointers.
+    The offset is incremented with the size of the type.  */
+ 
+ #define ROUND(V, A) \
+   ({ typeof(V) __v=(V); typeof(A) __a=(A); \
+      __a*((__v+__a-1)/__a); })
+ 
+ #define SET_BIT_FOR_OFFSET(mask, offset) \
+   GC_set_bit(mask, offset / sizeof (void*))
+ 
+ /* Some prototypes */
+ static void
+ __objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset);
+ static void
+ __objc_gc_setup_union (GC_bitmap mask, const char *type, int offset);
+ 
+ 
+ static void
+ __objc_gc_setup_array (GC_bitmap mask, const char *type, int offset)
+ {
+   int i, len = atoi(type + 1);
+ 
+   while (isdigit(*++type))
+     /* do nothing */;		/* skip the size of the array */
+ 
+   switch (*type) {
+   case _C_ARY_B:
+     for (i = 0; i < len; i++)
+       __objc_gc_setup_array (mask, type, offset);
+     break;
+ 
+   case _C_STRUCT_B:
+     for (i = 0; i < len; i++)
+       __objc_gc_setup_struct (mask, type, offset);
+     break;
+ 
+   case _C_UNION_B:
+     for (i = 0; i < len; i++)
+       __objc_gc_setup_union (mask, type, offset);
+     break;
+ 
+   default:
+     break;
+   }
+ }
+ 
+ static void
+ __objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset)
+ {
+   struct objc_struct_layout layout;
+   unsigned int position;
+   const char *mtype;
+ 
+   objc_layout_structure (type, &layout);
+ 
+   while (objc_layout_structure_next_member (&layout))
+     {
+       BOOL gc_invisible = NO;
+ 
+       objc_layout_structure_get_info (&layout, &position, NULL, &mtype);
+ 
+       /* Skip the variable name */
+       if (*mtype == '"')
+ 	{
+ 	  for (mtype++; *mtype++ != '"';)
+ 	    /* do nothing */;
+ 	}
+ 
+       if (*mtype == _C_GCINVISIBLE)
+ 	{
+ 	  gc_invisible = YES;
+ 	  mtype++;
+ 	}
+ 
+       /* Add to position the offset of this structure */
+       position += offset;
+ 
+       switch (*mtype) {
+       case _C_ID:
+       case _C_CLASS:
+       case _C_SEL:
+       case _C_PTR:
+       case _C_CHARPTR:
+       case _C_ATOM:
+ 	if (!gc_invisible)
+ 	  SET_BIT_FOR_OFFSET(mask, position);
+ 	break;
+ 
+       case _C_ARY_B:
+ 	__objc_gc_setup_array (mask, mtype, position);
+ 	break;
+ 
+       case _C_STRUCT_B:
+ 	__objc_gc_setup_struct (mask, mtype, position);
+ 	break;
+ 
+       case _C_UNION_B:
+ 	__objc_gc_setup_union (mask, mtype, position);
+ 	break;
+ 
+       default:
+         break;
+       }
+     }
+ }
+ 
+ static void
+ __objc_gc_setup_union (GC_bitmap mask, const char *type, int offset)
+ {
+   /* Sub-optimal, quick implementation: assume the union is made of
+      pointers, set up the mask accordingly. */
+ 
+   int i, size, align;
+ 
+   /* Skip the variable name */
+   if (*type == '"')
+     {
+       for (type++; *type++ != '"';)
+ 	/* do nothing */;
+     }
+ 
+   size = objc_sizeof_type (type);
+   align = objc_alignof_type (type);
+ 
+   offset = ROUND(offset, align);
+   for (i = 0; i < size; i += sizeof (void*))
+     {
+       SET_BIT_FOR_OFFSET(mask, offset);
+       offset += sizeof (void*);
+     }
+ }
+ 
+ 
+ /* Iterates over the types in the structure that represents the class
+    encoding and sets the bits in mask according to each ivar type.  */
+ static void
+ __objc_gc_type_description_from_type (GC_bitmap mask, const char *type)
+ {
+   struct objc_struct_layout layout;
+   unsigned int offset, align;
+   const char *ivar_type;
+ 
+   objc_layout_structure (type, &layout);
+ 
+   while (objc_layout_structure_next_member (&layout))
+     {
+       BOOL gc_invisible = NO;
+ 
+       objc_layout_structure_get_info (&layout, &offset, &align, &ivar_type);
+ 
+       /* Skip the variable name */
+       if (*ivar_type == '"')
+ 	{
+ 	  for (ivar_type++; *ivar_type++ != '"';)
+ 	    /* do nothing */;
+ 	}
+ 
+       if (*ivar_type == _C_GCINVISIBLE)
+ 	{
+ 	  gc_invisible = YES;
+ 	  ivar_type++;
+ 	}
+ 
+       switch (*ivar_type) {
+       case _C_ID:
+       case _C_CLASS:
+       case _C_SEL:
+       case _C_PTR:
+       case _C_CHARPTR:
+         if (!gc_invisible)
+           SET_BIT_FOR_OFFSET(mask, offset);
+ 	break;
+ 
+       case _C_ARY_B:
+ 	__objc_gc_setup_array (mask, ivar_type, offset);
+ 	break;
+ 
+       case _C_STRUCT_B:
+ 	__objc_gc_setup_struct (mask, ivar_type, offset);
+ 	break;
+ 
+       case _C_UNION_B:
+ 	__objc_gc_setup_union (mask, ivar_type, offset);
+ 	break;
+ 
+       default:
+         break;
+       }
+     }
+ }
+ 
+ /* Computes in *type the full type encoding of this class including
+    its super classes. '*size' gives the total number of bytes allocated
+    into *type, '*current' the number of bytes used so far by the
+    encoding. */
+ static void
+ __objc_class_structure_encoding (Class class, char **type, int *size,
+                                  int *current)
+ {
+   int i, ivar_count;
+   struct objc_ivar_list* ivars;
+ 
+   if (!class)
+     {
+       strcat (*type, "{");
+       *current++;
+       return;
+     }
+ 
+   /* Add the type encodings of the super classes */
+   __objc_class_structure_encoding (class->super_class, type, size, current);
+ 
+   ivars = class->ivars;
+   if (!ivars)
+     return;
+ 
+   ivar_count = ivars->ivar_count;
+ 
+   for (i = 0; i < ivar_count; i++)
+     {
+       struct objc_ivar *ivar = &(ivars->ivar_list[i]);
+       const char *ivar_type = ivar->ivar_type;
+       int len = strlen (ivar_type);
+ 
+       if (*current + len + 1 >= *size)
+         {
+           /* Increase the size of the encoding string so that it
+              contains this ivar's type. */
+           *size = ROUND(*current + len + 1, 10);
+           *type = objc_realloc (*type, *size);
+         }
+       strcat (*type + *current, ivar_type);
+       *current += len;
+     }
+ }
+ 
+ 
+ /* Allocates the memory that will hold the type description for class
+    and calls the __objc_class_structure_encoding that generates this
+    value. */
+ void
+ __objc_generate_gc_type_description (Class class)
+ {
+   GC_bitmap mask;
+   int bits_no, size;
+   int type_size = 10, current;
+   char *class_structure_type;
+ 
+   if (!CLS_ISCLASS(class))
+     return;
+ 
+   /* We have to create a mask in which each bit counts for a pointer member.
+      We take into consideration all the non-pointer instance variables and we
+      round them up to the alignment. */
+ 
+   /* The number of bits in the mask is the size of an instance in bytes divided
+      by the size of a pointer. */
+   bits_no = (ROUND(class_get_instance_size (class), sizeof(void*))
+              / sizeof (void*));
+   size = ROUND(bits_no, BITS_PER_WORD) / BITS_PER_WORD;
+   mask = objc_atomic_malloc (size * sizeof (int));
+   memset (mask, 0, size * sizeof (int));
+ 
+   class_structure_type = objc_atomic_malloc (type_size);
+   *class_structure_type = current = 0;
+   __objc_class_structure_encoding (class, &class_structure_type,
+                                    &type_size, &current);
+   if (current + 1 == type_size)
+     class_structure_type = objc_realloc (class_structure_type, ++type_size);
+   strcat (class_structure_type + current, "}");
+ //  printf ("type description for '%s' is %s\n", class->name, class_structure_type);
+   
+   __objc_gc_type_description_from_type (mask, class_structure_type);
+   objc_free (class_structure_type);
+ 
+ #define DEBUG 1
+ #ifdef DEBUG
+   printf ("  mask for '%s', type '%s' (bits %d, mask size %d) is:",
+ 	  class_structure_type, class->name, bits_no, size);
+   {
+     int i;
+     for (i = 0; i < size; i++)
+       printf (" %lx", mask[i]);
+   }
+   puts ("");
+ #endif
+ 
+   class->gc_object_type = (void*)GC_make_descriptor (mask, bits_no);
+ }
+ 
+ 
+ /* Returns YES if type denotes a pointer type, NO otherwise */
+ static inline BOOL
+ __objc_ivar_pointer (const char *type)
+ {
+   type = objc_skip_type_qualifiers (type);
+ 
+   return (*type == _C_ID
+           || *type == _C_CLASS
+           || *type == _C_SEL
+           || *type == _C_PTR
+           || *type == _C_CHARPTR
+           || *type == _C_ATOM);
+ }
+ 
+ 
+ /* Mark the instance variable whose name is given by ivarname as a
+    weak pointer (a pointer hidden to the garbage collector) if
+    gc_invisible is true. If gc_invisible is false it unmarks the
+    instance variable and makes it a normal pointer, visible to the
+    garbage collector.
+ 
+    This operation only makes sense on instance variables that are
+    pointers.  */
+ void
+ class_ivar_set_gcinvisible (Class class, const char* ivarname,
+                             BOOL gc_invisible)
+ {
+   int i, ivar_count;
+   struct objc_ivar_list* ivars;
+ 
+   if (!class || !ivarname)
+     return;
+ 
+   ivars = class->ivars;
+   if (!ivars)
+     return;
+ 
+   ivar_count = ivars->ivar_count;
+ 
+   for (i = 0; i < ivar_count; i++)
+     {
+       struct objc_ivar *ivar = &(ivars->ivar_list[i]);
+       const char *type;
+ 
+       if (!ivar->ivar_name || strcmp (ivar->ivar_name, ivarname))
+ 	continue;
+ 
+       assert (ivar->ivar_type);
+       type = ivar->ivar_type;
+ 
+       /* Skip the variable name */
+       if (*type == '"')
+ 	{
+ 	  for (type++; *type++ != '"';)
+ 	    /* do nothing */;
+ 	}
+ 
+       if (*type == _C_GCINVISIBLE)
+ 	{
+ 	  char *new_type;
+ 
+ 	  if (gc_invisible || !__objc_ivar_pointer (type))
+ 	    return;	/* The type of the variable already matches the
+ 			   requested gc_invisible type */
+ 
+ 	  /* The variable is gc_invisible and we have to reverse it */
+ 	  new_type = objc_atomic_malloc (strlen (ivar->ivar_type));
+ 	  strncpy (new_type, ivar->ivar_type,
+ 		   (size_t)(type - ivar->ivar_type));
+ 	  strcat (new_type, type + 1);
+ 	  ivar->ivar_type = new_type;
+ 	}
+       else
+ 	{
+ 	  char *new_type;
+ 
+ 	  if (!gc_invisible || !__objc_ivar_pointer (type))
+ 	    return;	/* The type of the variable already matches the
+ 			   requested gc_invisible type */
+ 
+ 	  /* The variable is gc visible and we have to make it gc_invisible */
+ 	  new_type = objc_malloc (strlen (ivar->ivar_type) + 2);
+ 	  strncpy (new_type, ivar->ivar_type,
+ 		   (size_t)(type - ivar->ivar_type));
+ 	  strcat (new_type, "!");
+ 	  strcat (new_type, type);
+ 	  ivar->ivar_type = new_type;
+ 	}
+ 
+       __objc_generate_gc_type_description (class);
+       return;
+     }
+ 
+   /* Search the instance variable in the superclasses */
+   class_ivar_set_gcinvisible (class->super_class, ivarname, gc_invisible);
+ }
+ 
+ #else /* !OBJC_WITH_GC */
+ 
+ void
+ __objc_generate_gc_type_description (Class class)
+ {
+ }
+ 
+ void class_ivar_set_gcinvisible (Class class,
+ 				 const char* ivarname,
+ 				 BOOL gc_invisible)
+ {
+ }
+ 
+ #endif /* OBJC_WITH_GC */
diff -rcP egcs/gcc/objc/misc.c egcs-1.1-objc-gc/gcc/objc/misc.c
*** egcs/gcc/objc/misc.c	Sat May 16 02:38:18 1998
--- egcs-1.1-objc-gc/gcc/objc/misc.c	Fri Jul  3 13:31:25 1998
***************
*** 144,152 ****
--- 144,180 ----
  ** Users should call the normal objc routines above for
  ** memory allocation and disposal within their programs.
  */
+ 
+ #if OBJC_WITH_GC
+ #include <gc.h>
+ 
+ static void *GC_calloc (size_t nelem, size_t size)
+ {
+   void* p = GC_malloc (nelem * size);
+   if (!p)
+     objc_error (nil, OBJC_ERR_MEMORY, "Virtual memory exhausted!\n");
+ 
+   memset (p, 0, nelem * size);
+   return p;
+ }
+ 
+ static void noFree (void* p) {}
+ 
+ void *(*_objc_malloc)(size_t) = GC_malloc;
+ void *(*_objc_atomic_malloc)(size_t) = GC_malloc_atomic;
+ void *(*_objc_valloc)(size_t) = GC_malloc;
+ void *(*_objc_realloc)(void *, size_t) = GC_realloc;
+ void *(*_objc_calloc)(size_t, size_t) = GC_calloc;
+ void (*_objc_free)(void *) = noFree;
+ 
+ #else
+ 
  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;
+ 
+ 
+ #endif
diff -rcP egcs/gcc/objc/objc-act.c egcs-1.1-objc-gc/gcc/objc/objc-act.c
*** egcs/gcc/objc/objc-act.c	Fri Jul  3 12:47:54 1998
--- egcs-1.1-objc-gc/gcc/objc/objc-act.c	Fri Jul  3 13:31:25 1998
***************
*** 3380,3385 ****
--- 3380,3386 ----
         struct objc_class *sibling_class;
       }
       struct objc_protocol_list *protocols;
+      void *gc_object_type;
     };  */
  
  static void
***************
*** 3515,3520 ****
--- 3516,3536 ----
  			  decl_specs, NULL_TREE);
    chainon (field_decl_chain, field_decl);
  
+   /* void *sel_id; */
+ 
+   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
+   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
+   field_decl
+     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+   chainon (field_decl_chain, field_decl);
+ 
+   /* void *gc_object_type; */
+ 
+   decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
+   field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
+   field_decl
+     = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+   chainon (field_decl_chain, field_decl);
  
    finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
  }
***************
*** 4287,4292 ****
--- 4303,4309 ----
         struct objc_class *sibling_class;
       }
       struct objc_protocol_list *protocols;
+      void *gc_object_type;
     };  */
  
  static tree
***************
*** 4377,4382 ****
--- 4394,4402 ----
       initlist = tree_cons (NULL_TREE, expr, initlist);
       }
  
+   /* gc_object_type = NULL */
+   initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+ 
    return build_constructor (type, nreverse (initlist));
  }
  
***************
*** 6819,6824 ****
--- 6839,6900 ----
  }
  
  static void
+ encode_complete_bitfield (int position, tree type, int size)
+ {
+   enum tree_code code = TREE_CODE (type);
+   char buffer[40];
+   char charType = '?';
+ 
+   if (code == INTEGER_TYPE)
+     {
+       if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0
+ 	  && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0)
+ 	{
+ 	  /* Unsigned integer types.  */
+ 
+ 	  if (TYPE_MODE (type) == QImode)
+ 	    charType = 'C';
+ 	  else if (TYPE_MODE (type) == HImode)
+ 	    charType = 'S';
+ 	  else if (TYPE_MODE (type) == SImode)
+ 	    {
+ 	      if (type == long_unsigned_type_node)
+ 		charType = 'L';
+ 	      else
+ 		charType = 'I';
+ 	    }
+ 	  else if (TYPE_MODE (type) == DImode)
+ 	    charType = 'Q';
+ 	}
+ 
+       else
+ 	/* Signed integer types.  */
+ 	{
+ 	  if (TYPE_MODE (type) == QImode)
+ 	    charType = 'c';
+ 	  else if (TYPE_MODE (type) == HImode)
+ 	    charType = 's';
+ 	  else if (TYPE_MODE (type) == SImode)
+ 	    {
+ 	      if (type == long_integer_type_node)
+ 		charType = 'l';
+ 	      else
+ 		charType = 'i';
+ 	    }
+ 
+ 	  else if (TYPE_MODE (type) == DImode)
+ 	    charType = 'q';
+ 	}
+     }
+ 
+   else
+     abort ();
+ 
+   sprintf (buffer, "b%d%c%d", position, charType, size);
+   obstack_grow (&util_obstack, buffer, strlen (buffer));
+ }
+ 
+ static void
  encode_field_decl (field_decl, curtype, format)
       tree field_decl;
       int curtype;
***************
*** 6826,6843 ****
  {
    tree type;
  
!  /* If this field is obviously a bitfield, or is a bitfield that has been
       clobbered to look like a ordinary integer mode, go ahead and generate
       the bitfield typing information.  */
!   type = TREE_TYPE (field_decl);
!   if (DECL_BIT_FIELD (field_decl))
!     encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
!   else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
! 	   && DECL_FIELD_SIZE (field_decl)
! 	   && TYPE_MODE (type) > DECL_MODE (field_decl))
!     encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
    else
!     encode_type (TREE_TYPE (field_decl), curtype, format);
  }
  
  static tree
--- 6902,6937 ----
  {
    tree type;
  
!   type = TREE_TYPE (field_decl);
! 
!   /* If this field is obviously a bitfield, or is a bitfield that has been
       clobbered to look like a ordinary integer mode, go ahead and generate
       the bitfield typing information.  */
!   if (flag_next_runtime)
!     {
!       if (DECL_BIT_FIELD (field_decl))
! 	encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
!       else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
! 	       && DECL_FIELD_SIZE (field_decl)
! 	       && TYPE_MODE (type) > DECL_MODE (field_decl))
! 	encode_bitfield (DECL_FIELD_SIZE (field_decl), format);
!       else
! 	encode_type (TREE_TYPE (field_decl), curtype, format);
!     }
    else
!     {
!       if (DECL_BIT_FIELD (field_decl)
! 	  || (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
! 	      && DECL_FIELD_SIZE (field_decl)
! 	      && TYPE_MODE (type) > DECL_MODE (field_decl)))
! 	{
! 	  encode_complete_bitfield (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)),
! 				    DECL_BIT_FIELD_TYPE (field_decl),
! 				    DECL_FIELD_SIZE (field_decl));
! 	}
!       else
! 	encode_type (TREE_TYPE (field_decl), curtype, format);
!     }
  }
  
  static tree
diff -rcP egcs/gcc/objc/objc-api.h egcs-1.1-objc-gc/gcc/objc/objc-api.h
*** egcs/gcc/objc/objc-api.h	Fri Jul  3 12:47:55 1998
--- egcs-1.1-objc-gc/gcc/objc/objc-api.h	Fri Jul  3 13:31:26 1998
***************
*** 59,64 ****
--- 59,66 ----
  #define _C_UINT     'I'
  #define _C_LNG      'l'
  #define _C_ULNG     'L'
+ #define _C_LNG_LNG  'q'
+ #define _C_ULNG_LNG 'Q'
  #define _C_FLT      'f'
  #define _C_DBL      'd'
  #define _C_BFLD     'b'
***************
*** 494,499 ****
--- 496,512 ----
    if (CLS_ISCLASS(class))
      class->version = version;
  }
+ 
+ static inline void *
+ class_get_gc_object_type (Class class)
+ {
+   return CLS_ISCLASS(class) ? class->gc_object_type : NULL;
+ }
+ 
+ /* Mark the instance variable as innaccessible to the garbage collector */
+ extern void class_ivar_set_gcinvisible (Class class,
+ 					const char* ivarname,
+ 					BOOL gcInvisible);
  
  static inline IMP
  method_get_imp(Method_t method)
diff -rcP egcs/gcc/objc/objc-features.texi egcs-1.1-objc-gc/gcc/objc/objc-features.texi
*** egcs/gcc/objc/objc-features.texi	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/objc/objc-features.texi	Fri Jul  3 13:31:26 1998
***************
*** 0 ****
--- 1,392 ----
+ \input texinfo  @c -*-texinfo-*-
+ @c %**start of header 
+ @setfilename objc-features.info
+ @settitle GNU Objective-C runtime features
+ @setchapternewpage odd
+ @c %**end of header
+      
+ @node Top, Executing code before main, , (dir), (dir)
+ @comment  node-name,  next,  previous,  up
+ 
+ @chapter GNU Objective-C runtime features
+ 
+ This document is meant to describe some of the GNU Objective-C runtime
+ features. It is not intended to teach you Objective-C, there are several
+ resources on the Internet that present the language.  Questions and
+ comments about this document to Ovidiu Predescu
+ @code{<ovidiu@@aracnet.com>}.
+ 
+ @menu
+ * Executing code before main::
+ * Type encoding::
+ * Garbage Collection::
+ @end menu
+ 
+ 
+ @node Executing code before main, What you can and what you cannot do in +load, Top, Top
+ @section @code{+load}: Executing code before main
+ 
+ 
+ The GNU Objective-C runtime provides a way that allows you to execute
+ code before the execution of the program enters the @code{main}
+ function. The code is executed on a per-class and a per-category basis,
+ through a special class method @code{+load}.
+ 
+ This facility is very useful if you want to initialize global variables
+ which can be accessed by the program directly, without sending a message
+ to the class first. The usual way to initialize global variables, in the
+ @code{+initialize} method, might not be useful because
+ @code{+initialize} is only called when the first message is sent to a
+ class object, which in some cases could be too late.
+ 
+ Suppose for example you have a @code{FileStream} class that declares
+ @code{Stdin}, @code{Stdout} and @code{Stderr} as global variables, like
+ below:
+ 
+ @example
+             
+ FileStream *Stdin = nil;                                              
+ FileStream *Stdout = nil;                                          
+ FileStream *Stderr = nil;                                                
+             
+ @@implementation FileStream                                               
+           
+ + (void)initialize                                                 
+ @{
+     Stdin = [[FileStream new] initWithFd:0];                           
+     Stdout = [[FileStream new] initWithFd:1];                           
+     Stderr = [[FileStream new] initWithFd:2];
+ @}
+  
+ /* Other methods here */
+ @@end
+ 
+ @end example
+ 
+ In this example, the initialization of @code{Stdin}, @code{Stdout} and
+ @code{Stderr} in @code{+initialize} occurs too late. The programmer can
+ send a message to one of these objects before the variables are actually
+ initialized, thus sending messages to the @code{nil} object. The
+ @code{+initialize} method which actually initializes the global
+ variables is not invoked until the first message is sent to the class
+ object. The solution would require these variables to be initialized
+ just before entering @code{main}.
+ 
+ The correct solution of the above problem is to use the @code{+load}
+ method instead of @code{+initialize}:
+ 
+ @example
+ 
+ @@implementation FileStream                                             
+  
+ + (void)load                                 
+ @{
+     Stdin = [[FileStream new] initWithFd:0];
+     Stdout = [[FileStream new] initWithFd:1];
+     Stderr = [[FileStream new] initWithFd:2];
+ @}
+  
+ /* Other methods here */                                               
+ @@end
+ 
+ @end example
+  
+ The @code{+load} is a method that is not overridden by categories. If a
+ class and a category of it both implement @code{+load}, both methods are
+ invoked.  This allows some additional initializations to be performed in
+ a category.
+    
+ This mechanism is not intended to be a replacement for @code{+initialize}.
+ You should be aware of its limitations when you decide to use it
+ instead of @code{+initialize}.
+ 
+ @menu
+ * What you can and what you cannot do in +load::
+ @end menu
+ 
+ 
+ @node What you can and what you cannot do in +load, Type encoding, Executing code before main, Executing code before main
+ @subsection What you can and what you cannot do in @code{+load}
+ 
+ The +load implementation in the GNU runtime guarantees you the following
+ things:
+ 
+ @itemize @bullet
+ 
+ @item
+ you can write whatever C code you like;
+ 
+ @item
+ you can send messages to Objective-C constant strings (@@"this is a
+ constant string");
+ 
+ @item
+ you can allocate and send messages to objects whose class is implemented
+ in the same file;
+ 
+ @item
+ the @code{+load} implementation of all super classes of a class are executed before the @code{+load} of that class is executed;
+ 
+ @item
+ the @code{+load} implementation of a class is executed before the
+ @code{+load} implementation of any category.
+ 
+ @end itemize
+ 
+ In particular, the following things, even if they can work in a
+ particular case, are not guaranteed:
+ 
+ @itemize @bullet
+ 
+ @item
+ allocation of or sending messages to arbitrary objects;
+ 
+ @item
+ allocation of or sending messages to objects whose classes have a
+ category implemented in the same file;
+ 
+ @end itemize
+ 
+ You should make no assumptions about receiving @code{+load} in sibling
+ classes when you write @code{+load} of a class. The order in which
+ sibling classes receive @code{+load} is not guaranteed.
+     
+ The order in which @code{+load} and @code{+initialize} are called could
+ be problematic if this matters. If you don't allocate objects inside
+ @code{+load}, it is guaranteed that @code{+load} is called before
+ @code{+initialize}. If you create an object inside @code{+load} the
+ @code{+initialize} method of object's class is invoked even if
+ @code{+load} was not invoked. Note if you explicitly call @code{+load}
+ on a class, @code{+initialize} will be called first. To avoid possible
+ problems try to implement only one of these methods.
+ 
+ The @code{+load} method is also invoked when a bundle is dynamically
+ loaded into your running program. This happens automatically without any
+ intervening operation from you. When you write bundles and you need to
+ write @code{+load} you can safely create and send messages to objects whose
+ classes already exist in the running program. The same restrictions as
+ above apply to classes defined in bundle.
+ 
+ 
+ 
+ @node Type encoding, Garbage Collection, What you can and what you cannot do in +load, Top
+ @section Type encoding
+ 
+ The Objective-C compiler generates type encodings for all the
+ types. These type encodings are used at runtime to find out information
+ about selectors and methods and about objects and classes.
+ 
+ The types are encoded in the following way:
+ 
+ @c @sp 1
+ 
+ @multitable @columnfractions .25 .75
+ @item @code{char}                      
+ @tab @code{c}
+ @item @code{unsigned char}             
+ @tab @code{C}
+ @item @code{short}                     
+ @tab @code{s}
+ @item @code{unsigned short}            
+ @tab @code{S}
+ @item @code{int}                       
+ @tab @code{i}
+ @item @code{unsigned int}              
+ @tab @code{I}
+ @item @code{long}                      
+ @tab @code{l}
+ @item @code{unsigned long}             
+ @tab @code{L}
+ @item @code{long long}                 
+ @tab @code{q}
+ @item @code{unsigned long long}        
+ @tab @code{Q}
+ @item @code{float}                     
+ @tab @code{f}
+ @item @code{double}                    
+ @tab @code{d}
+ @item @code{void}                      
+ @tab @code{v}
+ @item @code{id}                        
+ @tab @code{@@}
+ @item @code{Class}                     
+ @tab @code{#}
+ @item @code{SEL}                       
+ @tab @code{:}
+ @item @code{char*}                     
+ @tab @code{*}
+ @item unknown type                     
+ @tab @code{?}
+ @item bitfields                 
+ @tab @code{b} followed by the starting position of the bitfield, the type of the bitfield and the size of the bitfield (the bitfields encoding was changed from the NeXT's compiler encoding, see below)
+ @end multitable
+ 
+ @c @sp 1
+ 
+ The encoding of bitfields has changed to allow bitfields to be properly
+ handled by the runtime functions that compute sizes and alignments of
+ types that contain bitfields. The previous encoding contained only the
+ size of the bitfield. Using only this information it is not possible to
+ reliably compute the size occupied by the bitfield. This is very
+ important in the presence of the Boehm's garbage collector because the
+ objects are allocated using the typed memory facility available in this
+ collector. The typed memory allocation requires information about where
+ the pointers are located inside the object.
+ 
+ The position in the bitfield is the position, counting in bits, of the
+ bit closest to the beginning of the structure.
+ 
+ The non-atomic types are encoded as follows:
+ 
+ @c @sp 1
+ 
+ @multitable @columnfractions .2 .8
+ @item pointers          
+ @tab @code{'^'} followed by the pointed type.
+ @item arrays
+ @tab @code{'['} followed by the number of elements in the array followed by the type of the elements followed by @code{']'}
+ @item structures
+ @tab @code{'@{'} followed by the name of the structure (or '?' if the structure is unnamed), the '=' sign, the type of the members and by @code{'@}'}
+ @item unions
+ @tab @code{'('} followed by the name of the structure (or '?' if the union is unnamed), the '=' sign, the type of the members followed by @code{')'}
+ @end multitable
+ 
+ Here are some types and their encodings, as they are generated by the
+ compiler on a i386 machine:
+ 
+ @sp 1
+ 
+ @multitable @columnfractions .25 .75
+ @item Objective-C type
+ @tab Compiler encoding
+ @item
+ @example
+ int a[10];
+ @end example
+ @tab @code{[10i]}
+ @item
+ @example
+ struct @{
+   int i;
+   float f[3];
+   int a:3;
+   int b:2;
+   char c;
+ @}
+ @end example
+ @tab @code{@{?=i[3f]b128i3b131i2c@}}
+ @end multitable
+ 
+ @sp 1
+ 
+ In addition to the types the compiler also encodes the type
+ specifiers. The table below describes the encoding of the current
+ Objective-C type specifiers:
+ 
+ @sp 1
+ 
+ @multitable @columnfractions .25 .75
+ @item Specifier
+ @tab Encoding
+ @item @code{const}              
+ @tab @code{r}
+ @item @code{in}                 
+ @tab @code{n}
+ @item @code{inout}              
+ @tab @code{N}
+ @item @code{out}                
+ @tab @code{o}
+ @item @code{bycopy}             
+ @tab @code{O}
+ @item @code{oneway}             
+ @tab @code{V}
+ @end multitable
+ 
+ @sp 1
+ 
+ The type specifiers are encoded just before the type. Unlike types
+ however, the type specifiers are only encoded when they appear in method
+ argument types.
+ 
+ 
+ @node Garbage Collection, , Type encoding, Top
+ 
+ @page
+ @section Garbage Collection
+ 
+ Support for a new memory management policy has been added by using a
+ powerful conservative garbage collector, known as the
+ Boehm-Demers-Weiser conservative garbage collector. It is available from
+ @w{@url{http://reality.sgi.com/employees/boehm_mti/gc.html}}.
+ 
+ To enable the support for it you have to configure the compiler using an
+ additional argument, @w{@kbd{--enable-objc-gc}}. You need to have
+ garbage collector installed before building the compiler. This will
+ build an additional runtime library which has several enhancements to
+ support the garbage collector. The new library has a new name,
+ @kbd{libobjc_gc.a} to not conflict with the non-garbage-collected
+ library.
+ 
+ When the garbage collector is used, the objects are allocated using the
+ so-called typed memory allocation mechanism available in the
+ Boehm-Demers-Weiser collector. This mode requires precise information on
+ where pointers are located inside objects. This information is computed
+ once per class, immediately after the class has been initialized.
+ 
+ There is a new runtime function @code{class_ivar_set_gcinvisible()}
+ which can be used to declare a so-called @strong{weak pointer}
+ reference. Such a pointer is basically hidden for the garbage collector;
+ this can be useful in certain situations, especially when you want to
+ keep track of the allocated objects, yet allow them to be
+ collected. This kind of pointers can only be members of objects, you
+ cannot declare a global pointer as a weak reference. Every type which is
+ a pointer type can be declared a weak pointer, including @code{id},
+ @code{Class} and @code{SEL}.
+ 
+ Here is an example of how to use this feature. Suppose you want to
+ implement a class whose instances hold a weak pointer reference; the
+ following class does this:
+ 
+ @example
+ 
+ @@interface WeakPointer : Object
+ @{
+     const void* weakPointer;
+ @}
+ 
+ - initWithPointer:(const void*)p;
+ - (const void*)weakPointer;
+ @@end
+ 
+ 
+ @@implementation WeakPointer
+ 
+ + (void)initialize
+ @{
+   class_ivar_set_gcinvisible (self, "weakPointer", YES);
+ @}
+ 
+ - initWithPointer:(const void*)p
+ @{
+   weakPointer = p;
+   return self;
+ @}
+ 
+ - (const void*)weakPointer
+ @{
+   return weakPointer;
+ @}
+ 
+ @@end
+ 
+ @end example
+ 
+ Weak pointers are supported through a new type character specifier
+ represented by the @code{'!'} character. The
+ @code{class_ivar_set_gcinvisible()} function adds or removes this
+ specifier to the string type description of the instance variable named
+ as argument.
+ 
+ 
+ @bye
+ 
diff -rcP egcs/gcc/objc/objc.h egcs-1.1-objc-gc/gcc/objc/objc.h
*** egcs/gcc/objc/objc.h	Sat May 16 02:39:06 1998
--- egcs-1.1-objc-gc/gcc/objc/objc.h	Fri Jul  3 13:31:26 1998
***************
*** 126,131 ****
--- 126,132 ----
    struct objc_class* sibling_class;
  
    struct objc_protocol_list *protocols;	      /* Protocols conformed to */
+   void* gc_object_type;
  };
  
  #ifndef __OBJC__
diff -rcP egcs/gcc/objc/objects.c egcs-1.1-objc-gc/gcc/objc/objects.c
*** egcs/gcc/objc/objects.c	Sat May 16 02:39:06 1998
--- egcs-1.1-objc-gc/gcc/objc/objects.c	Fri Jul  3 13:31:26 1998
***************
*** 25,32 ****
--- 25,37 ----
     covered by the GNU General Public License.  */
  
  #include "../tconfig.h"         /* include defs of bzero for target */
+ #include "objc.h"
  #include "runtime.h"		/* the kitchen sink */
  
+ #if OBJC_WITH_GC
+ # include <gc.h>
+ #endif
+ 
  id __objc_object_alloc(Class);
  id __objc_object_dispose(id);
  id __objc_object_copy(id);
***************
*** 39,46 ****
--- 44,59 ----
  class_create_instance(Class class)
  {
    id new = nil;
+ 
+ #if OBJC_WITH_GC
+   if (CLS_ISCLASS(class))
+     new = (id)GC_malloc_explicitly_typed (class->instance_size,
+ 					  class->gc_object_type);
+ #else
    if (CLS_ISCLASS(class))
      new = (*_objc_object_alloc)(class);
+ #endif
+ 
    if (new!=nil)
      {
        memset (new, 0, class->instance_size);
diff -rcP egcs/gcc/objc/sendmsg.c egcs-1.1-objc-gc/gcc/objc/sendmsg.c
*** egcs/gcc/objc/sendmsg.c	Fri Jul  3 12:47:55 1998
--- egcs-1.1-objc-gc/gcc/objc/sendmsg.c	Fri Jul  3 13:31:26 1998
***************
*** 244,253 ****
        /* Install real dtable for factory methods */
        __objc_install_dispatch_table_for_class (receiver->class_pointer);
  
!       if (strcmp (sel_get_name (op), "initialize"))
! 	__objc_send_initialize((Class)receiver);
!       else
! 	CLS_SETINITIALIZED((Class)receiver);
      }
    objc_mutex_unlock(__objc_runtime_mutex);
  }
--- 244,250 ----
        /* Install real dtable for factory methods */
        __objc_install_dispatch_table_for_class (receiver->class_pointer);
  
!       __objc_send_initialize((Class)receiver);
      }
    objc_mutex_unlock(__objc_runtime_mutex);
  }
***************
*** 273,308 ****
      {
        CLS_SETINITIALIZED(class);
        CLS_SETINITIALIZED(class->class_pointer);
!       
        if(class->super_class)
  	__objc_send_initialize(class->super_class);
  
        {
! 	SEL 	op = sel_register_name ("initialize");
! 	Class	tmpclass = class;
! 	IMP	imp = 0;
! 
! 	while (!imp && tmpclass) {
! 	  MethodList_t method_list = tmpclass->class_pointer->methods;
! 
! 	  while(!imp && method_list) {
! 	    int i;
! 	    Method_t method;
! 
! 	    for (i=0;i<method_list->method_count;i++) {
! 	      method = &(method_list->method_list[i]);
! 	      if (method->method_name
! 		  && method->method_name->sel_id == op->sel_id) {
! 	        imp = method->method_imp;
! 	        break;
! 	      }
! 	    }
  
! 	    method_list = method_list->method_next;
  
! 	  }
  
- 	  tmpclass = tmpclass->super_class;
  	}
  	if (imp)
  	    (*imp)((id)class, op);
--- 270,305 ----
      {
        CLS_SETINITIALIZED(class);
        CLS_SETINITIALIZED(class->class_pointer);
! 
!       /* Create the garbage collector type memory description */
!       __objc_generate_gc_type_description (class);
! 
        if(class->super_class)
  	__objc_send_initialize(class->super_class);
  
        {
! 	SEL 	     op = sel_register_name ("initialize");
! 	IMP	     imp = 0;
!         MethodList_t method_list = class->class_pointer->methods;
! 
!         while (method_list) {
! 	  int i;
!           Method_t method;
! 
!           for (i = 0; i< method_list->method_count; i++) {
! 	    method = &(method_list->method_list[i]);
!             if (method->method_name
!                 && method->method_name->sel_id == op->sel_id) {
! 	      imp = method->method_imp;
!               break;
!             }
!           }
  
!           if (imp)
!             break;
  
!           method_list = method_list->method_next;
  
  	}
  	if (imp)
  	    (*imp)((id)class, op);
diff -rcP egcs/gcc/testsuite/lib/objc-torture.exp egcs-1.1-objc-gc/gcc/testsuite/lib/objc-torture.exp
*** egcs/gcc/testsuite/lib/objc-torture.exp	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/lib/objc-torture.exp	Fri Jul  3 13:31:26 1998
***************
*** 0 ****
--- 1,316 ----
+ # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997 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 of the License, or
+ # (at your option) any later version.
+ # 
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ # GNU General Public License for more details.
+ # 
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software
+ # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ 
+ # Please email any bugs, comments, and/or additions to this file to:
+ # bug-dejagnu.prep.ai.mit.edu
+ 
+ # This file was written by Rob Savoye. (rob@cygnus.com)
+ 
+ # The default option list can be overridden by
+ # TORTURE_OPTIONS="{ { list1 } ... { listN } }"
+ 
+ if ![info exists TORTURE_OPTIONS] {
+     # FIXME: We should test -g at least once.
+     set TORTURE_OPTIONS [list { -O }]
+ }
+ 
+ 
+ # Split TORTURE_OPTIONS into two choices: one for testcases with loops and
+ # one for testcases without loops.
+ 
+ set torture_with_loops $TORTURE_OPTIONS
+ set torture_without_loops ""
+ foreach option $TORTURE_OPTIONS {
+     if ![string match "*loop*" $option] {
+ 	lappend torture_without_loops $option
+     }
+ }
+ 
+ #
+ # objc-torture-compile -- runs the Tege C-torture test
+ #
+ # SRC is the full pathname of the testcase.
+ # OPTION is the specific compiler flag we're testing (eg: -O2).
+ #
+ proc objc-torture-compile { src option } {
+     global output
+     global srcdir tmpdir
+     global host_triplet
+ 
+     set output "$tmpdir/[file tail [file rootname $src]].o"
+ 
+     regsub "^$srcdir/?" $src "" testcase
+     # If we couldn't rip $srcdir out of `src' then just do the best we can.
+     # The point is to reduce the unnecessary noise in the logs.  Don't strip
+     # out too much because different testcases with the same name can confuse
+     # `test-tool'.
+     if [string match "/*" $testcase] {
+ 	set testcase "[file tail [file dirname $src]]/[file tail $src]"
+     }
+ 
+     verbose "Testing $testcase, $option" 1
+ 
+     # Run the compiler and analyze the results.
+     set options ""
+     lappend options "additional_flags=-w $option"
+ 
+     set comp_output [objc_target_compile "$src" "$output" object $options];
+     
+     # Set a few common compiler messages.
+     set fatal_signal "*77*: Internal compiler error: program*got fatal signal"
+  
+     if [string match "$fatal_signal 6" $comp_output] then {
+ 	objc_fail $testcase "Got Signal 6, $option"
+ 	remote_file build delete $output
+ 	return
+     }
+ 
+     if [string match "$fatal_signal 11" $comp_output] then {
+ 	objc_fail $testcase "Got Signal 11, $option"
+ 	remote_file build delete $output
+ 	return
+     }
+ 
+     # We shouldn't get these because of -w, but just in case.
+     if [string match "*77*:*warning:*" $comp_output] then {
+ 	warning "$testcase: (with warnings) $option"
+ 	send_log "$comp_output\n"
+ 	unresolved "$testcase, $option"
+ 	remote_file build delete $output
+ 	return
+     }
+ 
+     set comp_output [prune_warnings $comp_output]
+ 
+     set unsupported_message [objc_check_unsupported_p $comp_output]
+     if { $unsupported_message != "" } {
+ 	unsupported "$testcase: $unsupported_message"
+ 	remote_file build delete $output
+ 	return
+     }
+ 
+     # remove any leftover LF/CR to make sure any output is legit
+     regsub -all -- "\[\r\n\]*" $comp_output "" comp_output
+     # If any message remains, we fail.
+     if ![string match "" $comp_output] then {
+ 	objc_fail $testcase $option
+ 	remote_file build delete $output
+ 	return
+     }
+ 
+     objc_pass $testcase $option
+     remote_file build delete $output
+ }
+ 
+ #
+ # objc-torture-execute -- utility to compile and execute a testcase
+ #
+ # SRC is the full pathname of the testcase.
+ #
+ # If the testcase has an associated .cexp file, we source that to run the
+ # test instead.  We use .cexp instead of .exp so that the testcase is still
+ # controlled by the main .exp driver (this is useful when one wants to only
+ # run the compile.exp tests for example - one need only pass compile.exp to
+ # dejagnu, and not compile.exp, foo1.exp, foo2.exp, etc.).
+ #
+ proc objc-torture-execute { src } {
+     global tmpdir tool srcdir output 
+ 
+     # Check for alternate driver.
+     if [file exists [file rootname $src].cexp] {
+ 	verbose "Using alternate driver [file rootname [file tail $src]].cexp" 2
+ 	set done_p 0
+ 	catch "set done_p \[source [file rootname $src].cexp\]"
+ 	if { $done_p } {
+ 	    return
+ 	}
+     }
+    
+     # Look for a loop within the source code - if we don't find one,
+     # don't pass -funroll[-all]-loops.
+     global torture_with_loops torture_without_loops
+     if [expr [search_for $src "do *\[0-9\]"]+[search_for $src "end *do"]] then {
+ 	set option_list $torture_with_loops
+     } else {
+ 	set option_list $torture_without_loops
+     }
+ 
+     set executable $tmpdir/[file tail [file rootname $src].x]
+ 
+     regsub "^$srcdir/?" $src "" testcase
+     # If we couldn't rip $srcdir out of `src' then just do the best we can.
+     # The point is to reduce the unnecessary noise in the logs.  Don't strip
+     # out too much because different testcases with the same name can confuse
+     # `test-tool'.
+     if [string match "/*" $testcase] {
+ 	set testcase "[file tail [file dirname $src]]/[file tail $src]"
+     }
+ 
+     foreach option $option_list {
+ 	# torture_{compile,execute}_xfail are set by the .cexp script
+ 	# (if present)
+ 	if [info exists torture_compile_xfail] {
+ 	    setup_xfail $torture_compile_xfail
+ 	}
+ 	remote_file build delete $executable
+ 	verbose "Testing $testcase, $option" 1
+ 
+ 	set options ""
+ 	lappend options "additional_flags=-w $option"
+ 	set comp_output [objc_target_compile "$src" "$executable" executable $options];
+ 
+ 	# Set a few common compiler messages.
+ 	set fatal_signal "*77*: Internal compiler error: program*got fatal signal"
+ 	
+ 	if [string match "$fatal_signal 6" $comp_output] then {
+ 	    objc_fail $testcase "Got Signal 6, $option"
+ 	    remote_file build delete $executable
+ 	    continue
+ 	}
+ 	
+ 	if [string match "$fatal_signal 11" $comp_output] then {
+ 	    objc_fail $testcase "Got Signal 11, $option"
+ 	    remote_file build delete $executable
+ 	    continue
+ 	}
+ 	
+ 	# We shouldn't get these because of -w, but just in case.
+ 	if [string match "*77*:*warning:*" $comp_output] then {
+ 	    warning "$testcase: (with warnings) $option"
+ 	    send_log "$comp_output\n"
+ 	    unresolved "$testcase, $option"
+ 	    remote_file build delete $executable
+ 	    continue
+ 	}
+ 	
+ 	set comp_output [prune_warnings $comp_output]
+ 	
+ 	set unsupported_message [objc_check_unsupported_p $comp_output]
+ 
+ 	if { $unsupported_message != "" } {
+ 	    unsupported "$testcase: $unsupported_message"
+ 	    continue
+ 	} elseif ![file exists $executable] {
+ 	    if ![is3way] {
+ 		fail "$testcase compilation, $option"
+ 		untested "$testcase execution, $option"
+ 		continue
+ 	    } else {
+ 		# FIXME: since we can't test for the existance of a remote
+ 		# file without short of doing an remote file list, we assume
+ 		# that since we got no output, it must have compiled.
+ 		pass "$testcase compilation, $option"		
+ 	    }
+ 	} else {
+ 	    pass "$testcase compilation, $option"
+ 	}
+ 
+ 	# See if this source file uses "long long" types, if it does, and
+ 	# no_long_long is set, skip execution of the test.
+ 	if [target_info exists no_long_long] then {
+ 	    if [expr [search_for $src "integer\*8"]] then {
+ 		untested "$testcase execution, $option"
+ 		continue
+ 	    }
+ 	}
+ 
+ 	if [info exists torture_execute_xfail] {
+ 	    setup_xfail $torture_execute_xfail
+ 	}
+ 	
+ 	set result [objc_load "$executable" "" ""]
+ 	set status [lindex $result 0];
+ 	set output [lindex $result 1];
+         if { $status == "pass" } {
+ 	    remote_file build delete $executable
+         }
+ 	$status "$testcase execution, $option"
+     }
+ }
+ 
+ #
+ # search_for -- looks for a string match in a file
+ #
+ proc search_for { file pattern } {
+     set fd [open $file r]
+     while { [gets $fd cur_line]>=0 } {
+ 	set lower [string tolower $cur_line]
+ 	if [regexp "$pattern" $lower] then {
+ 	    close $fd
+ 	    return 1
+ 	}
+     }
+     close $fd
+     return 0
+ }
+ 
+ #
+ # objc-torture -- the objc-torture testcase source file processor
+ #
+ # This runs compilation only tests (no execute tests).
+ # SRC is the full pathname of the testcase, or just a file name in which case
+ # we prepend $srcdir/$subdir.
+ #
+ # If the testcase has an associated .cexp file, we source that to run the
+ # test instead.  We use .cexp instead of .exp so that the testcase is still
+ # controlled by the main .exp driver (this is useful when one wants to only
+ # run the compile.exp tests for example - one need only pass compile.exp to
+ # dejagnu, and not compile.exp, foo1.exp, foo2.exp, etc.).
+ #
+ proc objc-torture { args } {
+     global srcdir subdir
+ 
+     set src [lindex $args 0];
+     if { [llength $args] > 1 } {
+ 	set options [lindex $args 1];
+     } else {
+ 	set options ""
+     }
+ 
+     # Prepend $srdir/$subdir if missing.
+     if ![string match "*/*" $src] {
+ 	set src "$srcdir/$subdir/$src"
+     }
+ 
+     # Check for alternate driver.
+     if [file exists [file rootname $src].cexp] {
+ 	verbose "Using alternate driver [file rootname [file tail $src]].cexp" 2
+ 	set done_p 0
+ 	catch "set done_p \[source [file rootname $src].cexp\]"
+ 	if { $done_p } {
+ 	    return
+ 	}
+     }
+    
+     # Look for a loop within the source code - if we don't find one,
+     # don't pass -funroll[-all]-loops.
+     global torture_with_loops torture_without_loops
+     if [expr [search_for $src "do *\[0-9\]"]+[search_for $src "end *do"]] then {
+ 	set option_list $torture_with_loops
+     } else {
+ 	set option_list $torture_without_loops
+     }
+ 
+     # loop through all the options
+     foreach option $option_list {
+ 	# torture_compile_xfail is set by the .cexp script (if present)
+ 	if [info exists torture_compile_xfail] {
+ 	    setup_xfail $torture_compile_xfail
+ 	}
+ 
+ 	objc-torture-compile $src "$option $options"
+     }
+ }
diff -rcP egcs/gcc/testsuite/lib/objc.exp egcs-1.1-objc-gc/gcc/testsuite/lib/objc.exp
*** egcs/gcc/testsuite/lib/objc.exp	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/lib/objc.exp	Fri Jul  3 13:31:26 1998
***************
*** 0 ****
--- 1,263 ----
+ # Copyright (C) 1992, 1993, 1994, 1996, 1997 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 of the License, or
+ # (at your option) any later version.
+ # 
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ # GNU General Public License for more details.
+ # 
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software
+ # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ 
+ # This file was written by Rob Savoye (rob@cygnus.com)
+ # Currently maintained by Doug Evans (dje@cygnus.com)
+ 
+ # This file is loaded by the tool init file (eg: unix.exp).  It provides
+ # default definitions for objc_start, etc. and other supporting cast members.
+ 
+ # These globals are used by objc_start if no compiler arguments are provided.
+ # They are also used by the various testsuites to define the environment:
+ # where to find stdio.h, libc.a, etc.
+ 
+ #
+ # OBJC_UNDER_TEST is the compiler under test.
+ #
+ 
+ #
+ # default_objc_version -- extract and print the version number of the compiler
+ #
+ 
+ proc default_objc_version { } {
+     global OBJC_UNDER_TEST
+ 
+     objc_init;
+ 
+     # ignore any arguments after the command
+     set compiler [lindex $OBJC_UNDER_TEST 0]
+ 
+     if ![is_remote host] {
+ 	set compiler_name [which $compiler];
+     } else {
+ 	set compiler_name $compiler;
+     }
+ 
+     # verify that the compiler exists
+     if { $compiler_name != 0 } then {
+ 	set tmp [remote_exec host "$compiler -v"]
+ 	set status [lindex $tmp 0];
+ 	set output [lindex $tmp 1];
+ 	regexp "version.*$" $output version
+ 	if { $status == 0 && [info exists version] } then {
+ 	    clone_output "$compiler_name $version\n"
+ 	} else {
+ 	    clone_output "Couldn't determine version of $compiler_name: $output\n"
+ 	}
+     } else {
+ 	# compiler does not exist (this should have already been detected)
+ 	warning "$compiler does not exist"
+     }
+ }
+ 
+ #
+ # Call objc_version. We do it this way so we can override it if needed.
+ #
+ proc objc_version { } {
+     default_objc_version;
+ }
+ 
+ #
+ # objc_init -- called at the start of each .exp script.
+ #
+ # There currently isn't much to do, but always using it allows us to
+ # make some enhancements without having to go back and rewrite the scripts.
+ #
+ 
+ set objc_initialized 0
+ 
+ proc objc_init { args } {
+     global tmpdir
+     global libdir
+     global gluefile wrap_flags
+     global objc_initialized
+     global OBJC_UNDER_TEST
+     global TOOL_EXECUTABLE
+ 
+     if { $objc_initialized == 1 } { return; }
+ 
+     if ![info exists OBJC_UNDER_TEST] then {
+ 	if [info exists TOOL_EXECUTABLE] {
+ 	    set OBJC_UNDER_TEST $TOOL_EXECUTABLE;
+ 	} else {
+ 	    set OBJC_UNDER_TEST [find_gcc]
+ 	}
+     }
+ 
+     if ![info exists tmpdir] then {
+ 	set tmpdir /tmp
+     }
+     if { [target_info needs_status_wrapper]!="" && ![info exists gluefile] } {
+ 	set gluefile ${tmpdir}/testglue.o;
+ 	set result [build_wrapper $gluefile];
+ 	if { $result != "" } {
+ 	    set gluefile [lindex $result 0];
+ 	    set wrap_flags [lindex $result 1];
+ 	} else {
+ 	    unset gluefile
+ 	}
+     }
+ }
+ 
+ proc objc_target_compile { source dest type options } {
+     global tmpdir;
+     global gluefile wrap_flags;
+     global OBJC_UNDER_TEST
+     global TOOL_OPTIONS
+ 
+     lappend options "libs=-lobjc"
+     if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } {
+ 	lappend options "libs=${gluefile}"
+ 	lappend options "ldflags=$wrap_flags"
+     }
+ 
+     if [target_info exists objc,stack_size] {
+ 	lappend options "additional_flags=-DSTACK_SIZE=[target_info objc,stack_size]"
+     }
+     if [target_info exists objc,no_trampolines] {
+ 	lappend options "additional_flags=-DNO_TRAMPOLINES"
+     }
+     if [target_info exists objc,no_label_values] {
+ 	lappend options "additional_flags=-DNO_LABEL_VALUES"
+     }
+     if [info exists TOOL_OPTIONS] {
+ 	lappend options "additional_flags=$TOOL_OPTIONS"
+     }
+     if [target_info exists objc,no_varargs] {
+ 	lappend options "additional_flags=-DNO_VARARGS"
+     }
+     lappend options "compiler=$OBJC_UNDER_TEST"
+     return [target_compile $source $dest $type $options]
+ }
+ 
+ #
+ # objc_pass -- utility to record a testcase passed
+ #
+ 
+ proc objc_pass { testcase cflags } {
+     if { "$cflags" == "" } {
+ 	pass "$testcase"
+     } else {
+ 	pass "$testcase, $cflags"
+     }
+ }
+ 
+ #
+ # objc_fail -- utility to record a testcase failed
+ #
+ 
+ proc objc_fail { testcase cflags } {
+     if { "$cflags" == "" } {
+ 	fail "$testcase"
+     } else {
+ 	fail "$testcase, $cflags"
+     }
+ }
+ 
+ #
+ # objc_finish -- called at the end of every .exp script that calls objc_init
+ #
+ # The purpose of this proc is to hide all quirks of the testing environment
+ # from the testsuites.  It also exists to undo anything that objc_init did
+ # (that needs undoing).
+ #
+ 
+ proc objc_finish { } {
+     # The testing harness apparently requires this.
+     global errorInfo;
+ 
+     if [info exists errorInfo] then {
+ 	unset errorInfo
+     }
+ 
+     # Might as well reset these (keeps our caller from wondering whether
+     # s/he has to or not).
+     global prms_id bug_id
+     set prms_id 0
+     set bug_id 0
+ }
+ 
+ proc objc_exit { } {
+     global gluefile;
+ 
+     if [info exists gluefile] {
+ 	file_on_build delete $gluefile;
+ 	unset gluefile;
+     }
+ }
+     
+ # If this is an older version of dejagnu (without runtest_file_p),
+ # provide one and assume the old syntax: foo1.exp bar1.c foo2.exp bar2.c.
+ # This can be deleted after next dejagnu release.
+ 
+ if { [info procs runtest_file_p] == "" } then {
+     proc runtest_file_p { runtests testcase } {
+ 	if { $runtests != "" && [regexp "\[.\]\[cC\]" $runtests] } then {
+ 	    if { [lsearch $runtests [file tail $testcase]] >= 0 } then {
+ 		return 1
+ 	    } else {
+ 		return 0
+ 	    }
+ 	}
+ 	return 1
+     }
+ }
+ 
+ # Provide a definition of this if missing (delete after next dejagnu release).
+ 
+ if { [info procs prune_warnings] == "" } then {
+     proc prune_warnings { text } {
+ 	return $text
+     }
+ }
+ 
+ # Utility used by mike-gcc.exp and c-torture.exp.
+ # Check the compiler(/assembler/linker) output for text indicating that
+ # the testcase should be marked as "unsupported".
+ #
+ # When dealing with a large number of tests, it's difficult to weed out the
+ # ones that are too big for a particular cpu (eg: 16 bit with a small amount
+ # of memory).  There are various ways to deal with this.  Here's one.
+ # Fortunately, all of the cases where this is likely to happen will be using
+ # gld so we can tell what the error text will look like.
+ 
+ proc ${tool}_check_unsupported_p { output } {
+     if [regexp "(^|\n)\[^\n\]*: region \[^\n\]* is full" $output] {
+ 	return "memory full"
+     }
+     return ""
+ }
+ 
+ # Prune messages from objc that aren't useful.
+ 
+ proc prune_objc_output { text } {
+     #send_user "Before:$text\n"
+     regsub -all "(^|\n)\[^\n\]*: In (function|method) \[^\n\]*" $text "" text
+     regsub -all "(^|\n)\[^\n\]*: At top level:\[^\n\]*" $text "" text
+ 
+     # It would be nice to avoid passing anything to objc that would cause it to
+     # issue these messages (since ignoring them seems like a hack on our part),
+     # but that's too difficult in the general case.  For example, sometimes
+     # you need to use -B to point objc at crt0.o, but there are some targets
+     # that don't have crt0.o.
+     regsub -all "(^|\n)\[^\n\]*file path prefix \[^\n\]* never used" $text "" text
+     regsub -all "(^|\n)\[^\n\]*linker input file unused since linking not done" $text "" text
+ 
+     #send_user "After:$text\n"
+ 
+     return $text
+ }
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-1.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-1.m
*** egcs/gcc/testsuite/objc/execute/bf-1.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-1.m	Fri Jul 17 16:12:14 1998
***************
*** 0 ****
--- 1,24 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a;
+   struct {
+     int i:2;
+     int j:3;
+     int k:12;
+   } flags;
+   char c;
+ //  void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-10.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-10.m
*** egcs/gcc/testsuite/objc/execute/bf-10.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-10.m	Fri Jul 17 16:21:00 1998
***************
*** 0 ****
--- 1,22 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a[3];
+   int i:2;
+   int j:6;
+   char c;
+   int k:12;
+   char d;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-11.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-11.m
*** egcs/gcc/testsuite/objc/execute/bf-11.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-11.m	Fri Jul 17 16:21:18 1998
***************
*** 0 ****
--- 1,23 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a[3];
+   int i:2;
+   int j:6;
+   short s;
+   int k:12;
+   char d;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-12.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-12.m
*** egcs/gcc/testsuite/objc/execute/bf-12.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-12.m	Fri Jul 17 16:21:34 1998
***************
*** 0 ****
--- 1,23 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a[3];
+   int i:2;
+   int j:6;
+   int s;
+   int k:12;
+   char d;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-13.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-13.m
*** egcs/gcc/testsuite/objc/execute/bf-13.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-13.m	Fri Jul 17 16:21:46 1998
***************
*** 0 ****
--- 1,25 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a[3];
+   struct {
+     int i:2;
+     int j:6;
+     char s;
+     int k:12;
+   } flags;
+   char d;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-14.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-14.m
*** egcs/gcc/testsuite/objc/execute/bf-14.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-14.m	Fri Jul 17 16:22:01 1998
***************
*** 0 ****
--- 1,25 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a[3];
+   struct {
+     int i:2;
+     int j:6;
+     short s;
+     int k:12;
+   } flags;
+   char d;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-15.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-15.m
*** egcs/gcc/testsuite/objc/execute/bf-15.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-15.m	Fri Jul 17 16:22:13 1998
***************
*** 0 ****
--- 1,25 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a;
+   struct {
+     int i:2;
+     int j:6;
+     int s;
+     int k:12;
+   } flags;
+   char d;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-16.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-16.m
*** egcs/gcc/testsuite/objc/execute/bf-16.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-16.m	Fri Jul 17 16:22:26 1998
***************
*** 0 ****
--- 1,26 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ struct A {
+   int i;
+   float f;
+   int a:3;
+   int b:2;
+ };
+ 
+ @interface MyObject
+ {
+   Class isa;
+   int i;
+   float f[3];
+   struct A a, b;
+   char c;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-17.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-17.m
*** egcs/gcc/testsuite/objc/execute/bf-17.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-17.m	Fri Jul 17 16:22:41 1998
***************
*** 0 ****
--- 1,25 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ struct A {
+   int i;
+   float f;
+   int a:3;
+   int b:2;
+ };
+ 
+ @interface MyObject
+ {
+   Class isa;
+   int i;
+   float f[3];
+   struct A a;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-18.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-18.m
*** egcs/gcc/testsuite/objc/execute/bf-18.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-18.m	Thu Jul 23 00:39:43 1998
***************
*** 0 ****
--- 1,17 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   int i;
+   char c[1];
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-19.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-19.m
*** egcs/gcc/testsuite/objc/execute/bf-19.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-19.m	Thu Jul 23 20:31:04 1998
***************
*** 0 ****
--- 1,17 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   unsigned int i;
+   MyObject *object;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-2.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-2.m
*** egcs/gcc/testsuite/objc/execute/bf-2.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-2.m	Fri Jul 17 22:21:41 1998
***************
*** 0 ****
--- 1,24 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a[3];
+   struct {
+     int i:2;
+     int j:3;
+     int k:12;
+   } flags;
+   char c;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-3.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-3.m
*** egcs/gcc/testsuite/objc/execute/bf-3.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-3.m	Fri Jul 17 16:20:09 1998
***************
*** 0 ****
--- 1,24 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a;
+   struct {
+     int i:2;
+     int j:6;
+     int k:12;
+   } flags;
+   char c;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-4.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-4.m
*** egcs/gcc/testsuite/objc/execute/bf-4.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-4.m	Fri Jul 17 16:23:00 1998
***************
*** 0 ****
--- 1,24 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a[3];
+   struct {
+     int i:2;
+     int j:6;
+     int k:12;
+   } flags;
+   char c;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-5.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-5.m
*** egcs/gcc/testsuite/objc/execute/bf-5.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-5.m	Fri Jul 17 16:23:14 1998
***************
*** 0 ****
--- 1,22 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a;
+   int i:2;
+   int j:3;
+   int k:12;
+   char c;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-6.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-6.m
*** egcs/gcc/testsuite/objc/execute/bf-6.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-6.m	Fri Jul 17 16:23:36 1998
***************
*** 0 ****
--- 1,22 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a[3];
+   int i:2;
+   int j:3;
+   int k:12;
+   char c;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-7.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-7.m
*** egcs/gcc/testsuite/objc/execute/bf-7.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-7.m	Fri Jul 17 16:23:50 1998
***************
*** 0 ****
--- 1,22 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a;
+   int i:2;
+   int j:6;
+   int k:12;
+   char c;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-8.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-8.m
*** egcs/gcc/testsuite/objc/execute/bf-8.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-8.m	Fri Jul 17 16:24:02 1998
***************
*** 0 ****
--- 1,22 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a[3];
+   int i:2;
+   int j:6;
+   int k:12;
+   char c;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-9.m egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-9.m
*** egcs/gcc/testsuite/objc/execute/bf-9.m	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-9.m	Fri Jul 17 16:24:12 1998
***************
*** 0 ****
--- 1,23 ----
+ #include <objc/objc.h>
+ #include <objc/objc-api.h>
+ #include <objc/Object.h>
+ 
+ @interface MyObject
+ {
+   Class isa;
+   float f;
+   char a[3];
+   int i:2;
+   int j:3;
+   char c;
+   int k:12;
+   char d;
+   void *pointer;
+ }
+ @end
+ 
+ @implementation MyObject
+ @end
+ 
+ #include "bf-common.h"
+ 
diff -rcP egcs/gcc/testsuite/objc/execute/bf-common.h egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-common.h
*** egcs/gcc/testsuite/objc/execute/bf-common.h	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/bf-common.h	Thu Jul 30 19:06:28 1998
***************
*** 0 ****
--- 1,76 ----
+ #include <objc/encoding.h>
+ 
+ 
+ void print_ivars (Class class)
+ {
+   struct objc_ivar_list* ivars = class->ivars;
+   int i;
+ 
+   for (i = 0; i < ivars->ivar_count; i++) {
+     struct objc_ivar *ivar = &(ivars->ivar_list[i]);
+     printf ("ivar '%s', type '%s', offset %d\n",
+ 	    ivar->ivar_name, ivar->ivar_type, ivar->ivar_offset);
+   }
+ }
+ 
+ void compare_structures (Class class, const char* type)
+ {
+   struct objc_struct_layout layout;
+   struct objc_ivar_list* ivars = class->ivars;
+   int i = 0;
+   int position;
+ 
+   objc_layout_structure (type, &layout);
+ 
+   while (objc_layout_structure_next_member (&layout))
+     {
+       struct objc_ivar *ivar;
+       const char *ivar_type;
+ 
+       if (i > ivars->ivar_count)
+         {
+           printf ("too many ivars in type %s, layout = %s\n",
+                   type, layout.type);
+           exit (1);
+         }
+ 
+       ivar = &(ivars->ivar_list[i]);
+       objc_layout_structure_get_info (&layout, &position, NULL, &ivar_type);
+       printf ("real ivar '%s' offset %d\n",
+               ivar->ivar_name, ivar->ivar_offset);
+       printf ("computed type '%s' offset %d\n", ivar_type, position);
+       if (position != ivar->ivar_offset)
+         {
+           printf ("offset %d and computed position %d don't match on ivar '%s'"
+                   " (i = %d)\n",
+                   ivar->ivar_offset, position, ivar->ivar_name, i);
+           exit (1);
+         }
+       i++;
+     }
+   
+   printf ("%d ivars checked\n", i);
+ }
+ 
+ int main ()
+ {
+   struct class_vars
+     {
+       @defs (MyObject);
+     };
+   int size1, size2;
+   Class class = [MyObject class];
+ 
+   printf ("type = %s\n", @encode (struct class_vars));
+   print_ivars (class);
+ 
+   compare_structures (class, @encode(struct class_vars));
+   if ((size1 = objc_sizeof_type (@encode(struct class_vars)))
+       != (size2 = sizeof (struct class_vars)))
+     {
+       printf ("sizes don't match (computed %d, exact %d)\n", size1, size2);
+       abort ();
+     }
+   
+   exit (0);
+ }
diff -rcP egcs/gcc/testsuite/objc/execute/execute.exp egcs-1.1-objc-gc/gcc/testsuite/objc/execute/execute.exp
*** egcs/gcc/testsuite/objc/execute/execute.exp	Wed Dec 31 16:00:00 1969
--- egcs-1.1-objc-gc/gcc/testsuite/objc/execute/execute.exp	Fri Jul  3 13:31:27 1998
***************
*** 0 ****
--- 1,42 ----
+ # Copyright (C) 1991, 1992, 1993, 1995, 1997 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 of the License, or
+ # (at your option) any later version.
+ # 
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ # GNU General Public License for more details.
+ # 
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ 
+ # Please email any bugs, comments, and/or additions to this file to:
+ # bug-gcc@prep.ai.mit.edu
+ 
+ # This file was written by Rob Savoye. (rob@cygnus.com)
+ # Modified by Ovidiu Predescu (ovidiu@aracnet.com)
+ 
+ 
+ if $tracelevel then {
+     strace $tracelevel
+ }
+ 
+ # load support procs
+ load_lib objc-torture.exp
+ 
+ #
+ # main test loop
+ #
+ 
+ foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.m]] {
+     # If we're only testing specific files and this isn't one of them, skip it.
+     if ![runtest_file_p $runtests $src] then {
+ 	continue
+     }
+ 
+     objc-torture-execute $src
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]