mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 13:11:00 +00:00
[qfcc] Create glsl block before parsing members
This allows attributes to be put on the block before members are declared thus giving member attributes to override block attributes when appropriate.
This commit is contained in:
parent
f7f2790937
commit
db39fdbe37
5 changed files with 71 additions and 37 deletions
|
@ -69,8 +69,9 @@ extern const char *glsl_interface_names[glsl_num_interfaces];
|
|||
|
||||
typedef struct glsl_block_s {
|
||||
struct glsl_block_s *next;
|
||||
const char *name;
|
||||
attribute_t *attributes;
|
||||
symbol_t *name;
|
||||
glsl_interface_t interface;
|
||||
symtab_t *attributes;
|
||||
symtab_t *members;
|
||||
symbol_t *instance_name;
|
||||
} glsl_block_t;
|
||||
|
@ -88,8 +89,9 @@ extern glsl_sublang_t glsl_geom_sublanguage;
|
|||
extern glsl_sublang_t glsl_frag_sublanguage;
|
||||
|
||||
void glsl_block_clear (void);
|
||||
void glsl_declare_block (specifier_t spec, symbol_t *block_sym,
|
||||
symbol_t *instance_name);
|
||||
glsl_block_t *glsl_create_block (specifier_t spec, symbol_t *block_sym);
|
||||
void glsl_finish_block (glsl_block_t *block);
|
||||
void glsl_declare_block_instance (glsl_block_t *block, symbol_t *instance_name);
|
||||
glsl_block_t *glsl_get_block (const char *name, glsl_interface_t interface);
|
||||
symtab_t *glsl_optimize_attributes (attribute_t *attributes);
|
||||
void glsl_apply_attributes (symtab_t *attributes, specifier_t spec);
|
||||
|
|
|
@ -110,6 +110,8 @@ typedef union rua_val_s {
|
|||
struct symtab_s *symtab;
|
||||
struct attribute_s *attribute;
|
||||
struct designator_s *designator;
|
||||
|
||||
struct glsl_block_s *block;
|
||||
} rua_val_t;
|
||||
|
||||
#include "tools/qfcc/source/qc-parse.h"
|
||||
|
|
|
@ -104,6 +104,7 @@ typedef struct symtab_s {
|
|||
struct class_s *class; ///< owning class if ivar scope
|
||||
symbol_t *(*procsymbol) (const char *name, struct symtab_s *symtab);
|
||||
void *procsymbol_data;
|
||||
void *data;
|
||||
} symtab_t;
|
||||
|
||||
const char *symtype_str (sy_type_e type) __attribute__((const));
|
||||
|
|
|
@ -48,7 +48,7 @@ static const char *
|
|||
block_get_key (const void *_b, void *)
|
||||
{
|
||||
auto b = (const glsl_block_t *) _b;
|
||||
return b->name;
|
||||
return b->name->name;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -68,12 +68,17 @@ glsl_block_clear (void)
|
|||
static const expr_t *
|
||||
block_sym_ref (symbol_t *sym, void *data)
|
||||
{
|
||||
return new_symbol_expr (data);
|
||||
sym = data;
|
||||
glsl_block_t *block = sym->table->data;
|
||||
auto interface = new_name_expr (glsl_interface_names[block->interface]);
|
||||
auto blk = new_symbol_expr (block->name);
|
||||
auto expr = field_expr (interface, blk);
|
||||
expr = field_expr (expr, new_symbol_expr (sym));
|
||||
return expr;
|
||||
}
|
||||
|
||||
void
|
||||
glsl_declare_block (specifier_t spec, symbol_t *block_sym,
|
||||
symbol_t *instance_name)
|
||||
glsl_block_t *
|
||||
glsl_create_block (specifier_t spec, symbol_t *block_sym)
|
||||
{
|
||||
auto interface = glsl_iftype_from_sc(spec.storage);
|
||||
hashtab_t *block_tab = nullptr;
|
||||
|
@ -81,17 +86,18 @@ glsl_declare_block (specifier_t spec, symbol_t *block_sym,
|
|||
block_tab = interfaces[interface];
|
||||
}
|
||||
if (!block_tab) {
|
||||
error (0, "invalid storage for block: %d", spec.storage);
|
||||
return;
|
||||
error (0, "invalid interface for block: %d", spec.storage);
|
||||
return nullptr;
|
||||
}
|
||||
glsl_block_t *block;
|
||||
ALLOC (64, glsl_block_t, blocks, block);
|
||||
*block = (glsl_block_t) {
|
||||
.name = save_string (block_sym->name),
|
||||
.attributes = spec.attributes,
|
||||
.members = block_sym->namespace,
|
||||
.instance_name = instance_name,
|
||||
.name = new_symbol (block_sym->name),
|
||||
.interface = interface,
|
||||
.attributes = glsl_optimize_attributes (spec.attributes),
|
||||
.members = new_symtab (current_symtab, stab_struct),
|
||||
};
|
||||
block->members->data = block;
|
||||
Hash_Add (block_tab, block);
|
||||
for (auto sym = block->members->symbols; sym; sym = sym->next) {
|
||||
auto def = new_def (sym->name, nullptr, nullptr, spec.storage);
|
||||
|
@ -99,11 +105,27 @@ glsl_declare_block (specifier_t spec, symbol_t *block_sym,
|
|||
sym->sy_type = sy_var;
|
||||
sym->def = def;
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
void
|
||||
glsl_finish_block (glsl_block_t *block)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
glsl_declare_block_instance (glsl_block_t *block, symbol_t *instance_name)
|
||||
{
|
||||
if (!block) {
|
||||
// error recovery
|
||||
return;
|
||||
}
|
||||
if (instance_name) {
|
||||
block->instance_name = instance_name;
|
||||
auto type = new_type ();
|
||||
*type = (type_t) {
|
||||
.type = ev_invalid,
|
||||
.name = save_string (block_sym->name),
|
||||
.name = save_string (block->name->name),
|
||||
.alignment = 4,
|
||||
.width = 1,
|
||||
.columns = 1,
|
||||
|
@ -113,7 +135,8 @@ glsl_declare_block (specifier_t spec, symbol_t *block_sym,
|
|||
instance_name->type = append_type (instance_name->type, type);
|
||||
instance_name->type = find_type (instance_name->type);
|
||||
auto space = current_symtab->space;// FIXME
|
||||
initialize_def (instance_name, nullptr, space, spec.storage,
|
||||
initialize_def (instance_name, nullptr, space,
|
||||
glsl_sc_from_iftype (block->interface),
|
||||
current_symtab);
|
||||
} else {
|
||||
for (auto sym = block->members->symbols; sym; sym = sym->next) {
|
||||
|
|
|
@ -167,7 +167,7 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc);
|
|||
%token <spec> DISCARD COHERENT
|
||||
|
||||
%type <symbol> variable_identifier
|
||||
%type <symbol> block_declaration
|
||||
%type <block> block_declaration
|
||||
%type <expr> constant_expression
|
||||
%type <expr> expression primary_exprsssion assignment_expression
|
||||
%type <expr> for_init_statement conditionopt expressionopt else
|
||||
|
@ -576,24 +576,21 @@ declaration
|
|||
}
|
||||
| type_qualifier block_declaration ';'
|
||||
{
|
||||
auto spec = $1;
|
||||
auto block = $2;
|
||||
glsl_declare_block (spec, block, nullptr);
|
||||
auto block = $block_declaration;
|
||||
glsl_declare_block_instance (block, nullptr);
|
||||
}
|
||||
| type_qualifier block_declaration IDENTIFIER ';'
|
||||
{
|
||||
auto spec = $1;
|
||||
auto block = $2;
|
||||
auto instance_name = $3;
|
||||
glsl_declare_block (spec, block, instance_name);
|
||||
auto block = $block_declaration;
|
||||
auto instance_name = $IDENTIFIER;
|
||||
glsl_declare_block_instance (block, instance_name);
|
||||
}
|
||||
| type_qualifier block_declaration IDENTIFIER array_specifier ';'
|
||||
{
|
||||
auto spec = $1;
|
||||
auto block = $2;
|
||||
auto instance_name = $3;
|
||||
instance_name->type = $4;
|
||||
glsl_declare_block (spec, block, instance_name);
|
||||
auto block = $block_declaration;
|
||||
auto instance_name = $IDENTIFIER;
|
||||
instance_name->type = $array_specifier;
|
||||
glsl_declare_block_instance (block, instance_name);
|
||||
}
|
||||
| type_qualifier ';'
|
||||
{
|
||||
|
@ -621,16 +618,25 @@ declaration
|
|||
block_declaration
|
||||
: IDENTIFIER '{'
|
||||
{
|
||||
auto block = new_symtab (current_symtab, stab_struct);
|
||||
current_symtab = block;
|
||||
auto spec = $<spec>0;
|
||||
auto block_sym = $IDENTIFIER;
|
||||
auto block = glsl_create_block (spec, block_sym);
|
||||
if (block) {
|
||||
current_symtab = block->members;
|
||||
}
|
||||
$<block>$ = block;
|
||||
}
|
||||
struct_declaration_list '}'
|
||||
{
|
||||
auto sym = $1;
|
||||
auto block = $<block>3;
|
||||
if (block) {
|
||||
current_symtab = block->members->parent;
|
||||
auto sym = $IDENTIFIER;
|
||||
glsl_finish_block (block);
|
||||
sym->sy_type = sy_namespace;
|
||||
sym->namespace = current_symtab;
|
||||
current_symtab = sym->namespace->parent;
|
||||
$$ = sym;
|
||||
}
|
||||
$$ = block;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
Loading…
Reference in a new issue