glsl: Add method to determine whether an expression contains the sequence operator
authorIan Romanick <ian.d.romanick@intel.com>
Wed, 7 Oct 2015 20:03:53 +0000 (13:03 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 12 Oct 2015 17:15:13 +0000 (10:15 -0700)
This will be used in the next patch to enforce some language sematics.

v2: Fix inverted logic in
ast_function_expression::has_sequence_subexpression.  The method
originally had a different name and a different meaning.  I fixed the
logic in ast_to_hir.cpp, but I only changed the names in
ast_function.cpp.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Marta Lofstedt <marta.lofstedt@intel.com> [v1]
Reviewed-by: Matt Turner <mattst88@gmail.com>
Cc: "10.6 11.0" <mesa-stable@lists.freedesktop.org>
src/glsl/ast.h
src/glsl/ast_function.cpp
src/glsl/ast_to_hir.cpp

index 4c31436613304081eed3e4b19f45bde8f139d88f..67faacd0ef85105b82816578f3852afdf0974410 100644 (file)
@@ -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?
index 6538992ae0eb9b5588a4d10a2f220b7546028093..b72eb3ffb9ee864a2ce9ff45da2c7cec189b7518 100644 (file)
@@ -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)
index 0d83d02aa325dc7dffae01fd8c2156a841cf96e1..a5a9cc078f62f747547060eaeafbf217e08a8905 100644 (file)
@@ -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,