d3dcompiler: Parse variable references in expressions.
This commit is contained in:
parent
887ef49419
commit
96470dfcb4
|
@ -684,6 +684,7 @@ enum hlsl_ir_node_type
|
||||||
{
|
{
|
||||||
HLSL_IR_VAR = 0,
|
HLSL_IR_VAR = 0,
|
||||||
HLSL_IR_CONSTANT,
|
HLSL_IR_CONSTANT,
|
||||||
|
HLSL_IR_DEREF,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hlsl_ir_node
|
struct hlsl_ir_node
|
||||||
|
@ -722,6 +723,33 @@ struct hlsl_ir_var
|
||||||
struct hlsl_var_allocation *allocation;
|
struct hlsl_var_allocation *allocation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum hlsl_ir_deref_type
|
||||||
|
{
|
||||||
|
HLSL_IR_DEREF_VAR,
|
||||||
|
HLSL_IR_DEREF_ARRAY,
|
||||||
|
HLSL_IR_DEREF_RECORD,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hlsl_ir_deref
|
||||||
|
{
|
||||||
|
struct hlsl_ir_node node;
|
||||||
|
enum hlsl_ir_deref_type type;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct hlsl_ir_var *var;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct hlsl_ir_node *array;
|
||||||
|
struct hlsl_ir_node *index;
|
||||||
|
} array;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct hlsl_ir_node *record;
|
||||||
|
const char *field;
|
||||||
|
} record;
|
||||||
|
} v;
|
||||||
|
};
|
||||||
|
|
||||||
struct hlsl_ir_constant
|
struct hlsl_ir_constant
|
||||||
{
|
{
|
||||||
struct hlsl_ir_node node;
|
struct hlsl_ir_node node;
|
||||||
|
@ -779,6 +807,12 @@ extern struct hlsl_parse_ctx hlsl_ctx DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
void hlsl_message(const char *fmt, ...) PRINTF_ATTR(1,2) DECLSPEC_HIDDEN;
|
void hlsl_message(const char *fmt, ...) PRINTF_ATTR(1,2) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
static inline struct hlsl_ir_deref *deref_from_node(const struct hlsl_ir_node *node)
|
||||||
|
{
|
||||||
|
assert(node->type == HLSL_IR_DEREF);
|
||||||
|
return CONTAINING_RECORD(node, struct hlsl_ir_deref, node);
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct hlsl_ir_constant *constant_from_node(const struct hlsl_ir_node *node)
|
static inline struct hlsl_ir_constant *constant_from_node(const struct hlsl_ir_node *node)
|
||||||
{
|
{
|
||||||
assert(node->type == HLSL_IR_CONSTANT);
|
assert(node->type == HLSL_IR_CONSTANT);
|
||||||
|
|
|
@ -124,6 +124,7 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
|
||||||
BOOL boolval;
|
BOOL boolval;
|
||||||
char *name;
|
char *name;
|
||||||
DWORD modifiers;
|
DWORD modifiers;
|
||||||
|
struct hlsl_ir_var *var;
|
||||||
struct hlsl_ir_node *instr;
|
struct hlsl_ir_node *instr;
|
||||||
struct list *list;
|
struct list *list;
|
||||||
struct parse_variable_def *variable_def;
|
struct parse_variable_def *variable_def;
|
||||||
|
@ -243,6 +244,7 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
|
||||||
%type <instr> initializer_expr
|
%type <instr> initializer_expr
|
||||||
%type <modifiers> var_modifiers
|
%type <modifiers> var_modifiers
|
||||||
%type <instr> expr
|
%type <instr> expr
|
||||||
|
%type <var> variable
|
||||||
%type <intval> array
|
%type <intval> array
|
||||||
%type <name> semantic
|
%type <name> semantic
|
||||||
%type <variable_def> variable_def
|
%type <variable_def> variable_def
|
||||||
|
@ -544,11 +546,30 @@ primary_expr: C_FLOAT
|
||||||
c->v.value.b[0] = $1;
|
c->v.value.b[0] = $1;
|
||||||
$$ = &c->node;
|
$$ = &c->node;
|
||||||
}
|
}
|
||||||
|
| variable
|
||||||
|
{
|
||||||
|
struct hlsl_ir_deref *deref = new_var_deref($1);
|
||||||
|
$$ = deref ? &deref->node : NULL;
|
||||||
|
}
|
||||||
| '(' expr ')'
|
| '(' expr ')'
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable: VAR_IDENTIFIER
|
||||||
|
{
|
||||||
|
struct hlsl_ir_var *var;
|
||||||
|
var = get_variable(hlsl_ctx.cur_scope, $1);
|
||||||
|
if (!var)
|
||||||
|
{
|
||||||
|
hlsl_message("Line %d: variable '%s' not declared\n",
|
||||||
|
hlsl_ctx.line_no, $1);
|
||||||
|
set_parse_status(&hlsl_ctx.status, PARSE_ERR);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
$$ = var;
|
||||||
|
}
|
||||||
|
|
||||||
postfix_expr: primary_expr
|
postfix_expr: primary_expr
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
|
|
|
@ -844,6 +844,22 @@ BOOL find_function(const char *name)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var)
|
||||||
|
{
|
||||||
|
struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
|
||||||
|
|
||||||
|
if (!deref)
|
||||||
|
{
|
||||||
|
ERR("Out of memory.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
deref->node.type = HLSL_IR_DEREF;
|
||||||
|
deref->node.data_type = var->node.data_type;
|
||||||
|
deref->type = HLSL_IR_DEREF_VAR;
|
||||||
|
deref->v.var = var;
|
||||||
|
return deref;
|
||||||
|
}
|
||||||
|
|
||||||
void push_scope(struct hlsl_parse_ctx *ctx)
|
void push_scope(struct hlsl_parse_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct hlsl_scope *new_scope = d3dcompiler_alloc(sizeof(*new_scope));
|
struct hlsl_scope *new_scope = d3dcompiler_alloc(sizeof(*new_scope));
|
||||||
|
@ -951,6 +967,7 @@ const char *debug_node_type(enum hlsl_ir_node_type type)
|
||||||
{
|
{
|
||||||
"HLSL_IR_VAR",
|
"HLSL_IR_VAR",
|
||||||
"HLSL_IR_CONSTANT",
|
"HLSL_IR_CONSTANT",
|
||||||
|
"HLSL_IR_DEREF",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (type > sizeof(names) / sizeof(names[0]))
|
if (type > sizeof(names) / sizeof(names[0]))
|
||||||
|
@ -1010,6 +1027,25 @@ static void free_ir_constant(struct hlsl_ir_constant *constant)
|
||||||
d3dcompiler_free(constant);
|
d3dcompiler_free(constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void free_ir_deref(struct hlsl_ir_deref *deref)
|
||||||
|
{
|
||||||
|
switch (deref->type)
|
||||||
|
{
|
||||||
|
case HLSL_IR_DEREF_VAR:
|
||||||
|
/* Variables are shared among nodes in the tree. */
|
||||||
|
break;
|
||||||
|
case HLSL_IR_DEREF_ARRAY:
|
||||||
|
free_instr(deref->v.array.array);
|
||||||
|
free_instr(deref->v.array.index);
|
||||||
|
break;
|
||||||
|
case HLSL_IR_DEREF_RECORD:
|
||||||
|
free_instr(deref->v.record.record);
|
||||||
|
d3dcompiler_free((void *)deref->v.record.field);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
d3dcompiler_free(deref);
|
||||||
|
}
|
||||||
|
|
||||||
void free_instr(struct hlsl_ir_node *node)
|
void free_instr(struct hlsl_ir_node *node)
|
||||||
{
|
{
|
||||||
switch (node->type)
|
switch (node->type)
|
||||||
|
@ -1020,6 +1056,9 @@ void free_instr(struct hlsl_ir_node *node)
|
||||||
case HLSL_IR_CONSTANT:
|
case HLSL_IR_CONSTANT:
|
||||||
free_ir_constant(constant_from_node(node));
|
free_ir_constant(constant_from_node(node));
|
||||||
break;
|
break;
|
||||||
|
case HLSL_IR_DEREF:
|
||||||
|
free_ir_deref(deref_from_node(node));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
FIXME("Unsupported node type %s\n", debug_node_type(node->type));
|
FIXME("Unsupported node type %s\n", debug_node_type(node->type));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue