[PATCH 3/5] d3dcompiler: Parse function declarations.
Matteo Bruni
mbruni at codeweavers.com
Mon Jun 11 12:18:33 CDT 2012
---
dlls/d3dcompiler_43/d3dcompiler_private.h | 22 ++++++
dlls/d3dcompiler_43/hlsl.y | 104 ++++++++++++++++++++++++++++-
dlls/d3dcompiler_43/utils.c | 63 +++++++++++++++++-
3 files changed, 187 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 1c4b776..0fa3ac0 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -695,6 +695,7 @@ enum hlsl_ir_node_type
HLSL_IR_VAR = 0,
HLSL_IR_CONSTANT,
HLSL_IR_DEREF,
+ HLSL_IR_FUNCTION_DECL,
};
struct hlsl_ir_node
@@ -733,6 +734,15 @@ struct hlsl_ir_var
struct hlsl_var_allocation *allocation;
};
+struct hlsl_ir_function_decl
+{
+ struct hlsl_ir_node node;
+ const char *name;
+ const char *semantic;
+ struct list *parameters;
+ struct list *body;
+};
+
enum hlsl_ir_deref_type
{
HLSL_IR_DEREF_VAR,
@@ -787,6 +797,14 @@ struct hlsl_scope
};
/* Structures used only during parsing */
+struct parse_parameter
+{
+ struct hlsl_type *type;
+ const char *name;
+ const char *semantic;
+ unsigned int modifiers;
+};
+
struct parse_variable_def
{
struct list entry;
@@ -832,6 +850,7 @@ static inline struct hlsl_ir_constant *constant_from_node(const struct hlsl_ir_n
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;
+BOOL add_func_parameter(struct list *list, struct parse_parameter *param, unsigned int line) DECLSPEC_HIDDEN;
struct hlsl_type *new_hlsl_type(const char *name, enum hlsl_type_class type_class,
enum hlsl_base_type base_type, unsigned dimx, unsigned dimy) DECLSPEC_HIDDEN;
struct hlsl_type *new_array_type(struct hlsl_type *basic_type, unsigned int array_size) DECLSPEC_HIDDEN;
@@ -841,14 +860,17 @@ unsigned int components_count_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var) DECLSPEC_HIDDEN;
void push_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN;
BOOL pop_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN;
+struct hlsl_ir_function_decl *new_func_decl(const char *name, struct hlsl_type *return_type, struct list *parameters) DECLSPEC_HIDDEN;
struct bwriter_shader *parse_hlsl_shader(const char *text, enum shader_type type, DWORD version,
const char *entrypoint, char **messages) 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;
+void free_function(struct hlsl_ir_function_decl *func) DECLSPEC_HIDDEN;
#define MAKE_TAG(ch0, ch1, ch2, ch3) \
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index 7384e88..ce004f9 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -127,6 +127,8 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
struct hlsl_ir_var *var;
struct hlsl_ir_node *instr;
struct list *list;
+ struct hlsl_ir_function_decl *function;
+ struct parse_parameter parameter;
struct parse_variable_def *variable_def;
}
@@ -230,7 +232,7 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
%token <intval> PRE_LINE
%token <name> VAR_IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
-%type <name> any_identifier
+%type <name> any_identifier var_identifier
%token <name> STRING
%token <floatval> C_FLOAT
%token <intval> C_INTEGER
@@ -241,9 +243,14 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
%type <list> initializer_expr_list
%type <instr> initializer_expr
%type <modifiers> var_modifiers
+%type <list> parameters
+%type <list> param_list
%type <instr> expr
%type <var> variable
%type <intval> array
+%type <function> func_declaration
+%type <function> func_prototype
+%type <parameter> parameter
%type <name> semantic
%type <variable_def> variable_def
%type <list> variables_def
@@ -262,11 +269,17 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
%type <instr> logicor_expr
%type <instr> conditional_expr
%type <instr> assignment_expr
+%type <modifiers> input_mod
%%
hlsl_prog: /* empty */
{
}
+ | hlsl_prog func_declaration
+ {
+ FIXME("Check that the function doesn't conflict with an already declared one.\n");
+ list_add_tail(&hlsl_ctx.functions, &$2->node.entry);
+ }
| hlsl_prog declaration_statement
{
TRACE("Declaration statement parsed.\n");
@@ -287,6 +300,32 @@ any_identifier: VAR_IDENTIFIER
| TYPE_IDENTIFIER
| NEW_IDENTIFIER
+func_declaration: func_prototype ';'
+ {
+ TRACE("Function prototype for %s.\n", $1->name);
+ $$ = $1;
+ pop_scope(&hlsl_ctx);
+ }
+
+func_prototype: var_modifiers type var_identifier '(' parameters ')' semantic
+ {
+ $$ = new_func_decl($3, $2, $5);
+ if (!$$)
+ {
+ ERR("Out of memory.\n");
+ return -1;
+ }
+ $$->semantic = $7;
+ }
+
+scope_start: /* Empty */
+ {
+ push_scope(&hlsl_ctx);
+ }
+
+var_identifier: VAR_IDENTIFIER
+ | NEW_IDENTIFIER
+
semantic: /* Empty */
{
$$ = NULL;
@@ -296,6 +335,65 @@ semantic: /* Empty */
$$ = $2;
}
+parameters: scope_start
+ {
+ $$ = d3dcompiler_alloc(sizeof(*$$));
+ list_init($$);
+ }
+ | scope_start param_list
+ {
+ $$ = $2;
+ }
+
+param_list: parameter
+ {
+ $$ = d3dcompiler_alloc(sizeof(*$$));
+ list_init($$);
+ if (!add_func_parameter($$, &$1, hlsl_ctx.line_no))
+ {
+ ERR("Error adding function parameter %s.\n", $1.name);
+ set_parse_status(&hlsl_ctx.status, PARSE_ERR);
+ return -1;
+ }
+ }
+ | param_list ',' parameter
+ {
+ $$ = $1;
+ if (!add_func_parameter($$, &$3, hlsl_ctx.line_no))
+ {
+ hlsl_message("Line %u: duplicate parameter %s.\n",
+ hlsl_ctx.line_no, $3.name);
+ set_parse_status(&hlsl_ctx.status, PARSE_ERR);
+ return 1;
+ }
+ }
+
+parameter: input_mod var_modifiers type any_identifier semantic
+ {
+ $$.modifiers = $1;
+ $$.modifiers |= $2;
+ $$.type = $3;
+ $$.name = $4;
+ $$.semantic = $5;
+ }
+
+input_mod: /* Empty */
+ {
+ $$ = HLSL_MODIFIER_IN;
+ }
+ | KW_IN
+ {
+ $$ = HLSL_MODIFIER_IN;
+ }
+ | KW_OUT
+ {
+ $$ = HLSL_MODIFIER_OUT;
+ }
+ | KW_INOUT
+ {
+ $$ = HLSL_MODIFIER_IN | HLSL_MODIFIER_OUT;
+ }
+
type: base_type
{
$$ = $1;
@@ -714,6 +812,7 @@ expr: assignment_expr
struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const char *entrypoint, char **messages)
{
+ struct hlsl_ir_function_decl *function;
struct hlsl_scope *scope, *next_scope;
struct hlsl_type *hlsl_type, *next_type;
struct hlsl_ir_var *var, *next_var;
@@ -732,6 +831,9 @@ struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const ch
hlsl_parse();
d3dcompiler_free(hlsl_ctx.source_file);
+ TRACE("Freeing functions IR.\n");
+ LIST_FOR_EACH_ENTRY(function, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
+ free_function(function);
TRACE("Freeing variables.\n");
LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &hlsl_ctx.scopes, struct hlsl_scope, entry)
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index 6f8b013..53dd7f3 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -804,6 +804,31 @@ void free_declaration(struct hlsl_ir_var *decl)
d3dcompiler_free(decl);
}
+BOOL add_func_parameter(struct list *list, struct parse_parameter *param, unsigned int line)
+{
+ struct hlsl_ir_var *decl = d3dcompiler_alloc(sizeof(*decl));
+
+ if (!decl)
+ {
+ ERR("Out of memory.\n");
+ return FALSE;
+ }
+ decl->node.type = HLSL_IR_VAR;
+ decl->node.data_type = param->type;
+ decl->node.line = line;
+ decl->name = param->name;
+ decl->semantic = param->semantic;
+ decl->modifiers = param->modifiers;
+
+ if (!add_declaration(hlsl_ctx.cur_scope, decl, FALSE))
+ {
+ free_declaration(decl);
+ return FALSE;
+ }
+ list_add_tail(list, &decl->node.entry);
+ return TRUE;
+}
+
struct hlsl_type *new_hlsl_type(const char *name, enum hlsl_type_class type_class,
enum hlsl_base_type base_type, unsigned dimx, unsigned dimy)
{
@@ -840,7 +865,13 @@ struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recu
BOOL find_function(const char *name)
{
- FIXME("stub.\n");
+ struct hlsl_ir_function_decl *func;
+
+ LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
+ {
+ if (!strcmp(func->name, name))
+ return TRUE;
+ }
return FALSE;
}
@@ -886,6 +917,24 @@ BOOL pop_scope(struct hlsl_parse_ctx *ctx)
return TRUE;
}
+struct hlsl_ir_function_decl *new_func_decl(const char *name, struct hlsl_type *return_type, struct list *parameters)
+{
+ struct hlsl_ir_function_decl *decl;
+
+ decl = d3dcompiler_alloc(sizeof(*decl));
+ if (!decl)
+ {
+ ERR("Out of memory.\n");
+ return NULL;
+ }
+ decl->node.type = HLSL_IR_FUNCTION_DECL;
+ decl->node.data_type = return_type;
+ decl->name = name;
+ decl->parameters = parameters;
+
+ return decl;
+}
+
static const char *debug_base_type(const struct hlsl_type *type)
{
const char *name = "(unknown)";
@@ -978,6 +1027,7 @@ static const char *debug_node_type(enum hlsl_ir_node_type type)
"HLSL_IR_VAR",
"HLSL_IR_CONSTANT",
"HLSL_IR_DEREF",
+ "HLSL_IR_FUNCTION_DECL",
};
if (type > sizeof(names) / sizeof(names[0]))
@@ -1073,3 +1123,14 @@ void free_instr(struct hlsl_ir_node *node)
FIXME("Unsupported node type %s\n", debug_node_type(node->type));
}
}
+
+void free_function(struct hlsl_ir_function_decl *func)
+{
+ struct hlsl_ir_var *param, *next_param;
+
+ d3dcompiler_free((void *)func->name);
+ d3dcompiler_free((void *)func->semantic);
+ LIST_FOR_EACH_ENTRY_SAFE(param, next_param, func->parameters, struct hlsl_ir_var, node.entry)
+ d3dcompiler_free(param);
+ d3dcompiler_free(func->parameters);
+}
--
1.7.3.4
More information about the wine-patches
mailing list