diff options
author | kan <kan@FreeBSD.org> | 2003-07-11 03:40:53 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2003-07-11 03:40:53 +0000 |
commit | b2a8872fbe1ec1c49094559ac7b78e6ea4ab7180 (patch) | |
tree | f6b0610f4a17fd26aa234354f050080f789861a4 /contrib/gcc/objc | |
parent | 52e69d78eee5612ac195e0701a5cebe40d1ab0e1 (diff) | |
download | FreeBSD-src-b2a8872fbe1ec1c49094559ac7b78e6ea4ab7180.zip FreeBSD-src-b2a8872fbe1ec1c49094559ac7b78e6ea4ab7180.tar.gz |
Gcc 3.3.1-pre as of 2003-07-11.
Diffstat (limited to 'contrib/gcc/objc')
-rw-r--r-- | contrib/gcc/objc/Make-lang.in | 13 | ||||
-rw-r--r-- | contrib/gcc/objc/config-lang.in | 2 | ||||
-rw-r--r-- | contrib/gcc/objc/lang-specs.h | 14 | ||||
-rw-r--r-- | contrib/gcc/objc/objc-act.c | 865 | ||||
-rw-r--r-- | contrib/gcc/objc/objc-act.h | 21 | ||||
-rw-r--r-- | contrib/gcc/objc/objc-lang.c | 100 |
6 files changed, 598 insertions, 417 deletions
diff --git a/contrib/gcc/objc/Make-lang.in b/contrib/gcc/objc/Make-lang.in index 379a16c..480f96b 100644 --- a/contrib/gcc/objc/Make-lang.in +++ b/contrib/gcc/objc/Make-lang.in @@ -63,10 +63,10 @@ objc-lang.o : $(srcdir)/objc/objc-lang.c \ -c $(srcdir)/objc/objc-lang.c $(OUTPUT_OPTION) objc-parse.o : $(srcdir)/objc/objc-parse.c \ - $(CONFIG_H) $(TREE_H) $(srcdir)/toplev.h $(srcdir)/ggc.h \ - $(srcdir)/c-lex.h $(srcdir)/c-tree.h $(srcdir)/c-common.h \ + $(CONFIG_H) $(TREE_H) $(C_COMMON_H) $(srcdir)/toplev.h $(srcdir)/ggc.h \ + $(srcdir)/c-pragma.h $(srcdir)/c-tree.h \ $(srcdir)/input.h $(srcdir)/flags.h $(srcdir)/output.h \ - $(srcdir)/objc/objc-act.h $(SYSTEM_H) $(CPPLIB_H) + $(srcdir)/objc/objc-act.h $(SYSTEM_H) $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \ -c $(srcdir)/objc/objc-parse.c $(OUTPUT_OPTION) @@ -90,13 +90,15 @@ $(srcdir)/objc/objc-parse.y: $(srcdir)/c-parse.in objc-act.o : $(srcdir)/objc/objc-act.c \ $(CONFIG_H) $(TREE_H) $(RTL_H) $(SYSTEM_H) $(EXPR_H) $(TARGET_H) \ - $(srcdir)/c-tree.h $(srcdir)/c-common.h $(srcdir)/c-lex.h \ + $(C_COMMON_H) $(srcdir)/c-tree.h $(srcdir)/diagnostic.h \ $(srcdir)/toplev.h $(srcdir)/flags.h $(srcdir)/objc/objc-act.h \ $(srcdir)/input.h $(srcdir)/function.h $(srcdir)/output.h $(srcdir)/debug.h \ - $(srcdir)/langhooks.h $(LANGHOOKS_DEF_H) + $(srcdir)/langhooks.h $(LANGHOOKS_DEF_H) gtype-objc.h $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \ -c $(srcdir)/objc/objc-act.c +gtype-objc.h : s-gtype ; @true + # # Build hooks: @@ -129,6 +131,7 @@ objc.uninstall: objc.mostlyclean: -rm -f tmp-objc-prs.y -rm -f objc/*$(objext) objc/xforward objc/fflags + -rm -f objc/*$(coverageexts) objc.clean: objc.mostlyclean -rm -rf objc-headers objc.distclean: diff --git a/contrib/gcc/objc/config-lang.in b/contrib/gcc/objc/config-lang.in index 57066a4..d79ac13 100644 --- a/contrib/gcc/objc/config-lang.in +++ b/contrib/gcc/objc/config-lang.in @@ -32,3 +32,5 @@ compilers="cc1obj\$(exeext)" stagestuff="" target_libs=target-libobjc + +gtfiles="\$(srcdir)/objc/objc-act.h \$(srcdir)/c-parse.in \$(srcdir)/c-tree.h \$(srcdir)/c-decl.c \$(srcdir)/c-objc-common.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c \$(srcdir)/c-parse.in" diff --git a/contrib/gcc/objc/lang-specs.h b/contrib/gcc/objc/lang-specs.h index 66e705b..540a9ae 100644 --- a/contrib/gcc/objc/lang-specs.h +++ b/contrib/gcc/objc/lang-specs.h @@ -25,17 +25,15 @@ Boston, MA 02111-1307, USA. */ {"@objective-c", /* cc1obj has an integrated ISO C preprocessor. We should invoke the external preprocessor if -save-temps or -traditional is given. */ - "%{E|M|MM:%(trad_capable_cpp) -lang-objc %{ansi:-std=c89} %(cpp_options)}\ + "%{E|M|MM:%(trad_capable_cpp)\ + -lang-objc %(cpp_options) %(cpp_debug_options)}\ %{!E:%{!M:%{!MM:\ - %{save-temps|no-integrated-cpp:%(trad_capable_cpp) -lang-objc %{ansi:-std=c89}\ - %(cpp_options) %{save-temps:%b.mi} %{!save-temps:%g.mi} \n\ + %{traditional|ftraditional|traditional-cpp:\ +%eGNU Objective C no longer supports traditional compilation}\ + %{save-temps|no-integrated-cpp:cc1obj -E %(cpp_options) %{save-temps:%b.mi} %{!save-temps:%g.mi} \n\ cc1obj -fpreprocessed %{save-temps:%b.mi} %{!save-temps:%g.mi} %(cc1_options) %{gen-decls}}\ %{!save-temps:%{!no-integrated-cpp:\ - %{traditional|ftraditional|traditional-cpp:\ - tradcpp0 -lang-objc %{ansi:-std=c89} %(cpp_options) %{!pipe:%g.mi} |\n\ - cc1obj -fpreprocessed %{!pipe:%g.mi} %(cc1_options) %{gen-decls}}\ - %{!traditional:%{!ftraditional:%{!traditional-cpp:\ - cc1obj %{ansi:-std=c89} %(cpp_unique_options) %(cc1_options) %{gen-decls}}}}}}\ + cc1obj %(cpp_unique_options) %(cc1_options) %{gen-decls}}}\ %{!fsyntax-only:%(invoke_as)}}}}", 0}, {".mi", "@objc-cpp-output", 0}, {"@objc-cpp-output", diff --git a/contrib/gcc/objc/objc-act.c b/contrib/gcc/objc/objc-act.c index 02cb099..018ba04 100644 --- a/contrib/gcc/objc/objc-act.c +++ b/contrib/gcc/objc/objc-act.c @@ -45,7 +45,6 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "expr.h" #include "c-tree.h" -#include "c-lex.h" #include "c-common.h" #include "flags.h" #include "objc-act.h" @@ -55,9 +54,9 @@ Boston, MA 02111-1307, USA. */ #include "output.h" #include "toplev.h" #include "ggc.h" -#include "cpplib.h" #include "debug.h" #include "target.h" +#include "diagnostic.h" /* This is the default way of generating a method name. */ /* I am not sure it is really correct. @@ -86,48 +85,11 @@ Boston, MA 02111-1307, USA. */ #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. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, - -static const 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, - -static const 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, - -static const char * const 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, @@ -166,7 +128,6 @@ static tree build_objc_method_call PARAMS ((int, tree, tree, static void generate_strings PARAMS ((void)); static tree get_proto_encoding PARAMS ((tree)); static void build_selector_translation_table PARAMS ((void)); -static tree build_ivar_chain PARAMS ((tree, int)); static tree objc_add_static_instance PARAMS ((tree, tree)); @@ -199,7 +160,6 @@ static int check_methods_accessible PARAMS ((tree, tree, static void encode_aggregate_within PARAMS ((tree, int, int, int, int)); static const char *objc_demangle PARAMS ((const char *)); -static const char *objc_printable_name PARAMS ((tree, int)); static void objc_expand_function_end PARAMS ((void)); /* Hash tables to manage the global pool of method prototypes. */ @@ -270,7 +230,6 @@ static void dump_interface PARAMS ((FILE *, tree)); /* Everything else. */ -static void add_objc_tree_codes PARAMS ((void)); static tree define_decl PARAMS ((tree, tree)); static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int)); static tree lookup_protocol_in_reflist PARAMS ((tree, tree)); @@ -289,7 +248,6 @@ static tree build_typed_selector_reference PARAMS ((tree, tree)); static tree build_selector_reference PARAMS ((tree)); static tree build_class_reference_decl PARAMS ((void)); static void add_class_reference PARAMS ((tree)); -static tree objc_copy_list PARAMS ((tree, tree *)); static tree build_protocol_template PARAMS ((void)); static tree build_descriptor_table_initializer PARAMS ((tree, tree)); static tree build_method_prototype_list_template PARAMS ((tree, int)); @@ -332,9 +290,7 @@ static void generate_classref_translation_entry PARAMS ((tree)); static void handle_class_ref PARAMS ((tree)); static void generate_struct_by_value_array PARAMS ((void)) ATTRIBUTE_NORETURN; -static void objc_act_parse_init PARAMS ((void)); -static void ggc_mark_imp_list PARAMS ((void *)); -static void ggc_mark_hash_table PARAMS ((void *)); +static void encode_complete_bitfield PARAMS ((int, tree, int)); /*** Private Interface (data) ***/ @@ -353,13 +309,11 @@ static void ggc_mark_hash_table PARAMS ((void *)); #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" @@ -369,8 +323,6 @@ static void ggc_mark_hash_table PARAMS ((void *)); #define PROTOCOL_OBJECT_CLASS_NAME "Protocol" -static const char *constant_string_class_name = NULL; - static const char *TAG_GETCLASS; static const char *TAG_GETMETACLASS; static const char *TAG_MSGSEND; @@ -381,8 +333,6 @@ static const char *default_constant_string_class_name; /* The OCTI_... enumeration itself is in objc/objc-act.h. */ tree objc_global_trees[OCTI_MAX]; -int objc_receiver_context; - static void handle_impent PARAMS ((struct imp_entry *)); struct imp_entry *imp_list = 0; @@ -403,33 +353,10 @@ extern enum debug_info_type write_symbols; extern const 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; +static int flag_typed_selectors; 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 @@ -437,12 +364,6 @@ int flag_warn_protocol = 1; 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. */ @@ -511,9 +432,8 @@ objc_init (filename) const char *filename; { filename = c_objc_common_init (filename); - add_objc_tree_codes (); - - decl_printable_name = objc_printable_name; + if (filename == NULL) + return filename; /* Force the line number back to 0; check_newline will have raised it to 1, which will make the builtin functions appear @@ -557,8 +477,6 @@ objc_init (filename) if (print_struct_values) generate_struct_by_value_array (); - objc_act_parse_init (); - return filename; } @@ -567,52 +485,14 @@ finish_file () { c_objc_common_finish_file (); - finish_objc (); /* Objective-C finalization */ + /* Finalize Objective-C runtime data. No need to generate tables + and code if only checking syntax. */ + if (!flag_syntax_only) + finish_objc (); if (gen_declaration_file) fclose (gen_declaration_file); } - -int -objc_decode_option (argc, argv) - int argc; - char **argv; -{ - const char *p = argv[0]; - - 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; -#define CSTSTRCLASS "-fconstant-string-class=" - else if (!strncmp (p, CSTSTRCLASS, sizeof(CSTSTRCLASS) - 2)) { - if (strlen (argv[0]) <= strlen (CSTSTRCLASS)) - error ("no class name specified as argument to -fconstant-string-class"); - constant_string_class_name = xstrdup(argv[0] + sizeof(CSTSTRCLASS) - 1); - } -#undef CSTSTRCLASS - else - return c_decode_option (argc, argv); - - return 1; -} - static tree define_decl (declarator, declspecs) @@ -636,14 +516,6 @@ define_decl (declarator, declspecs) `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; -{ - return objc_comptypes (lhs, rhs, reflexive); -} - static tree lookup_method_in_protocol_list (rproto_list, sel_name, class_meth) tree rproto_list; @@ -715,10 +587,24 @@ lookup_protocol_in_reflist (rproto_list, lproto) 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. */ +/* 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 (because the types are really + just C types, not ObjC specific ones). When the operation is + REFLEXIVE (typically comparisons), check for compatibility in + either direction; when it's not (typically assignments), don't. + + This function is called in two cases: when both lhs and rhs are + pointers to records (in which case we check protocols too), and + when both lhs and rhs are records (in which case we check class + inheritance only). + + Warnings about classes/protocols not implementing a protocol are + emitted here (multiple of those warnings might be emitted for a + single line!); generic warnings about incompatible assignments and + lacks of casts in comparisons are/must be emitted by the caller if + we return 0. +*/ int objc_comptypes (lhs, rhs, reflexive) @@ -728,6 +614,8 @@ objc_comptypes (lhs, rhs, reflexive) { /* New clause for protocols. */ + /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only + manage the ObjC ones, and leave the rest to the C code. */ if (TREE_CODE (lhs) == POINTER_TYPE && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE && TREE_CODE (rhs) == POINTER_TYPE @@ -742,29 +630,75 @@ objc_comptypes (lhs, rhs, reflexive) tree rproto, rproto_list; tree p; + /* <Protocol> = <Protocol> */ 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)) + + if (!reflexive) { - p = TREE_VALUE (lproto); - rproto = lookup_protocol_in_reflist (rproto_list, p); + /* An assignment between objects of type 'id + <Protocol>'; make sure the protocol on the lhs 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))); + if (!rproto) + warning + ("object does not conform to the `%s' protocol", + IDENTIFIER_POINTER (PROTOCOL_NAME (p))); + } + return 1; + } + else + { + /* Obscure case - a comparison between two objects + of type 'id <Protocol>'. Check that either the + protocol on the lhs is supported by the object on + the rhs, or viceversa. */ + + /* Check if the protocol on the lhs 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) + { + /* Check failed - check if the protocol on the rhs + is supported by the object on the lhs. */ + for (rproto = rproto_list; rproto; + rproto = TREE_CHAIN (rproto)) + { + p = TREE_VALUE (rproto); + lproto = lookup_protocol_in_reflist (lproto_list, + p); + + if (!lproto) + { + /* This check failed too: incompatible */ + return 0; + } + } + return 1; + } + } + return 1; } } + /* <Protocol> = <class> * */ 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. */ + /* 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); @@ -776,13 +710,16 @@ objc_comptypes (lhs, rhs, reflexive) tree cat; rproto_list = CLASS_PROTOCOL_LIST (rinter); - /* If the underlying ObjC class does not have - protocols attached to it, perhaps there are - "one-off" protocols attached to the rhs? - E.g., 'id<MyProt> foo;'. */ - if (!rproto_list) - rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs)); rproto = lookup_protocol_in_reflist (rproto_list, p); + /* If the underlying ObjC class does not have + the protocol we're looking for, check for "one-off" + protocols (e.g., `NSObject<MyProt> *foo;') attached + to the rhs. */ + if (!rproto) + { + rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs)); + rproto = lookup_protocol_in_reflist (rproto_list, p); + } /* Check for protocols adopted by categories. */ cat = CLASS_CATEGORY_LIST (rinter); @@ -790,7 +727,6 @@ objc_comptypes (lhs, rhs, reflexive) { rproto_list = CLASS_PROTOCOL_LIST (cat); rproto = lookup_protocol_in_reflist (rproto_list, p); - cat = CLASS_CATEGORY_LIST (cat); } @@ -799,31 +735,127 @@ objc_comptypes (lhs, rhs, reflexive) if (!rproto) warning ("class `%s' does not implement the `%s' protocol", - IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))), - IDENTIFIER_POINTER (PROTOCOL_NAME (p))); + IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))), + IDENTIFIER_POINTER (PROTOCOL_NAME (p))); } + return 1; } - - /* May change...based on whether there was any mismatch */ - return 1; + /* <Protocol> = id */ + else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id) + { + return 1; + } + /* <Protocol> = Class */ + else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id) + { + return 0; + } + /* <Protocol> = ?? : let comptypes decide. */ + 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); + { + /* <class> * = <Protocol> */ + if (TYPED_OBJECT (TREE_TYPE (lhs))) + { + if (reflexive) + { + tree rname = TYPE_NAME (TREE_TYPE (lhs)); + tree rinter; + tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs); + + /* Make sure the protocol is supported by the object on + the lhs. */ + for (rproto = rproto_list; rproto; + rproto = TREE_CHAIN (rproto)) + { + tree p = TREE_VALUE (rproto); + tree lproto = 0; + rinter = lookup_interface (rname); + while (rinter && !lproto) + { + tree cat; + + tree lproto_list = CLASS_PROTOCOL_LIST (rinter); + lproto = lookup_protocol_in_reflist (lproto_list, p); + /* If the underlying ObjC class does not + have the protocol we're looking for, + check for "one-off" protocols (e.g., + `NSObject<MyProt> *foo;') attached to the + lhs. */ + if (!lproto) + { + lproto_list = TYPE_PROTOCOL_LIST + (TREE_TYPE (lhs)); + lproto = lookup_protocol_in_reflist + (lproto_list, p); + } + + /* Check for protocols adopted by categories. */ + cat = CLASS_CATEGORY_LIST (rinter); + while (cat && !lproto) + { + lproto_list = CLASS_PROTOCOL_LIST (cat); + lproto = lookup_protocol_in_reflist (lproto_list, + p); + cat = CLASS_CATEGORY_LIST (cat); + } + + rinter = lookup_interface (CLASS_SUPER_NAME + (rinter)); + } + + if (!lproto) + warning ("class `%s' does not implement the `%s' protocol", + IDENTIFIER_POINTER (TYPE_NAME + (TREE_TYPE (lhs))), + IDENTIFIER_POINTER (PROTOCOL_NAME (p))); + } + return 1; + } + else + return 0; + } + /* id = <Protocol> */ + else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id) + { + return 1; + } + /* Class = <Protocol> */ + else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id) + { + return 0; + } + /* ??? = <Protocol> : let comptypes decide */ + else + { + return -1; + } + } else - /* Defer to comptypes. */ - return -1; + { + /* Attention: we shouldn't defer to comptypes here. One bad + side effect would be that we might loose the REFLEXIVE + information. + */ + lhs = TREE_TYPE (lhs); + rhs = TREE_TYPE (rhs); + } } - 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 (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE) + { + /* Nothing to do with ObjC - let immediately comptypes take + responsibility for checking. */ + return -1; + } + /* `id' = `<class> *' `<class> *' = `id': always allow it. + Please note that + 'Object *o = [[Object alloc] init]; falls + in the case <class> * = `id'. + */ if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs)) || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs))) return 1; @@ -864,7 +896,7 @@ objc_comptypes (lhs, rhs, reflexive) return 0; } else - /* Defer to comptypes. */ + /* Not an ObjC type - let comptypes do the check. */ return -1; } @@ -882,13 +914,6 @@ objc_check_decl (decl) error_with_decl (decl, "`%s' cannot be statically allocated"); } -void -maybe_objc_check_decl (decl) - tree decl; -{ - objc_check_decl (decl); -} - /* Implement static typing. At this point, we know we have an interface. */ tree @@ -903,7 +928,6 @@ get_static_reference (interface, protocols) tree t, m = TYPE_MAIN_VARIANT (type); t = copy_node (type); - TYPE_BINFO (t) = make_tree_vec (2); /* Add this type to the chain of variants of TYPE. */ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); @@ -954,7 +978,6 @@ get_object_reference (protocols) tree t, m = TYPE_MAIN_VARIANT (type); t = copy_node (type); - TYPE_BINFO (t) = make_tree_vec (2); /* Add this type to the chain of variants of TYPE. */ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); @@ -1131,14 +1154,12 @@ synth_module_prologue () 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); pushdecl (umsg_decl); } else - umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, 0); + umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN, + NULL, NULL_TREE); /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */ @@ -1149,7 +1170,8 @@ synth_module_prologue () NULL_TREE))); umsg_super_decl = builtin_function (TAG_MSGSENDSUPER, - temp_type, 0, NOT_BUILT_IN, 0); + temp_type, 0, NOT_BUILT_IN, + NULL, NULL_TREE); /* id objc_getClass (const char *); */ @@ -1160,12 +1182,14 @@ synth_module_prologue () NULL_TREE))); objc_get_class_decl - = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, 0); + = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN, + NULL, NULL_TREE); /* id objc_getMetaClass (const char *); */ objc_get_meta_class_decl - = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, 0); + = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, + NULL, NULL_TREE); /* static SEL _OBJC_SELECTOR_TABLE[]; */ @@ -1176,7 +1200,7 @@ synth_module_prologue () /* Suppress outputting debug symbols, because dbxout_init hasn'r been called yet. */ enum debug_info_type save_write_symbols = write_symbols; - struct gcc_debug_hooks *save_hooks = debug_hooks; + const struct gcc_debug_hooks *const save_hooks = debug_hooks; write_symbols = NO_DEBUG; debug_hooks = &do_nothing_debug_hooks; @@ -1243,21 +1267,7 @@ my_build_string (len, str) int len; const 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 fix_string_type (build_string (len, str)); } /* Given a chain of STRING_CST's, build a static instance of @@ -1283,7 +1293,21 @@ build_objc_string_object (strings) add_class_reference (constant_string_id); - string = combine_strings (strings); + if (TREE_CHAIN (strings)) + { + varray_type vstrings; + VARRAY_TREE_INIT (vstrings, 32, "strings"); + + for (; strings ; strings = TREE_CHAIN (strings)) + VARRAY_PUSH_TREE (vstrings, strings); + + string = combine_strings (vstrings); + } + else + string = strings; + + string = fix_string_type (string); + TREE_SET_CODE (string, STRING_CST); length = TREE_STRING_LENGTH (string) - 1; @@ -1390,7 +1414,7 @@ build_constructor (type, elts) else { f = TYPE_FIELDS (type); - for (e = elts; e ; e = TREE_CHAIN (e), f = TREE_CHAIN (f)) + for (e = elts; e && f; e = TREE_CHAIN (e), f = TREE_CHAIN (f)) if (TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE || TREE_CODE (TREE_TYPE (f)) == INTEGER_TYPE) TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e)); @@ -1813,7 +1837,7 @@ get_objc_string_decl (ident, section) else abort (); - for (; chain != 0; chain = TREE_VALUE (chain)) + for (; chain != 0; chain = TREE_CHAIN (chain)) if (TREE_VALUE (chain) == ident) return (TREE_PURPOSE (chain)); @@ -2003,6 +2027,32 @@ build_selector_translation_table () { tree expr; + if (warn_selector && objc_implementation_context) + { + tree method_chain; + bool found = false; + for (method_chain = meth_var_names_chain; + method_chain; + method_chain = TREE_CHAIN (method_chain)) + { + if (TREE_VALUE (method_chain) == TREE_VALUE (chain)) + { + found = true; + break; + } + } + if (!found) + { + /* Adjust line number for warning message. */ + int save_lineno = lineno; + if (flag_next_runtime && TREE_PURPOSE (chain)) + lineno = DECL_SOURCE_LINE (TREE_PURPOSE (chain)); + warning ("creating selector for non existant method %s", + IDENTIFIER_POINTER (TREE_VALUE (chain))); + lineno = save_lineno; + } + } + expr = build_selector (TREE_VALUE (chain)); if (flag_next_runtime) @@ -2086,8 +2136,8 @@ get_proto_encoding (proto) identifier_node that represent the selector. */ static tree -build_typed_selector_reference (ident, proto) - tree ident, proto; +build_typed_selector_reference (ident, prototype) + tree ident, prototype; { tree *chain = &sel_ref_chain; tree expr; @@ -2095,14 +2145,14 @@ build_typed_selector_reference (ident, proto) while (*chain) { - if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto) + if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident) goto return_at_index; index++; chain = &TREE_CHAIN (*chain); } - *chain = tree_cons (proto, ident, NULL_TREE); + *chain = tree_cons (prototype, ident, NULL_TREE); return_at_index: expr = build_unary_op (ADDR_EXPR, @@ -2370,6 +2420,17 @@ is_class_name (ident) } tree +objc_is_id (ident) + tree ident; +{ + /* NB: This function may be called before the ObjC front-end + has been initialized, in which case ID_TYPE will be NULL. */ + return (id_type && ident && TYPE_P (ident) && IS_ID (ident)) + ? id_type + : NULL_TREE; +} + +tree lookup_interface (ident) tree ident; { @@ -2383,51 +2444,23 @@ lookup_interface (ident) 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. */ - if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0) - DECL_INITIAL (tail) = DECL_SIZE (tail); - - 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. */ +/* Used by: build_private_template, continue_class, + and for @defs constructs. */ -static tree -build_ivar_chain (interface, copy) +tree +get_class_ivars (interface) tree interface; - int copy; { tree my_name, super_name, ivar_chain; my_name = CLASS_NAME (interface); super_name = CLASS_SUPER_NAME (interface); + ivar_chain = CLASS_IVARS (interface); - /* Possibly copy leaf ivars. */ - if (copy) - objc_copy_list (CLASS_IVARS (interface), &ivar_chain); - else - ivar_chain = CLASS_IVARS (interface); + /* Save off a pristine copy of the leaf ivars (i.e, those not + inherited from a super class). */ + if (!CLASS_OWN_IVARS (interface)) + CLASS_OWN_IVARS (interface) = copy_list (ivar_chain); while (super_name) { @@ -2451,14 +2484,14 @@ build_ivar_chain (interface, copy) my_name = CLASS_NAME (interface); super_name = CLASS_SUPER_NAME (interface); - op1 = CLASS_IVARS (interface); + op1 = CLASS_OWN_IVARS (interface); if (op1) { - tree head, tail = objc_copy_list (op1, &head); + tree head = copy_list (op1); /* Prepend super class ivars...make a copy of the list, we do not want to alter the original. */ - TREE_CHAIN (tail) = ivar_chain; + chainon (head, ivar_chain); ivar_chain = head; } } @@ -2485,7 +2518,7 @@ build_private_template (class) { uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class)); - ivar_context = build_ivar_chain (class, 0); + ivar_context = get_class_ivars (class); finish_struct (uprivate_record, ivar_context, NULL_TREE); @@ -3003,6 +3036,43 @@ generate_protocol_references (plist) } } +/* For each protocol which was referenced either from a @protocol() + expression, or because a class/category implements it (then a + pointer to the protocol is stored in the struct describing the + class/category), we create a statically allocated instance of the + Protocol class. The code is written in such a way as to generate + as few Protocol objects as possible; we generate a unique Protocol + instance for each protocol, and we don't generate a Protocol + instance if the protocol is never referenced (either from a + @protocol() or from a class/category implementation). These + statically allocated objects can be referred to via the static + (that is, private to this module) symbols _OBJC_PROTOCOL_n. + + The statically allocated Protocol objects that we generate here + need to be fixed up at runtime in order to be used: the 'isa' + pointer of the objects need to be set up to point to the 'Protocol' + class, as known at runtime. + + The NeXT runtime fixes up all protocols at program startup time, + before main() is entered. It uses a low-level trick to look up all + those symbols, then loops on them and fixes them up. + + The GNU runtime as well fixes up all protocols before user code + from the module is executed; it requires pointers to those symbols + to be put in the objc_symtab (which is then passed as argument to + the function __objc_exec_class() which the compiler sets up to be + executed automatically when the module is loaded); setup of those + Protocol objects happen in two ways in the GNU runtime: all + Protocol objects referred to by a class or category implementation + are fixed up when the class/category is loaded; all Protocol + objects referred to by a @protocol() expression are added by the + compiler to the list of statically allocated instances to fixup + (the same list holding the statically allocated constant string + objects). Because, as explained above, the compiler generates as + few Protocol objects as possible, some Protocol object might end up + being referenced multiple times when compiled with the GNU runtime, + and end up being fixed up multiple times at runtime inizialization. + But that doesn't hurt, it's just a little inefficient. */ static void generate_protocols () { @@ -3464,9 +3534,9 @@ error_with_ivar (message, decl, rawdecl) tree decl; tree rawdecl; { - count_error (0); + diagnostic_count_diagnostic (global_dc, DK_ERROR); - report_error_function (DECL_SOURCE_FILE (decl)); + diagnostic_report_current_function (global_dc); error_with_file_and_line (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), @@ -3475,10 +3545,6 @@ error_with_ivar (message, decl, rawdecl) } -#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; @@ -4508,6 +4574,10 @@ adjust_type_for_id_default (type) chain; chain = TREE_CHAIN (chain)) { + if (TYPED_OBJECT (TREE_VALUE (chain)) + && !(TREE_VALUE (type) + && TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF)) + error ("can not use an object as parameter to a method\n"); if (!is_objc_type_qualifier (TREE_VALUE (chain))) return type; } @@ -4778,12 +4848,12 @@ receiver_is_class_object (receiver) the identifier of the selector of the message. This is used when printing warnings about argument mismatches. */ -static tree building_objc_message_expr = 0; +static tree current_objc_message_selector = 0; tree -maybe_building_objc_message_expr () +objc_message_selector () { - return building_objc_message_expr; + return current_objc_message_selector; } /* Construct an expression for sending a message. @@ -4924,7 +4994,7 @@ finish_message_expr (receiver, sel_name, method_params) if (iface) method_prototype = lookup_instance_method_static (iface, sel_name); - if (! method_prototype && TYPE_PROTOCOL_LIST (ctype)) + if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype)) method_prototype = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype), sel_name, 0); @@ -5059,7 +5129,7 @@ finish_message_expr (receiver, sel_name, method_params) } /* Save the selector name for printing error messages. */ - building_objc_message_expr = sel_name; + current_objc_message_selector = sel_name; /* Build the parameters list for looking up the method. These are the object itself and the selector. */ @@ -5073,7 +5143,7 @@ finish_message_expr (receiver, sel_name, method_params) receiver, self_object, selector, method_params); - building_objc_message_expr = 0; + current_objc_message_selector = 0; return retval; } @@ -5217,6 +5287,8 @@ build_protocol_reference (p) PROTOCOL_FORWARD_DECL (p) = decl; } +/* This function is called by the parser when (and only when) a + @protocol() expression is found, in order to compile it. */ tree build_protocol_expr (protoname) tree protoname; @@ -5238,9 +5310,56 @@ build_protocol_expr (protoname) TREE_TYPE (expr) = protocol_type; + /* The @protocol() expression is being compiled into a pointer to a + statically allocated instance of the Protocol class. To become + usable at runtime, the 'isa' pointer of the instance need to be + fixed up at runtime by the runtime library, to point to the + actual 'Protocol' class. */ + + /* For the GNU runtime, put the static Protocol instance in the list + of statically allocated instances, so that we make sure that its + 'isa' pointer is fixed up at runtime by the GNU runtime library + to point to the Protocol class (at runtime, when loading the + module, the GNU runtime library loops on the statically allocated + instances (as found in the defs field in objc_symtab) and fixups + all the 'isa' pointers of those objects). */ + if (! flag_next_runtime) + { + /* This type is a struct containing the fields of a Protocol + object. (Cfr. protocol_type instead is the type of a pointer + to such a struct). */ + tree protocol_struct_type = xref_tag + (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME)); + tree *chain; + + /* Look for the list of Protocol statically allocated instances + to fixup at runtime. Create a new list to hold Protocol + statically allocated instances, if the list is not found. At + present there is only another list, holding NSConstantString + static instances to be fixed up at runtime. */ + for (chain = &objc_static_instances; + *chain && TREE_VALUE (*chain) != protocol_struct_type; + chain = &TREE_CHAIN (*chain)); + if (!*chain) + { + *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE); + add_objc_string (TYPE_NAME (protocol_struct_type), + class_names); + } + + /* Add this statically allocated instance to the Protocol list. */ + TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, + PROTOCOL_FORWARD_DECL (p), + TREE_PURPOSE (*chain)); + } + + return expr; } +/* This function is called by the parser when a @selector() expression + is found, in order to compile it. It is only called by the parser + and only to compile a @selector(). */ tree build_selector_expr (selnamelist) tree selnamelist; @@ -5256,6 +5375,32 @@ build_selector_expr (selnamelist) else abort (); + /* If we are required to check @selector() expressions as they + are found, check that the selector has been declared. */ + if (warn_undeclared_selector) + { + /* Look the selector up in the list of all known class and + instance methods (up to this line) to check that the selector + exists. */ + hash hsh; + + /* First try with instance methods. */ + hsh = hash_lookup (nst_method_hash_list, selname); + + /* If not found, try with class methods. */ + if (!hsh) + { + hsh = hash_lookup (cls_method_hash_list, selname); + } + + /* If still not found, print out a warning. */ + if (!hsh) + { + warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname)); + } + } + + if (flag_typed_selectors) return build_typed_selector_reference (selname, 0); else @@ -5321,8 +5466,8 @@ hash_func (sel_name) static void hash_init () { - nst_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash)); - cls_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash)); + nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash)); + cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash)); } /* WARNING!!!! hash_enter is called with a method, and will peek @@ -5335,18 +5480,10 @@ hash_enter (hashlist, method) hash *hashlist; tree method; { - static hash hash_alloc_list = 0; - static int hash_alloc_index = 0; hash obj; int slot = hash_func (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); - } - obj = &hash_alloc_list[hash_alloc_index++]; + obj = (hash) ggc_alloc (sizeof (struct hashed_entry)); obj->list = 0; obj->next = hashlist[slot]; obj->key = method; @@ -5378,17 +5515,9 @@ 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); - } - obj = &attr_alloc_list[attr_alloc_index++]; + obj = (attr) ggc_alloc (sizeof (struct hashed_attribute)); obj->next = entry->list; obj->value = value; @@ -5411,6 +5540,7 @@ lookup_method (mchain, method) { if (METHOD_SEL_NAME (mchain) == key) return mchain; + mchain = TREE_CHAIN (mchain); } return NULL_TREE; @@ -5782,18 +5912,6 @@ is_public (expr, identifier) return 1; } - -/* Implement @defs (<classname>) within struct bodies. */ - -tree -get_class_ivars (interface) - tree interface; -{ - /* Make sure we copy the leaf ivars in case @defs is used in a local - context. Otherwise finish_struct will overwrite the layout info - using temporary storage. */ - return build_ivar_chain (interface, 1); -} /* Make sure all entries in CHAIN are also in LIST. */ @@ -5940,7 +6058,7 @@ check_protocol (p, type, name) int f1, f2; /* Ensure that all protocols have bodies! */ - if (flag_warn_protocol) + if (warn_protocol) { f1 = check_methods (PROTOCOL_CLS_METHODS (p), CLASS_CLS_METHODS (objc_implementation_context), @@ -6025,7 +6143,7 @@ start_class (code, class_name, super_name, protocol_list) } class = make_node (code); - TYPE_BINFO (class) = make_tree_vec (5); + TYPE_BINFO (class) = make_tree_vec (6); CLASS_NAME (class) = class_name; CLASS_SUPER_NAME (class) = super_name; @@ -6189,7 +6307,7 @@ continue_class (class) if (!objc_class_template) build_class_template (); - imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry)); + imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry)); imp_entry->next = imp_list; imp_entry->imp_context = class; @@ -6215,7 +6333,7 @@ continue_class (class) if (!TYPE_FIELDS (record)) { - finish_struct (record, build_ivar_chain (class, 0), NULL_TREE); + finish_struct (record, get_class_ivars (class), NULL_TREE); CLASS_STATIC_TEMPLATE (class) = record; /* Mark this record as a class template for static typing. */ @@ -6766,7 +6884,10 @@ encode_type (type, curtype, format) } static void -encode_complete_bitfield (int position, tree type, int size) +encode_complete_bitfield (position, type, size) + int position; + tree type; + int size; { enum tree_code code = TREE_CODE (type); char buffer[40]; @@ -6836,14 +6957,14 @@ encode_field_decl (field_decl, curtype, format) the bitfield typing information. */ if (flag_next_runtime) { - if (DECL_BIT_FIELD (field_decl)) + if (DECL_BIT_FIELD_TYPE (field_decl)) encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1)); else encode_type (TREE_TYPE (field_decl), curtype, format); } else { - if (DECL_BIT_FIELD (field_decl)) + if (DECL_BIT_FIELD_TYPE (field_decl)) encode_complete_bitfield (int_bit_position (field_decl), DECL_BIT_FIELD_TYPE (field_decl), tree_low_cst (DECL_SIZE (field_decl), 1)); @@ -6959,10 +7080,10 @@ warn_with_method (message, mtype, method) int mtype; tree method; { - if (count_error (1) == 0) + if (!diagnostic_count_diagnostic (global_dc, DK_WARNING)) return; - report_error_function (DECL_SOURCE_FILE (method)); + diagnostic_report_current_function (global_dc); /* Add a readable method name to the warning. */ warning_with_file_and_line (DECL_SOURCE_FILE (method), @@ -7203,9 +7324,13 @@ get_super_receiver () { super_class = get_class_reference (super_name); if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL) + /* Cast the super class to 'id', since the user may not have + included <objc/objc-class.h>, leaving 'struct objc_class' + an incomplete type. */ super_class - = build_component_ref (build_indirect_ref (super_class, "->"), - get_identifier ("isa")); + = build_component_ref (build_indirect_ref + (build_c_cast (id_type, super_class), "->"), + get_identifier ("isa")); } else { @@ -7963,12 +8088,21 @@ gen_method_decl (method, buf) /* Debug info. */ + +/* Dump an @interface declaration of the supplied class CHAIN to the + supplied file FP. Used to implement the -gen-decls option (which + prints out an @interface declaration of all classes compiled in + this run); potentially useful for debugging the compiler too. */ static void dump_interface (fp, chain) FILE *fp; tree chain; { - char *buf = (char *) xmalloc (256); + /* FIXME: A heap overflow here whenever a method (or ivar) + declaration is so long that it doesn't fit in the buffer. The + code and all the related functions should be rewritten to avoid + using fixed size buffers. */ + char *buf = (char *) xmalloc (1024 * 10); const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain)); tree ivar_decls = CLASS_RAW_IVARS (chain); tree nst_methods = CLASS_NST_METHODS (chain); @@ -7976,14 +8110,26 @@ dump_interface (fp, chain) fprintf (fp, "\n@interface %s", my_name); + /* CLASS_SUPER_NAME is used to store the superclass name for + classes, and the category name for categories. */ if (CLASS_SUPER_NAME (chain)) { - const char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain)); - fprintf (fp, " : %s\n", super_name); + const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain)); + + if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE + || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE) + { + fprintf (fp, " (%s)\n", name); + } + else + { + fprintf (fp, " : %s\n", name); + } } else fprintf (fp, "\n"); + /* FIXME - the following doesn't seem to work at the moment. */ if (ivar_decls) { fprintf (fp, "{\n"); @@ -8007,7 +8153,8 @@ dump_interface (fp, chain) fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf)); cls_methods = TREE_CHAIN (cls_methods); } - fprintf (fp, "\n@end"); + + fprintf (fp, "@end\n"); } /* Demangle function for Objective-C */ @@ -8067,7 +8214,7 @@ objc_demangle (mangled) return mangled; /* not an objc mangled name */ } -static const char * +const char * objc_printable_name (decl, kind) tree decl; int kind ATTRIBUTE_UNUSED; @@ -8075,22 +8222,6 @@ objc_printable_name (decl, kind) return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl))); } -/* Adds the tree codes specific to the ObjC/ObjC++ front end to the - list of all tree codes. */ - -static void -add_objc_tree_codes () -{ - int add = (int) LAST_OBJC_TREE_CODE - (int) LAST_BASE_TREE_CODE; - - memcpy (tree_code_type + (int) LAST_BASE_TREE_CODE, - objc_tree_code_type, add); - memcpy (tree_code_length + (int) LAST_BASE_TREE_CODE, - objc_tree_code_length, add * sizeof (int)); - memcpy (tree_code_name + (int) LAST_BASE_TREE_CODE, - objc_tree_code_name, add * sizeof (char *)); -} - static void init_objc () { @@ -8143,7 +8274,16 @@ finish_objc () UOBJC_CLASS_decl = impent->class_decl; UOBJC_METACLASS_decl = impent->meta_decl; - + + /* Dump the @interface of each class as we compile it, if the + -gen-decls option is in use. TODO: Dump the classes in the + order they were found, rather than in reverse order as we + are doing now. */ + if (flag_gen_declaration) + { + dump_interface (gen_declaration_file, objc_implementation_context); + } + if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE) { /* all of the following reference the string pool... */ @@ -8194,12 +8334,6 @@ finish_objc () generate_strings (); - if (flag_gen_declaration) - { - add_class (objc_implementation_context); - dump_interface (gen_declaration_file, objc_implementation_context); - } - if (warn_selector) { int slot; @@ -8364,7 +8498,7 @@ handle_impent (impent) tree decl, init; init = build_int_2 (0, 0); - TREE_TYPE (init) = type_for_size (BITS_PER_WORD, 1); + TREE_TYPE (init) = c_common_type_for_size (BITS_PER_WORD, 1); decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init)); TREE_PUBLIC (decl) = 1; TREE_READONLY (decl) = 1; @@ -8377,51 +8511,6 @@ handle_impent (impent) } } -static void -ggc_mark_imp_list (arg) - void *arg; -{ - struct imp_entry *impent; - - for (impent = *(struct imp_entry **)arg; impent; impent = impent->next) - { - ggc_mark_tree (impent->imp_context); - ggc_mark_tree (impent->imp_template); - ggc_mark_tree (impent->class_decl); - ggc_mark_tree (impent->meta_decl); - } -} - -static void -ggc_mark_hash_table (arg) - void *arg; -{ - hash *hash_table = *(hash **)arg; - hash hst; - attr list; - int i; - - if (hash_table == NULL) - return; - for (i = 0; i < SIZEHASHTABLE; i++) - for (hst = hash_table [i]; hst; hst = hst->next) - { - ggc_mark_tree (hst->key); - for (list = hst->list; list; list = list->next) - ggc_mark_tree (list->value); - } -} - -/* Add GC roots for variables local to this file. */ -static void -objc_act_parse_init () -{ - ggc_add_tree_root (objc_global_trees, OCTI_MAX); - ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list); - ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table); - ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table); -} - /* Look up ID as an instance variable. */ tree lookup_objc_ivar (id) @@ -8429,8 +8518,8 @@ lookup_objc_ivar (id) { tree decl; - if (objc_receiver_context && !strcmp (IDENTIFIER_POINTER (id), "super")) - /* we have a message to super */ + if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super")) + /* We have a message to super. */ return get_super_receiver (); else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id))) { @@ -8442,3 +8531,5 @@ lookup_objc_ivar (id) else return 0; } + +#include "gtype-objc.h" diff --git a/contrib/gcc/objc/objc-act.h b/contrib/gcc/objc/objc-act.h index 72b8b3e..af10387 100644 --- a/contrib/gcc/objc/objc-act.h +++ b/contrib/gcc/objc/objc-act.h @@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */ /*** Public Interface (procedures) ***/ const char *objc_init PARAMS ((const char *)); -int objc_decode_option PARAMS ((int, char **)); +const char *objc_printable_name PARAMS ((tree, int)); /* used by yyparse */ @@ -63,8 +63,6 @@ void objc_declare_alias PARAMS ((tree, tree)); void objc_declare_class PARAMS ((tree)); void objc_declare_protocols PARAMS ((tree)); -extern int objc_receiver_context; - /* the following routines are used to implement statically typed objects */ int objc_comptypes PARAMS ((tree, tree, int)); @@ -99,6 +97,7 @@ tree build_encode_expr PARAMS ((tree)); #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 CLASS_OWN_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 5) #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) @@ -132,28 +131,26 @@ enum objc_tree_code { typedef struct hashed_entry *hash; typedef struct hashed_attribute *attr; -struct hashed_attribute +struct hashed_attribute GTY(()) { attr next; tree value; }; -struct hashed_entry +struct hashed_entry GTY(()) { attr list; hash next; tree key; }; -extern hash *nst_method_hash_list; -extern hash *cls_method_hash_list; +extern GTY ((length ("SIZEHASHTABLE"))) hash *nst_method_hash_list; +extern GTY ((length ("SIZEHASHTABLE"))) hash *cls_method_hash_list; -#define HASH_ALLOC_LIST_SIZE 170 -#define ATTR_ALLOC_LIST_SIZE 170 #define SIZEHASHTABLE 257 /* Objective-C/Objective-C++ @implementation list. */ -struct imp_entry +struct imp_entry GTY(()) { struct imp_entry *next; tree imp_context; @@ -162,7 +159,7 @@ struct imp_entry tree meta_decl; /* _OBJC_METACLASS_<my_name>; */ }; -extern struct imp_entry *imp_list; +extern GTY(()) struct imp_entry *imp_list; extern int imp_count; /* `@implementation' */ extern int cat_count; /* `@category' */ @@ -247,7 +244,7 @@ enum objc_tree_index OCTI_MAX }; -extern tree objc_global_trees[OCTI_MAX]; +extern GTY(()) tree objc_global_trees[OCTI_MAX]; /* List of classes with list of their static instances. */ #define objc_static_instances objc_global_trees[OCTI_STATIC_NST] diff --git a/contrib/gcc/objc/objc-lang.c b/contrib/gcc/objc/objc-lang.c index 9effd14..73e6204 100644 --- a/contrib/gcc/objc/objc-lang.c +++ b/contrib/gcc/objc/objc-lang.c @@ -40,19 +40,49 @@ static void objc_init_options PARAMS ((void)); #undef LANG_HOOKS_INIT_OPTIONS #define LANG_HOOKS_INIT_OPTIONS objc_init_options #undef LANG_HOOKS_DECODE_OPTION -#define LANG_HOOKS_DECODE_OPTION objc_decode_option +#define LANG_HOOKS_DECODE_OPTION c_common_decode_option #undef LANG_HOOKS_POST_OPTIONS #define LANG_HOOKS_POST_OPTIONS c_common_post_options #undef LANG_HOOKS_GET_ALIAS_SET #define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set #undef LANG_HOOKS_SAFE_FROM_P #define LANG_HOOKS_SAFE_FROM_P c_safe_from_p +#undef LANG_HOOKS_PARSE_FILE +#define LANG_HOOKS_PARSE_FILE c_common_parse_file +#undef LANG_HOOKS_EXPAND_EXPR +#define LANG_HOOKS_EXPAND_EXPR c_expand_expr +#undef LANG_HOOKS_MARK_ADDRESSABLE +#define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable +#undef LANG_HOOKS_TRUTHVALUE_CONVERSION +#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion +#undef LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES +#define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES c_insert_default_attributes +#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL +#define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl +#undef LANG_HOOKS_UNSAFE_FOR_REEVAL +#define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval #undef LANG_HOOKS_STATICP #define LANG_HOOKS_STATICP c_staticp +#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL +#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl #undef LANG_HOOKS_PRINT_IDENTIFIER #define LANG_HOOKS_PRINT_IDENTIFIER c_print_identifier -#undef LANG_HOOKS_SET_YYDEBUG -#define LANG_HOOKS_SET_YYDEBUG c_set_yydebug +#undef LANG_HOOKS_DECL_PRINTABLE_NAME +#define LANG_HOOKS_DECL_PRINTABLE_NAME objc_printable_name +#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL +#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl + +#undef LANG_HOOKS_FUNCTION_ENTER_NESTED +#define LANG_HOOKS_FUNCTION_ENTER_NESTED c_push_function_context +#undef LANG_HOOKS_FUNCTION_LEAVE_NESTED +#define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context + +/* Attribute hooks. */ +#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE +#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table +#undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE +#define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE c_common_format_attribute_table + /* Inlining hooks same as the C front end. */ #undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN #define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \ @@ -67,11 +97,71 @@ static void objc_init_options PARAMS ((void)); #define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \ c_convert_parm_for_inlining +#undef LANG_HOOKS_TYPE_FOR_MODE +#define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode +#undef LANG_HOOKS_TYPE_FOR_SIZE +#define LANG_HOOKS_TYPE_FOR_SIZE c_common_type_for_size +#undef LANG_HOOKS_SIGNED_TYPE +#define LANG_HOOKS_SIGNED_TYPE c_common_signed_type +#undef LANG_HOOKS_UNSIGNED_TYPE +#define LANG_HOOKS_UNSIGNED_TYPE c_common_unsigned_type +#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE +#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE c_common_signed_or_unsigned_type +#undef LANG_HOOKS_INCOMPLETE_TYPE_ERROR +#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR c_incomplete_type_error +#undef LANG_HOOKS_TYPE_PROMOTES_TO +#define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to + /* Each front end provides its own hooks, for toplev.c. */ const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; +/* Define the special tree codes that we use. */ + +/* Table indexed by tree code giving a string containing a character + classifying the tree code. */ + +#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, + +const char tree_code_type[] = { +#include "tree.def" + 'x', +#include "c-common.def" + '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, + +const unsigned char tree_code_length[] = { +#include "tree.def" + 0, +#include "c-common.def" + 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, + +const char * const tree_code_name[] = { +#include "tree.def" + "@@dummy", +#include "c-common.def" + "@@dummy", +#include "objc-tree.def" +}; +#undef DEFTREECODE + static void objc_init_options () { - c_common_init_options (clk_objective_c); -} + flag_objc = 1; + c_common_init_options (clk_c); +} |