d3dcompiler: Parse function definitions.
This commit is contained in:
parent
552f10d0e8
commit
d2673848ea
|
@ -866,6 +866,7 @@ struct bwriter_shader *parse_hlsl_shader(const char *text, enum shader_type type
|
|||
|
||||
const char *debug_hlsl_type(const struct hlsl_type *type) DECLSPEC_HIDDEN;
|
||||
const char *debug_modifiers(DWORD modifiers) DECLSPEC_HIDDEN;
|
||||
void debug_dump_ir_function(const struct hlsl_ir_function_decl *func) DECLSPEC_HIDDEN;
|
||||
|
||||
void free_hlsl_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
|
||||
void free_instr(struct hlsl_ir_node *node) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -248,6 +248,9 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
|
|||
%type <instr> expr
|
||||
%type <var> variable
|
||||
%type <intval> array
|
||||
%type <list> statement
|
||||
%type <list> statement_list
|
||||
%type <list> compound_statement
|
||||
%type <function> func_declaration
|
||||
%type <function> func_prototype
|
||||
%type <parameter> parameter
|
||||
|
@ -269,6 +272,7 @@ static DWORD add_modifier(DWORD modifiers, DWORD mod)
|
|||
%type <instr> logicor_expr
|
||||
%type <instr> conditional_expr
|
||||
%type <instr> assignment_expr
|
||||
%type <list> expr_statement
|
||||
%type <modifiers> input_mod
|
||||
%%
|
||||
|
||||
|
@ -300,7 +304,14 @@ any_identifier: VAR_IDENTIFIER
|
|||
| TYPE_IDENTIFIER
|
||||
| NEW_IDENTIFIER
|
||||
|
||||
func_declaration: func_prototype ';'
|
||||
func_declaration: func_prototype compound_statement
|
||||
{
|
||||
TRACE("Function %s parsed.\n", $1->name);
|
||||
$$ = $1;
|
||||
$$->body = $2;
|
||||
pop_scope(&hlsl_ctx);
|
||||
}
|
||||
| func_prototype ';'
|
||||
{
|
||||
TRACE("Function prototype for %s.\n", $1->name);
|
||||
$$ = $1;
|
||||
|
@ -318,6 +329,17 @@ func_prototype: var_modifiers type var_identifier '(' parameters ')' s
|
|||
$$->semantic = $7;
|
||||
}
|
||||
|
||||
compound_statement: '{' '}'
|
||||
{
|
||||
$$ = d3dcompiler_alloc(sizeof(*$$));
|
||||
list_init($$);
|
||||
}
|
||||
| '{' scope_start statement_list '}'
|
||||
{
|
||||
pop_scope(&hlsl_ctx);
|
||||
$$ = $3;
|
||||
}
|
||||
|
||||
scope_start: /* Empty */
|
||||
{
|
||||
push_scope(&hlsl_ctx);
|
||||
|
@ -666,6 +688,44 @@ boolean: KW_TRUE
|
|||
$$ = FALSE;
|
||||
}
|
||||
|
||||
statement_list: statement
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| statement_list statement
|
||||
{
|
||||
$$ = $1;
|
||||
list_move_tail($$, $2);
|
||||
d3dcompiler_free($2);
|
||||
}
|
||||
|
||||
statement: declaration_statement
|
||||
{
|
||||
$$ = d3dcompiler_alloc(sizeof(*$$));
|
||||
list_init($$);
|
||||
}
|
||||
| expr_statement
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| compound_statement
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
expr_statement: ';'
|
||||
{
|
||||
$$ = d3dcompiler_alloc(sizeof(*$$));
|
||||
list_init($$);
|
||||
}
|
||||
| expr ';'
|
||||
{
|
||||
$$ = d3dcompiler_alloc(sizeof(*$$));
|
||||
list_init($$);
|
||||
if ($1)
|
||||
list_add_head($$, &$1->entry);
|
||||
}
|
||||
|
||||
primary_expr: C_FLOAT
|
||||
{
|
||||
struct hlsl_ir_constant *c = d3dcompiler_alloc(sizeof(*c));
|
||||
|
@ -830,6 +890,18 @@ struct bwriter_shader *parse_hlsl(enum shader_type type, DWORD version, const ch
|
|||
|
||||
hlsl_parse();
|
||||
|
||||
if (TRACE_ON(hlsl_parser))
|
||||
{
|
||||
struct hlsl_ir_function_decl *func;
|
||||
|
||||
TRACE("IR dump.\n");
|
||||
LIST_FOR_EACH_ENTRY(func, &hlsl_ctx.functions, struct hlsl_ir_function_decl, node.entry)
|
||||
{
|
||||
if (func->body)
|
||||
debug_dump_ir_function(func);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -770,8 +770,9 @@ BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL lo
|
|||
if (!strcmp(decl->name, var->name))
|
||||
return FALSE;
|
||||
}
|
||||
if (local_var)
|
||||
if (local_var && scope->upper->upper == hlsl_ctx.globals)
|
||||
{
|
||||
/* Check whether the variable redefines a function parameter. */
|
||||
LIST_FOR_EACH_ENTRY(var, &scope->upper->vars, struct hlsl_ir_var, scope_entry)
|
||||
{
|
||||
if (!strcmp(decl->name, var->name))
|
||||
|
@ -1037,6 +1038,125 @@ static const char *debug_node_type(enum hlsl_ir_node_type type)
|
|||
return names[type];
|
||||
}
|
||||
|
||||
static void debug_dump_instr(const struct hlsl_ir_node *instr);
|
||||
|
||||
static void debug_dump_ir_var(const struct hlsl_ir_var *var)
|
||||
{
|
||||
if (var->modifiers)
|
||||
TRACE("%s ", debug_modifiers(var->modifiers));
|
||||
TRACE("%s %s", debug_hlsl_type(var->node.data_type), var->name);
|
||||
if (var->semantic)
|
||||
TRACE(" : %s", debugstr_a(var->semantic));
|
||||
}
|
||||
|
||||
static void debug_dump_ir_deref(const struct hlsl_ir_deref *deref)
|
||||
{
|
||||
switch (deref->type)
|
||||
{
|
||||
case HLSL_IR_DEREF_VAR:
|
||||
TRACE("deref(");
|
||||
debug_dump_ir_var(deref->v.var);
|
||||
TRACE(")");
|
||||
break;
|
||||
case HLSL_IR_DEREF_ARRAY:
|
||||
debug_dump_instr(deref->v.array.array);
|
||||
TRACE("[");
|
||||
debug_dump_instr(deref->v.array.index);
|
||||
TRACE("]");
|
||||
break;
|
||||
case HLSL_IR_DEREF_RECORD:
|
||||
debug_dump_instr(deref->v.record.record);
|
||||
TRACE(".%s", debugstr_a(deref->v.record.field));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void debug_dump_ir_constant(const struct hlsl_ir_constant *constant)
|
||||
{
|
||||
struct hlsl_type *type = constant->node.data_type;
|
||||
unsigned int x, y;
|
||||
|
||||
if (type->dimy != 1)
|
||||
TRACE("{");
|
||||
for (y = 0; y < type->dimy; ++y)
|
||||
{
|
||||
if (type->dimx != 1)
|
||||
TRACE("{");
|
||||
for (x = 0; x < type->dimx; ++x)
|
||||
{
|
||||
switch (type->base_type)
|
||||
{
|
||||
case HLSL_TYPE_FLOAT:
|
||||
TRACE("%g ", (double)constant->v.value.f[y * type->dimx + x]);
|
||||
break;
|
||||
case HLSL_TYPE_DOUBLE:
|
||||
TRACE("%g ", constant->v.value.d[y * type->dimx + x]);
|
||||
break;
|
||||
case HLSL_TYPE_INT:
|
||||
TRACE("%d ", constant->v.value.i[y * type->dimx + x]);
|
||||
break;
|
||||
case HLSL_TYPE_UINT:
|
||||
TRACE("%u ", constant->v.value.u[y * type->dimx + x]);
|
||||
break;
|
||||
case HLSL_TYPE_BOOL:
|
||||
TRACE("%s ", constant->v.value.b[y * type->dimx + x] == FALSE ? "false" : "true");
|
||||
break;
|
||||
default:
|
||||
TRACE("Constants of type %s not supported\n", debug_base_type(type));
|
||||
}
|
||||
}
|
||||
if (type->dimx != 1)
|
||||
TRACE("}");
|
||||
}
|
||||
if (type->dimy != 1)
|
||||
TRACE("}");
|
||||
}
|
||||
|
||||
static void debug_dump_instr(const struct hlsl_ir_node *instr)
|
||||
{
|
||||
switch (instr->type)
|
||||
{
|
||||
case HLSL_IR_DEREF:
|
||||
debug_dump_ir_deref(deref_from_node(instr));
|
||||
break;
|
||||
case HLSL_IR_CONSTANT:
|
||||
debug_dump_ir_constant(constant_from_node(instr));
|
||||
break;
|
||||
default:
|
||||
TRACE("No dump function for %s\n", debug_node_type(instr->type));
|
||||
}
|
||||
}
|
||||
|
||||
static void debug_dump_instr_list(const struct list *list)
|
||||
{
|
||||
struct hlsl_ir_node *instr;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(instr, list, struct hlsl_ir_node, entry)
|
||||
{
|
||||
debug_dump_instr(instr);
|
||||
TRACE("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void debug_dump_ir_function(const struct hlsl_ir_function_decl *func)
|
||||
{
|
||||
struct hlsl_ir_var *param;
|
||||
|
||||
TRACE("Dumping function %s.\n", debugstr_a(func->name));
|
||||
TRACE("Function parameters:\n");
|
||||
LIST_FOR_EACH_ENTRY(param, func->parameters, struct hlsl_ir_var, node.entry)
|
||||
{
|
||||
debug_dump_ir_var(param);
|
||||
TRACE("\n");
|
||||
}
|
||||
if (func->semantic)
|
||||
TRACE("Function semantic: %s\n", debugstr_a(func->semantic));
|
||||
if (func->body)
|
||||
{
|
||||
debug_dump_instr_list(func->body);
|
||||
}
|
||||
}
|
||||
|
||||
void free_hlsl_type(struct hlsl_type *type)
|
||||
{
|
||||
struct hlsl_struct_field *field, *next_field;
|
||||
|
@ -1133,4 +1253,6 @@ void free_function(struct hlsl_ir_function_decl *func)
|
|||
LIST_FOR_EACH_ENTRY_SAFE(param, next_param, func->parameters, struct hlsl_ir_var, node.entry)
|
||||
d3dcompiler_free(param);
|
||||
d3dcompiler_free(func->parameters);
|
||||
free_instr_list(func->body);
|
||||
d3dcompiler_free(func->body);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue