diff options
Diffstat (limited to 'contrib/gcc/objc')
35 files changed, 0 insertions, 17379 deletions
diff --git a/contrib/gcc/objc/Make-lang.in b/contrib/gcc/objc/Make-lang.in deleted file mode 100644 index 9a84f0f59caa..000000000000 --- a/contrib/gcc/objc/Make-lang.in +++ /dev/null @@ -1,165 +0,0 @@ -# Top level makefile fragment for GNU Objective-C -# Copyright (C) 1997, 1998 Free Software Foundation, Inc. - -#This file is part of GNU CC. - -#GNU CC is free software; you can redistribute it and/or modify -#it under the terms of the GNU General Public License as published by -#the Free Software Foundation; either version 2, or (at your option) -#any later version. - -#GNU CC is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. - -#You should have received a copy of the GNU General Public License -#along with GNU CC; see the file COPYING. If not, write to -#the Free Software Foundation, 59 Temple Place - Suite 330, -#Boston, MA 02111-1307, USA. - -# This file provides the language dependent support in the main Makefile. -# Each language makefile fragment must provide the following targets: -# -# foo.all.build, foo.all.cross, foo.start.encap, foo.rest.encap, -# foo.info, foo.dvi, -# foo.install-normal, foo.install-common, foo.install-info, foo.install-man, -# foo.uninstall, foo.distdir, -# foo.mostlyclean, foo.clean, foo.distclean, foo.extraclean, -# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4 -# -# where `foo' is the name of the language. -# -# It should also provide rules for: -# -# - making any compiler driver (eg: g++) -# - the compiler proper (eg: cc1plus) -# - define the names for selecting the language in LANGUAGES. -# -# Extra flags to pass to recursive makes. -OBJC_FLAGS_TO_PASS = \ - "OBJC_FOR_BUILD=$(OBJC_FOR_BUILD)" \ - "OBJCFLAGS=$(OBJCFLAGS)" \ - "OBJC_FOR_TARGET=$(OBJC_FOR_TARGET)" \ - -# Actual names to use when installing a native compiler. -#OBJC_INSTALL_NAME = `t='$(program_transform_name)'; echo c++ | sed $$t` - -# Actual names to use when installing a cross-compiler. -#OBJC_CROSS_NAME = `t='$(program_transform_cross_name)'; echo c++ | sed $$t` - -# -# Define the names for selecting Objective-C in LANGUAGES. -OBJC objc: cc1obj$(exeext) -OBJECTIVE-C objective-c: cc1obj$(exeext) - -# Tell GNU make to ignore these if they exist. -.PHONY: objective-c objc ObjC - -# Language-specific object files for Objective C. -OBJC_OBJS = objc-parse.o objc-act.o $(C_AND_OBJC_OBJS) - -cc1obj$(exeext): $(P) $(OBJS) $(OBJC_OBJS) $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(OBJC_OBJS) $(LIBS) - -# Objective C language specific files. - -objc-parse.o : $(srcdir)/objc/objc-parse.c \ - $(CONFIG_H) $(TREE_H) $(srcdir)/toplev.h \ - $(srcdir)/c-lex.h $(srcdir)/c-tree.h $(srcdir)/input.h \ - $(srcdir)/flags.h $(srcdir)/output.h $(srcdir)/objc/objc-act.h system.h - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \ - -c $(srcdir)/objc/objc-parse.c - -$(INTL_TARGETS): $(srcdir)/objc/objc-parse.c -$(srcdir)/objc/objc-parse.c : $(srcdir)/objc/objc-parse.y - cd $(srcdir)/objc; \ - $(BISON) $(BISONFLAGS) -o objc-parse.c objc-parse.y - -$(srcdir)/objc/objc-parse.y: $(srcdir)/c-parse.in - echo '/*WARNING: This file is automatically generated!*/' >tmp-objc-prs.y - sed -e "/^ifc$$/,/^end ifc$$/d" \ - -e "/^ifobjc$$/d" -e "/^end ifobjc$$/d" \ - $(srcdir)/c-parse.in >>tmp-objc-prs.y - $(srcdir)/move-if-change tmp-objc-prs.y $(srcdir)/objc/objc-parse.y - -objc-act.o : $(srcdir)/objc/objc-act.c \ - $(CONFIG_H) $(TREE_H) $(RTL_H) system.h \ - $(srcdir)/c-tree.h $(srcdir)/c-lex.h $(srcdir)/toplev.h \ - $(srcdir)/flags.h $(srcdir)/objc/objc-act.h $(srcdir)/input.h \ - $(srcdir)/function.h $(srcdir)/output.h $(srcdir)/c-parse.h - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \ - -c $(srcdir)/objc/objc-act.c - -# -# Build hooks: - -objc.all.build: -objc.all.cross: -objc.start.encap: -objc.rest.encap: - -objc.info: -objc.dvi: - -# -# Install hooks: -# cc1obj is installed elsewhere as part of $(COMPILERS). - -objc.install-normal: - -objc.install-common: - -objc.install-info: - -objc.install-man: - -objc.uninstall: -# -# Clean hooks: -# A lot of the ancillary files are deleted by the main makefile. -# We just have to delete files specific to us. -objc.mostlyclean: - -rm -f tmp-objc-prs.y - -rm -f objc/*$(objext) objc/xforward objc/fflags -objc.clean: objc.mostlyclean - -rm -rf objc-headers -objc.distclean: - -rm -f objc/Makefile objc/Make-host objc/Make-target - -rm -f objc/config.status objc/config.cache - -rm -f objc-parse.output -objc.extraclean: -objc.maintainer-clean: - -rm -f objc/objc-parse.y - -rm -f objc/objc-parse.c objc/objc-parse.output - -# -# Stage hooks: - -objc.stage1: stage1-start - -mv objc/*$(objext) stage1/objc - -mv cc1obj$(exeext) stage1 -objc.stage2: stage2-start - -mv objc/*$(objext) stage2/objc - -mv cc1obj$(exeext) stage2 -objc.stage3: stage3-start - -mv objc/*$(objext) stage3/objc - -mv cc1obj$(exeext) stage3 -objc.stage4: stage4-start - -mv objc/*$(objext) stage4/objc - -mv cc1obj$(exeext) stage4 - -# -# Maintenance hooks: - -# This target creates the files that can be rebuilt, but go in the -# distribution anyway. It then copies the files to the distdir directory. -# ??? Note that this should be fixed once the Makefile is fixed to do -# the build in the inner directory. -objc.distdir: $(srcdir)/objc/objc-parse.c - mkdir tmp/objc -# cd objc ; $(MAKE) $(FLAGS_TO_PASS) objc-parse.c - cd objc; \ - for file in *[0-9a-zA-Z+]; do \ - ln $$file ../tmp/objc >/dev/null 2>&1 || cp $$file ../tmp/objc; \ - done diff --git a/contrib/gcc/objc/Makefile b/contrib/gcc/objc/Makefile deleted file mode 100644 index 36981337585a..000000000000 --- a/contrib/gcc/objc/Makefile +++ /dev/null @@ -1,100 +0,0 @@ -# GNU Objective C Runtime Makefile -# Copyright (C) 1993, 1995 Free Software Foundation, Inc. -# -# This file is part of GNU CC. -# -# GNU CC is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2, or (at your option) any later version. -# -# GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# GNU CC; see the file COPYING. If not, write to the Free Software -# Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -# This makefile is run by the parent dir's makefile. -# thisdir1=`pwd`; \ -# srcdir1=`cd $(srcdir); pwd`; \ -# cd objc; \ -# $(MAKE) $(MAKEFLAGS) -f $$srcdir1/objc/Makefile libobjc.a \ -# srcdir=$$srcdir1 tooldir=$(tooldir) AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" \ -# GCC_FOR_TARGET="$$thisdir1/xgcc -B$$thisdir1/" \ -# GCC_CFLAGS="$(GCC_CFLAGS)" incinstalldir=$$thisdir1/include -# Two targets are used by ../Makefile: `all' and `mostlyclean'. - -SHELL=/bin/sh - -.SUFFIXES: .m - -OPTIMIZE= -O - -VPATH = $(srcdir)/objc - -AR = ar -AR_FLAGS = rc - -# Always search these dirs when compiling. -SUBDIR_INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/config - -.c.o: - $(GCC_FOR_TARGET) $(OPTIMIZE) \ - -c $(GCC_CFLAGS) $(SUBDIR_INCLUDES) $< - -.m.o: - $(GCC_FOR_TARGET) $(OPTIMIZE) -fgnu-runtime \ - -c $(GCC_CFLAGS) $(SUBDIR_INCLUDES) $< - -# If we were not invoked from the parent dir, -# invoke make in the parent dir and have reinvoke this makefile. -# That's necessary to get the right values for srcdir, etc. -all: - cd ..; $(MAKE) sublibobjc.a - -OBJC_O = hash.o sarray.o class.o sendmsg.o init.o archive.o encoding.o \ - selector.o objects.o misc.o NXConstStr.o Object.o Protocol.o - -libobjc.a: $(OBJC_O) - -rm -f libobjc.a - $(AR) rc libobjc.a $? -# ranlib is run in the parent directory's makefile. - -OBJC_H = hash.h list.h sarray.h objc.h \ - objc-api.h \ - NXConstStr.h Object.h Protocol.h encoding.h typedstream.h - -# copy objc headers to installation include directory -copy-headers: - -rm -fr $(incinstalldir)/objc - -mkdir $(incinstalldir)/objc - for file in $(OBJC_H); do \ - realfile=$(srcdir)/objc/$${file}; \ - cp $${realfile} $(incinstalldir)/objc; \ - chmod a+r $(incinstalldir)/objc/$${file}; \ - done - -mostlyclean: - -rm -f *.o libobjc.a xforward fflags -clean: mostlyclean -distclean: mostlyclean -extraclean: mostlyclean - -# For Sun VPATH. - -hash.o: hash.c -sarray.o: sarray.c -class.o: class.c -sendmsg.o: sendmsg.c -init.o: init.c -archive.o: archive.c -encoding.o: encoding.c -selector.o: selector.c -objects.o: objects.c -misc.o: misc.c -NXConstStr.o: NXConstStr.m -Object.o: Object.m -Protocol.o: Protocol.m diff --git a/contrib/gcc/objc/Makefile.in b/contrib/gcc/objc/Makefile.in deleted file mode 100644 index 71c564c6c59c..000000000000 --- a/contrib/gcc/objc/Makefile.in +++ /dev/null @@ -1,73 +0,0 @@ -# GNU Objective C frontend Makefile -# Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. -# -# This file is part of GNU CC. -# -# GNU CC is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2, or (at your option) any later version. -# -# GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# GNU CC; see the file COPYING. If not, write to the Free Software -# Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -# The Makefile built from this file lives in the objc language subdirectory. -# Its purpose is to provide support for: -# -# 1. recursion where necessary, and only then (building .o's), and -# 2. building and debugging cc1objc from the language subdirectory. -# -# The parent Makefile handles all other chores, with help from the language -# Makefile fragment. -# -# The targets for external use are `all' and `mostlyclean'. - -SHELL=/bin/sh - -OPTIMIZE= -O - -srcdir = . -VPATH = $(srcdir) - -AR = ar -AR_FLAGS = rc - -# Define this as & to perform parallel make on a Sequent. -# Note that this has some bugs, and it seems currently necessary -# to compile all the gen* files first by hand to avoid erroneous results. -P = - -# Definition of `all' is here so that new rules inserted by sed -# do not specify the default target. -all: all.indirect - -# sed inserts variable overrides after the following line. -####target overrides -####host overrides -####cross overrides -####build overrides -# - -# Now figure out from those variables how to compile and link. -all.indirect: Makefile frontend - -frontend: - cd ..; $(MAKE) cc1obj$(exeext) - -Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure - cd ..; $(SHELL) config.status - -mostlyclean: - -rm -f *.o xforward fflags -clean: mostlyclean -distclean: mostlyclean -extraclean: mostlyclean - -# For Sun VPATH. - diff --git a/contrib/gcc/objc/NXConstStr.h b/contrib/gcc/objc/NXConstStr.h deleted file mode 100644 index c9799544a029..000000000000 --- a/contrib/gcc/objc/NXConstStr.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Interface for the NXConstantString class for Objective-C. - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by Pieter J. Schoenmakers <tiggr@es.ele.tue.nl> - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __nxconstantstring_INCLUDE_GNU -#define __nxconstantstring_INCLUDE_GNU - -#include "objc/Object.h" - -@interface NXConstantString: Object -{ - char *c_string; - unsigned int len; -} - --(const char *) cString; --(unsigned int) length; - -@end - -#endif diff --git a/contrib/gcc/objc/NXConstStr.m b/contrib/gcc/objc/NXConstStr.m deleted file mode 100644 index 4d2f3e1d7fc0..000000000000 --- a/contrib/gcc/objc/NXConstStr.m +++ /dev/null @@ -1,42 +0,0 @@ -/* Implementation of the NXConstantString class for Objective-C. - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by Pieter J. Schoenmakers <tiggr@es.ele.tue.nl> - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#include "objc/NXConstStr.h" - -@implementation NXConstantString - --(const char *) cString -{ - return (c_string); -} /* -cString */ - --(unsigned int) length -{ - return (len); -} /* -length */ - -@end diff --git a/contrib/gcc/objc/Object.h b/contrib/gcc/objc/Object.h deleted file mode 100644 index a762acc3f7db..000000000000 --- a/contrib/gcc/objc/Object.h +++ /dev/null @@ -1,124 +0,0 @@ -/* Interface for the Object class for Objective-C. - Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled - with GCC to produce an executable, this does not cause the resulting - executable to be covered by the GNU General Public License. This - exception does not however invalidate any other reasons why the - executable file might be covered by the GNU General Public License. */ - -#ifndef __object_INCLUDE_GNU -#define __object_INCLUDE_GNU - -#include <objc/objc.h> -#include <objc/typedstream.h> - -/* - * All classes are derived from Object. As such, - * this is the overhead tacked onto those objects. - */ -@interface Object -{ - Class isa; /* A pointer to the instance's class structure */ -} - - /* Initializing classes and instances */ -+ initialize; -- init; - - /* Creating, freeing, and copying instances */ -+ new; -+ alloc; -- free; -- copy; -- shallowCopy; -- deepen; -- deepCopy; - - /* Identifying classes */ -- (Class)class; -- (Class)superClass; -- (MetaClass)metaClass; -- (const char *)name; - - /* Identifying and comparing objects */ -- self; -- (unsigned int)hash; -- (BOOL)isEqual:anObject; -- (int)compare:anotherObject; - - /* Testing object type */ -- (BOOL)isMetaClass; -- (BOOL)isClass; -- (BOOL)isInstance; - - /* Testing inheritance relationships */ -- (BOOL)isKindOf:(Class)aClassObject; -- (BOOL)isMemberOf:(Class)aClassObject; -- (BOOL)isKindOfClassNamed:(const char *)aClassName; -- (BOOL)isMemberOfClassNamed:(const char *)aClassName; - - /* Testing class functionality */ -+ (BOOL)instancesRespondTo:(SEL)aSel; -- (BOOL)respondsTo:(SEL)aSel; - - /* Testing protocol conformance */ -- (BOOL)conformsTo:(Protocol*)aProtocol; - - /* Introspection */ -+ (IMP)instanceMethodFor:(SEL)aSel; -- (IMP)methodFor:(SEL)aSel; -+ (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel; -- (struct objc_method_description *)descriptionForMethod:(SEL)aSel; - - /* Sending messages determined at run time */ -- perform:(SEL)aSel; -- perform:(SEL)aSel with:anObject; -- perform:(SEL)aSel with:anObject1 with:anObject2; - - /* Forwarding */ -- (retval_t)forward:(SEL)aSel :(arglist_t)argFrame; -- (retval_t)performv:(SEL)aSel :(arglist_t)argFrame; - - /* Posing */ -+ poseAs:(Class)aClassObject; -- (Class)transmuteClassTo:(Class)aClassObject; - - /* Enforcing intentions */ -- subclassResponsibility:(SEL)aSel; -- notImplemented:(SEL)aSel; -- shouldNotImplement:(SEL)aSel; - - /* Error handling */ -- doesNotRecognize:(SEL)aSel; -- error:(const char *)aString, ...; - - /* Archiving */ -+ (int)version; -+ setVersion:(int)aVersion; -+ (int)streamVersion: (TypedStream*)aStream; - -- read: (TypedStream*)aStream; -- write: (TypedStream*)aStream; -- awake; - -@end - -#endif diff --git a/contrib/gcc/objc/Object.m b/contrib/gcc/objc/Object.m deleted file mode 100644 index 64b52f483687..000000000000 --- a/contrib/gcc/objc/Object.m +++ /dev/null @@ -1,387 +0,0 @@ -/* The implementation of class Object for Objective-C. - Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled - with GCC to produce an executable, this does not cause the resulting - executable to be covered by the GNU General Public License. This - exception does not however invalidate any other reasons why the - executable file might be covered by the GNU General Public License. */ - -#include <stdarg.h> -#include "objc/Object.h" -#include "objc/Protocol.h" -#include "objc/objc-api.h" - -extern int errno; - -#define MAX_CLASS_NAME_LEN 256 - -@implementation Object - -+ initialize -{ - return self; -} - -- init -{ - return self; -} - -+ new -{ - return [[self alloc] init]; -} - -+ alloc -{ - return class_create_instance(self); -} - -- free -{ - return object_dispose(self); -} - -- copy -{ - return [[self shallowCopy] deepen]; -} - -- shallowCopy -{ - return object_copy(self); -} - -- deepen -{ - return self; -} - -- deepCopy -{ - return [self copy]; -} - -- (Class)class -{ - return object_get_class(self); -} - -- (Class)superClass -{ - return object_get_super_class(self); -} - -- (MetaClass)metaClass -{ - return object_get_meta_class(self); -} - -- (const char *)name -{ - return object_get_class_name(self); -} - -- self -{ - return self; -} - -- (unsigned int)hash -{ - return (size_t)self; -} - -- (BOOL)isEqual:anObject -{ - return self==anObject; -} - -- (int)compare:anotherObject; -{ - if ([self isEqual:anotherObject]) - return 0; - // Ordering objects by their address is pretty useless, - // so subclasses should override this is some useful way. - else if (self > anotherObject) - return 1; - else - return -1; -} - -- (BOOL)isMetaClass -{ - return NO; -} - -- (BOOL)isClass -{ - return object_is_class(self); -} - -- (BOOL)isInstance -{ - return object_is_instance(self); -} - -- (BOOL)isKindOf:(Class)aClassObject -{ - Class class; - - for (class = self->isa; class!=Nil; class = class_get_super_class(class)) - if (class==aClassObject) - return YES; - return NO; -} - -- (BOOL)isMemberOf:(Class)aClassObject -{ - return self->isa==aClassObject; -} - -- (BOOL)isKindOfClassNamed:(const char *)aClassName -{ - Class class; - - if (aClassName!=NULL) - for (class = self->isa; class!=Nil; class = class_get_super_class(class)) - if (!strcmp(class_get_class_name(class), aClassName)) - return YES; - return NO; -} - -- (BOOL)isMemberOfClassNamed:(const char *)aClassName -{ - return ((aClassName!=NULL) - &&!strcmp(class_get_class_name(self->isa), aClassName)); -} - -+ (BOOL)instancesRespondTo:(SEL)aSel -{ - return class_get_instance_method(self, aSel)!=METHOD_NULL; -} - -- (BOOL)respondsTo:(SEL)aSel -{ - return ((object_is_instance(self) - ?class_get_instance_method(self->isa, aSel) - :class_get_class_method(self->isa, aSel))!=METHOD_NULL); -} - -+ (IMP)instanceMethodFor:(SEL)aSel -{ - return method_get_imp(class_get_instance_method(self, aSel)); -} - -// Indicates if the receiving class or instance conforms to the given protocol -// not usually overridden by subclasses -// -// Modified 9/5/94 to always search the class object's protocol list, rather -// than the meta class. - -+ (BOOL) conformsTo: (Protocol*)aProtocol -{ - int i; - struct objc_protocol_list* proto_list; - id parent; - - for (proto_list = ((Class)self)->protocols; - proto_list; proto_list = proto_list->next) - { - for (i=0; i < proto_list->count; i++) - { - if ([proto_list->list[i] conformsTo: aProtocol]) - return YES; - } - } - - if ((parent = [self superClass])) - return [parent conformsTo: aProtocol]; - else - return NO; -} - -- (BOOL) conformsTo: (Protocol*)aProtocol -{ - return [[self class] conformsTo:aProtocol]; -} - -- (IMP)methodFor:(SEL)aSel -{ - return (method_get_imp(object_is_instance(self) - ?class_get_instance_method(self->isa, aSel) - :class_get_class_method(self->isa, aSel))); -} - -+ (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel -{ - return ((struct objc_method_description *) - class_get_instance_method(self, aSel)); -} - -- (struct objc_method_description *)descriptionForMethod:(SEL)aSel -{ - return ((struct objc_method_description *) - (object_is_instance(self) - ?class_get_instance_method(self->isa, aSel) - :class_get_class_method(self->isa, aSel))); -} - -- perform:(SEL)aSel -{ - IMP msg = objc_msg_lookup(self, aSel); - if (!msg) - return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; - return (*msg)(self, aSel); -} - -- perform:(SEL)aSel with:anObject -{ - IMP msg = objc_msg_lookup(self, aSel); - if (!msg) - return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; - return (*msg)(self, aSel, anObject); -} - -- perform:(SEL)aSel with:anObject1 with:anObject2 -{ - IMP msg = objc_msg_lookup(self, aSel); - if (!msg) - return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; - return (*msg)(self, aSel, anObject1, anObject2); -} - -- (retval_t)forward:(SEL)aSel :(arglist_t)argFrame -{ - return (retval_t)[self doesNotRecognize: aSel]; -} - -- (retval_t)performv:(SEL)aSel :(arglist_t)argFrame -{ - return objc_msg_sendv(self, aSel, argFrame); -} - -+ poseAs:(Class)aClassObject -{ - return class_pose_as(self, aClassObject); -} - -- (Class)transmuteClassTo:(Class)aClassObject -{ - if (object_is_instance(self)) - if (class_is_class(aClassObject)) - if (class_get_instance_size(aClassObject)==class_get_instance_size(isa)) - if ([self isKindOf:aClassObject]) - { - Class old_isa = isa; - isa = aClassObject; - return old_isa; - } - return nil; -} - -- subclassResponsibility:(SEL)aSel -{ - return [self error:"subclass should override %s", sel_get_name(aSel)]; -} - -- notImplemented:(SEL)aSel -{ - return [self error:"method %s not implemented", sel_get_name(aSel)]; -} - -- shouldNotImplement:(SEL)aSel -{ - return [self error:"%s should not implement %s", - object_get_class_name(self), sel_get_name(aSel)]; -} - -- doesNotRecognize:(SEL)aSel -{ - return [self error:"%s does not recognize %s", - object_get_class_name(self), sel_get_name(aSel)]; -} - -#ifdef __alpha__ -extern size_t strlen(const char*); -#endif - -- error:(const char *)aString, ... -{ -#define FMT "error: %s (%s)\n%s\n" - char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self)) - +((aString!=NULL)?strlen((char*)aString):0)+8)]; - va_list ap; - - sprintf(fmt, FMT, object_get_class_name(self), - object_is_instance(self)?"instance":"class", - (aString!=NULL)?aString:""); - va_start(ap, aString); - objc_verror(self, OBJC_ERR_UNKNOWN, fmt, ap); - va_end(ap); - return nil; -#undef FMT -} - -+ (int)version -{ - return class_get_version(self); -} - -+ setVersion:(int)aVersion -{ - class_set_version(self, aVersion); - return self; -} - -+ (int)streamVersion: (TypedStream*)aStream -{ - if (aStream->mode == OBJC_READONLY) - return objc_get_stream_class_version (aStream, self); - else - return class_get_version (self); -} - -// These are used to write or read the instance variables -// declared in this particular part of the object. Subclasses -// should extend these, by calling [super read/write: aStream] -// before doing their own archiving. These methods are private, in -// the sense that they should only be called from subclasses. - -- read: (TypedStream*)aStream -{ - // [super read: aStream]; - return self; -} - -- write: (TypedStream*)aStream -{ - // [super write: aStream]; - return self; -} - -- awake -{ - // [super awake]; - return self; -} - -@end diff --git a/contrib/gcc/objc/Protocol.h b/contrib/gcc/objc/Protocol.h deleted file mode 100644 index c7464cf17a9a..000000000000 --- a/contrib/gcc/objc/Protocol.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Declare the class Protocol for Objective C programs. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __Protocol_INCLUDE_GNU -#define __Protocol_INCLUDE_GNU - -#include "objc/Object.h" - -@interface Protocol : Object -{ -@private - char *protocol_name; - struct objc_protocol_list *protocol_list; - struct objc_method_description_list *instance_methods, *class_methods; -} - -/* Obtaining attributes intrinsic to the protocol */ - -- (const char *)name; - -/* Testing protocol conformance */ - -- (BOOL) conformsTo: (Protocol *)aProtocolObject; - -/* Looking up information specific to a protocol */ - -- (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel; -- (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel; - -@end - - - - -#endif __Protocol_INCLUDE_GNU diff --git a/contrib/gcc/objc/Protocol.m b/contrib/gcc/objc/Protocol.m deleted file mode 100644 index 43ba44eaf4f7..000000000000 --- a/contrib/gcc/objc/Protocol.m +++ /dev/null @@ -1,128 +0,0 @@ -/* This file contains the implementation of class Protocol. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#include "objc/Protocol.h" -#include "objc/objc-api.h" - -/* Method description list */ -struct objc_method_description_list { - int count; - struct objc_method_description list[1]; -}; - - -@implementation Protocol -{ -@private - char *protocol_name; - struct objc_protocol_list *protocol_list; - struct objc_method_description_list *instance_methods, *class_methods; -} - -/* Obtaining attributes intrinsic to the protocol */ - -- (const char *)name -{ - return protocol_name; -} - -/* Testing protocol conformance */ - -- (BOOL) conformsTo: (Protocol *)aProtocolObject -{ - int i; - struct objc_protocol_list* proto_list; - - if (!strcmp(aProtocolObject->protocol_name, self->protocol_name)) - return YES; - - for (proto_list = protocol_list; proto_list; proto_list = proto_list->next) - { - for (i=0; i < proto_list->count; i++) - { - if ([proto_list->list[i] conformsTo: aProtocolObject]) - return YES; - } - } - - return NO; -} - -/* Looking up information specific to a protocol */ - -- (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel -{ - int i; - struct objc_protocol_list* proto_list; - const char* name = sel_get_name (aSel); - struct objc_method_description *result; - - for (i = 0; i < instance_methods->count; i++) - { - if (!strcmp ((char*)instance_methods->list[i].name, name)) - return &(instance_methods->list[i]); - } - - for (proto_list = protocol_list; proto_list; proto_list = proto_list->next) - { - for (i=0; i < proto_list->count; i++) - { - if ((result = [proto_list->list[i] - descriptionForInstanceMethod: aSel])) - return result; - } - } - - return NULL; -} - -- (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel; -{ - int i; - struct objc_protocol_list* proto_list; - const char* name = sel_get_name (aSel); - struct objc_method_description *result; - - for (i = 0; i < class_methods->count; i++) - { - if (!strcmp ((char*)class_methods->list[i].name, name)) - return &(class_methods->list[i]); - } - - for (proto_list = protocol_list; proto_list; proto_list = proto_list->next) - { - for (i=0; i < proto_list->count; i++) - { - if ((result = [proto_list->list[i] - descriptionForClassMethod: aSel])) - return result; - } - } - - return NULL; -} - -@end diff --git a/contrib/gcc/objc/README b/contrib/gcc/objc/README deleted file mode 100644 index f478d67dec8f..000000000000 --- a/contrib/gcc/objc/README +++ /dev/null @@ -1,97 +0,0 @@ - -GNU Objective C notes -********************* - -This document is to explain what has been done, and a little about how -specific features differ from other implementations. The runtime has -been completely rewritten in gcc 2.4. The earlier runtime had several -severe bugs and was rather incomplete. The compiler has had several -new features added as well. - -This is not documentation for Objective C, it is usable to someone -who knows Objective C from somewhere else. - - -Runtime API functions -===================== - -The runtime is modeled after the NeXT Objective C runtime. That is, -most functions have semantics as it is known from the NeXT. The -names, however, have changed. All runtime API functions have names -of lowercase letters and underscores as opposed to the -`traditional' mixed case names. - The runtime api functions are not documented as of now. -Someone offered to write it, and did it, but we were not allowed to -use it by his university (Very sad story). We have started writing -the documentation over again. This will be announced in appropriate -places when it becomes available. - - -Protocols -========= - -Protocols are now fully supported. The semantics is exactly as on the -NeXT. There is a flag to specify how protocols should be typechecked -when adopted to classes. The normal typechecker requires that all -methods in a given protocol must be implemented in the class that -adopts it -- it is not enough to inherit them. The flag -`-Wno-protocol' causes it to allow inherited methods, while -`-Wprotocols' is the default which requires them defined. - - -+initialize -=========== - -This method, if defined, is called before any other instance or class -methods of that particular class. This method is not inherited, and -is thus not called as initializer for a subclass that doesn't define -it itself. Thus, each +initialize method is called exactly once (or -never if no methods of that particular class is never called). -Besides this, it is allowed to have several +initialize methods, one -for each category. The order in which these (multiple methods) are -called is not well defined. I am not completely certain what the -semantics of this method is for other implementations, but this is -how it works for GNU Objective C. - - -Passivation/Activation/Typedstreams -=================================== - -This is supported in the style of NeXT TypedStream's. Consult the -headerfile Typedstreams.h for api functions. I (Kresten) have -rewritten it in Objective C, but this implementation is not part of -2.4, it is available from the GNU Objective C prerelease archive. - There is one difference worth noting concerning objects stored with -objc_write_object_reference (aka NXWriteObjectReference). When these -are read back in, their object is not guaranteed to be available until -the `-awake' method is called in the object that requests that object. -To objc_read_object you must pass a pointer to an id, which is valid -after exit from the function calling it (like e.g. an instance -variable). In general, you should not use objects read in until the --awake method is called. - - -Acknowledgements -================ - -The GNU Objective C team: Geoffrey Knauth <gsk@marble.com> (manager), -Tom Wood <wood@next.com> (compiler) and Kresten Krab Thorup -<krab@iesd.auc.dk> (runtime) would like to thank a some people for -participating in the development of the present GNU Objective C. - -Paul Burchard <burchard@geom.umn.edu> and Andrew McCallum -<mccallum@cs.rochester.edu> has been very helpful debugging the -runtime. Eric Herring <herring@iesd.auc.dk> has been very helpful -cleaning up after the documentation-copyright disaster and is now -helping with the new documentation. - -Steve Naroff <snaroff@next.com> and Richard Stallman -<rms@gnu.ai.mit.edu> has been very helpful with implementation details -in the compiler. - - -Bug Reports -=========== - -Please read the section `Submitting Bugreports' of the gcc manual -before you submit any bugs. diff --git a/contrib/gcc/objc/archive.c b/contrib/gcc/objc/archive.c deleted file mode 100644 index c762fe6186e5..000000000000 --- a/contrib/gcc/objc/archive.c +++ /dev/null @@ -1,1651 +0,0 @@ -/* GNU Objective C Runtime archiving - Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. - Contributed by Kresten Krab Thorup - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation; either version 2, or (at your option) any later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -GNU CC; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#include "config.h" -#include "runtime.h" -#include "typedstream.h" -#include "encoding.h" - -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif - -extern int fflush(FILE*); - -#define ROUND(V, A) \ - ({ typeof(V) __v=(V); typeof(A) __a=(A); \ - __a*((__v+__a-1)/__a); }) - -#define PTR2LONG(P) (((char*)(P))-(char*)0) -#define LONG2PTR(L) (((char*)0)+(L)) - -/* Declare some functions... */ - -static int -objc_read_class (struct objc_typed_stream* stream, Class* class); - -int objc_sizeof_type(const char* type); - -static int -objc_write_use_common (struct objc_typed_stream* stream, unsigned long key); - -static int -objc_write_register_common (struct objc_typed_stream* stream, - unsigned long key); - -static int -objc_write_class (struct objc_typed_stream* stream, - struct objc_class* class); - -const char* objc_skip_type (const char* type); - -static void __objc_finish_write_root_object(struct objc_typed_stream*); -static void __objc_finish_read_root_object(struct objc_typed_stream*); - -static __inline__ int -__objc_code_unsigned_char (unsigned char* buf, unsigned char val) -{ - if ((val&_B_VALUE) == val) - { - buf[0] = val|_B_SINT; - return 1; - } - else - { - buf[0] = _B_NINT|0x01; - buf[1] = val; - return 2; - } -} - -int -objc_write_unsigned_char (struct objc_typed_stream* stream, - unsigned char value) -{ - unsigned char buf[sizeof (unsigned char)+1]; - int len = __objc_code_unsigned_char (buf, value); - return (*stream->write)(stream->physical, buf, len); -} - -static __inline__ int -__objc_code_char (unsigned char* buf, char val) -{ - if (val >= 0) - return __objc_code_unsigned_char (buf, val); - else - { - buf[0] = _B_NINT|_B_SIGN|0x01; - buf[1] = -val; - return 2; - } -} - -int -objc_write_char (struct objc_typed_stream* stream, char value) -{ - unsigned char buf[sizeof (char)+1]; - int len = __objc_code_char (buf, value); - return (*stream->write)(stream->physical, buf, len); -} - -static __inline__ int -__objc_code_unsigned_short (unsigned char* buf, unsigned short val) -{ - if ((val&_B_VALUE) == val) - { - buf[0] = val|_B_SINT; - return 1; - } - else - { - int c, b; - - buf[0] = _B_NINT; - - for (c= sizeof(short); c != 0; c -= 1) - if (((val>>(8*(c-1)))%0x100) != 0) - break; - - buf[0] |= c; - - for (b = 1; c != 0; c--, b++) - { - buf[b] = (val >> (8*(c-1)))%0x100; - } - - return b; - } -} - -int -objc_write_unsigned_short (struct objc_typed_stream* stream, - unsigned short value) -{ - unsigned char buf[sizeof (unsigned short)+1]; - int len = __objc_code_unsigned_short (buf, value); - return (*stream->write)(stream->physical, buf, len); -} - -static __inline__ int -__objc_code_short (unsigned char* buf, short val) -{ - int sign = (val < 0); - int size = __objc_code_unsigned_short (buf, sign ? -val : val); - if (sign) - buf[0] |= _B_SIGN; - return size; -} - -int -objc_write_short (struct objc_typed_stream* stream, short value) -{ - unsigned char buf[sizeof (short)+1]; - int len = __objc_code_short (buf, value); - return (*stream->write)(stream->physical, buf, len); -} - - -static __inline__ int -__objc_code_unsigned_int (unsigned char* buf, unsigned int val) -{ - if ((val&_B_VALUE) == val) - { - buf[0] = val|_B_SINT; - return 1; - } - else - { - int c, b; - - buf[0] = _B_NINT; - - for (c= sizeof(int); c != 0; c -= 1) - if (((val>>(8*(c-1)))%0x100) != 0) - break; - - buf[0] |= c; - - for (b = 1; c != 0; c--, b++) - { - buf[b] = (val >> (8*(c-1)))%0x100; - } - - return b; - } -} - -int -objc_write_unsigned_int (struct objc_typed_stream* stream, unsigned int value) -{ - unsigned char buf[sizeof(unsigned int)+1]; - int len = __objc_code_unsigned_int (buf, value); - return (*stream->write)(stream->physical, buf, len); -} - -static __inline__ int -__objc_code_int (unsigned char* buf, int val) -{ - int sign = (val < 0); - int size = __objc_code_unsigned_int (buf, sign ? -val : val); - if (sign) - buf[0] |= _B_SIGN; - return size; -} - -int -objc_write_int (struct objc_typed_stream* stream, int value) -{ - unsigned char buf[sizeof(int)+1]; - int len = __objc_code_int (buf, value); - return (*stream->write)(stream->physical, buf, len); -} - -static __inline__ int -__objc_code_unsigned_long (unsigned char* buf, unsigned long val) -{ - if ((val&_B_VALUE) == val) - { - buf[0] = val|_B_SINT; - return 1; - } - else - { - int c, b; - - buf[0] = _B_NINT; - - for (c= sizeof(long); c != 0; c -= 1) - if (((val>>(8*(c-1)))%0x100) != 0) - break; - - buf[0] |= c; - - for (b = 1; c != 0; c--, b++) - { - buf[b] = (val >> (8*(c-1)))%0x100; - } - - return b; - } -} - -int -objc_write_unsigned_long (struct objc_typed_stream* stream, - unsigned long value) -{ - unsigned char buf[sizeof(unsigned long)+1]; - int len = __objc_code_unsigned_long (buf, value); - return (*stream->write)(stream->physical, buf, len); -} - -static __inline__ int -__objc_code_long (unsigned char* buf, long val) -{ - int sign = (val < 0); - int size = __objc_code_unsigned_long (buf, sign ? -val : val); - if (sign) - buf[0] |= _B_SIGN; - return size; -} - -int -objc_write_long (struct objc_typed_stream* stream, long value) -{ - unsigned char buf[sizeof(long)+1]; - int len = __objc_code_long (buf, value); - return (*stream->write)(stream->physical, buf, len); -} - - -int -objc_write_string (struct objc_typed_stream* stream, - const unsigned char* string, unsigned int nbytes) -{ - unsigned char buf[sizeof(unsigned int)+1]; - int len = __objc_code_unsigned_int (buf, nbytes); - - if ((buf[0]&_B_CODE) == _B_SINT) - buf[0] = (buf[0]&_B_VALUE)|_B_SSTR; - - else /* _B_NINT */ - buf[0] = (buf[0]&_B_VALUE)|_B_NSTR; - - if ((*stream->write)(stream->physical, buf, len) != 0) - return (*stream->write)(stream->physical, string, nbytes); - else - return 0; -} - -int -objc_write_string_atomic (struct objc_typed_stream* stream, - unsigned char* string, unsigned int nbytes) -{ - unsigned long key; - if ((key = PTR2LONG(hash_value_for_key (stream->stream_table, string)))) - return objc_write_use_common (stream, key); - else - { - int length; - hash_add (&stream->stream_table, LONG2PTR(key=PTR2LONG(string)), string); - if ((length = objc_write_register_common (stream, key))) - return objc_write_string (stream, string, nbytes); - return length; - } -} - -static int -objc_write_register_common (struct objc_typed_stream* stream, - unsigned long key) -{ - unsigned char buf[sizeof (unsigned long)+2]; - int len = __objc_code_unsigned_long (buf+1, key); - if (len == 1) - { - buf[0] = _B_RCOMM|0x01; - buf[1] &= _B_VALUE; - return (*stream->write)(stream->physical, buf, len+1); - } - else - { - buf[1] = (buf[1]&_B_VALUE)|_B_RCOMM; - return (*stream->write)(stream->physical, buf+1, len); - } -} - -static int -objc_write_use_common (struct objc_typed_stream* stream, unsigned long key) -{ - unsigned char buf[sizeof (unsigned long)+2]; - int len = __objc_code_unsigned_long (buf+1, key); - if (len == 1) - { - buf[0] = _B_UCOMM|0x01; - buf[1] &= _B_VALUE; - return (*stream->write)(stream->physical, buf, 2); - } - else - { - buf[1] = (buf[1]&_B_VALUE)|_B_UCOMM; - return (*stream->write)(stream->physical, buf+1, len); - } -} - -static __inline__ int -__objc_write_extension (struct objc_typed_stream* stream, unsigned char code) -{ - if (code <= _B_VALUE) - { - unsigned char buf = code|_B_EXT; - return (*stream->write)(stream->physical, &buf, 1); - } - else - { - objc_error(nil, OBJC_ERR_BAD_OPCODE, - "__objc_write_extension: bad opcode %c\n", code); - return -1; - } -} - -__inline__ int -__objc_write_object (struct objc_typed_stream* stream, id object) -{ - unsigned char buf = '\0'; - SEL write_sel = sel_get_any_uid ("write:"); - if (object) - { - __objc_write_extension (stream, _BX_OBJECT); - objc_write_class (stream, object->class_pointer); - (*objc_msg_lookup(object, write_sel))(object, write_sel, stream); - return (*stream->write)(stream->physical, &buf, 1); - } - else - return objc_write_use_common(stream, 0); -} - -int -objc_write_object_reference (struct objc_typed_stream* stream, id object) -{ - unsigned long key; - if ((key = PTR2LONG(hash_value_for_key (stream->object_table, object)))) - return objc_write_use_common (stream, key); - - __objc_write_extension (stream, _BX_OBJREF); - return objc_write_unsigned_long (stream, PTR2LONG (object)); -} - -int -objc_write_root_object (struct objc_typed_stream* stream, id object) -{ - int len = 0; - if (stream->writing_root_p) - objc_error (nil, OBJC_ERR_RECURSE_ROOT, - "objc_write_root_object called recursively"); - else - { - stream->writing_root_p = 1; - __objc_write_extension (stream, _BX_OBJROOT); - if((len = objc_write_object (stream, object))) - __objc_finish_write_root_object(stream); - stream->writing_root_p = 0; - } - return len; -} - -int -objc_write_object (struct objc_typed_stream* stream, id object) -{ - unsigned long key; - if ((key = PTR2LONG(hash_value_for_key (stream->object_table, object)))) - return objc_write_use_common (stream, key); - - else if (object == nil) - return objc_write_use_common(stream, 0); - - else - { - int length; - hash_add (&stream->object_table, LONG2PTR(key=PTR2LONG(object)), object); - if ((length = objc_write_register_common (stream, key))) - return __objc_write_object (stream, object); - return length; - } -} - -__inline__ int -__objc_write_class (struct objc_typed_stream* stream, struct objc_class* class) -{ - __objc_write_extension (stream, _BX_CLASS); - objc_write_string_atomic(stream, (char*)class->name, - strlen((char*)class->name)); - return objc_write_unsigned_long (stream, class->version); -} - - -static int -objc_write_class (struct objc_typed_stream* stream, - struct objc_class* class) -{ - unsigned long key; - if ((key = PTR2LONG(hash_value_for_key (stream->stream_table, class)))) - return objc_write_use_common (stream, key); - else - { - int length; - hash_add (&stream->stream_table, LONG2PTR(key=PTR2LONG(class)), class); - if ((length = objc_write_register_common (stream, key))) - return __objc_write_class (stream, class); - return length; - } -} - - -__inline__ int -__objc_write_selector (struct objc_typed_stream* stream, SEL selector) -{ - const char* sel_name; - __objc_write_extension (stream, _BX_SEL); - /* to handle NULL selectors */ - if ((SEL)0 == selector) - return objc_write_string (stream, "", 0); - sel_name = sel_get_name (selector); - return objc_write_string (stream, sel_name, strlen ((char*)sel_name)); -} - -int -objc_write_selector (struct objc_typed_stream* stream, SEL selector) -{ - const char* sel_name; - unsigned long key; - - /* to handle NULL selectors */ - if ((SEL)0 == selector) - return __objc_write_selector (stream, selector); - - sel_name = sel_get_name (selector); - if ((key = PTR2LONG(hash_value_for_key (stream->stream_table, sel_name)))) - return objc_write_use_common (stream, key); - else - { - int length; - hash_add (&stream->stream_table, - LONG2PTR(key=PTR2LONG(sel_name)), (char*)sel_name); - if ((length = objc_write_register_common (stream, key))) - return __objc_write_selector (stream, selector); - return length; - } -} - - - -/* -** Read operations -*/ - -__inline__ int -objc_read_char (struct objc_typed_stream* stream, char* val) -{ - unsigned char buf; - int len; - len = (*stream->read)(stream->physical, &buf, 1); - if (len != 0) - { - if ((buf & _B_CODE) == _B_SINT) - (*val) = (buf & _B_VALUE); - - else if ((buf & _B_NUMBER) == 1) - { - len = (*stream->read)(stream->physical, val, 1); - if (buf&_B_SIGN) - (*val) = -1*(*val); - } - - else - objc_error(nil, OBJC_ERR_BAD_DATA, - "expected 8bit signed int, got %dbit int", - (int)(buf&_B_NUMBER)*8); - } - return len; -} - - -__inline__ int -objc_read_unsigned_char (struct objc_typed_stream* stream, unsigned char* val) -{ - unsigned char buf; - int len; - if ((len = (*stream->read)(stream->physical, &buf, 1))) - { - if ((buf & _B_CODE) == _B_SINT) - (*val) = (buf & _B_VALUE); - - else if ((buf & _B_NUMBER) == 1) - len = (*stream->read)(stream->physical, val, 1); - - else - objc_error(nil, OBJC_ERR_BAD_DATA, - "expected 8bit unsigned int, got %dbit int", - (int)(buf&_B_NUMBER)*8); - } - return len; -} - -__inline__ int -objc_read_short (struct objc_typed_stream* stream, short* value) -{ - unsigned char buf[sizeof(short)+1]; - int len; - if ((len = (*stream->read)(stream->physical, buf, 1))) - { - if ((buf[0] & _B_CODE) == _B_SINT) - (*value) = (buf[0] & _B_VALUE); - - else - { - int pos = 1; - int nbytes = buf[0] & _B_NUMBER; - if (nbytes > sizeof (short)) - objc_error(nil, OBJC_ERR_BAD_DATA, - "expected short, got bigger (%dbits)", nbytes*8); - len = (*stream->read)(stream->physical, buf+1, nbytes); - (*value) = 0; - while (pos <= nbytes) - (*value) = ((*value)*0x100) + buf[pos++]; - if (buf[0] & _B_SIGN) - (*value) = -(*value); - } - } - return len; -} - -__inline__ int -objc_read_unsigned_short (struct objc_typed_stream* stream, - unsigned short* value) -{ - unsigned char buf[sizeof(unsigned short)+1]; - int len; - if ((len = (*stream->read)(stream->physical, buf, 1))) - { - if ((buf[0] & _B_CODE) == _B_SINT) - (*value) = (buf[0] & _B_VALUE); - - else - { - int pos = 1; - int nbytes = buf[0] & _B_NUMBER; - if (nbytes > sizeof (short)) - objc_error(nil, OBJC_ERR_BAD_DATA, - "expected short, got int or bigger"); - len = (*stream->read)(stream->physical, buf+1, nbytes); - (*value) = 0; - while (pos <= nbytes) - (*value) = ((*value)*0x100) + buf[pos++]; - } - } - return len; -} - - -__inline__ int -objc_read_int (struct objc_typed_stream* stream, int* value) -{ - unsigned char buf[sizeof(int)+1]; - int len; - if ((len = (*stream->read)(stream->physical, buf, 1))) - { - if ((buf[0] & _B_CODE) == _B_SINT) - (*value) = (buf[0] & _B_VALUE); - - else - { - int pos = 1; - int nbytes = buf[0] & _B_NUMBER; - if (nbytes > sizeof (int)) - objc_error(nil, OBJC_ERR_BAD_DATA, "expected int, got bigger"); - len = (*stream->read)(stream->physical, buf+1, nbytes); - (*value) = 0; - while (pos <= nbytes) - (*value) = ((*value)*0x100) + buf[pos++]; - if (buf[0] & _B_SIGN) - (*value) = -(*value); - } - } - return len; -} - -__inline__ int -objc_read_long (struct objc_typed_stream* stream, long* value) -{ - unsigned char buf[sizeof(long)+1]; - int len; - if ((len = (*stream->read)(stream->physical, buf, 1))) - { - if ((buf[0] & _B_CODE) == _B_SINT) - (*value) = (buf[0] & _B_VALUE); - - else - { - int pos = 1; - int nbytes = buf[0] & _B_NUMBER; - if (nbytes > sizeof (long)) - objc_error(nil, OBJC_ERR_BAD_DATA, "expected long, got bigger"); - len = (*stream->read)(stream->physical, buf+1, nbytes); - (*value) = 0; - while (pos <= nbytes) - (*value) = ((*value)*0x100) + buf[pos++]; - if (buf[0] & _B_SIGN) - (*value) = -(*value); - } - } - return len; -} - -__inline__ int -__objc_read_nbyte_uint (struct objc_typed_stream* stream, - unsigned int nbytes, unsigned int* val) -{ - int len, pos = 0; - unsigned char buf[sizeof(unsigned int)+1]; - - if (nbytes > sizeof (int)) - objc_error(nil, OBJC_ERR_BAD_DATA, "expected int, got bigger"); - - len = (*stream->read)(stream->physical, buf, nbytes); - (*val) = 0; - while (pos < nbytes) - (*val) = ((*val)*0x100) + buf[pos++]; - return len; -} - - -__inline__ int -objc_read_unsigned_int (struct objc_typed_stream* stream, - unsigned int* value) -{ - unsigned char buf[sizeof(unsigned int)+1]; - int len; - if ((len = (*stream->read)(stream->physical, buf, 1))) - { - if ((buf[0] & _B_CODE) == _B_SINT) - (*value) = (buf[0] & _B_VALUE); - - else - len = __objc_read_nbyte_uint (stream, (buf[0] & _B_VALUE), value); - - } - return len; -} - -int -__objc_read_nbyte_ulong (struct objc_typed_stream* stream, - unsigned int nbytes, unsigned long* val) -{ - int len, pos = 0; - unsigned char buf[sizeof(unsigned long)+1]; - - if (nbytes > sizeof (long)) - objc_error(nil, OBJC_ERR_BAD_DATA, "expected long, got bigger"); - - len = (*stream->read)(stream->physical, buf, nbytes); - (*val) = 0; - while (pos < nbytes) - (*val) = ((*val)*0x100) + buf[pos++]; - return len; -} - - -__inline__ int -objc_read_unsigned_long (struct objc_typed_stream* stream, - unsigned long* value) -{ - unsigned char buf[sizeof(unsigned long)+1]; - int len; - if ((len = (*stream->read)(stream->physical, buf, 1))) - { - if ((buf[0] & _B_CODE) == _B_SINT) - (*value) = (buf[0] & _B_VALUE); - - else - len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), value); - - } - return len; -} - -__inline__ int -objc_read_string (struct objc_typed_stream* stream, - char** string) -{ - unsigned char buf[sizeof(unsigned int)+1]; - int len; - if ((len = (*stream->read)(stream->physical, buf, 1))) - { - unsigned long key = 0; - - if ((buf[0]&_B_CODE) == _B_RCOMM) /* register following */ - { - len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); - len = (*stream->read)(stream->physical, buf, 1); - } - - switch (buf[0]&_B_CODE) { - case _B_SSTR: - { - int length = buf[0]&_B_VALUE; - (*string) = (char*)objc_malloc(length+1); - if (key) - hash_add (&stream->stream_table, LONG2PTR(key), *string); - len = (*stream->read)(stream->physical, *string, length); - (*string)[length] = '\0'; - } - break; - - case _B_UCOMM: - { - char *tmp; - len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); - tmp = hash_value_for_key (stream->stream_table, LONG2PTR (key)); - *string = objc_malloc (strlen(tmp) + 1); - strcpy (*string, tmp); - } - break; - - case _B_NSTR: - { - unsigned int nbytes = buf[0]&_B_VALUE; - len = __objc_read_nbyte_uint(stream, nbytes, &nbytes); - if (len) { - (*string) = (char*)objc_malloc(nbytes+1); - if (key) - hash_add (&stream->stream_table, LONG2PTR(key), *string); - len = (*stream->read)(stream->physical, *string, nbytes); - (*string)[nbytes] = '\0'; - } - } - break; - - default: - objc_error(nil, OBJC_ERR_BAD_DATA, - "expected string, got opcode %c\n", (buf[0]&_B_CODE)); - } - } - - return len; -} - - -int -objc_read_object (struct objc_typed_stream* stream, id* object) -{ - unsigned char buf[sizeof (unsigned int)]; - int len; - if ((len = (*stream->read)(stream->physical, buf, 1))) - { - SEL read_sel = sel_get_any_uid ("read:"); - unsigned long key = 0; - - if ((buf[0]&_B_CODE) == _B_RCOMM) /* register common */ - { - len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); - len = (*stream->read)(stream->physical, buf, 1); - } - - if (buf[0] == (_B_EXT | _BX_OBJECT)) - { - Class class; - - /* get class */ - len = objc_read_class (stream, &class); - - /* create instance */ - (*object) = class_create_instance(class); - - /* register? */ - if (key) - hash_add (&stream->object_table, LONG2PTR(key), *object); - - /* send -read: */ - if (__objc_responds_to (*object, read_sel)) - (*get_imp(class, read_sel))(*object, read_sel, stream); - - /* check null-byte */ - len = (*stream->read)(stream->physical, buf, 1); - if (buf[0] != '\0') - objc_error(nil, OBJC_ERR_BAD_DATA, - "expected null-byte, got opcode %c", buf[0]); - } - - else if ((buf[0]&_B_CODE) == _B_UCOMM) - { - if (key) - objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); - len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); - (*object) = hash_value_for_key (stream->object_table, LONG2PTR(key)); - } - - else if (buf[0] == (_B_EXT | _BX_OBJREF)) /* a forward reference */ - { - struct objc_list* other; - len = objc_read_unsigned_long (stream, &key); - other = (struct objc_list*)hash_value_for_key (stream->object_refs, - LONG2PTR(key)); - hash_add (&stream->object_refs, LONG2PTR(key), - (void*)list_cons(object, other)); - } - - else if (buf[0] == (_B_EXT | _BX_OBJROOT)) /* a root object */ - { - if (key) - objc_error(nil, OBJC_ERR_BAD_KEY, - "cannot register root object..."); - len = objc_read_object (stream, object); - __objc_finish_read_root_object (stream); - } - - else - objc_error(nil, OBJC_ERR_BAD_DATA, - "expected object, got opcode %c", buf[0]); - } - return len; -} - -static int -objc_read_class (struct objc_typed_stream* stream, Class* class) -{ - unsigned char buf[sizeof (unsigned int)]; - int len; - if ((len = (*stream->read)(stream->physical, buf, 1))) - { - unsigned long key = 0; - - if ((buf[0]&_B_CODE) == _B_RCOMM) /* register following */ - { - len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); - len = (*stream->read)(stream->physical, buf, 1); - } - - if (buf[0] == (_B_EXT | _BX_CLASS)) - { - char* class_name; - unsigned long version; - - /* get class */ - len = objc_read_string (stream, &class_name); - (*class) = objc_get_class(class_name); - objc_free(class_name); - - /* register */ - if (key) - hash_add (&stream->stream_table, LONG2PTR(key), *class); - - objc_read_unsigned_long(stream, &version); - hash_add (&stream->class_table, (*class)->name, (void*)version); - } - - else if ((buf[0]&_B_CODE) == _B_UCOMM) - { - if (key) - objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); - len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); - (*class) = hash_value_for_key (stream->stream_table, LONG2PTR(key)); - if (!*class) - objc_error(nil, OBJC_ERR_BAD_CLASS, - "cannot find class for key %lu", key); - } - - else - objc_error(nil, OBJC_ERR_BAD_DATA, - "expected class, got opcode %c", buf[0]); - } - return len; -} - -int -objc_read_selector (struct objc_typed_stream* stream, SEL* selector) -{ - unsigned char buf[sizeof (unsigned int)]; - int len; - if ((len = (*stream->read)(stream->physical, buf, 1))) - { - unsigned long key = 0; - - if ((buf[0]&_B_CODE) == _B_RCOMM) /* register following */ - { - len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); - len = (*stream->read)(stream->physical, buf, 1); - } - - if (buf[0] == (_B_EXT|_BX_SEL)) /* selector! */ - { - char* selector_name; - - /* get selector */ - len = objc_read_string (stream, &selector_name); - /* To handle NULL selectors */ - if (0 == strlen(selector_name)) - { - (*selector) = (SEL)0; - return 0; - } - else - (*selector) = sel_get_any_uid(selector_name); - objc_free(selector_name); - - /* register */ - if (key) - hash_add (&stream->stream_table, LONG2PTR(key), (void*)*selector); - } - - else if ((buf[0]&_B_CODE) == _B_UCOMM) - { - if (key) - objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode..."); - len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); - (*selector) = hash_value_for_key (stream->stream_table, - LONG2PTR(key)); - } - - else - objc_error(nil, OBJC_ERR_BAD_DATA, - "expected selector, got opcode %c", buf[0]); - } - return len; -} - -/* -** USER LEVEL FUNCTIONS -*/ - -/* -** Write one object, encoded in TYPE and pointed to by DATA to the -** typed stream STREAM. -*/ - -int -objc_write_type(TypedStream* stream, const char* type, const void* data) -{ - switch(*type) { - case _C_ID: - return objc_write_object (stream, *(id*)data); - break; - - case _C_CLASS: - return objc_write_class (stream, *(Class*)data); - break; - - case _C_SEL: - return objc_write_selector (stream, *(SEL*)data); - break; - - case _C_CHR: - return objc_write_char(stream, *(char*)data); - break; - - case _C_UCHR: - return objc_write_unsigned_char(stream, *(unsigned char*)data); - break; - - case _C_SHT: - return objc_write_short(stream, *(short*)data); - break; - - case _C_USHT: - return objc_write_unsigned_short(stream, *(unsigned short*)data); - break; - - case _C_INT: - return objc_write_int(stream, *(int*)data); - break; - - case _C_UINT: - return objc_write_unsigned_int(stream, *(unsigned int*)data); - break; - - case _C_LNG: - return objc_write_long(stream, *(long*)data); - break; - - case _C_ULNG: - return objc_write_unsigned_long(stream, *(unsigned long*)data); - break; - - case _C_CHARPTR: - return objc_write_string (stream, *(char**)data, strlen(*(char**)data)); - break; - - case _C_ATOM: - return objc_write_string_atomic (stream, *(char**)data, - strlen(*(char**)data)); - break; - - case _C_ARY_B: - { - int len = atoi(type+1); - while (isdigit(*++type)) - ; - return objc_write_array (stream, type, len, data); - } - break; - - 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); - objc_write_type (stream, type, ((char*)data)+acc_size); - acc_size += objc_sizeof_type (type); /* add component size */ - type = objc_skip_typespec (type); /* skip component */ - } - return 1; - } - - default: - { - objc_error(nil, OBJC_ERR_BAD_TYPE, - "objc_write_type: cannot parse typespec: %s\n", type); - return 0; - } - } -} - -/* -** Read one object, encoded in TYPE and pointed to by DATA to the -** typed stream STREAM. DATA specifies the address of the types to -** read. Expected type is checked against the type actually present -** on the stream. -*/ - -int -objc_read_type(TypedStream* stream, const char* type, void* data) -{ - char c; - switch(c = *type) { - case _C_ID: - return objc_read_object (stream, (id*)data); - break; - - case _C_CLASS: - return objc_read_class (stream, (Class*)data); - break; - - case _C_SEL: - return objc_read_selector (stream, (SEL*)data); - break; - - case _C_CHR: - return objc_read_char (stream, (char*)data); - break; - - case _C_UCHR: - return objc_read_unsigned_char (stream, (unsigned char*)data); - break; - - case _C_SHT: - return objc_read_short (stream, (short*)data); - break; - - case _C_USHT: - return objc_read_unsigned_short (stream, (unsigned short*)data); - break; - - case _C_INT: - return objc_read_int (stream, (int*)data); - break; - - case _C_UINT: - return objc_read_unsigned_int (stream, (unsigned int*)data); - break; - - case _C_LNG: - return objc_read_long (stream, (long*)data); - break; - - case _C_ULNG: - return objc_read_unsigned_long (stream, (unsigned long*)data); - break; - - case _C_CHARPTR: - case _C_ATOM: - return objc_read_string (stream, (char**)data); - break; - - case _C_ARY_B: - { - int len = atoi(type+1); - while (isdigit(*++type)) - ; - return objc_read_array (stream, type, len, data); - } - 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); - objc_read_type (stream, type, ((char*)data)+acc_size); - acc_size += objc_sizeof_type (type); /* add component size */ - type = objc_skip_typespec (type); /* skip component */ - } - return 1; - } - - default: - { - objc_error(nil, OBJC_ERR_BAD_TYPE, - "objc_read_type: cannot parse typespec: %s\n", type); - return 0; - } - } -} - -/* -** Write the object specified by the template TYPE to STREAM. Last -** arguments specify addresses of values to be written. It might -** seem surprising to specify values by address, but this is extremely -** convenient for copy-paste with objc_read_types calls. A more -** down-to-the-earth cause for this passing of addresses is that values -** of arbitrary size is not well supported in ANSI C for functions with -** variable number of arguments. -*/ - -int -objc_write_types (TypedStream* stream, const char* type, ...) -{ - va_list args; - const char *c; - int res = 0; - - va_start(args, type); - - for (c = type; *c; c = objc_skip_typespec (c)) - { - switch(*c) { - case _C_ID: - res = objc_write_object (stream, *va_arg (args, id*)); - break; - - case _C_CLASS: - res = objc_write_class (stream, *va_arg(args, Class*)); - break; - - case _C_SEL: - res = objc_write_selector (stream, *va_arg(args, SEL*)); - break; - - case _C_CHR: - res = objc_write_char (stream, *va_arg (args, char*)); - break; - - case _C_UCHR: - res = objc_write_unsigned_char (stream, - *va_arg (args, unsigned char*)); - break; - - case _C_SHT: - res = objc_write_short (stream, *va_arg(args, short*)); - break; - - case _C_USHT: - res = objc_write_unsigned_short (stream, - *va_arg(args, unsigned short*)); - break; - - case _C_INT: - res = objc_write_int(stream, *va_arg(args, int*)); - break; - - case _C_UINT: - res = objc_write_unsigned_int(stream, *va_arg(args, unsigned int*)); - break; - - case _C_LNG: - res = objc_write_long(stream, *va_arg(args, long*)); - break; - - case _C_ULNG: - res = objc_write_unsigned_long(stream, *va_arg(args, unsigned long*)); - break; - - case _C_CHARPTR: - { - char** str = va_arg(args, char**); - res = objc_write_string (stream, *str, strlen(*str)); - } - break; - - case _C_ATOM: - { - char** str = va_arg(args, char**); - res = objc_write_string_atomic (stream, *str, strlen(*str)); - } - break; - - case _C_ARY_B: - { - int len = atoi(c+1); - const char* t = c; - while (isdigit(*++t)) - ; - res = objc_write_array (stream, t, len, va_arg(args, void*)); - t = objc_skip_typespec (t); - if (*t != _C_ARY_E) - objc_error(nil, OBJC_ERR_BAD_TYPE, "expected `]', got: %s", t); - } - break; - - default: - objc_error(nil, OBJC_ERR_BAD_TYPE, - "objc_write_types: cannot parse typespec: %s\n", type); - } - } - va_end(args); - return res; -} - - -/* -** Last arguments specify addresses of values to be read. Expected -** type is checked against the type actually present on the stream. -*/ - -int -objc_read_types(TypedStream* stream, const char* type, ...) -{ - va_list args; - const char *c; - int res = 0; - - va_start(args, type); - - for (c = type; *c; c = objc_skip_typespec(c)) - { - switch(*c) { - case _C_ID: - res = objc_read_object(stream, va_arg(args, id*)); - break; - - case _C_CLASS: - res = objc_read_class(stream, va_arg(args, Class*)); - break; - - case _C_SEL: - res = objc_read_selector(stream, va_arg(args, SEL*)); - break; - - case _C_CHR: - res = objc_read_char(stream, va_arg(args, char*)); - break; - - case _C_UCHR: - res = objc_read_unsigned_char(stream, va_arg(args, unsigned char*)); - break; - - case _C_SHT: - res = objc_read_short(stream, va_arg(args, short*)); - break; - - case _C_USHT: - res = objc_read_unsigned_short(stream, va_arg(args, unsigned short*)); - break; - - case _C_INT: - res = objc_read_int(stream, va_arg(args, int*)); - break; - - case _C_UINT: - res = objc_read_unsigned_int(stream, va_arg(args, unsigned int*)); - break; - - case _C_LNG: - res = objc_read_long(stream, va_arg(args, long*)); - break; - - case _C_ULNG: - res = objc_read_unsigned_long(stream, va_arg(args, unsigned long*)); - break; - - case _C_CHARPTR: - case _C_ATOM: - { - char** str = va_arg(args, char**); - res = objc_read_string (stream, str); - } - break; - - case _C_ARY_B: - { - int len = atoi(c+1); - const char* t = c; - while (isdigit(*++t)) - ; - res = objc_read_array (stream, t, len, va_arg(args, void*)); - t = objc_skip_typespec (t); - if (*t != _C_ARY_E) - objc_error(nil, OBJC_ERR_BAD_TYPE, "expected `]', got: %s", t); - } - break; - - default: - objc_error(nil, OBJC_ERR_BAD_TYPE, - "objc_read_types: cannot parse typespec: %s\n", type); - } - } - va_end(args); - return res; -} - -/* -** Write an array of COUNT elements of TYPE from the memory address DATA. -** This is equivalent of objc_write_type (stream, "[N<type>]", data) -*/ - -int -objc_write_array (TypedStream* stream, const char* type, - int count, const void* data) -{ - int off = objc_sizeof_type(type); - const char* where = data; - - while (count-- > 0) - { - objc_write_type(stream, type, where); - where += off; - } - return 1; -} - -/* -** Read an array of COUNT elements of TYPE into the memory address -** DATA. The memory pointed to by data is supposed to be allocated -** by the callee. This is equivalent of -** objc_read_type (stream, "[N<type>]", data) -*/ - -int -objc_read_array (TypedStream* stream, const char* type, - int count, void* data) -{ - int off = objc_sizeof_type(type); - char* where = (char*)data; - - while (count-- > 0) - { - objc_read_type(stream, type, where); - where += off; - } - return 1; -} - -static int -__objc_fread(FILE* file, char* data, int len) -{ - return fread(data, len, 1, file); -} - -static int -__objc_fwrite(FILE* file, char* data, int len) -{ - return fwrite(data, len, 1, file); -} - -static int -__objc_feof(FILE* file) -{ - return feof(file); -} - -static int -__objc_no_write(FILE* file, char* data, int len) -{ - objc_error (nil, OBJC_ERR_NO_WRITE, "TypedStream not open for writing"); - return 0; -} - -static int -__objc_no_read(FILE* file, char* data, int len) -{ - objc_error (nil, OBJC_ERR_NO_READ, "TypedStream not open for reading"); - return 0; -} - -static int -__objc_read_typed_stream_signature (TypedStream* stream) -{ - char buffer[80]; - int pos = 0; - do - (*stream->read)(stream->physical, buffer+pos, 1); - while (buffer[pos++] != '\0') - ; - sscanf (buffer, "GNU TypedStream %d", &stream->version); - if (stream->version != OBJC_TYPED_STREAM_VERSION) - objc_error (nil, OBJC_ERR_STREAM_VERSION, - "cannot handle TypedStream version %d", stream->version); - return 1; -} - -static int -__objc_write_typed_stream_signature (TypedStream* stream) -{ - char buffer[80]; - sprintf(buffer, "GNU TypedStream %d", OBJC_TYPED_STREAM_VERSION); - stream->version = OBJC_TYPED_STREAM_VERSION; - (*stream->write)(stream->physical, buffer, strlen(buffer)+1); - return 1; -} - -static void __objc_finish_write_root_object(struct objc_typed_stream* stream) -{ - hash_delete (stream->object_table); - stream->object_table = hash_new(64, - (hash_func_type)hash_ptr, - (compare_func_type)compare_ptrs); -} - -static void __objc_finish_read_root_object(struct objc_typed_stream* stream) -{ - node_ptr node; - SEL awake_sel = sel_get_any_uid ("awake"); - cache_ptr free_list = hash_new (64, - (hash_func_type) hash_ptr, - (compare_func_type) compare_ptrs); - - /* resolve object forward references */ - for (node = hash_next (stream->object_refs, NULL); node; - node = hash_next (stream->object_refs, node)) - { - struct objc_list* reflist = node->value; - const void* key = node->key; - id object = hash_value_for_key (stream->object_table, key); - while(reflist) - { - *((id*)reflist->head) = object; - if (hash_value_for_key (free_list,reflist) == NULL) - hash_add (&free_list,reflist,reflist); - - reflist = reflist->tail; - } - } - - /* apply __objc_free to all objects stored in free_list */ - for (node = hash_next (free_list, NULL); node; - node = hash_next (free_list, node)) - objc_free ((void *) node->key); - - hash_delete (free_list); - - /* empty object reference table */ - hash_delete (stream->object_refs); - stream->object_refs = hash_new(8, (hash_func_type)hash_ptr, - (compare_func_type)compare_ptrs); - - /* call -awake for all objects read */ - if (awake_sel) - { - for (node = hash_next (stream->object_table, NULL); node; - node = hash_next (stream->object_table, node)) - { - id object = node->value; - if (__objc_responds_to (object, awake_sel)) - (*objc_msg_lookup(object, awake_sel))(object, awake_sel); - } - } - - /* empty object table */ - hash_delete (stream->object_table); - stream->object_table = hash_new(64, - (hash_func_type)hash_ptr, - (compare_func_type)compare_ptrs); -} - -/* -** Open the stream PHYSICAL in MODE -*/ - -TypedStream* -objc_open_typed_stream (FILE* physical, int mode) -{ - TypedStream* s = (TypedStream*)objc_malloc(sizeof(TypedStream)); - - s->mode = mode; - s->physical = physical; - s->stream_table = hash_new(64, - (hash_func_type)hash_ptr, - (compare_func_type)compare_ptrs); - s->object_table = hash_new(64, - (hash_func_type)hash_ptr, - (compare_func_type)compare_ptrs); - s->eof = (objc_typed_eof_func)__objc_feof; - s->flush = (objc_typed_flush_func)fflush; - s->writing_root_p = 0; - if (mode == OBJC_READONLY) - { - s->class_table = hash_new(8, (hash_func_type)hash_string, - (compare_func_type)compare_strings); - s->object_refs = hash_new(8, (hash_func_type)hash_ptr, - (compare_func_type)compare_ptrs); - s->read = (objc_typed_read_func)__objc_fread; - s->write = (objc_typed_write_func)__objc_no_write; - __objc_read_typed_stream_signature (s); - } - else if (mode == OBJC_WRITEONLY) - { - s->class_table = 0; - s->object_refs = 0; - s->read = (objc_typed_read_func)__objc_no_read; - s->write = (objc_typed_write_func)__objc_fwrite; - __objc_write_typed_stream_signature (s); - } - else - { - objc_close_typed_stream (s); - return NULL; - } - s->type = OBJC_FILE_STREAM; - return s; -} - -/* -** Open the file named by FILE_NAME in MODE -*/ - -TypedStream* -objc_open_typed_stream_for_file (const char* file_name, int mode) -{ - FILE* file = NULL; - TypedStream* s; - - if (mode == OBJC_READONLY) - file = fopen (file_name, "r"); - else - file = fopen (file_name, "w"); - - if (file) - { - s = objc_open_typed_stream (file, mode); - if (s) - s->type |= OBJC_MANAGED_STREAM; - return s; - } - else - return NULL; -} - -/* -** Close STREAM freeing the structure it self. If it was opened with -** objc_open_typed_stream_for_file, the file will also be closed. -*/ - -void -objc_close_typed_stream (TypedStream* stream) -{ - if (stream->mode == OBJC_READONLY) - { - __objc_finish_read_root_object (stream); /* Just in case... */ - hash_delete (stream->class_table); - hash_delete (stream->object_refs); - } - - hash_delete (stream->stream_table); - hash_delete (stream->object_table); - - if (stream->type == (OBJC_MANAGED_STREAM | OBJC_FILE_STREAM)) - fclose ((FILE*)stream->physical); - - objc_free(stream); -} - -BOOL -objc_end_of_typed_stream (TypedStream* stream) -{ - return (*stream->eof)(stream->physical); -} - -void -objc_flush_typed_stream (TypedStream* stream) -{ - (*stream->flush)(stream->physical); -} - -long -objc_get_stream_class_version (TypedStream* stream, Class class) -{ - if (stream->class_table) - return PTR2LONG(hash_value_for_key (stream->class_table, class->name)); - else - return class_get_version (class); -} - diff --git a/contrib/gcc/objc/class.c b/contrib/gcc/objc/class.c deleted file mode 100644 index 44aa1b9f98eb..000000000000 --- a/contrib/gcc/objc/class.c +++ /dev/null @@ -1,358 +0,0 @@ -/* GNU Objective C Runtime class related functions - Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. - Contributed by Kresten Krab Thorup and Dennis Glatting. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation; either version 2, or (at your option) any later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -GNU CC; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#include "runtime.h" /* the kitchen sink */ -#include "sarray.h" - -/* The table of classname->class. Used for objc_lookup_class and friends */ -static cache_ptr __objc_class_hash = 0; /* !T:MUTEX */ - -/* This is a hook which is called by objc_get_class and - objc_lookup_class if the runtime is not able to find the class. - This may e.g. try to load in the class using dynamic loading */ -Class (*_objc_lookup_class)(const char* name) = 0; /* !T:SAFE */ - - -/* True when class links has been resolved */ -BOOL __objc_class_links_resolved = NO; /* !T:UNUSED */ - - -/* Initial number of buckets size of class hash table. */ -#define CLASS_HASH_SIZE 32 - -void __objc_init_class_tables() -{ - /* Allocate the class hash table */ - - if(__objc_class_hash) - return; - - objc_mutex_lock(__objc_runtime_mutex); - - __objc_class_hash - = hash_new (CLASS_HASH_SIZE, - (hash_func_type) hash_string, - (compare_func_type) compare_strings); - - objc_mutex_unlock(__objc_runtime_mutex); -} - -/* This function adds a class to the class hash table, and assigns the - class a number, unless it's already known */ -void -__objc_add_class_to_hash(Class class) -{ - Class h_class; - - objc_mutex_lock(__objc_runtime_mutex); - - /* make sure the table is there */ - assert(__objc_class_hash); - - /* make sure it's not a meta class */ - assert(CLS_ISCLASS(class)); - - /* Check to see if the class is already in the hash table. */ - h_class = hash_value_for_key (__objc_class_hash, class->name); - if (!h_class) - { - /* The class isn't in the hash table. Add the class and assign a class - number. */ - static unsigned int class_number = 1; - - CLS_SETNUMBER(class, class_number); - CLS_SETNUMBER(class->class_pointer, class_number); - - ++class_number; - hash_add (&__objc_class_hash, class->name, class); - } - - objc_mutex_unlock(__objc_runtime_mutex); -} - -/* Get the class object for the class named NAME. If NAME does not - identify a known class, the hook _objc_lookup_class is called. If - this fails, nil is returned */ -Class objc_lookup_class (const char* name) -{ - Class class; - - objc_mutex_lock(__objc_runtime_mutex); - - /* Make sure the class hash table exists. */ - assert (__objc_class_hash); - - class = hash_value_for_key (__objc_class_hash, name); - - objc_mutex_unlock(__objc_runtime_mutex); - - if (class) - return class; - - if (_objc_lookup_class) - return (*_objc_lookup_class)(name); - else - return 0; -} - -/* Get the class object for the class named NAME. If NAME does not - identify a known class, the hook _objc_lookup_class is called. If - this fails, an error message is issued and the system aborts */ -Class -objc_get_class (const char *name) -{ - Class class; - - objc_mutex_lock(__objc_runtime_mutex); - - /* Make sure the class hash table exists. */ - assert (__objc_class_hash); - - class = hash_value_for_key (__objc_class_hash, name); - - objc_mutex_unlock(__objc_runtime_mutex); - - if (class) - return class; - - if (_objc_lookup_class) - class = (*_objc_lookup_class)(name); - - if(class) - return class; - - objc_error(nil, OBJC_ERR_BAD_CLASS, - "objc runtime: cannot find class %s\n", name); - return 0; -} - -MetaClass -objc_get_meta_class(const char *name) -{ - return objc_get_class(name)->class_pointer; -} - -/* This function provides a way to enumerate all the classes in the - executable. Pass *ENUM_STATE == NULL to start the enumeration. The - function will return 0 when there are no more classes. - For example: - id class; - void *es = NULL; - while ((class = objc_next_class(&es))) - ... do something with class; -*/ -Class -objc_next_class(void **enum_state) -{ - objc_mutex_lock(__objc_runtime_mutex); - - /* make sure the table is there */ - assert(__objc_class_hash); - - *(node_ptr*)enum_state = - hash_next(__objc_class_hash, *(node_ptr*)enum_state); - - objc_mutex_unlock(__objc_runtime_mutex); - - if (*(node_ptr*)enum_state) - return (*(node_ptr*)enum_state)->value; - return (Class)0; -} - -/* Resolve super/subclass links for all classes. The only thing we - can be sure of is that the class_pointer for class objects point - to the right meta class objects */ -void __objc_resolve_class_links() -{ - node_ptr node; - Class object_class = objc_get_class ("Object"); - - assert(object_class); - - objc_mutex_lock(__objc_runtime_mutex); - - /* Assign subclass links */ - for (node = hash_next (__objc_class_hash, NULL); node; - node = hash_next (__objc_class_hash, node)) - { - Class class1 = node->value; - - /* Make sure we have what we think we have. */ - assert (CLS_ISCLASS(class1)); - assert (CLS_ISMETA(class1->class_pointer)); - - /* The class_pointer of all meta classes point to Object's meta class. */ - class1->class_pointer->class_pointer = object_class->class_pointer; - - if (!(CLS_ISRESOLV(class1))) - { - CLS_SETRESOLV(class1); - CLS_SETRESOLV(class1->class_pointer); - - if(class1->super_class) - { - Class a_super_class - = objc_get_class ((char *) class1->super_class); - - assert (a_super_class); - - DEBUG_PRINTF ("making class connections for: %s\n", - class1->name); - - /* assign subclass links for superclass */ - class1->sibling_class = a_super_class->subclass_list; - a_super_class->subclass_list = class1; - - /* Assign subclass links for meta class of superclass */ - if (a_super_class->class_pointer) - { - class1->class_pointer->sibling_class - = a_super_class->class_pointer->subclass_list; - a_super_class->class_pointer->subclass_list - = class1->class_pointer; - } - } - else /* a root class, make its meta object */ - /* be a subclass of Object */ - { - class1->class_pointer->sibling_class - = object_class->subclass_list; - object_class->subclass_list = class1->class_pointer; - } - } - } - - /* Assign superclass links */ - for (node = hash_next (__objc_class_hash, NULL); node; - node = hash_next (__objc_class_hash, node)) - { - Class class1 = node->value; - Class sub_class; - for (sub_class = class1->subclass_list; sub_class; - sub_class = sub_class->sibling_class) - { - sub_class->super_class = class1; - if(CLS_ISCLASS(sub_class)) - sub_class->class_pointer->super_class = class1->class_pointer; - } - } - - objc_mutex_unlock(__objc_runtime_mutex); -} - - - -#define CLASSOF(c) ((c)->class_pointer) - -Class -class_pose_as (Class impostor, Class super_class) -{ - node_ptr node; - Class class1; - - if (!CLS_ISRESOLV (impostor)) - __objc_resolve_class_links (); - - /* preconditions */ - assert (impostor); - assert (super_class); - assert (impostor->super_class == super_class); - assert (CLS_ISCLASS (impostor)); - assert (CLS_ISCLASS (super_class)); - assert (impostor->instance_size == super_class->instance_size); - - { - Class *subclass = &(super_class->subclass_list); - - /* move subclasses of super_class to impostor */ - while (*subclass) - { - Class nextSub = (*subclass)->sibling_class; - - if (*subclass != impostor) - { - Class sub = *subclass; - - /* classes */ - sub->sibling_class = impostor->subclass_list; - sub->super_class = impostor; - impostor->subclass_list = sub; - - /* It will happen that SUB is not a class object if it is - the top of the meta class hierarchy chain. (root - meta-class objects inherit their class object) If that is - the case... don't mess with the meta-meta class. */ - if (CLS_ISCLASS (sub)) - { - /* meta classes */ - CLASSOF (sub)->sibling_class = - CLASSOF (impostor)->subclass_list; - CLASSOF (sub)->super_class = CLASSOF (impostor); - CLASSOF (impostor)->subclass_list = CLASSOF (sub); - } - } - - *subclass = nextSub; - } - - /* set subclasses of superclass to be impostor only */ - super_class->subclass_list = impostor; - CLASSOF (super_class)->subclass_list = CLASSOF (impostor); - - /* set impostor to have no sibling classes */ - impostor->sibling_class = 0; - CLASSOF (impostor)->sibling_class = 0; - } - - /* check relationship of impostor and super_class is kept. */ - assert (impostor->super_class == super_class); - assert (CLASSOF (impostor)->super_class == CLASSOF (super_class)); - - /* This is how to update the lookup table. Regardless of - what the keys of the hashtable is, change all values that are - superclass into impostor. */ - - objc_mutex_lock(__objc_runtime_mutex); - - for (node = hash_next (__objc_class_hash, NULL); node; - node = hash_next (__objc_class_hash, node)) - { - class1 = (Class)node->value; - if (class1 == super_class) - { - node->value = impostor; /* change hash table value */ - } - } - - objc_mutex_unlock(__objc_runtime_mutex); - - /* next, we update the dispatch tables... */ - __objc_update_dispatch_table_for_class (CLASSOF (impostor)); - __objc_update_dispatch_table_for_class (impostor); - - return impostor; -} - - diff --git a/contrib/gcc/objc/config-lang.in b/contrib/gcc/objc/config-lang.in deleted file mode 100644 index 5287c8d4d6c3..000000000000 --- a/contrib/gcc/objc/config-lang.in +++ /dev/null @@ -1,35 +0,0 @@ -# Top level configure fragment for the GNU Objective-C Runtime Library. -# Copyright (C) 1997, 1998 Free Software Foundation, Inc. - -#This file is part of GNU CC. - -#GNU CC is free software; you can redistribute it and/or modify -#it under the terms of the GNU General Public License as published by -#the Free Software Foundation; either version 2, or (at your option) -#any later version. - -#GNU CC is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. - -#You should have received a copy of the GNU General Public License -#along with GNU CC; see the file COPYING. If not, write to -#the Free Software Foundation, 59 Temple Place - Suite 330, -#Boston, MA 02111-1307, USA. - -# Configure looks for the existence of this file to auto-config each language. -# We define several parameters used by configure: -# -# language - name of language as it would appear in $(LANGUAGES) -# compilers - value to add to $(COMPILERS) -# stagestuff - files to add to $(STAGESTUFF) -# diff_excludes - files to ignore when building diffs between two versions. - -language="objc" - -compilers="cc1obj\$(exeext)" - -stagestuff="" - -diff_excludes="-x objc-parse.c -x objc-parse.y " diff --git a/contrib/gcc/objc/encoding.c b/contrib/gcc/objc/encoding.c deleted file mode 100644 index e6f84aa04a4f..000000000000 --- a/contrib/gcc/objc/encoding.c +++ /dev/null @@ -1,554 +0,0 @@ -/* Encoding of types for Objective C. - Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - Contributed by Kresten Krab Thorup - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#include "encoding.h" - -#define MAX(X, Y) \ - ({ typeof(X) __x = (X), __y = (Y); \ - (__x > __y ? __x : __y); }) - -#define MIN(X, Y) \ - ({ typeof(X) __x = (X), __y = (Y); \ - (__x < __y ? __x : __y); }) - -#define ROUND(V, A) \ - ({ typeof(V) __v=(V); typeof(A) __a=(A); \ - __a*((__v+__a-1)/__a); }) - - -static inline int -atoi (const char* str) -{ - int res = 0; - - while (isdigit (*str)) - res *= 10, res += (*str++ - '0'); - - return res; -} - -/* - return the size of an object specified by type -*/ - -int -objc_sizeof_type(const char* type) -{ - switch(*type) { - case _C_ID: - return sizeof(id); - break; - - case _C_CLASS: - return sizeof(Class); - break; - - case _C_SEL: - return sizeof(SEL); - break; - - case _C_CHR: - return sizeof(char); - break; - - case _C_UCHR: - return sizeof(unsigned char); - break; - - case _C_SHT: - return sizeof(short); - break; - - case _C_USHT: - return sizeof(unsigned short); - break; - - case _C_INT: - return sizeof(int); - break; - - case _C_UINT: - return sizeof(unsigned int); - break; - - case _C_LNG: - return sizeof(long); - break; - - case _C_ULNG: - return sizeof(unsigned long); - break; - - case _C_FLT: - return sizeof(float); - break; - - case _C_DBL: - return sizeof(double); - break; - - case _C_VOID: - return sizeof(void); - break; - case _C_PTR: - case _C_ATOM: - case _C_CHARPTR: - return sizeof(char*); - break; - - case _C_ARY_B: - { - int len = atoi(type+1); - while (isdigit(*++type)); - return len*objc_aligned_size (type); - } - break; - - case _C_STRUCT_B: - { - int acc_size = 0; - int align; - while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */ - while (*type != _C_STRUCT_E) - { - align = objc_alignof_type (type); /* padd to alignment */ - acc_size = ROUND (acc_size, align); - acc_size += objc_sizeof_type (type); /* add component size */ - type = objc_skip_typespec (type); /* skip component */ - } - return acc_size; - } - - case _C_UNION_B: - { - int max_size = 0; - while (*type != _C_UNION_E && *type++ != '=') /* do nothing */; - while (*type != _C_UNION_E) - { - max_size = MAX (max_size, objc_sizeof_type (type)); - type = objc_skip_typespec (type); - } - return max_size; - } - - default: - { - objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type); - return 0; - } - } -} - - -/* - Return the alignment of an object specified by type -*/ - -int -objc_alignof_type(const char* type) -{ - switch(*type) { - case _C_ID: - return __alignof__(id); - break; - - case _C_CLASS: - return __alignof__(Class); - break; - - case _C_SEL: - return __alignof__(SEL); - break; - - case _C_CHR: - return __alignof__(char); - break; - - case _C_UCHR: - return __alignof__(unsigned char); - break; - - case _C_SHT: - return __alignof__(short); - break; - - case _C_USHT: - return __alignof__(unsigned short); - break; - - case _C_INT: - return __alignof__(int); - break; - - case _C_UINT: - return __alignof__(unsigned int); - break; - - case _C_LNG: - return __alignof__(long); - break; - - case _C_ULNG: - return __alignof__(unsigned long); - break; - - case _C_FLT: - return __alignof__(float); - break; - - case _C_DBL: - return __alignof__(double); - break; - - case _C_PTR: - case _C_ATOM: - case _C_CHARPTR: - return __alignof__(char*); - break; - - case _C_ARY_B: - while (isdigit(*++type)) /* do nothing */; - return objc_alignof_type (type); - - case _C_STRUCT_B: - { - struct { int x; double y; } fooalign; - while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */; - if (*type != _C_STRUCT_E) - return MAX (objc_alignof_type (type), __alignof__ (fooalign)); - else - return __alignof__ (fooalign); - } - - case _C_UNION_B: - { - int maxalign = 0; - while (*type != _C_UNION_E && *type++ != '=') /* do nothing */; - while (*type != _C_UNION_E) - { - maxalign = MAX (maxalign, objc_alignof_type (type)); - type = objc_skip_typespec (type); - } - return maxalign; - } - - default: - { - objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type); - return 0; - } - } -} - -/* - The aligned size if the size rounded up to the nearest alignment. -*/ - -int -objc_aligned_size (const char* type) -{ - int size = objc_sizeof_type (type); - int align = objc_alignof_type (type); - return ROUND (size, align); -} - -/* - The size rounded up to the nearest integral of the wordsize, taken - to be the size of a void*. -*/ - -int -objc_promoted_size (const char* type) -{ - int size = objc_sizeof_type (type); - int wordsize = sizeof (void*); - - return ROUND (size, wordsize); -} - -/* - Skip type qualifiers. These may eventually precede typespecs - occurring in method prototype encodings. -*/ - -inline const char* -objc_skip_type_qualifiers (const char* type) -{ - while (*type == _C_CONST - || *type == _C_IN - || *type == _C_INOUT - || *type == _C_OUT - || *type == _C_BYCOPY - || *type == _C_ONEWAY) - { - type += 1; - } - return type; -} - - -/* - Skip one typespec element. If the typespec is prepended by type - qualifiers, these are skipped as well. -*/ - -const char* -objc_skip_typespec (const char* type) -{ - type = objc_skip_type_qualifiers (type); - - switch (*type) { - - case _C_ID: - /* An id may be annotated by the actual type if it is known - with the @"ClassName" syntax */ - - if (*++type != '"') - return type; - else - { - while (*++type != '"') /* do nothing */; - return type + 1; - } - - /* The following are one character type codes */ - case _C_CLASS: - case _C_SEL: - case _C_CHR: - case _C_UCHR: - case _C_CHARPTR: - case _C_ATOM: - case _C_SHT: - case _C_USHT: - case _C_INT: - case _C_UINT: - case _C_LNG: - case _C_ULNG: - case _C_FLT: - case _C_DBL: - case _C_VOID: - case _C_UNDEF: - return ++type; - break; - - case _C_ARY_B: - /* skip digits, typespec and closing ']' */ - - while(isdigit(*++type)); - type = objc_skip_typespec(type); - if (*type == _C_ARY_E) - return ++type; - else - { - objc_error(nil, OBJC_ERR_BAD_TYPE, "bad array type %s\n", type); - return 0; - } - - case _C_STRUCT_B: - /* skip name, and elements until closing '}' */ - - while (*type != _C_STRUCT_E && *type++ != '='); - while (*type != _C_STRUCT_E) { type = objc_skip_typespec (type); } - return ++type; - - case _C_UNION_B: - /* skip name, and elements until closing ')' */ - - while (*type != _C_UNION_E && *type++ != '='); - while (*type != _C_UNION_E) { type = objc_skip_typespec (type); } - return ++type; - - case _C_PTR: - /* Just skip the following typespec */ - - return objc_skip_typespec (++type); - - default: - { - objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type); - return 0; - } - } -} - -/* - Skip an offset as part of a method encoding. This is prepended by a - '+' if the argument is passed in registers. -*/ -inline const char* -objc_skip_offset (const char* type) -{ - if (*type == '+') type++; - while(isdigit(*++type)); - return type; -} - -/* - Skip an argument specification of a method encoding. -*/ -const char* -objc_skip_argspec (const char* type) -{ - type = objc_skip_typespec (type); - type = objc_skip_offset (type); - return type; -} - -/* - Return the number of arguments that the method MTH expects. - Note that all methods need two implicit arguments `self' and - `_cmd'. -*/ -int -method_get_number_of_arguments (struct objc_method* mth) -{ - int i = 0; - const char* type = mth->method_types; - while (*type) - { - type = objc_skip_argspec (type); - i += 1; - } - return i - 1; -} - -/* - Return the size of the argument block needed on the stack to invoke - the method MTH. This may be zero, if all arguments are passed in - registers. -*/ - -int -method_get_sizeof_arguments (struct objc_method* mth) -{ - const char* type = objc_skip_typespec (mth->method_types); - return atoi (type); -} - -/* - Return a pointer to the next argument of ARGFRAME. type points to - the last argument. Typical use of this look like: - - { - char *datum, *type; - for (datum = method_get_first_argument (method, argframe, &type); - datum; datum = method_get_next_argument (argframe, &type)) - { - unsigned flags = objc_get_type_qualifiers (type); - type = objc_skip_type_qualifiers (type); - if (*type != _C_PTR) - [portal encodeData: datum ofType: type]; - else - { - if ((flags & _F_IN) == _F_IN) - [portal encodeData: *(char**)datum ofType: ++type]; - } - } - } -*/ - -char* -method_get_next_argument (arglist_t argframe, - const char **type) -{ - const char *t = objc_skip_argspec (*type); - - if (*t == '\0') - return 0; - - *type = t; - t = objc_skip_typespec (t); - - if (*t == '+') - return argframe->arg_regs + atoi (++t); - else - return argframe->arg_ptr + atoi (t); -} - -/* - Return a pointer to the value of the first argument of the method - described in M with the given argumentframe ARGFRAME. The type - is returned in TYPE. type must be passed to successive calls of - method_get_next_argument. -*/ -char* -method_get_first_argument (struct objc_method* m, - arglist_t argframe, - const char** type) -{ - *type = m->method_types; - return method_get_next_argument (argframe, type); -} - -/* - Return a pointer to the ARGth argument of the method - M from the frame ARGFRAME. The type of the argument - is returned in the value-result argument TYPE -*/ - -char* -method_get_nth_argument (struct objc_method* m, - arglist_t argframe, int arg, - const char **type) -{ - const char* t = objc_skip_argspec (m->method_types); - - if (arg > method_get_number_of_arguments (m)) - return 0; - - while (arg--) - t = objc_skip_argspec (t); - - *type = t; - t = objc_skip_typespec (t); - - if (*t == '+') - return argframe->arg_regs + atoi (++t); - else - return argframe->arg_ptr + atoi (t); -} - -unsigned -objc_get_type_qualifiers (const char* type) -{ - unsigned res = 0; - BOOL flag = YES; - - while (flag) - switch (*type++) - { - case _C_CONST: res |= _F_CONST; break; - case _C_IN: res |= _F_IN; break; - case _C_INOUT: res |= _F_INOUT; break; - case _C_OUT: res |= _F_OUT; break; - case _C_BYCOPY: res |= _F_BYCOPY; break; - case _C_ONEWAY: res |= _F_ONEWAY; break; - default: flag = NO; - } - - return res; -} diff --git a/contrib/gcc/objc/encoding.h b/contrib/gcc/objc/encoding.h deleted file mode 100644 index 141e9fe9e978..000000000000 --- a/contrib/gcc/objc/encoding.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Encoding of types for Objective C. - Copyright (C) 1993, 1997 Free Software Foundation, Inc. - -Author: Kresten Krab Thorup - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __encoding_INCLUDE_GNU -#define __encoding_INCLUDE_GNU - -#include <ctype.h> -#include "objc/objc-api.h" - -#define _C_CONST 'r' -#define _C_IN 'n' -#define _C_INOUT 'N' -#define _C_OUT 'o' -#define _C_BYCOPY 'O' -#define _C_ONEWAY 'V' - -#define _F_CONST 0x01 -#define _F_IN 0x01 -#define _F_OUT 0x02 -#define _F_INOUT 0x03 -#define _F_BYCOPY 0x04 -#define _F_ONEWAY 0x08 - - -int objc_aligned_size (const char* type); -int objc_sizeof_type (const char* type); -int objc_alignof_type (const char* type); -int objc_aligned_size (const char* type); -int objc_promoted_size (const char* type); -const char* objc_skip_type_qualifiers (const char* type); -const char* objc_skip_typespec (const char* type); -const char* objc_skip_offset (const char* type); -const char* objc_skip_argspec (const char* type); -int method_get_number_of_arguments (struct objc_method*); -int method_get_sizeof_arguments (struct objc_method*); - -char* method_get_first_argument (struct objc_method*, - arglist_t argframe, - const char** type); -char* method_get_next_argument (arglist_t argframe, - const char **type); -char* method_get_nth_argument (struct objc_method* m, - arglist_t argframe, - int arg, - const char **type); - -unsigned objc_get_type_qualifiers (const char* type); - - -#endif /* __encoding_INCLUDE_GNU */ diff --git a/contrib/gcc/objc/hash.c b/contrib/gcc/objc/hash.c deleted file mode 100644 index 7534330fa1c7..000000000000 --- a/contrib/gcc/objc/hash.c +++ /dev/null @@ -1,283 +0,0 @@ -/* Hash tables for Objective C internal structures - Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#include "assert.h" - -#include "objc/hash.h" - -#include "runtime.h" /* for DEBUG_PRINTF */ - -/* These two macros determine when a hash table is full and - by how much it should be expanded respectively. - - These equations are percentages. */ -#define FULLNESS(cache) \ - ((((cache)->size * 75) / 100) <= (cache)->used) -#define EXPANSION(cache) \ - ((cache)->size * 2) - -cache_ptr -hash_new (unsigned int size, hash_func_type hash_func, - compare_func_type compare_func) -{ - cache_ptr cache; - - /* Pass me a value greater than 0 and a power of 2. */ - assert (size); - assert (!(size & (size - 1))); - - /* Allocate the cache structure. calloc insures - its initialization for default values. */ - cache = (cache_ptr) objc_calloc (1, sizeof (struct cache)); - assert (cache); - - /* Allocate the array of buckets for the cache. - calloc initializes all of the pointers to NULL. */ - cache->node_table - = (node_ptr *) objc_calloc (size, sizeof (node_ptr)); - assert (cache->node_table); - - cache->size = size; - - /* This should work for all processor architectures? */ - cache->mask = (size - 1); - - /* Store the hashing function so that codes can be computed. */ - cache->hash_func = hash_func; - - /* Store the function that compares hash keys to - determine if they are equal. */ - cache->compare_func = compare_func; - - return cache; -} - - -void -hash_delete (cache_ptr cache) -{ - node_ptr node; - node_ptr next_node; - unsigned int i; - - /* Purge all key/value pairs from the table. */ - /* Step through the nodes one by one and remove every node WITHOUT - using hash_next. this makes hash_delete much more efficient. */ - for (i = 0;i < cache->size;i++) { - if ((node = cache->node_table[i])) { - /* an entry in the hash table has been found, now step through the - nodes next in the list and free them. */ - while ((next_node = node->next)) { - hash_remove (cache,node->key); - node = next_node; - } - - hash_remove (cache,node->key); - } - } - - /* Release the array of nodes and the cache itself. */ - objc_free(cache->node_table); - objc_free(cache); -} - - -void -hash_add (cache_ptr *cachep, const void *key, void *value) -{ - size_t indx = (*(*cachep)->hash_func)(*cachep, key); - node_ptr node = (node_ptr) objc_calloc (1, sizeof (struct cache_node)); - - - assert (node); - - /* Initialize the new node. */ - node->key = key; - node->value = value; - node->next = (*cachep)->node_table[indx]; - - /* Debugging. - Check the list for another key. */ -#ifdef DEBUG - { node_ptr node1 = (*cachep)->node_table[indx]; - - while (node1) { - - assert (node1->key != key); - node1 = node1->next; - } - } -#endif - - /* Install the node as the first element on the list. */ - (*cachep)->node_table[indx] = node; - - /* Bump the number of entries in the cache. */ - ++(*cachep)->used; - - /* Check the hash table's fullness. We're going - to expand if it is above the fullness level. */ - if (FULLNESS (*cachep)) { - - /* The hash table has reached its fullness level. Time to - expand it. - - I'm using a slow method here but is built on other - primitive functions thereby increasing its - correctness. */ - node_ptr node1 = NULL; - cache_ptr new = hash_new (EXPANSION (*cachep), - (*cachep)->hash_func, - (*cachep)->compare_func); - - DEBUG_PRINTF ("Expanding cache %#x from %d to %d\n", - *cachep, (*cachep)->size, new->size); - - /* Copy the nodes from the first hash table to the new one. */ - while ((node1 = hash_next (*cachep, node1))) - hash_add (&new, node1->key, node1->value); - - /* Trash the old cache. */ - hash_delete (*cachep); - - /* Return a pointer to the new hash table. */ - *cachep = new; - } -} - - -void -hash_remove (cache_ptr cache, const void *key) -{ - size_t indx = (*cache->hash_func)(cache, key); - node_ptr node = cache->node_table[indx]; - - - /* We assume there is an entry in the table. Error if it is not. */ - assert (node); - - /* Special case. First element is the key/value pair to be removed. */ - if ((*cache->compare_func)(node->key, key)) { - cache->node_table[indx] = node->next; - objc_free(node); - } else { - - /* Otherwise, find the hash entry. */ - node_ptr prev = node; - BOOL removed = NO; - - do { - - if ((*cache->compare_func)(node->key, key)) { - prev->next = node->next, removed = YES; - objc_free(node); - } else - prev = node, node = node->next; - } while (!removed && node); - assert (removed); - } - - /* Decrement the number of entries in the hash table. */ - --cache->used; -} - - -node_ptr -hash_next (cache_ptr cache, node_ptr node) -{ - /* If the scan is being started then reset the last node - visitied pointer and bucket index. */ - if (!node) - cache->last_bucket = 0; - - /* If there is a node visited last then check for another - entry in the same bucket; Otherwise step to the next bucket. */ - if (node) { - if (node->next) - /* There is a node which follows the last node - returned. Step to that node and retun it. */ - return node->next; - else - ++cache->last_bucket; - } - - /* If the list isn't exhausted then search the buckets for - other nodes. */ - if (cache->last_bucket < cache->size) { - /* Scan the remainder of the buckets looking for an entry - at the head of the list. Return the first item found. */ - while (cache->last_bucket < cache->size) - if (cache->node_table[cache->last_bucket]) - return cache->node_table[cache->last_bucket]; - else - ++cache->last_bucket; - - /* No further nodes were found in the hash table. */ - return NULL; - } else - return NULL; -} - - -/* Given KEY, return corresponding value for it in CACHE. - Return NULL if the KEY is not recorded. */ - -void * -hash_value_for_key (cache_ptr cache, const void *key) -{ - node_ptr node = cache->node_table[(*cache->hash_func)(cache, key)]; - void *retval = NULL; - - if (node) - do { - if ((*cache->compare_func)(node->key, key)) { - retval = node->value; - break; - } else - node = node->next; - } while (!retval && node); - - return retval; -} - -/* Given KEY, return YES if it exists in the CACHE. - Return NO if it does not */ - -BOOL -hash_is_key_in_hash (cache_ptr cache, const void *key) -{ - node_ptr node = cache->node_table[(*cache->hash_func)(cache, key)]; - - if (node) - do { - if ((*cache->compare_func)(node->key, key)) - return YES; - else - node = node->next; - } while (node); - - return NO; -} diff --git a/contrib/gcc/objc/hash.h b/contrib/gcc/objc/hash.h deleted file mode 100644 index bddb791c820c..000000000000 --- a/contrib/gcc/objc/hash.h +++ /dev/null @@ -1,206 +0,0 @@ -/* Hash tables for Objective C method dispatch. - Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - - -#ifndef __hash_INCLUDE_GNU -#define __hash_INCLUDE_GNU - -#include <stddef.h> -#include <objc/objc.h> - -/* - * This data structure is used to hold items - * stored in a hash table. Each node holds - * a key/value pair. - * - * Items in the cache are really of type void *. - */ -typedef struct cache_node -{ - struct cache_node *next; /* Pointer to next entry on the list. - NULL indicates end of list. */ - const void *key; /* Key used to locate the value. Used - to locate value when more than one - key computes the same hash - value. */ - void *value; /* Value stored for the key. */ -} *node_ptr; - - -/* - * This data type is the function that computes a hash code given a key. - * Therefore, the key can be a pointer to anything and the function specific - * to the key type. - * - * Unfortunately there is a mutual data structure reference problem with this - * typedef. Therefore, to remove compiler warnings the functions passed to - * hash_new will have to be casted to this type. - */ -typedef unsigned int (*hash_func_type)(void *, const void *); - -/* - * This data type is the function that compares two hash keys and returns an - * integer greater than, equal to, or less than 0, according as the first - * parameter is lexicographically greater than, equal to, or less than the - * second. - */ - -typedef int (*compare_func_type)(const void *, const void *); - - -/* - * This data structure is the cache. - * - * It must be passed to all of the hashing routines - * (except for new). - */ -typedef struct cache -{ - /* Variables used to implement the hash itself. */ - node_ptr *node_table; /* Pointer to an array of hash nodes. */ - /* Variables used to track the size of the hash table so to determine - when to resize it. */ - unsigned int size; /* Number of buckets allocated for the hash table - (number of array entries allocated for - "node_table"). Must be a power of two. */ - unsigned int used; /* Current number of entries in the hash table. */ - unsigned int mask; /* Precomputed mask. */ - - /* Variables used to implement indexing through the hash table. */ - - unsigned int last_bucket; /* Tracks which entry in the array where - the last value was returned. */ - /* Function used to compute a hash code given a key. - This function is specified when the hash table is created. */ - hash_func_type hash_func; - /* Function used to compare two hash keys to see if they are equal. */ - compare_func_type compare_func; -} *cache_ptr; - - -/* Two important hash tables. */ -extern cache_ptr module_hash_table, class_hash_table; - -/* Allocate and initialize a hash table. */ - -cache_ptr hash_new (unsigned int size, - hash_func_type hash_func, - compare_func_type compare_func); - -/* Deallocate all of the hash nodes and the cache itself. */ - -void hash_delete (cache_ptr cache); - -/* Add the key/value pair to the hash table. If the - hash table reaches a level of fullness then it will be resized. - - assert if the key is already in the hash. */ - -void hash_add (cache_ptr *cachep, const void *key, void *value); - -/* Remove the key/value pair from the hash table. - assert if the key isn't in the table. */ - -void hash_remove (cache_ptr cache, const void *key); - -/* Used to index through the hash table. Start with NULL - to get the first entry. - - Successive calls pass the value returned previously. - ** Don't modify the hash during this operation *** - - Cache nodes are returned such that key or value can - be extracted. */ - -node_ptr hash_next (cache_ptr cache, node_ptr node); - -/* Used to return a value from a hash table using a given key. */ - -void *hash_value_for_key (cache_ptr cache, const void *key); - -/* Used to determine if the given key exists in the hash table */ - -BOOL hash_is_key_in_hash (cache_ptr cache, const void *key); - -/************************************************ - - Useful hashing functions. - - Declared inline for your pleasure. - -************************************************/ - -/* Calculate a hash code by performing some - manipulation of the key pointer. (Use the lowest bits - except for those likely to be 0 due to alignment.) */ - -static inline unsigned int -hash_ptr (cache_ptr cache, const void *key) -{ - return ((size_t)key / sizeof (void *)) & cache->mask; -} - - -/* Calculate a hash code by iterating over a NULL - terminate string. */ -static inline unsigned int -hash_string (cache_ptr cache, const void *key) -{ - unsigned int ret = 0; - unsigned int ctr = 0; - - - while (*(char*)key) { - ret ^= *(char*)key++ << ctr; - ctr = (ctr + 1) % sizeof (void *); - } - - return ret & cache->mask; -} - - -/* Compare two pointers for equality. */ -static inline int -compare_ptrs (const void *k1, const void *k2) -{ - return !(k1 - k2); -} - - -/* Compare two strings. */ -static inline int -compare_strings (const void *k1, const void *k2) -{ - if (k1 == k2) - return 1; - else if (k1 == 0 || k2 == 0) - return 0; - else - return !strcmp (k1, k2); -} - - -#endif /* not __hash_INCLUDE_GNU */ diff --git a/contrib/gcc/objc/init.c b/contrib/gcc/objc/init.c deleted file mode 100644 index f1fea8123186..000000000000 --- a/contrib/gcc/objc/init.c +++ /dev/null @@ -1,834 +0,0 @@ -/* GNU Objective C Runtime initialization - Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. - Contributed by Kresten Krab Thorup - +load support contributed by Ovidiu Predescu <ovidiu@net-community.com> - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation; either version 2, or (at your option) any later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -GNU CC; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#include "runtime.h" - -/* The version number of this runtime. This must match the number - defined in gcc (objc-act.c) */ -#define OBJC_VERSION 8 -#define PROTOCOL_VERSION 2 - -/* This list contains all modules currently loaded into the runtime */ -static struct objc_list* __objc_module_list = 0; /* !T:MUTEX */ - -/* This list contains all proto_list's not yet assigned class links */ -static struct objc_list* unclaimed_proto_list = 0; /* !T:MUTEX */ - -/* List of unresolved static instances. */ -static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */ - -/* Global runtime "write" mutex. */ -objc_mutex_t __objc_runtime_mutex = 0; - -/* Number of threads that are alive. */ -int __objc_runtime_threads_alive = 1; /* !T:MUTEX */ - -/* Check compiler vs runtime version */ -static void init_check_module_version (Module_t); - -/* Assign isa links to protos */ -static void __objc_init_protocols (struct objc_protocol_list* protos); - -/* Add protocol to class */ -static void __objc_class_add_protocols (Class, struct objc_protocol_list*); - -/* This is a hook which is called by __objc_exec_class every time a class - or a category is loaded into the runtime. This may e.g. help a - dynamic loader determine the classes that have been loaded when - an object file is dynamically linked in */ -void (*_objc_load_callback)(Class class, Category* category); /* !T:SAFE */ - -/* Is all categories/classes resolved? */ -BOOL __objc_dangling_categories = NO; /* !T:UNUSED */ - -extern SEL -__sel_register_typed_name (const char *name, const char *types, - struct objc_selector *orig, BOOL is_const); - -/* Sends +load to all classes and categories in certain situations. */ -static void objc_send_load (void); - -/* Inserts all the classes defined in module in a tree of classes that - resembles the class hierarchy. This tree is traversed in preorder and the - classes in its nodes receive the +load message if these methods were not - executed before. The algorithm ensures that when the +load method of a class - is executed all the superclasses have been already received the +load - message. */ -static void __objc_create_classes_tree (Module_t module); - -static void __objc_call_callback (Module_t module); - -/* A special version that works only before the classes are completely - installed in the runtime. */ -static BOOL class_is_subclass_of_class (Class class, Class superclass); - -typedef struct objc_class_tree { - Class class; - struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */ -} objc_class_tree; - -/* This is a linked list of objc_class_tree trees. The head of these trees - are root classes (their super class is Nil). These different trees - represent different class hierarchies. */ -static struct objc_list *__objc_class_tree_list = NULL; - -/* Keeps the +load methods who have been already executed. This hash should - not be destroyed during the execution of the program. */ -static cache_ptr __objc_load_methods = NULL; - -/* Creates a tree of classes whose topmost class is directly inherited from - `upper' and the bottom class in this tree is `bottom_class'. The classes - in this tree are super classes of `bottom_class'. `subclasses' member - of each tree node point to the next subclass tree node. */ -static objc_class_tree * -create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper) -{ - Class superclass = bottom_class->super_class ? - objc_lookup_class ((char*)bottom_class->super_class) - : Nil; - - objc_class_tree *tree, *prev; - - DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:"); - DEBUG_PRINTF ("bottom_class = %s, upper = %s\n", - (bottom_class ? bottom_class->name : NULL), - (upper ? upper->name : NULL)); - - tree = prev = objc_calloc (1, sizeof (objc_class_tree)); - prev->class = bottom_class; - - while (superclass != upper) - { - tree = objc_calloc (1, sizeof (objc_class_tree)); - tree->class = superclass; - tree->subclasses = list_cons (prev, tree->subclasses); - superclass = (superclass->super_class ? - objc_lookup_class ((char*)superclass->super_class) - : Nil); - prev = tree; - } - - return tree; -} - -/* Insert the `class' into the proper place in the `tree' class hierarchy. This - function returns a new tree if the class has been successfully inserted into - the tree or NULL if the class is not part of the classes hierarchy described - by `tree'. This function is private to objc_tree_insert_class(), you should - not call it directly. */ -static objc_class_tree * -__objc_tree_insert_class (objc_class_tree *tree, Class class) -{ - DEBUG_PRINTF ("__objc_tree_insert_class: tree = %x, class = %s\n", - tree, class->name); - - if (tree == NULL) - return create_tree_of_subclasses_inherited_from (class, NULL); - else if (class == tree->class) - { - /* `class' has been already inserted */ - DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name); - return tree; - } - else if ((class->super_class ? - objc_lookup_class ((char*)class->super_class) - : Nil) - == tree->class) - { - /* If class is a direct subclass of tree->class then add class to the - list of subclasses. First check to see if it wasn't already - inserted. */ - struct objc_list *list = tree->subclasses; - objc_class_tree *node; - - while (list) - { - /* Class has been already inserted; do nothing just return - the tree. */ - if (((objc_class_tree*)list->head)->class == class) - { - DEBUG_PRINTF ("2. class %s was previously inserted\n", - class->name); - return tree; - } - list = list->tail; - } - - /* Create a new node class and insert it into the list of subclasses */ - node = objc_calloc (1, sizeof (objc_class_tree)); - node->class = class; - tree->subclasses = list_cons (node, tree->subclasses); - DEBUG_PRINTF ("3. class %s inserted\n", class->name); - return tree; - } - else - { - /* The class is not a direct subclass of tree->class. Search for class's - superclasses in the list of subclasses. */ - struct objc_list *subclasses = tree->subclasses; - - /* Precondition: the class must be a subclass of tree->class; otherwise - return NULL to indicate our caller that it must take the next tree. */ - if (!class_is_subclass_of_class (class, tree->class)) - return NULL; - - for (; subclasses != NULL; subclasses = subclasses->tail) - { - Class aClass = ((objc_class_tree*)(subclasses->head))->class; - - if (class_is_subclass_of_class (class, aClass)) - { - /* If we found one of class's superclasses we insert the class - into its subtree and return the original tree since nothing - has been changed. */ - subclasses->head - = __objc_tree_insert_class (subclasses->head, class); - DEBUG_PRINTF ("4. class %s inserted\n", class->name); - return tree; - } - } - - /* We haven't found a subclass of `class' in the `subclasses' list. - Create a new tree of classes whose topmost class is a direct subclass - of tree->class. */ - { - objc_class_tree *new_tree - = create_tree_of_subclasses_inherited_from (class, tree->class); - tree->subclasses = list_cons (new_tree, tree->subclasses); - DEBUG_PRINTF ("5. class %s inserted\n", class->name); - return tree; - } - } -} - -/* This function inserts `class' in the right tree hierarchy classes. */ -static void -objc_tree_insert_class (Class class) -{ - struct objc_list *list_node; - objc_class_tree *tree; - - list_node = __objc_class_tree_list; - while (list_node) - { - tree = __objc_tree_insert_class (list_node->head, class); - if (tree) - { - list_node->head = tree; - break; - } - else - list_node = list_node->tail; - } - - /* If the list was finished but the class hasn't been inserted, insert it - here. */ - if (!list_node) - { - __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list); - __objc_class_tree_list->head = __objc_tree_insert_class (NULL, class); - } -} - -/* Traverse tree in preorder. Used to send +load. */ -static void -objc_preorder_traverse (objc_class_tree *tree, - int level, - void (*function)(objc_class_tree*, int)) -{ - struct objc_list *node; - - (*function) (tree, level); - for (node = tree->subclasses; node; node = node->tail) - objc_preorder_traverse (node->head, level + 1, function); -} - -/* Traverse tree in postorder. Used to destroy a tree. */ -static void -objc_postorder_traverse (objc_class_tree *tree, - int level, - void (*function)(objc_class_tree*, int)) -{ - struct objc_list *node; - - for (node = tree->subclasses; node; node = node->tail) - objc_postorder_traverse (node->head, level + 1, function); - (*function) (tree, level); -} - -/* Used to print a tree class hierarchy. */ -#ifdef DEBUG -static void -__objc_tree_print (objc_class_tree *tree, int level) -{ - int i; - - for (i = 0; i < level; i++) - printf (" "); - printf ("%s\n", tree->class->name); -} -#endif - -/* Walks on a linked list of methods in the reverse order and executes all - the methods corresponding to `op' selector. Walking in the reverse order - assures the +load of class is executed first and then +load of categories - because of the way in which categories are added to the class methods. */ -static void -__objc_send_message_in_list (MethodList_t method_list, Class class, SEL op) -{ - int i; - - if (!method_list) - return; - - /* First execute the `op' message in the following method lists */ - __objc_send_message_in_list (method_list->method_next, class, op); - - /* Search the method list. */ - for (i = 0; i < method_list->method_count; i++) - { - Method_t mth = &method_list->method_list[i]; - - if (mth->method_name && sel_eq (mth->method_name, op) - && !hash_is_key_in_hash (__objc_load_methods, mth->method_name)) - { - /* The method was found and wasn't previously executed. */ - (*mth->method_imp) ((id)class, mth->method_name); - - /* Add this method into the +load hash table */ - hash_add (&__objc_load_methods, mth->method_imp, mth->method_imp); - - DEBUG_PRINTF ("sending +load in class: %s\n", class->name); - - break; - } - } -} - -static void -__objc_send_load (objc_class_tree *tree, int level) -{ - static SEL load_sel = 0; - Class class = tree->class; - MethodList_t method_list = class->class_pointer->methods; - - if (!load_sel) - load_sel = sel_register_name ("load"); - - __objc_send_message_in_list (method_list, class, load_sel); -} - -static void -__objc_destroy_class_tree_node (objc_class_tree *tree, int level) -{ - objc_free (tree); -} - -/* This is used to check if the relationship between two classes before the - runtime completely installs the classes. */ -static BOOL -class_is_subclass_of_class (Class class, Class superclass) -{ - for (; class != Nil;) - { - if (class == superclass) - return YES; - class = (class->super_class ? - objc_lookup_class ((char*)class->super_class) - : Nil); - } - - return NO; -} - -/* This list contains all the classes in the runtime system for whom their - superclasses are not yet know to the runtime. */ -static struct objc_list* unresolved_classes = 0; - -/* Static function used to reference the Object and NXConstantString classes. - */ -static void -__objc_force_linking (void) -{ - extern void __objc_linking (void); - __objc_linking (); - - /* Call the function to avoid compiler warning */ - __objc_force_linking (); -} - -/* Run through the statics list, removing modules as soon as all its statics - have been initialized. */ -static void -objc_init_statics (void) -{ - struct objc_list **cell = &uninitialized_statics; - struct objc_static_instances **statics_in_module; - - objc_mutex_lock(__objc_runtime_mutex); - - while (*cell) - { - int module_initialized = 1; - - for (statics_in_module = (*cell)->head; - *statics_in_module; statics_in_module++) - { - struct objc_static_instances *statics = *statics_in_module; - Class class = objc_lookup_class (statics->class_name); - - if (!class) - module_initialized = 0; - /* Actually, the static's class_pointer will be NULL when we - haven't been here before. However, the comparison is to be - reminded of taking into account class posing and to think about - possible semantics... */ - else if (class != statics->instances[0]->class_pointer) - { - id *inst; - - for (inst = &statics->instances[0]; *inst; inst++) - { - (*inst)->class_pointer = class; - - /* ??? Make sure the object will not be freed. With - refcounting, invoke `-retain'. Without refcounting, do - nothing and hope that `-free' will never be invoked. */ - - /* ??? Send the object an `-initStatic' or something to - that effect now or later on? What are the semantics of - statically allocated instances, besides the trivial - NXConstantString, anyway? */ - } - } - } - if (module_initialized) - { - /* Remove this module from the uninitialized list. */ - struct objc_list *this = *cell; - *cell = this->tail; - objc_free(this); - } - else - cell = &(*cell)->tail; - } - - objc_mutex_unlock(__objc_runtime_mutex); -} /* objc_init_statics */ - -/* This function is called by constructor functions generated for each - module compiled. (_GLOBAL_$I$...) The purpose of this function is to - gather the module pointers so that they may be processed by the - initialization routines as soon as possible */ - -void -__objc_exec_class (Module_t module) -{ - /* Have we processed any constructors previously? This flag is used to - indicate that some global data structures need to be built. */ - static BOOL previous_constructors = 0; - - static struct objc_list* unclaimed_categories = 0; - - /* The symbol table (defined in objc-api.h) generated by gcc */ - Symtab_t symtab = module->symtab; - - /* The statics in this module */ - struct objc_static_instances **statics - = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt]; - - /* Entry used to traverse hash lists */ - struct objc_list** cell; - - /* The table of selector references for this module */ - SEL selectors = symtab->refs; - - /* dummy counter */ - int i; - - DEBUG_PRINTF ("received module: %s\n", module->name); - - /* check gcc version */ - init_check_module_version(module); - - /* On the first call of this routine, initialize some data structures. */ - if (!previous_constructors) - { - /* Initialize thread-safe system */ - __objc_init_thread_system(); - __objc_runtime_threads_alive = 1; - __objc_runtime_mutex = objc_mutex_allocate(); - - __objc_init_selector_tables(); - __objc_init_class_tables(); - __objc_init_dispatch_tables(); - __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list); - __objc_load_methods - = hash_new (128, (hash_func_type)hash_ptr, compare_ptrs); - previous_constructors = 1; - } - - /* Save the module pointer for later processing. (not currently used) */ - objc_mutex_lock(__objc_runtime_mutex); - __objc_module_list = list_cons(module, __objc_module_list); - - /* Replace referenced selectors from names to SEL's. */ - if (selectors) - { - for (i = 0; selectors[i].sel_id; ++i) - { - const char *name, *type; - name = (char*)selectors[i].sel_id; - type = (char*)selectors[i].sel_types; - /* Constructors are constant static data so we can safely store - pointers to them in the runtime structures. is_const == YES */ - __sel_register_typed_name (name, type, - (struct objc_selector*)&(selectors[i]), - YES); - } - } - - /* Parse the classes in the load module and gather selector information. */ - DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name); - for (i = 0; i < symtab->cls_def_cnt; ++i) - { - Class class = (Class) symtab->defs[i]; - const char* superclass = (char*)class->super_class; - - /* Make sure we have what we think. */ - assert (CLS_ISCLASS(class)); - assert (CLS_ISMETA(class->class_pointer)); - DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name); - - /* Initialize the subclass list to be NULL. - In some cases it isn't and this crashes the program. */ - class->subclass_list = NULL; - - /* Store the class in the class table and assign class numbers. */ - __objc_add_class_to_hash (class); - - /* Register all of the selectors in the class and meta class. */ - __objc_register_selectors_from_class (class); - __objc_register_selectors_from_class ((Class) class->class_pointer); - - /* Install the fake dispatch tables */ - __objc_install_premature_dtable(class); - __objc_install_premature_dtable(class->class_pointer); - - /* Register the instance methods as class methods, this is - only done for root classes. */ - __objc_register_instance_methods_to_class(class); - - if (class->protocols) - __objc_init_protocols (class->protocols); - - /* Check to see if the superclass is known in this point. If it's not - add the class to the unresolved_classes list. */ - if (superclass && !objc_lookup_class (superclass)) - unresolved_classes = list_cons (class, unresolved_classes); - } - - /* Process category information from the module. */ - for (i = 0; i < symtab->cat_def_cnt; ++i) - { - Category_t category = symtab->defs[i + symtab->cls_def_cnt]; - Class class = objc_lookup_class (category->class_name); - - /* If the class for the category exists then append its methods. */ - if (class) - { - - DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n", - module->name, - class->name); - - /* Do instance methods. */ - if (category->instance_methods) - class_add_method_list (class, category->instance_methods); - - /* Do class methods. */ - if (category->class_methods) - class_add_method_list ((Class) class->class_pointer, - category->class_methods); - - if (category->protocols) - { - __objc_init_protocols (category->protocols); - __objc_class_add_protocols (class, category->protocols); - } - - /* Register the instance methods as class methods, this is - only done for root classes. */ - __objc_register_instance_methods_to_class(class); - } - else - { - /* The object to which the category methods belong can't be found. - Save the information. */ - unclaimed_categories = list_cons(category, unclaimed_categories); - } - } - - if (statics) - uninitialized_statics = list_cons (statics, uninitialized_statics); - if (uninitialized_statics) - objc_init_statics (); - - /* Scan the unclaimed category hash. Attempt to attach any unclaimed - categories to objects. */ - for (cell = &unclaimed_categories; - *cell; - ({ if (*cell) cell = &(*cell)->tail; })) - { - Category_t category = (*cell)->head; - Class class = objc_lookup_class (category->class_name); - - if (class) - { - DEBUG_PRINTF ("attaching stored categories to object: %s\n", - class->name); - - list_remove_head (cell); - - if (category->instance_methods) - class_add_method_list (class, category->instance_methods); - - if (category->class_methods) - class_add_method_list ((Class) class->class_pointer, - category->class_methods); - - if (category->protocols) - { - __objc_init_protocols (category->protocols); - __objc_class_add_protocols (class, category->protocols); - } - - /* Register the instance methods as class methods, this is - only done for root classes. */ - __objc_register_instance_methods_to_class(class); - } - } - - if (unclaimed_proto_list && objc_lookup_class ("Protocol")) - { - list_mapcar (unclaimed_proto_list,(void(*)(void*))__objc_init_protocols); - list_free (unclaimed_proto_list); - unclaimed_proto_list = 0; - } - - objc_send_load (); - - objc_mutex_unlock(__objc_runtime_mutex); -} - -static void objc_send_load (void) -{ - if (!__objc_module_list) - return; - - /* Try to find out if all the classes loaded so far also have their - superclasses known to the runtime. We suppose that the objects that are - allocated in the +load method are in general of a class declared in the - same module. */ - if (unresolved_classes) - { - Class class = unresolved_classes->head; - - while (objc_lookup_class ((char*)class->super_class)) - { - list_remove_head (&unresolved_classes); - if (unresolved_classes) - class = unresolved_classes->head; - else - break; - } - - /* - * If we still have classes for whom we don't have yet their super - * classes known to the runtime we don't send the +load messages. - */ - if (unresolved_classes) - return; - } - - /* Special check to allow creating and sending messages to constant strings - in +load methods. If these classes are not yet known, even if all the - other classes are known, delay sending of +load. */ - if (!objc_lookup_class ("NXConstantString") || - !objc_lookup_class ("Object")) - return; - - /* Iterate over all modules in the __objc_module_list and call on them the - __objc_create_classes_tree function. This function creates a tree of - classes that resembles the class hierarchy. */ - list_mapcar (__objc_module_list, (void(*)(void*))__objc_create_classes_tree); - - while (__objc_class_tree_list) - { -#ifdef DEBUG - objc_preorder_traverse (__objc_class_tree_list->head, - 0, __objc_tree_print); -#endif - objc_preorder_traverse (__objc_class_tree_list->head, - 0, __objc_send_load); - objc_postorder_traverse (__objc_class_tree_list->head, - 0, __objc_destroy_class_tree_node); - list_remove_head (&__objc_class_tree_list); - } - - list_mapcar (__objc_module_list, (void(*)(void*))__objc_call_callback); - list_free (__objc_module_list); - __objc_module_list = NULL; -} - -static void -__objc_create_classes_tree (Module_t module) -{ - /* The runtime mutex is locked in this point */ - - Symtab_t symtab = module->symtab; - int i; - - /* Iterate thru classes defined in this module and insert them in the classes - tree hierarchy. */ - for (i = 0; i < symtab->cls_def_cnt; i++) - { - Class class = (Class) symtab->defs[i]; - - objc_tree_insert_class (class); - } -} - -static void -__objc_call_callback (Module_t module) -{ - /* The runtime mutex is locked in this point */ - - Symtab_t symtab = module->symtab; - int i; - - /* Iterate thru classes defined in this module and call the callback for - each one. */ - for (i = 0; i < symtab->cls_def_cnt; i++) - { - Class class = (Class) symtab->defs[i]; - - /* Call the _objc_load_callback for this class. */ - if (_objc_load_callback) - _objc_load_callback(class, 0); - } - - /* Call the _objc_load_callback for categories. Don't register the instance - methods as class methods for categories to root classes since they were - already added in the class. */ - for (i = 0; i < symtab->cat_def_cnt; i++) - { - Category_t category = symtab->defs[i + symtab->cls_def_cnt]; - Class class = objc_lookup_class (category->class_name); - - if (_objc_load_callback) - _objc_load_callback(class, category); - } -} - -/* Sanity check the version of gcc used to compile `module'*/ -static void init_check_module_version(Module_t module) -{ - if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module))) - { - int code; - - if(module->version > OBJC_VERSION) - code = OBJC_ERR_OBJC_VERSION; - else if (module->version < OBJC_VERSION) - code = OBJC_ERR_GCC_VERSION; - else - code = OBJC_ERR_MODULE_SIZE; - - objc_error(nil, code, "Module %s version %d doesn't match runtime %d\n", - module->name, (int)module->version, OBJC_VERSION); - } -} - -static void -__objc_init_protocols (struct objc_protocol_list* protos) -{ - int i; - static Class proto_class = 0; - - if (! protos) - return; - - objc_mutex_lock(__objc_runtime_mutex); - - if (!proto_class) - proto_class = objc_lookup_class("Protocol"); - - if (!proto_class) - { - unclaimed_proto_list = list_cons (protos, unclaimed_proto_list); - objc_mutex_unlock(__objc_runtime_mutex); - return; - } - -#if 0 - assert (protos->next == 0); /* only single ones allowed */ -#endif - - for(i = 0; i < protos->count; i++) - { - struct objc_protocol* aProto = protos->list[i]; - if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION) - { - /* assign class pointer */ - aProto->class_pointer = proto_class; - - /* init super protocols */ - __objc_init_protocols (aProto->protocol_list); - } - else if (protos->list[i]->class_pointer != proto_class) - { - objc_error(nil, OBJC_ERR_PROTOCOL_VERSION, - "Version %d doesn't match runtime protocol version %d\n", - (int)((char*)protos->list[i]->class_pointer-(char*)0), - PROTOCOL_VERSION); - } - } - - objc_mutex_unlock(__objc_runtime_mutex); -} - -static void __objc_class_add_protocols (Class class, - struct objc_protocol_list* protos) -{ - /* Well... */ - if (! protos) - return; - - /* Add it... */ - protos->next = class->protocols; - class->protocols = protos; -} diff --git a/contrib/gcc/objc/lang-specs.h b/contrib/gcc/objc/lang-specs.h deleted file mode 100644 index 7b9b2fa79cd1..000000000000 --- a/contrib/gcc/objc/lang-specs.h +++ /dev/null @@ -1,96 +0,0 @@ -/* Definitions for specs for Objective-C. - Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This is the contribution to the `default_compilers' array in gcc.c for - objc. */ - - {".m", {"@objective-c"}}, - {"@objective-c", -#if USE_CPPLIB - {"%{E|M|MM:cpp0 -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\ - %{C:%{!E:%eGNU C does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -D__OBJC__ %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2}\ - %{ansi:-trigraphs -D__STRICT_ANSI__}\ - %{!undef:%{!ansi:%p} %P} %{trigraphs}\ - %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\ - %{ffast-math:-D__FAST_MATH__}\ - %{traditional} %{ftraditional:-traditional}\ - %{traditional-cpp:-traditional}\ - %{fleading-underscore} %{fno-leading-underscore}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ - %i %{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}}\n}", - "%{!M:%{!MM:%{!E:cc1obj %i %1 \ - %{nostdinc*} %{A*} %{I*} %{P} %I\ - %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -D__OBJC__ %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2}\ - %{!undef:%{!ansi:%p} %P} %{trigraphs}\ - %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\ - %{ffast-math:-D__FAST_MATH__}\ - %{!Q:-quiet} -dumpbase %b.m %{d*} %{m*} %{a*}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ - %{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \ - -lang-objc %{gen-decls} \ - %{aux-info*} %{Qn:-fno-ident}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"} -#else /* ! USE_CPPLIB */ - {"cpp0 -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\ - %{C:%{!E:%eGNU C does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -D__OBJC__ %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2}\ - %{ansi:-trigraphs -D__STRICT_ANSI__}\ - %{!undef:%{!ansi:%p} %P} %{trigraphs}\ - %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\ - %{ffast-math:-D__FAST_MATH__}\ - %{traditional} %{ftraditional:-traditional}\ - %{traditional-cpp:-traditional}\ - %{fleading-underscore} %{fno-leading-underscore}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ - %i %{!M:%{!MM:%{!E:%{!pipe:%g.mi}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", - "%{!M:%{!MM:%{!E:cc1obj %{!pipe:%g.mi} %1 \ - %{!Q:-quiet} -dumpbase %b.m %{d*} %{m*} %{a*}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ - %{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \ - -lang-objc %{gen-decls} \ - %{aux-info*} %{Qn:-fno-ident}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"} -#endif /* ! USE_CPPLIB */ - }, - {".mi", {"@objc-cpp-output"}}, - {"@objc-cpp-output", - {"%{!M:%{!MM:%{!E:cc1obj %i %1 \ - %{!Q:-quiet} -dumpbase %b.m %{d*} %{m*} %{a*}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ - %{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \ - -lang-objc %{gen-decls} \ - %{aux-info*} %{Qn:-fno-ident}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n", - "%{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"}}, diff --git a/contrib/gcc/objc/list.h b/contrib/gcc/objc/list.h deleted file mode 100644 index a59b116d9673..000000000000 --- a/contrib/gcc/objc/list.h +++ /dev/null @@ -1,150 +0,0 @@ -/* Generic single linked list to keep various information - Copyright (C) 1993, 1994 Free Software Foundation, Inc. - -Author: Kresten Krab Thorup - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#ifndef __GNU_OBJC_LIST_H -#define __GNU_OBJC_LIST_H -void * __objc_xrealloc (void *optr, size_t size); -void * __objc_xmalloc (size_t size); - -struct objc_list { - void *head; - struct objc_list *tail; -}; - -/* Return a cons cell produced from (head . tail) */ - -static inline struct objc_list* -list_cons(void* head, struct objc_list* tail) -{ - struct objc_list* cell; - - cell = (struct objc_list*)__objc_xmalloc(sizeof(struct objc_list)); - cell->head = head; - cell->tail = tail; - return cell; -} - -/* Return the length of a list, list_length(NULL) returns zero */ - -static inline int -list_length(struct objc_list* list) -{ - int i = 0; - while(list) - { - i += 1; - list = list->tail; - } - return i; -} - -/* Return the Nth element of LIST, where N count from zero. If N - larger than the list length, NULL is returned */ - -static inline void* -list_nth(int index, struct objc_list* list) -{ - while(index-- != 0) - { - if(list->tail) - list = list->tail; - else - return 0; - } - return list->head; -} - -/* Remove the element at the head by replacing it by its successor */ - -static inline void -list_remove_head(struct objc_list** list) -{ - if ((*list)->tail) - { - struct objc_list* tail = (*list)->tail; /* fetch next */ - *(*list) = *tail; /* copy next to list head */ - free(tail); /* free next */ - } - else /* only one element in list */ - { - free (*list); - (*list) = 0; - } -} - - -/* Remove the element with `car' set to ELEMENT */ - -static inline void -list_remove_elem(struct objc_list** list, void* elem) -{ - while (*list) { - if ((*list)->head == elem) - list_remove_head(list); - list = &((*list)->tail); - } -} - -/* Map FUNCTION over all elements in LIST */ - -static inline void -list_mapcar(struct objc_list* list, void(*function)(void*)) -{ - while(list) - { - (*function)(list->head); - list = list->tail; - } -} - -/* Return element that has ELEM as car */ - -static inline struct objc_list** -list_find(struct objc_list** list, void* elem) -{ - while(*list) - { - if ((*list)->head == elem) - return list; - list = &((*list)->tail); - } - return NULL; -} - -/* Free list (backwards recursive) */ - -static void -list_free(struct objc_list* list) -{ - if(list) - { - list_free(list->tail); - free(list); - } -} -#endif __GNU_OBJC_LIST_H diff --git a/contrib/gcc/objc/makefile.dos b/contrib/gcc/objc/makefile.dos deleted file mode 100644 index 3e1b1871e40e..000000000000 --- a/contrib/gcc/objc/makefile.dos +++ /dev/null @@ -1,56 +0,0 @@ -# GNU Objective C Runtime Makefile for compiling with djgpp -# Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc. -# -# This file is part of GNU CC. -# -# GNU CC is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2, or (at your option) any later version. -# -# GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# GNU CC; see the file COPYING. If not, write to the Free Software -# Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -# This Makefile is configured for GnuMAKE - -GCC_FOR_TARGET=gcc - -.SUFFIXES: .o .m - -OPTIMIZE = -O2 - -# Always search these dirs when compiling. -SUBDIR_INCLUDES = -I. -I.. -I../config - -.c.o: - $(GCC_FOR_TARGET) $(OPTIMIZE) \ - -c $(GCC_CFLAGS) $(SUBDIR_INCLUDES) $< - -.m.o: - $(GCC_FOR_TARGET) $(OPTIMIZE) -fgnu-runtime \ - -c $(GCC_CFLAGS) $(SUBDIR_INCLUDES) $< - -OBJC_O = hash.o sarray.o class.o sendmsg.o init.o archive.o \ - selector.o objects.o misc.o object.o protocol.o encoding.o thread.o - -libobjc.a: $(OBJC_O) - -rm -f libobjc.a - ar rc libobjc.a $(OBJC_O) - ranlib libobjc.a - -OBJC_H = hash.h objc-list.h sarray.h objc.h \ - objc-api.h \ - object.h protocol.h mutex.h \ - typedstream.h thread.h - -mostlyclean: - -rm -f *.o libobjc.a xforward fflags -clean: mostlyclean -distclean: mostlyclean -extraclean: mostlyclean diff --git a/contrib/gcc/objc/misc.c b/contrib/gcc/objc/misc.c deleted file mode 100644 index 01f9d3bbafa8..000000000000 --- a/contrib/gcc/objc/misc.c +++ /dev/null @@ -1,152 +0,0 @@ -/* GNU Objective C Runtime Miscellaneous - Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc. - Contributed by Kresten Krab Thorup - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#define __USE_FIXED_PROTOTYPES__ -#include <stdlib.h> -#include "runtime.h" - -/* -** Error handler function -** NULL so that default is to just print to stderr -*/ -static objc_error_handler _objc_error_handler = NULL; - -/* Trigger an objc error */ -void -objc_error(id object, int code, const char* fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - objc_verror(object, code, fmt, ap); - va_end(ap); -} - -/* Trigger an objc error */ -void -objc_verror(id object, int code, const char* fmt, va_list ap) -{ - BOOL result = NO; - - /* Call the error handler if its there - Otherwise print to stderr */ - if (_objc_error_handler) - result = (*_objc_error_handler)(object, code, fmt, ap); - else - vfprintf (stderr, fmt, ap); - - /* Continue if the error handler says its ok - Otherwise abort the program */ - if (result) - return; - else - abort(); -} - -/* Set the error handler */ -objc_error_handler -objc_set_error_handler(objc_error_handler func) -{ - objc_error_handler temp = _objc_error_handler; - _objc_error_handler = func; - return temp; -} - -/* -** Standard functions for memory allocation and disposal. -** Users should use these functions in their ObjC programs so -** that they work properly with garbage collectors as well as -** can take advantage of the exception/error handling available. -*/ - -void * -objc_malloc(size_t size) -{ - void* res = (void*) (*_objc_malloc)(size); - if(!res) - objc_error(nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n"); - return res; -} - -void * -objc_atomic_malloc(size_t size) -{ - void* res = (void*) (*_objc_atomic_malloc)(size); - if(!res) - objc_error(nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n"); - return res; -} - -void * -objc_valloc(size_t size) -{ - void* res = (void*) (*_objc_valloc)(size); - if(!res) - objc_error(nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n"); - return res; -} - -void * -objc_realloc(void *mem, size_t size) -{ - void* res = (void*) (*_objc_realloc)(mem, size); - if(!res) - objc_error(nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n"); - return res; -} - -void * -objc_calloc(size_t nelem, size_t size) -{ - void* res = (void*) (*_objc_calloc)(nelem, size); - if(!res) - objc_error(nil, OBJC_ERR_MEMORY, "Virtual memory exhausted\n"); - return res; -} - -void -objc_free(void *mem) -{ - (*_objc_free)(mem); -} - -/* -** Hook functions for memory allocation and disposal. -** This makes it easy to substitute garbage collection systems -** such as Boehm's GC by assigning these function pointers -** to the GC's allocation routines. By default these point -** to the ANSI standard malloc, realloc, free, etc. -** -** Users should call the normal objc routines above for -** memory allocation and disposal within their programs. -*/ -void *(*_objc_malloc)(size_t) = malloc; -void *(*_objc_atomic_malloc)(size_t) = malloc; -void *(*_objc_valloc)(size_t) = malloc; -void *(*_objc_realloc)(void *, size_t) = realloc; -void *(*_objc_calloc)(size_t, size_t) = calloc; -void (*_objc_free)(void *) = free; diff --git a/contrib/gcc/objc/objc-act.c b/contrib/gcc/objc/objc-act.c deleted file mode 100644 index a2842c8c52a5..000000000000 --- a/contrib/gcc/objc/objc-act.c +++ /dev/null @@ -1,8572 +0,0 @@ -/* Implement classes and message passing for Objective C. - Copyright (C) 1992, 93-95, 97, 1998 Free Software Foundation, Inc. - Contributed by Steve Naroff. - -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. */ - -/* Purpose: This module implements the Objective-C 4.0 language. - - compatibility issues (with the Stepstone translator): - - - does not recognize the following 3.3 constructs. - @requires, @classes, @messages, = (...) - - methods with variable arguments must conform to ANSI standard. - - tagged structure definitions that appear in BOTH the interface - and implementation are not allowed. - - public/private: all instance variables are public within the - context of the implementation...I consider this to be a bug in - the translator. - - statically allocated objects are not supported. the user will - receive an error if this service is requested. - - code generation `options': - - - OBJC_INT_SELECTORS */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "c-tree.h" -#include "c-lex.h" -#include "flags.h" -#include "objc-act.h" -#include "input.h" -#include "except.h" -#include "function.h" -#include "output.h" -#include "toplev.h" - -#if USE_CPPLIB -#include "cpplib.h" -extern cpp_reader parse_in; -extern cpp_options parse_options; -#endif - -/* This is the default way of generating a method name. */ -/* I am not sure it is really correct. - Perhaps there's a danger that it will make name conflicts - if method names contain underscores. -- rms. */ -#ifndef OBJC_GEN_METHOD_LABEL -#define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \ - do { \ - char *temp; \ - sprintf ((BUF), "_%s_%s_%s_%s", \ - ((IS_INST) ? "i" : "c"), \ - (CLASS_NAME), \ - ((CAT_NAME)? (CAT_NAME) : ""), \ - (SEL_NAME)); \ - for (temp = (BUF); *temp; temp++) \ - if (*temp == ':') *temp = '_'; \ - } while (0) -#endif - -/* These need specifying. */ -#ifndef OBJC_FORWARDING_STACK_OFFSET -#define OBJC_FORWARDING_STACK_OFFSET 0 -#endif - -#ifndef OBJC_FORWARDING_MIN_OFFSET -#define OBJC_FORWARDING_MIN_OFFSET 0 -#endif - -/* Define the special tree codes that we use. */ - -/* Table indexed by tree code giving a string containing a character - classifying the tree code. Possibilities are - t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, - -char objc_tree_code_type[] = { - 'x', -#include "objc-tree.def" -}; -#undef DEFTREECODE - -/* Table indexed by tree code giving number of expression - operands beyond the fixed part of the node structure. - Not used for types or decls. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, - -int objc_tree_code_length[] = { - 0, -#include "objc-tree.def" -}; -#undef DEFTREECODE - -/* Names of tree components. - Used for printing out the tree and error messages. */ -#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, - -char *objc_tree_code_name[] = { - "@@dummy", -#include "objc-tree.def" -}; -#undef DEFTREECODE - -/* Set up for use of obstacks. */ - -#include "obstack.h" - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -/* This obstack is used to accumulate the encoding of a data type. */ -static struct obstack util_obstack; -/* This points to the beginning of obstack contents, - so we can free the whole contents. */ -char *util_firstobj; - -/* List of classes with list of their static instances. */ -static tree objc_static_instances = NULL_TREE; - -/* The declaration of the array administrating the static instances. */ -static tree static_instances_decl = NULL_TREE; - -/* for encode_method_def */ -#include "rtl.h" -#include "c-parse.h" - -#define OBJC_VERSION (flag_next_runtime ? 5 : 8) -#define PROTOCOL_VERSION 2 - -#define OBJC_ENCODE_INLINE_DEFS 0 -#define OBJC_ENCODE_DONT_INLINE_DEFS 1 - -/*** Private Interface (procedures) ***/ - -/* Used by compile_file. */ - -static void init_objc PROTO((void)); -static void finish_objc PROTO((void)); - -/* Code generation. */ - -static void synth_module_prologue PROTO((void)); -static tree build_constructor PROTO((tree, tree)); -static char *build_module_descriptor PROTO((void)); -static tree init_module_descriptor PROTO((tree)); -static tree build_objc_method_call PROTO((int, tree, tree, - tree, tree, tree)); -static void generate_strings PROTO((void)); -static tree get_proto_encoding PROTO((tree)); -static void build_selector_translation_table PROTO((void)); -static tree build_ivar_chain PROTO((tree, int)); - -static tree objc_add_static_instance PROTO((tree, tree)); - -static tree build_ivar_template PROTO((void)); -static tree build_method_template PROTO((void)); -static tree build_private_template PROTO((tree)); -static void build_class_template PROTO((void)); -static void build_selector_template PROTO((void)); -static void build_category_template PROTO((void)); -static tree build_super_template PROTO((void)); -static tree build_category_initializer PROTO((tree, tree, tree, - tree, tree, tree)); -static tree build_protocol_initializer PROTO((tree, tree, tree, - tree, tree)); - -static void synth_forward_declarations PROTO((void)); -static void generate_ivar_lists PROTO((void)); -static void generate_dispatch_tables PROTO((void)); -static void generate_shared_structures PROTO((void)); -static tree generate_protocol_list PROTO((tree)); -static void generate_forward_declaration_to_string_table PROTO((void)); -static void build_protocol_reference PROTO((tree)); - -#if 0 -static tree init_selector PROTO((int)); -#endif -static tree build_keyword_selector PROTO((tree)); -static tree synth_id_with_class_suffix PROTO((char *, tree)); - -static void generate_static_references PROTO((void)); -static int check_methods_accessible PROTO((tree, tree, - int)); -static void encode_aggregate_within PROTO((tree, int, int, - int, int)); - -/* We handle printing method names ourselves for ObjC */ -extern char *(*decl_printable_name) (); - -/* Misc. bookkeeping */ - -typedef struct hashed_entry *hash; -typedef struct hashed_attribute *attr; - -struct hashed_attribute -{ - attr next; - tree value; -}; -struct hashed_entry -{ - attr list; - hash next; - tree key; -}; - -static void hash_init PROTO((void)); -static void hash_enter PROTO((hash *, tree)); -static hash hash_lookup PROTO((hash *, tree)); -static void hash_add_attr PROTO((hash, tree)); -static tree lookup_method PROTO((tree, tree)); -static tree lookup_instance_method_static PROTO((tree, tree)); -static tree lookup_class_method_static PROTO((tree, tree)); -static tree add_class PROTO((tree)); -static void add_category PROTO((tree, tree)); - -enum string_section -{ - class_names, /* class, category, protocol, module names */ - meth_var_names, /* method and variable names */ - meth_var_types /* method and variable type descriptors */ -}; - -static tree add_objc_string PROTO((tree, - enum string_section)); -static tree get_objc_string_decl PROTO((tree, - enum string_section)); -static tree build_objc_string_decl PROTO((tree, - enum string_section)); -static tree build_selector_reference_decl PROTO((tree)); - -/* Protocol additions. */ - -static tree add_protocol PROTO((tree)); -static tree lookup_protocol PROTO((tree)); -static tree lookup_and_install_protocols PROTO((tree)); - -/* Type encoding. */ - -static void encode_type_qualifiers PROTO((tree)); -static void encode_pointer PROTO((tree, int, int)); -static void encode_array PROTO((tree, int, int)); -static void encode_aggregate PROTO((tree, int, int)); -static void encode_bitfield PROTO((int, int)); -static void encode_type PROTO((tree, int, int)); -static void encode_field_decl PROTO((tree, int, int)); - -static void really_start_method PROTO((tree, tree)); -static int comp_method_with_proto PROTO((tree, tree)); -static int comp_proto_with_proto PROTO((tree, tree)); -static tree get_arg_type_list PROTO((tree, int, int)); -static tree expr_last PROTO((tree)); - -/* Utilities for debugging and error diagnostics. */ - -static void warn_with_method PROTO((char *, int, tree)); -static void error_with_ivar PROTO((char *, tree, tree)); -static char *gen_method_decl PROTO((tree, char *)); -static char *gen_declaration PROTO((tree, char *)); -static char *gen_declarator PROTO((tree, char *, char *)); -static int is_complex_decl PROTO((tree)); -static void adorn_decl PROTO((tree, char *)); -static void dump_interface PROTO((FILE *, tree)); - -/* Everything else. */ - -static void objc_fatal PROTO((void)) - ATTRIBUTE_NORETURN; -static tree define_decl PROTO((tree, tree)); -static tree lookup_method_in_protocol_list PROTO((tree, tree, int)); -static tree lookup_protocol_in_reflist PROTO((tree, tree)); -static tree create_builtin_decl PROTO((enum tree_code, - tree, char *)); -static tree my_build_string PROTO((int, char *)); -static void build_objc_symtab_template PROTO((void)); -static tree init_def_list PROTO((tree)); -static tree init_objc_symtab PROTO((tree)); -static void forward_declare_categories PROTO((void)); -static void generate_objc_symtab_decl PROTO((void)); -static tree build_selector PROTO((tree)); -#if 0 -static tree build_msg_pool_reference PROTO((int)); -#endif -static tree build_typed_selector_reference PROTO((tree, tree)); -static tree build_selector_reference PROTO((tree)); -static tree build_class_reference_decl PROTO((tree)); -static void add_class_reference PROTO((tree)); -static tree objc_copy_list PROTO((tree, tree *)); -static tree build_protocol_template PROTO((void)); -static tree build_descriptor_table_initializer PROTO((tree, tree)); -static tree build_method_prototype_list_template PROTO((tree, int)); -static tree build_method_prototype_template PROTO((void)); -static int forwarding_offset PROTO((tree)); -static tree encode_method_prototype PROTO((tree, tree)); -static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree)); -static void generate_method_descriptors PROTO((tree)); -static tree build_tmp_function_decl PROTO((void)); -static void hack_method_prototype PROTO((tree, tree)); -static void generate_protocol_references PROTO((tree)); -static void generate_protocols PROTO((void)); -static void check_ivars PROTO((tree, tree)); -static tree build_ivar_list_template PROTO((tree, int)); -static tree build_method_list_template PROTO((tree, int)); -static tree build_ivar_list_initializer PROTO((tree, tree)); -static tree generate_ivars_list PROTO((tree, char *, - int, tree)); -static tree build_dispatch_table_initializer PROTO((tree, tree)); -static tree generate_dispatch_table PROTO((tree, char *, - int, tree)); -static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, - tree, int, tree, tree, - tree)); -static void generate_category PROTO((tree)); -static int is_objc_type_qualifier PROTO((tree)); -static tree adjust_type_for_id_default PROTO((tree)); -static tree check_duplicates PROTO((hash)); -static tree receiver_is_class_object PROTO((tree)); -static int check_methods PROTO((tree, tree, int)); -static int conforms_to_protocol PROTO((tree, tree)); -static void check_protocols PROTO((tree, char *, char *)); -static tree encode_method_def PROTO((tree)); -static void gen_declspecs PROTO((tree, char *, int)); -static void generate_classref_translation_entry PROTO((tree)); -static void handle_class_ref PROTO((tree)); - -/*** Private Interface (data) ***/ - -/* Reserved tag definitions. */ - -#define TYPE_ID "id" -#define TAG_OBJECT "objc_object" -#define TAG_CLASS "objc_class" -#define TAG_SUPER "objc_super" -#define TAG_SELECTOR "objc_selector" - -#define UTAG_CLASS "_objc_class" -#define UTAG_IVAR "_objc_ivar" -#define UTAG_IVAR_LIST "_objc_ivar_list" -#define UTAG_METHOD "_objc_method" -#define UTAG_METHOD_LIST "_objc_method_list" -#define UTAG_CATEGORY "_objc_category" -#define UTAG_MODULE "_objc_module" -#define UTAG_STATICS "_objc_statics" -#define UTAG_SYMTAB "_objc_symtab" -#define UTAG_SUPER "_objc_super" -#define UTAG_SELECTOR "_objc_selector" - -#define UTAG_PROTOCOL "_objc_protocol" -#define UTAG_PROTOCOL_LIST "_objc_protocol_list" -#define UTAG_METHOD_PROTOTYPE "_objc_method_prototype" -#define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list" - -#define STRING_OBJECT_CLASS_NAME "NXConstantString" -#define PROTOCOL_OBJECT_CLASS_NAME "Protocol" - -static char *TAG_GETCLASS; -static char *TAG_GETMETACLASS; -static char *TAG_MSGSEND; -static char *TAG_MSGSENDSUPER; -static char *TAG_EXECCLASS; - -/* Set by `continue_class' and checked by `is_public'. */ - -#define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type)) -#define TYPED_OBJECT(type) \ - (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type)) - -/* Some commonly used instances of "identifier_node". */ - -static tree self_id, ucmd_id; -static tree unused_list; - -static tree self_decl, umsg_decl, umsg_super_decl; -static tree objc_get_class_decl, objc_get_meta_class_decl; - -static tree super_type, selector_type, id_type, objc_class_type; -static tree instance_type, protocol_type; - -/* Type checking macros. */ - -#define IS_ID(TYPE) \ - (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type)) -#define IS_PROTOCOL_QUALIFIED_ID(TYPE) \ - (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE)) -#define IS_SUPER(TYPE) \ - (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type)) - -static tree class_chain = NULL_TREE; -static tree alias_chain = NULL_TREE; -static tree interface_chain = NULL_TREE; -static tree protocol_chain = NULL_TREE; - -/* Chains to manage selectors that are referenced and defined in the - module. */ - -static tree cls_ref_chain = NULL_TREE; /* Classes referenced. */ -static tree sel_ref_chain = NULL_TREE; /* Selectors referenced. */ - -/* Chains to manage uniquing of strings. */ - -static tree class_names_chain = NULL_TREE; -static tree meth_var_names_chain = NULL_TREE; -static tree meth_var_types_chain = NULL_TREE; - -/* Hash tables to manage the global pool of method prototypes. */ - -static hash *nst_method_hash_list = 0; -static hash *cls_method_hash_list = 0; - -/* Backend data declarations. */ - -static tree UOBJC_SYMBOLS_decl; -static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl; -static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl; -static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl; -static tree UOBJC_SELECTOR_TABLE_decl; -static tree UOBJC_MODULES_decl; -static tree UOBJC_STRINGS_decl; - -/* The following are used when compiling a class implementation. - implementation_template will normally be an interface, however if - none exists this will be equal to implementation_context...it is - set in start_class. */ - -static tree implementation_context = NULL_TREE; -static tree implementation_template = NULL_TREE; - -struct imp_entry -{ - struct imp_entry *next; - tree imp_context; - tree imp_template; - tree class_decl; /* _OBJC_CLASS_<my_name>; */ - tree meta_decl; /* _OBJC_METACLASS_<my_name>; */ -}; - -static void handle_impent PROTO((struct imp_entry *)); - -static struct imp_entry *imp_list = 0; -static int imp_count = 0; /* `@implementation' */ -static int cat_count = 0; /* `@category' */ - -static tree objc_class_template, objc_category_template, uprivate_record; -static tree objc_protocol_template, objc_selector_template; -static tree ucls_super_ref, uucls_super_ref; - -static tree objc_method_template, objc_ivar_template; -static tree objc_symtab_template, objc_module_template; -static tree objc_super_template, objc_object_reference; - -static tree objc_object_id, objc_class_id, objc_id_id; -static tree constant_string_id; -static tree constant_string_type; -static tree UOBJC_SUPER_decl; - -static tree method_context = NULL_TREE; -static int method_slot = 0; /* Used by start_method_def, */ - -#define BUFSIZE 1024 - -static char *errbuf; /* Buffer for error diagnostics */ - -/* Data imported from tree.c. */ - -extern enum debug_info_type write_symbols; - -/* Data imported from toplev.c. */ - -extern char *dump_base_name; - -/* Generate code for GNU or NeXT runtime environment. */ - -#ifdef NEXT_OBJC_RUNTIME -int flag_next_runtime = 1; -#else -int flag_next_runtime = 0; -#endif - -int flag_typed_selectors; - -/* Open and close the file for outputting class declarations, if requested. */ - -int flag_gen_declaration = 0; - -FILE *gen_declaration_file; - -/* Warn if multiple methods are seen for the same selector, but with - different argument types. */ - -int warn_selector = 0; - -/* Warn if methods required by a protocol are not implemented in the - class adopting it. When turned off, methods inherited to that - class are also considered implemented */ - -int flag_warn_protocol = 1; - -/* Tells "encode_pointer/encode_aggregate" whether we are generating - type descriptors for instance variables (as opposed to methods). - Type descriptors for instance variables contain more information - than methods (for static typing and embedded structures). This - was added to support features being planned for dbkit2. */ - -static int generating_instance_variables = 0; - -/* Tells the compiler that this is a special run. Do not perform - any compiling, instead we are to test some platform dependent - features and output a C header file with appropriate definitions. */ - -static int print_struct_values = 0; - -/* Some platforms pass small structures through registers versus through - an invisible pointer. Determine at what size structure is the - transition point between the two possibilities. */ - -void -generate_struct_by_value_array () -{ - tree type; - tree field_decl, field_decl_chain; - int i, j; - int aggregate_in_mem[32]; - int found = 0; - - /* Presumbaly no platform passes 32 byte structures in a register. */ - for (i = 1; i < 32; i++) - { - char buffer[5]; - - /* Create an unnamed struct that has `i' character components */ - type = start_struct (RECORD_TYPE, NULL_TREE); - - strcpy (buffer, "c1"); - field_decl = create_builtin_decl (FIELD_DECL, - char_type_node, - buffer); - field_decl_chain = field_decl; - - for (j = 1; j < i; j++) - { - sprintf (buffer, "c%d", j + 1); - field_decl = create_builtin_decl (FIELD_DECL, - char_type_node, - buffer); - chainon (field_decl_chain, field_decl); - } - finish_struct (type, field_decl_chain, NULL_TREE); - - aggregate_in_mem[i] = aggregate_value_p (type); - if (!aggregate_in_mem[i]) - found = 1; - } - - /* We found some structures that are returned in registers instead of memory - so output the necessary data. */ - if (found) - { - for (i = 31; i >= 0; i--) - if (!aggregate_in_mem[i]) - break; - printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i); - - /* The first member of the structure is always 0 because we don't handle - structures with 0 members */ - printf ("static int struct_forward_array[] = {\n 0"); - - for (j = 1; j <= i; j++) - printf (", %d", aggregate_in_mem[j]); - printf ("\n};\n"); - } - - exit (0); -} - -#if USE_CPPLIB -extern char *yy_cur; -#endif - -void -lang_init_options () -{ -#if USE_CPPLIB - cpp_reader_init (&parse_in); - parse_in.opts = &parse_options; - cpp_options_init (&parse_options); -#endif -} - -void -lang_init () -{ -#if !USE_CPPLIB - /* The beginning of the file is a new line; check for #. - With luck, we discover the real source file's name from that - and put it in input_filename. */ - ungetc (check_newline (), finput); -#else - check_newline (); - yy_cur--; -#endif - - /* The line number can be -1 if we had -g3 and the input file - had a directive specifying line 0. But we want predefined - functions to have a line number of 0, not -1. */ - if (lineno == -1) - lineno = 0; - - /* If gen_declaration desired, open the output file. */ - if (flag_gen_declaration) - { - int dump_base_name_length = strlen (dump_base_name); - register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); - strcpy (dumpname, dump_base_name); - strcat (dumpname, ".decl"); - gen_declaration_file = fopen (dumpname, "w"); - if (gen_declaration_file == 0) - pfatal_with_name (dumpname); - } - - if (flag_next_runtime) - { - TAG_GETCLASS = "objc_getClass"; - TAG_GETMETACLASS = "objc_getMetaClass"; - TAG_MSGSEND = "objc_msgSend"; - TAG_MSGSENDSUPER = "objc_msgSendSuper"; - TAG_EXECCLASS = "__objc_execClass"; - } - else - { - TAG_GETCLASS = "objc_get_class"; - TAG_GETMETACLASS = "objc_get_meta_class"; - TAG_MSGSEND = "objc_msg_lookup"; - TAG_MSGSENDSUPER = "objc_msg_lookup_super"; - TAG_EXECCLASS = "__objc_exec_class"; - flag_typed_selectors = 1; - } - - if (doing_objc_thang) - init_objc (); - - if (print_struct_values) - generate_struct_by_value_array (); -} - -static void -objc_fatal () -{ - fatal ("Objective-C text in C source file"); -} - -void -finish_file () -{ - if (doing_objc_thang) - finish_objc (); /* Objective-C finalization */ - - if (gen_declaration_file) - fclose (gen_declaration_file); -} - -void -lang_finish () -{ -} - -char * -lang_identify () -{ - return "objc"; -} - -int -lang_decode_option (argc, argv) - int argc; - char **argv; -{ - char *p = argv[0]; - if (!strcmp (p, "-lang-objc")) - doing_objc_thang = 1; - else if (!strcmp (p, "-gen-decls")) - flag_gen_declaration = 1; - else if (!strcmp (p, "-Wselector")) - warn_selector = 1; - else if (!strcmp (p, "-Wno-selector")) - warn_selector = 0; - else if (!strcmp (p, "-Wprotocol")) - flag_warn_protocol = 1; - else if (!strcmp (p, "-Wno-protocol")) - flag_warn_protocol = 0; - else if (!strcmp (p, "-fgnu-runtime")) - flag_next_runtime = 0; - else if (!strcmp (p, "-fno-next-runtime")) - flag_next_runtime = 0; - else if (!strcmp (p, "-fno-gnu-runtime")) - flag_next_runtime = 1; - else if (!strcmp (p, "-fnext-runtime")) - flag_next_runtime = 1; - else if (!strcmp (p, "-print-objc-runtime-info")) - print_struct_values = 1; - else - return c_decode_option (argc, argv); - - return 1; -} - -/* used by print-tree.c */ - -void -lang_print_xnode (file, node, indent) - FILE *file ATTRIBUTE_UNUSED; - tree node ATTRIBUTE_UNUSED; - int indent ATTRIBUTE_UNUSED; -{ -} - - -static tree -define_decl (declarator, declspecs) - tree declarator; - tree declspecs; -{ - tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE); - finish_decl (decl, NULL_TREE, NULL_TREE); - return decl; -} - -/* Return 1 if LHS and RHS are compatible types for assignment or - various other operations. Return 0 if they are incompatible, and - return -1 if we choose to not decide. When the operation is - REFLEXIVE, check for compatibility in either direction. - - For statically typed objects, an assignment of the form `a' = `b' - is permitted if: - - `a' is of type "id", - `a' and `b' are the same class type, or - `a' and `b' are of class types A and B such that B is a descendant of A. */ - -int -maybe_objc_comptypes (lhs, rhs, reflexive) - tree lhs, rhs; - int reflexive; -{ - if (doing_objc_thang) - return objc_comptypes (lhs, rhs, reflexive); - return -1; -} - -static tree -lookup_method_in_protocol_list (rproto_list, sel_name, class_meth) - tree rproto_list; - tree sel_name; - int class_meth; -{ - tree rproto, p; - tree fnd = 0; - - for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto)) - { - p = TREE_VALUE (rproto); - - if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) - { - if ((fnd = lookup_method (class_meth - ? PROTOCOL_CLS_METHODS (p) - : PROTOCOL_NST_METHODS (p), sel_name))) - ; - else if (PROTOCOL_LIST (p)) - fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p), - sel_name, class_meth); - } - else - { - ; /* An identifier...if we could not find a protocol. */ - } - - if (fnd) - return fnd; - } - - return 0; -} - -static tree -lookup_protocol_in_reflist (rproto_list, lproto) - tree rproto_list; - tree lproto; -{ - tree rproto, p; - - /* Make sure the protocol is support by the object on the rhs. */ - if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE) - { - tree fnd = 0; - for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto)) - { - p = TREE_VALUE (rproto); - - if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) - { - if (lproto == p) - fnd = lproto; - - else if (PROTOCOL_LIST (p)) - fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto); - } - - if (fnd) - return fnd; - } - } - else - { - ; /* An identifier...if we could not find a protocol. */ - } - - return 0; -} - -/* Return 1 if LHS and RHS are compatible types for assignment - or various other operations. Return 0 if they are incompatible, - and return -1 if we choose to not decide. When the operation - is REFLEXIVE, check for compatibility in either direction. */ - -int -objc_comptypes (lhs, rhs, reflexive) - tree lhs; - tree rhs; - int reflexive; -{ - /* New clause for protocols. */ - - if (TREE_CODE (lhs) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE - && TREE_CODE (rhs) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE) - { - int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs); - int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs); - - if (lhs_is_proto) - { - tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs); - tree rproto, rproto_list; - tree p; - - if (rhs_is_proto) - { - rproto_list = TYPE_PROTOCOL_LIST (rhs); - - /* Make sure the protocol is supported by the object - on the rhs. */ - for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto)) - { - p = TREE_VALUE (lproto); - rproto = lookup_protocol_in_reflist (rproto_list, p); - - if (!rproto) - warning ("object does not conform to the `%s' protocol", - IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - } - } - else if (TYPED_OBJECT (TREE_TYPE (rhs))) - { - tree rname = TYPE_NAME (TREE_TYPE (rhs)); - tree rinter; - - /* Make sure the protocol is supported by the object - on the rhs. */ - for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto)) - { - p = TREE_VALUE (lproto); - rproto = 0; - rinter = lookup_interface (rname); - - while (rinter && !rproto) - { - tree cat; - - rproto_list = CLASS_PROTOCOL_LIST (rinter); - rproto = lookup_protocol_in_reflist (rproto_list, p); - - /* Check for protocols adopted by categories. */ - cat = CLASS_CATEGORY_LIST (rinter); - while (cat && !rproto) - { - rproto_list = CLASS_PROTOCOL_LIST (cat); - rproto = lookup_protocol_in_reflist (rproto_list, p); - - cat = CLASS_CATEGORY_LIST (cat); - } - - rinter = lookup_interface (CLASS_SUPER_NAME (rinter)); - } - - if (!rproto) - warning ("class `%s' does not implement the `%s' protocol", - IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))), - IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - } - } - - /* May change...based on whether there was any mismatch */ - return 1; - } - else if (rhs_is_proto) - /* Lhs is not a protocol...warn if it is statically typed */ - return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0); - - else - /* Defer to comptypes .*/ - return -1; - } - - else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE) - ; /* Fall thru. This is the case we have been handling all along */ - else - /* Defer to comptypes. */ - return -1; - - /* `id' = `<class> *', `<class> *' = `id' */ - - if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs)) - || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs))) - return 1; - - /* `id' = `Class', `Class' = `id' */ - - else if ((TYPE_NAME (lhs) == objc_object_id - && TYPE_NAME (rhs) == objc_class_id) - || (TYPE_NAME (lhs) == objc_class_id - && TYPE_NAME (rhs) == objc_object_id)) - return 1; - - /* `<class> *' = `<class> *' */ - - else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs)) - { - tree lname = TYPE_NAME (lhs); - tree rname = TYPE_NAME (rhs); - tree inter; - - if (lname == rname) - return 1; - - /* If the left hand side is a super class of the right hand side, - allow it. */ - for (inter = lookup_interface (rname); inter; - inter = lookup_interface (CLASS_SUPER_NAME (inter))) - if (lname == CLASS_SUPER_NAME (inter)) - return 1; - - /* Allow the reverse when reflexive. */ - if (reflexive) - for (inter = lookup_interface (lname); inter; - inter = lookup_interface (CLASS_SUPER_NAME (inter))) - if (rname == CLASS_SUPER_NAME (inter)) - return 1; - - return 0; - } - else - /* Defer to comptypes. */ - return -1; -} - -/* Called from c-decl.c before all calls to rest_of_decl_compilation. */ - -void -objc_check_decl (decl) - tree decl; -{ - tree type = TREE_TYPE (decl); - - if (TREE_CODE (type) == RECORD_TYPE - && TREE_STATIC_TEMPLATE (type) - && type != constant_string_type) - { - error_with_decl (decl, "`%s' cannot be statically allocated"); - fatal ("statically allocated objects not supported"); - } -} - -void -maybe_objc_check_decl (decl) - tree decl; -{ - if (doing_objc_thang) - objc_check_decl (decl); -} - -/* Implement static typing. At this point, we know we have an interface. */ - -tree -get_static_reference (interface, protocols) - tree interface; - tree protocols; -{ - tree type = xref_tag (RECORD_TYPE, interface); - - if (protocols) - { - tree t, m = TYPE_MAIN_VARIANT (type); - - push_obstacks_nochange (); - end_temporary_allocation (); - t = copy_node (type); - TYPE_BINFO (t) = make_tree_vec (2); - pop_obstacks (); - - /* Add this type to the chain of variants of TYPE. */ - TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); - TYPE_NEXT_VARIANT (m) = t; - - /* Look up protocols and install in lang specific list. */ - TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols); - - /* This forces a new pointer type to be created later - (in build_pointer_type)...so that the new template - we just created will actually be used...what a hack! */ - if (TYPE_POINTER_TO (t)) - TYPE_POINTER_TO (t) = 0; - - type = t; - } - - return type; -} - -tree -get_object_reference (protocols) - tree protocols; -{ - tree type_decl = lookup_name (objc_id_id); - tree type; - - if (type_decl && TREE_CODE (type_decl) == TYPE_DECL) - { - type = TREE_TYPE (type_decl); - if (TYPE_MAIN_VARIANT (type) != id_type) - warning ("Unexpected type for `id' (%s)", - gen_declaration (type, errbuf)); - } - else - fatal ("Undefined type `id', please import <objc/objc.h>"); - - /* This clause creates a new pointer type that is qualified with - the protocol specification...this info is used later to do more - elaborate type checking. */ - - if (protocols) - { - tree t, m = TYPE_MAIN_VARIANT (type); - - push_obstacks_nochange (); - end_temporary_allocation (); - t = copy_node (type); - TYPE_BINFO (t) = make_tree_vec (2); - pop_obstacks (); - - /* Add this type to the chain of variants of TYPE. */ - TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); - TYPE_NEXT_VARIANT (m) = t; - - /* Look up protocols...and install in lang specific list */ - TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols); - - /* This forces a new pointer type to be created later - (in build_pointer_type)...so that the new template - we just created will actually be used...what a hack! */ - if (TYPE_POINTER_TO (t)) - TYPE_POINTER_TO (t) = NULL; - - type = t; - } - return type; -} - -static tree -lookup_and_install_protocols (protocols) - tree protocols; -{ - tree proto; - tree prev = NULL; - tree return_value = protocols; - - for (proto = protocols; proto; proto = TREE_CHAIN (proto)) - { - tree ident = TREE_VALUE (proto); - tree p = lookup_protocol (ident); - - if (!p) - { - error ("Cannot find protocol declaration for `%s'", - IDENTIFIER_POINTER (ident)); - if (prev) - TREE_CHAIN (prev) = TREE_CHAIN (proto); - else - return_value = TREE_CHAIN (proto); - } - else - { - /* Replace identifier with actual protocol node. */ - TREE_VALUE (proto) = p; - prev = proto; - } - } - - return return_value; -} - -/* Create and push a decl for a built-in external variable or field NAME. - CODE says which. - TYPE is its data type. */ - -static tree -create_builtin_decl (code, type, name) - enum tree_code code; - tree type; - char *name; -{ - tree decl = build_decl (code, get_identifier (name), type); - - if (code == VAR_DECL) - { - TREE_STATIC (decl) = 1; - make_decl_rtl (decl, 0, 1); - pushdecl (decl); - } - - DECL_ARTIFICIAL (decl) = 1; - return decl; -} - -/* Purpose: "play" parser, creating/installing representations - of the declarations that are required by Objective-C. - - Model: - - type_spec--------->sc_spec - (tree_list) (tree_list) - | | - | | - identifier_node identifier_node */ - -static void -synth_module_prologue () -{ - tree temp_type; - tree super_p; - - /* Defined in `objc.h' */ - objc_object_id = get_identifier (TAG_OBJECT); - - objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id); - - id_type = build_pointer_type (objc_object_reference); - - objc_id_id = get_identifier (TYPE_ID); - objc_class_id = get_identifier (TAG_CLASS); - - objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id)); - protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (PROTOCOL_OBJECT_CLASS_NAME))); - - /* Declare type of selector-objects that represent an operation name. */ - -#ifdef OBJC_INT_SELECTORS - /* `unsigned int' */ - selector_type = unsigned_type_node; -#else - /* `struct objc_selector *' */ - selector_type - = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); -#endif /* not OBJC_INT_SELECTORS */ - - /* Forward declare type, or else the prototype for msgSendSuper will - complain. */ - - super_p = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (TAG_SUPER))); - - - /* id objc_msgSend (id, SEL, ...); */ - - temp_type - = build_function_type (id_type, - tree_cons (NULL_TREE, id_type, - tree_cons (NULL_TREE, selector_type, - NULL_TREE))); - - if (! flag_next_runtime) - { - umsg_decl = build_decl (FUNCTION_DECL, - get_identifier (TAG_MSGSEND), temp_type); - DECL_EXTERNAL (umsg_decl) = 1; - TREE_PUBLIC (umsg_decl) = 1; - DECL_INLINE (umsg_decl) = 1; - DECL_ARTIFICIAL (umsg_decl) = 1; - - if (flag_traditional && TAG_MSGSEND[0] != '_') - DECL_BUILT_IN_NONANSI (umsg_decl) = 1; - - make_decl_rtl (umsg_decl, NULL_PTR, 1); - pushdecl (umsg_decl); - } - else - umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0); - - /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */ - - temp_type - = build_function_type (id_type, - tree_cons (NULL_TREE, super_p, - tree_cons (NULL_TREE, selector_type, - NULL_TREE))); - - umsg_super_decl = builtin_function (TAG_MSGSENDSUPER, - temp_type, NOT_BUILT_IN, 0); - - /* id objc_getClass (const char *); */ - - temp_type = build_function_type (id_type, - tree_cons (NULL_TREE, - const_string_type_node, - tree_cons (NULL_TREE, void_type_node, - NULL_TREE))); - - objc_get_class_decl - = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0); - - /* id objc_getMetaClass (const char *); */ - - objc_get_meta_class_decl - = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0); - - /* static SEL _OBJC_SELECTOR_TABLE[]; */ - - if (! flag_next_runtime) - { - if (flag_typed_selectors) - { - /* Suppress outputting debug symbols, because - dbxout_init hasn'r been called yet. */ - enum debug_info_type save_write_symbols = write_symbols; - write_symbols = NO_DEBUG; - - build_selector_template (); - temp_type = build_array_type (objc_selector_template, NULL_TREE); - - write_symbols = save_write_symbols; - } - else - temp_type = build_array_type (selector_type, NULL_TREE); - - layout_type (temp_type); - UOBJC_SELECTOR_TABLE_decl - = create_builtin_decl (VAR_DECL, temp_type, - "_OBJC_SELECTOR_TABLE"); - - /* Avoid warning when not sending messages. */ - TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1; - } - - generate_forward_declaration_to_string_table (); - - /* Forward declare constant_string_id and constant_string_type. */ - constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME); - constant_string_type = xref_tag (RECORD_TYPE, constant_string_id); -} - -/* Custom build_string which sets TREE_TYPE! */ - -static tree -my_build_string (len, str) - int len; - char *str; -{ - int wide_flag = 0; - tree a_string = build_string (len, str); - - /* Some code from combine_strings, which is local to c-parse.y. */ - if (TREE_TYPE (a_string) == int_array_type_node) - wide_flag = 1; - - TREE_TYPE (a_string) - = build_array_type (wide_flag ? integer_type_node : char_type_node, - build_index_type (build_int_2 (len - 1, 0))); - - TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */ - TREE_STATIC (a_string) = 1; - - return a_string; -} - -/* Return a newly constructed OBJC_STRING_CST node whose value is - the LEN characters at STR. - The TREE_TYPE is not initialized. */ - -tree -build_objc_string (len, str) - int len; - const char *str; -{ - tree s = build_string (len, str); - - TREE_SET_CODE (s, OBJC_STRING_CST); - return s; -} - -/* Given a chain of OBJC_STRING_CST's, build a static instance of - NXConstanString which points at the concatenation of those strings. - We place the string object in the __string_objects section of the - __OBJC segment. The Objective-C runtime will initialize the isa - pointers of the string objects to point at the NXConstandString class - object. */ - -tree -build_objc_string_object (strings) - tree strings; -{ - tree string, initlist, constructor; - int length; - - if (!doing_objc_thang) - objc_fatal (); - - if (lookup_interface (constant_string_id) == NULL_TREE) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (constant_string_id)); - return error_mark_node; - } - - add_class_reference (constant_string_id); - - /* Combine_strings will work for OBJC_STRING_CST's too. */ - string = combine_strings (strings); - TREE_SET_CODE (string, STRING_CST); - length = TREE_STRING_LENGTH (string) - 1; - - if (! flag_next_runtime) - { - push_obstacks_nochange (); - end_temporary_allocation (); - if (! TREE_PERMANENT (strings)) - string = my_build_string (length + 1, - TREE_STRING_POINTER (string)); - } - - /* & ((NXConstantString) {0, string, length}) */ - - initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0)); - initlist - = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)), - initlist); - initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist); - constructor = build_constructor (constant_string_type, nreverse (initlist)); - - if (!flag_next_runtime) - { - constructor - = objc_add_static_instance (constructor, constant_string_type); - pop_obstacks (); - } - - return (build_unary_op (ADDR_EXPR, constructor, 1)); -} - -/* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */ - -static tree -objc_add_static_instance (constructor, class_decl) - tree constructor, class_decl; -{ - static int num_static_inst; - tree *chain, decl; - char buf[256]; - - push_obstacks_nochange (); - end_temporary_allocation (); - - /* Find the list of static instances for the CLASS_DECL. Create one if - not found. */ - for (chain = &objc_static_instances; - *chain && TREE_VALUE (*chain) != class_decl; - chain = &TREE_CHAIN (*chain)); - if (!*chain) - { - *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE); - add_objc_string (TYPE_NAME (class_decl), class_names); - } - - sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++); - decl = build_decl (VAR_DECL, get_identifier (buf), class_decl); - DECL_COMMON (decl) = 1; - TREE_STATIC (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; - pushdecl_top_level (decl); - rest_of_decl_compilation (decl, 0, 1, 0); - - /* Do this here so it gets output later instead of possibly - inside something else we are writing. */ - DECL_INITIAL (decl) = constructor; - - /* Add the DECL to the head of this CLASS' list. */ - TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain)); - - pop_obstacks (); - return decl; -} - -/* Build a static constant CONSTRUCTOR - with type TYPE and elements ELTS. */ - -static tree -build_constructor (type, elts) - tree type, elts; -{ - tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts); - - TREE_CONSTANT (constructor) = 1; - TREE_STATIC (constructor) = 1; - TREE_READONLY (constructor) = 1; - - return constructor; -} - -/* Take care of defining and initializing _OBJC_SYMBOLS. */ - -/* Predefine the following data type: - - struct _objc_symtab - { - long sel_ref_cnt; - SEL *refs; - short cls_def_cnt; - short cat_def_cnt; - void *defs[cls_def_cnt + cat_def_cnt]; - }; */ - -static void -build_objc_symtab_template () -{ - tree field_decl, field_decl_chain, index; - - objc_symtab_template - = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB)); - - /* long sel_ref_cnt; */ - - field_decl = create_builtin_decl (FIELD_DECL, - long_integer_type_node, - "sel_ref_cnt"); - field_decl_chain = field_decl; - - /* SEL *refs; */ - - field_decl = create_builtin_decl (FIELD_DECL, - build_pointer_type (selector_type), - "refs"); - chainon (field_decl_chain, field_decl); - - /* short cls_def_cnt; */ - - field_decl = create_builtin_decl (FIELD_DECL, - short_integer_type_node, - "cls_def_cnt"); - chainon (field_decl_chain, field_decl); - - /* short cat_def_cnt; */ - - field_decl = create_builtin_decl (FIELD_DECL, - short_integer_type_node, - "cat_def_cnt"); - chainon (field_decl_chain, field_decl); - - /* void *defs[cls_def_cnt + cat_def_cnt]; */ - - if (!flag_next_runtime) - index = build_index_type (build_int_2 (imp_count + cat_count, 0)); - else - index = build_index_type (build_int_2 (imp_count + cat_count - 1, - imp_count == 0 && cat_count == 0 - ? -1 : 0)); - field_decl = create_builtin_decl (FIELD_DECL, - build_array_type (ptr_type_node, index), - "defs"); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE); -} - -/* Create the initial value for the `defs' field of _objc_symtab. - This is a CONSTRUCTOR. */ - -static tree -init_def_list (type) - tree type; -{ - tree expr, initlist = NULL_TREE; - struct imp_entry *impent; - - if (imp_count) - for (impent = imp_list; impent; impent = impent->next) - { - if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) - { - expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - } - - if (cat_count) - for (impent = imp_list; impent; impent = impent->next) - { - if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) - { - expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - } - - if (!flag_next_runtime) - { - /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */ - tree expr; - - if (static_instances_decl) - expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0); - else - expr = build_int_2 (0, 0); - - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - return build_constructor (type, nreverse (initlist)); -} - -/* Construct the initial value for all of _objc_symtab. */ - -static tree -init_objc_symtab (type) - tree type; -{ - tree initlist; - - /* sel_ref_cnt = { ..., 5, ... } */ - - initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0)); - - /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */ - - if (flag_next_runtime || ! sel_ref_chain) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - initlist = tree_cons (NULL_TREE, - build_unary_op (ADDR_EXPR, - UOBJC_SELECTOR_TABLE_decl, 1), - initlist); - - /* cls_def_cnt = { ..., 5, ... } */ - - initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist); - - /* cat_def_cnt = { ..., 5, ... } */ - - initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist); - - /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */ - - if (imp_count || cat_count || static_instances_decl) - { - - tree field = TYPE_FIELDS (type); - field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field)))); - - initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)), - initlist); - } - - return build_constructor (type, nreverse (initlist)); -} - -/* Push forward-declarations of all the categories - so that init_def_list can use them in a CONSTRUCTOR. */ - -static void -forward_declare_categories () -{ - struct imp_entry *impent; - tree sav = implementation_context; - - for (impent = imp_list; impent; impent = impent->next) - { - if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) - { - /* Set an invisible arg to synth_id_with_class_suffix. */ - implementation_context = impent->imp_context; - impent->class_decl - = create_builtin_decl (VAR_DECL, objc_category_template, - IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context))); - } - } - implementation_context = sav; -} - -/* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab' - and initialized appropriately. */ - -static void -generate_objc_symtab_decl () -{ - tree sc_spec; - - if (!objc_category_template) - build_category_template (); - - /* forward declare categories */ - if (cat_count) - forward_declare_categories (); - - if (!objc_symtab_template) - build_objc_symtab_template (); - - sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]); - - UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"), - tree_cons (NULL_TREE, - objc_symtab_template, sc_spec), - 1, - NULL_TREE, NULL_TREE); - - TREE_USED (UOBJC_SYMBOLS_decl) = 1; - DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1; - DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1; - finish_decl (UOBJC_SYMBOLS_decl, - init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)), - NULL_TREE); -} - -static tree -init_module_descriptor (type) - tree type; -{ - tree initlist, expr; - - /* version = { 1, ... } */ - - expr = build_int_2 (OBJC_VERSION, 0); - initlist = build_tree_list (NULL_TREE, expr); - - /* size = { ..., sizeof (struct objc_module), ... } */ - - expr = size_in_bytes (objc_module_template); - initlist = tree_cons (NULL_TREE, expr, initlist); - - /* name = { ..., "foo.m", ... } */ - - expr = add_objc_string (get_identifier (input_filename), class_names); - initlist = tree_cons (NULL_TREE, expr, initlist); - - /* symtab = { ..., _OBJC_SYMBOLS, ... } */ - - if (UOBJC_SYMBOLS_decl) - expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0); - else - expr = build_int_2 (0, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - - return build_constructor (type, nreverse (initlist)); -} - -/* Write out the data structures to describe Objective C classes defined. - If appropriate, compile and output a setup function to initialize them. - Return a string which is the name of a function to call to initialize - the Objective C data structures for this file (and perhaps for other files - also). - - struct objc_module { ... } _OBJC_MODULE = { ... }; */ - -static char * -build_module_descriptor () -{ - tree decl_specs, field_decl, field_decl_chain; - - objc_module_template - = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE)); - - /* Long version; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("version"); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* long size; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("size"); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* char *name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_symtab *symtab; */ - - decl_specs = get_identifier (UTAG_SYMTAB); - decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs)); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_module_template, field_decl_chain, NULL_TREE); - - /* Create an instance of "objc_module". */ - - decl_specs = tree_cons (NULL_TREE, objc_module_template, - build_tree_list (NULL_TREE, - ridpointers[(int) RID_STATIC])); - - UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"), - decl_specs, 1, NULL_TREE, NULL_TREE); - - DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1; - DECL_IGNORED_P (UOBJC_MODULES_decl) = 1; - finish_decl (UOBJC_MODULES_decl, - init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)), - NULL_TREE); - - /* Mark the decl to avoid "defined but not used" warning. */ - DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1; - - /* Generate a constructor call for the module descriptor. - This code was generated by reading the grammar rules - of c-parse.in; Therefore, it may not be the most efficient - way of generating the requisite code. */ - - if (flag_next_runtime) - return 0; - - { - tree parms, function_decl, decelerator, void_list_node; - tree function_type; - tree init_function_name = get_file_function_name ('I'); - - /* Declare void __objc_execClass (void *); */ - - void_list_node = build_tree_list (NULL_TREE, void_type_node); - function_type - = build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - void_list_node)); - function_decl = build_decl (FUNCTION_DECL, - get_identifier (TAG_EXECCLASS), - function_type); - DECL_EXTERNAL (function_decl) = 1; - DECL_ARTIFICIAL (function_decl) = 1; - TREE_PUBLIC (function_decl) = 1; - - pushdecl (function_decl); - rest_of_decl_compilation (function_decl, 0, 0, 0); - - parms - = build_tree_list (NULL_TREE, - build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0)); - decelerator = build_function_call (function_decl, parms); - - /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */ - - start_function (void_list_node, - build_parse_node (CALL_EXPR, init_function_name, - /* This has the format of the output - of get_parm_info. */ - tree_cons (NULL_TREE, NULL_TREE, - void_list_node), - NULL_TREE), - NULL_TREE, NULL_TREE, 0); -#if 0 /* This should be turned back on later - for the systems where collect is not needed. */ - /* Make these functions nonglobal - so each file can use the same name. */ - TREE_PUBLIC (current_function_decl) = 0; -#endif - TREE_USED (current_function_decl) = 1; - store_parm_decls (); - - assemble_external (function_decl); - c_expand_expr_stmt (decelerator); - - TREE_PUBLIC (current_function_decl) = 1; - - function_decl = current_function_decl; - finish_function (0); - - /* Return the name of the constructor function. */ - return XSTR (XEXP (DECL_RTL (function_decl), 0), 0); - } -} - -/* extern const char _OBJC_STRINGS[]; */ - -static void -generate_forward_declaration_to_string_table () -{ - tree sc_spec, decl_specs, expr_decl; - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec); - - expr_decl - = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE); - - UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs); -} - -/* Return the DECL of the string IDENT in the SECTION. */ - -static tree -get_objc_string_decl (ident, section) - tree ident; - enum string_section section; -{ - tree chain; - - if (section == class_names) - chain = class_names_chain; - else if (section == meth_var_names) - chain = meth_var_names_chain; - else if (section == meth_var_types) - chain = meth_var_types_chain; - else - abort (); - - for (; chain != 0; chain = TREE_VALUE (chain)) - if (TREE_VALUE (chain) == ident) - return (TREE_PURPOSE (chain)); - - abort (); - return NULL_TREE; -} - -/* Output references to all statically allocated objects. Return the DECL - for the array built. */ - -static void -generate_static_references () -{ - tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE; - tree class_name, class, decl, initlist; - tree cl_chain, in_chain, type; - int num_inst, num_class; - char buf[256]; - - if (flag_next_runtime) - abort (); - - for (cl_chain = objc_static_instances, num_class = 0; - cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++) - { - for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain); - in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain)); - - sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class); - ident = get_identifier (buf); - - expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE); - decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node), - build_tree_list (NULL_TREE, - ridpointers[(int) RID_STATIC])); - decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE); - DECL_CONTEXT (decl) = 0; - DECL_ARTIFICIAL (decl) = 1; - - /* Output {class_name, ...}. */ - class = TREE_VALUE (cl_chain); - class_name = get_objc_string_decl (TYPE_NAME (class), class_names); - initlist = build_tree_list (NULL_TREE, - build_unary_op (ADDR_EXPR, class_name, 1)); - - /* Output {..., instance, ...}. */ - for (in_chain = TREE_PURPOSE (cl_chain); - in_chain; in_chain = TREE_CHAIN (in_chain)) - { - expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - /* Output {..., NULL}. */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - - expr = build_constructor (TREE_TYPE (decl), nreverse (initlist)); - finish_decl (decl, expr, NULL_TREE); - TREE_USED (decl) = 1; - - type = build_array_type (build_pointer_type (void_type_node), 0); - decl = build_decl (VAR_DECL, ident, type); - make_decl_rtl (decl, 0, 1); - TREE_USED (decl) = 1; - decls - = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls); - } - - decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls); - ident = get_identifier ("_OBJC_STATIC_INSTANCES"); - expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE); - decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node), - build_tree_list (NULL_TREE, - ridpointers[(int) RID_STATIC])); - static_instances_decl - = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE); - TREE_USED (static_instances_decl) = 1; - DECL_CONTEXT (static_instances_decl) = 0; - DECL_ARTIFICIAL (static_instances_decl) = 1; - end_temporary_allocation (); - expr = build_constructor (TREE_TYPE (static_instances_decl), - nreverse (decls)); - finish_decl (static_instances_decl, expr, NULL_TREE); -} - -/* Output all strings. */ - -static void -generate_strings () -{ - tree sc_spec, decl_specs, expr_decl; - tree chain, string_expr; - tree string, decl; - - for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain)) - { - string = TREE_VALUE (chain); - decl = TREE_PURPOSE (chain); - sc_spec - = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec); - expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE); - decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE); - end_temporary_allocation (); - string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, - IDENTIFIER_POINTER (string)); - finish_decl (decl, string_expr, NULL_TREE); - } - - for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain)) - { - string = TREE_VALUE (chain); - decl = TREE_PURPOSE (chain); - sc_spec - = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec); - expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE); - decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE); - string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, - IDENTIFIER_POINTER (string)); - finish_decl (decl, string_expr, NULL_TREE); - } - - for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain)) - { - string = TREE_VALUE (chain); - decl = TREE_PURPOSE (chain); - sc_spec - = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec); - expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE); - decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE); - string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, - IDENTIFIER_POINTER (string)); - finish_decl (decl, string_expr, NULL_TREE); - } -} - -static tree -build_selector_reference_decl (name) - tree name; -{ - tree decl, ident; - char buf[256]; - static int idx = 0; - - sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++); - - push_obstacks_nochange (); - end_temporary_allocation (); - - ident = get_identifier (buf); - - decl = build_decl (VAR_DECL, ident, selector_type); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - TREE_READONLY (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; - DECL_CONTEXT (decl) = 0; - - make_decl_rtl (decl, 0, 1); - pushdecl_top_level (decl); - - pop_obstacks (); - - return decl; -} - -/* Just a handy wrapper for add_objc_string. */ - -static tree -build_selector (ident) - tree ident; -{ - tree expr = add_objc_string (ident, meth_var_names); - if (flag_typed_selectors) - return expr; - else - return build_c_cast (selector_type, expr); /* cast! */ -} - -/* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>] - The cast stops the compiler from issuing the following message: - grok.m: warning: initialization of non-const * pointer from const * - grok.m: warning: initialization between incompatible pointer types. */ - -#if 0 -static tree -build_msg_pool_reference (offset) - int offset; -{ - tree expr = build_int_2 (offset, 0); - tree cast; - - expr = build_array_ref (UOBJC_STRINGS_decl, expr); - expr = build_unary_op (ADDR_EXPR, expr, 0); - - cast = build_tree_list (build_tree_list (NULL_TREE, - ridpointers[(int) RID_CHAR]), - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)); - TREE_TYPE (expr) = groktypename (cast); - return expr; -} - -static tree -init_selector (offset) - int offset; -{ - tree expr = build_msg_pool_reference (offset); - TREE_TYPE (expr) = selector_type; - return expr; -} -#endif - -static void -build_selector_translation_table () -{ - tree sc_spec, decl_specs; - tree chain, initlist = NULL_TREE; - int offset = 0; - tree decl = NULL_TREE, var_decl, name; - - /* The corresponding pop_obstacks is in finish_decl, - called at the end of this function. */ - if (! flag_next_runtime) - push_obstacks_nochange (); - - for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain)) - { - tree expr; - - expr = build_selector (TREE_VALUE (chain)); - - if (flag_next_runtime) - { - name = DECL_NAME (TREE_PURPOSE (chain)); - - sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]); - - /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */ - decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec); - - var_decl = name; - - /* The `decl' that is returned from start_decl is the one that we - forward declared in `build_selector_reference' */ - decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE); - } - - /* add one for the '\0' character */ - offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1; - - if (flag_next_runtime) - finish_decl (decl, expr, NULL_TREE); - else - { - if (flag_typed_selectors) - { - tree eltlist = NULL_TREE; - tree encoding = get_proto_encoding (TREE_PURPOSE (chain)); - eltlist = tree_cons (NULL_TREE, expr, NULL_TREE); - eltlist = tree_cons (NULL_TREE, encoding, eltlist); - expr = build_constructor (objc_selector_template, - nreverse (eltlist)); - } - initlist = tree_cons (NULL_TREE, expr, initlist); - - } - } - - if (! flag_next_runtime) - { - /* Cause the variable and its initial value to be actually output. */ - DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0; - TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1; - /* NULL terminate the list and fix the decl for output. */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1; - initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl), - nreverse (initlist)); - finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE); - current_function_decl = NULL_TREE; - } -} - -static tree -get_proto_encoding (proto) - tree proto; -{ - tree encoding; - if (proto) - { - tree tmp_decl; - - if (! METHOD_ENCODING (proto)) - { - tmp_decl = build_tmp_function_decl (); - hack_method_prototype (proto, tmp_decl); - encoding = encode_method_prototype (proto, tmp_decl); - METHOD_ENCODING (proto) = encoding; - } - else - encoding = METHOD_ENCODING (proto); - - return add_objc_string (encoding, meth_var_types); - } - else - return build_int_2 (0, 0); -} - -/* sel_ref_chain is a list whose "value" fields will be instances of - identifier_node that represent the selector. */ - -static tree -build_typed_selector_reference (ident, proto) - tree ident, proto; -{ - tree *chain = &sel_ref_chain; - tree expr; - int index = 0; - - while (*chain) - { - if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto) - goto return_at_index; - - index++; - chain = &TREE_CHAIN (*chain); - } - - *chain = perm_tree_cons (proto, ident, NULL_TREE); - - return_at_index: - expr = build_unary_op (ADDR_EXPR, - build_array_ref (UOBJC_SELECTOR_TABLE_decl, - build_int_2 (index, 0)), - 1); - return build_c_cast (selector_type, expr); -} - -static tree -build_selector_reference (ident) - tree ident; -{ - tree *chain = &sel_ref_chain; - tree expr; - int index = 0; - - while (*chain) - { - if (TREE_VALUE (*chain) == ident) - return (flag_next_runtime - ? TREE_PURPOSE (*chain) - : build_array_ref (UOBJC_SELECTOR_TABLE_decl, - build_int_2 (index, 0))); - - index++; - chain = &TREE_CHAIN (*chain); - } - - expr = build_selector_reference_decl (ident); - - *chain = perm_tree_cons (expr, ident, NULL_TREE); - - return (flag_next_runtime - ? expr - : build_array_ref (UOBJC_SELECTOR_TABLE_decl, - build_int_2 (index, 0))); -} - -static tree -build_class_reference_decl (name) - tree name; -{ - tree decl, ident; - char buf[256]; - static int idx = 0; - - sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++); - - push_obstacks_nochange (); - end_temporary_allocation (); - - ident = get_identifier (buf); - - decl = build_decl (VAR_DECL, ident, objc_class_type); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - TREE_READONLY (decl) = 1; - DECL_CONTEXT (decl) = 0; - DECL_ARTIFICIAL (decl) = 1; - - make_decl_rtl (decl, 0, 1); - pushdecl_top_level (decl); - - pop_obstacks (); - - return decl; -} - -/* Create a class reference, but don't create a variable to reference - it. */ - -static void -add_class_reference (ident) - tree ident; -{ - tree chain; - - if ((chain = cls_ref_chain)) - { - tree tail; - do - { - if (ident == TREE_VALUE (chain)) - return; - - tail = chain; - chain = TREE_CHAIN (chain); - } - while (chain); - - /* Append to the end of the list */ - TREE_CHAIN (tail) = perm_tree_cons (NULL_TREE, ident, NULL_TREE); - } - else - cls_ref_chain = perm_tree_cons (NULL_TREE, ident, NULL_TREE); -} - -/* Get a class reference, creating it if necessary. Also create the - reference variable. */ - -tree -get_class_reference (ident) - tree ident; -{ - if (flag_next_runtime) - { - tree *chain; - tree decl; - - for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain)) - if (TREE_VALUE (*chain) == ident) - { - if (! TREE_PURPOSE (*chain)) - TREE_PURPOSE (*chain) = build_class_reference_decl (ident); - - return TREE_PURPOSE (*chain); - } - - decl = build_class_reference_decl (ident); - *chain = perm_tree_cons (decl, ident, NULL_TREE); - return decl; - } - else - { - tree params; - - add_class_reference (ident); - - params = build_tree_list (NULL_TREE, - my_build_string (IDENTIFIER_LENGTH (ident) + 1, - IDENTIFIER_POINTER (ident))); - - assemble_external (objc_get_class_decl); - return build_function_call (objc_get_class_decl, params); - } -} - -/* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances - of identifier_node that represent the selector. It returns the - offset of the selector from the beginning of the _OBJC_STRINGS - pool. This offset is typically used by init_selector during code - generation. - - For each string section we have a chain which maps identifier nodes - to decls for the strings. */ - -static tree -add_objc_string (ident, section) - tree ident; - enum string_section section; -{ - tree *chain, decl; - - if (section == class_names) - chain = &class_names_chain; - else if (section == meth_var_names) - chain = &meth_var_names_chain; - else if (section == meth_var_types) - chain = &meth_var_types_chain; - else - abort (); - - while (*chain) - { - if (TREE_VALUE (*chain) == ident) - return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1); - - chain = &TREE_CHAIN (*chain); - } - - decl = build_objc_string_decl (ident, section); - - *chain = perm_tree_cons (decl, ident, NULL_TREE); - - return build_unary_op (ADDR_EXPR, decl, 1); -} - -static tree -build_objc_string_decl (name, section) - tree name; - enum string_section section; -{ - tree decl, ident; - char buf[256]; - static int class_names_idx = 0; - static int meth_var_names_idx = 0; - static int meth_var_types_idx = 0; - - if (section == class_names) - sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++); - else if (section == meth_var_names) - sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++); - else if (section == meth_var_types) - sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++); - - push_obstacks_nochange (); - end_temporary_allocation (); - ident = get_identifier (buf); - - decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0)); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - TREE_READONLY (decl) = 1; - TREE_CONSTANT (decl) = 1; - DECL_CONTEXT (decl) = 0; - DECL_ARTIFICIAL (decl) = 1; - - make_decl_rtl (decl, 0, 1); - pushdecl_top_level (decl); - - pop_obstacks (); - - return decl; -} - - -void -objc_declare_alias (alias_ident, class_ident) - tree alias_ident; - tree class_ident; -{ - if (!doing_objc_thang) - objc_fatal (); - - if (is_class_name (class_ident) != class_ident) - warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident)); - else if (is_class_name (alias_ident)) - warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident)); - else - alias_chain = tree_cons (class_ident, alias_ident, alias_chain); -} - -void -objc_declare_class (ident_list) - tree ident_list; -{ - tree list; - - if (!doing_objc_thang) - objc_fatal (); - - for (list = ident_list; list; list = TREE_CHAIN (list)) - { - tree ident = TREE_VALUE (list); - tree decl; - - if ((decl = lookup_name (ident))) - { - error ("`%s' redeclared as different kind of symbol", - IDENTIFIER_POINTER (ident)); - error_with_decl (decl, "previous declaration of `%s'"); - } - - if (! is_class_name (ident)) - { - tree record = xref_tag (RECORD_TYPE, ident); - TREE_STATIC_TEMPLATE (record) = 1; - class_chain = tree_cons (NULL_TREE, ident, class_chain); - } - } -} - -tree -is_class_name (ident) - tree ident; -{ - tree chain; - - if (lookup_interface (ident)) - return ident; - - for (chain = class_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == TREE_VALUE (chain)) - return ident; - } - - for (chain = alias_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == TREE_VALUE (chain)) - return TREE_PURPOSE (chain); - } - - return 0; -} - -tree -lookup_interface (ident) - tree ident; -{ - tree chain; - - for (chain = interface_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == CLASS_NAME (chain)) - return chain; - } - return NULL_TREE; -} - -static tree -objc_copy_list (list, head) - tree list; - tree *head; -{ - tree newlist = NULL_TREE, tail = NULL_TREE; - - while (list) - { - tail = copy_node (list); - - /* The following statement fixes a bug when inheriting instance - variables that are declared to be bitfields. finish_struct - expects to find the width of the bitfield in DECL_INITIAL, - which it nulls out after processing the decl of the super - class...rather than change the way finish_struct works (which - is risky), I create the situation it expects...s.naroff - (7/23/89). */ - - if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0) - DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0); - - newlist = chainon (newlist, tail); - list = TREE_CHAIN (list); - } - - *head = newlist; - return tail; -} - -/* Used by: build_private_template, get_class_ivars, and - continue_class. COPY is 1 when called from @defs. In this case - copy all fields. Otherwise don't copy leaf ivars since we rely on - them being side-effected exactly once by finish_struct. */ - -static tree -build_ivar_chain (interface, copy) - tree interface; - int copy; -{ - tree my_name, super_name, ivar_chain; - - my_name = CLASS_NAME (interface); - super_name = CLASS_SUPER_NAME (interface); - - /* Possibly copy leaf ivars. */ - if (copy) - objc_copy_list (CLASS_IVARS (interface), &ivar_chain); - else - ivar_chain = CLASS_IVARS (interface); - - while (super_name) - { - tree op1; - tree super_interface = lookup_interface (super_name); - - if (!super_interface) - { - /* fatal did not work with 2 args...should fix */ - error ("Cannot find interface declaration for `%s', superclass of `%s'", - IDENTIFIER_POINTER (super_name), - IDENTIFIER_POINTER (my_name)); - exit (FATAL_EXIT_CODE); - } - - if (super_interface == interface) - { - fatal ("Circular inheritance in interface declaration for `%s'", - IDENTIFIER_POINTER (super_name)); - } - - interface = super_interface; - my_name = CLASS_NAME (interface); - super_name = CLASS_SUPER_NAME (interface); - - op1 = CLASS_IVARS (interface); - if (op1) - { - tree head, tail = objc_copy_list (op1, &head); - - /* Prepend super class ivars...make a copy of the list, we - do not want to alter the original. */ - TREE_CHAIN (tail) = ivar_chain; - ivar_chain = head; - } - } - return ivar_chain; -} - -/* struct <classname> { - struct objc_class *isa; - ... - }; */ - -static tree -build_private_template (class) - tree class; -{ - tree ivar_context; - - if (CLASS_STATIC_TEMPLATE (class)) - { - uprivate_record = CLASS_STATIC_TEMPLATE (class); - ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class)); - } - else - { - uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class)); - - ivar_context = build_ivar_chain (class, 0); - - finish_struct (uprivate_record, ivar_context, NULL_TREE); - - CLASS_STATIC_TEMPLATE (class) = uprivate_record; - - /* mark this record as class template - for class type checking */ - TREE_STATIC_TEMPLATE (uprivate_record) = 1; - } - - instance_type - = groktypename (build_tree_list (build_tree_list (NULL_TREE, - uprivate_record), - build1 (INDIRECT_REF, NULL_TREE, - NULL_TREE))); - - return ivar_context; -} - -/* Begin code generation for protocols... */ - -/* struct objc_protocol { - char *protocol_name; - struct objc_protocol **protocol_list; - struct objc_method_desc *instance_methods; - struct objc_method_desc *class_methods; - }; */ - -static tree -build_protocol_template () -{ - tree decl_specs, field_decl, field_decl_chain; - tree template; - - template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL)); - - /* struct objc_class *isa; */ - - decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (UTAG_CLASS))); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* char *protocol_name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_protocol **protocol_list; */ - - decl_specs = build_tree_list (NULL_TREE, template); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list")); - field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *instance_methods; */ - - decl_specs - = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_PROTOTYPE_LIST))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *class_methods; */ - - decl_specs - = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_PROTOTYPE_LIST))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - return finish_struct (template, field_decl_chain, NULL_TREE); -} - -static tree -build_descriptor_table_initializer (type, entries) - tree type; - tree entries; -{ - tree initlist = NULL_TREE; - - do - { - tree eltlist = NULL_TREE; - - eltlist - = tree_cons (NULL_TREE, - build_selector (METHOD_SEL_NAME (entries)), NULL_TREE); - eltlist - = tree_cons (NULL_TREE, - add_objc_string (METHOD_ENCODING (entries), - meth_var_types), - eltlist); - - initlist - = tree_cons (NULL_TREE, - build_constructor (type, nreverse (eltlist)), initlist); - - entries = TREE_CHAIN (entries); - } - while (entries); - - return build_constructor (build_array_type (type, 0), nreverse (initlist)); -} - -/* struct objc_method_prototype_list { - int count; - struct objc_method_prototype { - SEL name; - char *types; - } list[1]; - }; */ - -static tree -build_method_prototype_list_template (list_type, size) - tree list_type; - int size; -{ - tree objc_ivar_list_record; - tree decl_specs, field_decl, field_decl_chain; - - /* Generate an unnamed struct definition. */ - - objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE); - - /* int method_count; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("method_count"); - - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* struct objc_method method_list[]; */ - - decl_specs = build_tree_list (NULL_TREE, list_type); - field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"), - build_int_2 (size, 0)); - - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE); - - return objc_ivar_list_record; -} - -static tree -build_method_prototype_template () -{ - tree proto_record; - tree decl_specs, field_decl, field_decl_chain; - - proto_record - = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE)); - -#ifdef OBJC_INT_SELECTORS - /* unsigned int _cmd; */ - decl_specs - = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs); - field_decl = get_identifier ("_cmd"); -#else /* OBJC_INT_SELECTORS */ - /* struct objc_selector *_cmd; */ - decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR)), NULL_TREE); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd")); -#endif /* OBJC_INT_SELECTORS */ - - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (proto_record, field_decl_chain, NULL_TREE); - - return proto_record; -} - -/* True if last call to forwarding_offset yielded a register offset. */ -static int offset_is_register; - -static int -forwarding_offset (parm) - tree parm; -{ - int offset_in_bytes; - - if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM) - { - rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0); - - /* ??? Here we assume that the parm address is indexed - off the frame pointer or arg pointer. - If that is not true, we produce meaningless results, - but do not crash. */ - if (GET_CODE (addr) == PLUS - && GET_CODE (XEXP (addr, 1)) == CONST_INT) - offset_in_bytes = INTVAL (XEXP (addr, 1)); - else - offset_in_bytes = 0; - - offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET; - offset_is_register = 0; - } - else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG) - { - int regno = REGNO (DECL_INCOMING_RTL (parm)); - offset_in_bytes = apply_args_register_offset (regno); - offset_is_register = 1; - } - else - return 0; - - /* This is the case where the parm is passed as an int or double - and it is converted to a char, short or float and stored back - in the parmlist. In this case, describe the parm - with the variable's declared type, and adjust the address - if the least significant bytes (which we are using) are not - the first ones. */ - if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm)) - offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm))) - - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm)))); - - return offset_in_bytes; -} - -static tree -encode_method_prototype (method_decl, func_decl) - tree method_decl; - tree func_decl; -{ - tree parms; - int stack_size, i; - tree user_args; - int max_parm_end = 0; - char buf[40]; - tree result; - - /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */ - encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl))); - - /* C type. */ - encode_type (TREE_TYPE (TREE_TYPE (func_decl)), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - - /* Stack size. */ - for (parms = DECL_ARGUMENTS (func_decl); parms; - parms = TREE_CHAIN (parms)) - { - int parm_end = (forwarding_offset (parms) - + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms))) - / BITS_PER_UNIT)); - - if (!offset_is_register && max_parm_end < parm_end) - max_parm_end = parm_end; - } - - stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET; - - sprintf (buf, "%d", stack_size); - obstack_grow (&util_obstack, buf, strlen (buf)); - - user_args = METHOD_SEL_ARGS (method_decl); - - /* Argument types. */ - for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms; - parms = TREE_CHAIN (parms), i++) - { - /* Process argument qualifiers for user supplied arguments. */ - if (i > 1) - { - encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args))); - user_args = TREE_CHAIN (user_args); - } - - /* Type. */ - encode_type (TREE_TYPE (parms), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - - /* Compute offset. */ - sprintf (buf, "%d", forwarding_offset (parms)); - - /* Indicate register. */ - if (offset_is_register) - obstack_1grow (&util_obstack, '+'); - - obstack_grow (&util_obstack, buf, strlen (buf)); - } - - obstack_1grow (&util_obstack, '\0'); - result = get_identifier (obstack_finish (&util_obstack)); - obstack_free (&util_obstack, util_firstobj); - return result; -} - -static tree -generate_descriptor_table (type, name, size, list, proto) - tree type; - char *name; - int size; - tree list; - tree proto; -{ - tree sc_spec, decl_specs, decl, initlist; - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, type, sc_spec); - - decl = start_decl (synth_id_with_class_suffix (name, proto), - decl_specs, 1, NULL_TREE, NULL_TREE); - - initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0)); - initlist = tree_cons (NULL_TREE, list, initlist); - - finish_decl (decl, build_constructor (type, nreverse (initlist)), - NULL_TREE); - - return decl; -} - -static void -generate_method_descriptors (protocol) /* generate_dispatch_tables */ - tree protocol; -{ - static tree objc_method_prototype_template; - tree initlist, chain, method_list_template; - tree cast, variable_length_type; - int size; - - if (!objc_method_prototype_template) - objc_method_prototype_template = build_method_prototype_template (); - - cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_PROTOTYPE_LIST))), - NULL_TREE); - variable_length_type = groktypename (cast); - - chain = PROTOCOL_CLS_METHODS (protocol); - if (chain) - { - size = list_length (chain); - - method_list_template - = build_method_prototype_list_template (objc_method_prototype_template, - size); - - initlist - = build_descriptor_table_initializer (objc_method_prototype_template, - chain); - - UOBJC_CLASS_METHODS_decl - = generate_descriptor_table (method_list_template, - "_OBJC_PROTOCOL_CLASS_METHODS", - size, initlist, protocol); - TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type; - } - else - UOBJC_CLASS_METHODS_decl = 0; - - chain = PROTOCOL_NST_METHODS (protocol); - if (chain) - { - size = list_length (chain); - - method_list_template - = build_method_prototype_list_template (objc_method_prototype_template, - size); - initlist - = build_descriptor_table_initializer (objc_method_prototype_template, - chain); - - UOBJC_INSTANCE_METHODS_decl - = generate_descriptor_table (method_list_template, - "_OBJC_PROTOCOL_INSTANCE_METHODS", - size, initlist, protocol); - TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type; - } - else - UOBJC_INSTANCE_METHODS_decl = 0; -} - -static tree -build_tmp_function_decl () -{ - tree decl_specs, expr_decl, parms; - static int xxx = 0; - char buffer[80]; - - /* struct objc_object *objc_xxx (id, SEL, ...); */ - pushlevel (0); - decl_specs = build_tree_list (NULL_TREE, objc_object_reference); - push_parm_decl (build_tree_list - (build_tree_list (decl_specs, - build1 (INDIRECT_REF, NULL_TREE, - NULL_TREE)), - build_tree_list (NULL_TREE, NULL_TREE))); - - decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); - expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE); - - push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl), - build_tree_list (NULL_TREE, NULL_TREE))); - parms = get_parm_info (0); - poplevel (0, 0, 0); - - decl_specs = build_tree_list (NULL_TREE, objc_object_reference); - sprintf (buffer, "__objc_tmp_%x", xxx++); - expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE); - expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl); - - return define_decl (expr_decl, decl_specs); -} - -static void -hack_method_prototype (nst_methods, tmp_decl) - tree nst_methods; - tree tmp_decl; -{ - tree parms; - tree parm; - - /* Hack to avoid problem with static typing of self arg. */ - TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL); - start_method_def (nst_methods); - TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL); - - if (METHOD_ADD_ARGS (nst_methods) == (tree) 1) - parms = get_parm_info (0); /* we have a `, ...' */ - else - parms = get_parm_info (1); /* place a `void_at_end' */ - - poplevel (0, 0, 0); /* Must be called BEFORE start_function. */ - - /* Usually called from store_parm_decls -> init_function_start. */ - - DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms); - current_function_decl = tmp_decl; - - { - /* Code taken from start_function. */ - tree restype = TREE_TYPE (TREE_TYPE (tmp_decl)); - /* Promote the value to int before returning it. */ - if (TREE_CODE (restype) == INTEGER_TYPE - && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node)) - restype = integer_type_node; - DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype); - } - - for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm)) - DECL_CONTEXT (parm) = tmp_decl; - - init_function_start (tmp_decl, "objc-act", 0); - - /* Typically called from expand_function_start for function definitions. */ - assign_parms (tmp_decl, 0); - - /* install return type */ - TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods)); - -} - -static void -generate_protocol_references (plist) - tree plist; -{ - tree lproto; - - /* Forward declare protocols referenced. */ - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) - { - tree proto = TREE_VALUE (lproto); - - if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE - && PROTOCOL_NAME (proto)) - { - if (! PROTOCOL_FORWARD_DECL (proto)) - build_protocol_reference (proto); - - if (PROTOCOL_LIST (proto)) - generate_protocol_references (PROTOCOL_LIST (proto)); - } - } -} - -static void -generate_protocols () -{ - tree p, tmp_decl, encoding; - tree sc_spec, decl_specs, decl; - tree initlist, protocol_name_expr, refs_decl, refs_expr; - tree cast_type2 = 0; - - tmp_decl = build_tmp_function_decl (); - - if (! objc_protocol_template) - objc_protocol_template = build_protocol_template (); - - /* If a protocol was directly referenced, pull in indirect references. */ - for (p = protocol_chain; p; p = TREE_CHAIN (p)) - if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p)) - generate_protocol_references (PROTOCOL_LIST (p)); - - for (p = protocol_chain; p; p = TREE_CHAIN (p)) - { - tree nst_methods = PROTOCOL_NST_METHODS (p); - tree cls_methods = PROTOCOL_CLS_METHODS (p); - - /* If protocol wasn't referenced, don't generate any code. */ - if (! PROTOCOL_FORWARD_DECL (p)) - continue; - - /* Make sure we link in the Protocol class. */ - add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME)); - - while (nst_methods) - { - if (! METHOD_ENCODING (nst_methods)) - { - hack_method_prototype (nst_methods, tmp_decl); - encoding = encode_method_prototype (nst_methods, tmp_decl); - METHOD_ENCODING (nst_methods) = encoding; - } - nst_methods = TREE_CHAIN (nst_methods); - } - - while (cls_methods) - { - if (! METHOD_ENCODING (cls_methods)) - { - hack_method_prototype (cls_methods, tmp_decl); - encoding = encode_method_prototype (cls_methods, tmp_decl); - METHOD_ENCODING (cls_methods) = encoding; - } - - cls_methods = TREE_CHAIN (cls_methods); - } - generate_method_descriptors (p); - - if (PROTOCOL_LIST (p)) - refs_decl = generate_protocol_list (p); - else - refs_decl = 0; - - /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */ - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], - NULL_TREE); - decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec); - - decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p), - decl_specs, 1, NULL_TREE, NULL_TREE); - - protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names); - - if (refs_decl) - { - if (!cast_type2) - cast_type2 - = groktypename - (build_tree_list (build_tree_list (NULL_TREE, - objc_protocol_template), - build1 (INDIRECT_REF, NULL_TREE, - build1 (INDIRECT_REF, NULL_TREE, - NULL_TREE)))); - - refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0); - TREE_TYPE (refs_expr) = cast_type2; - } - else - refs_expr = build_int_2 (0, 0); - - /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set - by generate_method_descriptors, which is called above. */ - initlist = build_protocol_initializer (TREE_TYPE (decl), - protocol_name_expr, refs_expr, - UOBJC_INSTANCE_METHODS_decl, - UOBJC_CLASS_METHODS_decl); - finish_decl (decl, initlist, NULL_TREE); - - /* Mark the decl as used to avoid "defined but not used" warning. */ - TREE_USED (decl) = 1; - } -} - -static tree -build_protocol_initializer (type, protocol_name, protocol_list, - instance_methods, class_methods) - tree type; - tree protocol_name; - tree protocol_list; - tree instance_methods; - tree class_methods; -{ - tree initlist = NULL_TREE, expr; - static tree cast_type = 0; - - if (!cast_type) - cast_type - = groktypename - (build_tree_list - (build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_CLASS))), - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))); - - /* Filling the "isa" in with one allows the runtime system to - detect that the version change...should remove before final release. */ - - expr = build_int_2 (PROTOCOL_VERSION, 0); - TREE_TYPE (expr) = cast_type; - initlist = tree_cons (NULL_TREE, expr, initlist); - initlist = tree_cons (NULL_TREE, protocol_name, initlist); - initlist = tree_cons (NULL_TREE, protocol_list, initlist); - - if (!instance_methods) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, instance_methods, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - if (!class_methods) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, class_methods, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - return build_constructor (type, nreverse (initlist)); -} - -/* struct objc_category { - char *category_name; - char *class_name; - struct objc_method_list *instance_methods; - struct objc_method_list *class_methods; - struct objc_protocol_list *protocols; - }; */ - -static void -build_category_template () -{ - tree decl_specs, field_decl, field_decl_chain; - - objc_category_template = start_struct (RECORD_TYPE, - get_identifier (UTAG_CATEGORY)); - /* char *category_name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* char *class_name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *instance_methods; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *class_methods; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_protocol **protocol_list; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list")); - field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_category_template, field_decl_chain, NULL_TREE); -} - -/* struct objc_selector { - void *sel_id; - char *sel_type; - }; */ - -static void -build_selector_template () -{ - - tree decl_specs, field_decl, field_decl_chain; - - objc_selector_template - = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR)); - - /* 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); - field_decl_chain = field_decl; - - /* char *sel_type; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_selector_template, field_decl_chain, NULL_TREE); -} - -/* struct objc_class { - struct objc_class *isa; - struct objc_class *super_class; - char *name; - long version; - long info; - long instance_size; - struct objc_ivar_list *ivars; - struct objc_method_list *methods; - if (flag_next_runtime) - struct objc_cache *cache; - else { - struct sarray *dtable; - struct objc_class *subclass_list; - struct objc_class *sibling_class; - } - struct objc_protocol_list *protocols; - void *gc_object_type; - }; */ - -static void -build_class_template () -{ - tree decl_specs, field_decl, field_decl_chain; - - objc_class_template - = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS)); - - /* struct objc_class *isa; */ - - decl_specs = build_tree_list (NULL_TREE, objc_class_template); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* struct objc_class *super_class; */ - - decl_specs = build_tree_list (NULL_TREE, objc_class_template); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* char *name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* long version; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("version"); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* long info; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("info"); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* long instance_size; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("instance_size"); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_ivar_list *ivars; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_IVAR_LIST))); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *methods; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - if (flag_next_runtime) - { - /* struct objc_cache *cache; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier ("objc_cache"))); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - } - else - { - /* struct sarray *dtable; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier ("sarray"))); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_class *subclass_list; */ - - decl_specs = build_tree_list (NULL_TREE, objc_class_template); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_class *sibling_class; */ - - decl_specs = build_tree_list (NULL_TREE, objc_class_template); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - } - - /* struct objc_protocol **protocol_list; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list")); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, field_decl); - field_decl = grokfield (input_filename, lineno, field_decl, - 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); -} - -/* Generate appropriate forward declarations for an implementation. */ - -static void -synth_forward_declarations () -{ - tree sc_spec, decl_specs, an_id; - - /* extern struct objc_class _OBJC_CLASS_<my_name>; */ - - an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context); - - sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]); - decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec); - UOBJC_CLASS_decl = define_decl (an_id, decl_specs); - TREE_USED (UOBJC_CLASS_decl) = 1; - DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1; - - /* extern struct objc_class _OBJC_METACLASS_<my_name>; */ - - an_id = synth_id_with_class_suffix ("_OBJC_METACLASS", - implementation_context); - - UOBJC_METACLASS_decl = define_decl (an_id, decl_specs); - TREE_USED (UOBJC_METACLASS_decl) = 1; - DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1; - - /* Pre-build the following entities - for speed/convenience. */ - - an_id = get_identifier ("super_class"); - ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id); - uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id); -} - -static void -error_with_ivar (message, decl, rawdecl) - char *message; - tree decl; - tree rawdecl; -{ - count_error (0); - - report_error_function (DECL_SOURCE_FILE (decl)); - - fprintf (stderr, "%s:%d: ", - DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); - bzero (errbuf, BUFSIZE); - fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf)); -} - -#define USERTYPE(t) \ - (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \ - || TREE_CODE (t) == ENUMERAL_TYPE) - -static void -check_ivars (inter, imp) - tree inter; - tree imp; -{ - tree intdecls = CLASS_IVARS (inter); - tree impdecls = CLASS_IVARS (imp); - tree rawintdecls = CLASS_RAW_IVARS (inter); - tree rawimpdecls = CLASS_RAW_IVARS (imp); - - while (1) - { - tree t1, t2; - - if (intdecls == 0 && impdecls == 0) - break; - if (intdecls == 0 || impdecls == 0) - { - error ("inconsistent instance variable specification"); - break; - } - - t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls); - - if (!comptypes (t1, t2)) - { - if (DECL_NAME (intdecls) == DECL_NAME (impdecls)) - { - error_with_ivar ("conflicting instance variable type", - impdecls, rawimpdecls); - error_with_ivar ("previous declaration of", - intdecls, rawintdecls); - } - else /* both the type and the name don't match */ - { - error ("inconsistent instance variable specification"); - break; - } - } - - else if (DECL_NAME (intdecls) != DECL_NAME (impdecls)) - { - error_with_ivar ("conflicting instance variable name", - impdecls, rawimpdecls); - error_with_ivar ("previous declaration of", - intdecls, rawintdecls); - } - - intdecls = TREE_CHAIN (intdecls); - impdecls = TREE_CHAIN (impdecls); - rawintdecls = TREE_CHAIN (rawintdecls); - rawimpdecls = TREE_CHAIN (rawimpdecls); - } -} - -/* Set super_type to the data type node for struct objc_super *, - first defining struct objc_super itself. - This needs to be done just once per compilation. */ - -static tree -build_super_template () -{ - tree record, decl_specs, field_decl, field_decl_chain; - - record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER)); - - /* struct objc_object *self; */ - - decl_specs = build_tree_list (NULL_TREE, objc_object_reference); - field_decl = get_identifier ("self"); - field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl); - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* struct objc_class *class; */ - - decl_specs = get_identifier (UTAG_CLASS); - decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs)); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class")); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (record, field_decl_chain, NULL_TREE); - - /* `struct objc_super *' */ - super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE, - record), - build1 (INDIRECT_REF, - NULL_TREE, NULL_TREE))); - return record; -} - -/* struct objc_ivar { - char *ivar_name; - char *ivar_type; - int ivar_offset; - }; */ - -static tree -build_ivar_template () -{ - tree objc_ivar_id, objc_ivar_record; - tree decl_specs, field_decl, field_decl_chain; - - objc_ivar_id = get_identifier (UTAG_IVAR); - objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id); - - /* char *ivar_name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name")); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* char *ivar_type; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type")); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* int ivar_offset; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("ivar_offset"); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE); - - return objc_ivar_record; -} - -/* struct { - int ivar_count; - struct objc_ivar ivar_list[ivar_count]; - }; */ - -static tree -build_ivar_list_template (list_type, size) - tree list_type; - int size; -{ - tree objc_ivar_list_record; - tree decl_specs, field_decl, field_decl_chain; - - objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE); - - /* int ivar_count; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("ivar_count"); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* struct objc_ivar ivar_list[]; */ - - decl_specs = build_tree_list (NULL_TREE, list_type); - field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"), - build_int_2 (size, 0)); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE); - - return objc_ivar_list_record; -} - -/* struct { - int method_next; - int method_count; - struct objc_method method_list[method_count]; - }; */ - -static tree -build_method_list_template (list_type, size) - tree list_type; - int size; -{ - tree objc_ivar_list_record; - tree decl_specs, field_decl, field_decl_chain; - - objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE); - - /* int method_next; */ - - decl_specs - = build_tree_list - (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_PROTOTYPE_LIST))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* int method_count; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("method_count"); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method method_list[]; */ - - decl_specs = build_tree_list (NULL_TREE, list_type); - field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"), - build_int_2 (size, 0)); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE); - - return objc_ivar_list_record; -} - -static tree -build_ivar_list_initializer (type, field_decl) - tree type; - tree field_decl; -{ - tree initlist = NULL_TREE; - - do - { - tree ivar = NULL_TREE; - - /* Set name. */ - if (DECL_NAME (field_decl)) - ivar = tree_cons (NULL_TREE, - add_objc_string (DECL_NAME (field_decl), - meth_var_names), - ivar); - else - /* Unnamed bit-field ivar (yuck). */ - ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar); - - /* Set type. */ - encode_field_decl (field_decl, - obstack_object_size (&util_obstack), - OBJC_ENCODE_DONT_INLINE_DEFS); - - /* Null terminate string. */ - obstack_1grow (&util_obstack, 0); - ivar - = tree_cons - (NULL_TREE, - add_objc_string (get_identifier (obstack_finish (&util_obstack)), - meth_var_types), - ivar); - obstack_free (&util_obstack, util_firstobj); - - /* set offset */ - ivar - = tree_cons - (NULL_TREE, - build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)) - / BITS_PER_UNIT), - 0), - ivar); - - initlist = tree_cons (NULL_TREE, - build_constructor (type, nreverse (ivar)), - initlist); - - field_decl = TREE_CHAIN (field_decl); - } - while (field_decl); - - return build_constructor (build_array_type (type, 0), nreverse (initlist)); -} - -static tree -generate_ivars_list (type, name, size, list) - tree type; - char *name; - int size; - tree list; -{ - tree sc_spec, decl_specs, decl, initlist; - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, type, sc_spec); - - decl = start_decl (synth_id_with_class_suffix (name, implementation_context), - decl_specs, 1, NULL_TREE, NULL_TREE); - - initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0)); - initlist = tree_cons (NULL_TREE, list, initlist); - - finish_decl (decl, - build_constructor (TREE_TYPE (decl), nreverse (initlist)), - NULL_TREE); - - return decl; -} - -static void -generate_ivar_lists () -{ - tree initlist, ivar_list_template, chain; - tree cast, variable_length_type; - int size; - - generating_instance_variables = 1; - - if (!objc_ivar_template) - objc_ivar_template = build_ivar_template (); - - cast - = build_tree_list - (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (UTAG_IVAR_LIST))), - NULL_TREE); - variable_length_type = groktypename (cast); - - /* Only generate class variables for the root of the inheritance - hierarchy since these will be the same for every class. */ - - if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE - && (chain = TYPE_FIELDS (objc_class_template))) - { - size = list_length (chain); - - ivar_list_template = build_ivar_list_template (objc_ivar_template, size); - initlist = build_ivar_list_initializer (objc_ivar_template, chain); - - UOBJC_CLASS_VARIABLES_decl - = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES", - size, initlist); - TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type; - } - else - UOBJC_CLASS_VARIABLES_decl = 0; - - chain = CLASS_IVARS (implementation_template); - if (chain) - { - size = list_length (chain); - ivar_list_template = build_ivar_list_template (objc_ivar_template, size); - initlist = build_ivar_list_initializer (objc_ivar_template, chain); - - UOBJC_INSTANCE_VARIABLES_decl - = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES", - size, initlist); - TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type; - } - else - UOBJC_INSTANCE_VARIABLES_decl = 0; - - generating_instance_variables = 0; -} - -static tree -build_dispatch_table_initializer (type, entries) - tree type; - tree entries; -{ - tree initlist = NULL_TREE; - - do - { - tree elemlist = NULL_TREE; - - elemlist = tree_cons (NULL_TREE, - build_selector (METHOD_SEL_NAME (entries)), - NULL_TREE); - - elemlist = tree_cons (NULL_TREE, - add_objc_string (METHOD_ENCODING (entries), - meth_var_types), - elemlist); - - elemlist = tree_cons (NULL_TREE, - build_unary_op (ADDR_EXPR, - METHOD_DEFINITION (entries), 1), - elemlist); - - initlist = tree_cons (NULL_TREE, - build_constructor (type, nreverse (elemlist)), - initlist); - - entries = TREE_CHAIN (entries); - } - while (entries); - - return build_constructor (build_array_type (type, 0), nreverse (initlist)); -} - -/* To accomplish method prototyping without generating all kinds of - inane warnings, the definition of the dispatch table entries were - changed from: - - struct objc_method { SEL _cmd; ...; id (*_imp)(); }; - to: - struct objc_method { SEL _cmd; ...; void *_imp; }; */ - -static tree -build_method_template () -{ - tree _SLT_record; - tree decl_specs, field_decl, field_decl_chain; - - _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD)); - -#ifdef OBJC_INT_SELECTORS - /* unsigned int _cmd; */ - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], - NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs); - field_decl = get_identifier ("_cmd"); -#else /* not OBJC_INT_SELECTORS */ - /* struct objc_selector *_cmd; */ - decl_specs = tree_cons (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR)), - NULL_TREE); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd")); -#endif /* not OBJC_INT_SELECTORS */ - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE); - field_decl = build1 (INDIRECT_REF, NULL_TREE, - get_identifier ("method_types")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* void *_imp; */ - - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (_SLT_record, field_decl_chain, NULL_TREE); - - return _SLT_record; -} - - -static tree -generate_dispatch_table (type, name, size, list) - tree type; - char *name; - int size; - tree list; -{ - tree sc_spec, decl_specs, decl, initlist; - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, type, sc_spec); - - decl = start_decl (synth_id_with_class_suffix (name, implementation_context), - decl_specs, 1, NULL_TREE, NULL_TREE); - - initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0)); - initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist); - initlist = tree_cons (NULL_TREE, list, initlist); - - finish_decl (decl, - build_constructor (TREE_TYPE (decl), nreverse (initlist)), - NULL_TREE); - - return decl; -} - -static void -generate_dispatch_tables () -{ - tree initlist, chain, method_list_template; - tree cast, variable_length_type; - int size; - - if (!objc_method_template) - objc_method_template = build_method_template (); - - cast - = build_tree_list - (build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))), - NULL_TREE); - - variable_length_type = groktypename (cast); - - chain = CLASS_CLS_METHODS (implementation_context); - if (chain) - { - size = list_length (chain); - - method_list_template - = build_method_list_template (objc_method_template, size); - initlist - = build_dispatch_table_initializer (objc_method_template, chain); - - UOBJC_CLASS_METHODS_decl - = generate_dispatch_table (method_list_template, - ((TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - ? "_OBJC_CLASS_METHODS" - : "_OBJC_CATEGORY_CLASS_METHODS"), - size, initlist); - TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type; - } - else - UOBJC_CLASS_METHODS_decl = 0; - - chain = CLASS_NST_METHODS (implementation_context); - if (chain) - { - size = list_length (chain); - - method_list_template - = build_method_list_template (objc_method_template, size); - initlist - = build_dispatch_table_initializer (objc_method_template, chain); - - if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE) - UOBJC_INSTANCE_METHODS_decl - = generate_dispatch_table (method_list_template, - "_OBJC_INSTANCE_METHODS", - size, initlist); - else - /* We have a category. */ - UOBJC_INSTANCE_METHODS_decl - = generate_dispatch_table (method_list_template, - "_OBJC_CATEGORY_INSTANCE_METHODS", - size, initlist); - TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type; - } - else - UOBJC_INSTANCE_METHODS_decl = 0; -} - -static tree -generate_protocol_list (i_or_p) - tree i_or_p; -{ - static tree cast_type = 0; - tree initlist, decl_specs, sc_spec; - tree refs_decl, expr_decl, lproto, e, plist; - int size = 0; - - if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE - || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE) - plist = CLASS_PROTOCOL_LIST (i_or_p); - else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE) - plist = PROTOCOL_LIST (i_or_p); - else - abort (); - - if (!cast_type) - cast_type - = groktypename - (build_tree_list - (build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))), - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))); - - /* Compute size. */ - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) - if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE - && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto))) - size++; - - /* Build initializer. */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE); - - e = build_int_2 (size, 0); - TREE_TYPE (e) = cast_type; - initlist = tree_cons (NULL_TREE, e, initlist); - - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) - { - tree pval = TREE_VALUE (lproto); - - if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE - && PROTOCOL_FORWARD_DECL (pval)) - { - e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0); - initlist = tree_cons (NULL_TREE, e, initlist); - } - } - - /* static struct objc_protocol *refs[n]; */ - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL)), - sc_spec); - - if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE) - expr_decl = build_nt (ARRAY_REF, - synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", - i_or_p), - build_int_2 (size + 2, 0)); - else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE) - expr_decl = build_nt (ARRAY_REF, - synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", - i_or_p), - build_int_2 (size + 2, 0)); - else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE) - expr_decl - = build_nt (ARRAY_REF, - synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", - i_or_p), - build_int_2 (size + 2, 0)); - else - abort (); - - expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl); - - refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE); - - finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl), - nreverse (initlist)), - NULL_TREE); - - return refs_decl; -} - -static tree -build_category_initializer (type, cat_name, class_name, - instance_methods, class_methods, protocol_list) - tree type; - tree cat_name; - tree class_name; - tree instance_methods; - tree class_methods; - tree protocol_list; -{ - tree initlist = NULL_TREE, expr; - - initlist = tree_cons (NULL_TREE, cat_name, initlist); - initlist = tree_cons (NULL_TREE, class_name, initlist); - - if (!instance_methods) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, instance_methods, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - if (!class_methods) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, class_methods, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - /* protocol_list = */ - if (!protocol_list) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - static tree cast_type2; - - if (!cast_type2) - cast_type2 - = groktypename - (build_tree_list - (build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))), - build1 (INDIRECT_REF, NULL_TREE, - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)))); - - expr = build_unary_op (ADDR_EXPR, protocol_list, 0); - TREE_TYPE (expr) = cast_type2; - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - return build_constructor (type, nreverse (initlist)); -} - -/* struct objc_class { - struct objc_class *isa; - struct objc_class *super_class; - char *name; - long version; - long info; - long instance_size; - struct objc_ivar_list *ivars; - struct objc_method_list *methods; - if (flag_next_runtime) - struct objc_cache *cache; - else { - struct sarray *dtable; - struct objc_class *subclass_list; - struct objc_class *sibling_class; - } - struct objc_protocol_list *protocols; - void *gc_object_type; - }; */ - -static tree -build_shared_structure_initializer (type, isa, super, name, size, status, - dispatch_table, ivar_list, protocol_list) - tree type; - tree isa; - tree super; - tree name; - tree size; - int status; - tree dispatch_table; - tree ivar_list; - tree protocol_list; -{ - tree initlist = NULL_TREE, expr; - - /* isa = */ - initlist = tree_cons (NULL_TREE, isa, initlist); - - /* super_class = */ - initlist = tree_cons (NULL_TREE, super, initlist); - - /* name = */ - initlist = tree_cons (NULL_TREE, default_conversion (name), initlist); - - /* version = */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - - /* info = */ - initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist); - - /* instance_size = */ - initlist = tree_cons (NULL_TREE, size, initlist); - - /* objc_ivar_list = */ - if (!ivar_list) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, ivar_list, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - /* objc_method_list = */ - if (!dispatch_table) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, dispatch_table, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - if (flag_next_runtime) - /* method_cache = */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - /* dtable = */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - - /* subclass_list = */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - - /* sibling_class = */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - } - - /* protocol_list = */ - if (! protocol_list) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - static tree cast_type2; - - if (!cast_type2) - cast_type2 - = groktypename - (build_tree_list - (build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))), - build1 (INDIRECT_REF, NULL_TREE, - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)))); - - expr = build_unary_op (ADDR_EXPR, protocol_list, 0); - TREE_TYPE (expr) = cast_type2; - 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)); -} - -/* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */ - -static void -generate_category (cat) - tree cat; -{ - tree sc_spec, decl_specs, decl; - tree initlist, cat_name_expr, class_name_expr; - tree protocol_decl, category; - - add_class_reference (CLASS_NAME (cat)); - cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names); - - class_name_expr = add_objc_string (CLASS_NAME (cat), class_names); - - category = CLASS_CATEGORY_LIST (implementation_template); - - /* find the category interface from the class it is associated with */ - while (category) - { - if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category)) - break; - category = CLASS_CATEGORY_LIST (category); - } - - if (category && CLASS_PROTOCOL_LIST (category)) - { - generate_protocol_references (CLASS_PROTOCOL_LIST (category)); - protocol_decl = generate_protocol_list (category); - } - else - protocol_decl = 0; - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec); - - decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY", - implementation_context), - decl_specs, 1, NULL_TREE, NULL_TREE); - - initlist = build_category_initializer (TREE_TYPE (decl), - cat_name_expr, class_name_expr, - UOBJC_INSTANCE_METHODS_decl, - UOBJC_CLASS_METHODS_decl, - protocol_decl); - - TREE_USED (decl) = 1; - finish_decl (decl, initlist, NULL_TREE); -} - -/* static struct objc_class _OBJC_METACLASS_Foo={ ... }; - static struct objc_class _OBJC_CLASS_Foo={ ... }; */ - -static void -generate_shared_structures () -{ - tree sc_spec, decl_specs, decl; - tree name_expr, super_expr, root_expr; - tree my_root_id = NULL_TREE, my_super_id = NULL_TREE; - tree cast_type, initlist, protocol_decl; - - my_super_id = CLASS_SUPER_NAME (implementation_template); - if (my_super_id) - { - add_class_reference (my_super_id); - - /* Compute "my_root_id" - this is required for code generation. - the "isa" for all meta class structures points to the root of - the inheritance hierarchy (e.g. "__Object")... */ - my_root_id = my_super_id; - do - { - tree my_root_int = lookup_interface (my_root_id); - - if (my_root_int && CLASS_SUPER_NAME (my_root_int)) - my_root_id = CLASS_SUPER_NAME (my_root_int); - else - break; - } - while (1); - } - else - /* No super class. */ - my_root_id = CLASS_NAME (implementation_template); - - cast_type - = groktypename (build_tree_list (build_tree_list (NULL_TREE, - objc_class_template), - build1 (INDIRECT_REF, - NULL_TREE, NULL_TREE))); - - name_expr = add_objc_string (CLASS_NAME (implementation_template), - class_names); - - /* Install class `isa' and `super' pointers at runtime. */ - if (my_super_id) - { - super_expr = add_objc_string (my_super_id, class_names); - super_expr = build_c_cast (cast_type, super_expr); /* cast! */ - } - else - super_expr = build_int_2 (0, 0); - - root_expr = add_objc_string (my_root_id, class_names); - root_expr = build_c_cast (cast_type, root_expr); /* cast! */ - - if (CLASS_PROTOCOL_LIST (implementation_template)) - { - generate_protocol_references - (CLASS_PROTOCOL_LIST (implementation_template)); - protocol_decl = generate_protocol_list (implementation_template); - } - else - protocol_decl = 0; - - /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */ - - sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]); - decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec); - - decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1, - NULL_TREE, NULL_TREE); - - initlist - = build_shared_structure_initializer - (TREE_TYPE (decl), - root_expr, super_expr, name_expr, - build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template)) - / BITS_PER_UNIT), - 0), - 2 /*CLS_META*/, - UOBJC_CLASS_METHODS_decl, - UOBJC_CLASS_VARIABLES_decl, - protocol_decl); - - finish_decl (decl, initlist, NULL_TREE); - - /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */ - - decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1, - NULL_TREE, NULL_TREE); - - initlist - = build_shared_structure_initializer - (TREE_TYPE (decl), - build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0), - super_expr, name_expr, - build_int_2 - ((TREE_INT_CST_LOW - (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template))) - / BITS_PER_UNIT), - 0), - 1 /*CLS_FACTORY*/, - UOBJC_INSTANCE_METHODS_decl, - UOBJC_INSTANCE_VARIABLES_decl, - protocol_decl); - - finish_decl (decl, initlist, NULL_TREE); -} - -static tree -synth_id_with_class_suffix (preamble, ctxt) - char *preamble; - tree ctxt; -{ - char *string; - if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE - || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE) - { - char *class_name - = IDENTIFIER_POINTER (CLASS_NAME (implementation_context)); - string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3); - sprintf (string, "%s_%s", preamble, - IDENTIFIER_POINTER (CLASS_NAME (ctxt))); - } - else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE - || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE) - { - /* We have a category. */ - char *class_name - = IDENTIFIER_POINTER (CLASS_NAME (implementation_context)); - char *class_super_name - = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)); - string = (char *) alloca (strlen (preamble) - + strlen (class_name) - + strlen (class_super_name) - + 3); - sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name); - } - else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE) - { - char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt)); - string - = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3); - sprintf (string, "%s_%s", preamble, protocol_name); - } - else - abort (); - - return get_identifier (string); -} - -static int -is_objc_type_qualifier (node) - tree node; -{ - return (TREE_CODE (node) == IDENTIFIER_NODE - && (node == ridpointers [(int) RID_CONST] - || node == ridpointers [(int) RID_VOLATILE] - || node == ridpointers [(int) RID_IN] - || node == ridpointers [(int) RID_OUT] - || node == ridpointers [(int) RID_INOUT] - || node == ridpointers [(int) RID_BYCOPY] - || node == ridpointers [(int) RID_BYREF] - || node == ridpointers [(int) RID_ONEWAY])); -} - -/* If type is empty or only type qualifiers are present, add default - type of id (otherwise grokdeclarator will default to int). */ - -static tree -adjust_type_for_id_default (type) - tree type; -{ - tree declspecs, chain; - - if (!type) - return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference), - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)); - - declspecs = TREE_PURPOSE (type); - - /* Determine if a typespec is present. */ - for (chain = declspecs; - chain; - chain = TREE_CHAIN (chain)) - { - if (!is_objc_type_qualifier (TREE_VALUE (chain))) - return type; - } - - return build_tree_list (tree_cons (NULL_TREE, objc_object_reference, - declspecs), - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)); -} - -/* Usage: - keyworddecl: - selector ':' '(' typename ')' identifier - - Purpose: - Transform an Objective-C keyword argument into - the C equivalent parameter declarator. - - In: key_name, an "identifier_node" (optional). - arg_type, a "tree_list" (optional). - arg_name, an "identifier_node". - - Note: It would be really nice to strongly type the preceding - arguments in the function prototype; however, then I - could not use the "accessor" macros defined in "tree.h". - - Out: an instance of "keyword_decl". */ - -tree -build_keyword_decl (key_name, arg_type, arg_name) - tree key_name; - tree arg_type; - tree arg_name; -{ - tree keyword_decl; - - /* If no type is specified, default to "id". */ - arg_type = adjust_type_for_id_default (arg_type); - - keyword_decl = make_node (KEYWORD_DECL); - - TREE_TYPE (keyword_decl) = arg_type; - KEYWORD_ARG_NAME (keyword_decl) = arg_name; - KEYWORD_KEY_NAME (keyword_decl) = key_name; - - return keyword_decl; -} - -/* Given a chain of keyword_decl's, synthesize the full keyword selector. */ - -static tree -build_keyword_selector (selector) - tree selector; -{ - int len = 0; - tree key_chain, key_name; - char *buf; - - for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain)) - { - if (TREE_CODE (selector) == KEYWORD_DECL) - key_name = KEYWORD_KEY_NAME (key_chain); - else if (TREE_CODE (selector) == TREE_LIST) - key_name = TREE_PURPOSE (key_chain); - else - abort (); - - if (key_name) - len += IDENTIFIER_LENGTH (key_name) + 1; - else - /* Just a ':' arg. */ - len++; - } - - buf = (char *)alloca (len + 1); - bzero (buf, len + 1); - - for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain)) - { - if (TREE_CODE (selector) == KEYWORD_DECL) - key_name = KEYWORD_KEY_NAME (key_chain); - else if (TREE_CODE (selector) == TREE_LIST) - key_name = TREE_PURPOSE (key_chain); - else - abort (); - - if (key_name) - strcat (buf, IDENTIFIER_POINTER (key_name)); - strcat (buf, ":"); - } - - return get_identifier (buf); -} - -/* Used for declarations and definitions. */ - -tree -build_method_decl (code, ret_type, selector, add_args) - enum tree_code code; - tree ret_type; - tree selector; - tree add_args; -{ - tree method_decl; - - /* If no type is specified, default to "id". */ - ret_type = adjust_type_for_id_default (ret_type); - - method_decl = make_node (code); - TREE_TYPE (method_decl) = ret_type; - - /* If we have a keyword selector, create an identifier_node that - represents the full selector name (`:' included)... */ - if (TREE_CODE (selector) == KEYWORD_DECL) - { - METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector); - METHOD_SEL_ARGS (method_decl) = selector; - METHOD_ADD_ARGS (method_decl) = add_args; - } - else - { - METHOD_SEL_NAME (method_decl) = selector; - METHOD_SEL_ARGS (method_decl) = NULL_TREE; - METHOD_ADD_ARGS (method_decl) = NULL_TREE; - } - - return method_decl; -} - -#define METHOD_DEF 0 -#define METHOD_REF 1 - -/* Used by `build_message_expr' and `comp_method_types'. Return an - argument list for method METH. CONTEXT is either METHOD_DEF or - METHOD_REF, saying whether we are trying to define a method or call - one. SUPERFLAG says this is for a send to super; this makes a - difference for the NeXT calling sequence in which the lookup and - the method call are done together. */ - -static tree -get_arg_type_list (meth, context, superflag) - tree meth; - int context; - int superflag; -{ - tree arglist, akey; - - /* Receiver type. */ - if (flag_next_runtime && superflag) - arglist = build_tree_list (NULL_TREE, super_type); - else if (context == METHOD_DEF) - arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl)); - else - arglist = build_tree_list (NULL_TREE, id_type); - - /* Selector type - will eventually change to `int'. */ - chainon (arglist, build_tree_list (NULL_TREE, selector_type)); - - /* Build a list of argument types. */ - for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey)) - { - tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey)); - chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl))); - } - - if (METHOD_ADD_ARGS (meth) == (tree)1) - /* We have a `, ...' immediately following the selector, - finalize the arglist...simulate get_parm_info (0). */ - ; - else if (METHOD_ADD_ARGS (meth)) - { - /* we have a variable length selector */ - tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth)); - chainon (arglist, add_arg_list); - } - else - /* finalize the arglist...simulate get_parm_info (1) */ - chainon (arglist, build_tree_list (NULL_TREE, void_type_node)); - - return arglist; -} - -static tree -check_duplicates (hsh) - hash hsh; -{ - tree meth = NULL_TREE; - - if (hsh) - { - meth = hsh->key; - - if (hsh->list) - { - /* We have two methods with the same name and different types. */ - attr loop; - char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+'; - - warning ("multiple declarations for method `%s'", - IDENTIFIER_POINTER (METHOD_SEL_NAME (meth))); - - warn_with_method ("using", type, meth); - for (loop = hsh->list; loop; loop = loop->next) - warn_with_method ("also found", type, loop->value); - } - } - return meth; -} - -/* If RECEIVER is a class reference, return the identifier node for the - referenced class. RECEIVER is created by get_class_reference, so we - check the exact form created depending on which runtimes are used. */ - -static tree -receiver_is_class_object (receiver) - tree receiver; -{ - tree chain, exp, arg; - if (flag_next_runtime) - { - /* The receiver is a variable created by build_class_reference_decl. */ - if (TREE_CODE (receiver) == VAR_DECL - && TREE_TYPE (receiver) == objc_class_type) - /* Look up the identifier. */ - for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) - if (TREE_PURPOSE (chain) == receiver) - return TREE_VALUE (chain); - } - else - { - /* The receiver is a function call that returns an id. Check if - it is a call to objc_getClass, if so, pick up the class name. */ - if ((exp = TREE_OPERAND (receiver, 0)) - && TREE_CODE (exp) == ADDR_EXPR - && (exp = TREE_OPERAND (exp, 0)) - && TREE_CODE (exp) == FUNCTION_DECL - && exp == objc_get_class_decl - /* we have a call to objc_getClass! */ - && (arg = TREE_OPERAND (receiver, 1)) - && TREE_CODE (arg) == TREE_LIST - && (arg = TREE_VALUE (arg))) - { - STRIP_NOPS (arg); - if (TREE_CODE (arg) == ADDR_EXPR - && (arg = TREE_OPERAND (arg, 0)) - && TREE_CODE (arg) == STRING_CST) - /* Finally, we have the class name. */ - return get_identifier (TREE_STRING_POINTER (arg)); - } - } - return 0; -} - -/* If we are currently building a message expr, this holds - the identifier of the selector of the message. This is - used when printing warnings about argument mismatches. */ - -static tree building_objc_message_expr = 0; - -tree -maybe_building_objc_message_expr () -{ - return building_objc_message_expr; -} - -/* Construct an expression for sending a message. - MESS has the object to send to in TREE_PURPOSE - and the argument list (including selector) in TREE_VALUE. - - (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...); - (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */ - -tree -build_message_expr (mess) - tree mess; -{ - tree receiver = TREE_PURPOSE (mess); - tree selector, self_object; - tree rtype, sel_name; - tree args = TREE_VALUE (mess); - tree method_params = NULL_TREE; - tree method_prototype = NULL_TREE; - tree retval; - int statically_typed = 0, statically_allocated = 0; - tree class_ident = 0; - - /* 1 if this is sending to the superclass. */ - int super; - - if (!doing_objc_thang) - objc_fatal (); - - if (TREE_CODE (receiver) == ERROR_MARK) - return error_mark_node; - - /* Determine receiver type. */ - rtype = TREE_TYPE (receiver); - super = IS_SUPER (rtype); - - if (! super) - { - if (TREE_STATIC_TEMPLATE (rtype)) - statically_allocated = 1; - else if (TREE_CODE (rtype) == POINTER_TYPE - && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype))) - statically_typed = 1; - else if ((flag_next_runtime - || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype))) - && (class_ident = receiver_is_class_object (receiver))) - ; - else if (! IS_ID (rtype) - /* Allow any type that matches objc_class_type. */ - && ! comptypes (rtype, objc_class_type)) - { - bzero (errbuf, BUFSIZE); - warning ("invalid receiver type `%s'", - gen_declaration (rtype, errbuf)); - } - - if (statically_allocated) - receiver = build_unary_op (ADDR_EXPR, receiver, 0); - - /* Don't evaluate the receiver twice. */ - receiver = save_expr (receiver); - self_object = receiver; - } - else - /* If sending to `super', use current self as the object. */ - self_object = self_decl; - - /* Obtain the full selector name. */ - - if (TREE_CODE (args) == IDENTIFIER_NODE) - /* A unary selector. */ - sel_name = args; - else if (TREE_CODE (args) == TREE_LIST) - sel_name = build_keyword_selector (args); - else - abort (); - - /* Build the parameter list to give to the method. */ - - method_params = NULL_TREE; - if (TREE_CODE (args) == TREE_LIST) - { - tree chain = args, prev = NULL_TREE; - - /* We have a keyword selector--check for comma expressions. */ - while (chain) - { - tree element = TREE_VALUE (chain); - - /* We have a comma expression, must collapse... */ - if (TREE_CODE (element) == TREE_LIST) - { - if (prev) - TREE_CHAIN (prev) = element; - else - args = element; - } - prev = chain; - chain = TREE_CHAIN (chain); - } - method_params = args; - } - - /* Determine operation return type. */ - - if (IS_SUPER (rtype)) - { - tree iface; - - if (CLASS_SUPER_NAME (implementation_template)) - { - iface - = lookup_interface (CLASS_SUPER_NAME (implementation_template)); - - if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL) - method_prototype = lookup_instance_method_static (iface, sel_name); - else - method_prototype = lookup_class_method_static (iface, sel_name); - - if (iface && !method_prototype) - warning ("`%s' does not respond to `%s'", - IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)), - IDENTIFIER_POINTER (sel_name)); - } - else - { - error ("no super class declared in interface for `%s'", - IDENTIFIER_POINTER (CLASS_NAME (implementation_template))); - return error_mark_node; - } - - } - else if (statically_allocated) - { - tree ctype = TREE_TYPE (rtype); - tree iface = lookup_interface (TYPE_NAME (rtype)); - - if (iface) - method_prototype = lookup_instance_method_static (iface, sel_name); - - if (! method_prototype && TYPE_PROTOCOL_LIST (ctype)) - method_prototype - = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype), - sel_name, 0); - - if (!method_prototype) - warning ("`%s' does not respond to `%s'", - IDENTIFIER_POINTER (TYPE_NAME (rtype)), - IDENTIFIER_POINTER (sel_name)); - } - else if (statically_typed) - { - tree ctype = TREE_TYPE (rtype); - - /* `self' is now statically_typed. All methods should be visible - within the context of the implementation. */ - if (implementation_context - && CLASS_NAME (implementation_context) == TYPE_NAME (ctype)) - { - method_prototype - = lookup_instance_method_static (implementation_template, - sel_name); - - if (! method_prototype && TYPE_PROTOCOL_LIST (ctype)) - method_prototype - = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype), - sel_name, 0); - - if (! method_prototype - && implementation_template != implementation_context) - /* The method is not published in the interface. Check - locally. */ - method_prototype - = lookup_method (CLASS_NST_METHODS (implementation_context), - sel_name); - } - else - { - tree iface; - - if ((iface = lookup_interface (TYPE_NAME (ctype)))) - method_prototype = lookup_instance_method_static (iface, sel_name); - - if (! method_prototype) - { - tree protocol_list = TYPE_PROTOCOL_LIST (ctype); - if (protocol_list) - method_prototype - = lookup_method_in_protocol_list (protocol_list, - sel_name, 0); - } - } - - if (!method_prototype) - warning ("`%s' does not respond to `%s'", - IDENTIFIER_POINTER (TYPE_NAME (ctype)), - IDENTIFIER_POINTER (sel_name)); - } - else if (class_ident) - { - if (implementation_context - && CLASS_NAME (implementation_context) == class_ident) - { - method_prototype - = lookup_class_method_static (implementation_template, sel_name); - - if (!method_prototype - && implementation_template != implementation_context) - /* The method is not published in the interface. Check - locally. */ - method_prototype - = lookup_method (CLASS_CLS_METHODS (implementation_context), - sel_name); - } - else - { - tree iface; - - if ((iface = lookup_interface (class_ident))) - method_prototype = lookup_class_method_static (iface, sel_name); - } - - if (!method_prototype) - { - warning ("cannot find class (factory) method."); - warning ("return type for `%s' defaults to id", - IDENTIFIER_POINTER (sel_name)); - } - } - else if (IS_PROTOCOL_QUALIFIED_ID (rtype)) - { - /* An anonymous object that has been qualified with a protocol. */ - - tree protocol_list = TYPE_PROTOCOL_LIST (rtype); - - method_prototype = lookup_method_in_protocol_list (protocol_list, - sel_name, 0); - - if (!method_prototype) - { - hash hsh; - - warning ("method `%s' not implemented by protocol.", - IDENTIFIER_POINTER (sel_name)); - - /* Try and find the method signature in the global pools. */ - - if (!(hsh = hash_lookup (nst_method_hash_list, sel_name))) - hsh = hash_lookup (cls_method_hash_list, sel_name); - - if (!(method_prototype = check_duplicates (hsh))) - warning ("return type defaults to id"); - } - } - else - { - hash hsh; - - /* We think we have an instance...loophole: extern id Object; */ - hsh = hash_lookup (nst_method_hash_list, sel_name); - if (!hsh) - /* For various loopholes, like sending messages to self in a - factory context. */ - hsh = hash_lookup (cls_method_hash_list, sel_name); - - method_prototype = check_duplicates (hsh); - if (!method_prototype) - { - warning ("cannot find method."); - warning ("return type for `%s' defaults to id", - IDENTIFIER_POINTER (sel_name)); - } - } - - /* Save the selector name for printing error messages. */ - building_objc_message_expr = sel_name; - - /* Build the parameters list for looking up the method. - These are the object itself and the selector. */ - - if (flag_typed_selectors) - selector = build_typed_selector_reference (sel_name, method_prototype); - else - selector = build_selector_reference (sel_name); - - retval = build_objc_method_call (super, method_prototype, - receiver, self_object, - selector, method_params); - - building_objc_message_expr = 0; - - return retval; -} - -/* Build a tree expression to send OBJECT the operation SELECTOR, - looking up the method on object LOOKUP_OBJECT (often same as OBJECT), - assuming the method has prototype METHOD_PROTOTYPE. - (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.) - Use METHOD_PARAMS as list of args to pass to the method. - If SUPER_FLAG is nonzero, we look up the superclass's method. */ - -static tree -build_objc_method_call (super_flag, method_prototype, lookup_object, object, - selector, method_params) - int super_flag; - tree method_prototype, lookup_object, object, selector, method_params; -{ - tree sender = (super_flag ? umsg_super_decl : umsg_decl); - tree rcv_p = (super_flag - ? build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (TAG_SUPER))) - : id_type); - - if (flag_next_runtime) - { - if (! method_prototype) - { - method_params = tree_cons (NULL_TREE, lookup_object, - tree_cons (NULL_TREE, selector, - method_params)); - assemble_external (sender); - return build_function_call (sender, method_params); - } - else - { - /* This is a real kludge, but it is used only for the Next. - Clobber the data type of SENDER temporarily to accept - all the arguments for this operation, and to return - whatever this operation returns. */ - tree arglist = NULL_TREE; - tree retval; - - /* Save the proper contents of SENDER's data type. */ - tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender)); - tree savret = TREE_TYPE (TREE_TYPE (sender)); - - /* Install this method's argument types. */ - arglist = get_arg_type_list (method_prototype, METHOD_REF, - super_flag); - TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist; - - /* Install this method's return type. */ - TREE_TYPE (TREE_TYPE (sender)) - = groktypename (TREE_TYPE (method_prototype)); - - /* Call SENDER with all the parameters. This will do type - checking using the arg types for this method. */ - method_params = tree_cons (NULL_TREE, lookup_object, - tree_cons (NULL_TREE, selector, - method_params)); - assemble_external (sender); - retval = build_function_call (sender, method_params); - - /* Restore SENDER's return/argument types. */ - TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg; - TREE_TYPE (TREE_TYPE (sender)) = savret; - return retval; - } - } - else - { - /* This is the portable way. - First call the lookup function to get a pointer to the method, - then cast the pointer, then call it with the method arguments. */ - tree method; - - /* Avoid trouble since we may evaluate each of these twice. */ - object = save_expr (object); - selector = save_expr (selector); - - lookup_object = build_c_cast (rcv_p, lookup_object); - - assemble_external (sender); - method - = build_function_call (sender, - tree_cons (NULL_TREE, lookup_object, - tree_cons (NULL_TREE, selector, - NULL_TREE))); - - /* If we have a method prototype, construct the data type this - method needs, and cast what we got from SENDER into a pointer - to that type. */ - if (method_prototype) - { - tree arglist = get_arg_type_list (method_prototype, METHOD_REF, - super_flag); - tree valtype = groktypename (TREE_TYPE (method_prototype)); - tree fake_function_type = build_function_type (valtype, arglist); - TREE_TYPE (method) = build_pointer_type (fake_function_type); - } - else - TREE_TYPE (method) - = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE)); - - /* Pass the object to the method. */ - assemble_external (method); - return build_function_call (method, - tree_cons (NULL_TREE, object, - tree_cons (NULL_TREE, selector, - method_params))); - } -} - -static void -build_protocol_reference (p) - tree p; -{ - tree decl, ident, ptype; - - push_obstacks_nochange (); - end_temporary_allocation (); - - /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */ - - ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p); - ptype - = groktypename (build_tree_list (build_tree_list (NULL_TREE, - objc_protocol_template), - NULL_TREE)); - - if (IDENTIFIER_GLOBAL_VALUE (ident)) - decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */ - else - { - decl = build_decl (VAR_DECL, ident, ptype); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; - - make_decl_rtl (decl, 0, 1); - pushdecl_top_level (decl); - } - - PROTOCOL_FORWARD_DECL (p) = decl; - pop_obstacks (); -} - -tree -build_protocol_expr (protoname) - tree protoname; -{ - tree expr; - tree p; - - if (!doing_objc_thang) - objc_fatal (); - - p = lookup_protocol (protoname); - - if (!p) - { - error ("Cannot find protocol declaration for `%s'", - IDENTIFIER_POINTER (protoname)); - return error_mark_node; - } - - if (!PROTOCOL_FORWARD_DECL (p)) - build_protocol_reference (p); - - expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0); - - TREE_TYPE (expr) = protocol_type; - - return expr; -} - -tree -build_selector_expr (selnamelist) - tree selnamelist; -{ - tree selname; - - if (!doing_objc_thang) - objc_fatal (); - - /* Obtain the full selector name. */ - if (TREE_CODE (selnamelist) == IDENTIFIER_NODE) - /* A unary selector. */ - selname = selnamelist; - else if (TREE_CODE (selnamelist) == TREE_LIST) - selname = build_keyword_selector (selnamelist); - else - abort (); - - if (flag_typed_selectors) - return build_typed_selector_reference (selname, 0); - else - return build_selector_reference (selname); -} - -tree -build_encode_expr (type) - tree type; -{ - tree result; - char *string; - - if (!doing_objc_thang) - objc_fatal (); - - encode_type (type, obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - obstack_1grow (&util_obstack, 0); /* null terminate string */ - string = obstack_finish (&util_obstack); - - /* Synthesize a string that represents the encoded struct/union. */ - result = my_build_string (strlen (string) + 1, string); - obstack_free (&util_obstack, util_firstobj); - return result; -} - -tree -build_ivar_reference (id) - tree id; -{ - if (TREE_CODE (method_context) == CLASS_METHOD_DECL) - { - /* Historically, a class method that produced objects (factory - method) would assign `self' to the instance that it - allocated. This would effectively turn the class method into - an instance method. Following this assignment, the instance - variables could be accessed. That practice, while safe, - violates the simple rule that a class method should not refer - to an instance variable. It's better to catch the cases - where this is done unknowingly than to support the above - paradigm. */ - warning ("instance variable `%s' accessed in class method", - IDENTIFIER_POINTER (id)); - TREE_TYPE (self_decl) = instance_type; /* cast */ - } - - return build_component_ref (build_indirect_ref (self_decl, "->"), id); -} - -#define HASH_ALLOC_LIST_SIZE 170 -#define ATTR_ALLOC_LIST_SIZE 170 -#define SIZEHASHTABLE 257 - -/* make positive */ -#define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff) - -static void -hash_init () -{ - nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash)); - cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash)); - - if (!nst_method_hash_list || !cls_method_hash_list) - perror ("unable to allocate space in objc-tree.c"); - else - { - int i; - - for (i = 0; i < SIZEHASHTABLE; i++) - { - nst_method_hash_list[i] = 0; - cls_method_hash_list[i] = 0; - } - } -} - -static void -hash_enter (hashlist, method) - hash *hashlist; - tree method; -{ - static hash hash_alloc_list = 0; - static int hash_alloc_index = 0; - hash obj; - int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE; - - if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE) - { - hash_alloc_index = 0; - hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry) - * HASH_ALLOC_LIST_SIZE); - if (! hash_alloc_list) - perror ("unable to allocate in objc-tree.c"); - } - obj = &hash_alloc_list[hash_alloc_index++]; - obj->list = 0; - obj->next = hashlist[slot]; - obj->key = method; - - hashlist[slot] = obj; /* append to front */ -} - -static hash -hash_lookup (hashlist, sel_name) - hash *hashlist; - tree sel_name; -{ - hash target; - - target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE]; - - while (target) - { - if (sel_name == METHOD_SEL_NAME (target->key)) - return target; - - target = target->next; - } - return 0; -} - -static void -hash_add_attr (entry, value) - hash entry; - tree value; -{ - static attr attr_alloc_list = 0; - static int attr_alloc_index = 0; - attr obj; - - if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE) - { - attr_alloc_index = 0; - attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute) - * ATTR_ALLOC_LIST_SIZE); - if (! attr_alloc_list) - perror ("unable to allocate in objc-tree.c"); - } - obj = &attr_alloc_list[attr_alloc_index++]; - obj->next = entry->list; - obj->value = value; - - entry->list = obj; /* append to front */ -} - -static tree -lookup_method (mchain, method) - tree mchain; - tree method; -{ - tree key; - - if (TREE_CODE (method) == IDENTIFIER_NODE) - key = method; - else - key = METHOD_SEL_NAME (method); - - while (mchain) - { - if (METHOD_SEL_NAME (mchain) == key) - return mchain; - mchain = TREE_CHAIN (mchain); - } - return NULL_TREE; -} - -static tree -lookup_instance_method_static (interface, ident) - tree interface; - tree ident; -{ - tree inter = interface; - tree chain = CLASS_NST_METHODS (inter); - tree meth = NULL_TREE; - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - if (CLASS_CATEGORY_LIST (inter)) - { - tree category = CLASS_CATEGORY_LIST (inter); - chain = CLASS_NST_METHODS (category); - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - /* Check for instance methods in protocols in categories. */ - if (CLASS_PROTOCOL_LIST (category)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (category), ident, 0)))) - return meth; - } - - if ((category = CLASS_CATEGORY_LIST (category))) - chain = CLASS_NST_METHODS (category); - } - while (category); - } - - if (CLASS_PROTOCOL_LIST (inter)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (inter), ident, 0)))) - return meth; - } - - if ((inter = lookup_interface (CLASS_SUPER_NAME (inter)))) - chain = CLASS_NST_METHODS (inter); - } - while (inter); - - return meth; -} - -static tree -lookup_class_method_static (interface, ident) - tree interface; - tree ident; -{ - tree inter = interface; - tree chain = CLASS_CLS_METHODS (inter); - tree meth = NULL_TREE; - tree root_inter = NULL_TREE; - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - if (CLASS_CATEGORY_LIST (inter)) - { - tree category = CLASS_CATEGORY_LIST (inter); - chain = CLASS_CLS_METHODS (category); - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - /* Check for class methods in protocols in categories. */ - if (CLASS_PROTOCOL_LIST (category)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (category), ident, 1)))) - return meth; - } - - if ((category = CLASS_CATEGORY_LIST (category))) - chain = CLASS_CLS_METHODS (category); - } - while (category); - } - - /* Check for class methods in protocols. */ - if (CLASS_PROTOCOL_LIST (inter)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (inter), ident, 1)))) - return meth; - } - - root_inter = inter; - if ((inter = lookup_interface (CLASS_SUPER_NAME (inter)))) - chain = CLASS_CLS_METHODS (inter); - } - while (inter); - - /* Simulate wrap around. */ - return lookup_instance_method_static (root_inter, ident); -} - -tree -add_class_method (class, method) - tree class; - tree method; -{ - tree mth; - hash hsh; - - /* We will have allocated the method parameter declarations on the - maybepermanent_obstack. Need to make sure they stick around! */ - preserve_data (); - - if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method))) - { - /* put method on list in reverse order */ - TREE_CHAIN (method) = CLASS_CLS_METHODS (class); - CLASS_CLS_METHODS (class) = method; - } - else - { - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - error ("duplicate definition of class method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - else - { - /* Check types; if different, complain. */ - if (!comp_proto_with_proto (method, mth)) - error ("duplicate declaration of class method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - } - } - - if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method)))) - { - /* Install on a global chain. */ - hash_enter (cls_method_hash_list, method); - } - else - { - /* Check types; if different, add to a list. */ - if (!comp_proto_with_proto (method, hsh->key)) - hash_add_attr (hsh, method); - } - return method; -} - -tree -add_instance_method (class, method) - tree class; - tree method; -{ - tree mth; - hash hsh; - - /* We will have allocated the method parameter declarations on the - maybepermanent_obstack. Need to make sure they stick around! */ - preserve_data (); - - if (!(mth = lookup_method (CLASS_NST_METHODS (class), method))) - { - /* Put method on list in reverse order. */ - TREE_CHAIN (method) = CLASS_NST_METHODS (class); - CLASS_NST_METHODS (class) = method; - } - else - { - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - error ("duplicate definition of instance method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - else - { - /* Check types; if different, complain. */ - if (!comp_proto_with_proto (method, mth)) - error ("duplicate declaration of instance method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - } - } - - if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method)))) - { - /* Install on a global chain. */ - hash_enter (nst_method_hash_list, method); - } - else - { - /* Check types; if different, add to a list. */ - if (!comp_proto_with_proto (method, hsh->key)) - hash_add_attr (hsh, method); - } - return method; -} - -static tree -add_class (class) - tree class; -{ - /* Put interfaces on list in reverse order. */ - TREE_CHAIN (class) = interface_chain; - interface_chain = class; - return interface_chain; -} - -static void -add_category (class, category) - tree class; - tree category; -{ - /* Put categories on list in reverse order. */ - tree cat = CLASS_CATEGORY_LIST (class); - - while (cat) - { - if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category)) - warning ("duplicate interface declaration for category `%s(%s)'", - IDENTIFIER_POINTER (CLASS_NAME (class)), - IDENTIFIER_POINTER (CLASS_SUPER_NAME (category))); - cat = CLASS_CATEGORY_LIST (cat); - } - - CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class); - CLASS_CATEGORY_LIST (class) = category; -} - -/* Called after parsing each instance variable declaration. Necessary to - preserve typedefs and implement public/private... - - PUBLIC is 1 for public, 0 for protected, and 2 for private. */ - -tree -add_instance_variable (class, public, declarator, declspecs, width) - tree class; - int public; - tree declarator; - tree declspecs; - tree width; -{ - tree field_decl, raw_decl; - - raw_decl = build_tree_list (declspecs, declarator); - - if (CLASS_RAW_IVARS (class)) - chainon (CLASS_RAW_IVARS (class), raw_decl); - else - CLASS_RAW_IVARS (class) = raw_decl; - - field_decl = grokfield (input_filename, lineno, - declarator, declspecs, width); - - /* Overload the public attribute, it is not used for FIELD_DECLs. */ - switch (public) - { - case 0: - TREE_PUBLIC (field_decl) = 0; - TREE_PRIVATE (field_decl) = 0; - TREE_PROTECTED (field_decl) = 1; - break; - - case 1: - TREE_PUBLIC (field_decl) = 1; - TREE_PRIVATE (field_decl) = 0; - TREE_PROTECTED (field_decl) = 0; - break; - - case 2: - TREE_PUBLIC (field_decl) = 0; - TREE_PRIVATE (field_decl) = 1; - TREE_PROTECTED (field_decl) = 0; - break; - - } - - if (CLASS_IVARS (class)) - chainon (CLASS_IVARS (class), field_decl); - else - CLASS_IVARS (class) = field_decl; - - return class; -} - -tree -is_ivar (decl_chain, ident) - tree decl_chain; - tree ident; -{ - for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain)) - if (DECL_NAME (decl_chain) == ident) - return decl_chain; - return NULL_TREE; -} - -/* True if the ivar is private and we are not in its implementation. */ - -int -is_private (decl) - tree decl; -{ - if (TREE_PRIVATE (decl) - && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl))) - { - error ("instance variable `%s' is declared private", - IDENTIFIER_POINTER (DECL_NAME (decl))); - return 1; - } - else - return 0; -} - -/* We have an instance variable reference;, check to see if it is public. */ - -int -is_public (expr, identifier) - tree expr; - tree identifier; -{ - tree basetype = TREE_TYPE (expr); - enum tree_code code = TREE_CODE (basetype); - tree decl; - - if (code == RECORD_TYPE) - { - if (TREE_STATIC_TEMPLATE (basetype)) - { - if (!lookup_interface (TYPE_NAME (basetype))) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (TYPE_NAME (basetype))); - return 0; - } - - if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier))) - { - if (TREE_PUBLIC (decl)) - return 1; - - /* Important difference between the Stepstone translator: - all instance variables should be public within the context - of the implementation. */ - if (implementation_context - && (((TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - || (TREE_CODE (implementation_context) - == CATEGORY_IMPLEMENTATION_TYPE)) - && (CLASS_NAME (implementation_context) - == TYPE_NAME (basetype)))) - return ! is_private (decl); - - error ("instance variable `%s' is declared %s", - IDENTIFIER_POINTER (identifier), - TREE_PRIVATE (decl) ? "private" : "protected"); - return 0; - } - } - - else if (implementation_context && (basetype == objc_object_reference)) - { - TREE_TYPE (expr) = uprivate_record; - warning ("static access to object of type `id'"); - } - } - - return 1; -} - -/* Implement @defs (<classname>) within struct bodies. */ - -tree -get_class_ivars (interface) - tree interface; -{ - if (!doing_objc_thang) - objc_fatal (); - - return build_ivar_chain (interface, 1); -} - -/* Make sure all entries in CHAIN are also in LIST. */ - -static int -check_methods (chain, list, mtype) - tree chain; - tree list; - int mtype; -{ - int first = 1; - - while (chain) - { - if (!lookup_method (list, chain)) - { - if (first) - { - if (TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of class `%s'", - IDENTIFIER_POINTER (CLASS_NAME (implementation_context))); - else if (TREE_CODE (implementation_context) - == CATEGORY_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of category `%s'", - IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))); - first = 0; - } - - warning ("method definition for `%c%s' not found", - mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain))); - } - - chain = TREE_CHAIN (chain); - } - - return first; -} - -static int -conforms_to_protocol (class, protocol) - tree class; - tree protocol; -{ - while (protocol) - { - tree p = CLASS_PROTOCOL_LIST (class); - - while (p && TREE_VALUE (p) != TREE_VALUE (protocol)) - p = TREE_CHAIN (p); - - if (!p) - { - tree super = (CLASS_SUPER_NAME (class) - ? lookup_interface (CLASS_SUPER_NAME (class)) - : NULL_TREE); - int tmp = super ? conforms_to_protocol (super, protocol) : 0; - if (!tmp) - return 0; - } - - protocol = TREE_CHAIN (protocol); - } - - return 1; -} - -/* Make sure all methods in CHAIN are accessible as MTYPE methods in - CONTEXT. This is one of two mechanisms to check protocol integrity. */ - -static int -check_methods_accessible (chain, context, mtype) - tree chain; - tree context; - int mtype; -{ - int first = 1; - tree list; - tree base_context = context; - - while (chain) - { - context = base_context; - while (context) - { - if (mtype == '+') - list = CLASS_CLS_METHODS (context); - else - list = CLASS_NST_METHODS (context); - - if (lookup_method (list, chain)) - break; - - else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE - || TREE_CODE (context) == CLASS_INTERFACE_TYPE) - context = (CLASS_SUPER_NAME (context) - ? lookup_interface (CLASS_SUPER_NAME (context)) - : NULL_TREE); - - else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE - || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE) - context = (CLASS_NAME (context) - ? lookup_interface (CLASS_NAME (context)) - : NULL_TREE); - else - abort (); - } - - if (context == NULL_TREE) - { - if (first) - { - if (TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of class `%s'", - IDENTIFIER_POINTER - (CLASS_NAME (implementation_context))); - else if (TREE_CODE (implementation_context) - == CATEGORY_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of category `%s'", - IDENTIFIER_POINTER - (CLASS_SUPER_NAME (implementation_context))); - first = 0; - } - warning ("method definition for `%c%s' not found", - mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain))); - } - - chain = TREE_CHAIN (chain); /* next method... */ - } - return first; -} - -static void -check_protocols (proto_list, type, name) - tree proto_list; - char *type; - char *name; -{ - for ( ; proto_list; proto_list = TREE_CHAIN (proto_list)) - { - tree p = TREE_VALUE (proto_list); - - if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) - { - int f1, f2; - - /* Ensure that all protocols have bodies. */ - if (flag_warn_protocol) { - f1 = check_methods (PROTOCOL_CLS_METHODS (p), - CLASS_CLS_METHODS (implementation_context), - '+'); - f2 = check_methods (PROTOCOL_NST_METHODS (p), - CLASS_NST_METHODS (implementation_context), - '-'); - } else { - f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p), - implementation_context, - '+'); - f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p), - implementation_context, - '-'); - } - - if (!f1 || !f2) - warning ("%s `%s' does not fully implement the `%s' protocol", - type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - - } - else - { - ; /* An identifier if we could not find a protocol. */ - } - - /* Check protocols recursively. */ - if (PROTOCOL_LIST (p)) - { - tree super_class - = lookup_interface (CLASS_SUPER_NAME (implementation_template)); - if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p))) - check_protocols (PROTOCOL_LIST (p), type, name); - } - } -} - -/* Make sure that the class CLASS_NAME is defined - CODE says which kind of thing CLASS_NAME ought to be. - It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE, - CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. - - If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange - whose matching pop is in continue_class. */ - -tree -start_class (code, class_name, super_name, protocol_list) - enum tree_code code; - tree class_name; - tree super_name; - tree protocol_list; -{ - tree class, decl; - - if (code == CLASS_INTERFACE_TYPE) - { - push_obstacks_nochange (); - end_temporary_allocation (); - } - - if (!doing_objc_thang) - objc_fatal (); - - class = make_node (code); - TYPE_BINFO (class) = make_tree_vec (5); - - CLASS_NAME (class) = class_name; - CLASS_SUPER_NAME (class) = super_name; - CLASS_CLS_METHODS (class) = NULL_TREE; - - if (! is_class_name (class_name) && (decl = lookup_name (class_name))) - { - error ("`%s' redeclared as different kind of symbol", - IDENTIFIER_POINTER (class_name)); - error_with_decl (decl, "previous declaration of `%s'"); - } - - if (code == CLASS_IMPLEMENTATION_TYPE) - { - { - static tree implemented_classes = 0; - tree chain = implemented_classes; - for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain)) - if (TREE_VALUE (chain) == class_name) - { - error ("reimplementation of class `%s'", - IDENTIFIER_POINTER (class_name)); - return error_mark_node; - } - implemented_classes = perm_tree_cons (NULL_TREE, class_name, - implemented_classes); - } - - /* Pre-build the following entities - for speed/convenience. */ - if (!self_id) - self_id = get_identifier ("self"); - if (!ucmd_id) - ucmd_id = get_identifier ("_cmd"); - if (!unused_list) - unused_list - = build_tree_list (get_identifier ("__unused__"), NULL_TREE); - if (!objc_super_template) - objc_super_template = build_super_template (); - - /* Reset for multiple classes per file. */ - method_slot = 0; - - implementation_context = class; - - /* Lookup the interface for this implementation. */ - - if (!(implementation_template = lookup_interface (class_name))) - { - warning ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (class_name)); - add_class (implementation_template = implementation_context); - } - - /* If a super class has been specified in the implementation, - insure it conforms to the one specified in the interface. */ - - if (super_name - && (super_name != CLASS_SUPER_NAME (implementation_template))) - { - tree previous_name = CLASS_SUPER_NAME (implementation_template); - char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : ""; - error ("conflicting super class name `%s'", - IDENTIFIER_POINTER (super_name)); - error ("previous declaration of `%s'", name); - } - - else if (! super_name) - { - CLASS_SUPER_NAME (implementation_context) - = CLASS_SUPER_NAME (implementation_template); - } - } - - else if (code == CLASS_INTERFACE_TYPE) - { - if (lookup_interface (class_name)) - warning ("duplicate interface declaration for class `%s'", - IDENTIFIER_POINTER (class_name)); - else - add_class (class); - - if (protocol_list) - CLASS_PROTOCOL_LIST (class) - = lookup_and_install_protocols (protocol_list); - } - - else if (code == CATEGORY_INTERFACE_TYPE) - { - tree class_category_is_assoc_with; - - /* For a category, class_name is really the name of the class that - the following set of methods will be associated with. We must - find the interface so that can derive the objects template. */ - - if (!(class_category_is_assoc_with = lookup_interface (class_name))) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (class_name)); - exit (FATAL_EXIT_CODE); - } - else - add_category (class_category_is_assoc_with, class); - - if (protocol_list) - CLASS_PROTOCOL_LIST (class) - = lookup_and_install_protocols (protocol_list); - } - - else if (code == CATEGORY_IMPLEMENTATION_TYPE) - { - /* Pre-build the following entities for speed/convenience. */ - if (!self_id) - self_id = get_identifier ("self"); - if (!ucmd_id) - ucmd_id = get_identifier ("_cmd"); - if (!unused_list) - unused_list - = build_tree_list (get_identifier ("__unused__"), NULL_TREE); - if (!objc_super_template) - objc_super_template = build_super_template (); - - /* Reset for multiple classes per file. */ - method_slot = 0; - - implementation_context = class; - - /* For a category, class_name is really the name of the class that - the following set of methods will be associated with. We must - find the interface so that can derive the objects template. */ - - if (!(implementation_template = lookup_interface (class_name))) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (class_name)); - exit (FATAL_EXIT_CODE); - } - } - return class; -} - -tree -continue_class (class) - tree class; -{ - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE - || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE) - { - struct imp_entry *imp_entry; - tree ivar_context; - - /* Check consistency of the instance variables. */ - - if (CLASS_IVARS (class)) - check_ivars (implementation_template, class); - - /* code generation */ - - ivar_context = build_private_template (implementation_template); - - if (!objc_class_template) - build_class_template (); - - if (!(imp_entry - = (struct imp_entry *) xmalloc (sizeof (struct imp_entry)))) - perror ("unable to allocate in objc-tree.c"); - - imp_entry->next = imp_list; - imp_entry->imp_context = class; - imp_entry->imp_template = implementation_template; - - synth_forward_declarations (); - imp_entry->class_decl = UOBJC_CLASS_decl; - imp_entry->meta_decl = UOBJC_METACLASS_decl; - - /* Append to front and increment count. */ - imp_list = imp_entry; - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - imp_count++; - else - cat_count++; - - return ivar_context; - } - - else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE) - { - tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class)); - - if (!TYPE_FIELDS (record)) - { - finish_struct (record, build_ivar_chain (class, 0), NULL_TREE); - CLASS_STATIC_TEMPLATE (class) = record; - - /* Mark this record as a class template for static typing. */ - TREE_STATIC_TEMPLATE (record) = 1; - } - - return NULL_TREE; - } - - else - return error_mark_node; -} - -/* This is called once we see the "@end" in an interface/implementation. */ - -void -finish_class (class) - tree class; -{ - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - { - /* All code generation is done in finish_objc. */ - - if (implementation_template != implementation_context) - { - /* Ensure that all method listed in the interface contain bodies. */ - check_methods (CLASS_CLS_METHODS (implementation_template), - CLASS_CLS_METHODS (implementation_context), '+'); - check_methods (CLASS_NST_METHODS (implementation_template), - CLASS_NST_METHODS (implementation_context), '-'); - - if (CLASS_PROTOCOL_LIST (implementation_template)) - check_protocols (CLASS_PROTOCOL_LIST (implementation_template), - "class", - IDENTIFIER_POINTER (CLASS_NAME (implementation_context))); - } - } - - else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE) - { - tree category = CLASS_CATEGORY_LIST (implementation_template); - - /* Find the category interface from the class it is associated with. */ - while (category) - { - if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category)) - break; - category = CLASS_CATEGORY_LIST (category); - } - - if (category) - { - /* Ensure all method listed in the interface contain bodies. */ - check_methods (CLASS_CLS_METHODS (category), - CLASS_CLS_METHODS (implementation_context), '+'); - check_methods (CLASS_NST_METHODS (category), - CLASS_NST_METHODS (implementation_context), '-'); - - if (CLASS_PROTOCOL_LIST (category)) - check_protocols (CLASS_PROTOCOL_LIST (category), - "category", - IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))); - } - } - - else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE) - { - tree decl_specs; - char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class)); - char *string = (char *) alloca (strlen (class_name) + 3); - - /* extern struct objc_object *_<my_name>; */ - - sprintf (string, "_%s", class_name); - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]); - decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs); - define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)), - decl_specs); - } -} - -static tree -add_protocol (protocol) - tree protocol; -{ - /* Put protocol on list in reverse order. */ - TREE_CHAIN (protocol) = protocol_chain; - protocol_chain = protocol; - return protocol_chain; -} - -static tree -lookup_protocol (ident) - tree ident; -{ - tree chain; - - for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == PROTOCOL_NAME (chain)) - return chain; - } - - return NULL_TREE; -} - -tree -start_protocol (code, name, list) - enum tree_code code; - tree name; - tree list; -{ - tree protocol; - - if (!doing_objc_thang) - objc_fatal (); - - /* This is as good a place as any. Need to invoke push_tag_toplevel. */ - if (!objc_protocol_template) - objc_protocol_template = build_protocol_template (); - - protocol = make_node (code); - TYPE_BINFO (protocol) = make_tree_vec (2); - - PROTOCOL_NAME (protocol) = name; - PROTOCOL_LIST (protocol) = list; - - lookup_and_install_protocols (list); - - if (lookup_protocol (name)) - warning ("duplicate declaration for protocol `%s'", - IDENTIFIER_POINTER (name)); - else - add_protocol (protocol); - - PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE; - - return protocol; -} - -void -finish_protocol (protocol) - tree protocol ATTRIBUTE_UNUSED; -{ -} - - -/* "Encode" a data type into a string, which grows in util_obstack. - ??? What is the FORMAT? Someone please document this! */ - -static void -encode_type_qualifiers (declspecs) - tree declspecs; -{ - tree spec; - - for (spec = declspecs; spec; spec = TREE_CHAIN (spec)) - { - if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'r'); - else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'n'); - else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'N'); - else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'o'); - else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'O'); - else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'R'); - else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'V'); - } -} - -/* Encode a pointer type. */ - -static void -encode_pointer (type, curtype, format) - tree type; - int curtype; - int format; -{ - tree pointer_to = TREE_TYPE (type); - - if (TREE_CODE (pointer_to) == RECORD_TYPE) - { - if (TYPE_NAME (pointer_to) - && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE) - { - char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to)); - - if (strcmp (name, TAG_OBJECT) == 0) /* '@' */ - { - obstack_1grow (&util_obstack, '@'); - return; - } - else if (TREE_STATIC_TEMPLATE (pointer_to)) - { - if (generating_instance_variables) - { - obstack_1grow (&util_obstack, '@'); - obstack_1grow (&util_obstack, '"'); - obstack_grow (&util_obstack, name, strlen (name)); - obstack_1grow (&util_obstack, '"'); - return; - } - else - { - obstack_1grow (&util_obstack, '@'); - return; - } - } - else if (strcmp (name, TAG_CLASS) == 0) /* '#' */ - { - obstack_1grow (&util_obstack, '#'); - return; - } -#ifndef OBJC_INT_SELECTORS - else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */ - { - obstack_1grow (&util_obstack, ':'); - return; - } -#endif /* OBJC_INT_SELECTORS */ - } - } - else if (TREE_CODE (pointer_to) == INTEGER_TYPE - && TYPE_MODE (pointer_to) == QImode) - { - obstack_1grow (&util_obstack, '*'); - return; - } - - /* We have a type that does not get special treatment. */ - - /* NeXT extension */ - obstack_1grow (&util_obstack, '^'); - encode_type (pointer_to, curtype, format); -} - -static void -encode_array (type, curtype, format) - tree type; - int curtype; - int format; -{ - tree an_int_cst = TYPE_SIZE (type); - tree array_of = TREE_TYPE (type); - char buffer[40]; - - /* An incomplete array is treated like a pointer. */ - if (an_int_cst == NULL) - { - encode_pointer (type, curtype, format); - return; - } - - sprintf (buffer, "[%ld", - (long) (TREE_INT_CST_LOW (an_int_cst) - / TREE_INT_CST_LOW (TYPE_SIZE (array_of)))); - - obstack_grow (&util_obstack, buffer, strlen (buffer)); - encode_type (array_of, curtype, format); - obstack_1grow (&util_obstack, ']'); - return; -} - -static void -encode_aggregate_within (type, curtype, format, left, right) - tree type; - int curtype; - int format; - int left; - int right; -{ - if (obstack_object_size (&util_obstack) > 0 - && *(obstack_next_free (&util_obstack) - 1) == '^') - { - tree name = TYPE_NAME (type); - - /* we have a reference; this is a NeXT extension. */ - - if (obstack_object_size (&util_obstack) - curtype == 1 - && format == OBJC_ENCODE_INLINE_DEFS) - { - /* Output format of struct for first level only. */ - tree fields = TYPE_FIELDS (type); - - if (name && TREE_CODE (name) == IDENTIFIER_NODE) - { - obstack_1grow (&util_obstack, left); - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - obstack_1grow (&util_obstack, '='); - } - else - { - obstack_1grow (&util_obstack, left); - obstack_grow (&util_obstack, "?=", 2); - } - - for ( ; fields; fields = TREE_CHAIN (fields)) - encode_field_decl (fields, curtype, format); - - obstack_1grow (&util_obstack, right); - } - - else if (name && TREE_CODE (name) == IDENTIFIER_NODE) - { - obstack_1grow (&util_obstack, left); - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - obstack_1grow (&util_obstack, right); - } - - else - { - /* We have an untagged structure or a typedef. */ - obstack_1grow (&util_obstack, left); - obstack_1grow (&util_obstack, '?'); - obstack_1grow (&util_obstack, right); - } - } - - else - { - tree name = TYPE_NAME (type); - tree fields = TYPE_FIELDS (type); - - if (format == OBJC_ENCODE_INLINE_DEFS - || generating_instance_variables) - { - obstack_1grow (&util_obstack, left); - if (name && TREE_CODE (name) == IDENTIFIER_NODE) - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - else - obstack_1grow (&util_obstack, '?'); - - obstack_1grow (&util_obstack, '='); - - for (; fields; fields = TREE_CHAIN (fields)) - { - if (generating_instance_variables) - { - tree fname = DECL_NAME (fields); - - obstack_1grow (&util_obstack, '"'); - if (fname && TREE_CODE (fname) == IDENTIFIER_NODE) - { - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (fname), - strlen (IDENTIFIER_POINTER (fname))); - } - - obstack_1grow (&util_obstack, '"'); - } - - encode_field_decl (fields, curtype, format); - } - - obstack_1grow (&util_obstack, right); - } - - else - { - obstack_1grow (&util_obstack, left); - if (name && TREE_CODE (name) == IDENTIFIER_NODE) - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - else - /* We have an untagged structure or a typedef. */ - obstack_1grow (&util_obstack, '?'); - - obstack_1grow (&util_obstack, right); - } - } -} - -static void -encode_aggregate (type, curtype, format) - tree type; - int curtype; - int format; -{ - enum tree_code code = TREE_CODE (type); - - switch (code) - { - case RECORD_TYPE: - { - encode_aggregate_within(type, curtype, format, '{', '}'); - break; - } - case UNION_TYPE: - { - encode_aggregate_within(type, curtype, format, '(', ')'); - break; - } - - case ENUMERAL_TYPE: - obstack_1grow (&util_obstack, 'i'); - break; - - default: - break; - } -} - -/* Support bitfields. The current version of Objective-C does not support - them. The string will consist of one or more "b:n"'s where n is an - integer describing the width of the bitfield. Currently, classes in - the kit implement a method "-(char *)describeBitfieldStruct:" that - simulates this. If they do not implement this method, the archiver - assumes the bitfield is 16 bits wide (padded if necessary) and packed - according to the GNU compiler. After looking at the "kit", it appears - that all classes currently rely on this default behavior, rather than - hand generating this string (which is tedious). */ - -static void -encode_bitfield (width, format) - int width; - int format; -{ - char buffer[40]; - sprintf (buffer, "b%d", width); - obstack_grow (&util_obstack, buffer, strlen (buffer)); -} - -/* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */ - -static void -encode_type (type, curtype, format) - tree type; - int curtype; - int format; -{ - enum tree_code code = TREE_CODE (type); - - 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) - obstack_1grow (&util_obstack, 'C'); - else if (TYPE_MODE (type) == HImode) - obstack_1grow (&util_obstack, 'S'); - else if (TYPE_MODE (type) == SImode) - { - if (type == long_unsigned_type_node) - obstack_1grow (&util_obstack, 'L'); - else - obstack_1grow (&util_obstack, 'I'); - } - else if (TYPE_MODE (type) == DImode) - obstack_1grow (&util_obstack, 'Q'); - } - - else - /* Signed integer types. */ - { - if (TYPE_MODE (type) == QImode) - obstack_1grow (&util_obstack, 'c'); - else if (TYPE_MODE (type) == HImode) - obstack_1grow (&util_obstack, 's'); - else if (TYPE_MODE (type) == SImode) - { - if (type == long_integer_type_node) - obstack_1grow (&util_obstack, 'l'); - else - obstack_1grow (&util_obstack, 'i'); - } - - else if (TYPE_MODE (type) == DImode) - obstack_1grow (&util_obstack, 'q'); - } - } - - else if (code == REAL_TYPE) - { - /* Floating point types. */ - - if (TYPE_MODE (type) == SFmode) - obstack_1grow (&util_obstack, 'f'); - else if (TYPE_MODE (type) == DFmode - || TYPE_MODE (type) == TFmode) - obstack_1grow (&util_obstack, 'd'); - } - - else if (code == VOID_TYPE) - obstack_1grow (&util_obstack, 'v'); - - else if (code == ARRAY_TYPE) - encode_array (type, curtype, format); - - else if (code == POINTER_TYPE) - encode_pointer (type, curtype, format); - - else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE) - encode_aggregate (type, curtype, format); - - else if (code == FUNCTION_TYPE) /* '?' */ - obstack_1grow (&util_obstack, '?'); -} - -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; - int format; -{ - 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 -expr_last (complex_expr) - tree complex_expr; -{ - tree next; - - if (complex_expr) - while ((next = TREE_OPERAND (complex_expr, 0))) - complex_expr = next; - - return complex_expr; -} - -/* The selector of the current method, - or NULL if we aren't compiling a method. */ - -tree -maybe_objc_method_name (decl) - tree decl; -{ - if (method_context) - return METHOD_SEL_NAME (method_context); - else - return 0; -} - -/* Transform a method definition into a function definition as follows: - - synthesize the first two arguments, "self" and "_cmd". */ - -void -start_method_def (method) - tree method; -{ - tree decl_specs; - - /* Required to implement _msgSuper. */ - method_context = method; - UOBJC_SUPER_decl = NULL_TREE; - - /* Must be called BEFORE start_function. */ - pushlevel (0); - - /* Generate prototype declarations for arguments..."new-style". */ - - if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL) - decl_specs = build_tree_list (NULL_TREE, uprivate_record); - else - /* Really a `struct objc_class *'. However, we allow people to - assign to self, which changes its type midstream. */ - decl_specs = build_tree_list (NULL_TREE, objc_object_reference); - - push_parm_decl (build_tree_list - (build_tree_list (decl_specs, - build1 (INDIRECT_REF, NULL_TREE, self_id)), - build_tree_list (unused_list, NULL_TREE))); - -#ifdef OBJC_INT_SELECTORS - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs); - push_parm_decl (build_tree_list (build_tree_list (decl_specs, ucmd_id), - build_tree_list (unused_list, NULL_TREE))); -#else /* not OBJC_INT_SELECTORS */ - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); - push_parm_decl (build_tree_list - (build_tree_list (decl_specs, - build1 (INDIRECT_REF, NULL_TREE, ucmd_id)), - build_tree_list (unused_list, NULL_TREE))); -#endif /* not OBJC_INT_SELECTORS */ - - /* Generate argument declarations if a keyword_decl. */ - if (METHOD_SEL_ARGS (method)) - { - tree arglist = METHOD_SEL_ARGS (method); - do - { - tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist)); - tree arg_decl = TREE_VALUE (TREE_TYPE (arglist)); - - if (arg_decl) - { - tree last_expr = expr_last (arg_decl); - - /* Unite the abstract decl with its name. */ - TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist); - push_parm_decl (build_tree_list - (build_tree_list (arg_spec, arg_decl), - build_tree_list (NULL_TREE, NULL_TREE))); - - /* Unhook: restore the abstract declarator. */ - TREE_OPERAND (last_expr, 0) = NULL_TREE; - } - - else - push_parm_decl (build_tree_list - (build_tree_list (arg_spec, - KEYWORD_ARG_NAME (arglist)), - build_tree_list (NULL_TREE, NULL_TREE))); - - arglist = TREE_CHAIN (arglist); - } - while (arglist); - } - - if (METHOD_ADD_ARGS (method) > (tree)1) - { - /* We have a variable length selector - in "prototype" format. */ - tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method)); - while (akey) - { - /* This must be done prior to calling pushdecl. pushdecl is - going to change our chain on us. */ - tree nextkey = TREE_CHAIN (akey); - pushdecl (akey); - akey = nextkey; - } - } -} - -static void -warn_with_method (message, mtype, method) - char *message; - int mtype; - tree method; -{ - if (count_error (1) == 0) - return; - - report_error_function (DECL_SOURCE_FILE (method)); - - fprintf (stderr, "%s:%d: warning: ", - DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method)); - bzero (errbuf, BUFSIZE); - fprintf (stderr, "%s `%c%s'\n", - message, mtype, gen_method_decl (method, errbuf)); -} - -/* Return 1 if METHOD is consistent with PROTO. */ - -static int -comp_method_with_proto (method, proto) - tree method, proto; -{ - static tree function_type = 0; - - /* Create a function_type node once. */ - if (!function_type) - { - push_obstacks_nochange (); - end_temporary_allocation (); - function_type = make_node (FUNCTION_TYPE); - pop_obstacks (); - } - - /* Install argument types - normally set by build_function_type. */ - TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0); - - /* install return type */ - TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto)); - - return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type); -} - -/* Return 1 if PROTO1 is consistent with PROTO2. */ - -static int -comp_proto_with_proto (proto1, proto2) - tree proto1, proto2; -{ - static tree function_type1 = 0, function_type2 = 0; - - /* Create a couple function_type node's once. */ - if (!function_type1) - { - push_obstacks_nochange (); - end_temporary_allocation (); - function_type1 = make_node (FUNCTION_TYPE); - function_type2 = make_node (FUNCTION_TYPE); - pop_obstacks (); - } - - /* Install argument types; normally set by build_function_type. */ - TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0); - TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0); - - /* Install return type. */ - TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1)); - TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2)); - - return comptypes (function_type1, function_type2); -} - -/* - Generate an identifier for the function. the format is "_n_cls", - where 1 <= n <= nMethods, and cls is the name the implementation we - are processing. - - Install the return type from the method declaration. - - If we have a prototype, check for type consistency. */ - -static void -really_start_method (method, parmlist) - tree method, parmlist; -{ - tree sc_spec, ret_spec, ret_decl, decl_specs; - tree method_decl, method_id; - char *buf, *sel_name, *class_name, *cat_name; - - /* Synth the storage class & assemble the return type. */ - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - ret_spec = TREE_PURPOSE (TREE_TYPE (method)); - decl_specs = chainon (sc_spec, ret_spec); - - sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method)); - class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context)); - cat_name = ((TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - ? NULL - : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))); - method_slot++; - - /* Make sure this is big enough for any plausible method label. */ - buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name) - + (cat_name ? strlen (cat_name) : 0)); - - OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL, - class_name, cat_name, sel_name, method_slot); - - method_id = get_identifier (buf); - - method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE); - - /* Check the declarator portion of the return type for the method. */ - if ((ret_decl = TREE_VALUE (TREE_TYPE (method)))) - { - /* Unite the complex decl (specified in the abstract decl) with the - function decl just synthesized..(int *), (int (*)()), (int (*)[]). */ - tree save_expr = expr_last (ret_decl); - - TREE_OPERAND (save_expr, 0) = method_decl; - method_decl = ret_decl; - - /* Fool the parser into thinking it is starting a function. */ - start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0); - - /* Unhook: this has the effect of restoring the abstract declarator. */ - TREE_OPERAND (save_expr, 0) = NULL_TREE; - } - - else - { - TREE_VALUE (TREE_TYPE (method)) = method_decl; - - /* Fool the parser into thinking it is starting a function. */ - start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0); - - /* Unhook: this has the effect of restoring the abstract declarator. */ - TREE_VALUE (TREE_TYPE (method)) = NULL_TREE; - } - - METHOD_DEFINITION (method) = current_function_decl; - - if (implementation_template != implementation_context) - { - tree proto; - - if (TREE_CODE (method) == INSTANCE_METHOD_DECL) - proto = lookup_instance_method_static (implementation_template, - METHOD_SEL_NAME (method)); - else - proto = lookup_class_method_static (implementation_template, - METHOD_SEL_NAME (method)); - - if (proto && ! comp_method_with_proto (method, proto)) - { - char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+'); - - warn_with_method ("conflicting types for", type, method); - warn_with_method ("previous declaration of", type, proto); - } - } -} - -/* The following routine is always called...this "architecture" is to - accommodate "old-style" variable length selectors. - - - a:a b:b // prototype ; id c; id d; // old-style. */ - -void -continue_method_def () -{ - tree parmlist; - - if (METHOD_ADD_ARGS (method_context) == (tree)1) - /* We have a `, ...' immediately following the selector. */ - parmlist = get_parm_info (0); - else - parmlist = get_parm_info (1); /* place a `void_at_end' */ - - /* Set self_decl from the first argument...this global is used by - build_ivar_reference calling build_indirect_ref. */ - self_decl = TREE_PURPOSE (parmlist); - - poplevel (0, 0, 0); - really_start_method (method_context, parmlist); - store_parm_decls (); -} - -/* Called by the parser, from the `pushlevel' production. */ - -void -add_objc_decls () -{ - if (!UOBJC_SUPER_decl) - { - UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER), - build_tree_list (NULL_TREE, - objc_super_template), - 0, NULL_TREE, NULL_TREE); - - finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE); - - /* This prevents `unused variable' warnings when compiling with -Wall. */ - TREE_USED (UOBJC_SUPER_decl) = 1; - DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1; - } -} - -/* _n_Method (id self, SEL sel, ...) - { - struct objc_super _S; - _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...); - } */ - -tree -get_super_receiver () -{ - if (method_context) - { - tree super_expr, super_expr_list; - - /* Set receiver to self. */ - super_expr = build_component_ref (UOBJC_SUPER_decl, self_id); - super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl); - super_expr_list = build_tree_list (NULL_TREE, super_expr); - - /* Set class to begin searching. */ - super_expr = build_component_ref (UOBJC_SUPER_decl, - get_identifier ("class")); - - if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE) - { - /* [_cls, __cls]Super are "pre-built" in - synth_forward_declarations. */ - - super_expr = build_modify_expr (super_expr, NOP_EXPR, - ((TREE_CODE (method_context) - == INSTANCE_METHOD_DECL) - ? ucls_super_ref - : uucls_super_ref)); - } - - else - /* We have a category. */ - { - tree super_name = CLASS_SUPER_NAME (implementation_template); - tree super_class; - - if (!super_name) - { - error ("no super class declared in interface for `%s'", - IDENTIFIER_POINTER (CLASS_NAME (implementation_template))); - return error_mark_node; - } - - if (flag_next_runtime) - { - super_class = get_class_reference (super_name); - if (TREE_CODE (method_context) == CLASS_METHOD_DECL) - super_class - = build_component_ref (build_indirect_ref (super_class, "->"), - get_identifier ("isa")); - } - else - { - add_class_reference (super_name); - super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL - ? objc_get_class_decl : objc_get_meta_class_decl); - assemble_external (super_class); - super_class - = build_function_call - (super_class, - build_tree_list - (NULL_TREE, - my_build_string (IDENTIFIER_LENGTH (super_name) + 1, - IDENTIFIER_POINTER (super_name)))); - } - - TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref); - super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class); - } - - chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr)); - - super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0); - chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr)); - - return build_compound_expr (super_expr_list); - } - else - { - error ("[super ...] must appear in a method context"); - return error_mark_node; - } -} - -static tree -encode_method_def (func_decl) - tree func_decl; -{ - tree parms; - int stack_size; - int max_parm_end = 0; - char buffer[40]; - tree result; - - /* Return type. */ - encode_type (TREE_TYPE (TREE_TYPE (func_decl)), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - - /* Stack size. */ - for (parms = DECL_ARGUMENTS (func_decl); parms; - parms = TREE_CHAIN (parms)) - { - int parm_end = (forwarding_offset (parms) - + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms))) - / BITS_PER_UNIT)); - - if (!offset_is_register && parm_end > max_parm_end) - max_parm_end = parm_end; - } - - stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET; - - sprintf (buffer, "%d", stack_size); - obstack_grow (&util_obstack, buffer, strlen (buffer)); - - /* Argument types. */ - for (parms = DECL_ARGUMENTS (func_decl); parms; - parms = TREE_CHAIN (parms)) - { - /* Type. */ - encode_type (TREE_TYPE (parms), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - - /* Compute offset. */ - sprintf (buffer, "%d", forwarding_offset (parms)); - - /* Indicate register. */ - if (offset_is_register) - obstack_1grow (&util_obstack, '+'); - - obstack_grow (&util_obstack, buffer, strlen (buffer)); - } - - obstack_1grow (&util_obstack, 0); - result = get_identifier (obstack_finish (&util_obstack)); - obstack_free (&util_obstack, util_firstobj); - return result; -} - -void -finish_method_def () -{ - METHOD_ENCODING (method_context) = encode_method_def (current_function_decl); - - finish_function (0); - - /* Required to implement _msgSuper. This must be done AFTER finish_function, - since the optimizer may find "may be used before set" errors. */ - method_context = NULL_TREE; -} - -#if 0 -int -lang_report_error_function (decl) - tree decl; -{ - if (method_context) - { - fprintf (stderr, "In method `%s'\n", - IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context))); - return 1; - } - - else - return 0; -} -#endif - -static int -is_complex_decl (type) - tree type; -{ - return (TREE_CODE (type) == ARRAY_TYPE - || TREE_CODE (type) == FUNCTION_TYPE - || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type))); -} - - -/* Code to convert a decl node into text for a declaration in C. */ - -static char tmpbuf[256]; - -static void -adorn_decl (decl, str) - tree decl; - char *str; -{ - enum tree_code code = TREE_CODE (decl); - - if (code == ARRAY_REF) - { - tree an_int_cst = TREE_OPERAND (decl, 1); - - if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST) - sprintf (str + strlen (str), "[%ld]", - (long) TREE_INT_CST_LOW (an_int_cst)); - else - strcat (str, "[]"); - } - - else if (code == ARRAY_TYPE) - { - tree an_int_cst = TYPE_SIZE (decl); - tree array_of = TREE_TYPE (decl); - - if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE) - sprintf (str + strlen (str), "[%ld]", - (long) (TREE_INT_CST_LOW (an_int_cst) - / TREE_INT_CST_LOW (TYPE_SIZE (array_of)))); - else - strcat (str, "[]"); - } - - else if (code == CALL_EXPR) - { - tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1)); - - strcat (str, "("); - while (chain) - { - gen_declaration (chain, str); - chain = TREE_CHAIN (chain); - if (chain) - strcat (str, ", "); - } - strcat (str, ")"); - } - - else if (code == FUNCTION_TYPE) - { - tree chain = TYPE_ARG_TYPES (decl); - - strcat (str, "("); - while (chain && TREE_VALUE (chain) != void_type_node) - { - gen_declaration (TREE_VALUE (chain), str); - chain = TREE_CHAIN (chain); - if (chain && TREE_VALUE (chain) != void_type_node) - strcat (str, ", "); - } - strcat (str, ")"); - } - - else if (code == INDIRECT_REF) - { - strcpy (tmpbuf, "*"); - if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST) - { - tree chain; - - for (chain = nreverse (copy_list (TREE_TYPE (decl))); - chain; - chain = TREE_CHAIN (chain)) - { - if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE) - { - strcat (tmpbuf, " "); - strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain))); - } - } - if (str[0]) - strcat (tmpbuf, " "); - } - strcat (tmpbuf, str); - strcpy (str, tmpbuf); - } - - else if (code == POINTER_TYPE) - { - strcpy (tmpbuf, "*"); - if (TREE_READONLY (decl) || TYPE_VOLATILE (decl)) - { - if (TREE_READONLY (decl)) - strcat (tmpbuf, " const"); - if (TYPE_VOLATILE (decl)) - strcat (tmpbuf, " volatile"); - if (str[0]) - strcat (tmpbuf, " "); - } - strcat (tmpbuf, str); - strcpy (str, tmpbuf); - } -} - -static char * -gen_declarator (decl, buf, name) - tree decl; - char *buf; - char *name; -{ - if (decl) - { - enum tree_code code = TREE_CODE (decl); - char *str; - tree op; - int wrap = 0; - - switch (code) - { - case ARRAY_REF: - case INDIRECT_REF: - case CALL_EXPR: - op = TREE_OPERAND (decl, 0); - - /* We have a pointer to a function or array...(*)(), (*)[] */ - if ((code == ARRAY_REF || code == CALL_EXPR) - && op && TREE_CODE (op) == INDIRECT_REF) - wrap = 1; - - str = gen_declarator (op, buf, name); - - if (wrap) - { - strcpy (tmpbuf, "("); - strcat (tmpbuf, str); - strcat (tmpbuf, ")"); - strcpy (str, tmpbuf); - } - - adorn_decl (decl, str); - break; - - case ARRAY_TYPE: - case FUNCTION_TYPE: - case POINTER_TYPE: - strcpy (buf, name); - str = buf; - - /* This clause is done iteratively rather than recursively. */ - do - { - op = (is_complex_decl (TREE_TYPE (decl)) - ? TREE_TYPE (decl) : NULL_TREE); - - adorn_decl (decl, str); - - /* We have a pointer to a function or array...(*)(), (*)[] */ - if (code == POINTER_TYPE - && op && (TREE_CODE (op) == FUNCTION_TYPE - || TREE_CODE (op) == ARRAY_TYPE)) - { - strcpy (tmpbuf, "("); - strcat (tmpbuf, str); - strcat (tmpbuf, ")"); - strcpy (str, tmpbuf); - } - - decl = (is_complex_decl (TREE_TYPE (decl)) - ? TREE_TYPE (decl) : NULL_TREE); - } - - while (decl && (code = TREE_CODE (decl))) - ; - - break; - - case IDENTIFIER_NODE: - /* Will only happen if we are processing a "raw" expr-decl. */ - strcpy (buf, IDENTIFIER_POINTER (decl)); - return buf; - - default: - abort (); - } - - return str; - } - - else - /* We have an abstract declarator or a _DECL node. */ - { - strcpy (buf, name); - return buf; - } -} - -static void -gen_declspecs (declspecs, buf, raw) - tree declspecs; - char *buf; - int raw; -{ - if (raw) - { - tree chain; - - for (chain = nreverse (copy_list (declspecs)); - chain; chain = TREE_CHAIN (chain)) - { - tree aspec = TREE_VALUE (chain); - - if (TREE_CODE (aspec) == IDENTIFIER_NODE) - strcat (buf, IDENTIFIER_POINTER (aspec)); - else if (TREE_CODE (aspec) == RECORD_TYPE) - { - if (TYPE_NAME (aspec)) - { - tree protocol_list = TYPE_PROTOCOL_LIST (aspec); - - if (! TREE_STATIC_TEMPLATE (aspec)) - strcat (buf, "struct "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec))); - - /* NEW!!! */ - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, - IDENTIFIER_POINTER - (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - strcat (buf, ">"); - } - } - - else - strcat (buf, "untagged struct"); - } - - else if (TREE_CODE (aspec) == UNION_TYPE) - { - if (TYPE_NAME (aspec)) - { - if (! TREE_STATIC_TEMPLATE (aspec)) - strcat (buf, "union "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec))); - } - else - strcat (buf, "untagged union"); - } - - else if (TREE_CODE (aspec) == ENUMERAL_TYPE) - { - if (TYPE_NAME (aspec)) - { - if (! TREE_STATIC_TEMPLATE (aspec)) - strcat (buf, "enum "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec))); - } - else - strcat (buf, "untagged enum"); - } - - else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec)) - strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec))); - - else if (IS_ID (aspec)) - { - tree protocol_list = TYPE_PROTOCOL_LIST (aspec); - - strcat (buf, "id"); - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, - IDENTIFIER_POINTER - (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - strcat (buf, ">"); - } - } - if (TREE_CHAIN (chain)) - strcat (buf, " "); - } - } - else - { - /* Type qualifiers. */ - if (TREE_READONLY (declspecs)) - strcat (buf, "const "); - if (TYPE_VOLATILE (declspecs)) - strcat (buf, "volatile "); - - switch (TREE_CODE (declspecs)) - { - /* Type specifiers. */ - - case INTEGER_TYPE: - declspecs = TYPE_MAIN_VARIANT (declspecs); - - /* Signed integer types. */ - - if (declspecs == short_integer_type_node) - strcat (buf, "short int "); - else if (declspecs == integer_type_node) - strcat (buf, "int "); - else if (declspecs == long_integer_type_node) - strcat (buf, "long int "); - else if (declspecs == long_long_integer_type_node) - strcat (buf, "long long int "); - else if (declspecs == signed_char_type_node - || declspecs == char_type_node) - strcat (buf, "char "); - - /* Unsigned integer types. */ - - else if (declspecs == short_unsigned_type_node) - strcat (buf, "unsigned short "); - else if (declspecs == unsigned_type_node) - strcat (buf, "unsigned int "); - else if (declspecs == long_unsigned_type_node) - strcat (buf, "unsigned long "); - else if (declspecs == long_long_unsigned_type_node) - strcat (buf, "unsigned long long "); - else if (declspecs == unsigned_char_type_node) - strcat (buf, "unsigned char "); - break; - - case REAL_TYPE: - declspecs = TYPE_MAIN_VARIANT (declspecs); - - if (declspecs == float_type_node) - strcat (buf, "float "); - else if (declspecs == double_type_node) - strcat (buf, "double "); - else if (declspecs == long_double_type_node) - strcat (buf, "long double "); - break; - - case RECORD_TYPE: - if (TYPE_NAME (declspecs) - && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE) - { - tree protocol_list = TYPE_PROTOCOL_LIST (declspecs); - - if (! TREE_STATIC_TEMPLATE (declspecs)) - strcat (buf, "struct "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs))); - - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, - IDENTIFIER_POINTER - (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - strcat (buf, ">"); - } - } - - else - strcat (buf, "untagged struct"); - - strcat (buf, " "); - break; - - case UNION_TYPE: - if (TYPE_NAME (declspecs) - && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE) - { - strcat (buf, "union "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs))); - strcat (buf, " "); - } - - else - strcat (buf, "untagged union "); - break; - - case ENUMERAL_TYPE: - if (TYPE_NAME (declspecs) - && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE) - { - strcat (buf, "enum "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs))); - strcat (buf, " "); - } - - else - strcat (buf, "untagged enum "); - break; - - case VOID_TYPE: - strcat (buf, "void "); - break; - - case POINTER_TYPE: - { - tree protocol_list = TYPE_PROTOCOL_LIST (declspecs); - - strcat (buf, "id"); - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, - IDENTIFIER_POINTER - (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - - strcat (buf, ">"); - } - } - break; - - default: - break; - } - } -} - -static char * -gen_declaration (atype_or_adecl, buf) - tree atype_or_adecl; - char *buf; -{ - char declbuf[256]; - - if (TREE_CODE (atype_or_adecl) == TREE_LIST) - { - tree declspecs; /* "identifier_node", "record_type" */ - tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */ - - /* We have a "raw", abstract declarator (typename). */ - declarator = TREE_VALUE (atype_or_adecl); - declspecs = TREE_PURPOSE (atype_or_adecl); - - gen_declspecs (declspecs, buf, 1); - if (declarator) - { - strcat (buf, " "); - strcat (buf, gen_declarator (declarator, declbuf, "")); - } - } - - else - { - tree atype; - tree declspecs; /* "integer_type", "real_type", "record_type"... */ - tree declarator; /* "array_type", "function_type", "pointer_type". */ - - if (TREE_CODE (atype_or_adecl) == FIELD_DECL - || TREE_CODE (atype_or_adecl) == PARM_DECL - || TREE_CODE (atype_or_adecl) == FUNCTION_DECL) - atype = TREE_TYPE (atype_or_adecl); - else - /* Assume we have a *_type node. */ - atype = atype_or_adecl; - - if (is_complex_decl (atype)) - { - tree chain; - - /* Get the declaration specifier; it is at the end of the list. */ - declarator = chain = atype; - do - chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */ - while (is_complex_decl (chain)); - declspecs = chain; - } - - else - { - declspecs = atype; - declarator = NULL_TREE; - } - - gen_declspecs (declspecs, buf, 0); - - if (TREE_CODE (atype_or_adecl) == FIELD_DECL - || TREE_CODE (atype_or_adecl) == PARM_DECL - || TREE_CODE (atype_or_adecl) == FUNCTION_DECL) - { - char *decl_name = (DECL_NAME (atype_or_adecl) - ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) - : ""); - - if (declarator) - { - strcat (buf, " "); - strcat (buf, gen_declarator (declarator, declbuf, decl_name)); - } - - else if (decl_name[0]) - { - strcat (buf, " "); - strcat (buf, decl_name); - } - } - else if (declarator) - { - strcat (buf, " "); - strcat (buf, gen_declarator (declarator, declbuf, "")); - } - } - - return buf; -} - -#define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth)))) - -static char * -gen_method_decl (method, buf) - tree method; - char *buf; -{ - tree chain; - - if (RAW_TYPESPEC (method) != objc_object_reference) - { - strcpy (buf, "("); - gen_declaration (TREE_TYPE (method), buf); - strcat (buf, ")"); - } - - chain = METHOD_SEL_ARGS (method); - if (chain) - { - /* We have a chain of keyword_decls. */ - do - { - if (KEYWORD_KEY_NAME (chain)) - strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain))); - - strcat (buf, ":"); - if (RAW_TYPESPEC (chain) != objc_object_reference) - { - strcat (buf, "("); - gen_declaration (TREE_TYPE (chain), buf); - strcat (buf, ")"); - } - - strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain))); - if ((chain = TREE_CHAIN (chain))) - strcat (buf, " "); - } - while (chain); - - if (METHOD_ADD_ARGS (method) == (tree)1) - strcat (buf, ", ..."); - else if (METHOD_ADD_ARGS (method)) - { - /* We have a tree list node as generate by get_parm_info. */ - chain = TREE_PURPOSE (METHOD_ADD_ARGS (method)); - - /* Know we have a chain of parm_decls. */ - while (chain) - { - strcat (buf, ", "); - gen_declaration (chain, buf); - chain = TREE_CHAIN (chain); - } - } - } - - else - /* We have a unary selector. */ - strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method))); - - return buf; -} - -/* Debug info. */ - -static void -dump_interface (fp, chain) - FILE *fp; - tree chain; -{ - char *buf = (char *)xmalloc (256); - char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain)); - tree ivar_decls = CLASS_RAW_IVARS (chain); - tree nst_methods = CLASS_NST_METHODS (chain); - tree cls_methods = CLASS_CLS_METHODS (chain); - - fprintf (fp, "\n@interface %s", my_name); - - if (CLASS_SUPER_NAME (chain)) - { - char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain)); - fprintf (fp, " : %s\n", super_name); - } - else - fprintf (fp, "\n"); - - if (ivar_decls) - { - fprintf (fp, "{\n"); - do - { - bzero (buf, 256); - fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf)); - ivar_decls = TREE_CHAIN (ivar_decls); - } - while (ivar_decls); - fprintf (fp, "}\n"); - } - - while (nst_methods) - { - bzero (buf, 256); - fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf)); - nst_methods = TREE_CHAIN (nst_methods); - } - - while (cls_methods) - { - bzero (buf, 256); - fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf)); - cls_methods = TREE_CHAIN (cls_methods); - } - fprintf (fp, "\n@end"); -} - -/* Demangle function for Objective-C */ -static const char * -objc_demangle (mangled) - const char *mangled; -{ - char *demangled, *cp; - - if (mangled[0] == '_' && - (mangled[1] == 'i' || mangled[1] == 'c') && - mangled[2] == '_') - { - cp = demangled = xmalloc(strlen(mangled) + 2); - if (mangled[1] == 'i') - *cp++ = '-'; /* for instance method */ - else - *cp++ = '+'; /* for class method */ - *cp++ = '['; /* opening left brace */ - strcpy(cp, mangled+3); /* tack on the rest of the mangled name */ - while (*cp && *cp == '_') - cp++; /* skip any initial underbars in class name */ - cp = strchr(cp, '_'); /* find first non-initial underbar */ - if (cp == NULL) - { - free(demangled); /* not mangled name */ - return mangled; - } - if (cp[1] == '_') /* easy case: no category name */ - { - *cp++ = ' '; /* replace two '_' with one ' ' */ - strcpy(cp, mangled + (cp - demangled) + 2); - } - else - { - *cp++ = '('; /* less easy case: category name */ - cp = strchr(cp, '_'); - if (cp == 0) - { - free(demangled); /* not mangled name */ - return mangled; - } - *cp++ = ')'; - *cp++ = ' '; /* overwriting 1st char of method name... */ - strcpy(cp, mangled + (cp - demangled)); /* get it back */ - } - while (*cp && *cp == '_') - cp++; /* skip any initial underbars in method name */ - for (; *cp; cp++) - if (*cp == '_') - *cp = ':'; /* replace remaining '_' with ':' */ - *cp++ = ']'; /* closing right brace */ - *cp++ = 0; /* string terminator */ - return demangled; - } - else - return mangled; /* not an objc mangled name */ -} - -static const char * -objc_printable_name (decl, kind) - tree decl; - char **kind; -{ - return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl))); -} - -static void -init_objc () -{ - /* Add the special tree codes of Objective C to the tables. */ - -#define LAST_CODE LAST_AND_UNUSED_TREE_CODE - - gcc_obstack_init (&util_obstack); - util_firstobj = (char *) obstack_finish (&util_obstack); - - bcopy (objc_tree_code_type, - tree_code_type + (int) LAST_CODE, - (int) LAST_OBJC_TREE_CODE - (int) LAST_CODE); - bcopy ((char *) objc_tree_code_length, - (char *) (tree_code_length + (int) LAST_CODE), - (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) - * sizeof (int))); - bcopy ((char *) objc_tree_code_name, - (char *) (tree_code_name + (int) LAST_CODE), - (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) - * sizeof (char *))); - - errbuf = (char *)xmalloc (BUFSIZE); - hash_init (); - synth_module_prologue (); - - /* Change the default error function */ - decl_printable_name = (char* (*)()) objc_printable_name; -} - -static void -finish_objc () -{ - struct imp_entry *impent; - tree chain; - /* The internally generated initializers appear to have missing braces. - Don't warn about this. */ - int save_warn_missing_braces = warn_missing_braces; - warn_missing_braces = 0; - - generate_forward_declaration_to_string_table (); - -#ifdef OBJC_PROLOGUE - OBJC_PROLOGUE; -#endif - - /* Process the static instances here because initialization of objc_symtab - depends on them. */ - if (objc_static_instances) - generate_static_references (); - - if (implementation_context || class_names_chain - || meth_var_names_chain || meth_var_types_chain || sel_ref_chain) - generate_objc_symtab_decl (); - - for (impent = imp_list; impent; impent = impent->next) - { - implementation_context = impent->imp_context; - implementation_template = impent->imp_template; - - UOBJC_CLASS_decl = impent->class_decl; - UOBJC_METACLASS_decl = impent->meta_decl; - - if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE) - { - /* all of the following reference the string pool... */ - generate_ivar_lists (); - generate_dispatch_tables (); - generate_shared_structures (); - } - else - { - generate_dispatch_tables (); - generate_category (implementation_context); - } - } - - /* If we are using an array of selectors, we must always - finish up the array decl even if no selectors were used. */ - if (! flag_next_runtime || sel_ref_chain) - build_selector_translation_table (); - - if (protocol_chain) - generate_protocols (); - - if (implementation_context || class_names_chain || objc_static_instances - || meth_var_names_chain || meth_var_types_chain || sel_ref_chain) - { - /* Arrange for Objc data structures to be initialized at run time. */ - char *init_name = build_module_descriptor (); - if (init_name) - assemble_constructor (init_name); - } - - /* Dump the class references. This forces the appropriate classes - to be linked into the executable image, preserving unix archive - semantics. This can be removed when we move to a more dynamically - linked environment. */ - - for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) - { - handle_class_ref (chain); - if (TREE_PURPOSE (chain)) - generate_classref_translation_entry (chain); - } - - for (impent = imp_list; impent; impent = impent->next) - handle_impent (impent); - - /* Dump the string table last. */ - - generate_strings (); - - if (flag_gen_declaration) - { - add_class (implementation_context); - dump_interface (gen_declaration_file, implementation_context); - } - - if (warn_selector) - { - int slot; - hash hsh; - - /* Run through the selector hash tables and print a warning for any - selector which has multiple methods. */ - - for (slot = 0; slot < SIZEHASHTABLE; slot++) - for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next) - if (hsh->list) - { - tree meth = hsh->key; - char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL - ? '-' : '+'); - attr loop; - - warning ("potential selector conflict for method `%s'", - IDENTIFIER_POINTER (METHOD_SEL_NAME (meth))); - warn_with_method ("found", type, meth); - for (loop = hsh->list; loop; loop = loop->next) - warn_with_method ("found", type, loop->value); - } - - for (slot = 0; slot < SIZEHASHTABLE; slot++) - for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next) - if (hsh->list) - { - tree meth = hsh->key; - char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL - ? '-' : '+'); - attr loop; - - warning ("potential selector conflict for method `%s'", - IDENTIFIER_POINTER (METHOD_SEL_NAME (meth))); - warn_with_method ("found", type, meth); - for (loop = hsh->list; loop; loop = loop->next) - warn_with_method ("found", type, loop->value); - } - } - - warn_missing_braces = save_warn_missing_braces; -} - -/* Subroutines of finish_objc. */ - -static void -generate_classref_translation_entry (chain) - tree chain; -{ - tree expr, name, decl_specs, decl, sc_spec; - tree type; - - type = TREE_TYPE (TREE_PURPOSE (chain)); - - expr = add_objc_string (TREE_VALUE (chain), class_names); - expr = build_c_cast (type, expr); /* cast! */ - - name = DECL_NAME (TREE_PURPOSE (chain)); - - sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]); - - /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */ - decl_specs = tree_cons (NULL_TREE, type, sc_spec); - - /* The decl that is returned from start_decl is the one that we - forward declared in build_class_reference. */ - decl = start_decl (name, decl_specs, 1, NULL_TREE, NULL_TREE); - finish_decl (decl, expr, NULL_TREE); - return; -} - -static void -handle_class_ref (chain) - tree chain; -{ - char *name = IDENTIFIER_POINTER (TREE_VALUE (chain)); - if (! flag_next_runtime) - { - tree decl; - char *string = (char *) alloca (strlen (name) + 30); - tree exp; - - sprintf (string, "%sobjc_class_name_%s", - (flag_next_runtime ? "." : "__"), name); - - /* Make a decl for this name, so we can use its address in a tree. */ - decl = build_decl (VAR_DECL, get_identifier (string), char_type_node); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - - pushdecl (decl); - rest_of_decl_compilation (decl, 0, 0, 0); - - /* Make following constant read-only (why not)? */ - readonly_data_section (); - - exp = build1 (ADDR_EXPR, string_type_node, decl); - - /* Align the section properly. */ - assemble_constant_align (exp); - - /* Inform the assembler about this new external thing. */ - assemble_external (decl); - - /* Output a constant to reference this address. */ - output_constant (exp, int_size_in_bytes (string_type_node)); - } - else - { - /* This overreliance on our assembler (i.e. lack of portability) - should be dealt with at some point. The GNU strategy (above) - won't work either, but it is a start. */ - char *string = (char *) alloca (strlen (name) + 30); - sprintf (string, ".reference .objc_class_name_%s", name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - } -} - -static void -handle_impent (impent) - struct imp_entry *impent; -{ - implementation_context = impent->imp_context; - implementation_template = impent->imp_template; - - if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) - { - char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)); - char *string = (char *) alloca (strlen (class_name) + 30); - - if (flag_next_runtime) - { - /* Grossly unportable. - People should know better than to assume - such things about assembler syntax! */ - sprintf (string, ".objc_class_name_%s=0", class_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - - sprintf (string, ".globl .objc_class_name_%s", class_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - } - - else - { - sprintf (string, "%sobjc_class_name_%s", - (flag_next_runtime ? "." : "__"), class_name); - assemble_global (string); - assemble_label (string); - } - } - - else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) - { - char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)); - char *class_super_name - = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)); - char *string = (char *) alloca (strlen (class_name) - + strlen (class_super_name) + 30); - - /* Do the same for categories. Even though no references to these - symbols are generated automatically by the compiler, it gives - you a handle to pull them into an archive by hand. */ - if (flag_next_runtime) - { - /* Grossly unportable. */ - sprintf (string, ".objc_category_name_%s_%s=0", - class_name, class_super_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - - sprintf (string, ".globl .objc_category_name_%s_%s", - class_name, class_super_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - } - - else - { - sprintf (string, "%sobjc_category_name_%s_%s", - (flag_next_runtime ? "." : "__"), - class_name, class_super_name); - assemble_global (string); - assemble_label (string); - } - } -} - -#ifdef DEBUG - -static void -objc_debug (fp) - FILE *fp; -{ - char *buf = (char *)xmalloc (256); - - { /* dump function prototypes */ - tree loop = UOBJC_MODULES_decl; - - fprintf (fp, "\n\nfunction prototypes:\n"); - while (loop) - { - if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop)) - { - /* We have a function definition: generate prototype. */ - bzero (errbuf, BUFSIZE); - gen_declaration (loop, errbuf); - fprintf (fp, "%s;\n", errbuf); - } - loop = TREE_CHAIN (loop); - } - } - { - /* Dump global chains. */ - tree loop; - int i, index = 0, offset = 0; - hash hashlist; - - for (i = 0; i < SIZEHASHTABLE; i++) - { - if (hashlist = nst_method_hash_list[i]) - { - fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i); - do - { - bzero (buf, 256); - fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf)); - hashlist = hashlist->next; - } - while (hashlist); - } - } - - for (i = 0; i < SIZEHASHTABLE; i++) - { - if (hashlist = cls_method_hash_list[i]) - { - fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i); - do - { - bzero (buf, 256); - fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf)); - hashlist = hashlist->next; - } - while (hashlist); - } - } - - fprintf (fp, "\nsel_refdef_chain:\n"); - for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop)) - { - fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset, - IDENTIFIER_POINTER (TREE_VALUE (loop))); - index++; - /* add one for the '\0' character */ - offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1; - } - - fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index); - } -} -#endif - -void -print_lang_statistics () -{ -} diff --git a/contrib/gcc/objc/objc-act.h b/contrib/gcc/objc/objc-act.h deleted file mode 100644 index 65224de84f4c..000000000000 --- a/contrib/gcc/objc/objc-act.h +++ /dev/null @@ -1,117 +0,0 @@ -/* Declarations for objc-act.c. - Copyright (C) 1990 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/*** Public Interface (procedures) ***/ - -/* used by yyparse */ - -void finish_file PROTO((void)); -tree start_class PROTO((enum tree_code, tree, tree, tree)); -tree continue_class PROTO((tree)); -void finish_class PROTO((tree)); -void start_method_def PROTO((tree)); -void continue_method_def PROTO((void)); -void finish_method_def PROTO((void)); -tree start_protocol PROTO((enum tree_code, tree, tree)); -void finish_protocol PROTO((tree)); -void add_objc_decls PROTO((void)); - -tree is_ivar PROTO((tree, tree)); -int is_private PROTO((tree)); -int is_public PROTO((tree, tree)); -tree add_instance_variable PROTO((tree, int, tree, tree, tree)); -tree add_class_method PROTO((tree, tree)); -tree add_instance_method PROTO((tree, tree)); -tree get_super_receiver PROTO((void)); -tree get_class_ivars PROTO((tree)); -tree get_class_reference PROTO((tree)); -tree get_static_reference PROTO((tree, tree)); -tree get_object_reference PROTO((tree)); -tree build_message_expr PROTO((tree)); -tree build_selector_expr PROTO((tree)); -tree build_ivar_reference PROTO((tree)); -tree build_keyword_decl PROTO((tree, tree, tree)); -tree build_method_decl PROTO((enum tree_code, tree, tree, tree)); -tree build_protocol_expr PROTO((tree)); -tree build_objc_string_object PROTO((tree)); - -extern tree objc_ivar_chain; -extern tree objc_method_context; - -void objc_declare_alias PROTO((tree, tree)); -void objc_declare_class PROTO((tree)); - -extern int objc_receiver_context; - -/* the following routines are used to implement statically typed objects */ - -int objc_comptypes PROTO((tree, tree, int)); -void objc_check_decl PROTO((tree)); - -/* NeXT extensions */ - -tree build_encode_expr PROTO((tree)); - -/* Objective-C structures */ - -/* KEYWORD_DECL */ -#define KEYWORD_KEY_NAME(DECL) ((DECL)->decl.name) -#define KEYWORD_ARG_NAME(DECL) ((DECL)->decl.arguments) - -/* INSTANCE_METHOD_DECL, CLASS_METHOD_DECL */ -#define METHOD_SEL_NAME(DECL) ((DECL)->decl.name) -#define METHOD_SEL_ARGS(DECL) ((DECL)->decl.arguments) -#define METHOD_ADD_ARGS(DECL) ((DECL)->decl.result) -#define METHOD_DEFINITION(DECL) ((DECL)->decl.initial) -#define METHOD_ENCODING(DECL) ((DECL)->decl.context) - -/* CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE, - CATEGORY_INTERFACE_TYPE, CATEGORY_IMPLEMENTATION_TYPE, - PROTOCOL_INTERFACE_TYPE */ -#define CLASS_NAME(CLASS) ((CLASS)->type.name) -#define CLASS_SUPER_NAME(CLASS) ((CLASS)->type.context) -#define CLASS_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 0) -#define CLASS_RAW_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1) -#define CLASS_NST_METHODS(CLASS) ((CLASS)->type.minval) -#define CLASS_CLS_METHODS(CLASS) ((CLASS)->type.maxval) -#define CLASS_STATIC_TEMPLATE(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 2) -#define CLASS_CATEGORY_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 3) -#define CLASS_PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 4) -#define PROTOCOL_NAME(CLASS) ((CLASS)->type.name) -#define PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 0) -#define PROTOCOL_NST_METHODS(CLASS) ((CLASS)->type.minval) -#define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval) -#define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1) -#define TYPE_PROTOCOL_LIST(TYPE) ((TYPE)->type.context) - -/* Define the Objective-C or Objective-C++ language-specific tree codes. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM, -enum objc_tree_code { -#ifdef OBJCPLUS - dummy_tree_code = LAST_CPLUS_TREE_CODE, -#else - dummy_tree_code = LAST_AND_UNUSED_TREE_CODE, -#endif -#include "objc-tree.def" - LAST_OBJC_TREE_CODE -}; -#undef DEFTREECODE diff --git a/contrib/gcc/objc/objc-api.h b/contrib/gcc/objc/objc-api.h deleted file mode 100644 index 9eb000b5b391..000000000000 --- a/contrib/gcc/objc/objc-api.h +++ /dev/null @@ -1,584 +0,0 @@ -/* GNU Objective-C Runtime API. - Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled - with GCC to produce an executable, this does not cause the resulting - executable to be covered by the GNU General Public License. This - exception does not however invalidate any other reasons why the - executable file might be covered by the GNU General Public License. */ - -#ifndef __objc_api_INCLUDE_GNU -#define __objc_api_INCLUDE_GNU - -#include "objc/objc.h" -#include "objc/hash.h" -#include "objc/thr.h" -#include <stdio.h> -#include <stdarg.h> - -/* For functions which return Method_t */ -#define METHOD_NULL (Method_t)0 - /* Boolean typedefs */ -/* -** Method descriptor returned by introspective Object methods. -** This is really just the first part of the more complete objc_method -** structure defined below and used internally by the runtime. -*/ -struct objc_method_description -{ - SEL name; /* this is a selector, not a string */ - char *types; /* type encoding */ -}; - -/* Filer types used to describe Ivars and Methods. */ -#define _C_ID '@' -#define _C_CLASS '#' -#define _C_SEL ':' -#define _C_CHR 'c' -#define _C_UCHR 'C' -#define _C_SHT 's' -#define _C_USHT 'S' -#define _C_INT 'i' -#define _C_UINT 'I' -#define _C_LNG 'l' -#define _C_ULNG 'L' -#define _C_FLT 'f' -#define _C_DBL 'd' -#define _C_BFLD 'b' -#define _C_VOID 'v' -#define _C_UNDEF '?' -#define _C_PTR '^' -#define _C_CHARPTR '*' -#define _C_ATOM '%' -#define _C_ARY_B '[' -#define _C_ARY_E ']' -#define _C_UNION_B '(' -#define _C_UNION_E ')' -#define _C_STRUCT_B '{' -#define _C_STRUCT_E '}' - - -/* -** Error handling -** -** Call objc_error() or objc_verror() to record an error; this error -** routine will generally exit the program but not necessarily if the -** user has installed his own error handler. -** -** Call objc_set_error_handler to assign your own function for -** handling errors. The function should return YES if it is ok -** to continue execution, or return NO or just abort if the -** program should be stopped. The default error handler is just to -** print a message on stderr. -** -** The error handler function should be of type objc_error_handler -** The first parameter is an object instance of relevance. -** The second parameter is an error code. -** The third parameter is a format string in the printf style. -** The fourth parameter is a variable list of arguments. -*/ -extern void objc_error(id object, int code, const char* fmt, ...); -extern void objc_verror(id object, int code, const char* fmt, va_list ap); -typedef BOOL (*objc_error_handler)(id, int code, const char *fmt, va_list ap); -objc_error_handler objc_set_error_handler(objc_error_handler func); - -/* -** Error codes -** These are used by the runtime library, and your -** error handling may use them to determine if the error is -** hard or soft thus whether execution can continue or abort. -*/ -#define OBJC_ERR_UNKNOWN 0 /* Generic error */ - -#define OBJC_ERR_OBJC_VERSION 1 /* Incorrect runtime version */ -#define OBJC_ERR_GCC_VERSION 2 /* Incorrect compiler version */ -#define OBJC_ERR_MODULE_SIZE 3 /* Bad module size */ -#define OBJC_ERR_PROTOCOL_VERSION 4 /* Incorrect protocol version */ - -#define OBJC_ERR_MEMORY 10 /* Out of memory */ - -#define OBJC_ERR_RECURSE_ROOT 20 /* Attempt to archive the root - object more than once. */ -#define OBJC_ERR_BAD_DATA 21 /* Didn't read expected data */ -#define OBJC_ERR_BAD_KEY 22 /* Bad key for object */ -#define OBJC_ERR_BAD_CLASS 23 /* Unknown class */ -#define OBJC_ERR_BAD_TYPE 24 /* Bad type specification */ -#define OBJC_ERR_NO_READ 25 /* Cannot read stream */ -#define OBJC_ERR_NO_WRITE 26 /* Cannot write stream */ -#define OBJC_ERR_STREAM_VERSION 27 /* Incorrect stream version */ -#define OBJC_ERR_BAD_OPCODE 28 /* Bad opcode */ - -#define OBJC_ERR_UNIMPLEMENTED 30 /* Method is not implemented */ - -#define OBJC_ERR_BAD_STATE 40 /* Bad thread state */ - -/* -** Set this variable nonzero to print a line describing each -** message that is sent. (this is currently disabled) -*/ -extern BOOL objc_trace; - - -/* For every class which happens to have statically allocated instances in - this module, one OBJC_STATIC_INSTANCES is allocated by the compiler. - INSTANCES is NULL terminated and points to all statically allocated - instances of this class. */ -struct objc_static_instances -{ - char *class_name; - id instances[0]; -}; - -/* -** Whereas a Module (defined further down) is the root (typically) of a file, -** a Symtab is the root of the class and category definitions within the -** module. -** -** A Symtab contains a variable length array of pointers to classes and -** categories defined in the module. -*/ -typedef struct objc_symtab { - unsigned long sel_ref_cnt; /* Unknown. */ - SEL refs; /* Unknown. */ - unsigned short cls_def_cnt; /* Number of classes compiled - (defined) in the module. */ - unsigned short cat_def_cnt; /* Number of categories - compiled (defined) in the - module. */ - - void *defs[1]; /* Variable array of pointers. - cls_def_cnt of type Class - followed by cat_def_cnt of - type Category_t, followed - by a NULL terminated array - of objc_static_instances. */ -} Symtab, *Symtab_t; - - -/* -** The compiler generates one of these structures for each module that -** composes the executable (eg main.m). -** -** This data structure is the root of the definition tree for the module. -** -** A collect program runs between ld stages and creates a ObjC ctor array. -** That array holds a pointer to each module structure of the executable. -*/ -typedef struct objc_module { - unsigned long version; /* Compiler revision. */ - unsigned long size; /* sizeof(Module). */ - const char* name; /* Name of the file where the - module was generated. The - name includes the path. */ - - Symtab_t symtab; /* Pointer to the Symtab of - the module. The Symtab - holds an array of - pointers to - the classes and categories - defined in the module. */ -} Module, *Module_t; - - -/* -** The compiler generates one of these structures for a class that has -** instance variables defined in its specification. -*/ -typedef struct objc_ivar* Ivar_t; -typedef struct objc_ivar_list { - int ivar_count; /* Number of structures (Ivar) - contained in the list. One - structure per instance - variable defined in the - class. */ - struct objc_ivar { - const char* ivar_name; /* Name of the instance - variable as entered in the - class definition. */ - const char* ivar_type; /* Description of the Ivar's - type. Useful for - debuggers. */ - int ivar_offset; /* Byte offset from the base - address of the instance - structure to the variable. */ - - } ivar_list[1]; /* Variable length - structure. */ -} IvarList, *IvarList_t; - - -/* -** The compiler generates one (or more) of these structures for a class that -** has methods defined in its specification. -** -** The implementation of a class can be broken into separate pieces in a file -** and categories can break them across modules. To handle this problem is a -** singly linked list of methods. -*/ -typedef struct objc_method Method; -typedef Method* Method_t; -typedef struct objc_method_list { - struct objc_method_list* method_next; /* This variable is used to link - a method list to another. It - is a singly linked list. */ - int method_count; /* Number of methods defined in - this structure. */ - struct objc_method { - SEL method_name; /* This variable is the method's - name. It is a char*. - The unique integer passed to - objc_msg_send is a char* too. - It is compared against - method_name using strcmp. */ - const char* method_types; /* Description of the method's - parameter list. Useful for - debuggers. */ - IMP method_imp; /* Address of the method in the - executable. */ - } method_list[1]; /* Variable length - structure. */ -} MethodList, *MethodList_t; - -struct objc_protocol_list { - struct objc_protocol_list *next; - int count; - Protocol *list[1]; -}; - -/* -** This is used to assure consistent access to the info field of -** classes -*/ -#ifndef HOST_BITS_PER_LONG -#define HOST_BITS_PER_LONG (sizeof(long)*8) -#endif - -#define __CLS_INFO(cls) ((cls)->info) -#define __CLS_ISINFO(cls, mask) ((__CLS_INFO(cls)&mask)==mask) -#define __CLS_SETINFO(cls, mask) (__CLS_INFO(cls) |= mask) - -/* The structure is of type MetaClass */ -#define _CLS_META 0x2L -#define CLS_ISMETA(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_META)) - - -/* The structure is of type Class */ -#define _CLS_CLASS 0x1L -#define CLS_ISCLASS(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_CLASS)) - -/* -** The class is initialized within the runtime. This means that -** it has had correct super and sublinks assigned -*/ -#define _CLS_RESOLV 0x8L -#define CLS_ISRESOLV(cls) __CLS_ISINFO(cls, _CLS_RESOLV) -#define CLS_SETRESOLV(cls) __CLS_SETINFO(cls, _CLS_RESOLV) - -/* -** The class has been send a +initialize message or a such is not -** defined for this class -*/ -#define _CLS_INITIALIZED 0x04L -#define CLS_ISINITIALIZED(cls) __CLS_ISINFO(cls, _CLS_INITIALIZED) -#define CLS_SETINITIALIZED(cls) __CLS_SETINFO(cls, _CLS_INITIALIZED) - -/* -** The class number of this class. This must be the same for both the -** class and its meta class object -*/ -#define CLS_GETNUMBER(cls) (__CLS_INFO(cls) >> (HOST_BITS_PER_LONG/2)) -#define CLS_SETNUMBER(cls, num) \ - ({ (cls)->info <<= (HOST_BITS_PER_LONG/2); \ - (cls)->info >>= (HOST_BITS_PER_LONG/2); \ - __CLS_SETINFO(cls, (((unsigned long)num) << (HOST_BITS_PER_LONG/2))); }) - -/* -** The compiler generates one of these structures for each category. A class -** may have many categories and contain both instance and factory methods. -*/ -typedef struct objc_category { - const char* category_name; /* Name of the category. Name - contained in the () of the - category definition. */ - const char* class_name; /* Name of the class to which - the category belongs. */ - MethodList_t instance_methods; /* Linked list of instance - methods defined in the - category. NULL indicates no - instance methods defined. */ - MethodList_t class_methods; /* Linked list of factory - methods defined in the - category. NULL indicates no - class methods defined. */ - struct objc_protocol_list *protocols; /* List of Protocols - conformed to */ -} Category, *Category_t; - -/* -** Structure used when a message is send to a class's super class. The -** compiler generates one of these structures and passes it to -** objc_msg_super. -*/ -typedef struct objc_super { - id self; /* Id of the object sending - the message. */ - Class class; /* Object's super class. */ -} Super, *Super_t; - -IMP objc_msg_lookup_super(Super_t super, SEL sel); - -retval_t objc_msg_sendv(id, SEL, arglist_t); - - - -/* -** This is a hook which is called by objc_lookup_class and -** objc_get_class if the runtime is not able to find the class. -** This may e.g. try to load in the class using dynamic loading. -** The function is guaranteed to be passed a non-NULL name string. -*/ -extern Class (*_objc_lookup_class)(const char *name); - -/* -** This is a hook which is called by __objc_exec_class every time a class -** or a category is loaded into the runtime. This may e.g. help a -** dynamic loader determine the classes that have been loaded when -** an object file is dynamically linked in. -*/ -extern void (*_objc_load_callback)(Class class, Category* category); - -/* -** Hook functions for allocating, copying and disposing of instances -*/ -extern id (*_objc_object_alloc)(Class class); -extern id (*_objc_object_copy)(id object); -extern id (*_objc_object_dispose)(id object); - -/* -** Standard functions for memory allocation and disposal. -** Users should use these functions in their ObjC programs so -** that they work properly with garbage collectors as well as -** can take advantage of the exception/error handling available. -*/ -void * -objc_malloc(size_t size); - -void * -objc_atomic_malloc(size_t size); - -void * -objc_valloc(size_t size); - -void * -objc_realloc(void *mem, size_t size); - -void * -objc_calloc(size_t nelem, size_t size); - -void -objc_free(void *mem); - -/* -** Hook functions for memory allocation and disposal. -** This makes it easy to substitute garbage collection systems -** such as Boehm's GC by assigning these function pointers -** to the GC's allocation routines. By default these point -** to the ANSI standard malloc, realloc, free, etc. -** -** Users should call the normal objc routines above for -** memory allocation and disposal within their programs. -*/ -extern void *(*_objc_malloc)(size_t); -extern void *(*_objc_atomic_malloc)(size_t); -extern void *(*_objc_valloc)(size_t); -extern void *(*_objc_realloc)(void *, size_t); -extern void *(*_objc_calloc)(size_t, size_t); -extern void (*_objc_free)(void *); - -Method_t class_get_class_method(MetaClass class, SEL aSel); - -Method_t class_get_instance_method(Class class, SEL aSel); - -Class class_pose_as(Class impostor, Class superclass); - -Class objc_get_class(const char *name); - -Class objc_lookup_class(const char *name); - -Class objc_next_class(void **enum_state); - -const char *sel_get_name(SEL selector); - -const char *sel_get_type(SEL selector); - -SEL sel_get_uid(const char *name); - -SEL sel_get_any_uid(const char *name); - -SEL sel_get_any_typed_uid(const char *name); - -SEL sel_get_typed_uid(const char *name, const char*); - -SEL sel_register_name(const char *name); - -SEL sel_register_typed_name(const char *name, const char*type); - - -BOOL sel_is_mapped (SEL aSel); - -extern id class_create_instance(Class class); - -static inline const char * -class_get_class_name(Class class) -{ - return CLS_ISCLASS(class)?class->name:((class==Nil)?"Nil":0); -} - -static inline long -class_get_instance_size(Class class) -{ - return CLS_ISCLASS(class)?class->instance_size:0; -} - -static inline MetaClass -class_get_meta_class(Class class) -{ - return CLS_ISCLASS(class)?class->class_pointer:Nil; -} - -static inline Class -class_get_super_class(Class class) -{ - return CLS_ISCLASS(class)?class->super_class:Nil; -} - -static inline int -class_get_version(Class class) -{ - return CLS_ISCLASS(class)?class->version:-1; -} - -static inline BOOL -class_is_class(Class class) -{ - return CLS_ISCLASS(class); -} - -static inline BOOL -class_is_meta_class(Class class) -{ - return CLS_ISMETA(class); -} - - -static inline void -class_set_version(Class class, long version) -{ - if (CLS_ISCLASS(class)) - class->version = version; -} - -static inline IMP -method_get_imp(Method_t method) -{ - return (method!=METHOD_NULL)?method->method_imp:(IMP)0; -} - -IMP get_imp (Class class, SEL sel); - -/* Redefine on NeXTSTEP so as not to conflict with system function */ -#ifdef __NeXT__ -#define object_copy gnu_object_copy -#define object_dispose gnu_object_dispose -#endif - -id object_copy(id object); - -id object_dispose(id object); - -static inline Class -object_get_class(id object) -{ - return ((object!=nil) - ? (CLS_ISCLASS(object->class_pointer) - ? object->class_pointer - : (CLS_ISMETA(object->class_pointer) - ? (Class)object - : Nil)) - : Nil); -} - -static inline const char * -object_get_class_name(id object) -{ - return ((object!=nil)?(CLS_ISCLASS(object->class_pointer) - ?object->class_pointer->name - :((Class)object)->name) - :"Nil"); -} - -static inline MetaClass -object_get_meta_class(id object) -{ - return ((object!=nil)?(CLS_ISCLASS(object->class_pointer) - ?object->class_pointer->class_pointer - :(CLS_ISMETA(object->class_pointer) - ?object->class_pointer - :Nil)) - :Nil); -} - -static inline Class -object_get_super_class -(id object) -{ - return ((object!=nil)?(CLS_ISCLASS(object->class_pointer) - ?object->class_pointer->super_class - :(CLS_ISMETA(object->class_pointer) - ?((Class)object)->super_class - :Nil)) - :Nil); -} - -static inline BOOL -object_is_class(id object) -{ - return CLS_ISCLASS((Class)object); -} - -static inline BOOL -object_is_instance(id object) -{ - return (object!=nil)&&CLS_ISCLASS(object->class_pointer); -} - -static inline BOOL -object_is_meta_class(id object) -{ - return CLS_ISMETA((Class)object); -} - -struct sarray* -objc_get_uninstalled_dtable(void); - -#endif /* not __objc_api_INCLUDE_GNU */ - - - diff --git a/contrib/gcc/objc/objc-tree.def b/contrib/gcc/objc/objc-tree.def deleted file mode 100644 index a6616243d106..000000000000 --- a/contrib/gcc/objc/objc-tree.def +++ /dev/null @@ -1,37 +0,0 @@ -/* This file contains the definitions and documentation for the - additional tree codes used in the Objective C front end (see tree.def - for the standard codes). - Copyright (C) 1990, 1997 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Objective-C types. */ -DEFTREECODE (CLASS_INTERFACE_TYPE, "class_interface_type", 't', 0) -DEFTREECODE (CLASS_IMPLEMENTATION_TYPE, "class_implementation_type", 't', 0) -DEFTREECODE (CATEGORY_INTERFACE_TYPE, "category_interface_type", 't', 0) -DEFTREECODE (CATEGORY_IMPLEMENTATION_TYPE,"category_implementation_type",'t',0) -DEFTREECODE (PROTOCOL_INTERFACE_TYPE, "protocol_interface_type", 't', 0) - -/* Objective-C decls. */ -DEFTREECODE (KEYWORD_DECL, "keyword_decl", 'd', 0) -DEFTREECODE (INSTANCE_METHOD_DECL, "instance_method_decl", 'd', 0) -DEFTREECODE (CLASS_METHOD_DECL, "class_method_decl", 'd', 0) - -/* Objective-C constants. */ -DEFTREECODE (OBJC_STRING_CST, "objc_string_cst", 'c', 3) diff --git a/contrib/gcc/objc/objc.gperf b/contrib/gcc/objc/objc.gperf deleted file mode 100644 index 407459f15898..000000000000 --- a/contrib/gcc/objc/objc.gperf +++ /dev/null @@ -1,64 +0,0 @@ -%{ -/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ objc.gperf */ -%} -struct resword { char *name; short token; enum rid rid; }; -%% -@defs, DEFS, NORID -@encode, ENCODE, NORID -@end, END, NORID -@implementation, IMPLEMENTATION, NORID -@interface, INTERFACE, NORID -@public, PUBLIC, NORID -@selector, SELECTOR, NORID -__alignof, ALIGNOF, NORID -__alignof__, ALIGNOF, NORID -__asm, ASM, NORID -__asm__, ASM, NORID -__attribute, ATTRIBUTE, NORID -__attribute__, ATTRIBUTE, NORID -__const, TYPE_QUAL, RID_CONST -__const__, TYPE_QUAL, RID_CONST -__extension__, EXTENSION, NORID -__inline, SCSPEC, RID_INLINE -__inline__, SCSPEC, RID_INLINE -__signed, TYPESPEC, RID_SIGNED -__signed__, TYPESPEC, RID_SIGNED -__typeof, TYPEOF, NORID -__typeof__, TYPEOF, NORID -__volatile, TYPE_QUAL, RID_VOLATILE -__volatile__, TYPE_QUAL, RID_VOLATILE -asm, ASM, NORID -auto, SCSPEC, RID_AUTO -break, BREAK, NORID -case, CASE, NORID -char, TYPESPEC, RID_CHAR -const, TYPE_QUAL, RID_CONST -continue, CONTINUE, NORID -default, DEFAULT, NORID -do, DO, NORID -double, TYPESPEC, RID_DOUBLE -else, ELSE, NORID -enum, ENUM, NORID -extern, SCSPEC, RID_EXTERN -float, TYPESPEC, RID_FLOAT -for, FOR, NORID -goto, GOTO, NORID -if, IF, NORID -inline, SCSPEC, RID_INLINE -int, TYPESPEC, RID_INT -long, TYPESPEC, RID_LONG -register, SCSPEC, RID_REGISTER -return, RETURN, NORID -short, TYPESPEC, RID_SHORT -signed, TYPESPEC, RID_SIGNED -sizeof, SIZEOF, NORID -static, SCSPEC, RID_STATIC -struct, STRUCT, NORID -switch, SWITCH, NORID -typedef, SCSPEC, RID_TYPEDEF -typeof, TYPEOF, NORID -union, UNION, NORID -unsigned, TYPESPEC, RID_UNSIGNED -void, TYPESPEC, RID_VOID -volatile, TYPE_QUAL, RID_VOLATILE -while, WHILE, NORID diff --git a/contrib/gcc/objc/objc.h b/contrib/gcc/objc/objc.h deleted file mode 100644 index e48b0fd5bfb4..000000000000 --- a/contrib/gcc/objc/objc.h +++ /dev/null @@ -1,157 +0,0 @@ -/* Basic data types for Objective C. - Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __objc_INCLUDE_GNU -#define __objc_INCLUDE_GNU - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stddef.h> - -/* -** Definition of the boolean type. -*/ -#ifdef __vxworks -typedef int BOOL; -#else -typedef unsigned char BOOL; -#endif -#define YES (BOOL)1 -#define NO (BOOL)0 - -/* -** Definition of a selector. Selectors themselves are not unique, but -** the sel_id is a unique identifier. -*/ -typedef const struct objc_selector -{ - void *sel_id; - const char *sel_types; -} *SEL; - -inline static BOOL -sel_eq (SEL s1, SEL s2) -{ - if (s1 == 0 || s2 == 0) - return s1 == s2; - else - return s1->sel_id == s2->sel_id; -} - - -/* -** ObjC uses this typedef for untyped instances. -*/ -typedef struct objc_object { - struct objc_class* class_pointer; -} *id; - -/* -** Definition of method type. When retrieving the implementation of a -** method, this is type of the pointer returned -*/ -typedef id (*IMP)(id, SEL, ...); - -/* -** More simple types... -*/ -#define nil (id)0 /* id of Nil instance */ -#define Nil (Class)0 /* id of Nil class */ -typedef char *STR; /* String alias */ - -/* -** The compiler generates one of these structures for each class. -** -** This structure is the definition for classes. -** -** This structure is generated by the compiler in the executable and used by -** the run-time during normal messaging operations. Therefore some members -** change type. The compiler generates "char* const" and places a string in -** the following member variables: super_class. -*/ -typedef struct objc_class *MetaClass; -typedef struct objc_class *Class; -struct objc_class { - MetaClass class_pointer; /* Pointer to the class's - meta class. */ - struct objc_class* super_class; /* Pointer to the super - class. NULL for class - Object. */ - const char* name; /* Name of the class. */ - long version; /* Unknown. */ - unsigned long info; /* Bit mask. See class masks - defined above. */ - long instance_size; /* Size in bytes of the class. - The sum of the class - definition and all super - class definitions. */ - struct objc_ivar_list* ivars; /* Pointer to a structure that - describes the instance - variables in the class - definition. NULL indicates - no instance variables. Does - not include super class - variables. */ - struct objc_method_list* methods; /* Linked list of instance - methods defined for the - class. */ - struct sarray * dtable; /* Pointer to instance - method dispatch table. */ - struct objc_class* subclass_list; /* Subclasses */ - struct objc_class* sibling_class; - - struct objc_protocol_list *protocols; /* Protocols conformed to */ -}; - -#ifndef __OBJC__ -typedef struct objc_protocol { - struct objc_class* class_pointer; - char *protocol_name; - struct objc_protocol_list *protocol_list; - struct objc_method_description_list *instance_methods, *class_methods; -} Protocol; - -#else /* __OBJC__ */ -@class Protocol; -#endif - -typedef void* retval_t; /* return value */ -typedef void(*apply_t)(void); /* function pointer */ -typedef union { - char *arg_ptr; - char arg_regs[sizeof (char*)]; -} *arglist_t; /* argument frame */ - - -IMP objc_msg_lookup(id receiver, SEL op); - -#ifdef __cplusplus -} -#endif - -#endif /* not __objc_INCLUDE_GNU */ diff --git a/contrib/gcc/objc/objects.c b/contrib/gcc/objc/objects.c deleted file mode 100644 index 3e68334c924b..000000000000 --- a/contrib/gcc/objc/objects.c +++ /dev/null @@ -1,92 +0,0 @@ -/* GNU Objective C Runtime class related functions - Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. - Contributed by Kresten Krab Thorup - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation; either version 2, or (at your option) any later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -GNU CC; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#include "../tconfig.h" /* include defs of bzero for target */ -#include "runtime.h" /* the kitchen sink */ - -id __objc_object_alloc(Class); -id __objc_object_dispose(id); -id __objc_object_copy(id); - -id (*_objc_object_alloc)(Class) = __objc_object_alloc; /* !T:SINGLE */ -id (*_objc_object_dispose)(id) = __objc_object_dispose; /* !T:SINGLE */ -id (*_objc_object_copy)(id) = __objc_object_copy; /* !T:SINGLE */ - -id -class_create_instance(Class class) -{ - id new = nil; - if (CLS_ISCLASS(class)) - new = (*_objc_object_alloc)(class); - if (new!=nil) - { - memset (new, 0, class->instance_size); - new->class_pointer = class; - } - return new; -} - -id -object_copy(id object) -{ - if ((object!=nil)&&CLS_ISCLASS(object->class_pointer)) - return (*_objc_object_copy)(object); - else - return nil; -} - -id -object_dispose(id object) -{ - if ((object!=nil)&&CLS_ISCLASS(object->class_pointer)) - { - if (_objc_object_dispose) - (*_objc_object_dispose)(object); - else - objc_free(object); - } - return nil; -} - -id __objc_object_alloc(Class class) -{ - return (id)objc_malloc(class->instance_size); -} - -id __objc_object_dispose(id object) -{ - objc_free(object); - return 0; -} - -id __objc_object_copy(id object) -{ - id copy = class_create_instance(object->class_pointer); - memcpy(copy, object, object->class_pointer->instance_size); - return copy; -} - - diff --git a/contrib/gcc/objc/runtime.h b/contrib/gcc/objc/runtime.h deleted file mode 100644 index b0eae4a222d3..000000000000 --- a/contrib/gcc/objc/runtime.h +++ /dev/null @@ -1,88 +0,0 @@ -/* GNU Objective C Runtime internal declarations - Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. - Contributed by Kresten Krab Thorup - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation; either version 2, or (at your option) any later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -GNU CC; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#ifndef __objc_runtime_INCLUDE_GNU -#define __objc_runtime_INCLUDE_GNU - -#include <stdarg.h> /* for varargs and va_list's */ - -#include <stdio.h> -#include <ctype.h> - -#include <stddef.h> /* so noone else will get system versions */ -#include "assert.h" - -#include "objc/objc.h" /* core data types */ -#include "objc/objc-api.h" /* runtime api functions */ - -#include "objc/thr.h" /* thread and mutex support */ - -#include "objc/hash.h" /* hash structures */ -#include "objc/objc-list.h" /* linear lists */ - -extern void __objc_add_class_to_hash(Class); /* (objc-class.c) */ -extern void __objc_init_selector_tables(void); /* (objc-sel.c) */ -extern void __objc_init_class_tables(void); /* (objc-class.c) */ -extern void __objc_init_dispatch_tables(void); /* (objc-dispatch.c) */ -extern void __objc_install_premature_dtable(Class); /* (objc-dispatch.c) */ -extern void __objc_resolve_class_links(void); /* (objc-class.c) */ -extern void __objc_register_selectors_from_class(Class); /* (objc-sel.c) */ -extern void __objc_update_dispatch_table_for_class (Class);/* (objc-msg.c) */ - -extern int __objc_init_thread_system(void); /* thread.c */ -extern int __objc_fini_thread_system(void); /* thread.c */ -extern void __objc_print_dtable_stats(void); /* sendmsg.c */ - -extern void class_add_method_list(Class, MethodList_t); - -/* Registering instance methods as class methods for root classes */ -extern void __objc_register_instance_methods_to_class(Class); -extern Method_t search_for_method_in_list(MethodList_t list, SEL op); - -/* True when class links has been resolved */ -extern BOOL __objc_class_links_resolved; - -/* Number of selectors stored in each of the selector tables */ -extern int __objc_selector_max_index; - -/* Mutex locking __objc_selector_max_index and its arrays. */ -extern objc_mutex_t __objc_runtime_mutex; - -/* Number of threads which are alive. */ -extern int __objc_runtime_threads_alive; - -#ifdef DEBUG -#define DEBUG_PRINTF(format, args...) printf (format, ## args) -#else -#define DEBUG_PRINTF(format, args...) -#endif - -BOOL __objc_responds_to (id object, SEL sel); /* for internal use only! */ -SEL __sel_register_typed_name (const char*, const char*, - struct objc_selector*, BOOL is_const); - -#endif /* not __objc_runtime_INCLUDE_GNU */ - - diff --git a/contrib/gcc/objc/sarray.c b/contrib/gcc/objc/sarray.c deleted file mode 100644 index 7e40fba750f6..000000000000 --- a/contrib/gcc/objc/sarray.c +++ /dev/null @@ -1,522 +0,0 @@ -/* Sparse Arrays for Objective C dispatch tables - Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#include "objc/sarray.h" -#include "objc/runtime.h" -#include <stdio.h> -#include "assert.h" - -int nbuckets = 0; /* !T:MUTEX */ -int nindices = 0; /* !T:MUTEX */ -int narrays = 0; /* !T:MUTEX */ -int idxsize = 0; /* !T:MUTEX */ - -static void * first_free_data = NULL; /* !T:MUTEX */ - -#ifdef OBJC_SPARSE2 -const char* __objc_sparse2_id = "2 level sparse indices"; -#endif - -#ifdef OBJC_SPARSE3 -const char* __objc_sparse3_id = "3 level sparse indices"; -#endif - -#ifdef __alpha__ -const void *memcpy (void*, const void*, size_t); -#endif - -/* This function removes any structures left over from free operations - that were not safe in a multi-threaded environment. */ -void -sarray_remove_garbage(void) -{ - void **vp; - void *np; - - objc_mutex_lock(__objc_runtime_mutex); - - vp = first_free_data; - first_free_data = NULL; - - while (vp) { - np = *vp; - objc_free(vp); - vp = np; - } - - objc_mutex_unlock(__objc_runtime_mutex); -} - -/* Free a block of dynamically allocated memory. If we are in multi-threaded - mode, it is ok to free it. If not, we add it to the garbage heap to be - freed later. */ - -static void -sarray_free_garbage(void *vp) -{ - objc_mutex_lock(__objc_runtime_mutex); - - if (__objc_runtime_threads_alive == 1) { - objc_free(vp); - if (first_free_data) - sarray_remove_garbage(); - } - else { - *(void **)vp = first_free_data; - first_free_data = vp; - } - - objc_mutex_unlock(__objc_runtime_mutex); -} - -/* sarray_at_put : copies data in such a way as to be thread reader safe. */ -void -sarray_at_put(struct sarray* array, sidx index, void* element) -{ -#ifdef OBJC_SPARSE3 - struct sindex** the_index; - struct sindex* new_index; -#endif - struct sbucket** the_bucket; - struct sbucket* new_bucket; -#ifdef OBJC_SPARSE3 - size_t ioffset; -#endif - size_t boffset; - size_t eoffset; -#ifdef PRECOMPUTE_SELECTORS - union sofftype xx; - xx.idx = index; -#ifdef OBJC_SPARSE3 - ioffset = xx.off.ioffset; -#endif - boffset = xx.off.boffset; - eoffset = xx.off.eoffset; -#else /* not PRECOMPUTE_SELECTORS */ -#ifdef OBJC_SPARSE3 - ioffset = index/INDEX_CAPACITY; - boffset = (index/BUCKET_SIZE)%INDEX_SIZE; - eoffset = index%BUCKET_SIZE; -#else - boffset = index/BUCKET_SIZE; - eoffset = index%BUCKET_SIZE; -#endif -#endif /* not PRECOMPUTE_SELECTORS */ - - assert(soffset_decode(index) < array->capacity); /* Range check */ - -#ifdef OBJC_SPARSE3 - the_index = &(array->indices[ioffset]); - the_bucket = &((*the_index)->buckets[boffset]); -#else - the_bucket = &(array->buckets[boffset]); -#endif - - if ((*the_bucket)->elems[eoffset] == element) - return; /* great! we just avoided a lazy copy */ - -#ifdef OBJC_SPARSE3 - - /* First, perform lazy copy/allocation of index if needed */ - - if ((*the_index) == array->empty_index) { - - /* The index was previously empty, allocate a new */ - new_index = (struct sindex*)objc_malloc(sizeof(struct sindex)); - memcpy(new_index, array->empty_index, sizeof(struct sindex)); - new_index->version.version = array->version.version; - *the_index = new_index; /* Prepared for install. */ - the_bucket = &((*the_index)->buckets[boffset]); - - nindices += 1; - } else if ((*the_index)->version.version != array->version.version) { - - /* This index must be lazy copied */ - struct sindex* old_index = *the_index; - new_index = (struct sindex*)objc_malloc(sizeof(struct sindex)); - memcpy( new_index, old_index, sizeof(struct sindex)); - new_index->version.version = array->version.version; - *the_index = new_index; /* Prepared for install. */ - the_bucket = &((*the_index)->buckets[boffset]); - - nindices += 1; - } - -#endif /* OBJC_SPARSE3 */ - - /* next, perform lazy allocation/copy of the bucket if needed */ - - if ((*the_bucket) == array->empty_bucket) { - - /* The bucket was previously empty (or something like that), */ - /* allocate a new. This is the effect of `lazy' allocation */ - new_bucket = (struct sbucket*)objc_malloc(sizeof(struct sbucket)); - memcpy((void *) new_bucket, (const void*)array->empty_bucket, - sizeof(struct sbucket)); - new_bucket->version.version = array->version.version; - *the_bucket = new_bucket; /* Prepared for install. */ - - nbuckets += 1; - - } else if ((*the_bucket)->version.version != array->version.version) { - - /* Perform lazy copy. */ - struct sbucket* old_bucket = *the_bucket; - new_bucket = (struct sbucket*)objc_malloc(sizeof(struct sbucket)); - memcpy( new_bucket, old_bucket, sizeof(struct sbucket)); - new_bucket->version.version = array->version.version; - *the_bucket = new_bucket; /* Prepared for install. */ - - nbuckets += 1; - - } - (*the_bucket)->elems[eoffset] = element; -} - -void -sarray_at_put_safe(struct sarray* array, sidx index, void* element) -{ - if(soffset_decode(index) >= array->capacity) - sarray_realloc(array, soffset_decode(index)+1); - sarray_at_put(array, index, element); -} - -struct sarray* -sarray_new (int size, void* default_element) -{ - struct sarray* arr; -#ifdef OBJC_SPARSE3 - size_t num_indices = ((size-1)/(INDEX_CAPACITY))+1; - struct sindex ** new_indices; -#else /* OBJC_SPARSE2 */ - size_t num_indices = ((size-1)/BUCKET_SIZE)+1; - struct sbucket ** new_buckets; -#endif - int counter; - - assert(size > 0); - - /* Allocate core array */ - arr = (struct sarray*) objc_malloc(sizeof(struct sarray)); - arr->version.version = 0; - - /* Initialize members */ -#ifdef OBJC_SPARSE3 - arr->capacity = num_indices*INDEX_CAPACITY; - new_indices = (struct sindex**) - objc_malloc(sizeof(struct sindex*)*num_indices); - - arr->empty_index = (struct sindex*) objc_malloc(sizeof(struct sindex)); - arr->empty_index->version.version = 0; - - narrays += 1; - idxsize += num_indices; - nindices += 1; - -#else /* OBJC_SPARSE2 */ - arr->capacity = num_indices*BUCKET_SIZE; - new_buckets = (struct sbucket**) - objc_malloc(sizeof(struct sbucket*)*num_indices); - - narrays += 1; - idxsize += num_indices; - -#endif - - arr->empty_bucket = (struct sbucket*) objc_malloc(sizeof(struct sbucket)); - arr->empty_bucket->version.version = 0; - - nbuckets += 1; - - arr->ref_count = 1; - arr->is_copy_of = (struct sarray*)0; - - for (counter=0; counter<BUCKET_SIZE; counter++) - arr->empty_bucket->elems[counter] = default_element; - -#ifdef OBJC_SPARSE3 - for (counter=0; counter<INDEX_SIZE; counter++) - arr->empty_index->buckets[counter] = arr->empty_bucket; - - for (counter=0; counter<num_indices; counter++) - new_indices[counter] = arr->empty_index; - -#else /* OBJC_SPARSE2 */ - - for (counter=0; counter<num_indices; counter++) - new_buckets[counter] = arr->empty_bucket; - -#endif - -#ifdef OBJC_SPARSE3 - arr->indices = new_indices; -#else /* OBJC_SPARSE2 */ - arr->buckets = new_buckets; -#endif - - return arr; -} - - -/* Reallocate the sparse array to hold `newsize' entries - Note: We really allocate and then free. We have to do this to ensure that - any concurrent readers notice the update. */ - -void -sarray_realloc(struct sarray* array, int newsize) -{ -#ifdef OBJC_SPARSE3 - size_t old_max_index = (array->capacity-1)/INDEX_CAPACITY; - size_t new_max_index = ((newsize-1)/INDEX_CAPACITY); - size_t rounded_size = (new_max_index+1)*INDEX_CAPACITY; - - struct sindex ** new_indices; - struct sindex ** old_indices; - -#else /* OBJC_SPARSE2 */ - size_t old_max_index = (array->capacity-1)/BUCKET_SIZE; - size_t new_max_index = ((newsize-1)/BUCKET_SIZE); - size_t rounded_size = (new_max_index+1)*BUCKET_SIZE; - - struct sbucket ** new_buckets; - struct sbucket ** old_buckets; - -#endif - - int counter; - - assert(newsize > 0); - - /* The size is the same, just ignore the request */ - if(rounded_size <= array->capacity) - return; - - assert(array->ref_count == 1); /* stop if lazy copied... */ - - /* We are asked to extend the array -- allocate new bucket table, */ - /* and insert empty_bucket in newly allocated places. */ - if(rounded_size > array->capacity) - { - -#ifdef OBJC_SPARSE3 - new_max_index += 4; - rounded_size = (new_max_index+1)*INDEX_CAPACITY; - -#else /* OBJC_SPARSE2 */ - new_max_index += 4; - rounded_size = (new_max_index+1)*BUCKET_SIZE; -#endif - - /* update capacity */ - array->capacity = rounded_size; - -#ifdef OBJC_SPARSE3 - /* alloc to force re-read by any concurrent readers. */ - old_indices = array->indices; - new_indices = (struct sindex**) - objc_malloc((new_max_index+1)*sizeof(struct sindex*)); -#else /* OBJC_SPARSE2 */ - old_buckets = array->buckets; - new_buckets = (struct sbucket**) - objc_malloc((new_max_index+1)*sizeof(struct sbucket*)); -#endif - - /* copy buckets below old_max_index (they are still valid) */ - for(counter = 0; counter <= old_max_index; counter++ ) { -#ifdef OBJC_SPARSE3 - new_indices[counter] = old_indices[counter]; -#else /* OBJC_SPARSE2 */ - new_buckets[counter] = old_buckets[counter]; -#endif - } - -#ifdef OBJC_SPARSE3 - /* reset entries above old_max_index to empty_bucket */ - for(counter = old_max_index+1; counter <= new_max_index; counter++) - new_indices[counter] = array->empty_index; -#else /* OBJC_SPARSE2 */ - /* reset entries above old_max_index to empty_bucket */ - for(counter = old_max_index+1; counter <= new_max_index; counter++) - new_buckets[counter] = array->empty_bucket; -#endif - -#ifdef OBJC_SPARSE3 - /* install the new indices */ - array->indices = new_indices; -#else /* OBJC_SPARSE2 */ - array->buckets = new_buckets; -#endif - -#ifdef OBJC_SPARSE3 - /* free the old indices */ - sarray_free_garbage(old_indices); -#else /* OBJC_SPARSE2 */ - sarray_free_garbage(old_buckets); -#endif - - idxsize += (new_max_index-old_max_index); - return; - } -} - - -/* Free a sparse array allocated with sarray_new */ - -void -sarray_free(struct sarray* array) { - -#ifdef OBJC_SPARSE3 - size_t old_max_index = (array->capacity-1)/INDEX_CAPACITY; - struct sindex ** old_indices; -#else - size_t old_max_index = (array->capacity-1)/BUCKET_SIZE; - struct sbucket ** old_buckets; -#endif - int counter = 0; - - assert(array->ref_count != 0); /* Freed multiple times!!! */ - - if(--(array->ref_count) != 0) /* There exists copies of me */ - return; - -#ifdef OBJC_SPARSE3 - old_indices = array->indices; -#else - old_buckets = array->buckets; -#endif - - if((array->is_copy_of) && ((array->is_copy_of->ref_count - 1) == 0)) - sarray_free(array->is_copy_of); - - /* Free all entries that do not point to empty_bucket */ - for(counter = 0; counter <= old_max_index; counter++ ) { -#ifdef OBJC_SPARSE3 - struct sindex* idx = old_indices[counter]; - if((idx != array->empty_index) && - (idx->version.version == array->version.version)) { - int c2; - for(c2=0; c2<INDEX_SIZE; c2++) { - struct sbucket* bkt = idx->buckets[c2]; - if((bkt != array->empty_bucket) && - (bkt->version.version == array->version.version)) - { - sarray_free_garbage(bkt); - nbuckets -= 1; - } - } - sarray_free_garbage(idx); - nindices -= 1; - } -#else /* OBJC_SPARSE2 */ - struct sbucket* bkt = array->buckets[counter]; - if ((bkt != array->empty_bucket) && - (bkt->version.version == array->version.version)) - { - sarray_free_garbage(bkt); - nbuckets -= 1; - } -#endif - } - -#ifdef OBJC_SPARSE3 - /* free empty_index */ - if(array->empty_index->version.version == array->version.version) { - sarray_free_garbage(array->empty_index); - nindices -= 1; - } -#endif - - /* free empty_bucket */ - if(array->empty_bucket->version.version == array->version.version) { - sarray_free_garbage(array->empty_bucket); - nbuckets -= 1; - } - idxsize -= (old_max_index+1); - narrays -= 1; - -#ifdef OBJC_SPARSE3 - /* free bucket table */ - sarray_free_garbage(array->indices); - -#else - /* free bucket table */ - sarray_free_garbage(array->buckets); - -#endif - - /* free array */ - sarray_free_garbage(array); -} - -/* This is a lazy copy. Only the core of the structure is actually */ -/* copied. */ - -struct sarray* -sarray_lazy_copy(struct sarray* oarr) -{ - struct sarray* arr; - -#ifdef OBJC_SPARSE3 - size_t num_indices = ((oarr->capacity-1)/INDEX_CAPACITY)+1; - struct sindex ** new_indices; -#else /* OBJC_SPARSE2 */ - size_t num_indices = ((oarr->capacity-1)/BUCKET_SIZE)+1; - struct sbucket ** new_buckets; -#endif - - /* Allocate core array */ - arr = (struct sarray*) objc_malloc(sizeof(struct sarray)); /* !!! */ - arr->version.version = oarr->version.version + 1; -#ifdef OBJC_SPARSE3 - arr->empty_index = oarr->empty_index; -#endif - arr->empty_bucket = oarr->empty_bucket; - arr->ref_count = 1; - oarr->ref_count += 1; - arr->is_copy_of = oarr; - arr->capacity = oarr->capacity; - -#ifdef OBJC_SPARSE3 - /* Copy bucket table */ - new_indices = (struct sindex**) - objc_malloc(sizeof(struct sindex*)*num_indices); - memcpy( new_indices,oarr->indices, - sizeof(struct sindex*)*num_indices); - arr->indices = new_indices; -#else - /* Copy bucket table */ - new_buckets = (struct sbucket**) - objc_malloc(sizeof(struct sbucket*)*num_indices); - memcpy( new_buckets,oarr->buckets, - sizeof(struct sbucket*)*num_indices); - arr->buckets = new_buckets; -#endif - - idxsize += num_indices; - narrays += 1; - - return arr; -} diff --git a/contrib/gcc/objc/sarray.h b/contrib/gcc/objc/sarray.h deleted file mode 100644 index 74fa38652ba3..000000000000 --- a/contrib/gcc/objc/sarray.h +++ /dev/null @@ -1,237 +0,0 @@ -/* Sparse Arrays for Objective C dispatch tables - Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. - Contributed by Kresten Krab Thorup. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -#ifndef __sarray_INCLUDE_GNU -#define __sarray_INCLUDE_GNU - -#define OBJC_SPARSE2 /* 2-level sparse array */ -/* #define OBJC_SPARSE3 */ /* 3-level sparse array */ - -#ifdef OBJC_SPARSE2 -extern const char* __objc_sparse2_id; -#endif - -#ifdef OBJC_SPARSE3 -extern const char* __objc_sparse3_id; -#endif - -#include <stddef.h> - -#include "objc/thr.h" - -extern int nbuckets; /* for stats */ -extern int nindices; -extern int narrays; -extern int idxsize; - -#include <assert.h> - -/* An unsigned integer of same size as a pointer */ -#define SIZET_BITS (sizeof(size_t)*8) - -#if defined(__sparc__) || defined(OBJC_SPARSE2) -#define PRECOMPUTE_SELECTORS -#endif - -#ifdef OBJC_SPARSE3 - -/* Buckets are 8 words each */ -#define BUCKET_BITS 3 -#define BUCKET_SIZE (1<<BUCKET_BITS) -#define BUCKET_MASK (BUCKET_SIZE-1) - -/* Indices are 16 words each */ -#define INDEX_BITS 4 -#define INDEX_SIZE (1<<INDEX_BITS) -#define INDEX_MASK (INDEX_SIZE-1) - -#define INDEX_CAPACITY (BUCKET_SIZE*INDEX_SIZE) - -#else /* OBJC_SPARSE2 */ - -/* Buckets are 32 words each */ -#define BUCKET_BITS 5 -#define BUCKET_SIZE (1<<BUCKET_BITS) -#define BUCKET_MASK (BUCKET_SIZE-1) - -#endif /* OBJC_SPARSE2 */ - -typedef size_t sidx; - -#ifdef PRECOMPUTE_SELECTORS - -struct soffset { -#ifdef OBJC_SPARSE3 - unsigned int unused : SIZET_BITS/4; - unsigned int eoffset : SIZET_BITS/4; - unsigned int boffset : SIZET_BITS/4; - unsigned int ioffset : SIZET_BITS/4; -#else /* OBJC_SPARSE2 */ -#ifdef __sparc__ - unsigned int boffset : (SIZET_BITS - 2) - BUCKET_BITS; - unsigned int eoffset : BUCKET_BITS; - unsigned int unused : 2; -#else - unsigned int boffset : SIZET_BITS/2; - unsigned int eoffset : SIZET_BITS/2; -#endif -#endif /* OBJC_SPARSE2 */ -}; - -union sofftype { - struct soffset off; - sidx idx; -}; - -#endif /* not PRECOMPUTE_SELECTORS */ - -union sversion { - int version; - void *next_free; -}; - -struct sbucket { - void* elems[BUCKET_SIZE]; /* elements stored in array */ - union sversion version; /* used for copy-on-write */ -}; - -#ifdef OBJC_SPARSE3 - -struct sindex { - struct sbucket* buckets[INDEX_SIZE]; - union sversion version; /* used for copy-on-write */ -}; - -#endif /* OBJC_SPARSE3 */ - -struct sarray { -#ifdef OBJC_SPARSE3 - struct sindex** indices; - struct sindex* empty_index; -#else /* OBJC_SPARSE2 */ - struct sbucket** buckets; -#endif /* OBJC_SPARSE2 */ - struct sbucket* empty_bucket; - union sversion version; /* used for copy-on-write */ - short ref_count; - struct sarray* is_copy_of; - size_t capacity; -}; - -struct sarray* sarray_new(int, void* default_element); -void sarray_free(struct sarray*); -struct sarray* sarray_lazy_copy(struct sarray*); -void sarray_realloc(struct sarray*, int new_size); -void sarray_at_put(struct sarray*, sidx index, void* elem); -void sarray_at_put_safe(struct sarray*, sidx index, void* elem); - -struct sarray* sarray_hard_copy(struct sarray*); /* ... like the name? */ -void sarray_remove_garbage(void); - - -#ifdef PRECOMPUTE_SELECTORS -/* Transform soffset values to ints and vica verca */ -static inline unsigned int -soffset_decode(sidx index) -{ - union sofftype x; - x.idx = index; -#ifdef OBJC_SPARSE3 - return x.off.eoffset - + (x.off.boffset*BUCKET_SIZE) - + (x.off.ioffset*INDEX_CAPACITY); -#else /* OBJC_SPARSE2 */ - return x.off.eoffset + (x.off.boffset*BUCKET_SIZE); -#endif /* OBJC_SPARSE2 */ -} - -static inline sidx -soffset_encode(size_t offset) -{ - union sofftype x; - x.off.eoffset = offset%BUCKET_SIZE; -#ifdef OBJC_SPARSE3 - x.off.boffset = (offset/BUCKET_SIZE)%INDEX_SIZE; - x.off.ioffset = offset/INDEX_CAPACITY; -#else /* OBJC_SPARSE2 */ - x.off.boffset = offset/BUCKET_SIZE; -#endif - return (sidx)x.idx; -} - -#else /* not PRECOMPUTE_SELECTORS */ - -static inline size_t -soffset_decode(sidx index) -{ - return index; -} - -static inline sidx -soffset_encode(size_t offset) -{ - return offset; -} -#endif /* not PRECOMPUTE_SELECTORS */ - -/* Get element from the Sparse array `array' at offset `index' */ - -static inline void* sarray_get(struct sarray* array, sidx index) -{ -#ifdef PRECOMPUTE_SELECTORS - union sofftype x; - x.idx = index; -#ifdef OBJC_SPARSE3 - return - array-> - indices[x.off.ioffset]-> - buckets[x.off.boffset]-> - elems[x.off.eoffset]; -#else /* OBJC_SPARSE2 */ - return array->buckets[x.off.boffset]->elems[x.off.eoffset]; -#endif /* OBJC_SPARSE2 */ -#else /* not PRECOMPUTE_SELECTORS */ -#ifdef OBJC_SPARSE3 - return array-> - indices[index/INDEX_CAPACITY]-> - buckets[(index/BUCKET_SIZE)%INDEX_SIZE]-> - elems[index%BUCKET_SIZE]; -#else /* OBJC_SPARSE2 */ - return array->buckets[index/BUCKET_SIZE]->elems[index%BUCKET_SIZE]; -#endif /* not OBJC_SPARSE3 */ -#endif /* not PRECOMPUTE_SELECTORS */ -} - -static inline void* sarray_get_safe(struct sarray* array, sidx index) -{ - if(soffset_decode(index) < array->capacity) - return sarray_get(array, index); - else - return (array->empty_bucket->elems[0]); -} - -#endif /* __sarray_INCLUDE_GNU */ diff --git a/contrib/gcc/objc/selector.c b/contrib/gcc/objc/selector.c deleted file mode 100644 index 83c70e4ae0f1..000000000000 --- a/contrib/gcc/objc/selector.c +++ /dev/null @@ -1,458 +0,0 @@ -/* GNU Objective C Runtime selector related functions - Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. - Contributed by Kresten Krab Thorup - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation; either version 2, or (at your option) any later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -GNU CC; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#include "runtime.h" -#include "objc/sarray.h" -#include "encoding.h" - -/* Initial selector hash table size. Value doesn't matter much */ -#define SELECTOR_HASH_SIZE 128 - -/* Tables mapping selector names to uid and opposite */ -static struct sarray* __objc_selector_array = 0; /* uid -> sel !T:MUTEX */ -static struct sarray* __objc_selector_names = 0; /* uid -> name !T:MUTEX */ -static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */ - -static void register_selectors_from_list(MethodList_t); - -/* Number of selectors stored in each of the above tables */ -int __objc_selector_max_index = 0; /* !T:MUTEX */ - -void __objc_init_selector_tables() -{ - __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0); - __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0); - __objc_selector_hash - = hash_new (SELECTOR_HASH_SIZE, - (hash_func_type) hash_string, - (compare_func_type) compare_strings); -} - -/* This routine is given a class and records all of the methods in its class - structure in the record table. */ -void -__objc_register_selectors_from_class (Class class) -{ - MethodList_t method_list; - - method_list = class->methods; - while (method_list) - { - register_selectors_from_list (method_list); - method_list = method_list->method_next; - } -} - - -/* This routine is given a list of methods and records each of the methods in - the record table. This is the routine that does the actual recording - work. - - This one is only called for Class objects. For categories, - class_add_method_list is called. - */ -static void -register_selectors_from_list (MethodList_t method_list) -{ - int i = 0; - while (i < method_list->method_count) - { - Method_t method = &method_list->method_list[i]; - method->method_name - = sel_register_typed_name ((const char*)method->method_name, - method->method_types); - i += 1; - } -} - - -/* Register instance methods as class methods for root classes */ -void __objc_register_instance_methods_to_class(Class class) -{ - MethodList_t method_list; - MethodList_t class_method_list; - int max_methods_no = 16; - MethodList_t new_list; - Method_t curr_method; - - /* Only if a root class. */ - if(class->super_class) - return; - - /* Allocate a method list to hold the new class methods */ - new_list = objc_calloc(sizeof(struct objc_method_list) - + sizeof(struct objc_method[max_methods_no]), 1); - method_list = class->methods; - class_method_list = class->class_pointer->methods; - curr_method = &new_list->method_list[0]; - - /* Iterate through the method lists for the class */ - while (method_list) - { - int i; - - /* Iterate through the methods from this method list */ - for (i = 0; i < method_list->method_count; i++) - { - Method_t mth = &method_list->method_list[i]; - if (mth->method_name - && !search_for_method_in_list (class_method_list, - mth->method_name)) - { - /* This instance method isn't a class method. - Add it into the new_list. */ - *curr_method = *mth; - - /* Reallocate the method list if necessary */ - if(++new_list->method_count == max_methods_no) - new_list = - objc_realloc(new_list, sizeof(struct objc_method_list) - + sizeof(struct - objc_method[max_methods_no += 16])); - curr_method = &new_list->method_list[new_list->method_count]; - } - } - - method_list = method_list->method_next; - } - - /* If we created any new class methods - then attach the method list to the class */ - if (new_list->method_count) - { - new_list = - objc_realloc(new_list, sizeof(struct objc_method_list) - + sizeof(struct objc_method[new_list->method_count])); - new_list->method_next = class->class_pointer->methods; - class->class_pointer->methods = new_list; - } - - __objc_update_dispatch_table_for_class (class->class_pointer); -} - - -/* Returns YES iff t1 and t2 have same method types, but we ignore - the argframe layout */ -BOOL -sel_types_match (const char* t1, const char* t2) -{ - if (!t1 || !t2) - return NO; - while (*t1 && *t2) - { - if (*t1 == '+') t1++; - if (*t2 == '+') t2++; - while (isdigit(*t1)) t1++; - while (isdigit(*t2)) t2++; - /* xxx Remove these next two lines when qualifiers are put in - all selectors, not just Protocol selectors. */ - t1 = objc_skip_type_qualifiers(t1); - t2 = objc_skip_type_qualifiers(t2); - if (!*t1 && !*t2) - return YES; - if (*t1 != *t2) - return NO; - t1++; - t2++; - } - return NO; -} - -/* return selector representing name */ -SEL -sel_get_typed_uid (const char *name, const char *types) -{ - struct objc_list *l; - sidx i; - - objc_mutex_lock(__objc_runtime_mutex); - - i = (sidx) hash_value_for_key (__objc_selector_hash, name); - if (i == 0) - { - objc_mutex_unlock(__objc_runtime_mutex); - return 0; - } - - for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); - l; l = l->tail) - { - SEL s = (SEL)l->head; - if (types == 0 || s->sel_types == 0) - { - if (s->sel_types == types) - { - objc_mutex_unlock(__objc_runtime_mutex); - return s; - } - } - else if (sel_types_match (s->sel_types, types)) - { - objc_mutex_unlock(__objc_runtime_mutex); - return s; - } - } - - objc_mutex_unlock(__objc_runtime_mutex); - return 0; -} - -/* Return selector representing name; prefer a selector with non-NULL type */ -SEL -sel_get_any_typed_uid (const char *name) -{ - struct objc_list *l; - sidx i; - SEL s = NULL; - - objc_mutex_lock(__objc_runtime_mutex); - - i = (sidx) hash_value_for_key (__objc_selector_hash, name); - if (i == 0) - { - objc_mutex_unlock(__objc_runtime_mutex); - return 0; - } - - for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); - l; l = l->tail) - { - s = (SEL) l->head; - if (s->sel_types) - { - objc_mutex_unlock(__objc_runtime_mutex); - return s; - } - } - - objc_mutex_unlock(__objc_runtime_mutex); - return s; -} - -/* return selector representing name */ -SEL -sel_get_any_uid (const char *name) -{ - struct objc_list *l; - sidx i; - - objc_mutex_lock(__objc_runtime_mutex); - - i = (sidx) hash_value_for_key (__objc_selector_hash, name); - if (soffset_decode (i) == 0) - { - objc_mutex_unlock(__objc_runtime_mutex); - return 0; - } - - l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); - objc_mutex_unlock(__objc_runtime_mutex); - - if (l == 0) - return 0; - - return (SEL)l->head; -} - -/* return selector representing name */ -SEL -sel_get_uid (const char *name) -{ - return sel_register_typed_name (name, 0); -} - -/* Get name of selector. If selector is unknown, the empty string "" - is returned */ -const char* -sel_get_name (SEL selector) -{ - const char *ret; - - objc_mutex_lock(__objc_runtime_mutex); - if ((soffset_decode((sidx)selector->sel_id) > 0) - && (soffset_decode((sidx)selector->sel_id) <= __objc_selector_max_index)) - ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id); - else - ret = 0; - objc_mutex_unlock(__objc_runtime_mutex); - return ret; -} - -BOOL -sel_is_mapped (SEL selector) -{ - unsigned int idx = soffset_decode ((sidx)selector->sel_id); - return ((idx > 0) && (idx <= __objc_selector_max_index)); -} - - -const char* -sel_get_type (SEL selector) -{ - if (selector) - return selector->sel_types; - else - return 0; -} - -/* The uninstalled dispatch table */ -extern struct sarray* __objc_uninstalled_dtable; - -/* Store the passed selector name in the selector record and return its - selector value (value returned by sel_get_uid). - Assumes that the calling function has locked down __objc_runtime_mutex. */ -/* is_const parameter tells us if the name and types parameters - are really constant or not. If YES then they are constant and - we can just store the pointers. If NO then we need to copy - name and types because the pointers may disappear later on. */ -SEL -__sel_register_typed_name (const char *name, const char *types, - struct objc_selector *orig, BOOL is_const) -{ - struct objc_selector* j; - sidx i; - struct objc_list *l; - - i = (sidx) hash_value_for_key (__objc_selector_hash, name); - if (soffset_decode (i) != 0) - { - for (l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); - l; l = l->tail) - { - SEL s = (SEL)l->head; - if (types == 0 || s->sel_types == 0) - { - if (s->sel_types == types) - { - if (orig) - { - orig->sel_id = (void*)i; - return orig; - } - else - return s; - } - } - else if (!strcmp (s->sel_types, types)) - { - if (orig) - { - orig->sel_id = (void*)i; - return orig; - } - else - return s; - } - } - if (orig) - j = orig; - else - j = objc_malloc (sizeof (struct objc_selector)); - - j->sel_id = (void*)i; - /* Can we use the pointer or must copy types? Don't copy if NULL */ - if ((is_const) || (types == 0)) - j->sel_types = (const char*)types; - else { - j->sel_types = (char *) objc_malloc(strlen(types)+1); - strcpy((char *)j->sel_types, types); - } - l = (struct objc_list*)sarray_get_safe (__objc_selector_array, i); - } - else - { - __objc_selector_max_index += 1; - i = soffset_encode(__objc_selector_max_index); - if (orig) - j = orig; - else - j = objc_malloc (sizeof (struct objc_selector)); - - j->sel_id = (void*)i; - /* Can we use the pointer or must copy types? Don't copy if NULL */ - if ((is_const) || (types == 0)) - j->sel_types = (const char*)types; - else { - j->sel_types = (char *) objc_malloc(strlen(types)+1); - strcpy((char *)j->sel_types, types); - } - l = 0; - } - - DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types, - soffset_decode (i)); - - { - int is_new = (l == 0); - const char *new_name; - - /* Can we use the pointer or must copy name? Don't copy if NULL */ - if ((is_const) || (name == 0)) - new_name = name; - else { - new_name = (char *) objc_malloc(strlen(name)+1); - strcpy((char *)new_name, name); - } - - l = list_cons ((void*)j, l); - sarray_at_put_safe (__objc_selector_names, i, (void *) new_name); - sarray_at_put_safe (__objc_selector_array, i, (void *) l); - if (is_new) - hash_add (&__objc_selector_hash, (void *) new_name, (void *) i); - } - - sarray_realloc(__objc_uninstalled_dtable, __objc_selector_max_index+1); - - return (SEL) j; -} - -SEL -sel_register_name (const char *name) -{ - SEL ret; - - objc_mutex_lock(__objc_runtime_mutex); - /* Assume that name is not constant static memory and needs to be - copied before put into a runtime structure. is_const == NO */ - ret = __sel_register_typed_name (name, 0, 0, NO); - objc_mutex_unlock(__objc_runtime_mutex); - - return ret; -} - -SEL -sel_register_typed_name (const char *name, const char *type) -{ - SEL ret; - - objc_mutex_lock(__objc_runtime_mutex); - /* Assume that name and type are not constant static memory and need to - be copied before put into a runtime structure. is_const == NO */ - ret = __sel_register_typed_name (name, type, 0, NO); - objc_mutex_unlock(__objc_runtime_mutex); - - return ret; -} - diff --git a/contrib/gcc/objc/sendmsg.c b/contrib/gcc/objc/sendmsg.c deleted file mode 100644 index 245b8b9eaf79..000000000000 --- a/contrib/gcc/objc/sendmsg.c +++ /dev/null @@ -1,651 +0,0 @@ -/* GNU Objective C Runtime message lookup - Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - Contributed by Kresten Krab Thorup - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation; either version 2, or (at your option) any later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -details. - -You should have received a copy of the GNU General Public License along with -GNU CC; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled with - GCC to produce an executable, this does not cause the resulting executable - to be covered by the GNU General Public License. This exception does not - however invalidate any other reasons why the executable file might be - covered by the GNU General Public License. */ - -#include "../tconfig.h" -#include "runtime.h" -#include "sarray.h" -#include "encoding.h" -#include "runtime-info.h" - -/* this is how we hack STRUCT_VALUE to be 1 or 0 */ -#define gen_rtx(args...) 1 -#define gen_rtx_MEM(args...) 1 -#define rtx int - -#if !defined(STRUCT_VALUE) || STRUCT_VALUE == 0 -#define INVISIBLE_STRUCT_RETURN 1 -#else -#define INVISIBLE_STRUCT_RETURN 0 -#endif - -/* The uninstalled dispatch table */ -struct sarray* __objc_uninstalled_dtable = 0; /* !T:MUTEX */ - -/* Send +initialize to class */ -static void __objc_send_initialize(Class); - -static void __objc_install_dispatch_table_for_class (Class); - -/* Forward declare some functions */ -static void __objc_init_install_dtable(id, SEL); - -/* Various forwarding functions that are used based upon the - return type for the selector. - __objc_block_forward for structures. - __objc_double_forward for floats/doubles. - __objc_word_forward for pointers or types that fit in registers. - */ -static double __objc_double_forward(id, SEL, ...); -static id __objc_word_forward(id, SEL, ...); -typedef struct { id many[8]; } __big; -#if INVISIBLE_STRUCT_RETURN -static __big -#else -static id -#endif -__objc_block_forward(id, SEL, ...); -static Method_t search_for_method_in_hierarchy (Class class, SEL sel); -Method_t search_for_method_in_list(MethodList_t list, SEL op); -id nil_method(id, SEL, ...); - -/* Given a selector, return the proper forwarding implementation. */ -__inline__ -IMP -__objc_get_forward_imp (SEL sel) -{ - const char *t = sel->sel_types; - - if (t && (*t == '[' || *t == '(' || *t == '{') -#ifdef OBJC_MAX_STRUCT_BY_VALUE - && objc_sizeof_type(t) > OBJC_MAX_STRUCT_BY_VALUE -#endif - ) - return (IMP)__objc_block_forward; - else if (t && (*t == 'f' || *t == 'd')) - return (IMP)__objc_double_forward; - else - return (IMP)__objc_word_forward; -} - -/* Given a class and selector, return the selector's implementation. */ -__inline__ -IMP -get_imp (Class class, SEL sel) -{ - void* res = sarray_get_safe (class->dtable, (size_t) sel->sel_id); - if (res == 0) - { - /* Not a valid method */ - if(class->dtable == __objc_uninstalled_dtable) - { - /* The dispatch table needs to be installed. */ - objc_mutex_lock(__objc_runtime_mutex); - __objc_install_dispatch_table_for_class (class); - objc_mutex_unlock(__objc_runtime_mutex); - /* Call ourselves with the installed dispatch table - and get the real method */ - res = get_imp(class, sel); - } - else - { - /* The dispatch table has been installed so the - method just doesn't exist for the class. - Return the forwarding implementation. */ - res = __objc_get_forward_imp(sel); - } - } - return res; -} - -/* Query if an object can respond to a selector, returns YES if the -object implements the selector otherwise NO. Does not check if the -method can be forwarded. */ -__inline__ -BOOL -__objc_responds_to (id object, SEL sel) -{ - void* res; - - /* Install dispatch table if need be */ - if (object->class_pointer->dtable == __objc_uninstalled_dtable) - { - objc_mutex_lock(__objc_runtime_mutex); - __objc_install_dispatch_table_for_class (object->class_pointer); - objc_mutex_unlock(__objc_runtime_mutex); - } - - /* Get the method from the dispatch table */ - res = sarray_get_safe (object->class_pointer->dtable, (size_t) sel->sel_id); - return (res != 0); -} - -/* This is the lookup function. All entries in the table are either a - valid method *or* zero. If zero then either the dispatch table - needs to be installed or it doesn't exist and forwarding is attempted. */ -__inline__ -IMP -objc_msg_lookup(id receiver, SEL op) -{ - IMP result; - if(receiver) - { - result = sarray_get_safe (receiver->class_pointer->dtable, - (sidx)op->sel_id); - if (result == 0) - { - /* Not a valid method */ - if(receiver->class_pointer->dtable == __objc_uninstalled_dtable) - { - /* The dispatch table needs to be installed. - This happens on the very first method call to the class. */ - __objc_init_install_dtable(receiver, op); - - /* Get real method for this in newly installed dtable */ - result = get_imp(receiver->class_pointer, op); - } - else - { - /* The dispatch table has been installed so the - method just doesn't exist for the class. - Attempt to forward the method. */ - result = __objc_get_forward_imp(op); - } - } - return result; - } - else - return nil_method; -} - -IMP -objc_msg_lookup_super (Super_t super, SEL sel) -{ - if (super->self) - return get_imp (super->class, sel); - else - return nil_method; -} - -int method_get_sizeof_arguments (Method*); - -retval_t -objc_msg_sendv(id object, SEL op, arglist_t arg_frame) -{ - Method* m = class_get_instance_method(object->class_pointer, op); - const char *type; - *((id*)method_get_first_argument (m, arg_frame, &type)) = object; - *((SEL*)method_get_next_argument (arg_frame, &type)) = op; - return __builtin_apply((apply_t)m->method_imp, - arg_frame, - method_get_sizeof_arguments (m)); -} - -void -__objc_init_dispatch_tables() -{ - __objc_uninstalled_dtable - = sarray_new(200, 0); -} - -/* This function is called by objc_msg_lookup when the - dispatch table needs to be installed; thus it is called once - for each class, namely when the very first message is sent to it. */ -static void -__objc_init_install_dtable(id receiver, SEL op) -{ - /* This may happen, if the programmer has taken the address of a - method before the dtable was initialized... too bad for him! */ - if(receiver->class_pointer->dtable != __objc_uninstalled_dtable) - return; - - objc_mutex_lock(__objc_runtime_mutex); - - if(CLS_ISCLASS(receiver->class_pointer)) - { - /* receiver is an ordinary object */ - assert(CLS_ISCLASS(receiver->class_pointer)); - - /* install instance methods table */ - __objc_install_dispatch_table_for_class (receiver->class_pointer); - - /* call +initialize -- this will in turn install the factory - dispatch table if not already done :-) */ - __objc_send_initialize(receiver->class_pointer); - } - else - { - /* receiver is a class object */ - assert(CLS_ISCLASS((Class)receiver)); - assert(CLS_ISMETA(receiver->class_pointer)); - - /* 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); -} - -/* Install dummy table for class which causes the first message to - that class (or instances hereof) to be initialized properly */ -void -__objc_install_premature_dtable(Class class) -{ - assert(__objc_uninstalled_dtable); - class->dtable = __objc_uninstalled_dtable; -} - -/* Send +initialize to class if not already done */ -static void -__objc_send_initialize(Class class) -{ - /* This *must* be a class object */ - assert(CLS_ISCLASS(class)); - assert(!CLS_ISMETA(class)); - - if (!CLS_ISINITIALIZED(class)) - { - 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); - - } - } -} - -/* Walk on the methods list of class and install the methods in the reverse - order of the lists. Since methods added by categories are before the methods - of class in the methods list, this allows categories to substitute methods - declared in class. However if more than one category replaces the same - method nothing is guaranteed about what method will be used. - Assumes that __objc_runtime_mutex is locked down. */ -static void -__objc_install_methods_in_dtable (Class class, MethodList_t method_list) -{ - int i; - - if (!method_list) - return; - - if (method_list->method_next) - __objc_install_methods_in_dtable (class, method_list->method_next); - - for (i = 0; i < method_list->method_count; i++) - { - Method_t method = &(method_list->method_list[i]); - sarray_at_put_safe (class->dtable, - (sidx) method->method_name->sel_id, - method->method_imp); - } -} - -/* Assumes that __objc_runtime_mutex is locked down. */ -static void -__objc_install_dispatch_table_for_class (Class class) -{ - Class super; - - /* If the class has not yet had its class links resolved, we must - re-compute all class links */ - if(!CLS_ISRESOLV(class)) - __objc_resolve_class_links(); - - super = class->super_class; - - if (super != 0 && (super->dtable == __objc_uninstalled_dtable)) - __objc_install_dispatch_table_for_class (super); - - /* Allocate dtable if necessary */ - if (super == 0) - { - objc_mutex_lock(__objc_runtime_mutex); - class->dtable = sarray_new (__objc_selector_max_index, 0); - objc_mutex_unlock(__objc_runtime_mutex); - } - else - class->dtable = sarray_lazy_copy (super->dtable); - - __objc_install_methods_in_dtable (class, class->methods); -} - -void -__objc_update_dispatch_table_for_class (Class class) -{ - Class next; - struct sarray *arr; - - /* not yet installed -- skip it */ - if (class->dtable == __objc_uninstalled_dtable) - return; - - objc_mutex_lock(__objc_runtime_mutex); - - arr = class->dtable; - __objc_install_premature_dtable (class); /* someone might require it... */ - sarray_free (arr); /* release memory */ - - /* could have been lazy... */ - __objc_install_dispatch_table_for_class (class); - - if (class->subclass_list) /* Traverse subclasses */ - for (next = class->subclass_list; next; next = next->sibling_class) - __objc_update_dispatch_table_for_class (next); - - objc_mutex_unlock(__objc_runtime_mutex); -} - - -/* This function adds a method list to a class. This function is - typically called by another function specific to the run-time. As - such this function does not worry about thread safe issues. - - This one is only called for categories. Class objects have their - methods installed right away, and their selectors are made into - SEL's by the function __objc_register_selectors_from_class. */ -void -class_add_method_list (Class class, MethodList_t list) -{ - int i; - - /* Passing of a linked list is not allowed. Do multiple calls. */ - assert (!list->method_next); - - /* Check for duplicates. */ - for (i = 0; i < list->method_count; ++i) - { - Method_t method = &list->method_list[i]; - - if (method->method_name) /* Sometimes these are NULL */ - { - /* This is where selector names are transmogrified to SEL's */ - method->method_name = - sel_register_typed_name ((const char*)method->method_name, - method->method_types); - } - } - - /* Add the methods to the class's method list. */ - list->method_next = class->methods; - class->methods = list; - - /* Update the dispatch table of class */ - __objc_update_dispatch_table_for_class (class); -} - -Method_t -class_get_instance_method(Class class, SEL op) -{ - return search_for_method_in_hierarchy(class, op); -} - -Method_t -class_get_class_method(MetaClass class, SEL op) -{ - return search_for_method_in_hierarchy(class, op); -} - - -/* Search for a method starting from the current class up its hierarchy. - Return a pointer to the method's method structure if found. NULL - otherwise. */ - -static Method_t -search_for_method_in_hierarchy (Class cls, SEL sel) -{ - Method_t method = NULL; - Class class; - - if (! sel_is_mapped (sel)) - return NULL; - - /* Scan the method list of the class. If the method isn't found in the - list then step to its super class. */ - for (class = cls; ((! method) && class); class = class->super_class) - method = search_for_method_in_list (class->methods, sel); - - return method; -} - - - -/* Given a linked list of method and a method's name. Search for the named - method's method structure. Return a pointer to the method's method - structure if found. NULL otherwise. */ -Method_t -search_for_method_in_list (MethodList_t list, SEL op) -{ - MethodList_t method_list = list; - - if (! sel_is_mapped (op)) - return NULL; - - /* If not found then we'll search the list. */ - while (method_list) - { - int i; - - /* Search the method list. */ - for (i = 0; i < method_list->method_count; ++i) - { - Method_t method = &method_list->method_list[i]; - - if (method->method_name) - if (method->method_name->sel_id == op->sel_id) - return method; - } - - /* The method wasn't found. Follow the link to the next list of - methods. */ - method_list = method_list->method_next; - } - - return NULL; -} - -static retval_t __objc_forward (id object, SEL sel, arglist_t args); - -/* Forwarding pointers/integers through the normal registers */ -static id -__objc_word_forward (id rcv, SEL op, ...) -{ - void *args, *res; - - args = __builtin_apply_args (); - res = __objc_forward (rcv, op, args); - if (res) - __builtin_return (res); - else - return res; -} - -/* Specific routine for forwarding floats/double because of - architectural differences on some processors. i386s for - example which uses a floating point stack versus general - registers for floating point numbers. This forward routine - makes sure that GCC restores the proper return values */ -static double -__objc_double_forward (id rcv, SEL op, ...) -{ - void *args, *res; - - args = __builtin_apply_args (); - res = __objc_forward (rcv, op, args); - __builtin_return (res); -} - -#if INVISIBLE_STRUCT_RETURN -static __big -#else -static id -#endif -__objc_block_forward (id rcv, SEL op, ...) -{ - void *args, *res; - - args = __builtin_apply_args (); - res = __objc_forward (rcv, op, args); - if (res) - __builtin_return (res); - else -#if INVISIBLE_STRUCT_RETURN - return (__big) {{0, 0, 0, 0, 0, 0, 0, 0}}; -#else - return nil; -#endif -} - - -/* This function is installed in the dispatch table for all methods which are - not implemented. Thus, it is called when a selector is not recognized. */ -static retval_t -__objc_forward (id object, SEL sel, arglist_t args) -{ - IMP imp; - static SEL frwd_sel = 0; /* !T:SAFE2 */ - SEL err_sel; - - /* first try if the object understands forward:: */ - if (!frwd_sel) - frwd_sel = sel_get_any_uid("forward::"); - - if (__objc_responds_to (object, frwd_sel)) - { - imp = get_imp(object->class_pointer, frwd_sel); - return (*imp)(object, frwd_sel, sel, args); - } - - /* If the object recognizes the doesNotRecognize: method then we're going - to send it. */ - err_sel = sel_get_any_uid ("doesNotRecognize:"); - if (__objc_responds_to (object, err_sel)) - { - imp = get_imp (object->class_pointer, err_sel); - return (*imp) (object, err_sel, sel); - } - - /* The object doesn't recognize the method. Check for responding to - error:. If it does then sent it. */ - { - size_t strlen (const char*); - char msg[256 + strlen ((const char*)sel_get_name (sel)) - + strlen ((const char*)object->class_pointer->name)]; - - sprintf (msg, "(%s) %s does not recognize %s", - (CLS_ISMETA(object->class_pointer) - ? "class" - : "instance" ), - object->class_pointer->name, sel_get_name (sel)); - - err_sel = sel_get_any_uid ("error:"); - if (__objc_responds_to (object, err_sel)) - { - imp = get_imp (object->class_pointer, err_sel); - return (*imp) (object, sel_get_any_uid ("error:"), msg); - } - - /* The object doesn't respond to doesNotRecognize: or error:; Therefore, - a default action is taken. */ - objc_error (object, OBJC_ERR_UNIMPLEMENTED, "%s\n", msg); - - return 0; - } -} - -void -__objc_print_dtable_stats() -{ - int total = 0; - - objc_mutex_lock(__objc_runtime_mutex); - - printf("memory usage: (%s)\n", -#ifdef OBJC_SPARSE2 - "2-level sparse arrays" -#else - "3-level sparse arrays" -#endif - ); - - printf("arrays: %d = %ld bytes\n", narrays, - (long)narrays*sizeof(struct sarray)); - total += narrays*sizeof(struct sarray); - printf("buckets: %d = %ld bytes\n", nbuckets, - (long)nbuckets*sizeof(struct sbucket)); - total += nbuckets*sizeof(struct sbucket); - - printf("idxtables: %d = %ld bytes\n", idxsize, (long)idxsize*sizeof(void*)); - total += idxsize*sizeof(void*); - printf("-----------------------------------\n"); - printf("total: %d bytes\n", total); - printf("===================================\n"); - - objc_mutex_unlock(__objc_runtime_mutex); -} - -/* Returns the uninstalled dispatch table indicator. - If a class' dispatch table points to __objc_uninstalled_dtable - then that means it needs its dispatch table to be installed. */ -__inline__ -struct sarray* -objc_get_uninstalled_dtable() -{ - return __objc_uninstalled_dtable; -} diff --git a/contrib/gcc/objc/typedstream.h b/contrib/gcc/objc/typedstream.h deleted file mode 100644 index eb4642f344be..000000000000 --- a/contrib/gcc/objc/typedstream.h +++ /dev/null @@ -1,132 +0,0 @@ -/* GNU Objective-C Typed Streams interface. - Copyright (C) 1993, 1995 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -GNU CC is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files compiled - with GCC to produce an executable, this does not cause the resulting - executable to be covered by the GNU General Public License. This - exception does not however invalidate any other reasons why the - executable file might be covered by the GNU General Public License. */ - -#ifndef __typedstream_INCLUDE_GNU -#define __typedstream_INCLUDE_GNU - -#include "objc/objc.h" -#include "objc/hash.h" -#include <stdio.h> - -typedef int (*objc_typed_read_func)(void*, char*, int); -typedef int (*objc_typed_write_func)(void*, const char*, int); -typedef int (*objc_typed_flush_func)(void*); -typedef int (*objc_typed_eof_func)(void*); - -#define OBJC_READONLY 0x01 -#define OBJC_WRITEONLY 0x02 - -#define OBJC_MANAGED_STREAM 0x01 -#define OBJC_FILE_STREAM 0x02 -#define OBJC_MEMORY_STREAM 0x04 - -#define OBJC_TYPED_STREAM_VERSION 0x01 - -typedef struct objc_typed_stream { - void* physical; - cache_ptr object_table; /* read/written objects */ - cache_ptr stream_table; /* other read/written but shared things.. */ - cache_ptr class_table; /* class version mapping */ - cache_ptr object_refs; /* forward references */ - int mode; /* OBJC_READONLY or OBJC_WRITEONLY */ - int type; /* MANAGED, FILE, MEMORY etc bit string */ - int version; /* version used when writing */ - int writing_root_p; - objc_typed_read_func read; - objc_typed_write_func write; - objc_typed_eof_func eof; - objc_typed_flush_func flush; -} TypedStream; - -/* opcode masks */ -#define _B_VALUE 0x1fU -#define _B_CODE 0xe0U -#define _B_SIGN 0x10U -#define _B_NUMBER 0x0fU - -/* standard opcodes */ -#define _B_INVALID 0x00U -#define _B_SINT 0x20U -#define _B_NINT 0x40U -#define _B_SSTR 0x60U -#define _B_NSTR 0x80U -#define _B_RCOMM 0xa0U -#define _B_UCOMM 0xc0U -#define _B_EXT 0xe0U - -/* eXtension opcodes */ -#define _BX_OBJECT 0x00U -#define _BX_CLASS 0x01U -#define _BX_SEL 0x02U -#define _BX_OBJREF 0x03U -#define _BX_OBJROOT 0x04U -#define _BX_EXT 0x1fU - -/* -** Read and write objects as specified by TYPE. All the `last' -** arguments are pointers to the objects to read/write. -*/ - -int objc_write_type (TypedStream* stream, const char* type, const void* data); -int objc_read_type (TypedStream* stream, const char* type, void* data); - -int objc_write_types (TypedStream* stream, const char* type, ...); -int objc_read_types (TypedStream* stream, const char* type, ...); - -int objc_write_object_reference (TypedStream* stream, id object); -int objc_write_root_object (TypedStream* stream, id object); - -long objc_get_stream_class_version (TypedStream* stream, Class class); - - -/* -** Convenience functions -*/ - -int objc_write_array (TypedStream* stream, const char* type, - int count, const void* data); -int objc_read_array (TypedStream* stream, const char* type, - int count, void* data); - -int objc_write_object (TypedStream* stream, id object); -int objc_read_object (TypedStream* stream, id* object); - - - -/* -** Open a typed stream for reading or writing. MODE may be either of -** OBJC_READONLY or OBJC_WRITEONLY. -*/ - -TypedStream* objc_open_typed_stream (FILE* physical, int mode); -TypedStream* objc_open_typed_stream_for_file (const char* file_name, int mode); - -void objc_close_typed_stream (TypedStream* stream); - -BOOL objc_end_of_typed_stream (TypedStream* stream); -void objc_flush_typed_stream (TypedStream* stream); - -#endif /* not __typedstream_INCLUDE_GNU */ |