[PATCH 4/5] d3dcompiler: Parse variable initializers, basic expressions.
Matteo Bruni
mbruni at codeweavers.com
Wed Jun 6 17:19:04 CDT 2012
---
dlls/d3dcompiler_43/d3dcompiler_private.h | 29 ++++
dlls/d3dcompiler_43/hlsl.y | 198 +++++++++++++++++++++++++++++
dlls/d3dcompiler_43/utils.c | 49 +++++++
3 files changed, 276 insertions(+), 0 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 77d81fe..cb322bc 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -33,6 +33,8 @@
#include "d3dcompiler.h"
+#include <assert.h>
+
/*
* This doesn't belong here, but for some functions it is possible to return that value,
* see http://msdn.microsoft.com/en-us/library/bb205278%28v=VS.85%29.aspx
@@ -681,6 +683,7 @@ struct hlsl_struct_field
enum hlsl_ir_node_type
{
HLSL_IR_VAR = 0,
+ HLSL_IR_CONSTANT,
};
struct hlsl_ir_node
@@ -719,6 +722,24 @@ struct hlsl_ir_var
struct hlsl_var_allocation *allocation;
};
+struct hlsl_ir_constant
+{
+ struct hlsl_ir_node node;
+ union
+ {
+ union
+ {
+ unsigned u[16];
+ int i[16];
+ float f[16];
+ double d[16];
+ BOOL b[16];
+ } value;
+ struct hlsl_ir_constant *array_elements;
+ struct list *struct_elements;
+ } v;
+};
+
struct hlsl_scope
{
struct list entry;
@@ -758,6 +779,12 @@ extern struct hlsl_parse_ctx hlsl_ctx DECLSPEC_HIDDEN;
void hlsl_message(const char *fmt, ...) PRINTF_ATTR(1,2) DECLSPEC_HIDDEN;
+static inline struct hlsl_ir_constant *constant_from_node(const struct hlsl_ir_node *node)
+{
+ assert(node->type == HLSL_IR_CONSTANT);
+ return CONTAINING_RECORD(node, struct hlsl_ir_constant, node);
+}
+
BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL local_var) DECLSPEC_HIDDEN;
struct hlsl_ir_var *get_variable(struct hlsl_scope *scope, const char *name) DECLSPEC_HIDDEN;
void free_declaration(struct hlsl_ir_var *decl) DECLSPEC_HIDDEN;
@@ -777,6 +804,8 @@ const char *debug_base_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
const char *debug_modifiers(DWORD modifiers) DECLSPEC_HIDDEN;
void free_hlsl_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
+void free_instr(struct hlsl_ir_node *node) DECLSPEC_HIDDEN;
+void free_instr_list(struct list *list) DECLSPEC_HIDDEN;
#define MAKE_TAG(ch0, ch1, ch2, ch3) \
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index 704d5d6..0057d5d 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -121,8 +121,10 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
struct hlsl_type *type;
INT intval;
FLOAT floatval;
+ BOOL boolval;
char *name;
DWORD modifiers;
+ struct hlsl_ir_node *instr;
struct list *list;
struct parse_variable_def *variable_def;
}
@@ -233,13 +235,33 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
%token <name> STRING
%token <floatval> C_FLOAT
%token <intval> C_INTEGER
+%type <boolval> boolean
%type <type> base_type
%type <type> type
+%type <list> complex_initializer
+%type <list> initializer_expr_list
+%type <instr> initializer_expr
%type <modifiers> var_modifiers
+%type <instr> expr
%type <intval> array
%type <name> semantic
%type <variable_def> variable_def
%type <list> variables_def
+%type <instr> primary_expr
+%type <instr> postfix_expr
+%type <instr> unary_expr
+%type <instr> mul_expr
+%type <instr> add_expr
+%type <instr> shift_expr
+%type <instr> relational_expr
+%type <instr> equality_expr
+%type <instr> bitand_expr
+%type <instr> bitxor_expr
+%type <instr> bitor_expr
+%type <instr> logicand_expr
+%type <instr> logicor_expr
+%type <instr> conditional_expr
+%type <instr> assignment_expr
%%
hlsl_prog: /* empty */
@@ -337,6 +359,7 @@ declaration: var_modifiers type variables_def ';'
if (v->initializer)
{
FIXME("Variable with an initializer.\n");
+ free_instr_list(v->initializer);
}
if (hlsl_ctx.cur_scope == hlsl_ctx.globals)
@@ -375,11 +398,26 @@ variable_def: any_identifier array semantic
$$->array_size = $2;
$$->semantic = $3;
}
+ | any_identifier array semantic '=' complex_initializer
+ {
+ TRACE("Declaration with initializer.\n");
+ $$ = d3dcompiler_alloc(sizeof(*$$));
+ $$->name = $1;
+ $$->array_size = $2;
+ $$->semantic = $3;
+ $$->initializer = $5;
+ }
array: /* Empty */
{
$$ = 0;
}
+ | '[' expr ']'
+ {
+ FIXME("Array.\n");
+ $$ = 0;
+ free_instr($2);
+ }
var_modifiers: /* Empty */
{
@@ -430,6 +468,166 @@ var_modifiers: /* Empty */
$$ = add_modifier($2, HLSL_MODIFIER_COLUMN_MAJOR);
}
+complex_initializer: initializer_expr
+ {
+ $$ = d3dcompiler_alloc(sizeof(*$$));
+ list_init($$);
+ list_add_head($$, &$1->entry);
+ }
+ | '{' initializer_expr_list '}'
+ {
+ $$ = $2;
+ }
+
+initializer_expr: assignment_expr
+ {
+ $$ = $1;
+ }
+
+initializer_expr_list: initializer_expr
+ {
+ $$ = d3dcompiler_alloc(sizeof(*$$));
+ list_init($$);
+ list_add_head($$, &$1->entry);
+ }
+ | initializer_expr_list ',' initializer_expr
+ {
+ $$ = $1;
+ list_add_tail($$, &$3->entry);
+ }
+
+boolean: KW_TRUE
+ {
+ $$ = TRUE;
+ }
+ | KW_FALSE
+ {
+ $$ = FALSE;
+ }
+
+primary_expr: C_FLOAT
+ {
+ struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
+ if (!c)
+ {
+ ERR("Out of memory.\n");
+ return -1;
+ }
+ c->node.type = HLSL_IR_CONSTANT;
+ c->node.data_type = new_hlsl_type("float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
+ c->v.value.f[0] = $1;
+ $$ = &c->node;
+ }
+ | C_INTEGER
+ {
+ struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
+ if (!c)
+ {
+ ERR("Out of memory.\n");
+ return -1;
+ }
+ c->node.type = HLSL_IR_CONSTANT;
+ c->node.data_type = new_hlsl_type("int", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
+ c->v.value.i[0] = $1;
+ $$ = &c->node;
+ }
+ | boolean
+ {
+ struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
+ if (!c)
+ {
+ ERR("Out of memory.\n");
+ return -1;
+ }
+ c->node.type = HLSL_IR_CONSTANT;
+ c->node.data_type = new_hlsl_type("bool", HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
+ c->v.value.b[0] = $1;
+ $$ = &c->node;
+ }
+ | '(' expr ')'
+ {
+ $$ = $2;
+ }
+
+postfix_expr: primary_expr
+ {
+ $$ = $1;
+ }
+
+unary_expr: postfix_expr
+ {
+ $$ = $1;
+ }
+
+mul_expr: unary_expr
+ {
+ $$ = $1;
+ }
+
+add_expr: mul_expr
+ {
+ $$ = $1;
+ }
+
+shift_expr: add_expr
+ {
+ $$ = $1;
+ }
+
+relational_expr: shift_expr
+ {
+ $$ = $1;
+ }
+
+equality_expr: relational_expr
+ {
+ $$ = $1;
+ }
+
+bitand_expr: equality_expr
+ {
+ $$ = $1;
+ }
+
+bitxor_expr: bitand_expr
+ {
+ $$ = $1;
+ }
+
+bitor_expr: bitxor_expr
+ {
+ $$ = $1;
+ }
+
+logicand_expr: bitor_expr
+ {
+ $$ = $1;
+ }
+
+logicor_expr: logicand_expr
+ {
+ $$ = $1;
+ }
+
+conditional_expr: logicor_expr
+ {
+ $$ = $1;
+ }
+
+assignment_expr: conditional_expr
+ {
+ $$ = $1;
+ }
+
+expr: assignment_expr
+ {
+ $$ = $1;
+ }
+ | expr ',' assignment_expr
+ {
+ FIXME("Comma expression\n");
+ }
+
%%
struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const char *entrypoint, char **messages)
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index 33cce05..b15a89a 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -950,6 +950,7 @@ const char *debug_node_type(enum hlsl_ir_node_type type)
const char *names[] =
{
"HLSL_IR_VAR",
+ "HLSL_IR_CONSTANT",
};
if (type > sizeof(names) / sizeof(names[0]))
@@ -975,3 +976,51 @@ void free_hlsl_type(struct hlsl_type *type)
}
d3dcompiler_free(type);
}
+
+void free_instr_list(struct list *list)
+{
+ struct hlsl_ir_node *node, *next_node;
+
+ if (!list)
+ return;
+ LIST_FOR_EACH_ENTRY_SAFE(node, next_node, list, struct hlsl_ir_node, entry)
+ free_instr(node);
+}
+
+static void free_ir_constant(struct hlsl_ir_constant *constant)
+{
+ struct hlsl_type *type = constant->node.data_type;
+ unsigned int i;
+ struct hlsl_ir_constant *field, *next_field;
+
+ switch (type->type)
+ {
+ case HLSL_CLASS_ARRAY:
+ for (i = 0; i < type->e.array.elements_count; ++i)
+ free_ir_constant(&constant->v.array_elements[i]);
+ d3dcompiler_free(constant->v.array_elements);
+ break;
+ case HLSL_CLASS_STRUCT:
+ LIST_FOR_EACH_ENTRY_SAFE(field, next_field, constant->v.struct_elements, struct hlsl_ir_constant, node.entry)
+ free_ir_constant(field);
+ break;
+ default:
+ break;
+ }
+ d3dcompiler_free(constant);
+}
+
+void free_instr(struct hlsl_ir_node *node)
+{
+ switch (node->type)
+ {
+ case HLSL_IR_VAR:
+ /* These are freed later on from the scopes. */
+ break;
+ case HLSL_IR_CONSTANT:
+ free_ir_constant(constant_from_node(node));
+ break;
+ default:
+ FIXME("Unsupported node type %s\n", debug_node_type(node->type));
+ }
+}
--
1.7.3.4
More information about the wine-patches
mailing list