mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 05:00:35 +00:00
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:
parent
15ba4091bc
commit
4481ba9b0d
5 changed files with 45 additions and 2 deletions
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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
|
||||
|
|
2
tools/qfcc/test/reference.r
Normal file
2
tools/qfcc/test/reference.r
Normal file
|
@ -0,0 +1,2 @@
|
|||
@reference Array(Private);
|
||||
@reference Foo;
|
Loading…
Reference in a new issue