PATCH: Pre-ObjC++ ObjC Overhaul -- Part B
Ziemowit Laski
zlaski@apple.com
Mon Aug 16 08:03:00 GMT 2004
This is the ObjC-specific part of the patch. As you can see, the
changes to objc-act.c
are very extensive (with c-parse.in changes to match), and have mostly
to do with
weaning ObjC off the raw-declspec tree format in favor of better
groomed VAR_DECLs,
PARM_DECLs, FIELD_DECLs and the like.
[gcc/ChangeLog]
2004-08-16 Ziemowit Laski <zlaski@apple.com>
* c-parse.in (methodtype): Specify %type; remove (explicit) semantic
actions.
(objc_inherit_code, objc_public_flag): Remove.
(primary): Call objc_is_public() instead of is_public(),
objc_build_message_expr() instead of build_message_expr(),
objc_build_selector_expr() instead of build_selector_expr(),
objc_build_protocol_expr() instead of build_protocol_expr(),
objc_build_encode_expr() instead of build_encode_expr(),
objc_build_string_object() instead of build_objc_string_object().
(typespec_nonreserved_nonattr): Call objc_get_static_reference()
instead of get_static_reference(), objc_get_object_reference()
instead of get_object_reference().
(component_decl_list2): Call objc_get_class_ivars() instead of
get_class_ivars_from_name().
(objcdef): Move semantic action to objc_finish_implementation(),
and call it.
(classdef): Move semantic actions to objc_start_class_interface(),
objc_continue_interface(), objc_finish_interface(),
objc_start_class_implementation(), objc_continue_implementation(),
objc_start_category_interface() and
objc_start_category_implementation()
and call them.
(protocoldef): Move semantic actions to objc_start_protocol() and
objc_finish_interface() and call them.
(visibility_spec): Move semantic actions to objc_set_visibility() and
call it.
* c-parse.in (OBJC_TYPE_QUAL): New %token.
(ivars, ivar_declarator): Remove nonterminals and their associated
productions.
(objc_quals, objc_qual, objc_typename, optparms, optellipsis): New
nonterminals.
(ivar_decl): Use component_decl; adjust call to
objc_add_instance_variable().
(opt_semi): New nonterminal, with a pedantic-mode warning.
(objc_catch_prefix): Call grokparm() before calling
objc_begin_catch_clause().
(methoddef): Move semantic actions to objc_set_method_type() and
objc_start_method_definition(), objc_continue_method_definition()
and objc_finish_method_definition() and call them.
(methodproto): Move semantic actions to objc_set_method_type() and
objc_add_method_declaration() and call them.
(methoddecl): Call objc_build_method_signature() instead of
build_method_decl(); use objc_typename instead of typename.
(optparmlist): Call objc_method_ellipsis().
(keyworddecl): Call objc_build_keyword_decl() instead of
build_keyword_decl(); use objc_typename instead of typename.
(receiver): Call objc_get_class_reference() instead of
get_class_reference().
(rid_to_yy): Mark RID_IN, RID_OUT, RID_INOUT, RID_BYCOPY, RID_BYREF
and RID_ONEWAY as returning OBJC_TYPE_QUAL to yyparse().
(yylexname): Call objc_is_class_name() instead of is_class_name().
* stub-objc.c (lookup_interface): Remove stub.
(is_class_name): Rename to objc_is_class_name.
(lookup_objc_ivar): Rename to objc_lookup_ivar.
(objc_is_reserved_word, objc_declare_alias, objc_declare_class,
objc_declare_protocols, objc_start_protocol, objc_is_id,
objc_start_class_interface, objc_start_category_interface,
objc_continue_interface, objc_finish_interface,
objc_add_instance_variable, objc_set_visibility,
objc_set_method_type, objc_start_class_implementation,
objc_start_category_implementation, objc_continue_implementation,
objc_finish_implementation, objc_add_method_declaration,
objc_start_method_definition, objc_get_protocol_qualified_type,
objc_finish_method_definition, objc_build_keyword_decl,
objc_build_method_signature, objc_build_encode_expr,
objc_build_protocol_expr, objc_static_init_needed_p,
objc_build_selector_expr, objc_build_message_expr,
objc_build_string_object, objc_get_class_reference,
objc_generate_static_init_call): New stubs.
[gcc/objc/ChangeLog]
2004-08-16 Ziemowit Laski <zlaski@apple.com>
* Make-lang.in (objc/objc-act.o): Depend on $(HASHTAB_H).
(objc/objc-parse.o): Depend on $(C_COMMON_H) instead of
objc/objc-act.h.
* config-lang.in (lang_requires): Add "C" as a dependency.
* lang-specs.h: Rename 'objc-cpp-output' to 'objective-c-cpp-output'.
* objc-act.c: Include hashtab.h; in ObjC++ mode, include cp-tree.h and
objcp-decl.h instead of c-tree.h.
(objc_inherit_code, objc_public_flag): New, moved from c-parse.in.
(TYPE_ID): Rename to OBJECT_TYPEDEF_NAME.
(CLASS_TYPEDEF_NAME): New.
(TAG_EXECCLASS): Change from a global variable to a #define.
(TAG_RETURN_STRUCT): Delete.
(TAG_GNUINIT): New, holds '__objc_gnu_init' name.
(string_descriptor): New type.
(string_htab): New hash table, for constant strings.
(string_hash, string_eq): New functions.
(hash_init): Initialize string_htab hash table.
(build_objc_string_object): Rename to objc_build_string_object();
unique string objects using the string_htab hash table.
(objc_start_function, objc_push_parm, objc_get_parm_info,
gen_type_name, start_var_decl, finish_var_decl): New functions.
(objc_expr_last, gen_declaration_1, gen_declarator, is_complex_decl,
adorn_decl, define_decl, gen_declspecs, objc_is_type_qualifier): Remove
functions.
(synth_module_prologue): Call build_class_template(); predefine 'id'
and 'Class' as typedefs; rename 'temp_type' to 'type'; disable debug
hooks for duration of function; fix GNU runtime messenger signatures
to correspond to reality; forward-declare '__objc_exec_class' for the
GNU runtime; call build_selector_table_decl(); in ObjC++ mode, generate
'extern "C" { ... }' wrappers around synthesized declarations; call
build_protocol_template() and build_category_template().
(build_metadata_decl): Call start_var_decl() instead of define_decl().
(generate_objc_symtab_decl): Do not call build_category_template();
call start_var_decl() and finish_var_decl() instead of start_decl()
and finish_decl().
(build_module_descriptor): Call create_field_decl() instead of
grokfield(); call start_var_decl() and finish_var_decl() instead of
start_decl() and finish_decl(); always mark module descriptor as
used; move GNU runtime-specific functionality to
build_module_initializer_routine().
(build_module_initializer_routine): New function,
broken off of build_module_descriptor().
(generate_static_references, generate_strings,
build_selector_translation_table, generate_descriptor_table,
generate_ivars_list, generate_dispatch_table, generate_category): Call
start_var_decl() and finish_var_decl() instead of start_decl() and
finish_decl(); : build a type directly instead of via groktypename().
(build_selector_reference_decl, build_selector_table_decl,
build_class_reference_decl, build_protocol_reference,
generate_objc_image_info): Call start_var_decl() instead of
build_decl().
(build_selector_reference): For GNU runtime, do not call
build_selector_reference_decl().
(objc_get_class_ivars): Do not call grokfield().
(get_class_ivars): Remove second parameter; create a fresh copy
of the ivar list for each call; do not check for existence of
super class.
(objc_begin_catch_clause): Convert the incoming PARM_DECL into
a VAR_DECL before placing it in the appropriate scope; do not
call define_decl().
(build_private_template): Adjust call to get_class_ivars(); build
a type directly instead of via groktypename().
(build_protocol_template, build_method_prototype_list_template,
build_method_prototype_template, build_category_template,
build_selector_template, build_class_template, build_super_template,
build_ivar_template, build_ivar_list_template,
build_method_list_template, build_method_template):
Call create_field_decl() instead of grokfield().
(objc_method_parm_type): Do not call groktypename().
(objc_encoded_type_size): Use INTEGRALTYPE_P instead of INTEGER_TYPE,
BOOLEAN_TYPE and ENUMERAL_TYPE.
(generate_protocols): Do not call build_protocol_template() or
groktypename(); call start_var_decl() and finish_var_decl() instead of
start_decl() and finish_decl().
(synth_forward_declarations): Adjust call to build_metadata_decl().
(error_with_ivar): Remove last parameter.
(check_ivars): Do not iterate ovar CLASS_RAW_IVARS lists in addition
to CLASS_IVARS lists; adjust calls to error_with_ivar().
(generate_protocol_list, generate_shared_structures): Call
start_var_decl() and finish_var_decl() instead of start_decl() and
finish_decl(); build a type directly instead of via
groktypename().
(synth_id_with_class_suffix): Return a string.
(get_arg_type_list): For instance methods, use the instance type for
'self'; do not call groktypename_in_parm_context().
(finish_message_expr): Rename to objc_finish_message_expr();
call gen_type_name() instead of gen_declaration(); call objc_is_id()
instead of using IS_ID and IS_CLASS; Use objc_class_name instead of
calling get_identifier("Class"); handle CONVERT_EXPRs in receiver.
(build_objc_method_call, warn_with_method): Do not call groktypename().
(add_instance_variable): Simplify parameter list; do not call
grokfield();
do not populate CLASS_IVARS list.
(start_class): Check for the existence of super class, if one was
specified.
(continue_class): Use CLASS_RAW_IVARS rather than CLASS_IVARS; do not
call build_class_template(); adjust call to get_class_ivars(); call
build_decl(), pushdecl() and finish_decl() instead of define_decl().
(add_protocols): Use PROTOCOL_BINFO_ELTS for the tree vector size.
(start_protocol): Do not call build_protocol_template(); use
PROTOCOL_BINFO_ELTS for the tree vector size.
(encode_type_qualifiers): Do not handle the 'const' qualifier here.
(encode_pointer): Encode 'const char *' as 'r*', for backwards
compatibility.
(encode_array): Use HOST_WIDE_INT_PRINT_DEC instead of "%ld".
(encode_type): Handle the 'const' qualifier here.
(objc_parmlist): New global variable, sued by objc_push_parm and
objc_get_parm_info().
(synth_self_and_ucmd_args): For instance methods, use the instance
type for 'self'; call objc_push_parm() instead of push_parm_decl().
(start_method_def): Do not call push_scope(), declare_parm_level(),
pop_scope(), push_parm_decl(), store_parm_decls() or objc_expr_last();
just use objc_push_parm() and objc_get_parm_info().
(really_start_method); Call objc_start_function() instead of
start_function() and objc_expr_last().
(get_super_receiver): Call build_decl() and pushdecl() instead of
start_decl().
(tmpbuf, RAW_TYPESPEC): Remove.
(gen_method_decl): Call gen_type_name() instead of gen_declaration_1().
(generate_classref_translation_entry): Do not call start_decl(); call
finish_var_decl() instead of finish_decl(); call convert() instead of
build_c_cast().
(init_objc_symtab): Cast initializer element to appropriate
type.
(objc_static_init_needed_p, objc_generate_static_init_call): New
functions, called from within C and C++ static initializer logic.
(build_selector, build_typed_selector_reference): Always convert
result to the selector type.
(build_method_prototype_template, build_selector_template,
build_method_template): Use actual selector type for fields
pointing to selectors.
(finish_objc): For GNU runtime, call
build_module_initializer_routine() after build_module_descriptor().
(objc_init): Do not initialize objc_ellipsis_node or TAG_EXECCLASS;
In ObjC++ mode, call cxx_init() instead of c_objc_common_init().
(objc_method_ellipsis): Remove.
(get_static_reference, get_object_reference): Removed, replaced by...
(objc_get_protocol_qualified_type): ... this function; the 'id' and
'Class' types no longer need to be defined in a header.
(id_type, objc_id_id): Rename to objc_object_type and objc_object_name,
respectively.
(objc_class_type, objc_class_name, objc_class_reference): New.
(objc_build_constructor): Remove initializer element conversions;
tweak Objective-C++ impedance matching.
(add_objc_string): Cast return value to 'char *'.
(objc_is_id): New function.
(objc_is_object_ptr): Return the canonical type node.
(generate_ivar_lists): Convert one of the initializer elements.
(get_arg_type_list, start_method_def, gen_method_def): Account for
new representation of variable arguments and '...' in Objective-C
methods; add Objective-C++ impedance matching code.
(really_start_method): Initialize SELF_DECL here, and not in
start_method_def.
(continue_method_def): Remove.
(is_objc_type_qualifier): Rename to objc_is_type_qualifier and
make extern.
(adjust_type_for_id_default): Call objc_is_type_qualifier() instead
of is_objc_type_qualifier(); simplify; there is no longer a need to
wade through declspecs.
(objc_finish_file): Instantiate templates before calling
finish_objc(); move calls to cp_finish_file() (for ObjC++) or
c_objc_common_finish_file() (for ObjC) to the end.
(objc_is_object_ptr): Rewrite using POINTER_TYPE_P() and
IS_CLASS() macros.
(receiver_is_class_object, finish_message_expr): Use new
IS_CLASS() macro.
(build_module_descriptor): Use '__objc_gnu_init'
as static constructor name, so as not to collide with the
global C/C++ module constructor, and mark it as
DECL_STATIC_CONSTRUCTOR so that the back-end treats it
properly; call objc_begin_compount_stmt() and
objc_end_compound_stmt().
(objc_begin_compound_stmt, objc_end_compound_stmt,
objc_build_selector_decl): New functions.
(objc_enter_block): Call objc_begin_compound_stmt().
(objc_exit_block): Call objc_end_compound_stmt().
(create_builtin_decl): Rename to 'create_field_decl' and get
rid of the first parameter.
(objc_build_constructor): For ObjC++, zero out the constructor
type.
(generate_struct_by_value_array, build_objc_symtab_template):
Call create_field_decl() instead of create_builtin_decl().
(build_objc_exception_stuff): Call create_field_decl() instead
of create_builtin_decl(); do not touch debug hooks.
(build_super_template): Do not touch debug hooks.
(finish_objc): Do not hand-generate the constructor after
calling build_module_descriptor(); the C/C++ machinery will
do it for us.
(lookup_interface, start_class, continue_class,
finish_class, start_method_def, start_protocol, build_method_decl,
objc_add_method, add_instance_variable, build_ivar_reference,
is_ivar, is_private, get_super_receiver,
objc_build_finally_epilogue): Make into static functions.
(objc_start_class_interface, objc_start_category_interface,
objc_start_protocol, objc_continue_interface, objc_finish_interface,
objc_start_class_implementation, objc_start_category_implementation,
objc_continue_implementation, objc_finish_implementation,
objc_set_visibility, objc_set_method_type, objc_method_ellipsis,
objc_build_method_signature, objc_add_method_declaration,
objc_start_method_definition, objc_add_instance_variable,
objc_is_reserved_word): New functions.
(objc_check_decl): Call objc_is_class_name() instead of
is_class_name().
(objc_declare_alias): Call objc_is_class_name() instead of
is_class_name().
(is_class_name): Rename to objc_is_class_name().
(get_class_ivars_from_name): Rename to objc_get_class_ivars.
(objc_build_try_prologue): Call objc_get_current_scope()
instead of get_current_scope().
(objc_build_catch_stmt): Call objc_get_class_reference()
instead of get_class_reference().
(build_super_template): Name field 'super_class' instead
of 'class'.
(build_keyword_decl): Rename to objc_build_keyword_decl.
(build_method_decl): Tweak ObjC++ additional argument handling.
(build_message_expr): Rename to objc_build_message_expr;
tweak ObjC++ message argument handling; call
objc_finish_message_expr() instead of finish_message_expr().
(build_protocol_expr): Rename to objc_build_protocol_expr.
(build_selector_expr): Rename to objc_build_selector_expr.
(build_encode_expr): Rename to objc_build_encode_expr.
(is_public): Rename to objc_is_public.
(start_class): Call objc_is_class_name() instead of
is_class_name().
(finish_protocol, objc_expand_function_end): Remove.
(start_method_def): Tweak ObjC++ additional argument
handling.
(get_super_receiver): Call objc_get_current_scope() instead of
get_current_scope(); reference 'super_class' field (instead of
'class'); call objc_get_class_reference() instead of
get_class_reference().
(finish_method_def): Rename to objc_finish_method_definition and
add a function decl parameter; move method encoding call from
objc_expand_function_end.
(lookup_objc_ivar): Rename to objc_lookup_ivar.
(comp_method_with_proto): Remove.
(objc_check_decl, is_class_name): Use OBJC_TYPE_NAME instead of
TYPE_NAME.
(objc_exit_block): Adjust ObjC++ finish_compound_stmt() impedance
mismatch.
(finish_message_expr): Use OBJC_TYPE_NAME and OBJC_SET_TYPE_NAME
macros instead of TYPE_NAME.
(objc_types_are_equivalent): Strip away indirections before comparing
underlying types.
(really_start_method): Call comp_proto_with_proto instead of
comp_method_with_proto.
* objc-act.h (CLASS_OWN_IVARS): Remove accessor.
(CLASS_BINFO_ELTS): Reduce from 6 to 5, now that CLASS_OWN_IVARS is
gone.
(OCTI_GNU_INIT_DECL, GNU_INIT_decl): New.
(OCTI_ELLIPSIS_NODE, objc_ellipsis_node): Remove.
(OCTI_ID_ID, id_type, objc_id_id): Rename to OCTI_ID_NAME,
objc_object_type and objc_object_name, respectively.
(OCTI_CLS_REF, OCTI_CLASS_NAME, objc_class_reference,
objc_class_name): New.
(IS_CLASS): New macro.
(IS_ID, IS_SUPER): Robustify.
(OCTI_EXECCLASS_DECL, execclass_decl): New.
(finish_file, start_class, continue_class, finish_class,
start_method_def, continue_method_def, finish_method_def,
start_protocol, finish_protocol, objc_build_throw_stmt,
objc_build_try_catch_finally_stmt, objc_build_synchronized_prologue,
objc_build_synchronized_epilogue, objc_build_try_prologue,
objc_build_try_epilogue, objc_build_catch_stmt,
objc_build_catch_epilogue,
objc_build_finally_prologue, objc_build_finally_epilogue,
is_ivar, is_private, is_public, add_instance_variable, objc_add_method,
get_super_receiver, objc_clear_super_receiver,
get_class_ivars_from_name,
get_class_reference, get_static_reference, get_object_reference,
build_message_expr, finish_message_expr, build_selector_expr,
build_ivar_reference, build_keyword_decl, build_method_decl,
build_protocol_expr, build_objc_string_object, objc_declare_alias,
objc_declare_class, objc_declare_protocols, objc_comptypes,
objc_check_decl, build_encode_expr): Remove prototypes.
(imp_count, cat_count): Make GGC-aware.
(OBJC_SET_TYPE_NAME): New macro.
[gcc/testsuite/ChangeLog]
2004-08-16 Ziemowit Laski <zlaski@apple.com>
* objc/execute/next_mapping.h: Include stdlib.h and string.h.
(MIN, MAX, ROUND): Redefine macros to be C/C++-agnostic.
(__small_struct): New typedef.
(STRUCTURE_SIZE_BOUNDARY): Use __small_struct instead of an inline
struct definition.
(arglist_t): Provide a union tag.
(objc_aligned_size): Add missing prototype.
(objc_sizeof_type): Use sizeof(char) in place of sizeof(void);
remove extraneous break statements.
(objc_alignof_type, objc_skip_typespec): Remove extraneous break
statements.
* objc.dg/bitfield-2.m: Make 'id' definition a typedef.
* obj.dg/bitfield-4.m, objc.dg/method-6.m: Allow 'unsigned' in addition
to 'unsigned int' in error message.
* objc.dg/const-str-3.m: Include <memory.h> and <stdlib.h>.
* objc.dg/id-1.m: Attempt to define 'id' in an incompatible fashion.
* objc.dg/proto-qual-1.m: Protocol qualifiers now appear before the
types they qualify.
* objc.dg/type-size-2.m: Fix wording in comment.
* objc.dg/va-meth-1.m: New test case.
Index: gcc/c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.226
diff -u -3 -p -r1.226 c-parse.in
--- gcc/c-parse.in 15 Aug 2004 15:44:51 -0000 1.226
+++ gcc/c-parse.in 16 Aug 2004 00:26:05 -0000
@@ -175,7 +176,7 @@ do {
\
/* The Objective-C keywords. These are included in C and in
Objective C, so that the token codes are the same in both. */
%token AT_INTERFACE AT_IMPLEMENTATION AT_END AT_SELECTOR AT_DEFS
AT_ENCODE
-%token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL
+%token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL
%token OBJECTNAME AT_CLASS AT_ALIAS
%token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED
%token OBJC_STRING
@@ -244,17 +245,18 @@ do {
\
@@ifobjc
/* the Objective-C nonterminals */
-%type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator
%type <ttype> methoddecl unaryselector keywordselector selector
+%type <code> methodtype
%type <ttype> keyworddecl receiver objcmessageexpr messageargs
%type <ttype> keywordexpr keywordarglist keywordarg
-%type <ttype> myparms myparm optparmlist reservedwords objcselectorexpr
+%type <ttype> optparmlist optparms reservedwords objcselectorexpr
%type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
%type <ttype> non_empty_protocolrefs protocolrefs identifier_list
objcprotocolexpr
-%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING
+%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING OBJC_TYPE_QUAL
-%type <ttype> superclass
+%type <ttype> superclass objc_quals objc_qual objc_typename
+%type <itype> objc_try_catch_stmt optellipsis
@@end_ifobjc
%{
@@ -308,8 +310,7 @@ static GTY(()) tree declspec_stack;
@@ifobjc
/* Objective-C specific parser/lexer information */
-static enum tree_code objc_inherit_code;
-static int objc_pq_context = 0, objc_public_flag = 0;
+static int objc_pq_context = 0;
/* The following flag is needed to contextualize ObjC lexical analysis.
In some cases (e.g., 'int NSObject;'), it is undesirable to bind
@@ -730,19 +731,19 @@ primary:
$$.original_code = ERROR_MARK; }
@@ifobjc
| objcmessageexpr
- { $$.value = build_message_expr ($1);
+ { $$.value = objc_build_message_expr ($1);
$$.original_code = ERROR_MARK; }
| objcselectorexpr
- { $$.value = build_selector_expr ($1);
+ { $$.value = objc_build_selector_expr ($1);
$$.original_code = ERROR_MARK; }
| objcprotocolexpr
- { $$.value = build_protocol_expr ($1);
+ { $$.value = objc_build_protocol_expr ($1);
$$.original_code = ERROR_MARK; }
| objcencodeexpr
- { $$.value = build_encode_expr ($1);
+ { $$.value = objc_build_encode_expr ($1);
$$.original_code = ERROR_MARK; }
| OBJC_STRING
- { $$.value = build_objc_string_object ($1);
+ { $$.value = objc_build_string_object ($1);
$$.original_code = ERROR_MARK; }
@@end_ifobjc
;
@@ -1356,14 +1357,14 @@ typespec_nonreserved_nonattr:
$$ = lookup_name ($1); }
@@ifobjc
| CLASSNAME protocolrefs
- { $$ = get_static_reference ($1, $2); }
+ { $$ = objc_get_protocol_qualified_type ($1, $2); }
| OBJECTNAME protocolrefs
- { $$ = get_protocol_reference ($2); }
+ { $$ = objc_get_protocol_qualified_type ($1, $2); }
/* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>"
- nisse@lysator.liu.se */
| non_empty_protocolrefs
- { $$ = get_protocol_reference ($1); }
+ { $$ = objc_get_protocol_qualified_type (NULL_TREE,
$1); }
@@end_ifobjc
| typeof '(' expr ')'
{ skip_evaluation--;
@@ -1796,7 +1797,7 @@ component_decl_list2: /* empty */
@@ifobjc
/* foo(sizeof(struct{ @defs(ClassName)})); */
| AT_DEFS '(' CLASSNAME ')'
- { $$ = nreverse (get_class_ivars_from_name ($3)); }
+ { $$ = nreverse (objc_get_class_ivars ($3)); }
@@end_ifobjc
;
@@ -2305,7 +2306,7 @@ stmt_nocomp:
objc_catch_prefix:
AT_CATCH '(' parm ')'
- { objc_begin_catch_clause ($3); }
+ { objc_begin_catch_clause (grokparm ($3)); }
;
objc_catch_clause:
@@ -2648,14 +2649,7 @@ objcdef:
| methoddef
| AT_END
{
- if (objc_implementation_context)
- {
- finish_class (objc_implementation_context);
- objc_ivar_chain = NULL_TREE;
- objc_implementation_context = NULL_TREE;
- }
- else
- warning ("`@end' must appear in an implementation
context");
+ objc_finish_implementation ();
}
;
@@ -2694,50 +2688,38 @@ class_ivars:
classdef:
AT_INTERFACE identifier superclass protocolrefs
{
- objc_interface_context = objc_ivar_context
- = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4);
- objc_public_flag = 0;
+ objc_start_class_interface ($2, $3, $4);
}
class_ivars
{
- continue_class (objc_interface_context);
+ objc_continue_interface ();
}
methodprotolist AT_END
{
- finish_class (objc_interface_context);
- objc_interface_context = NULL_TREE;
+ objc_finish_interface ();
}
| AT_IMPLEMENTATION identifier superclass
{
- objc_implementation_context = objc_ivar_context
- = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3,
NULL_TREE);
- objc_public_flag = 0;
+ objc_start_class_implementation ($2, $3);
}
class_ivars
{
- objc_ivar_chain
- = continue_class (objc_implementation_context);
+ objc_continue_implementation ();
}
| AT_INTERFACE identifier '(' identifier ')' protocolrefs
{
- objc_interface_context
- = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6);
- continue_class (objc_interface_context);
+ objc_start_category_interface ($2, $4, $6);
}
methodprotolist AT_END
{
- finish_class (objc_interface_context);
- objc_interface_context = NULL_TREE;
+ objc_finish_interface ();
}
| AT_IMPLEMENTATION identifier '(' identifier ')'
{
- objc_implementation_context
- = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2,
$4, NULL_TREE);
- objc_ivar_chain
- = continue_class (objc_implementation_context);
+ objc_start_category_implementation ($2, $4);
}
;
@@ -2745,14 +2727,12 @@ protocoldef:
AT_PROTOCOL identifier protocolrefs
{
objc_pq_context = 1;
- objc_interface_context
- = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3);
+ objc_start_protocol ($2, $3);
}
methodprotolist AT_END
{
objc_pq_context = 0;
- finish_protocol(objc_interface_context);
- objc_interface_context = NULL_TREE;
+ objc_finish_interface ();
}
/* The @protocol forward-declaration production introduces a
reduce/reduce conflict on ';', which should be resolved in
@@ -2782,109 +2762,67 @@ non_empty_protocolrefs:
;
ivar_decl_list:
- ivar_decl_list visibility_spec ivar_decls
- | ivar_decls
+ /* empty */
+ | ivar_decl_list visibility_spec ivar_decls
;
visibility_spec:
- AT_PRIVATE { objc_public_flag = 2; }
- | AT_PROTECTED { objc_public_flag = 0; }
- | AT_PUBLIC { objc_public_flag = 1; }
+ /* empty */
+ | AT_PRIVATE { objc_set_visibility (2); }
+ | AT_PROTECTED { objc_set_visibility (0); }
+ | AT_PUBLIC { objc_set_visibility (1); }
;
ivar_decls:
- /* empty */
- {
- $$ = NULL_TREE;
- }
+ /* empty */
| ivar_decls ivar_decl ';'
| ivar_decls ';'
{
- if (pedantic)
+ if (pedantic)
pedwarn ("extra semicolon in struct or union
specified");
- }
+ }
;
-
-/* There is a shift-reduce conflict here, because `components' may
- start with a `typename'. It happens that shifting (the default
resolution)
- does the right thing, because it treats the `typename' as part of
- a `typed_typespecs'.
-
- It is possible that this same technique would allow the distinction
- between `notype_initdecls' and `initdecls' to be eliminated.
- But I am being cautious and not trying it. */
-
ivar_decl:
- declspecs_nosc_ts setspecs ivars
- { $$ = $3;
- POP_DECLSPEC_STACK; }
- | declspecs_nosc_nots setspecs ivars
- { $$ = $3;
- POP_DECLSPEC_STACK; }
- | error
- { $$ = NULL_TREE; }
- ;
+ component_decl
+ {
+ /* Comma-separated ivars are chained together in
+ reverse order; add them one by one. */
+ tree ivar = nreverse ($1);
-ivars:
- /* empty */
- { $$ = NULL_TREE; }
- | ivar_declarator
- | ivars ',' maybe_resetattrs ivar_declarator
+ for (; ivar; ivar = TREE_CHAIN (ivar))
+ objc_add_instance_variable (copy_node (ivar));
+ }
;
-ivar_declarator:
- declarator
- {
- $$ = add_instance_variable (objc_ivar_context,
- objc_public_flag,
- $1, current_declspecs,
- NULL_TREE);
- }
- | declarator ':' expr_no_commas
- {
- $$ = add_instance_variable (objc_ivar_context,
- objc_public_flag,
- $1, current_declspecs,
$3.value);
- }
- | ':' expr_no_commas
+opt_semi:
+ /* NULL */
+ | ';'
{
- $$ = add_instance_variable (objc_ivar_context,
- objc_public_flag,
- NULL_TREE,
- current_declspecs,
$2.value);
- }
+ if (pedantic)
+ pedwarn ("extra semicolon in method definition
specified");
+ }
;
methodtype:
'+'
- { objc_inherit_code = CLASS_METHOD_DECL; }
| '-'
- { objc_inherit_code = INSTANCE_METHOD_DECL; }
;
methoddef:
methodtype
{
+ objc_set_method_type ($1);
objc_pq_context = 1;
- if (!objc_implementation_context)
- fatal_error ("method definition not in class
context");
}
- methoddecl
+ methoddecl opt_semi
{
objc_pq_context = 0;
- objc_add_method (objc_implementation_context,
- $3,
- objc_inherit_code ==
CLASS_METHOD_DECL);
- start_method_def ($3);
- }
- optarglist
- {
- continue_method_def ();
+ objc_start_method_definition ($3);
}
compstmt_or_error
{
- finish_method_def ();
+ objc_finish_method_definition (current_function_decl);
}
;
@@ -2906,6 +2844,7 @@ semi_or_error:
methodproto:
methodtype
{
+ objc_set_method_type ($1);
/* Remember protocol qualifiers in prototypes. */
objc_pq_context = 1;
}
@@ -2913,109 +2852,63 @@ methodproto:
{
/* Forget protocol qualifiers here. */
objc_pq_context = 0;
- objc_add_method (objc_interface_context,
- $3,
- objc_inherit_code ==
CLASS_METHOD_DECL);
+ objc_add_method_declaration ($3);
}
semi_or_error
;
methoddecl:
- '(' typename ')' unaryselector
+ '(' objc_typename ')' unaryselector
{
- $$ = build_method_decl (objc_inherit_code, $2, $4,
NULL_TREE);
+ $$ = objc_build_method_signature ($2, $4, NULL_TREE);
}
| unaryselector
{
- $$ = build_method_decl (objc_inherit_code, NULL_TREE,
$1, NULL_TREE);
+ $$ = objc_build_method_signature (NULL_TREE, $1,
NULL_TREE);
}
- | '(' typename ')' keywordselector optparmlist
+ | '(' objc_typename ')' keywordselector optparmlist
{
- $$ = build_method_decl (objc_inherit_code, $2, $4,
$5);
+ $$ = objc_build_method_signature ($2, $4, $5);
}
| keywordselector optparmlist
{
- $$ = build_method_decl (objc_inherit_code, NULL_TREE,
$1, $2);
+ $$ = objc_build_method_signature (NULL_TREE, $1, $2);
}
;
-/* "optarglist" assumes that start_method_def has already been
called...
- if it is not, the "xdecls" will not be placed in the proper scope */
-
-optarglist:
- /* empty */
- | ';' myxdecls
- ;
-
-/* to get around the following situation: "int foo (int a) int b; {}"
that
- is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */
-
-myxdecls:
- /* empty */
- | mydecls
- ;
-
-mydecls:
- mydecl
- | errstmt
- | mydecls mydecl
- | mydecl errstmt
- ;
-
-mydecl:
- declspecs_ts setspecs myparms ';'
- { POP_DECLSPEC_STACK; }
- | declspecs_ts ';'
- { shadow_tag ($1); }
- | declspecs_nots ';'
- { pedwarn ("empty declaration"); }
- ;
-
-myparms:
- myparm
- { push_parm_decl ($1); }
- | myparms ',' myparm
- { push_parm_decl ($3); }
- ;
+/* Optional ObjC method parameters follow the C syntax, and may
include '...'
+ to denote a variable number of arguments. */
-/* A single parameter declaration or parameter type name,
- as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */
-
-myparm:
- parm_declarator maybe_attribute
- { $$ = build_tree_list (build_tree_list
(current_declspecs,
- $1),
- chainon ($2,
all_prefix_attributes)); }
- | notype_declarator maybe_attribute
- { $$ = build_tree_list (build_tree_list
(current_declspecs,
- $1),
- chainon ($2,
all_prefix_attributes)); }
- | absdcl_maybe_attribute
- { $$ = $1; }
+optparmlist:
+ optparms optellipsis
+ {
+ TREE_OVERFLOW ($$) = $2;
+ }
;
-optparmlist:
- /* empty */
+optparms:
+ /* NULL */
{
- $$ = NULL_TREE;
+ $$ = make_node (TREE_LIST);
}
- | ',' ELLIPSIS
+ | optparms ',' parm
{
- /* oh what a kludge! */
- $$ = objc_ellipsis_node;
+ $$ = chainon ($1, build_tree_list (NULL_TREE,
+ grokparm ($3)));
}
- | ','
+ ;
+
+optellipsis:
+ /* NULL */
{
- push_scope ();
+ $$ = 0;
}
- parmlist_2
+ | ',' ELLIPSIS
{
- /* returns a tree list node generated by
get_parm_info */
- $$ = $3;
- pop_scope ();
+ $$ = 1;
}
;
@@ -3041,31 +2934,57 @@ selector:
;
reservedwords:
- ENUM | STRUCT | UNION | IF | ELSE | WHILE | DO | FOR
+ ENUM | STRUCT | UNION | IF | ELSE | WHILE | DO | FOR
| SWITCH | CASE | DEFAULT | BREAK | CONTINUE | RETURN
| GOTO | ASM_KEYWORD | SIZEOF | TYPEOF | ALIGNOF
| TYPESPEC | TYPE_QUAL
;
+objc_qual:
+ OBJC_TYPE_QUAL
+ ;
+
+objc_quals:
+ objc_quals objc_qual
+ {
+ $$ = chainon ($1, build_tree_list (NULL_TREE, $2));
+ }
+ | /* NULL */
+ {
+ $$ = NULL_TREE;
+ }
+ ;
+
+objc_typename:
+ objc_quals typename
+ {
+ $$ = build_tree_list ($1, groktypename ($2));
+ }
+ | objc_quals
+ {
+ $$ = build_tree_list ($1, NULL_TREE);
+ }
+ ;
+
keyworddecl:
- selector ':' '(' typename ')' identifier
+ selector ':' '(' objc_typename ')' identifier
{
- $$ = build_keyword_decl ($1, $4, $6);
+ $$ = objc_build_keyword_decl ($1, $4, $6);
}
| selector ':' identifier
{
- $$ = build_keyword_decl ($1, NULL_TREE, $3);
+ $$ = objc_build_keyword_decl ($1, NULL_TREE, $3);
}
- | ':' '(' typename ')' identifier
+ | ':' '(' objc_typename ')' identifier
{
- $$ = build_keyword_decl (NULL_TREE, $3, $5);
+ $$ = objc_build_keyword_decl (NULL_TREE, $3, $5);
}
| ':' identifier
{
- $$ = build_keyword_decl (NULL_TREE, NULL_TREE, $2);
+ $$ = objc_build_keyword_decl (NULL_TREE, NULL_TREE,
$2);
}
;
@@ -3111,11 +3030,11 @@ receiver:
{ $$ = $1.value; }
| CLASSNAME
{
- $$ = get_class_reference ($1);
+ $$ = objc_get_class_reference ($1);
}
| TYPENAME
{
- $$ = get_class_reference ($1);
+ $$ = objc_get_class_reference ($1);
}
;
@@ -3274,6 +3193,7 @@ static const struct resword reswords[] =
{ "void", RID_VOID, 0 },
{ "volatile", RID_VOLATILE, 0 },
{ "while", RID_WHILE, 0 },
+
@@ifobjc
{ "id", RID_ID, D_OBJC },
@@ -3339,12 +3259,12 @@ static const short rid_to_yy[RID_MAX] =
/* RID_MUTABLE */ 0,
/* ObjC */
- /* RID_IN */ TYPE_QUAL,
- /* RID_OUT */ TYPE_QUAL,
- /* RID_INOUT */ TYPE_QUAL,
- /* RID_BYCOPY */ TYPE_QUAL,
- /* RID_BYREF */ TYPE_QUAL,
- /* RID_ONEWAY */ TYPE_QUAL,
+ /* RID_IN */ OBJC_TYPE_QUAL,
+ /* RID_OUT */ OBJC_TYPE_QUAL,
+ /* RID_INOUT */ OBJC_TYPE_QUAL,
+ /* RID_BYCOPY */ OBJC_TYPE_QUAL,
+ /* RID_BYREF */ OBJC_TYPE_QUAL,
+ /* RID_ONEWAY */ OBJC_TYPE_QUAL,
/* C */
/* RID_INT */ TYPESPEC,
@@ -3518,7 +3438,7 @@ yylexname (void)
@@ifobjc
else
{
- tree objc_interface_decl = is_class_name (yylval.ttype);
+ tree objc_interface_decl = objc_is_class_name (yylval.ttype);
/* ObjC class names are in the same namespace as variables and
typedefs, and hence are shadowed by local declarations. */
if (objc_interface_decl
Index: gcc/stub-objc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stub-objc.c,v
retrieving revision 2.4
diff -u -3 -p -r2.4 stub-objc.c
--- gcc/stub-objc.c 25 Jul 2004 00:13:00 -0000 2.4
+++ gcc/stub-objc.c 16 Aug 2004 04:35:39 -0000
@@ -2,7 +2,7 @@
that are called from within the C and C++ front-ends,
respectively.
Copyright (C) 1991, 1995, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -28,13 +28,13 @@ Software Foundation, 59 Temple Place - S
#include "c-common.h"
tree
-lookup_interface (tree ARG_UNUSED (arg))
+objc_is_class_name (tree ARG_UNUSED (arg))
{
return 0;
}
tree
-is_class_name (tree ARG_UNUSED (arg))
+objc_is_id (tree ARG_UNUSED (arg))
{
return 0;
}
@@ -46,7 +46,7 @@ objc_is_object_ptr (tree ARG_UNUSED (arg
}
tree
-lookup_objc_ivar (tree ARG_UNUSED (arg))
+objc_lookup_ivar (tree ARG_UNUSED (arg))
{
return 0;
}
@@ -57,9 +57,15 @@ objc_check_decl (tree ARG_UNUSED (decl))
}
int
+objc_is_reserved_word (tree ARG_UNUSED (ident))
+{
+ return 0;
+}
+
+int
objc_comptypes (tree ARG_UNUSED (lhs), tree ARG_UNUSED (rhs),
int ARG_UNUSED (reflexive))
-{
+{
return -1;
}
@@ -70,10 +76,178 @@ objc_message_selector (void)
}
void
+objc_declare_alias (tree ARG_UNUSED (alias), tree ARG_UNUSED (orig))
+{
+}
+
+void
+objc_declare_class (tree ARG_UNUSED (list))
+{
+}
+
+void
+objc_declare_protocols (tree ARG_UNUSED (list))
+{
+}
+
+void
+objc_start_protocol (tree ARG_UNUSED (proto),
+ tree ARG_UNUSED (protorefs))
+{
+}
+
+void
+objc_start_class_interface (tree ARG_UNUSED (name),
+ tree ARG_UNUSED (super),
+ tree ARG_UNUSED (protos))
+{
+}
+
+void
+objc_start_category_interface (tree ARG_UNUSED (name),
+ tree ARG_UNUSED (categ),
+ tree ARG_UNUSED (protos))
+{
+}
+
+void
+objc_continue_interface (void)
+{
+}
+
+void
+objc_finish_interface (void)
+{
+}
+
+void
+objc_add_instance_variable (tree ARG_UNUSED (decl))
+{
+}
+
+void
+objc_set_visibility (int ARG_UNUSED (vis))
+{
+}
+
+void
+objc_set_method_type (enum tree_code ARG_UNUSED (code))
+{
+}
+
+void
+objc_start_class_implementation (tree ARG_UNUSED (name),
+ tree ARG_UNUSED (super))
+{
+}
+
+void
+objc_start_category_implementation (tree ARG_UNUSED (name),
+ tree ARG_UNUSED (categ))
+{
+}
+
+void
+objc_continue_implementation (void)
+{
+}
+
+void
objc_clear_super_receiver (void)
{
}
+void
+objc_finish_implementation (void)
+{
+}
+
+void
+objc_add_method_declaration (tree ARG_UNUSED (signature))
+{
+}
+
+void
+objc_start_method_definition (tree ARG_UNUSED (signature))
+{
+}
+
+void
+objc_finish_method_definition (tree ARG_UNUSED (fndecl))
+{
+}
+
+tree
+objc_build_keyword_decl (tree ARG_UNUSED (selector),
+ tree ARG_UNUSED (typename),
+ tree ARG_UNUSED (identifier))
+{
+ return 0;
+}
+
+tree
+objc_build_method_signature (tree ARG_UNUSED (rettype),
+ tree ARG_UNUSED (selectors),
+ tree ARG_UNUSED (optparms))
+{
+ return 0;
+}
+
+tree
+objc_build_encode_expr (tree ARG_UNUSED (expr))
+{
+ return 0;
+}
+
+tree
+objc_build_protocol_expr (tree ARG_UNUSED (expr))
+{
+ return 0;
+}
+
+tree
+objc_build_selector_expr (tree ARG_UNUSED (expr))
+{
+ return 0;
+}
+
+tree
+objc_build_message_expr (tree ARG_UNUSED (expr))
+{
+ return 0;
+}
+
+tree
+objc_build_string_object (tree ARG_UNUSED (str))
+{
+ return 0;
+}
+
+tree
+objc_get_class_reference (tree ARG_UNUSED (name))
+{
+ return 0;
+}
+
+tree
+objc_get_protocol_qualified_type (tree ARG_UNUSED (name),
+ tree ARG_UNUSED (protos))
+{
+ return 0;
+}
+
+int
+objc_static_init_needed_p (void)
+{
+ return 0;
+}
+
+tree
+objc_generate_static_init_call (tree ARG_UNUSED (ctors))
+{
+ return 0;
+}
+
int
objc_is_public (tree ARG_UNUSED (expr), tree ARG_UNUSED (identifier))
{
Index: gcc/objc/Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/Make-lang.in,v
retrieving revision 1.73
diff -u -3 -p -r1.73 Make-lang.in
--- gcc/objc/Make-lang.in 15 Aug 2004 21:47:32 -0000 1.73
+++ gcc/objc/Make-lang.in 16 Aug 2004 04:35:42 -0000
@@ -66,18 +66,18 @@ objc/objc-lang.o : objc/objc-lang.c \
objc/objc-parse.o : objc/objc-parse.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_TREE_H) \
- toplev.h $(GGC_H) c-pragma.h input.h flags.h output.h
objc/objc-act.h \
+ toplev.h $(GGC_H) c-pragma.h input.h flags.h output.h $(C_COMMON_H)
\
langhooks.h
objc/objc-act.o : objc/objc-act.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H)
$(TM_P_H) \
$(EXPR_H) $(TARGET_H) $(C_TREE_H) diagnostic.h toplev.h flags.h \
objc/objc-act.h input.h function.h output.h debug.h langhooks.h \
- $(LANGHOOKS_DEF_H) gt-objc-objc-act.h
+ $(LANGHOOKS_DEF_H) $(HASHTAB_H) gt-objc-objc-act.h
objc.srcextra: objc/objc-parse.c objc/objc-parse.y
-cp -p $^ $(srcdir)/objc
-
+
objc/objc-parse.c : objc/objc-parse.y
-$(BISON) $(BISONFLAGS) -o $@ $<
Index: gcc/objc/config-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/config-lang.in,v
retrieving revision 1.12
diff -u -3 -p -r1.12 config-lang.in
--- gcc/objc/config-lang.in 20 Aug 2003 10:50:20 -0000 1.12
+++ gcc/objc/config-lang.in 16 Aug 2004 04:35:42 -0000
@@ -34,4 +34,7 @@ stagestuff="cc1obj\$(exeext)"
target_libs=target-libobjc
+# Most of the object files for cc1obj actually come from C.
+lang_requires="c"
+
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)/objc/objc-act.c"
Index: gcc/objc/lang-specs.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/lang-specs.h,v
retrieving revision 1.35
diff -u -3 -p -r1.35 lang-specs.h
--- gcc/objc/lang-specs.h 5 Apr 2004 19:23:24 -0000 1.35
+++ gcc/objc/lang-specs.h 16 Aug 2004 04:35:42 -0000
@@ -34,8 +34,8 @@ Boston, MA 02111-1307, USA. */
%{!save-temps:%{!no-integrated-cpp:\
cc1obj %(cpp_unique_options) %(cc1_options)
%{print-objc-runtime-info} %{gen-decls}}}\
%{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
- {".mi", "@objc-cpp-output", 0, 0, 0},
- {"@objc-cpp-output",
+ {".mi", "@objective-c-cpp-output", 0, 0, 0},
+ {"@objective-c-cpp-output",
"%{!M:%{!MM:%{!E:cc1obj -fpreprocessed %i %(cc1_options)
%{print-objc-runtime-info} %{gen-decls}\
%{!fsyntax-only:%(invoke_as)}}}}", 0, 0,
0},
{"@objective-c-header",
Index: gcc/objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.237
diff -u -3 -p -r1.237 objc-act.c
--- gcc/objc/objc-act.c 15 Aug 2004 21:47:32 -0000 1.237
+++ gcc/objc/objc-act.c 16 Aug 2004 04:35:42 -0000
@@ -47,7 +47,13 @@ Boston, MA 02111-1307, USA. */
#include "rtl.h"
#include "tm_p.h"
#include "expr.h"
+
+#ifdef OBJCPLUS
+#include "cp-tree.h"
+#else
#include "c-tree.h"
+#endif
+
#include "c-common.h"
#include "flags.h"
#include "langhooks.h"
@@ -65,6 +71,16 @@ Boston, MA 02111-1307, USA. */
#include "cgraph.h"
#include "tree-iterator.h"
#include "libfuncs.h"
+#include "hashtab.h"
+
+#define OBJC_VOID_AT_END void_list_node
+
+/* When building Objective-C++, we are not linking against the C
front-end
+ and so need to replicate the C tree-construction functions in some
way. */
+#ifdef OBJCPLUS
+#define OBJCP_REMAP_FUNCTIONS
+#include "objcp-decl.h"
+#endif /* OBJCPLUS */
/* This is the default way of generating a method name. */
/* I am not sure it is really correct.
@@ -126,15 +142,30 @@ static void finish_objc (void);
static void synth_module_prologue (void);
static tree objc_build_constructor (tree, tree);
-static rtx build_module_descriptor (void);
+static void build_module_descriptor (void);
+static void build_module_initializer_routine (void);
static tree init_module_descriptor (tree);
static tree build_objc_method_call (int, tree, tree, tree, tree);
static void generate_strings (void);
static tree get_proto_encoding (tree);
static void build_selector_translation_table (void);
-
+static tree lookup_interface (tree);
static tree objc_add_static_instance (tree, tree);
+static tree start_class (enum tree_code, tree, tree, tree);
+static tree continue_class (tree);
+static void finish_class (tree);
+static void start_method_def (tree);
+static void objc_start_function (tree, tree, tree, tree);
+static tree start_protocol (enum tree_code, tree, tree);
+static tree build_method_decl (enum tree_code, tree, tree, tree);
+static tree objc_add_method (tree, tree, int);
+static tree add_instance_variable (tree, int, tree);
+static tree build_ivar_reference (tree);
+static tree is_ivar (tree, tree);
+static int is_private (tree);
+static tree get_super_receiver (void);
+
static void build_objc_exception_stuff (void);
static void build_next_objc_exception_stuff (void);
@@ -150,7 +181,7 @@ static tree build_category_initializer (
static tree build_protocol_initializer (tree, tree, tree, tree, tree);
static void synth_forward_declarations (void);
static int ivar_list_length (tree);
-static tree get_class_ivars (tree, int);
+static tree get_class_ivars (tree);
static void generate_ivar_lists (void);
static void generate_dispatch_tables (void);
static void generate_shared_structures (void);
@@ -158,13 +189,12 @@ static tree generate_protocol_list (tree
static void build_protocol_reference (tree);
static tree build_keyword_selector (tree);
-static tree synth_id_with_class_suffix (const char *, tree);
+static const char *synth_id_with_class_suffix (const char *, tree);
static void generate_static_references (void);
static int check_methods_accessible (tree, tree, int);
static void encode_aggregate_within (tree, int, int, int, int);
static const char *objc_demangle (const char *);
-static void objc_expand_function_end (void);
/* Hash tables to manage the global pool of method prototypes. */
@@ -194,6 +224,7 @@ static tree add_objc_string (tree, enum
static tree get_objc_string_decl (tree, enum string_section);
static tree build_objc_string_decl (enum string_section);
static tree build_selector_reference_decl (void);
+static void build_selector_table_decl (void);
/* Protocol additions. */
@@ -214,31 +245,29 @@ static void encode_type (tree, int, int)
static void encode_field_decl (tree, int, int);
static void really_start_method (tree, tree);
-static int comp_method_with_proto (tree, tree);
static int objc_types_are_equivalent (tree, tree);
static int comp_proto_with_proto (tree, tree);
static tree get_arg_type_list (tree, int, int);
-static tree objc_expr_last (tree);
+static void objc_push_parm (tree);
+static tree objc_get_parm_info (int);
static void synth_self_and_ucmd_args (void);
/* Utilities for debugging and error diagnostics. */
static void warn_with_method (const char *, int, tree);
-static void error_with_ivar (const char *, tree, tree);
+static void error_with_ivar (const char *, tree);
+static char *gen_type_name (tree, char *);
static char *gen_method_decl (tree, char *);
static char *gen_declaration (tree, char *);
-static void gen_declaration_1 (tree, char *);
-static char *gen_declarator (tree, char *, const char *);
-static int is_complex_decl (tree);
-static void adorn_decl (tree, char *);
static void dump_interface (FILE *, tree);
/* Everything else. */
-static tree define_decl (tree, tree);
static tree lookup_method_in_protocol_list (tree, tree, int);
static tree lookup_protocol_in_reflist (tree, tree);
-static tree create_builtin_decl (enum tree_code, tree, const char *);
+static tree start_var_decl (tree, const char *);
+static void finish_var_decl (tree, tree);
+static tree create_field_decl (tree, const char *);
static void setup_string_decl (void);
static int check_string_class_template (void);
static tree my_build_string (int, const char *);
@@ -253,7 +282,7 @@ static tree build_typed_selector_referen
static tree build_selector_reference (tree);
static tree build_class_reference_decl (void);
static void add_class_reference (tree);
-static tree build_protocol_template (void);
+static void build_protocol_template (void);
static tree build_descriptor_table_initializer (tree, tree);
static tree build_method_prototype_list_template (tree, int);
static tree build_method_prototype_template (void);
@@ -274,7 +303,6 @@ static tree generate_dispatch_table (tre
static tree build_shared_structure_initializer (tree, tree, tree, tree,
tree, int, tree, tree,
tree);
static void generate_category (tree);
-static int is_objc_type_qualifier (tree);
static tree adjust_type_for_id_default (tree);
static tree check_duplicates (hash, int, int);
static tree receiver_is_class_object (tree, int, int);
@@ -282,7 +310,6 @@ static int check_methods (tree, tree, in
static int conforms_to_protocol (tree, tree);
static void check_protocol (tree, const char *, const char *);
static void check_protocols (tree, const char *, const char *);
-static void gen_declspecs (tree, char *, int);
static void generate_classref_translation_entry (tree);
static void handle_class_ref (tree);
static void generate_struct_by_value_array (void)
@@ -294,32 +321,34 @@ static void generate_objc_image_info (vo
/* 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_SYMTAB "_objc_symtab"
-#define UTAG_SUPER "_objc_super"
-#define UTAG_SELECTOR "_objc_selector"
-
-#define UTAG_PROTOCOL "_objc_protocol"
-#define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
-#define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
+#define OBJECT_TYPEDEF_NAME "id"
+#define CLASS_TYPEDEF_NAME "Class"
+
+#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_SYMTAB "_objc_symtab"
+#define UTAG_SUPER "_objc_super"
+#define UTAG_SELECTOR "_objc_selector"
+
+#define UTAG_PROTOCOL "_objc_protocol"
+#define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
+#define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
/* Note that the string object global name is only needed for the
NeXT runtime. */
-#define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
+#define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
-#define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
+#define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
static const char *TAG_GETCLASS;
static const char *TAG_GETMETACLASS;
@@ -329,7 +358,6 @@ static const char *TAG_MSGSENDSUPER;
when returning a structure. */
static const char *TAG_MSGSEND_STRET;
static const char *TAG_MSGSENDSUPER_STRET;
-static const char *TAG_EXECCLASS;
static const char *default_constant_string_class_name;
/* Runtime metadata flags. */
@@ -348,6 +376,8 @@ static const char *default_constant_stri
#define OBJC_MODIFIER_TRANSIENT 0x00000200
#define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
+/* NeXT-specific tags. */
+
#define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
#define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
#define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
@@ -358,10 +388,13 @@ static const char *default_constant_stri
#define TAG_SYNCENTER "objc_sync_enter"
#define TAG_SYNCEXIT "objc_sync_exit"
#define TAG_SETJMP "_setjmp"
-#define TAG_RETURN_STRUCT "objc_return_struct"
-
#define UTAG_EXCDATA "_objc_exception_data"
+/* GNU-specific tags. */
+
+#define TAG_EXECCLASS "__objc_exec_class"
+#define TAG_GNUINIT "__objc_gnu_init"
+
/* The OCTI_... enumeration itself is in objc/objc-act.h. */
tree objc_global_trees[OCTI_MAX];
@@ -371,6 +404,9 @@ struct imp_entry *imp_list = 0;
int imp_count = 0; /* `@implementation' */
int cat_count = 0; /* `@category' */
+enum tree_code objc_inherit_code;
+int objc_public_flag;
+
/* Use to generate method labels. */
static int method_slot = 0;
@@ -388,6 +424,23 @@ extern const char *dump_base_name;
static int flag_typed_selectors;
+/* Store all constructed constant strings in a hash table so that
+ they get uniqued properly. */
+
+struct string_descriptor GTY(())
+{
+ /* The literal argument . */
+ tree literal;
+
+ /* The resulting constant string. */
+ tree constructor;
+};
+
+static GTY((param_is (struct string_descriptor))) htab_t string_htab;
+
+static hashval_t string_hash (const void *);
+static int string_eq (const void *, const void *);
+
FILE *gen_declaration_file;
/* Tells "encode_pointer/encode_aggregate" whether we are generating
@@ -419,17 +472,15 @@ generate_struct_by_value_array (void)
type = start_struct (RECORD_TYPE, NULL_TREE);
strcpy (buffer, "c1");
- field_decl = create_builtin_decl (FIELD_DECL,
- char_type_node,
- buffer);
+ field_decl = create_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);
+ field_decl = create_field_decl (char_type_node,
+ buffer);
chainon (field_decl_chain, field_decl);
}
finish_struct (type, field_decl_chain, NULL_TREE);
@@ -463,7 +514,11 @@ generate_struct_by_value_array (void)
bool
objc_init (void)
{
+#ifdef OBJCPLUS
+ if (cxx_init () == false)
+#else
if (c_objc_common_init () == false)
+#endif
return false;
/* Force the line number back to 0; check_newline will have
@@ -489,7 +544,6 @@ objc_init (void)
TAG_MSGSENDSUPER = "objc_msgSendSuper";
TAG_MSGSEND_STRET = "objc_msgSend_stret";
TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
- TAG_EXECCLASS = "__objc_execClass";
default_constant_string_class_name = "NSConstantString";
}
else
@@ -500,13 +554,10 @@ objc_init (void)
TAG_MSGSENDSUPER = "objc_msg_lookup_super";
/* GNU runtime does not provide special functions to support
structure-returning methods. */
- TAG_EXECCLASS = "__objc_exec_class";
default_constant_string_class_name = "NXConstantString";
flag_typed_selectors = 1;
}
- objc_ellipsis_node = make_node (ERROR_MARK);
-
init_objc ();
if (print_struct_values)
@@ -520,6 +571,12 @@ objc_finish_file (void)
{
mark_referenced_methods ();
+#ifdef OBJCPLUS
+ /* We need to instantiate templates _before_ we emit ObjC metadata;
+ if we do not, some metadata (such as selectors) may go missing.
*/
+ instantiate_pending_templates ();
+#endif
+
/* Finalize Objective-C runtime data. No need to generate tables
and code if only checking syntax. */
if (!flag_syntax_only)
@@ -527,16 +584,12 @@ objc_finish_file (void)
if (gen_declaration_file)
fclose (gen_declaration_file);
+
+#ifdef OBJCPLUS
+ cp_finish_file ();
+#endif
}
-static tree
-define_decl (tree declarator, tree declspecs)
-{
- tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
- finish_decl (decl, NULL_TREE, NULL_TREE);
- return decl;
-}
-
/* Return the first occurrence of a method declaration corresponding
to sel_name in rproto_list. Search rproto_list recursively.
If is_class is 0, search for instance methods, otherwise for class
@@ -608,6 +661,151 @@ lookup_protocol_in_reflist (tree rproto_
return 0;
}
+void
+objc_start_class_interface (tree class, tree super_class, tree protos)
+{
+ objc_interface_context
+ = objc_ivar_context
+ = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
+ objc_public_flag = 0;
+}
+
+void
+objc_start_category_interface (tree class, tree categ, tree protos)
+{
+ objc_interface_context
+ = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
+ objc_ivar_chain
+ = continue_class (objc_interface_context);
+}
+
+void
+objc_start_protocol (tree name, tree protos)
+{
+ objc_interface_context
+ = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
+}
+
+void
+objc_continue_interface (void)
+{
+ objc_ivar_chain
+ = continue_class (objc_interface_context);
+}
+
+void
+objc_finish_interface (void)
+{
+ finish_class (objc_interface_context);
+ objc_interface_context = NULL_TREE;
+}
+
+void
+objc_start_class_implementation (tree class, tree super_class)
+{
+ objc_implementation_context
+ = objc_ivar_context
+ = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class,
NULL_TREE);
+ objc_public_flag = 0;
+}
+
+void
+objc_start_category_implementation (tree class, tree categ)
+{
+ objc_implementation_context
+ = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ,
NULL_TREE);
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+}
+
+void
+objc_continue_implementation (void)
+{
+ objc_ivar_chain
+ = continue_class (objc_implementation_context);
+}
+
+void
+objc_finish_implementation (void)
+{
+ if (objc_implementation_context)
+ {
+ finish_class (objc_implementation_context);
+ objc_ivar_chain = NULL_TREE;
+ objc_implementation_context = NULL_TREE;
+ }
+ else
+ warning ("`@end' must appear in an @implementation context");
+}
+
+void
+objc_set_visibility (int visibility)
+{
+ objc_public_flag = visibility;
+}
+
+void
+objc_set_method_type (enum tree_code type)
+{
+ objc_inherit_code = (type == PLUS_EXPR
+ ? CLASS_METHOD_DECL
+ : INSTANCE_METHOD_DECL);
+}
+
+tree
+objc_build_method_signature (tree rettype, tree selector, tree
optparms)
+{
+ return build_method_decl (objc_inherit_code, rettype, selector,
optparms);
+}
+
+void
+objc_add_method_declaration (tree decl)
+{
+ if (!objc_interface_context)
+ fatal_error ("method declaration not in @interface context");
+
+ objc_add_method (objc_interface_context,
+ decl,
+ objc_inherit_code == CLASS_METHOD_DECL);
+}
+
+void
+objc_start_method_definition (tree decl)
+{
+ if (!objc_implementation_context)
+ fatal_error ("method definition not in @implementation context");
+
+ objc_add_method (objc_implementation_context,
+ decl,
+ objc_inherit_code == CLASS_METHOD_DECL);
+ start_method_def (decl);
+}
+
+void
+objc_add_instance_variable (tree decl)
+{
+ (void) add_instance_variable (objc_ivar_context,
+ objc_public_flag,
+ decl);
+}
+
+/* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context
of
+ an '@'. */
+
+int
+objc_is_reserved_word (tree ident)
+{
+ unsigned char code = C_RID_CODE (ident);
+
+ return (OBJC_IS_AT_KEYWORD (code)
+#ifdef OBJCPLUS
+ || code == RID_CLASS || code == RID_PUBLIC
+ || code == RID_PROTECTED || code == RID_PRIVATE
+ || code == RID_TRY || code == RID_THROW || code == RID_CATCH
+#endif
+ );
+}
+
/* Return true if TYPE is 'id'. */
static bool
@@ -944,67 +1142,31 @@ objc_check_decl (tree decl)
if (TREE_CODE (type) != RECORD_TYPE)
return;
- if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type))))
+ if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name
(OBJC_TYPE_NAME (type))))
error ("statically allocated instance of Objective-C class `%s'",
IDENTIFIER_POINTER (type));
}
-/* Implement static typing. At this point, we know we have an
interface. */
-
-tree
-get_static_reference (tree interface, tree protocols)
-{
- tree type = xref_tag (RECORD_TYPE, interface);
-
- if (protocols)
- {
- tree t, m = TYPE_MAIN_VARIANT (type);
-
- t = copy_node (type);
-
- /* 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. Note
- that the protocol list can have a different lifetime than T!
*/
- SET_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_TREE;
-
- type = t;
- }
-
- return type;
-}
+/* Construct a PROTOCOLS-qualified variant of INTERFACE, where
INTERFACE may
+ either name an Objective-C class, or refer to the special 'id' or
'Class'
+ types. If INTERFACE is not a valid ObjC type, just return it
unchanged. */
-/* Return a declaration corresponding to a protocol list qualified
'id'. */
tree
-get_protocol_reference (tree protocols)
+objc_get_protocol_qualified_type (tree interface, tree protocols)
{
- tree type_decl = lookup_name (objc_id_id);
tree type;
- if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
+ if (!interface)
+ type = objc_object_type;
+ else if (!(type = objc_is_id (interface)))
{
- type = TREE_TYPE (type_decl);
- if (TYPE_MAIN_VARIANT (type) != objc_id_type)
- warning ("unexpected type for `id' (%s)",
- gen_declaration (type, errbuf));
- }
- else
- {
- error ("undefined type `id', please import <objc/objc.h>");
- return error_mark_node;
- }
+ type = objc_is_class_name (interface);
- /* 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 (type)
+ type = xref_tag (RECORD_TYPE, type);
+ else
+ return interface;
+ }
if (protocols)
{
@@ -1016,7 +1178,8 @@ get_protocol_reference (tree protocols)
TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
TYPE_NEXT_VARIANT (m) = t;
- /* Look up protocols...and install in lang specific list */
+ /* Look up protocols and install in lang specific list. Note
+ that the protocol list can have a different lifetime than T!
*/
SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols
(protocols));
/* This forces a new pointer type to be created later
@@ -1027,6 +1190,7 @@ get_protocol_reference (tree protocols)
type = t;
}
+
return type;
}
@@ -1079,24 +1243,44 @@ lookup_and_install_protocols (tree 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. */
+/* Create a declaration for field NAME of a given TYPE. */
static tree
-create_builtin_decl (enum tree_code code, tree type, const char *name)
+create_field_decl (tree type, const char *name)
{
- tree decl = build_decl (code, get_identifier (name), type);
+ return build_decl (FIELD_DECL, get_identifier (name), type);
+}
- if (code == VAR_DECL)
- {
- TREE_STATIC (decl) = 1;
- make_decl_rtl (decl);
- pushdecl (decl);
- DECL_ARTIFICIAL (decl) = 1;
- }
+/* Create a global, static declaration for variable NAME of a given
TYPE. The
+ finish_var_decl() routine will need to be called on it afterwards.
*/
- return decl;
+static tree
+start_var_decl (tree type, const char *name)
+{
+ tree var = build_decl (VAR_DECL, get_identifier (name), type);
+
+ TREE_STATIC (var) = 1;
+ DECL_INITIAL (var) = error_mark_node; /* A real initializer is
coming... */
+ DECL_IGNORED_P (var) = 1;
+ DECL_ARTIFICIAL (var) = 1;
+ DECL_CONTEXT (var) = NULL_TREE;
+#ifdef OBJCPLUS
+ DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
+#endif
+
+ return var;
+}
+
+/* Finish off the variable declaration created by start_var_decl(). */
+
+static void
+finish_var_decl (tree var, tree initializer)
+{
+ finish_decl (var, initializer, NULL_TREE);
+ /* Ensure that the variable actually gets output. */
+ mark_decl_referenced (var);
+ /* Mark the decl to avoid "defined but not used" warning. */
+ TREE_USED (var) = 1;
}
/* Find the decl for the constant string class. */
@@ -1136,22 +1320,50 @@ setup_string_decl (void)
static void
synth_module_prologue (void)
{
- tree temp_type;
+ tree type;
+ enum debug_info_type save_write_symbols = write_symbols;
+ const struct gcc_debug_hooks *const save_hooks = debug_hooks;
+
+ /* Suppress outputting debug symbols, because
+ dbxout_init hasn'r been called yet. */
+ write_symbols = NO_DEBUG;
+ debug_hooks = &do_nothing_debug_hooks;
+
+#ifdef OBJCPLUS
+ push_lang_context (lang_name_c); /* extern "C" */
+#endif
+
+ /* The following are also defined in <objc/objc.h> and friends. */
- /* Defined in `objc.h' */
objc_object_id = get_identifier (TAG_OBJECT);
+ objc_class_id = get_identifier (TAG_CLASS);
objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
+ objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
+
+ objc_object_type = build_pointer_type (objc_object_reference);
+ objc_class_type = build_pointer_type (objc_class_reference);
- objc_id_type = build_pointer_type (objc_object_reference);
+ objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
+ objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
- objc_id_id = get_identifier (TYPE_ID);
- objc_class_id = get_identifier (TAG_CLASS);
+ /* Declare the 'id' and 'Class' typedefs. */
- objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE,
objc_class_id));
- temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
- objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
- objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
temp_type));
+ type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
+ objc_object_name,
+ objc_object_type));
+ DECL_IN_SYSTEM_HEADER (type) = 1;
+ type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
+ objc_class_name,
+ objc_class_type));
+ DECL_IN_SYSTEM_HEADER (type) = 1;
+
+ /* Forward-declare '@interface Protocol'. */
+
+ type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
+ objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
+ objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
+ type));
/* Declare type of selector-objects that represent an operation
name. */
@@ -1185,38 +1397,36 @@ synth_module_prologue (void)
/* id objc_msgSendNonNil (id, SEL, ...); */
/* id objc_msgSend_stret (id, SEL, ...); */
/* id objc_msgSendNonNil_stret (id, SEL, ...); */
- temp_type
- = build_function_type (objc_id_type,
- tree_cons (NULL_TREE, objc_id_type,
- tree_cons (NULL_TREE,
- objc_selector_type,
+ type
+ = build_function_type (objc_object_type,
+ tree_cons (NULL_TREE, objc_object_type,
+ tree_cons (NULL_TREE,
objc_selector_type,
NULL_TREE)));
umsg_decl = builtin_function (TAG_MSGSEND,
- temp_type, 0, NOT_BUILT_IN,
+ type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
- temp_type, 0, NOT_BUILT_IN,
+ type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
- temp_type, 0, NOT_BUILT_IN,
+ type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
umsg_nonnil_stret_decl = builtin_function
(TAG_MSGSEND_NONNIL_STRET,
- temp_type, 0,
NOT_BUILT_IN,
+ type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
/* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
/* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
- temp_type
- = build_function_type (objc_id_type,
+ type
+ = build_function_type (objc_object_type,
tree_cons (NULL_TREE, objc_super_type,
- tree_cons (NULL_TREE,
- objc_selector_type,
+ tree_cons (NULL_TREE,
objc_selector_type,
NULL_TREE)));
umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
- temp_type, 0, NOT_BUILT_IN,
+ type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
- temp_type, 0,
NOT_BUILT_IN, 0,
+ type, 0, NOT_BUILT_IN,
0,
NULL_TREE);
}
else
@@ -1226,86 +1436,73 @@ synth_module_prologue (void)
/* typedef id (*IMP)(id, SEL, ...); */
tree IMP_type
= build_pointer_type
- (build_function_type (objc_id_type,
- tree_cons (NULL_TREE, objc_id_type,
- tree_cons (NULL_TREE,
-
objc_selector_type,
+ (build_function_type (objc_object_type,
+ tree_cons (NULL_TREE, objc_object_type,
+ tree_cons (NULL_TREE,
objc_selector_type,
NULL_TREE))));
/* IMP objc_msg_lookup (id, SEL); */
- temp_type
+ type
= build_function_type (IMP_type,
- tree_cons (NULL_TREE, objc_id_type,
- tree_cons (NULL_TREE,
- objc_selector_type,
- void_list_node)));
+ tree_cons (NULL_TREE, objc_object_type,
+ tree_cons (NULL_TREE,
objc_selector_type,
+
OBJC_VOID_AT_END)));
umsg_decl = builtin_function (TAG_MSGSEND,
- temp_type, 0, NOT_BUILT_IN,
+ type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
/* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
- temp_type
+ type
= build_function_type (IMP_type,
- tree_cons (NULL_TREE, objc_super_type,
- tree_cons (NULL_TREE,
- objc_selector_type,
- void_list_node)));
+ tree_cons (NULL_TREE, objc_super_type,
+ tree_cons (NULL_TREE,
objc_selector_type,
+
OBJC_VOID_AT_END)));
umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
- temp_type, 0, NOT_BUILT_IN,
+ type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
+
+ /* The following GNU runtime entry point is called to initialize
+ each module:
+
+ __objc_exec_class (void *); */
+ type
+ = build_function_type (void_type_node,
+ tree_cons (NULL_TREE, ptr_type_node,
+ OBJC_VOID_AT_END));
+ execclass_decl = builtin_function (TAG_EXECCLASS,
+ type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
}
/* id objc_getClass (const char *); */
- temp_type = build_function_type (objc_id_type,
+ type = build_function_type (objc_object_type,
tree_cons (NULL_TREE,
const_string_type_node,
- void_list_node));
+ OBJC_VOID_AT_END));
objc_get_class_decl
- = builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
+ = builtin_function (TAG_GETCLASS, 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,
NULL, NULL_TREE);
+ = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL,
NULL_TREE);
+ build_class_template ();
build_super_template ();
+ build_protocol_template ();
+ build_category_template ();
build_objc_exception_stuff ();
+
if (flag_next_runtime)
build_next_objc_exception_stuff ();
/* 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;
- const struct gcc_debug_hooks *const save_hooks = debug_hooks;
- write_symbols = NO_DEBUG;
- debug_hooks = &do_nothing_debug_hooks;
-
- build_selector_template ();
- temp_type = build_array_type (objc_selector_template,
NULL_TREE);
-
- write_symbols = save_write_symbols;
- debug_hooks = save_hooks;
- }
- else
- temp_type = build_array_type (objc_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;
- }
+ build_selector_table_decl ();
/* Forward declare constant_string_id and constant_string_type. */
if (!constant_string_class_name)
@@ -1320,7 +1517,14 @@ synth_module_prologue (void)
#ifndef OBJCPLUS
/* The C++ front-end does not appear to grok
__attribute__((__unused__)). */
unused_list = build_tree_list (get_identifier ("__unused__"),
NULL_TREE);
-#endif
+#endif
+
+#ifdef OBJCPLUS
+ pop_lang_context ();
+#endif
+
+ write_symbols = save_write_symbols;
+ debug_hooks = save_hooks;
}
/* Ensure that the ivar list for NSConstantString/NXConstantString
@@ -1369,6 +1573,33 @@ my_build_string (int len, const char *st
return fix_string_type (build_string (len, str));
}
+
+static hashval_t
+string_hash (const void *ptr)
+{
+ tree str = ((struct string_descriptor *)ptr)->literal;
+ const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER
(str);
+ int i, len = TREE_STRING_LENGTH (str);
+ hashval_t h = len;
+
+ for (i = 0; i < len; i++)
+ h = ((h * 613) + p[i]);
+
+ return h;
+}
+
+static int
+string_eq (const void *ptr1, const void *ptr2)
+{
+ tree str1 = ((struct string_descriptor *)ptr1)->literal;
+ tree str2 = ((struct string_descriptor *)ptr2)->literal;
+ int len1 = TREE_STRING_LENGTH (str1);
+
+ return (len1 == TREE_STRING_LENGTH (str2)
+ && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER
(str2),
+ len1));
+}
+
/* Given a chain of STRING_CST's, build a static instance of
NXConstantString which points at the concatenation of those
strings. We place the string object in the __string_objects
@@ -1377,13 +1608,29 @@ my_build_string (int len, const char *st
NXConstantString class object. */
tree
-build_objc_string_object (tree string)
+objc_build_string_object (tree string)
{
tree initlist, constructor, constant_string_class;
int length;
tree fields;
+ struct string_descriptor *desc, key;
+ void **loc;
string = fix_string_type (string);
+ TREE_SET_CODE (string, STRING_CST);
+ length = TREE_STRING_LENGTH (string) - 1;
+
+ /* Perhaps we already constructed a constant string just like this
one? */
+ key.literal = string;
+ loc = htab_find_slot (string_htab, &key, INSERT);
+ desc = *loc;
+
+ if (desc)
+ return desc->constructor;
+
+ *loc = desc = ggc_alloc (sizeof (*desc));
+ desc->literal = string;
+ desc->constructor = error_mark_node; /* For now. */
constant_string_class = lookup_interface (constant_string_id);
if (!constant_string_class
@@ -1395,37 +1642,35 @@ build_objc_string_object (tree string)
return error_mark_node;
}
- /* Call to 'combine_strings' has been moved above. */
- TREE_SET_CODE (string, STRING_CST);
- length = TREE_STRING_LENGTH (string) - 1;
-
if (!string_layout_checked)
{
- /* The NSConstantString/NXConstantString ivar layout is now
- known. */
+ /* The NSConstantString/NXConstantString ivar layout is now
known. */
if (!check_string_class_template ())
{
error ("interface `%s' does not have valid constant string
layout",
IDENTIFIER_POINTER (constant_string_id));
return error_mark_node;
}
+
add_class_reference (constant_string_id);
}
+
fields = TYPE_FIELDS (constant_string_type);
/* & ((NXConstantString) { NULL, string, length }) */
-
if (flag_next_runtime)
{
/* For the NeXT runtime, we can generate a literal reference
to the string class, don't need to run a constructor. */
setup_string_decl ();
+
if (string_class_decl == NULL_TREE)
{
error ("cannot find reference tag for class `%s'",
IDENTIFIER_POINTER (constant_string_id));
return error_mark_node;
}
+
initlist = build_tree_list
(fields,
copy_node (build_unary_op (ADDR_EXPR, string_class_decl, 0)));
@@ -1446,6 +1691,7 @@ build_objc_string_object (tree string)
initlist = tree_cons (fields, build_int_cst (NULL_TREE, length, 0),
initlist);
constructor = objc_build_constructor (constant_string_type,
nreverse (initlist));
+ TREE_INVARIANT (constructor) = true;
if (!flag_next_runtime)
{
@@ -1455,7 +1701,10 @@ build_objc_string_object (tree string)
constructor = build_unary_op (ADDR_EXPR, constructor, 1);
TREE_CONSTANT (constructor) = true;
- return constructor;
+ TREE_INVARIANT (constructor) = true;
+ TREE_STATIC (constructor) = true;
+
+ return (desc->constructor = constructor);
}
/* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR.
*/
@@ -1504,36 +1753,20 @@ objc_add_static_instance (tree construct
static tree
objc_build_constructor (tree type, tree elts)
{
- tree constructor, f, e;
-
- /* ??? Most of the places that we build constructors, we don't fill
in
- the type of integers properly. Convert them all en masse. */
- if (TREE_CODE (type) == ARRAY_TYPE)
- {
- f = TREE_TYPE (type);
- if (TREE_CODE (f) == POINTER_TYPE || TREE_CODE (f) ==
INTEGER_TYPE)
- for (e = elts; e ; e = TREE_CHAIN (e))
- TREE_VALUE (e) = convert (f, TREE_VALUE (e));
- }
- else
- {
- f = TYPE_FIELDS (type);
- 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));
- }
+ tree constructor = build_constructor (type, elts);
- constructor = build_constructor (type, elts);
TREE_CONSTANT (constructor) = 1;
TREE_STATIC (constructor) = 1;
TREE_READONLY (constructor) = 1;
#ifdef OBJCPLUS
- /* zlaski 2001-Apr-02: mark this as a call to a constructor, as
required by
- build_unary_op (wasn't true in 2.7.2.1 days) */
+ /* Adjust for impedance mismatch. We should figure out how to build
+ CONSTRUCTORs that consistently please both the C and C++ gods. */
+ if (!TREE_PURPOSE (elts))
+ TREE_TYPE (constructor) = NULL_TREE;
TREE_HAS_CONSTRUCTOR (constructor) = 1;
#endif
+
return constructor;
}
@@ -1559,31 +1792,21 @@ build_objc_symtab_template (void)
= 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 = create_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
(objc_selector_type),
- "refs");
+ field_decl = create_field_decl (build_pointer_type
(objc_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");
+ field_decl = create_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");
+ field_decl = create_field_decl (short_integer_type_node,
+ "cat_def_cnt");
chainon (field_decl_chain, field_decl);
if (imp_count || cat_count || !flag_next_runtime)
@@ -1592,9 +1815,8 @@ build_objc_symtab_template (void)
/* NB: The index is one less than the size of the array. */
int index = imp_count + cat_count
+ (flag_next_runtime? -1: 0);
- field_decl = create_builtin_decl
- (FIELD_DECL,
- build_array_type
+ field_decl = create_field_decl
+ (build_array_type
(ptr_type_node,
build_index_type (build_int_cst (NULL_TREE, index,
0))),
"defs");
@@ -1665,10 +1887,12 @@ init_objc_symtab (tree type)
if (flag_next_runtime || ! sel_ref_chain)
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0),
initlist);
else
- initlist = tree_cons (NULL_TREE,
- build_unary_op (ADDR_EXPR,
- UOBJC_SELECTOR_TABLE_decl, 1),
- initlist);
+ initlist
+ = tree_cons (NULL_TREE,
+ convert (build_pointer_type (objc_selector_type),
+ build_unary_op (ADDR_EXPR,
+ UOBJC_SELECTOR_TABLE_decl,
1)),
+ initlist);
/* cls_def_cnt = { ..., 5, ... } */
@@ -1699,17 +1923,13 @@ init_objc_symtab (tree type)
static tree
build_metadata_decl (const char *name, tree type)
{
- tree decl, decl_specs;
- /* extern struct TYPE NAME_<name>; */
- decl_specs = build_tree_list (NULL_TREE, ridpointers[(int)
RID_EXTERN]);
- decl_specs = tree_cons (NULL_TREE, type, decl_specs);
- decl = define_decl (synth_id_with_class_suffix
- (name,
- objc_implementation_context),
- decl_specs);
- TREE_USED (decl) = 1;
- DECL_ARTIFICIAL (decl) = 1;
- TREE_PUBLIC (decl) = 0;
+ tree decl;
+
+ /* struct TYPE NAME_<name>; */
+ decl = start_var_decl (type, synth_id_with_class_suffix
+ (name,
+ objc_implementation_context));
+
return decl;
}
@@ -1730,7 +1950,7 @@ forward_declare_categories (void)
objc_implementation_context = impent->imp_context;
/* extern struct objc_category _OBJC_CATEGORY_<name>; */
impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
-
objc_category_template);
+
objc_category_template);
}
}
objc_implementation_context = sav;
@@ -1742,32 +1962,14 @@ forward_declare_categories (void)
static void
generate_objc_symtab_decl (void)
{
- 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);
-
- 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);
+ build_objc_symtab_template ();
+ UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template,
"_OBJC_SYMBOLS");
+ finish_var_decl (UOBJC_SYMBOLS_decl,
+ init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
}
static tree
@@ -1780,7 +1982,7 @@ init_module_descriptor (tree type)
expr = build_int_cst (NULL_TREE, OBJC_VERSION, 0);
initlist = build_tree_list (NULL_TREE, expr);
- /* size = { ..., sizeof (struct objc_module), ... } */
+ /* size = { ..., sizeof (struct _objc_module), ... } */
expr = size_in_bytes (objc_module_template);
initlist = tree_cons (NULL_TREE, expr, initlist);
@@ -1802,132 +2004,124 @@ init_module_descriptor (tree type)
}
/* Write out the data structures to describe Objective C classes
defined.
- If appropriate, compile and output a setup function to initialize
them.
- Return a symbol_ref to the function to call to initialize the
Objective C
- data structures for this file (and perhaps for other files also).
- struct objc_module { ... } _OBJC_MODULE = { ... }; */
+ struct _objc_module { ... } _OBJC_MODULE = { ... }; */
-static rtx
+static void
build_module_descriptor (void)
{
- tree decl_specs, field_decl, field_decl_chain;
+ tree field_decl, field_decl_chain;
+
+#ifdef OBJCPLUS
+ push_lang_context (lang_name_c); /* extern "C" */
+#endif
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 (field_decl, decl_specs, NULL_TREE);
+ /* long version; */
+ field_decl = create_field_decl (long_integer_type_node, "version");
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 (field_decl, decl_specs, NULL_TREE);
+ /* long size; */
+ field_decl = create_field_decl (long_integer_type_node, "size");
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 (field_decl, decl_specs, NULL_TREE);
+ /* char *name; */
+ field_decl = create_field_decl (string_type_node, "name");
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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_symtab *symtab; */
+ field_decl
+ = create_field_decl (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_SYMTAB))),
+ "symtab");
chainon (field_decl_chain, field_decl);
finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
- /* Create an instance of "objc_module". */
+ /* Create an instance of "_objc_module". */
+ UOBJC_MODULES_decl = start_var_decl (objc_module_template,
"_OBJC_MODULES");
+ finish_var_decl (UOBJC_MODULES_decl,
+ init_module_descriptor (TREE_TYPE
(UOBJC_MODULES_decl)));
- 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);
-
- DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1;
- DECL_IGNORED_P (UOBJC_MODULES_decl) = 1;
- DECL_CONTEXT (UOBJC_MODULES_decl) = NULL_TREE;
-
- finish_decl (UOBJC_MODULES_decl,
- init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)),
- NULL_TREE);
+#ifdef OBJCPLUS
+ pop_lang_context ();
+#endif
+}
- /* Mark the decl to avoid "defined but not used" warning. */
- DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1;
-
- mark_decl_referenced (UOBJC_MODULES_decl);
+/* The GNU runtime requires us to provide a static initializer function
+ for each module:
- /* 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. */
+ static void __objc_gnu_init (void) {
+ __objc_exec_class (&L_OBJC_MODULES);
+ } */
- if (flag_next_runtime)
- return NULL_RTX;
+static void
+build_module_initializer_routine (void)
+{
+ tree body;
+
+#ifdef OBJCPLUS
+ push_lang_context (lang_name_c); /* extern "C" */
+#endif
+
+ objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
+ objc_start_function (get_identifier (TAG_GNUINIT),
+ build_function_type (void_type_node,
+ OBJC_VOID_AT_END),
+ NULL_TREE, objc_get_parm_info (0));
+
+ body = c_begin_compound_stmt (true);
+ add_stmt (build_function_call
+ (execclass_decl,
+ build_tree_list
+ (NULL_TREE,
+ build_unary_op (ADDR_EXPR,
+ UOBJC_MODULES_decl, 0))));
+ add_stmt (c_end_compound_stmt (body, true));
+
+ TREE_PUBLIC (current_function_decl) = 0;
+ DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
+ GNU_INIT_decl = current_function_decl;
+ finish_function ();
+
+#ifdef OBJCPLUS
+ pop_lang_context ();
+#endif
+}
- {
- tree parms, execclass_decl, decelerator, void_list_node_1;
- tree init_function_name, init_function_decl, compound;
-
- /* Declare void __objc_execClass (void *); */
-
- void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
- execclass_decl = build_decl (FUNCTION_DECL,
- get_identifier (TAG_EXECCLASS),
- build_function_type (void_type_node,
- tree_cons (NULL_TREE,
ptr_type_node,
- void_list_node)));
-
- DECL_EXTERNAL (execclass_decl) = 1;
- DECL_ARTIFICIAL (execclass_decl) = 1;
- TREE_PUBLIC (execclass_decl) = 1;
- pushdecl (execclass_decl);
- rest_of_decl_compilation (execclass_decl, 0, 0);
- assemble_external (execclass_decl);
-
- /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);}
*/
-
- init_function_name = get_file_function_name ('I');
- start_function (void_list_node_1,
- build_nt (CALL_EXPR, init_function_name,
- tree_cons (NULL_TREE, NULL_TREE,
- void_list_node),
- NULL_TREE),
- NULL_TREE);
- store_parm_decls ();
- compound = c_begin_compound_stmt (true);
-
- init_function_decl = current_function_decl;
- TREE_PUBLIC (init_function_decl) = ! targetm.have_ctors_dtors;
- TREE_USED (init_function_decl) = 1;
- /* Don't let this one be deferred. */
- DECL_INLINE (init_function_decl) = 0;
- DECL_UNINLINABLE (init_function_decl) = 1;
-
- parms
- = build_tree_list (NULL_TREE,
- build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl,
0));
- decelerator = build_function_call (execclass_decl, parms);
+/* Return 1 if the __objc_gnu_init function has been synthesized and
needs
+ to be called by the module initializer routine. */
- add_stmt (decelerator);
- add_stmt (c_end_compound_stmt (compound, true));
+int
+objc_static_init_needed_p (void)
+{
+ return (GNU_INIT_decl != NULL_TREE);
+}
- finish_function ();
+/* Generate a call to the __objc_gnu_init initializer function. The
routine
+ below gets called from within the bowels of C or C++, with a list of
+ initializer functions, from which we must remove __objc_gnu_init.
*/
- return XEXP (DECL_RTL (init_function_decl), 0);
- }
+tree
+objc_generate_static_init_call (tree ctors)
+{
+ tree *ctor_ptr = &ctors;
+
+ add_stmt (build_stmt (EXPR_STMT,
+ build_function_call (GNU_INIT_decl,
NULL_TREE)));
+
+ while (*ctor_ptr)
+ {
+ if (TREE_VALUE (*ctor_ptr) == GNU_INIT_decl)
+ *ctor_ptr = TREE_CHAIN (*ctor_ptr);
+ else
+ ctor_ptr = &TREE_CHAIN (*ctor_ptr);
+ }
+
+ return ctors;
}
/* Return the DECL of the string IDENT in the SECTION. */
@@ -1960,9 +2154,10 @@ get_objc_string_decl (tree ident, enum s
static void
generate_static_references (void)
{
- tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr =
NULL_TREE;
+ tree decls = NULL_TREE, expr = NULL_TREE;
tree class_name, class, decl, initlist;
- tree cl_chain, in_chain;
+ tree cl_chain, in_chain, type
+ = build_array_type (build_pointer_type (void_type_node),
NULL_TREE);
int num_inst, num_class;
char buf[256];
@@ -1976,16 +2171,7 @@ generate_static_references (void)
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, NULL_TREE,
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);
- DECL_CONTEXT (decl) = 0;
- DECL_ARTIFICIAL (decl) = 1;
- TREE_USED (decl) = 1;
+ decl = start_var_decl (type, buf);
/* Output {class_name, ...}. */
class = TREE_VALUE (cl_chain);
@@ -2005,26 +2191,15 @@ generate_static_references (void)
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0,
0), initlist);
expr = objc_build_constructor (TREE_TYPE (decl), nreverse
(initlist));
- finish_decl (decl, expr, NULL_TREE);
+ finish_var_decl (decl, expr);
decls
= tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1),
decls);
}
decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0),
decls);
- ident = get_identifier ("_OBJC_STATIC_INSTANCES");
- expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE,
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);
- TREE_USED (static_instances_decl) = 1;
- DECL_CONTEXT (static_instances_decl) = 0;
- DECL_ARTIFICIAL (static_instances_decl) = 1;
- expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
- nreverse (decls));
- finish_decl (static_instances_decl, expr, NULL_TREE);
- rest_of_decl_compilation (static_instances_decl, 0, 0);
+ expr = objc_build_constructor (type, nreverse (decls));
+ static_instances_decl = start_var_decl (type,
"_OBJC_STATIC_INSTANCES");
+ finish_var_decl (static_instances_decl, expr);
}
/* Output all strings. */
@@ -2032,56 +2207,46 @@ generate_static_references (void)
static void
generate_strings (void)
{
- tree sc_spec, decl_specs, expr_decl;
tree chain, string_expr;
- tree string, decl;
+ tree string, decl, type;
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,
- NULL_TREE, NULL_TREE);
- decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
- DECL_CONTEXT (decl) = NULL_TREE;
+ type = build_array_type
+ (char_type_node,
+ build_index_type (build_int_2 (IDENTIFIER_LENGTH
(string), 0)));
+ decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME
(decl)));
string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
IDENTIFIER_POINTER (string));
- finish_decl (decl, string_expr, NULL_TREE);
+ finish_var_decl (decl, string_expr);
}
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,
- NULL_TREE, NULL_TREE);
- decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
- DECL_CONTEXT (decl) = NULL_TREE;
+ type = build_array_type
+ (char_type_node,
+ build_index_type (build_int_2 (IDENTIFIER_LENGTH
(string), 0)));
+ decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME
(decl)));
string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
IDENTIFIER_POINTER (string));
- finish_decl (decl, string_expr, NULL_TREE);
+ finish_var_decl (decl, string_expr);
}
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,
- NULL_TREE, NULL_TREE);
- decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
- DECL_CONTEXT (decl) = NULL_TREE;
+ type = build_array_type
+ (char_type_node,
+ build_index_type (build_int_2 (IDENTIFIER_LENGTH
(string), 0)));
+ decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME
(decl)));
string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
- IDENTIFIER_POINTER (string));
- finish_decl (decl, string_expr, NULL_TREE);
+ IDENTIFIER_POINTER (string));
+ finish_var_decl (decl, string_expr);
}
}
@@ -2090,24 +2255,29 @@ static GTY(()) int selector_reference_id
static tree
build_selector_reference_decl (void)
{
- tree decl, ident;
+ tree decl;
char buf[256];
sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d",
selector_reference_idx++);
+ decl = start_var_decl (objc_selector_type, buf);
- ident = get_identifier (buf);
+ return decl;
+}
- decl = build_decl (VAR_DECL, ident, objc_selector_type);
- DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 0;
- TREE_USED (decl) = 1;
- DECL_ARTIFICIAL (decl) = 1;
- DECL_CONTEXT (decl) = 0;
+static void
+build_selector_table_decl (void)
+{
+ tree temp;
- make_decl_rtl (decl);
- pushdecl_top_level (decl);
+ if (flag_typed_selectors)
+ {
+ build_selector_template ();
+ temp = build_array_type (objc_selector_template, NULL_TREE);
+ }
+ else
+ temp = build_array_type (objc_selector_type, NULL_TREE);
- return decl;
+ UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp,
"_OBJC_SELECTOR_TABLE");
}
/* Just a handy wrapper for add_objc_string. */
@@ -2115,20 +2285,16 @@ build_selector_reference_decl (void)
static tree
build_selector (tree ident)
{
- tree expr = add_objc_string (ident, meth_var_names);
- if (flag_typed_selectors)
- return expr;
- else
- return build_c_cast (objc_selector_type, expr); /* cast! */
+ return convert (objc_selector_type,
+ add_objc_string (ident, meth_var_names));
}
static void
build_selector_translation_table (void)
{
- tree sc_spec, decl_specs;
tree chain, initlist = NULL_TREE;
int offset = 0;
- tree decl = NULL_TREE, var_decl, name;
+ tree decl = NULL_TREE;
for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
{
@@ -2161,28 +2327,14 @@ build_selector_translation_table (void)
}
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, objc_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 );
- }
-
/* add one for the '\0' character */
offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
if (flag_next_runtime)
- finish_decl (decl, expr, NULL_TREE);
+ {
+ decl = TREE_PURPOSE (chain);
+ finish_var_decl (decl, expr);
+ }
else
{
if (flag_typed_selectors)
@@ -2194,13 +2346,25 @@ build_selector_translation_table (void)
expr = objc_build_constructor (objc_selector_template,
nreverse (eltlist));
}
- initlist = tree_cons (NULL_TREE, expr, initlist);
+ initlist = tree_cons (NULL_TREE, expr, initlist);
}
}
if (! flag_next_runtime)
{
+ /* Cause the selector table (previously forward-declared)
+ to be actually output. */
+ initlist = tree_cons (NULL_TREE,
+ flag_typed_selectors
+ ? objc_build_constructor
+ (objc_selector_template,
+ tree_cons (NULL_TREE,
+ build_int_cst (NULL_TREE, 0,
0),
+ tree_cons (NULL_TREE,
+ build_int_cst
(NULL_TREE, 0, 0),
+ NULL_TREE)))
+ : build_int_cst (NULL_TREE, 0, 0),
initlist);
/* 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;
@@ -2209,8 +2373,7 @@ build_selector_translation_table (void)
DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
initlist = objc_build_constructor (TREE_TYPE
(UOBJC_SELECTOR_TABLE_decl),
nreverse (initlist));
- finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
- current_function_decl = NULL_TREE;
+ finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
}
}
@@ -2260,7 +2423,7 @@ build_typed_selector_reference (tree ide
build_array_ref (UOBJC_SELECTOR_TABLE_decl,
build_int_cst (NULL_TREE,
index, 0)),
1);
- return build_c_cast (objc_selector_type, expr);
+ return convert (objc_selector_type, expr);
}
static tree
@@ -2282,7 +2445,7 @@ build_selector_reference (tree ident)
chain = &TREE_CHAIN (*chain);
}
- expr = build_selector_reference_decl ();
+ expr = (flag_next_runtime ? build_selector_reference_decl ():
NULL_TREE);
*chain = tree_cons (expr, ident, NULL_TREE);
@@ -2297,22 +2460,11 @@ static GTY(()) int class_reference_idx;
static tree
build_class_reference_decl (void)
{
- tree decl, ident;
+ tree decl;
char buf[256];
sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
-
- ident = get_identifier (buf);
-
- decl = build_decl (VAR_DECL, ident, objc_class_type);
- DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 0;
- TREE_USED (decl) = 1;
- DECL_CONTEXT (decl) = 0;
- DECL_ARTIFICIAL (decl) = 1;
-
- make_decl_rtl (decl);
- pushdecl_top_level (decl);
+ decl = start_var_decl (objc_class_type, buf);
return decl;
}
@@ -2349,7 +2501,7 @@ add_class_reference (tree ident)
reference variable. */
tree
-get_class_reference (tree ident)
+objc_get_class_reference (tree ident)
{
tree orig_ident;
@@ -2362,7 +2514,7 @@ get_class_reference (tree ident)
#endif
orig_ident = ident;
- if (!(ident = is_class_name (ident)))
+ if (!(ident = objc_is_class_name (ident)))
{
error ("`%s' is not an Objective-C class name or alias",
IDENTIFIER_POINTER (orig_ident));
@@ -2422,7 +2574,8 @@ add_objc_string (tree ident, enum string
while (*chain)
{
if (TREE_VALUE (*chain) == ident)
- return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1);
+ return convert (string_type_node,
+ build_unary_op (ADDR_EXPR, TREE_PURPOSE
(*chain), 1));
chain = &TREE_CHAIN (*chain);
}
@@ -2431,7 +2584,7 @@ add_objc_string (tree ident, enum string
*chain = tree_cons (decl, ident, NULL_TREE);
- return build_unary_op (ADDR_EXPR, decl, 1);
+ return convert (string_type_node, build_unary_op (ADDR_EXPR, decl,
1));
}
static GTY(()) int class_names_idx;
@@ -2460,6 +2613,9 @@ build_objc_string_decl (enum string_sect
TREE_CONSTANT (decl) = 1;
DECL_CONTEXT (decl) = 0;
DECL_ARTIFICIAL (decl) = 1;
+#ifdef OBJCPLUS
+ DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
+#endif
make_decl_rtl (decl);
pushdecl_top_level (decl);
@@ -2479,9 +2635,9 @@ objc_declare_alias (tree alias_ident, tr
}
#endif /* OBJCPLUS */
- if (!(underlying_class = is_class_name (class_ident)))
+ if (!(underlying_class = objc_is_class_name (class_ident)))
warning ("cannot find class `%s'", IDENTIFIER_POINTER
(class_ident));
- else if (is_class_name (alias_ident))
+ else if (objc_is_class_name (alias_ident))
warning ("class `%s' already exists", IDENTIFIER_POINTER
(alias_ident));
else
alias_chain = tree_cons (underlying_class, alias_ident,
alias_chain);
@@ -2501,7 +2657,7 @@ objc_declare_class (tree ident_list)
{
tree ident = TREE_VALUE (list);
- if (! is_class_name (ident))
+ if (! objc_is_class_name (ident))
{
tree record = lookup_name (ident);
@@ -2521,7 +2677,7 @@ objc_declare_class (tree ident_list)
}
tree
-is_class_name (tree ident)
+objc_is_class_name (tree ident)
{
tree chain;
@@ -2529,11 +2685,11 @@ is_class_name (tree ident)
&& identifier_global_value (ident))
ident = identifier_global_value (ident);
while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE
(ident))
- ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
+ ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
#ifdef OBJCPLUS
if (ident && TREE_CODE (ident) == RECORD_TYPE)
- ident = TYPE_NAME (ident);
+ ident = OBJC_TYPE_NAME (ident);
if (ident && TREE_CODE (ident) == TYPE_DECL)
ident = DECL_NAME (ident);
#endif
@@ -2558,6 +2714,25 @@ is_class_name (tree ident)
return 0;
}
+/* Check whether TYPE is either 'id' or 'Class'. */
+
+tree
+objc_is_id (tree type)
+{
+ if (type && TREE_CODE (type) == IDENTIFIER_NODE
+ && identifier_global_value (type))
+ type = identifier_global_value (type);
+
+ if (type && TREE_CODE (type) == TYPE_DECL)
+ type = TREE_TYPE (type);
+
+ /* NB: This function may be called before the ObjC front-end has
+ been initialized, in which case OBJC_OBJECT_TYPE will (still) be
NULL. */
+ return (objc_object_type && type && (IS_ID (type) || IS_CLASS (type))
+ ? type
+ : NULL_TREE);
+}
+
/* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
class instance. This is needed by other parts of the compiler to
handle ObjC types gracefully. */
@@ -2565,19 +2740,20 @@ is_class_name (tree ident)
tree
objc_is_object_ptr (tree type)
{
+ tree ret;
+
type = TYPE_MAIN_VARIANT (type);
- if (!type || TREE_CODE (type) != POINTER_TYPE)
+ if (!POINTER_TYPE_P (type))
return 0;
- /* NB: This function may be called before the ObjC front-end has
- been initialized, in which case OBJC_ID_TYPE will be NULL. */
- if (objc_id_type && type && TYPE_P (type)
- && (IS_ID (type)
- || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
- return type;
- return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
+
+ ret = objc_is_id (type);
+ if (!ret)
+ ret = objc_is_class_name (TREE_TYPE (type));
+
+ return ret;
}
-tree
+static tree
lookup_interface (tree ident)
{
tree chain;
@@ -2597,88 +2773,40 @@ lookup_interface (tree ident)
/* Implement @defs (<classname>) within struct bodies. */
tree
-get_class_ivars_from_name (tree class_name)
+objc_get_class_ivars (tree class_name)
{
tree interface = lookup_interface (class_name);
- tree field, fields = NULL_TREE;
if (interface)
- {
- tree raw_ivar = get_class_ivars (interface, 1);
+ return get_class_ivars (interface);
- /* Regenerate the FIELD_DECLs for the enclosing struct. */
- for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
- {
- field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
- TREE_PURPOSE (raw_ivar),
- TREE_VALUE (TREE_VALUE (raw_ivar)));
-#ifdef OBJCPLUS
- finish_member_declaration (field);
-#else
- fields = chainon (fields, field);
-#endif
- }
- }
- else
- error ("cannot find interface declaration for `%s'",
- IDENTIFIER_POINTER (class_name));
+ error ("cannot find interface declaration for `%s'",
+ IDENTIFIER_POINTER (class_name));
- return fields;
+ return error_mark_node;
}
/* Used by: build_private_template, continue_class,
and for @defs constructs. */
static tree
-get_class_ivars (tree interface, int raw)
+get_class_ivars (tree interface)
{
- tree my_name, super_name, ivar_chain;
-
- my_name = CLASS_NAME (interface);
- super_name = CLASS_SUPER_NAME (interface);
- if (raw)
- ivar_chain = CLASS_RAW_IVARS (interface);
- 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)
- {
- 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_error ("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);
+ tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
- op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS
(interface));
- if (op1)
- {
- tree head = copy_list (op1);
-
- /* Prepend super class ivars...make a copy of the list, we
- do not want to alter the original. */
- chainon (head, ivar_chain);
- ivar_chain = head;
- }
+ /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars
declared
+ by the current class (i.e., they do not include super-class
ivars).
+ However, the CLASS_IVARS list will be side-effected by a call to
+ finish_struct(), which will fill in field offsets. */
+ if (!CLASS_IVARS (interface))
+ CLASS_IVARS (interface) = ivar_chain;
+
+ while (CLASS_SUPER_NAME (interface))
+ {
+ /* Prepend super-class ivars. */
+ interface = lookup_interface (CLASS_SUPER_NAME (interface));
+ ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
+ ivar_chain);
}
return ivar_chain;
@@ -2739,11 +2867,13 @@ static struct objc_try_context *cur_try_
that represents TYPE. For Objective-C, this is just the class
name. */
/* ??? Isn't there a class object or some such? Is it easy to get? */
+#ifndef OBJCPLUS
static tree
objc_eh_runtime_type (tree type)
{
return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)),
class_names);
}
+#endif
/* Initialize exception handling. */
@@ -2755,12 +2885,16 @@ objc_init_exceptions (void)
return;
done = true;
- /* Why? */
- if (!flag_objc_exceptions)
- warning ("use %<-fobjc-exceptions%> to enable Objective-C "
- "exception syntax");
-
- if (!flag_objc_sjlj_exceptions)
+ if (flag_objc_sjlj_exceptions)
+ {
+ /* On Darwin, ObjC exceptions require a sufficiently recent
+ version of the runtime, so the user must ask for them
explicitly. */
+ if (!flag_objc_exceptions)
+ warning ("use %<-fobjc-exceptions%> to enable Objective-C "
+ "exception syntax");
+ }
+#ifndef OBJCPLUS
+ else
{
c_eh_initialized_p = true;
eh_personality_libfunc
@@ -2770,6 +2904,7 @@ objc_init_exceptions (void)
using_eh_for_cleanups ();
lang_eh_runtime_type = objc_eh_runtime_type;
}
+#endif
}
/* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of
Darwin,
@@ -2784,13 +2919,13 @@ objc_build_exc_ptr (void)
tree var = cur_try_context->caught_decl;
if (!var)
{
- var = objc_create_temporary_var (objc_id_type);
+ var = objc_create_temporary_var (objc_object_type);
cur_try_context->caught_decl = var;
}
return var;
}
else
- return build (EXC_PTR_EXPR, objc_id_type);
+ return build (EXC_PTR_EXPR, objc_object_type);
}
/* Build "objc_exception_try_exit(&_stack)". */
@@ -2895,7 +3030,7 @@ next_sjlj_build_catch_list (void)
else
{
args = tree_cons (NULL, cur_try_context->caught_decl,
NULL);
- t = get_class_reference (OBJC_TYPE_NAME (TREE_TYPE
(type)));
+ t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE
(type)));
args = tree_cons (NULL, t, args);
t = build_function_call (objc_exception_match_decl, args);
cond = lang_hooks.truthvalue_conversion (t);
@@ -2970,7 +3105,7 @@ next_sjlj_build_try_catch_finally (void)
stack_decl = objc_create_temporary_var (t);
cur_try_context->stack_decl = stack_decl;
- rethrow_decl = objc_create_temporary_var (objc_id_type);
+ rethrow_decl = objc_create_temporary_var (objc_object_type);
cur_try_context->rethrow_decl = rethrow_decl;
TREE_THIS_VOLATILE (rethrow_decl) = 1;
TREE_CHAIN (rethrow_decl) = stack_decl;
@@ -2982,7 +3117,7 @@ next_sjlj_build_try_catch_finally (void)
/* Initialize rethrow_decl. */
t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
- convert (objc_id_type, null_pointer_node));
+ convert (objc_object_type, null_pointer_node));
annotate_with_locus (t, cur_try_context->try_locus);
append_to_statement_list (t, &BIND_EXPR_BODY (bind));
@@ -3056,20 +3191,20 @@ objc_begin_try_stmt (location_t try_locu
}
/* Called just after parsing "@catch (parm)". Open a binding level,
- enter PARM into the binding level, and initialize it. Leave the
+ enter DECL into the binding level, and initialize it. Leave the
binding level open while the body of the compound statement is
parsed. */
void
-objc_begin_catch_clause (tree parm)
+objc_begin_catch_clause (tree decl)
{
- tree compound, decl, type, t;
+ tree compound, type, t;
/* Begin a new scope that the entire catch clause will live in. */
- compound = c_begin_compound_stmt (1);
+ compound = c_begin_compound_stmt (true);
- /* Turn the raw declarator/declspecs into a decl in the current
scope. */
- decl = define_decl (TREE_VALUE (TREE_PURPOSE (parm)),
- TREE_PURPOSE (TREE_PURPOSE (parm)));
+ /* The parser passed in a PARM_DECL, but what we really want is a
VAR_DECL. */
+ decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
+ lang_hooks.decls.pushdecl (decl);
/* Since a decl is required here by syntax, don't warn if its
unused. */
/* ??? As opposed to __attribute__((unused))? Anyway, this appears
to
@@ -3102,7 +3237,7 @@ objc_begin_catch_clause (tree parm)
warning ("exception of type %<%T%> will be caught",
TREE_TYPE (type));
warning ("%H by earlier handler for %<%T%>",
- EXPR_LOCUS (stmt), TREE_TYPE (t ? t :
objc_id_type));
+ EXPR_LOCUS (stmt), TREE_TYPE (t ? t :
objc_object_type));
break;
}
}
@@ -3264,31 +3399,21 @@ build_next_objc_exception_stuff (void)
{
tree field_decl, field_decl_chain, index, temp_type;
- /* Suppress outputting debug symbols, because
- dbxout_init hasn't been called yet. */
- enum debug_info_type save_write_symbols = write_symbols;
- const struct gcc_debug_hooks *save_hooks = debug_hooks;
-
- write_symbols = NO_DEBUG;
- debug_hooks = &do_nothing_debug_hooks;
-
objc_exception_data_template
= start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
/* int buf[_JBLEN]; */
index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1, 0));
- field_decl = create_builtin_decl (FIELD_DECL,
- build_array_type
(integer_type_node, index),
- "buf");
+ field_decl = create_field_decl (build_array_type (integer_type_node,
index),
+ "buf");
field_decl_chain = field_decl;
/* void *pointers[4]; */
index = build_index_type (build_int_cst (NULL_TREE, 4 - 1, 0));
- field_decl = create_builtin_decl (FIELD_DECL,
- build_array_type (ptr_type_node,
index),
- "pointers");
+ field_decl = create_field_decl (build_array_type (ptr_type_node,
index),
+ "pointers");
chainon (field_decl_chain, field_decl);
finish_struct (objc_exception_data_template, field_decl_chain,
NULL_TREE);
@@ -3302,10 +3427,10 @@ build_next_objc_exception_stuff (void)
/* id objc_exception_extract(struct _objc_exception_data *); */
temp_type
- = build_function_type (objc_id_type,
+ = build_function_type (objc_object_type,
tree_cons (NULL_TREE,
build_pointer_type
(objc_exception_data_template),
- void_list_node));
+ OBJC_VOID_AT_END));
objc_exception_extract_decl
= builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0,
NOT_BUILT_IN, NULL, NULL_TREE);
/* void objc_exception_try_enter(struct _objc_exception_data *); */
@@ -3314,7 +3439,7 @@ build_next_objc_exception_stuff (void)
= build_function_type (void_type_node,
tree_cons (NULL_TREE,
build_pointer_type
(objc_exception_data_template),
- void_list_node));
+ OBJC_VOID_AT_END));
objc_exception_try_enter_decl
= builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0,
NOT_BUILT_IN, NULL, NULL_TREE);
objc_exception_try_exit_decl
@@ -3323,14 +3448,11 @@ build_next_objc_exception_stuff (void)
/* int objc_exception_match(id, id); */
temp_type
= build_function_type (integer_type_node,
- tree_cons (NULL_TREE, objc_id_type,
- tree_cons (NULL_TREE,
objc_id_type,
+ tree_cons (NULL_TREE, objc_object_type,
+ tree_cons (NULL_TREE,
objc_object_type,
void_list_node)));
objc_exception_match_decl
= builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0,
NOT_BUILT_IN, NULL, NULL_TREE);
-
- write_symbols = save_write_symbols;
- debug_hooks = save_hooks;
}
static void
@@ -3345,8 +3467,8 @@ build_objc_exception_stuff (void)
/* void objc_sync_enter(id); */
/* void objc_sync_exit(id); */
temp_type = build_function_type (void_type_node,
- tree_cons (NULL_TREE, objc_id_type,
- void_list_node));
+ tree_cons (NULL_TREE,
objc_object_type,
+ OBJC_VOID_AT_END));
objc_exception_throw_decl
= builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0,
NOT_BUILT_IN, NULL,
noreturn_list);
@@ -3360,7 +3482,7 @@ build_objc_exception_stuff (void)
/* struct <classname> {
- struct objc_class *isa;
+ struct _objc_class *isa;
...
}; */
@@ -3377,7 +3499,7 @@ build_private_template (tree class)
else
{
uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
- ivar_context = get_class_ivars (class, 0);
+ ivar_context = get_class_ivars (class);
finish_struct (uprivate_record, ivar_context, NULL_TREE);
@@ -3387,80 +3509,64 @@ build_private_template (tree class)
TREE_STATIC_TEMPLATE (uprivate_record) = 1;
}
- objc_instance_type
- = groktypename (build_tree_list (build_tree_list (NULL_TREE,
- uprivate_record),
- build1 (INDIRECT_REF, NULL_TREE,
- NULL_TREE)));
+ objc_instance_type = build_pointer_type (uprivate_record);
return ivar_context;
}
/* Begin code generation for protocols... */
-/* struct objc_protocol {
+/* struct _objc_protocol {
+ struct _objc_class *isa;
char *protocol_name;
- struct objc_protocol **protocol_list;
- struct objc_method_desc *instance_methods;
- struct objc_method_desc *class_methods;
+ struct _objc_protocol **protocol_list;
+ struct _objc__method_prototype_list *instance_methods;
+ struct _objc__method_prototype_list *class_methods;
}; */
-static tree
+static void
build_protocol_template (void)
{
- tree decl_specs, field_decl, field_decl_chain;
- tree template;
-
- template = start_struct (RECORD_TYPE, get_identifier
(UTAG_PROTOCOL));
+ tree field_decl, field_decl_chain;
- /* struct objc_class *isa; */
+ objc_protocol_template = start_struct (RECORD_TYPE,
+ get_identifier
(UTAG_PROTOCOL));
- 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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_class *isa; */
+ field_decl = create_field_decl (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier
(UTAG_CLASS))),
+ "isa");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (string_type_node, "protocol_name");
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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_protocol **protocol_list; */
+ field_decl = create_field_decl (build_pointer_type
+ (build_pointer_type
+ (objc_protocol_template)),
+ "protocol_list");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier
+
(UTAG_METHOD_PROTOTYPE_LIST))),
+ "instance_methods");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier
+
(UTAG_METHOD_PROTOTYPE_LIST))),
+ "class_methods");
chainon (field_decl_chain, field_decl);
- return finish_struct (template, field_decl_chain, NULL_TREE);
+ finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
}
static tree
@@ -3506,25 +3612,22 @@ static tree
build_method_prototype_list_template (tree list_type, int size)
{
tree objc_ivar_list_record;
- tree decl_specs, field_decl, field_decl_chain;
+ tree 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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (integer_type_node, "method_count");
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_cst (NULL_TREE, size, 0), NULL_TREE,
NULL_TREE);
- field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_array_type
+ (list_type,
+ build_index_type
+ (build_int_cst (NULL_TREE, size - 1,
0))),
+ "method_list");
chainon (field_decl_chain, field_decl);
finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
@@ -3536,22 +3639,17 @@ static tree
build_method_prototype_template (void)
{
tree proto_record;
- tree decl_specs, field_decl, field_decl_chain;
+ tree field_decl, field_decl_chain;
proto_record
= start_struct (RECORD_TYPE, get_identifier
(UTAG_METHOD_PROTOTYPE));
- /* 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"));
- field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+ /* SEL _cmd; */
+ field_decl = create_field_decl (objc_selector_type, "_cmd");
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 (field_decl, decl_specs, NULL_TREE);
+ /* char *method_types; */
+ field_decl = create_field_decl (string_type_node, "method_types");
chainon (field_decl_chain, field_decl);
finish_struct (proto_record, field_decl_chain, NULL_TREE);
@@ -3562,7 +3660,7 @@ build_method_prototype_template (void)
static tree
objc_method_parm_type (tree type)
{
- type = groktypename (TREE_TYPE (type));
+ type = TREE_VALUE (TREE_TYPE (type));
if (TREE_CODE (type) == TYPE_DECL)
type = TREE_TYPE (type);
return TYPE_MAIN_VARIANT (type);
@@ -3575,9 +3673,7 @@ objc_encoded_type_size (tree type)
/* Make all integer and enum types at least as large
as an int. */
- if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
- || TREE_CODE (type) == BOOLEAN_TYPE
- || TREE_CODE (type) == ENUMERAL_TYPE))
+ if (sz > 0 && INTEGRAL_TYPE_P (type))
sz = MAX (sz, int_size_in_bytes (integer_type_node));
/* Treat arrays as pointers, since that's how they're
passed in. */
@@ -3660,20 +3756,14 @@ static tree
generate_descriptor_table (tree type, const 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);
+ tree decl, initlist;
- decl = start_decl (synth_id_with_class_suffix (name, proto),
- decl_specs, 1, NULL_TREE);
- DECL_CONTEXT (decl) = NULL_TREE;
+ decl = start_var_decl (type, synth_id_with_class_suffix (name,
proto));
initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE,
size, 0));
initlist = tree_cons (NULL_TREE, list, initlist);
- finish_decl (decl, objc_build_constructor (type, nreverse
(initlist)),
- NULL_TREE);
+ finish_var_decl (decl, objc_build_constructor (type, nreverse
(initlist)));
return decl;
}
@@ -3682,17 +3772,14 @@ static void
generate_method_descriptors (tree protocol)
{
tree initlist, chain, method_list_template;
- tree cast, variable_length_type;
+ tree variable_length_type
+ = xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_METHOD_PROTOTYPE_LIST));
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)
{
@@ -3801,12 +3888,8 @@ static void
generate_protocols (void)
{
tree p, encoding;
- tree sc_spec, decl_specs, decl;
+ tree decl;
tree initlist, protocol_name_expr, refs_decl, refs_expr;
- tree cast_type2;
-
- 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))
@@ -3819,7 +3902,9 @@ generate_protocols (void)
tree cls_methods = PROTOCOL_CLS_METHODS (p);
/* If protocol wasn't referenced, don't generate any code. */
- if (! PROTOCOL_FORWARD_DECL (p))
+ decl = PROTOCOL_FORWARD_DECL (p);
+
+ if (!decl)
continue;
/* Make sure we link in the Protocol class. */
@@ -3853,31 +3938,12 @@ generate_protocols (void)
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);
-
- DECL_CONTEXT (decl) = NULL_TREE;
-
protocol_name_expr = add_objc_string (PROTOCOL_NAME (p),
class_names);
if (refs_decl)
- {
- 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;
- }
+ refs_expr = convert (build_pointer_type (build_pointer_type
+
(objc_protocol_template)),
+ build_unary_op (ADDR_EXPR, refs_decl, 0));
else
refs_expr = build_int_cst (NULL_TREE, 0, 0);
@@ -3887,10 +3953,7 @@ generate_protocols (void)
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;
+ finish_var_decl (decl, initlist);
}
}
@@ -3900,20 +3963,14 @@ build_protocol_initializer (tree type, t
tree class_methods)
{
tree initlist = NULL_TREE, expr;
- tree 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)));
+ tree cast_type = build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_CLASS)));
/* Filling the "isa" in with one allows the runtime system to
detect that the version change...should remove before final
release. */
- expr = build_int_cst (NULL_TREE, PROTOCOL_VERSION, 0);
- TREE_TYPE (expr) = cast_type;
+ expr = convert (cast_type, build_int_cst (NULL_TREE,
PROTOCOL_VERSION, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
initlist = tree_cons (NULL_TREE, protocol_name, initlist);
initlist = tree_cons (NULL_TREE, protocol_list, initlist);
@@ -3937,72 +3994,58 @@ build_protocol_initializer (tree type, t
return objc_build_constructor (type, nreverse (initlist));
}
-/* struct objc_category {
+/* 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;
+ struct _objc_method_list *instance_methods;
+ struct _objc_method_list *class_methods;
+ struct _objc_protocol_list *protocols;
}; */
static void
build_category_template (void)
{
- tree decl_specs, field_decl, field_decl_chain;
+ tree 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 (field_decl, decl_specs, NULL_TREE);
+ /* char *category_name; */
+ field_decl = create_field_decl (string_type_node, "category_name");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (string_type_node, "class_name");
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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_method_list *instance_methods; */
+ field_decl = create_field_decl (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier
+ (UTAG_METHOD_LIST))),
+ "instance_methods");
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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_method_list *class_methods; */
+ field_decl = create_field_decl (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier
+ (UTAG_METHOD_LIST))),
+ "class_methods");
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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_protocol **protocol_list; */
+ field_decl = create_field_decl (build_pointer_type
+ (build_pointer_type
+ (objc_protocol_template)),
+ "protocol_list");
chainon (field_decl_chain, field_decl);
finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
}
-/* struct objc_selector {
- void *sel_id;
+/* struct _objc_selector {
+ SEL sel_id;
char *sel_type;
}; */
@@ -4010,47 +4053,42 @@ static void
build_selector_template (void)
{
- tree decl_specs, field_decl, field_decl_chain;
+ tree 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 (field_decl, decl_specs, NULL_TREE);
+ /* SEL sel_id; */
+ field_decl = create_field_decl (objc_selector_type, "sel_id");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (string_type_node, "sel_type");
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;
+/* 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_ivar_list *ivars;
+ struct _objc_method_list *methods;
+ #ifdef __NEXT_RUNTIME__
struct objc_cache *cache;
- else {
+ #else
struct sarray *dtable;
- struct objc_class *subclass_list;
- struct objc_class *sibling_class;
- }
- struct objc_protocol_list *protocols;
- if (flag_next_runtime)
+ struct _objc_class *subclass_list;
+ struct _objc_class *sibling_class;
+ #endif
+ struct _objc_protocol_list *protocols;
+ #ifdef __NEXT_RUNTIME__
void *sel_id;
+ #endif
void *gc_object_type;
}; */
@@ -4062,139 +4100,106 @@ build_selector_template (void)
static void
build_class_template (void)
{
- tree decl_specs, field_decl, field_decl_chain;
+ tree 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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_class *isa; */
+ field_decl = create_field_decl (build_pointer_type
(objc_class_template),
+ "isa");
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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_class *super_class; */
+ field_decl = create_field_decl (build_pointer_type
(objc_class_template),
+ "super_class");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (string_type_node, "name");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (long_integer_type_node, "version");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (long_integer_type_node, "info");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (long_integer_type_node,
"instance_size");
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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_ivar_list *ivars; */
+ field_decl = create_field_decl (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier
+ (UTAG_IVAR_LIST))),
+ "ivars");
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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_method_list *methods; */
+ field_decl = create_field_decl (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier
+ (UTAG_METHOD_LIST))),
+ "methods");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier
+ ("objc_cache"))),
+ "cache");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier
+ ("sarray"))),
+ "dtable");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_pointer_type
+ (objc_class_template),
+ "subclass_list");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_pointer_type
+ (objc_class_template),
+ "sibling_class");
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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_protocol **protocol_list; */
+ field_decl = create_field_decl (build_pointer_type
+ (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier
+ (UTAG_PROTOCOL)))),
+ "protocol_list");
chainon (field_decl_chain, field_decl);
if (flag_next_runtime)
{
/* 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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_pointer_type
(void_type_node),
+ "sel_id");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_pointer_type (void_type_node),
+ "gc_object_type");
chainon (field_decl_chain, field_decl);
finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
@@ -4209,14 +4214,11 @@ synth_forward_declarations (void)
/* static struct objc_class _OBJC_CLASS_<my_name>; */
UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
- objc_class_template);
+ objc_class_template);
/* static struct objc_class _OBJC_METACLASS_<my_name>; */
UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
objc_class_template);
-
- mark_decl_referenced (UOBJC_CLASS_decl);
- mark_decl_referenced (UOBJC_METACLASS_decl);
/* Pre-build the following entities - for speed/convenience. */
@@ -4226,20 +4228,18 @@ synth_forward_declarations (void)
}
static void
-error_with_ivar (const char *message, tree decl, tree rawdecl)
+error_with_ivar (const char *message, tree decl)
{
error ("%J%s `%s'", decl,
- message, gen_declaration (rawdecl, errbuf));
+ message, gen_declaration (decl, errbuf));
}
static void
check_ivars (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);
+ tree intdecls = CLASS_RAW_IVARS (inter);
+ tree impdecls = CLASS_RAW_IVARS (imp);
while (1)
{
@@ -4259,26 +4259,16 @@ check_ivars (tree inter, tree imp)
t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
- if (TREE_VALUE (TREE_VALUE (rawimpdecls)))
- {
- /* t1 is the bit-field type, so t2 must be converted to the
- bit-field type for comparison as well. */
- unsigned HOST_WIDE_INT width
- = tree_low_cst (TREE_VALUE (TREE_VALUE (rawimpdecls)), 1);
- if (width != TYPE_PRECISION (t2))
- t2 = build_nonstandard_integer_type (width, TYPE_UNSIGNED
(t2));
- }
-
if (!comptypes (t1, t2)
- || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
- TREE_VALUE (TREE_VALUE
(rawimpdecls))))
+ || !tree_int_cst_equal (DECL_INITIAL (intdecls),
+ DECL_INITIAL (impdecls)))
{
if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
{
error_with_ivar ("conflicting instance variable type",
- impdecls, rawimpdecls);
+ impdecls);
error_with_ivar ("previous declaration of",
- intdecls, rawintdecls);
+ intdecls);
}
else /* both the type and the name don't
match */
{
@@ -4290,68 +4280,44 @@ check_ivars (tree inter, tree imp)
else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
{
error_with_ivar ("conflicting instance variable name",
- impdecls, rawimpdecls);
+ impdecls);
error_with_ivar ("previous declaration of",
- intdecls, rawintdecls);
+ intdecls);
}
intdecls = TREE_CHAIN (intdecls);
impdecls = TREE_CHAIN (impdecls);
- rawintdecls = TREE_CHAIN (rawintdecls);
- rawimpdecls = TREE_CHAIN (rawimpdecls);
}
}
/* Set 'objc_super_template' to the data type node for 'struct
_objc_super'.
This needs to be done just once per compilation. */
+/* struct _objc_super {
+ struct _objc_object *self;
+ struct _objc_class *super_class;
+ }; */
+
static void
build_super_template (void)
{
- tree decl_specs, field_decl, field_decl_chain;
-
- /* Suppress outputting debug symbols, because
- dbxout_init hasn't been called yet. */
- enum debug_info_type save_write_symbols = write_symbols;
- const struct gcc_debug_hooks *save_hooks = debug_hooks;
-
- write_symbols = NO_DEBUG;
- debug_hooks = &do_nothing_debug_hooks;
+ tree field_decl, field_decl_chain;
objc_super_template = 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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_object *self; */
+ field_decl = create_field_decl (objc_object_type, "self");
field_decl_chain = field_decl;
-#ifdef OBJCPLUS
- /* struct objc_class *super_class; */
-#else
- /* struct objc_class *class; */
-#endif
-
- decl_specs = get_identifier (UTAG_CLASS);
- decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
decl_specs));
-#ifdef OBJCPLUS
- field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier
("super_class"));
-#else
- field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier
("class"));
-#endif
-
- field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc_class *super_class; */
+ field_decl = create_field_decl (build_pointer_type
(objc_class_template),
+ "super_class");
chainon (field_decl_chain, field_decl);
finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
-
- write_symbols = save_write_symbols;
- debug_hooks = save_hooks;
}
-/* struct objc_ivar {
+/* struct _objc_ivar {
char *ivar_name;
char *ivar_type;
int ivar_offset;
@@ -4361,33 +4327,21 @@ static tree
build_ivar_template (void)
{
tree objc_ivar_id, objc_ivar_record;
- tree decl_specs, field_decl, field_decl_chain;
+ tree 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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (string_type_node, "ivar_name");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (string_type_node, "ivar_type");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (integer_type_node, "ivar_offset");
chainon (field_decl_chain, field_decl);
finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
@@ -4404,25 +4358,20 @@ static tree
build_ivar_list_template (tree list_type, int size)
{
tree objc_ivar_list_record;
- tree decl_specs, field_decl, field_decl_chain;
+ tree 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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (integer_type_node, "ivar_count");
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_cst (NULL_TREE, size, 0), NULL_TREE,
NULL_TREE);
-
- field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_array_type
+ (list_type,
+ build_index_type
+ (build_int_cst (NULL_TREE, size - 1,
0))),
+ "ivar_list");
chainon (field_decl_chain, field_decl);
finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
@@ -4431,7 +4380,7 @@ build_ivar_list_template (tree list_type
}
/* struct {
- int method_next;
+ struct _objc__method_prototype_list *method_next;
int method_count;
struct objc_method method_list[method_count];
}; */
@@ -4440,37 +4389,28 @@ static tree
build_method_list_template (tree list_type, int size)
{
tree objc_ivar_list_record;
- tree decl_specs, field_decl, field_decl_chain;
+ tree 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 (field_decl, decl_specs, NULL_TREE);
+ /* struct _objc__method_prototype_list *method_next; */
+ field_decl = create_field_decl (build_pointer_type
+ (xref_tag (RECORD_TYPE,
+ get_identifier
+
(UTAG_METHOD_PROTOTYPE_LIST))),
+ "method_next");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (integer_type_node, "method_count");
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_cst (NULL_TREE, size, 0), NULL_TREE,
NULL_TREE);
-
- field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_array_type
+ (list_type,
+ build_index_type
+ (build_int_cst (NULL_TREE, size - 1,
0))),
+ "method_list");
chainon (field_decl_chain, field_decl);
finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
@@ -4530,20 +4470,17 @@ build_ivar_list_initializer (tree type,
static tree
generate_ivars_list (tree type, const char *name, int size, tree list)
{
- tree sc_spec, decl_specs, decl, initlist;
+ tree 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,
objc_implementation_context),
- decl_specs, 1, NULL_TREE);
+ decl = start_var_decl (type, synth_id_with_class_suffix
+ (name, objc_implementation_context));
initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE,
size, 0));
initlist = tree_cons (NULL_TREE, list, initlist);
- finish_decl (decl,
- objc_build_constructor (TREE_TYPE (decl), nreverse
(initlist)),
- NULL_TREE);
+ finish_var_decl (decl,
+ objc_build_constructor (TREE_TYPE (decl),
+ nreverse (initlist)));
return decl;
}
@@ -4565,7 +4502,8 @@ static void
generate_ivar_lists (void)
{
tree initlist, ivar_list_template, chain;
- tree cast, variable_length_type;
+ tree variable_length_type
+ = xref_tag (RECORD_TYPE, get_identifier (UTAG_IVAR_LIST));
int size;
generating_instance_variables = 1;
@@ -4573,13 +4511,6 @@ generate_ivar_lists (void)
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. */
@@ -4640,10 +4571,12 @@ build_dispatch_table_initializer (tree t
meth_var_types),
elemlist);
- elemlist = tree_cons (NULL_TREE,
- build_unary_op (ADDR_EXPR,
- METHOD_DEFINITION
(entries), 1),
- elemlist);
+ elemlist
+ = tree_cons (NULL_TREE,
+ convert (ptr_type_node,
+ build_unary_op (ADDR_EXPR,
+ METHOD_DEFINITION
(entries), 1)),
+ elemlist);
initlist = tree_cons (NULL_TREE,
objc_build_constructor (type, nreverse
(elemlist)),
@@ -4669,31 +4602,21 @@ static tree
build_method_template (void)
{
tree _SLT_record;
- tree decl_specs, field_decl, field_decl_chain;
+ tree field_decl, field_decl_chain;
_SLT_record = start_struct (RECORD_TYPE, get_identifier
(UTAG_METHOD));
- /* 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"));
-
- field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
+ /* SEL _cmd; */
+ field_decl = create_field_decl (objc_selector_type, "_cmd");
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 (field_decl, decl_specs, NULL_TREE);
+ /* char *method_types; */
+ field_decl = create_field_decl (string_type_node, "method_types");
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 (field_decl, decl_specs, NULL_TREE);
+ field_decl = create_field_decl (build_pointer_type (void_type_node),
+ "_imp");
chainon (field_decl_chain, field_decl);
finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
@@ -4705,21 +4628,18 @@ build_method_template (void)
static tree
generate_dispatch_table (tree type, const 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);
+ tree decl, initlist;
- decl = start_decl (synth_id_with_class_suffix (name,
objc_implementation_context),
- decl_specs, 1, NULL_TREE);
+ decl = start_var_decl (type, synth_id_with_class_suffix
+ (name, objc_implementation_context));
initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0,
0));
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size, 0),
initlist);
initlist = tree_cons (NULL_TREE, list, initlist);
- finish_decl (decl,
- objc_build_constructor (TREE_TYPE (decl), nreverse
(initlist)),
- NULL_TREE);
+ finish_var_decl (decl,
+ objc_build_constructor (TREE_TYPE (decl),
+ nreverse (initlist)));
return decl;
}
@@ -4752,21 +4672,13 @@ static void
generate_dispatch_tables (void)
{
tree initlist, chain, method_list_template;
- tree cast, variable_length_type;
+ tree variable_length_type
+ = xref_tag (RECORD_TYPE, get_identifier (UTAG_METHOD_LIST));
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 (objc_implementation_context);
if (chain)
{
@@ -4819,10 +4731,10 @@ generate_dispatch_tables (void)
static tree
generate_protocol_list (tree i_or_p)
{
- tree initlist, decl_specs, sc_spec;
- tree refs_decl, expr_decl, lproto, e, plist;
- tree cast_type;
+ tree initlist;
+ tree refs_decl, lproto, e, plist;
int size = 0;
+ const char *ref_name;
if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
|| TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
@@ -4832,13 +4744,6 @@ generate_protocol_list (tree i_or_p)
else
abort ();
- 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
@@ -4848,8 +4753,8 @@ generate_protocol_list (tree i_or_p)
/* Build initializer. */
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0),
NULL_TREE);
- e = build_int_cst (NULL_TREE, size, 0);
- TREE_TYPE (e) = cast_type;
+ e = convert (build_pointer_type (objc_protocol_template),
+ build_int_cst (NULL_TREE, size, 0));
initlist = tree_cons (NULL_TREE, e, initlist);
for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
@@ -4866,38 +4771,23 @@ generate_protocol_list (tree i_or_p)
/* 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_cst (NULL_TREE, size + 2, 0),
NULL_TREE, NULL_TREE);
+ ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
i_or_p);
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_cst (NULL_TREE, size + 2, 0),
NULL_TREE, NULL_TREE);
+ ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
i_or_p);
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_cst (NULL_TREE, size + 2, 0), NULL_TREE,
NULL_TREE);
+ ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
i_or_p);
else
abort ();
- expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
+ refs_decl = start_var_decl
+ (build_array_type
+ (build_pointer_type (objc_protocol_template),
+ build_index_type (build_int_2 (size + 2, 0))),
+ ref_name);
- refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
- DECL_CONTEXT (refs_decl) = NULL_TREE;
-
- finish_decl (refs_decl, objc_build_constructor (TREE_TYPE
(refs_decl),
- nreverse (initlist)),
- NULL_TREE);
+ finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE
(refs_decl),
+ nreverse
(initlist)));
return refs_decl;
}
@@ -4931,24 +4821,18 @@ build_category_initializer (tree type, t
if (!protocol_list)
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0),
initlist);
else
- {
- tree 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);
- }
+ {
+ expr = convert (build_pointer_type
+ (build_pointer_type
+ (objc_protocol_template)),
+ build_unary_op (ADDR_EXPR, protocol_list, 0));
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
return objc_build_constructor (type, nreverse (initlist));
}
-/* struct objc_class {
+/* struct _objc_class {
struct objc_class *isa;
struct objc_class *super_class;
char *name;
@@ -5033,20 +4917,13 @@ build_shared_structure_initializer (tree
if (! protocol_list)
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0, 0),
initlist);
else
- {
- tree 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);
- }
+ {
+ expr = convert (build_pointer_type
+ (build_pointer_type
+ (objc_protocol_template)),
+ build_unary_op (ADDR_EXPR, protocol_list, 0));
+ initlist = tree_cons (NULL_TREE, expr, initlist);
+ }
if (flag_next_runtime)
/* sel_id = NULL */
@@ -5075,7 +4952,7 @@ lookup_category (tree class, tree cat_na
static void
generate_category (tree cat)
{
- tree sc_spec, decl_specs, decl;
+ tree decl;
tree initlist, cat_name_expr, class_name_expr;
tree protocol_decl, category;
@@ -5095,12 +4972,9 @@ generate_category (tree cat)
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",
-
objc_implementation_context),
- decl_specs, 1, NULL_TREE);
+ decl = start_var_decl (objc_category_template,
+ synth_id_with_class_suffix
+ ("_OBJC_CATEGORY",
objc_implementation_context));
initlist = build_category_initializer (TREE_TYPE (decl),
cat_name_expr, class_name_expr,
@@ -5108,7 +4982,7 @@ generate_category (tree cat)
UOBJC_CLASS_METHODS_decl,
protocol_decl);
- finish_decl (decl, initlist, NULL_TREE);
+ finish_var_decl (decl, initlist);
}
/* static struct objc_class _OBJC_METACLASS_Foo={ ... };
@@ -5146,12 +5020,7 @@ generate_shared_structures (void)
/* 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)));
-
+ cast_type = build_pointer_type (objc_class_template);
name_expr = add_objc_string (CLASS_NAME (implementation_template),
class_names);
@@ -5181,8 +5050,9 @@ generate_shared_structures (void)
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);
+ decl = start_var_decl (objc_class_template,
+ IDENTIFIER_POINTER
+ (DECL_NAME (UOBJC_METACLASS_decl)));
initlist
= build_shared_structure_initializer
@@ -5194,12 +5064,13 @@ generate_shared_structures (void)
UOBJC_CLASS_VARIABLES_decl,
protocol_decl);
- finish_decl (decl, initlist, NULL_TREE);
+ finish_var_decl (decl, initlist);
/* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
- decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1,
- NULL_TREE);
+ decl = start_var_decl (objc_class_template,
+ IDENTIFIER_POINTER
+ (DECL_NAME (UOBJC_CLASS_decl)));
initlist
= build_shared_structure_initializer
@@ -5214,19 +5085,18 @@ generate_shared_structures (void)
UOBJC_INSTANCE_VARIABLES_decl,
protocol_decl);
- finish_decl (decl, initlist, NULL_TREE);
+ finish_var_decl (decl, initlist);
}
-static tree
+
+static const char *
synth_id_with_class_suffix (const char *preamble, tree ctxt)
{
- char *string;
+ static char string[BUFSIZE];
+
if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
|| TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
{
- const char *const class_name
- = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
- string = (char *) alloca (strlen (preamble) + strlen
(class_name) + 3);
sprintf (string, "%s_%s", preamble,
IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
}
@@ -5238,37 +5108,17 @@ synth_id_with_class_suffix (const char *
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
const char *const class_super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME
(objc_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)
{
const 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 (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]));
+ return string;
}
/* If type is empty or only type qualifiers are present, add default
@@ -5277,30 +5127,16 @@ is_objc_type_qualifier (tree node)
static tree
adjust_type_for_id_default (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));
+ type = make_node (TREE_LIST);
- declspecs = TREE_PURPOSE (type);
+ if (!TREE_VALUE (type))
+ TREE_VALUE (type) = objc_object_type;
+ else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
+ && TYPED_OBJECT (TREE_VALUE (type)))
+ error ("can not use an object as parameter to a method");
- /* Determine if a typespec is present. */
- for (chain = declspecs;
- 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;
- }
-
- return build_tree_list (tree_cons (NULL_TREE, objc_object_reference,
- declspecs),
- build1 (INDIRECT_REF, NULL_TREE, NULL_TREE));
+ return type;
}
/* Usage:
@@ -5322,7 +5158,7 @@ adjust_type_for_id_default (tree type)
Out: an instance of "keyword_decl". */
tree
-build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
+objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
{
tree keyword_decl;
@@ -5393,7 +5229,7 @@ build_keyword_selector (tree selector)
/* Used for declarations and definitions. */
-tree
+static tree
build_method_decl (enum tree_code code, tree ret_type, tree selector,
tree add_args)
{
@@ -5442,10 +5278,10 @@ get_arg_type_list (tree meth, int contex
/* Receiver type. */
if (flag_next_runtime && superflag)
arglist = build_tree_list (NULL_TREE, objc_super_type);
- else if (context == METHOD_DEF)
- arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl));
+ else if (context == METHOD_DEF && TREE_CODE (meth) ==
INSTANCE_METHOD_DECL)
+ arglist = build_tree_list (NULL_TREE, objc_instance_type);
else
- arglist = build_tree_list (NULL_TREE, objc_id_type);
+ arglist = build_tree_list (NULL_TREE, objc_object_type);
/* Selector type - will eventually change to `int'. */
chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
@@ -5458,23 +5294,29 @@ get_arg_type_list (tree meth, int contex
/* 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)));
+ tree arg_type = TREE_VALUE (TREE_TYPE (akey));
+
+ chainon (arglist, build_tree_list (NULL_TREE, arg_type));
}
- if (METHOD_ADD_ARGS (meth) == objc_ellipsis_node)
- /* We have a `, ...' immediately following the selector,
- finalize the arglist...simulate get_parm_info (true). */
- ;
- else if (METHOD_ADD_ARGS (meth))
+ 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);
+ for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
+ akey; akey = TREE_CHAIN (akey))
+ {
+ tree arg_type = TREE_TYPE (TREE_VALUE (akey));
+
+ chainon (arglist, build_tree_list (NULL_TREE, arg_type));
+ }
+
+ if (!TREE_OVERFLOW (METHOD_ADD_ARGS (meth)))
+ goto lack_of_ellipsis;
}
else
- /* finalize the arglist...simulate get_parm_info (false) */
- chainon (arglist, void_list_node);
+ {
+ lack_of_ellipsis:
+ chainon (arglist, OBJC_VOID_AT_END);
+ }
return arglist;
}
@@ -5516,7 +5358,7 @@ check_duplicates (hash hsh, int methods,
}
/* If RECEIVER is a class reference, return the identifier node for
- the referenced class. RECEIVER is created by get_class_reference,
+ the referenced class. RECEIVER is created by
objc_get_class_reference,
so we check the exact form created depending on which runtimes are
used. */
@@ -5537,8 +5379,7 @@ receiver_is_class_object (tree receiver,
{
/* The receiver is a variable created by
build_class_reference_decl. */
- if (TREE_CODE (receiver) == VAR_DECL
- && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE
(objc_class_type))
+ if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE
(receiver)))
/* Look up the identifier. */
for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
if (TREE_PURPOSE (chain) == receiver)
@@ -5592,11 +5433,15 @@ objc_message_selector (void)
(*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...);
*/
tree
-build_message_expr (tree mess)
+objc_build_message_expr (tree mess)
{
tree receiver = TREE_PURPOSE (mess);
tree sel_name;
+#ifdef OBJCPLUS
+ tree args = TREE_PURPOSE (TREE_VALUE (mess));
+#else
tree args = TREE_VALUE (mess);
+#endif
tree method_params = NULL_TREE;
if (TREE_CODE (receiver) == ERROR_MARK)
@@ -5613,6 +5458,9 @@ build_message_expr (tree mess)
/* Build the parameter list to give to the method. */
if (TREE_CODE (args) == TREE_LIST)
+#ifdef OBJCPLUS
+ method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
+#else
{
tree chain = args, prev = NULL_TREE;
@@ -5634,6 +5482,7 @@ build_message_expr (tree mess)
}
method_params = args;
}
+#endif
#ifdef OBJCPLUS
if (processing_template_decl)
@@ -5642,7 +5491,7 @@ build_message_expr (tree mess)
method_params);
#endif
- return finish_message_expr (receiver, sel_name, method_params);
+ return objc_finish_message_expr (receiver, sel_name, method_params);
}
/* Look up method SEL_NAME that would be suitable for receiver
@@ -5668,13 +5517,13 @@ lookup_method_in_hash_lists (tree sel_na
return check_duplicates (method_prototype, 1, is_class);
}
-/* The 'finish_message_expr' routine is called from within
- 'build_message_expr' for non-template functions. In the case of
+/* The 'objc_finish_message_expr' routine is called from within
+ 'objc_build_message_expr' for non-template functions. In the case
of
C++ template functions, it is called from 'build_expr_from_tree'
(in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded.
*/
tree
-finish_message_expr (tree receiver, tree sel_name, tree method_params)
+objc_finish_message_expr (tree receiver, tree sel_name, tree
method_params)
{
tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
tree selector, retval, class_tree;
@@ -5687,6 +5536,7 @@ finish_message_expr (tree receiver, tree
while (TREE_CODE (rtype) == COMPOUND_EXPR
|| TREE_CODE (rtype) == MODIFY_EXPR
|| TREE_CODE (rtype) == NOP_EXPR
+ || TREE_CODE (rtype) == CONVERT_EXPR
|| TREE_CODE (rtype) == COMPONENT_REF)
rtype = TREE_OPERAND (rtype, 0);
self = (rtype == self_decl);
@@ -5724,8 +5574,7 @@ finish_message_expr (tree receiver, tree
/* If receiver is of type `id' or `Class' (or if the @interface for a
class is not visible), we shall be satisfied with the existence of
any instance or class method. */
- if (!rtype || IS_ID (rtype)
- || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
+ if (!rtype || objc_is_id (rtype))
{
if (!rtype)
rtype = xref_tag (RECORD_TYPE, class_tree);
@@ -5735,7 +5584,10 @@ finish_message_expr (tree receiver, tree
rtype = NULL_TREE;
}
else
- class_tree = TYPE_NAME (rtype) = get_identifier ("Class");
+ {
+ class_tree = objc_class_name;
+ OBJC_SET_TYPE_NAME (rtype, class_tree);
+ }
if (rprotos)
method_prototype
@@ -5753,10 +5605,10 @@ finish_message_expr (tree receiver, tree
if (TREE_CODE (rtype) == POINTER_TYPE)
rtype = TREE_TYPE (rtype);
/* Traverse typedef aliases */
- while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
- && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
- && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
- rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
+ while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
+ && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
+ && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
+ rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
saved_rtype = rtype;
if (TYPED_OBJECT (rtype))
{
@@ -5800,7 +5652,7 @@ finish_message_expr (tree receiver, tree
else
{
warning ("invalid receiver type `%s'",
- gen_declaration (orig_rtype, errbuf));
+ gen_type_name (orig_rtype, errbuf));
rtype = rprotos = NULL_TREE;
}
}
@@ -5863,15 +5715,15 @@ build_objc_method_call (int super_flag,
(!flag_next_runtime || flag_nil_receivers
? umsg_decl
: umsg_nonnil_decl));
- tree rcv_p = (super_flag ? objc_super_type : objc_id_type);
+ tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
/* If a prototype for the method to be called exists, then cast
the sender's return type and arguments to match that of the
method.
Otherwise, leave sender as is. */
tree ret_type
= (method_prototype
- ? groktypename (TREE_TYPE (method_prototype))
- : objc_id_type);
+ ? TREE_VALUE (TREE_TYPE (method_prototype))
+ : objc_object_type);
tree sender_cast
= build_pointer_type
(build_function_type
@@ -5933,29 +5785,13 @@ build_objc_method_call (int super_flag,
static void
build_protocol_reference (tree p)
{
- tree decl, ident, ptype;
+ tree decl;
+ const char *proto_name;
- /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
+ /* static 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) = 0;
- TREE_USED (decl) = 1;
- DECL_ARTIFICIAL (decl) = 1;
-
- make_decl_rtl (decl);
- pushdecl_top_level (decl);
- }
+ proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
+ decl = start_var_decl (objc_protocol_template, proto_name);
PROTOCOL_FORWARD_DECL (p) = decl;
}
@@ -5963,7 +5799,7 @@ build_protocol_reference (tree p)
/* 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 (tree protoname)
+objc_build_protocol_expr (tree protoname)
{
tree expr;
tree p = lookup_protocol (protoname);
@@ -6035,7 +5871,7 @@ build_protocol_expr (tree protoname)
is found, in order to compile it. It is only called by the parser
and only to compile a @selector(). */
tree
-build_selector_expr (tree selnamelist)
+objc_build_selector_expr (tree selnamelist)
{
tree selname;
@@ -6081,7 +5917,7 @@ build_selector_expr (tree selnamelist)
}
tree
-build_encode_expr (tree type)
+objc_build_encode_expr (tree type)
{
tree result;
const char *string;
@@ -6097,7 +5933,7 @@ build_encode_expr (tree type)
return result;
}
-tree
+static tree
build_ivar_reference (tree id)
{
if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
@@ -6113,7 +5949,7 @@ build_ivar_reference (tree id)
paradigm. */
warning ("instance variable `%s' accessed in class method",
IDENTIFIER_POINTER (id));
- TREE_TYPE (self_decl) = objc_instance_type; /* cast */
+ self_decl = convert (objc_instance_type, self_decl); /* cast */
}
return build_component_ref (build_indirect_ref (self_decl, "->"),
id);
@@ -6140,6 +5976,10 @@ hash_init (void)
= (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
cls_method_hash_list
= (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
+
+ /* Initialize the hash table used to hold the constant string
objects. */
+ string_htab = htab_create_ggc (31, string_hash,
+ string_eq, NULL);
}
/* WARNING!!!! hash_enter is called with a method, and will peek
@@ -6288,12 +6128,14 @@ add_method_to_hash_list (hash *hash_list
}
}
-tree
+static tree
objc_add_method (tree class, tree method, int is_class)
{
tree mth;
- if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) :
CLASS_NST_METHODS (class), method)))
+ if (!(mth = lookup_method (is_class
+ ? CLASS_CLS_METHODS (class)
+ : CLASS_NST_METHODS (class), method)))
{
/* put method on list in reverse order */
if (is_class)
@@ -6318,7 +6160,8 @@ objc_add_method (tree class, tree method
|| TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
&& !comp_proto_with_proto (method, mth))
error ("duplicate declaration of method `%c%s'",
- is_class ? '+' : '-', IDENTIFIER_POINTER
(METHOD_SEL_NAME (mth)));
+ is_class ? '+' : '-',
+ IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
}
if (is_class)
@@ -6374,16 +6217,13 @@ add_category (tree class, tree category)
PUBLIC is 1 for public, 0 for protected, and 2 for private. */
-tree
-add_instance_variable (tree class, int public, tree declarator,
- tree declspecs, tree width)
+static tree
+add_instance_variable (tree class, int public, tree field_decl)
{
- tree field_decl = grokfield (declarator, declspecs, width);
tree field_type = TREE_TYPE (field_decl);
const char *ivar_name = DECL_NAME (field_decl)
? IDENTIFIER_POINTER (DECL_NAME (field_decl))
: "<unnamed>";
- tree raw_decl;
#ifdef OBJCPLUS
if (TREE_CODE (field_type) == REFERENCE_TYPE)
@@ -6396,13 +6236,8 @@ add_instance_variable (tree class, int p
#endif
if (field_type == error_mark_node || !TYPE_SIZE (field_type)
- || TYPE_SIZE (field_type) == error_mark_node
+ || TYPE_SIZE (field_type) == error_mark_node)
/* 'type[0]' is allowed, but 'type[]' is not! */
-#ifdef OBJCPLUS
- || (TYPE_SIZE (field_type) == bitsize_zero_node
- && !TREE_OPERAND (declarator, 1))
-#endif
- )
{
error ("instance variable `%s' has unknown size", ivar_name);
/* Return class as is without adding this ivar. */
@@ -6457,13 +6292,12 @@ add_instance_variable (tree class, int p
}
- raw_decl = build_tree_list (declspecs, build_tree_list (declarator,
width));
- CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class),
raw_decl);
- CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
+ CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class),
field_decl);
+
return class;
}
-tree
+static tree
is_ivar (tree decl_chain, tree ident)
{
for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
@@ -6474,7 +6308,7 @@ is_ivar (tree decl_chain, tree ident)
/* True if the ivar is private and we are not in its implementation.
*/
-int
+static int
is_private (tree decl)
{
return (TREE_PRIVATE (decl)
@@ -6546,7 +6380,7 @@ objc_is_public (tree expr, tree identifi
else if (objc_implementation_context && (basetype ==
objc_object_reference))
{
- TREE_TYPE (expr) = uprivate_record;
+ expr = convert (uprivate_record, expr);
warning ("static access to object of type `id'");
}
}
@@ -6752,7 +6586,7 @@ check_protocols (tree proto_list, const
It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
-tree
+static tree
start_class (enum tree_code code, tree class_name, tree super_name,
tree protocol_list)
{
@@ -6775,17 +6609,27 @@ start_class (enum tree_code code, tree c
class = make_node (code);
TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
+ /* Check for existence of the super class, if one was specified. */
+ if ((code == CLASS_INTERFACE_TYPE || code ==
CLASS_IMPLEMENTATION_TYPE)
+ && super_name && !objc_is_class_name (super_name))
+ {
+ error ("cannot find interface declaration for `%s', superclass
of `%s'",
+ IDENTIFIER_POINTER (super_name),
+ IDENTIFIER_POINTER (class_name));
+ super_name = NULL_TREE;
+ }
+
CLASS_NAME (class) = class_name;
CLASS_SUPER_NAME (class) = super_name;
CLASS_CLS_METHODS (class) = NULL_TREE;
- if (! is_class_name (class_name)
+ if (! objc_is_class_name (class_name)
&& (decl = lookup_name (class_name)))
{
error ("`%s' redeclared as different kind of symbol",
IDENTIFIER_POINTER (class_name));
error ("%Jprevious declaration of '%D'",
- decl, decl);
+ decl, decl);
}
if (code == CLASS_IMPLEMENTATION_TYPE)
@@ -6899,7 +6743,7 @@ start_class (enum tree_code code, tree c
return class;
}
-tree
+static tree
continue_class (tree class)
{
if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
@@ -6910,15 +6754,16 @@ continue_class (tree class)
/* Check consistency of the instance variables. */
- if (CLASS_IVARS (class))
+ if (CLASS_RAW_IVARS (class))
check_ivars (implementation_template, class);
/* code generation */
- ivar_context = build_private_template (implementation_template);
+#ifdef OBJCPLUS
+ push_lang_context (lang_name_c);
+#endif
- if (!objc_class_template)
- build_class_template ();
+ ivar_context = build_private_template (implementation_template);
imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct
imp_entry));
@@ -6937,21 +6782,33 @@ continue_class (tree class)
else
cat_count++;
+#ifdef OBJCPLUS
+ pop_lang_context ();
+#endif /* OBJCPLUS */
+
return ivar_context;
}
else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
{
+#ifdef OBJCPLUS
+ push_lang_context (lang_name_c);
+#endif /* OBJCPLUS */
+
if (!CLASS_STATIC_TEMPLATE (class))
{
tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
- finish_struct (record, get_class_ivars (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. */
TREE_STATIC_TEMPLATE (record) = 1;
}
+#ifdef OBJCPLUS
+ pop_lang_context ();
+#endif /* OBJCPLUS */
+
return NULL_TREE;
}
@@ -6961,7 +6818,7 @@ continue_class (tree class)
/* This is called once we see the "@end" in an
interface/implementation. */
-void
+static void
finish_class (tree class)
{
if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
@@ -7004,7 +6861,7 @@ finish_class (tree class)
else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
{
- tree decl_specs;
+ tree decl;
const char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class));
char *string = (char *) alloca (strlen (class_name) + 3);
@@ -7012,10 +6869,11 @@ finish_class (tree class)
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);
+ decl = build_decl (VAR_DECL, get_identifier (string),
+ build_pointer_type (objc_object_reference));
+ DECL_EXTERNAL (decl) = 1;
+ lang_hooks.decls.pushdecl (decl);
+ finish_decl (decl, NULL_TREE, NULL_TREE);
}
}
@@ -7073,7 +6931,7 @@ objc_declare_protocols (tree names)
}
}
-tree
+static tree
start_protocol (enum tree_code code, tree name, tree list)
{
tree protocol;
@@ -7084,11 +6942,6 @@ start_protocol (enum tree_code code, tre
}
#endif /* OBJCPLUS */
- /* 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 = lookup_protocol (name);
if (!protocol)
@@ -7119,11 +6972,6 @@ start_protocol (enum tree_code code, tre
return protocol;
}
-void
-finish_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! */
@@ -7135,9 +6983,7 @@ encode_type_qualifiers (tree declspecs)
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))
+ 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');
@@ -7208,6 +7054,11 @@ encode_pointer (tree type, int curtype,
if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname),
"BOOL"))
{
+ /* It appears that "r*" means "const char *" rather than
+ "char *const". */
+ if (TYPE_READONLY (pointer_to))
+ obstack_1grow (&util_obstack, 'r');
+
obstack_1grow (&util_obstack, '*');
return;
}
@@ -7234,9 +7085,9 @@ encode_array (tree type, int curtype, in
return;
}
- sprintf (buffer, "[%ld",
- (long) (TREE_INT_CST_LOW (an_int_cst)
- / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
+ sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
+ (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);
@@ -7357,6 +7208,9 @@ encode_type (tree type, int curtype, int
enum tree_code code = TREE_CODE (type);
char c;
+ if (TYPE_READONLY (type))
+ obstack_1grow (&util_obstack, 'r');
+
if (code == INTEGER_TYPE)
{
switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
@@ -7494,110 +7348,124 @@ encode_field_decl (tree field_decl, int
encode_type (TREE_TYPE (field_decl), curtype, format);
}
+static GTY(()) tree objc_parmlist = NULL_TREE;
+
+/* Append PARM to a list of formal parameters of a method, making a
necessary
+ array-to-pointer adjustment along the way. */
+
+static void
+objc_push_parm (tree parm)
+{
+ /* Convert array parameters of unknown size into pointers. */
+ if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
+ && !TYPE_SIZE (TREE_TYPE (parm)))
+ TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE
(parm)));
+
+ objc_parmlist = chainon (objc_parmlist, parm);
+}
+
+/* Retrieve the formal paramter list constructed via preceding calls to
+ objc_push_parm(). */
+
static tree
-objc_expr_last (tree complex_expr)
+#ifdef OBJCPLUS
+objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
+#else
+objc_get_parm_info (int have_ellipsis)
+#endif
{
- tree next;
+ tree parm_info = objc_parmlist;
- if (complex_expr)
- while ((next = TREE_OPERAND (complex_expr, 0)))
- complex_expr = next;
+#ifndef OBJCPLUS
+ /* The C front-end requires an elaborate song and dance at
+ this point. */
+ push_scope ();
+ declare_parm_level ();
+ while (parm_info)
+ {
+ tree next = TREE_CHAIN (parm_info);
- return complex_expr;
+ TREE_CHAIN (parm_info) = NULL_TREE;
+ pushdecl (parm_info);
+ parm_info = next;
+ }
+ parm_info = get_parm_info (have_ellipsis);
+ pop_scope ();
+#endif
+ objc_parmlist = NULL_TREE;
+
+ return parm_info;
}
+/* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed
for ObjC
+ method definitions. In the case of instance methods, we can be more
+ specific as to the type of 'self'. */
+
static void
synth_self_and_ucmd_args (void)
{
- tree decl_specs;
+ tree self_type;
if (objc_method_context
&& TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
- decl_specs = build_tree_list (NULL_TREE, uprivate_record);
+ self_type = objc_instance_type;
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);
+ self_type = objc_object_type;
+
+ /* id self; */
+ objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
- push_parm_decl (build_tree_list
- (build_tree_list (decl_specs,
- build1 (INDIRECT_REF, NULL_TREE,
self_id)),
- unused_list));
-
- decl_specs = build_tree_list (NULL_TREE, TREE_TYPE
(objc_selector_type));
- push_parm_decl (build_tree_list
- (build_tree_list (decl_specs,
- build1 (INDIRECT_REF, NULL_TREE,
ucmd_id)),
- unused_list));
+ /* SEL _cmd; */
+ objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
}
-/* Transform a method definition into a function definition as follows:
- - synthesize the first two arguments, "self" and "_cmd". */
+/* Transform an Objective-C method definition into a static C function
+ definition, synthesizing the first two arguments, "self" and "_cmd",
+ in the process. */
-void
+static void
start_method_def (tree method)
{
+ tree parmlist;
+ int have_ellipsis = 0;
+
/* Required to implement _msgSuper. */
objc_method_context = method;
UOBJC_SUPER_decl = NULL_TREE;
- /* Must be called BEFORE start_function. */
- push_scope ();
- declare_parm_level ();
-
/* Generate prototype declarations for arguments..."new-style". */
synth_self_and_ucmd_args ();
/* Generate argument declarations if a keyword_decl. */
- if (METHOD_SEL_ARGS (method))
+ parmlist = METHOD_SEL_ARGS (method);
+ while (parmlist)
{
- 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 = objc_expr_last (arg_decl);
+ tree parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist),
+ TREE_VALUE (TREE_TYPE (parmlist)));
- /* 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),
- NULL_TREE));
-
-#ifndef OBJCPLUS
- /* Unhook: restore the abstract declarator. */
- TREE_OPERAND (last_expr, 0) = NULL_TREE;
-#endif
- }
-
- else
- push_parm_decl (build_tree_list
- (build_tree_list (arg_spec,
- KEYWORD_ARG_NAME
(arglist)),
- NULL_TREE));
-
- arglist = TREE_CHAIN (arglist);
- }
- while (arglist);
+ objc_push_parm (parm);
+ parmlist = TREE_CHAIN (parmlist);
}
- if (METHOD_ADD_ARGS (method) != NULL_TREE
- && METHOD_ADD_ARGS (method) != objc_ellipsis_node)
+ if (METHOD_ADD_ARGS (method))
{
- /* We have a variable length selector - in "prototype" format.
*/
- tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method));
- while (akey)
+ tree akey;
+
+ for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
+ akey; akey = TREE_CHAIN (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;
+ objc_push_parm (TREE_VALUE (akey));
}
+
+ if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
+ have_ellipsis = 1;
}
+
+ parmlist = objc_get_parm_info (have_ellipsis);
+
+ really_start_method (objc_method_context, parmlist);
}
static void
@@ -7608,34 +7476,22 @@ warn_with_method (const char *message, i
message, mtype, gen_method_decl (method, errbuf));
}
-/* Return 1 if METHOD is consistent with PROTO. */
-
-static int
-comp_method_with_proto (tree method, tree proto)
-{
- /* Create a function template node at most once. */
- if (!function1_template)
- function1_template = make_node (FUNCTION_TYPE);
-
- /* Install argument types - normally set by build_function_type. */
- TYPE_ARG_TYPES (function1_template)
- = get_arg_type_list (proto, METHOD_DEF, 0);
-
- /* install return type */
- TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
-
- return comptypes (TREE_TYPE (METHOD_DEFINITION (method)),
function1_template);
-}
-
-/* Return 1 if TYPE1 is equivalent to TYPE2. */
+/* Return 1 if TYPE1 is equivalent to TYPE2
+ for purposes of method overloading. */
static int
objc_types_are_equivalent (tree type1, tree type2)
{
if (type1 == type2)
return 1;
+
+ /* Strip away indirections. */
+ while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) ==
POINTER_TYPE)
+ && (TREE_CODE (type1) == TREE_CODE (type2)))
+ type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
return 0;
+
type1 = TYPE_PROTOCOL_LIST (type1);
type2 = TYPE_PROTOCOL_LIST (type2);
if (list_length (type1) == list_length (type2))
@@ -7648,7 +7504,8 @@ objc_types_are_equivalent (tree type1, t
return 0;
}
-/* Return 1 if PROTO1 is equivalent to PROTO2. */
+/* Return 1 if PROTO1 is equivalent to PROTO2
+ for purposes of method overloading. */
static int
comp_proto_with_proto (tree proto1, tree proto2)
@@ -7661,8 +7518,8 @@ comp_proto_with_proto (tree proto1, tree
return 0;
/* Compare return types. */
- type1 = groktypename (TREE_TYPE (proto1));
- type2 = groktypename (TREE_TYPE (proto2));
+ type1 = TREE_VALUE (TREE_TYPE (proto1));
+ type2 = TREE_VALUE (TREE_TYPE (proto2));
if (!objc_types_are_equivalent (type1, type2))
return 0;
@@ -7680,6 +7537,36 @@ comp_proto_with_proto (tree proto1, tree
return (!type1 && !type2);
}
+static void
+objc_start_function (tree name, tree type, tree attrs, tree params)
+{
+ tree fndecl = build_decl (FUNCTION_DECL, name, type);
+
+ DECL_ARGUMENTS (fndecl) = params;
+ DECL_INITIAL (fndecl) = error_mark_node;
+ DECL_EXTERNAL (fndecl) = 0;
+ TREE_STATIC (fndecl) = 1;
+
+#ifdef OBJCPLUS
+ retrofit_lang_decl (fndecl);
+ cplus_decl_attributes (&fndecl, attrs, 0);
+ start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
+#else
+ decl_attributes (&fndecl, attrs, 0);
+ announce_function (fndecl);
+ current_function_decl = pushdecl (fndecl);
+ push_scope ();
+ declare_parm_level ();
+ DECL_RESULT (current_function_decl)
+ = build_decl (RESULT_DECL, NULL_TREE,
+ TREE_TYPE (TREE_TYPE (current_function_decl)));
+ start_fname_decls ();
+ store_parm_decls ();
+#endif
+
+ TREE_USED (current_function_decl) = 1;
+}
+
/* - 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.
@@ -7689,15 +7576,13 @@ comp_proto_with_proto (tree proto1, tree
static void
really_start_method (tree method, tree parmlist)
{
- tree sc_spec, ret_spec, ret_decl, decl_specs;
- tree method_decl, method_id;
+ tree ret_type, meth_type;
+ tree method_id;
const char *sel_name, *class_name, *cat_name;
char *buf;
/* 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);
+ ret_type = TREE_VALUE (TREE_TYPE (method));
sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
class_name = IDENTIFIER_POINTER (CLASS_NAME
(objc_implementation_context));
@@ -7722,49 +7607,18 @@ really_start_method (tree method, tree p
push_lang_context (lang_name_c);
#endif
- 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 = objc_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);
+ meth_type
+ = build_function_type (ret_type,
+ get_arg_type_list (method, METHOD_DEF, 0));
+ objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
- /* 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);
-
- /* Unhook: this has the effect of restoring the abstract
declarator. */
- TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
- }
-
-#ifdef OBJCPLUS
- /* set self_decl from the first argument...this global is used by
- * build_ivar_reference().build_indirect_ref().
- */
+ /* Set self_decl from the first argument. */
self_decl = DECL_ARGUMENTS (current_function_decl);
- /* snaroff (3/28/96): when compiling with -Wall, this suppresses
- * the following: warning:unused parameter `struct objc_selector *
_cmd'
- */
+ /* Suppress unused warnings. */
TREE_USED (self_decl) = 1;
TREE_USED (TREE_CHAIN (self_decl)) = 1;
- /* Ditto for the underlying (static) C function. */
- TREE_USED (current_function_decl) = 1;
+#ifdef OBJCPLUS
pop_lang_context ();
#endif
@@ -7781,7 +7635,7 @@ really_start_method (tree method, tree p
if (proto)
{
- if (!comp_method_with_proto (method, proto))
+ if (!comp_proto_with_proto (method, proto))
{
char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ?
'-' : '+');
@@ -7811,33 +7665,6 @@ really_start_method (tree method, tree p
}
}
-/* 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 (void)
-{
- tree parmlist;
-
- if (METHOD_ADD_ARGS (objc_method_context) == objc_ellipsis_node)
- /* We have a `, ...' immediately following the selector. */
- parmlist = get_parm_info (/*ellipsis=*/true);
- else
- parmlist = get_parm_info (/*ellipsis=*/false);
-
-#ifndef OBJCPLUS
- /* Set self_decl from the first argument...this global is used by
- build_ivar_reference calling build_indirect_ref. */
- self_decl = TREE_PURPOSE (parmlist);
-#endif /* !OBJCPLUS */
-
- pop_scope ();
- really_start_method (objc_method_context, parmlist);
- store_parm_decls ();
-}
-
static void *UOBJC_SUPER_scope = 0;
/* _n_Method (id self, SEL sel, ...)
@@ -7846,7 +7673,7 @@ static void *UOBJC_SUPER_scope = 0;
_msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
} */
-tree
+static tree
get_super_receiver (void)
{
if (objc_method_context)
@@ -7855,18 +7682,13 @@ get_super_receiver (void)
if (!UOBJC_SUPER_decl)
{
- UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
- build_tree_list (NULL_TREE,
- objc_super_template),
- 0, NULL_TREE);
-
- finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
-
+ UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier
(TAG_SUPER),
+ objc_super_template);
/* This prevents `unused variable' warnings when compiling with
-Wall. */
TREE_USED (UOBJC_SUPER_decl) = 1;
- DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
-
- UOBJC_SUPER_scope = get_current_scope ();
+ lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
+ finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
+ UOBJC_SUPER_scope = objc_get_current_scope ();
}
/* Set receiver to self. */
@@ -7875,13 +7697,8 @@ get_super_receiver (void)
super_expr_list = super_expr;
/* Set class to begin searching. */
-#ifdef OBJCPLUS
super_expr = build_component_ref (UOBJC_SUPER_decl,
get_identifier ("super_class"));
-#else
- super_expr = build_component_ref (UOBJC_SUPER_decl,
- get_identifier ("class"));
-#endif
if (TREE_CODE (objc_implementation_context) ==
CLASS_IMPLEMENTATION_TYPE)
{
@@ -7911,7 +7728,7 @@ get_super_receiver (void)
if (flag_next_runtime && !flag_zero_link)
{
- super_class = get_class_reference (super_name);
+ super_class = objc_get_class_reference (super_name);
if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
/* If we are in a class method, we must retrieve the
_metaclass_ for the current class, pointed at by
@@ -7964,38 +7781,28 @@ void
objc_clear_super_receiver (void)
{
if (objc_method_context
- && UOBJC_SUPER_scope == get_current_scope ()) {
+ && UOBJC_SUPER_scope == objc_get_current_scope ()) {
UOBJC_SUPER_decl = 0;
UOBJC_SUPER_scope = 0;
}
}
-static void
-objc_expand_function_end (void)
-{
- /* This routine may also get called for C functions, including those
- nested within ObjC methods. In such cases, method encoding is
- meaningless. */
- if (objc_method_context == NULL_TREE
- || DECL_INITIAL (objc_method_context) != current_function_decl)
- return;
-
- METHOD_ENCODING (objc_method_context)
- = encode_method_prototype (objc_method_context);
-}
-
void
-finish_method_def (void)
+objc_finish_method_definition (tree fndecl)
{
- lang_expand_function_end = objc_expand_function_end;
/* We cannot validly inline ObjC methods, at least not without a
language
extension to declare that a method need not be dynamically
dispatched, so suppress all thoughts of doing so. */
- DECL_INLINE (current_function_decl) = 0;
- DECL_UNINLINABLE (current_function_decl) = 1;
+ DECL_INLINE (fndecl) = 0;
+ DECL_UNINLINABLE (fndecl) = 1;
+#ifndef OBJCPLUS
+ /* The C++ front-end will have called finish_function() for us. */
finish_function ();
- lang_expand_function_end = NULL;
+#endif
+
+ METHOD_ENCODING (objc_method_context)
+ = encode_method_prototype (objc_method_context);
/* Required to implement _msgSuper. This must be done AFTER
finish_function,
since the optimizer may find "may be used before set" errors. */
@@ -8018,567 +7825,77 @@ lang_report_error_function (tree decl)
}
#endif
-static int
-is_complex_decl (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 (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_1 (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_1 (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 (TYPE_READONLY (decl) || TYPE_VOLATILE (decl))
- {
- if (TYPE_READONLY (decl))
- strcat (tmpbuf, " const");
- if (TYPE_VOLATILE (decl))
- strcat (tmpbuf, " volatile");
- if (str[0])
- strcat (tmpbuf, " ");
- }
- strcat (tmpbuf, str);
- strcpy (str, tmpbuf);
- }
-}
+/* Given a tree DECL node, produce a printable description of it in
the given
+ buffer, overwriting the buffer. */
static char *
-gen_declarator (tree decl, char *buf, const char *name)
+gen_declaration (tree decl, char *buf)
{
- 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;
- }
-}
+ buf[0] = '\0';
-static void
-gen_declspecs (tree declspecs, char *buf, int raw)
-{
- if (raw)
+ if (DECL_P (decl))
{
- tree chain;
+ gen_type_name (TREE_TYPE (decl), buf);
- for (chain = nreverse (copy_list (declspecs));
- chain; chain = TREE_CHAIN (chain))
+ if (DECL_NAME (decl))
{
- tree aspec = TREE_VALUE (chain);
-
- if (TREE_CODE (aspec) == IDENTIFIER_NODE)
- strcat (buf, IDENTIFIER_POINTER (aspec));
- else if (TREE_CODE (aspec) == RECORD_TYPE)
- {
- if (OBJC_TYPE_NAME (aspec))
- {
- tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
-
- if (! TREE_STATIC_TEMPLATE (aspec))
- strcat (buf, "struct ");
- strcat (buf, IDENTIFIER_POINTER (OBJC_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 (OBJC_TYPE_NAME (aspec))
- {
- if (! TREE_STATIC_TEMPLATE (aspec))
- strcat (buf, "union ");
- strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME
(aspec)));
- }
- else
- strcat (buf, "untagged union");
- }
-
- else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
- {
- if (OBJC_TYPE_NAME (aspec))
- {
- if (! TREE_STATIC_TEMPLATE (aspec))
- strcat (buf, "enum ");
- strcat (buf, IDENTIFIER_POINTER (OBJC_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))
+ if (!POINTER_TYPE_P (TREE_TYPE (decl)))
strcat (buf, " ");
- }
- }
- else
- {
- /* Type qualifiers. */
- if (TYPE_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 (OBJC_TYPE_NAME (declspecs)
- && TREE_CODE (OBJC_TYPE_NAME (declspecs)) ==
IDENTIFIER_NODE)
- {
- tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
-
- if (! TREE_STATIC_TEMPLATE (declspecs))
- strcat (buf, "struct ");
- strcat (buf, IDENTIFIER_POINTER (OBJC_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 (OBJC_TYPE_NAME (declspecs)
- && TREE_CODE (OBJC_TYPE_NAME (declspecs)) ==
IDENTIFIER_NODE)
- {
- strcat (buf, "union ");
- strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME
(declspecs)));
- strcat (buf, " ");
- }
-
- else
- strcat (buf, "untagged union ");
- break;
-
- case ENUMERAL_TYPE:
- if (OBJC_TYPE_NAME (declspecs)
- && TREE_CODE (OBJC_TYPE_NAME (declspecs)) ==
IDENTIFIER_NODE)
- {
- strcat (buf, "enum ");
- strcat (buf, IDENTIFIER_POINTER (OBJC_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;
+ strcat (buf, IDENTIFIER_POINTER (DECL_NAME (decl)));
}
+
+ if (DECL_INITIAL (decl)
+ && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
+ sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_DEC,
+ TREE_INT_CST_LOW (DECL_INITIAL (decl)));
}
+
+ return buf;
}
-/* Given a tree node, produce a printable description of it in the
given
+/* Given a tree TYPE node, produce a printable description of it in
the given
buffer, overwriting the buffer. */
static char *
-gen_declaration (tree atype_or_adecl, char *buf)
-{
- buf[0] = '\0';
- gen_declaration_1 (atype_or_adecl, buf);
- return buf;
-}
-
-/* Given a tree node, append a printable description to the end of the
- given buffer. */
-
-static void
-gen_declaration_1 (tree atype_or_adecl, char *buf)
+gen_type_name (tree type, char *buf)
{
- char declbuf[256];
+ tree orig = type, proto;
- if (TREE_CODE (atype_or_adecl) == TREE_LIST)
+ if (TYPE_P (type) && TYPE_NAME (type))
+ type = TYPE_NAME (type);
+ else if (POINTER_TYPE_P (type))
{
- tree declspecs; /* "identifier_node", "record_type" */
- tree declarator; /* "array_ref", "indirect_ref", "call_expr"...
*/
- tree width = NULL_TREE; /* for bitfields */
-
- /* We have a "raw", abstract declarator (typename). */
- declarator = TREE_VALUE (atype_or_adecl);
- /* In the case of raw ivars, the declarator itself is a list,
- and contains bitfield widths. */
- if (declarator && TREE_CODE (declarator) == TREE_LIST)
- {
- width = TREE_VALUE (declarator);
- declarator = TREE_PURPOSE (declarator);
- }
- declspecs = TREE_PURPOSE (atype_or_adecl);
+ gen_type_name (TREE_TYPE (type), buf);
+
+ if (!POINTER_TYPE_P (TREE_TYPE (type)))
+ strcat (buf, " ");
- gen_declspecs (declspecs, buf, 1);
- if (declarator)
- {
- strcat (buf, " ");
- strcat (buf, gen_declarator (declarator, declbuf, ""));
- }
- if (width)
- sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
- TREE_INT_CST_LOW (width));
+ strcat (buf, "*");
+ goto exit_function;
}
- 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 (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
+ type = DECL_NAME (type);
- 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;
- }
+ strcat (buf, IDENTIFIER_POINTER (type));
+ proto = TYPE_PROTOCOL_LIST (orig);
- 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)
- {
- const char *const 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));
- }
+ if (proto)
+ {
+ strcat (buf, " <");
- else if (decl_name[0])
- {
- strcat (buf, " ");
- strcat (buf, decl_name);
- }
- }
- else if (declarator)
- {
- strcat (buf, " ");
- strcat (buf, gen_declarator (declarator, declbuf, ""));
- }
+ while (proto) {
+ strcat (buf,
+ IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE
(proto))));
+ proto = TREE_CHAIN (proto);
+ strcat (buf, proto ? ", " : ">");
+ }
}
-}
-#define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE
(meth))))
+ exit_function:
+ return buf;
+}
/* Given a method tree, put a printable description into the given
buffer (overwriting) and return a pointer to the buffer. */
@@ -8588,13 +7905,9 @@ gen_method_decl (tree method, char *buf)
{
tree chain;
- buf[0] = '\0';
- if (RAW_TYPESPEC (method) != objc_object_reference)
- {
- strcat (buf, "(");
- gen_declaration_1 (TREE_TYPE (method), buf);
- strcat (buf, ")");
- }
+ strcpy (buf, "("); /* NB: Do _not_ call strcat() here. */
+ gen_type_name (TREE_VALUE (TREE_TYPE (method)), buf);
+ strcat (buf, ")");
chain = METHOD_SEL_ARGS (method);
if (chain)
@@ -8605,13 +7918,9 @@ gen_method_decl (tree method, char *buf)
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_1 (TREE_TYPE (chain), buf);
- strcat (buf, ")");
- }
+ strcat (buf, ":(");
+ gen_type_name (TREE_VALUE (TREE_TYPE (chain)), buf);
+ strcat (buf, ")");
strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
if ((chain = TREE_CHAIN (chain)))
@@ -8619,20 +7928,20 @@ gen_method_decl (tree method, char *buf)
}
while (chain);
- if (METHOD_ADD_ARGS (method) == objc_ellipsis_node)
- 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));
+ if (METHOD_ADD_ARGS (method))
+ {
+ chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
- /* Know we have a chain of parm_decls. */
- while (chain)
- {
+ /* Know we have a chain of parm_decls. */
+ while (chain)
+ {
strcat (buf, ", ");
- gen_declaration_1 (chain, buf);
+ gen_type_name (TREE_TYPE (TREE_VALUE (chain)), buf);
chain = TREE_CHAIN (chain);
- }
+ }
+
+ if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
+ strcat (buf, ", ...");
}
}
@@ -8855,13 +8164,14 @@ finish_objc (void)
if (flag_replace_objc_classes && imp_list)
generate_objc_image_info ();
+ /* Arrange for ObjC data structures to be initialized at run time.
*/
if (objc_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. */
- rtx init_sym = build_module_descriptor ();
- if (init_sym && targetm.have_ctors_dtors)
- (* targetm.asm_out.constructor) (init_sym,
DEFAULT_INIT_PRIORITY);
+ build_module_descriptor ();
+
+ if (!flag_next_runtime)
+ build_module_initializer_routine ();
}
/* Dump the class references. This forces the appropriate classes
@@ -8908,26 +8218,17 @@ finish_objc (void)
static void
generate_classref_translation_entry (tree chain)
{
- tree expr, name, decl_specs, decl, sc_spec;
- tree type;
+ tree expr, decl, type;
- type = TREE_TYPE (TREE_PURPOSE (chain));
+ decl = TREE_PURPOSE (chain);
+ type = TREE_TYPE (decl);
expr = add_objc_string (TREE_VALUE (chain), class_names);
- expr = build_c_cast (type, expr); /* cast! */
+ expr = convert (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
+ /* The decl that is the one that we
forward declared in build_class_reference. */
- decl = start_decl (name, decl_specs, 1, NULL_TREE);
- DECL_CONTEXT (decl) = NULL_TREE;
- finish_decl (decl, expr, NULL_TREE);
+ finish_var_decl (decl, expr);
return;
}
@@ -9042,32 +8343,24 @@ handle_impent (struct imp_entry *impent)
static void
generate_objc_image_info (void)
{
- tree sc_spec, decl, initlist;
+ tree decl, initlist;
- sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
- decl
- = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
- tree_cons (NULL_TREE,
- build_array_type
- (integer_type_node,
- build_index_type (build_int_cst
(NULL_TREE, 1, 0))),
- sc_spec),
- 1,
- NULL_TREE);
+ decl = start_var_decl (build_array_type
+ (integer_type_node,
+ build_index_type (build_int_cst (NULL_TREE,
1, 0))),
+ "_OBJC_IMAGE_INFO");
initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0,
0));
initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 1, 0),
initlist);
- initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
+ initlist = objc_build_constructor (TREE_TYPE (decl), nreverse
(initlist));
- TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) =
1;
- TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
- finish_decl (decl, initlist, NULL_TREE);
+ finish_var_decl (decl, initlist);
}
/* Look up ID as an instance variable. */
tree
-lookup_objc_ivar (tree id)
+objc_lookup_ivar (tree id)
{
tree decl;
Index: gcc/objc/objc-act.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.h,v
retrieving revision 1.27
diff -u -3 -p -r1.27 objc-act.h
--- gcc/objc/objc-act.h 15 Aug 2004 21:47:32 -0000 1.27
+++ gcc/objc/objc-act.h 16 Aug 2004 04:35:42 -0000
@@ -28,61 +28,12 @@ bool objc_init (void);
const char *objc_printable_name (tree, int);
void objc_finish_file (void);
-/* used by yyparse */
-
-tree start_class (enum tree_code, tree, tree, tree);
-tree continue_class (tree);
-void finish_class (tree);
-void start_method_def (tree);
-void continue_method_def (void);
-void finish_method_def (void);
-tree start_protocol (enum tree_code, tree, tree);
-void finish_protocol (tree);
-
-tree objc_build_throw_stmt (tree);
-void objc_begin_try_stmt (location_t, tree);
-void objc_begin_catch_clause (tree);
-void objc_finish_catch_clause (void);
-void objc_build_finally_clause (location_t, tree);
-void objc_finish_try_stmt (void);
-void objc_build_synchronized (location_t, tree, tree);
-
-tree is_ivar (tree, tree);
-int is_private (tree);
-int objc_is_public (tree, tree);
-tree add_instance_variable (tree, int, tree, tree, tree);
-tree objc_add_method (tree, tree, int);
-tree get_super_receiver (void);
-void objc_clear_super_receiver (void);
-tree get_class_ivars_from_name (tree);
-tree get_class_reference (tree);
-tree get_static_reference (tree, tree);
-tree get_protocol_reference (tree);
-tree build_message_expr (tree);
-tree finish_message_expr (tree, tree, tree);
-tree build_selector_expr (tree);
-tree build_ivar_reference (tree);
-tree build_keyword_decl (tree, tree, tree);
-tree build_method_decl (enum tree_code, tree, tree, tree);
-tree build_protocol_expr (tree);
-tree build_objc_string_object (tree);
-
-void objc_declare_alias (tree, tree);
-void objc_declare_class (tree);
-void objc_declare_protocols (tree);
-
-/* the following routines are used to implement statically typed
objects */
-
-int objc_comptypes (tree, tree, int);
-void objc_check_decl (tree);
-
-/* NeXT extensions */
-
-tree build_encode_expr (tree);
+/* NB: The remaining public functions are prototyped in c-common.h,
for the
+ benefit of stub-objc.c and objc-act.c. */
/* Objective-C structures */
-#define CLASS_LANG_SLOT_ELTS 6
+#define CLASS_LANG_SLOT_ELTS 5
#define PROTOCOL_LANG_SLOT_ELTS 2
/* KEYWORD_DECL */
@@ -108,13 +59,13 @@ tree build_encode_expr (tree);
#define CLASS_STATIC_TEMPLATE(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1
(CLASS), 2)
#define CLASS_CATEGORY_LIST(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1
(CLASS), 3)
#define CLASS_PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1
(CLASS), 4)
-#define CLASS_OWN_IVARS(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS),
5)
#define PROTOCOL_NAME(CLASS) ((CLASS)->type.name)
#define PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (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_LANG_SLOT_1
(CLASS), 1)
#define PROTOCOL_DEFINED(CLASS) TREE_USED (CLASS)
+
/* We need to distinguish TYPE_PROTOCOL_LISTs from TYPE_CONTEXTs, both
of which
are stored in the same accessor slot. */
#define TYPE_PROTOCOL_LIST(TYPE) \
@@ -123,12 +74,11 @@ tree build_encode_expr (tree);
? (TYPE)->type.context : NULL_TREE)
#define SET_TYPE_PROTOCOL_LIST(TYPE, P) (TYPE_CHECK
(TYPE)->type.context = (P))
-/* Set by `continue_class' and checked by `objc_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))
#define OBJC_TYPE_NAME(type) TYPE_NAME(type)
+#define OBJC_SET_TYPE_NAME(type, name) (TYPE_NAME (type) = name)
/* Define the Objective-C or Objective-C++ language-specific tree
codes. */
@@ -182,8 +132,11 @@ struct imp_entry GTY(())
};
extern GTY(()) struct imp_entry *imp_list;
-extern int imp_count; /* `@implementation' */
-extern int cat_count; /* `@category' */
+extern GTY(()) int imp_count; /* `@implementation' */
+extern GTY(()) int cat_count; /* `@category' */
+
+extern GTY(()) enum tree_code objc_inherit_code;
+extern GTY(()) int objc_public_flag;
/* Objective-C/Objective-C++ global tree enumeration. */
@@ -194,7 +147,6 @@ enum objc_tree_index
OCTI_SELF_ID,
OCTI_UCMD_ID,
OCTI_UNUSED_LIST,
- OCTI_ELLIPSIS_NODE,
OCTI_SELF_DECL,
OCTI_UMSG_DECL,
@@ -231,6 +183,7 @@ enum objc_tree_index
OCTI_MCLS_DECL,
OCTI_SEL_TABLE_DECL,
OCTI_MODULES_DECL,
+ OCTI_GNU_INIT_DECL,
OCTI_INTF_CTX,
OCTI_IMPL_CTX,
@@ -251,13 +204,15 @@ enum objc_tree_index
OCTI_MODULE_TEMPL,
OCTI_SUPER_TEMPL,
OCTI_OBJ_REF,
+ OCTI_CLS_REF,
OCTI_METH_PROTO_TEMPL,
OCTI_FUNCTION1_TEMPL,
OCTI_FUNCTION2_TEMPL,
OCTI_OBJ_ID,
OCTI_CLS_ID,
- OCTI_ID_ID,
+ OCTI_ID_NAME,
+ OCTI_CLASS_NAME,
OCTI_CNST_STR_ID,
OCTI_CNST_STR_TYPE,
OCTI_CNST_STR_GLOB_ID,
@@ -280,6 +235,7 @@ enum objc_tree_index
OCTI_RETHROW_EXCEPTION_DECL,
OCTI_EVAL_ONCE_DECL,
OCTI_CATCH_TYPE,
+ OCTI_EXECCLASS_DECL,
OCTI_MAX
};
@@ -297,7 +253,6 @@ extern GTY(()) tree objc_global_trees[OC
#define self_id objc_global_trees[OCTI_SELF_ID]
#define ucmd_id objc_global_trees[OCTI_UCMD_ID]
#define unused_list objc_global_trees[OCTI_UNUSED_LIST]
-#define objc_ellipsis_node objc_global_trees[OCTI_ELLIPSIS_NODE]
#define self_decl objc_global_trees[OCTI_SELF_DECL]
#define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
@@ -309,8 +264,8 @@ extern GTY(()) tree objc_global_trees[OC
objc_global_trees[OCTI_GET_MCLASS_DECL]
#define objc_super_type
objc_global_trees[OCTI_SUPER_TYPE]
-#define objc_selector_type objc_global_trees[OCTI_SEL_TYPE]
-#define objc_id_type objc_global_trees[OCTI_ID_TYPE]
+#define objc_selector_type objc_global_trees[OCTI_SEL_TYPE]
+#define objc_object_type objc_global_trees[OCTI_ID_TYPE]
#define objc_class_type objc_global_trees[OCTI_CLS_TYPE]
#define objc_instance_type objc_global_trees[OCTI_NST_TYPE]
#define objc_protocol_type objc_global_trees[OCTI_PROTO_TYPE]
@@ -318,11 +273,13 @@ extern GTY(()) tree objc_global_trees[OC
/* Type checking macros. */
#define IS_ID(TYPE) \
- (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (objc_id_type))
+ (POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == TREE_TYPE
(objc_object_type))
+#define IS_CLASS(TYPE) \
+ (POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == TREE_TYPE
(objc_class_type))
#define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
(IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
#define IS_SUPER(TYPE) \
- (TREE_CODE (TYPE) == POINTER_TYPE && TREE_TYPE (TYPE) ==
objc_super_template)
+ (POINTER_TYPE_P (TYPE) && TREE_TYPE (TYPE) == objc_super_template)
#define class_chain objc_global_trees[OCTI_CLS_CHAIN]
#define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
@@ -355,6 +312,7 @@ extern GTY(()) tree objc_global_trees[OC
#define UOBJC_METACLASS_decl
objc_global_trees[OCTI_MCLS_DECL]
#define UOBJC_SELECTOR_TABLE_decl
objc_global_trees[OCTI_SEL_TABLE_DECL]
#define UOBJC_MODULES_decl
objc_global_trees[OCTI_MODULES_DECL]
+#define GNU_INIT_decl
objc_global_trees[OCTI_GNU_INIT_DECL]
/* The following are used when compiling a class implementation.
implementation_template will normally be an interface, however if
@@ -400,12 +358,15 @@ extern GTY(()) tree objc_global_trees[OC
#define objc_eval_once objc_global_trees[OCTI_EVAL_ONCE_DECL]
#define objc_catch_type
objc_global_trees[OCTI_CATCH_TYPE]
+#define execclass_decl objc_global_trees[OCTI_EXECCLASS_DECL]
+
#define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
#define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
#define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
#define objc_module_template objc_global_trees[OCTI_MODULE_TEMPL]
#define objc_super_template objc_global_trees[OCTI_SUPER_TEMPL]
#define objc_object_reference objc_global_trees[OCTI_OBJ_REF]
+#define objc_class_reference objc_global_trees[OCTI_CLS_REF]
#define objc_method_prototype_template \
objc_global_trees[OCTI_METH_PROTO_TEMPL]
#define function1_template objc_global_trees[OCTI_FUNCTION1_TEMPL]
@@ -413,7 +374,8 @@ extern GTY(()) tree objc_global_trees[OC
#define objc_object_id objc_global_trees[OCTI_OBJ_ID]
#define objc_class_id objc_global_trees[OCTI_CLS_ID]
-#define objc_id_id objc_global_trees[OCTI_ID_ID]
+#define objc_object_name objc_global_trees[OCTI_ID_NAME]
+#define objc_class_name
objc_global_trees[OCTI_CLASS_NAME]
#define constant_string_id objc_global_trees[OCTI_CNST_STR_ID]
#define constant_string_type objc_global_trees[OCTI_CNST_STR_TYPE]
#define constant_string_global_id \
Index: gcc/testsuite/objc/execute/next_mapping.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc/execute/next_mapping.h,v
retrieving revision 1.3
diff -u -3 -p -r1.3 next_mapping.h
--- gcc/testsuite/objc/execute/next_mapping.h 7 Jun 2004 08:48:31
-0000 1.3
+++ gcc/testsuite/objc/execute/next_mapping.h 16 Aug 2004 04:35:57
-0000
@@ -1,6 +1,7 @@
/* This file "renames" various ObjC GNU runtime entry points
(and fakes the existence of several others)
if the NeXT runtime is being used. */
+
/* Authors: Ziemowit Laski <zlaski@apple.com> */
/* David Ayers <d.ayers@inode.at> */
@@ -8,6 +9,8 @@
#include <objc/objc-class.h>
#include <objc/Object.h>
#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
#define objc_get_class(C) objc_getClass(C)
#define objc_get_meta_class(C) objc_getMetaClass(C)
@@ -45,22 +48,15 @@
/* The following is necessary to "cover" the bf*.m test cases on NeXT.
*/
#undef MAX
-#define MAX(X, Y) \
- ({ typeof (X) __x = (X), __y = (Y); \
- (__x > __y ? __x : __y); })
-
+#define MAX(X, Y) ((X > Y) ? X : Y)
#undef MIN
-#define MIN(X, Y) \
- ({ typeof (X) __x = (X), __y = (Y); \
- (__x < __y ? __x : __y); })
-
+#define MIN(X, Y) ((X < Y) ? X : Y)
#undef ROUND
-#define ROUND(V, A) \
- ({ typeof (V) __v = (V); typeof (A) __a = (A); \
- __a * ((__v+__a - 1)/__a); })
+#define ROUND(V, A) (A * ((V + A - 1) / A))
#define BITS_PER_UNIT __CHAR_BIT__
-#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char
a;}))
+typedef struct{char a; } __small_struct;
+#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof
(__small_struct))
/* Not sure why the following are missing from NeXT objc headers... */
@@ -104,7 +100,7 @@ struct objc_struct_layout
unsigned int record_align;
};
-typedef union {
+typedef union arglist {
char *arg_ptr;
char arg_regs[sizeof (char*)];
} *arglist_t; /* argument frame */
@@ -117,6 +113,7 @@ void objc_layout_structure (const char *
BOOL objc_layout_structure_next_member (struct objc_struct_layout
*layout);
void objc_layout_finish_structure (struct objc_struct_layout *layout,
unsigned int *size, unsigned int *align);
+int objc_aligned_size (const char *type);
/*
return the size of an object specified by type
@@ -135,73 +132,53 @@ 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_LNG_LNG:
return sizeof (long long);
- break;
case _C_ULNG_LNG:
return sizeof (unsigned long 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:
{
@@ -210,7 +187,6 @@ objc_sizeof_type (const char *type)
;
return len * objc_aligned_size (type);
}
- break;
case _C_BFLD:
{
@@ -252,6 +228,7 @@ objc_sizeof_type (const char *type)
return max_size;
}
}
+
return 0; /* error */
}
@@ -269,63 +246,50 @@ objc_alignof_type (const char *type)
for (type++; *type++ != '"';)
/* do nothing */;
}
+
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:
case _C_BFLD: /* This is for the NeXT only */
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_LNG_LNG:
return __alignof__ (long long);
- break;
case _C_ULNG_LNG:
return __alignof__ (unsigned long long);
- break;
case _C_FLT:
return __alignof__ (float);
- break;
case _C_DBL:
return __alignof__ (double);
@@ -374,6 +338,7 @@ objc_alignof_type (const char *type)
return maxalign;
}
}
+
return 0; /* error */
}
@@ -497,7 +462,6 @@ objc_skip_typespec (const char *type)
case _C_VOID:
case _C_UNDEF:
return ++type;
- break;
case _C_ARY_B:
/* skip digits, typespec and closing ']' */
@@ -543,6 +507,7 @@ objc_skip_typespec (const char *type)
return objc_skip_typespec (++type);
}
+
return 0; /* error */
}
Index: gcc/testsuite/objc.dg/bitfield-2.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/bitfield-2.m,v
retrieving revision 1.3
diff -u -3 -p -r1.3 bitfield-2.m
--- gcc/testsuite/objc.dg/bitfield-2.m 25 Sep 2003 01:26:00 -0000
1.3
+++ gcc/testsuite/objc.dg/bitfield-2.m 16 Aug 2004 04:35:57 -0000
@@ -4,7 +4,7 @@
/* { dg-options "-fnext-runtime -fsigned-char" } */
/* { dg-do run { target *-*-darwin* } } */
-struct objc_object { struct objc_class *class_pointer; } *id;
+typedef struct objc_object { struct objc_class *class_pointer; } *id;
extern void abort(void);
extern int strcmp(const char *, const char *);
Index: gcc/testsuite/objc.dg/bitfield-4.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/bitfield-4.m,v
retrieving revision 1.2
diff -u -3 -p -r1.2 bitfield-4.m
--- gcc/testsuite/objc.dg/bitfield-4.m 25 Sep 2003 01:26:00 -0000
1.2
+++ gcc/testsuite/objc.dg/bitfield-4.m 16 Aug 2004 04:35:57 -0000
@@ -19,11 +19,10 @@
@implementation WithBitfields {
char *isa; /* { dg-error "conflicting instance variable type .char
\\*isa." } */
/* { dg-error "previous declaration of .void \\*isa." "" { target
*-*-* } 12 } */
- unsigned a: 5; /* { dg-error "conflicting instance variable type
.unsigned a: 5." } */
- /* { dg-error "previous declaration of .unsigned a: 3." "" { target
*-*-* } 13 } */
+ unsigned a: 5; /* { dg-error "conflicting instance variable type
.unsigned( int)? a: 5." } */
+ /* { dg-error "previous declaration of .unsigned( int)? a: 3." "" {
target *-*-* } 13 } */
signed b: 4; /* This one is fine. */
int c: 3; /* { dg-error "conflicting instance variable type .int c:
3." } */
/* { dg-error "previous declaration of .int c: 5." "" { target *-*-*
} 15 } */
}
@end
-
Index: gcc/testsuite/objc.dg/const-str-3.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/const-str-3.m,v
retrieving revision 1.2
diff -u -3 -p -r1.2 const-str-3.m
--- gcc/testsuite/objc.dg/const-str-3.m 25 Sep 2003 01:26:00 -0000
1.2
+++ gcc/testsuite/objc.dg/const-str-3.m 16 Aug 2004 04:35:57 -0000
@@ -6,6 +6,8 @@
/* { dg-do run { target *-*-darwin* } } */
#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
#include <objc/objc.h>
#include <objc/Object.h>
Index: gcc/testsuite/objc.dg/id-1.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/id-1.m,v
retrieving revision 1.2
diff -u -3 -p -r1.2 id-1.m
--- gcc/testsuite/objc.dg/id-1.m 2 Dec 2001 00:04:36 -0000
1.2
+++ gcc/testsuite/objc.dg/id-1.m 16 Aug 2004 04:35:57 -0000
@@ -1,6 +1,7 @@
-/* Test the id type warning. */
+/* Test attempt to redefine 'id' in an incompatible fashion. */
/* { dg-do compile } */
-typedef int id;
+typedef int id; /* { dg-error "conflicting types for .id." } */
+/* { dg-error "previous declaration of .id. was here" "" { target
*-*-* } 0 } */
-id b; /* { dg-warning "nexpected type for `id'" } */
+id b;
Index: gcc/testsuite/objc.dg/method-6.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/method-6.m,v
retrieving revision 1.3
diff -u -3 -p -r1.3 method-6.m
--- gcc/testsuite/objc.dg/method-6.m 3 Oct 2003 22:24:03 -0000
1.3
+++ gcc/testsuite/objc.dg/method-6.m 16 Aug 2004 04:35:57 -0000
@@ -19,7 +19,7 @@ void foo(void) {
Class receiver;
[receiver port]; /* { dg-warning "multiple methods named .\\+port.
found" } */
- /* { dg-warning "using .\\-\\(unsigned\\)port." "" { target
*-*-* } 9 } */
+ /* { dg-warning "using .\\-\\(unsigned( int)?\\)port." "" {
target *-*-* } 9 } */
/* { dg-warning "also found .\\+\\(Protocol \\*\\)port." "" {
target *-*-* } 14 } */
[receiver starboard]; /* { dg-warning ".Class. may not respond to
.\\+starboard." } */
Index: gcc/testsuite/objc.dg/proto-qual-1.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/proto-qual-1.m,v
retrieving revision 1.3
diff -u -3 -p -r1.3 proto-qual-1.m
--- gcc/testsuite/objc.dg/proto-qual-1.m 29 Jan 2004 03:14:35
-0000 1.3
+++ gcc/testsuite/objc.dg/proto-qual-1.m 16 Aug 2004 04:35:57
-0000
@@ -43,10 +43,10 @@ static void scan_initial(const char *pat
int main(void) {
meth = [proto descriptionForInstanceMethod:
@selector(address:with:)];
- scan_initial("O@%u@%u:%uNR@%uo^^S%u");
+ scan_initial("O@%u@%u:%uRN@%uo^^S%u");
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 +
aligned_sizeof(unsigned));
meth = [proto descriptionForClassMethod:
@selector(retainArgument:with:)];
- scan_initial("Vv%u@%u:%uOo@%un^*%u");
+ scan_initial("Vv%u@%u:%uoO@%un^*%u");
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 +
aligned_sizeof(char **));
return 0;
}
Index: gcc/testsuite/objc.dg/type-size-2.m
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/objc.dg/type-size-2.m,v
retrieving revision 1.2
diff -u -3 -p -r1.2 type-size-2.m
--- gcc/testsuite/objc.dg/type-size-2.m 25 Sep 2003 01:26:01 -0000
1.2
+++ gcc/testsuite/objc.dg/type-size-2.m 16 Aug 2004 04:35:57 -0000
@@ -1,6 +1,6 @@
/* Make sure that array arguments to methods are given the size of
pointers. */
/* As in the case of ivars, arrays without size (e.g., 'int []') are
- encoded as pointers as well. */
+ encoded as pointers. */
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
/* { dg-do run } */
Index: gcc/testsuite/objc.dg/va-meth-1.m
===================================================================
RCS file: gcc/testsuite/objc.dg/va-meth-1.m
diff -N gcc/testsuite/objc.dg/va-meth-1.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/objc.dg/va-meth-1.m 16 Aug 2004 04:35:57 -0000
@@ -0,0 +1,69 @@
+/* Based on objc/execute/va_method.m, by Nicola Pero */
+/* { dg-do run } */
+
+#include <objc/Object.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+/* Test methods with "C-style" trailing arguments, with or without
ellipsis. */
+
+@interface MathClass: Object
+/* sum positive numbers; -1 ends the list */
++ (int) sum: (int)firstNumber, int secondNumber, ...;
++ (int) prod: (int) firstNumber, int secondNumber, int thirdNumber;
++ (int) minimum: (int) firstNumber, ...;
+@end
+
+@implementation MathClass
++ (int) sum: (int)firstNumber, int secondNumber, ...
+{
+ va_list ap;
+ int sum = 0, number = 0;
+
+ va_start (ap, secondNumber);
+ number = firstNumber + secondNumber;
+
+ while (number >= 0)
+ {
+ sum += number;
+ number = va_arg (ap, int);
+ }
+
+ va_end (ap);
+
+ return sum;
+}
++ (int) prod: (int) firstNumber, int secondNumber, int thirdNumber {
+ return firstNumber * secondNumber * thirdNumber;
+}
++ (int) minimum: (int)firstNumber, ...
+{
+ va_list ap;
+ int minimum = 999, number = 0;
+
+ va_start (ap, firstNumber);
+ number = firstNumber;
+
+ while (number >= 0)
+ {
+ minimum = (minimum < number ? minimum: number);
+ number = va_arg (ap, int);
+ }
+
+ va_end (ap);
+
+ return minimum;
+}
+@end
+
+int main (void)
+{
+ if ([MathClass sum: 1, 2, 3, 4, 5, -1] != 15)
+ abort ();
+ if ([MathClass prod: 4, 5, 6] != 120)
+ abort ();
+ if ([MathClass minimum: 17, 9, 133, 84, 35, -1] != 9)
+ abort ();
+
+ return 0;
+}
More information about the Gcc-patches
mailing list