diff options
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/ast.h | 6 | ||||
-rw-r--r-- | src/glsl/ast_function.cpp | 11 | ||||
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 80 |
3 files changed, 97 insertions, 0 deletions
diff --git a/src/glsl/ast.h b/src/glsl/ast.h index 4c314366133..67faacd0ef8 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -62,6 +62,8 @@ public: virtual ir_rvalue *hir(exec_list *instructions, struct _mesa_glsl_parse_state *state); + virtual bool has_sequence_subexpression() const; + /** * Retrieve the source location of an AST node * @@ -221,6 +223,8 @@ public: virtual void hir_no_rvalue(exec_list *instructions, struct _mesa_glsl_parse_state *state); + virtual bool has_sequence_subexpression() const; + ir_rvalue *do_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state, bool needs_rvalue); @@ -299,6 +303,8 @@ public: virtual void hir_no_rvalue(exec_list *instructions, struct _mesa_glsl_parse_state *state); + virtual bool has_sequence_subexpression() const; + private: /** * Is this function call actually a constructor? diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 6538992ae0e..b72eb3ffb9e 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -1999,6 +1999,17 @@ ast_function_expression::hir(exec_list *instructions, unreachable("not reached"); } +bool +ast_function_expression::has_sequence_subexpression() const +{ + foreach_list_typed(const ast_node, ast, link, &this->expressions) { + if (ast->has_sequence_subexpression()) + return true; + } + + return false; +} + ir_rvalue * ast_aggregate_initializer::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 0d83d02aa32..a5a9cc078f6 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1004,6 +1004,12 @@ ast_node::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) return NULL; } +bool +ast_node::has_sequence_subexpression() const +{ + return false; +} + void ast_function_expression::hir_no_rvalue(exec_list *instructions, struct _mesa_glsl_parse_state *state) @@ -1915,6 +1921,80 @@ ast_expression::do_hir(exec_list *instructions, return result; } +bool +ast_expression::has_sequence_subexpression() const +{ + switch (this->oper) { + case ast_plus: + case ast_neg: + case ast_bit_not: + case ast_logic_not: + case ast_pre_inc: + case ast_pre_dec: + case ast_post_inc: + case ast_post_dec: + return this->subexpressions[0]->has_sequence_subexpression(); + + case ast_assign: + case ast_add: + case ast_sub: + case ast_mul: + case ast_div: + case ast_mod: + case ast_lshift: + case ast_rshift: + case ast_less: + case ast_greater: + case ast_lequal: + case ast_gequal: + case ast_nequal: + case ast_equal: + case ast_bit_and: + case ast_bit_xor: + case ast_bit_or: + case ast_logic_and: + case ast_logic_or: + case ast_logic_xor: + case ast_array_index: + case ast_mul_assign: + case ast_div_assign: + case ast_add_assign: + case ast_sub_assign: + case ast_mod_assign: + case ast_ls_assign: + case ast_rs_assign: + case ast_and_assign: + case ast_xor_assign: + case ast_or_assign: + return this->subexpressions[0]->has_sequence_subexpression() || + this->subexpressions[1]->has_sequence_subexpression(); + + case ast_conditional: + return this->subexpressions[0]->has_sequence_subexpression() || + this->subexpressions[1]->has_sequence_subexpression() || + this->subexpressions[2]->has_sequence_subexpression(); + + case ast_sequence: + return true; + + case ast_field_selection: + case ast_identifier: + case ast_int_constant: + case ast_uint_constant: + case ast_float_constant: + case ast_bool_constant: + case ast_double_constant: + return false; + + case ast_aggregate: + unreachable("ast_aggregate: Should never get here."); + + case ast_function_call: + unreachable("should be handled by ast_function_expression::hir"); + } + + return false; +} ir_rvalue * ast_expression_statement::hir(exec_list *instructions, |