Commit 552f10d0 authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

d3dcompiler: Parse function declarations.

parent 5e343752
......@@ -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) \
......
......@@ -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)
......
......@@ -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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment