Allow explicit references to classes and categories.

Use "@reference ClassName;" or "@reference ClassName(CategoryName);" to
create a refence to the class or category, forcing the defining object file
to be linked into the program when the object file is part of a library.
This commit is contained in:
Bill Currie 2010-12-12 20:27:56 +09:00
parent 15ba4091bc
commit 4481ba9b0d
5 changed files with 45 additions and 2 deletions

View file

@ -111,6 +111,8 @@ void category_add_protocols (category_t *category, protocollist_t *protocols);
void class_finish_module (void);
void class_to_struct (class_t *class, struct struct_s *strct);
void emit_class_ref (const char *class_name);
void emit_category_ref (const char *class_name, const char *category_name);
protocol_t *get_protocol (const char *name, int create);
void protocol_add_methods (protocol_t *protocol, struct methodlist_s *methods);

View file

@ -250,7 +250,7 @@ class_begin (class_type_t *class_type)
}
}
static void
void
emit_class_ref (const char *class_name)
{
def_t *def;
@ -283,6 +283,27 @@ emit_class_name (const char *class_name)
G_INT (def->ofs) = 0;
}
void
emit_category_ref (const char *class_name, const char *category_name)
{
def_t *def;
def_t *ref;
def = get_def (&type_pointer,
va (".obj_category_ref_%s_%s", class_name, category_name),
pr.scope, st_static);
if (def->initialized)
return;
def->initialized = def->constant = 1;
def->nosave = 1;
ref = get_def (&type_integer,
va (".obj_category_name_%s_%s", class_name, category_name),
pr.scope, st_extern);
if (!ref->external)
G_INT (def->ofs) = ref->ofs;
reloc_def_def (ref, def->ofs);
}
static void
emit_category_name (const char *class_name, const char *category_name)
{

View file

@ -306,6 +306,7 @@ static keyword_t keywords[] = {
{"@protected", PROTECTED, 0, 0, PROG_VERSION},
{"@protocol", PROTOCOL, 0, 0, PROG_VERSION},
{"@public", PUBLIC, 0, 0, PROG_VERSION},
{"@reference", REFERENCE, 0, 0, PROG_VERSION},
{"@selector", SELECTOR, 0, 0, PROG_VERSION},
{"@self", SELF, 0, 0, PROG_VERSION},
{"@this", THIS, 0, 0, PROG_VERSION},

View file

@ -162,7 +162,7 @@ expr_t *argv_expr (void);
%token <type> TYPE
%token <typename> TYPE_NAME
%token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE PROTECTED
%token PROTOCOL PUBLIC SELECTOR
%token PROTOCOL PUBLIC SELECTOR REFERENCE
%type <type> type non_field_type type_name def simple_def struct_def
%type <type> struct_def_item ivar_decl ivar_declarator def_item def_list
@ -1307,6 +1307,21 @@ new_category_name
}
;
class_reference
: identifier
{
emit_class_ref ($1);
}
;
category_reference
: identifier '(' identifier ')'
{
emit_category_ref ($1, $3);
}
;
protocol_name
: identifier
{
@ -1404,6 +1419,8 @@ classdef
}
| IMPLEMENTATION class_with_super { class_begin (&$2->class_type); }
| IMPLEMENTATION category_name { class_begin (&$2->class_type); }
| REFERENCE class_reference ';' { }
| REFERENCE category_reference ';' { }
;
protocoldef

View file

@ -0,0 +1,2 @@
@reference Array(Private);
@reference Foo;