glsl: fix block member alignment validation for vec3
[mesa.git] / src / compiler / glsl / ast.h
index ca98ed2834d0ad956015ce36e221a70c434912d5..94bcf644a26953291239104cdbbe710ec2e580cc 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  */
 
-#pragma once
 #ifndef AST_H
 #define AST_H
 
 #include "list.h"
 #include "glsl_parser_extras.h"
+#include "compiler/glsl_types.h"
+#include "util/bitset.h"
 
 struct _mesa_glsl_parse_state;
 
@@ -49,7 +50,7 @@ struct YYLTYPE;
  */
 class ast_node {
 public:
-   DECLARE_RALLOC_CXX_OPERATORS(ast_node);
+   DECLARE_LINEAR_ZALLOC_CXX_OPERATORS(ast_node);
 
    /**
     * Print an AST node in something approximating the original GLSL code
@@ -195,9 +196,20 @@ enum ast_operators {
    ast_float_constant,
    ast_bool_constant,
    ast_double_constant,
+   ast_int64_constant,
+   ast_uint64_constant,
 
    ast_sequence,
    ast_aggregate
+
+   /**
+    * Number of possible operators for an ast_expression
+    *
+    * This is done as a define instead of as an additional value in the enum so
+    * that the compiler won't generate spurious messages like "warning:
+    * enumeration value ‘ast_num_operators’ not handled in switch"
+    */
+   #define AST_NUM_OPERATORS (ast_aggregate + 1)
 };
 
 /**
@@ -246,6 +258,8 @@ public:
       unsigned uint_constant;
       int bool_constant;
       double double_constant;
+      uint64_t uint64_constant;
+      int64_t int64_constant;
    } primary_expression;
 
 
@@ -346,8 +360,8 @@ public:
 
    bool is_single_dimension() const
    {
-      return this->array_dimensions.tail_pred->prev != NULL &&
-             this->array_dimensions.tail_pred->prev->is_head_sentinel();
+      return this->array_dimensions.get_tail_raw()->prev != NULL &&
+             this->array_dimensions.get_tail_raw()->prev->is_head_sentinel();
    }
 
    virtual void print(void) const;
@@ -415,15 +429,6 @@ public:
                               struct _mesa_glsl_parse_state *state);
 };
 
-/**
- * Number of possible operators for an ast_expression
- *
- * This is done as a define instead of as an additional value in the enum so
- * that the compiler won't generate spurious messages like "warning:
- * enumeration value ‘ast_num_operators’ not handled in switch"
- */
-#define AST_NUM_OPERATORS (ast_sequence + 1)
-
 
 class ast_compound_statement : public ast_node {
 public:
@@ -459,10 +464,25 @@ enum {
    ast_precision_low
 };
 
+enum {
+   ast_depth_none = 0, /**< Absence of depth qualifier. */
+   ast_depth_any,
+   ast_depth_greater,
+   ast_depth_less,
+   ast_depth_unchanged
+};
+
 struct ast_type_qualifier {
    DECLARE_RALLOC_CXX_OPERATORS(ast_type_qualifier);
+   /* Note: this bitset needs to have at least as many bits as the 'q'
+    * struct has flags, below.  Previously, the size was 128 instead of 96.
+    * But an apparent bug in GCC 5.4.0 causes bad SSE code generation
+    * elsewhere, leading to a crash.  96 bits works around the issue.
+    * See https://bugs.freedesktop.org/show_bug.cgi?id=105497
+    */
+   DECLARE_BITSET_T(bitset_t, 96);
 
-   union {
+   union flags {
       struct {
         unsigned invariant:1;
          unsigned precise:1;
@@ -524,10 +544,7 @@ struct ast_type_qualifier {
 
          /** \name Layout qualifiers for GL_AMD_conservative_depth */
          /** \{ */
-         unsigned depth_any:1;
-         unsigned depth_greater:1;
-         unsigned depth_less:1;
-         unsigned depth_unchanged:1;
+         unsigned depth_type:1;
          /** \} */
 
         /** \name Layout qualifiers for GL_ARB_uniform_buffer_object */
@@ -552,6 +569,11 @@ struct ast_type_qualifier {
           */
          unsigned local_size:3;
 
+        /** \name Layout qualifiers for ARB_compute_variable_group_size. */
+        /** \{ */
+        unsigned local_size_variable:1;
+        /** \} */
+
         /** \name Layout and memory qualifiers for ARB_shader_image_load_store. */
         /** \{ */
         unsigned early_fragment_tests:1;
@@ -593,19 +615,59 @@ struct ast_type_qualifier {
          /** \name Qualifiers for GL_ARB_shader_subroutine */
         /** \{ */
          unsigned subroutine:1;  /**< Is this marked 'subroutine' */
-         unsigned subroutine_def:1; /**< Is this marked 'subroutine' with a list of types */
         /** \} */
+
+         /** \name Qualifiers for GL_KHR_blend_equation_advanced */
+         /** \{ */
+         unsigned blend_support:1; /**< Are there any blend_support_ qualifiers */
+         /** \} */
+
+         /**
+          * Flag set if GL_ARB_post_depth_coverage layout qualifier is used.
+          */
+         unsigned post_depth_coverage:1;
+
+         /**
+          * Flags for the layout qualifers added by ARB_fragment_shader_interlock
+          */
+
+         unsigned pixel_interlock_ordered:1;
+         unsigned pixel_interlock_unordered:1;
+         unsigned sample_interlock_ordered:1;
+         unsigned sample_interlock_unordered:1;
+
+         /**
+          * Flag set if GL_INTEL_conservartive_rasterization layout qualifier
+          * is used.
+          */
+         unsigned inner_coverage:1;
+
+         /** \name Layout qualifiers for GL_ARB_bindless_texture */
+         /** \{ */
+         unsigned bindless_sampler:1;
+         unsigned bindless_image:1;
+         unsigned bound_sampler:1;
+         unsigned bound_image:1;
+         /** \} */
+
+         /** \name Layout qualifiers for GL_EXT_shader_framebuffer_fetch_non_coherent */
+         /** \{ */
+         unsigned non_coherent:1;
+         /** \} */
       }
       /** \brief Set of flags, accessed by name. */
       q;
 
       /** \brief Set of flags, accessed as a bitmask. */
-      uint64_t i;
+      bitset_t i;
    } flags;
 
    /** Precision of the type (highp/medium/lowp). */
    unsigned precision:2;
 
+   /** Type of layout qualifiers for GL_AMD_conservative_depth. */
+   unsigned depth_type:3;
+
    /**
     * Alignment specified via GL_ARB_enhanced_layouts "align" layout qualifier
     */
@@ -684,7 +746,7 @@ struct ast_type_qualifier {
    ast_layout_expression *local_size[3];
 
    /** Tessellation evaluation shader: vertex spacing (equal, fractional even/odd) */
-   GLenum vertex_spacing;
+   enum gl_tess_spacing vertex_spacing;
 
    /** Tessellation evaluation shader: vertex ordering (CW or CCW) */
    GLenum ordering;
@@ -714,9 +776,6 @@ struct ast_type_qualifier {
     */
    glsl_base_type image_base_type;
 
-   /** Flag to know if this represents a default value for a qualifier */
-   bool is_default_qualifier;
-
    /**
     * Return true if and only if an interpolation qualifier is present.
     */
@@ -737,25 +796,58 @@ struct ast_type_qualifier {
     */
    bool has_auxiliary_storage() const;
 
+   /**
+    * Return true if and only if a memory qualifier is present.
+    */
+   bool has_memory() const;
+
+   /**
+    * Return true if the qualifier is a subroutine declaration.
+    */
+   bool is_subroutine_decl() const;
+
    bool merge_qualifier(YYLTYPE *loc,
                        _mesa_glsl_parse_state *state,
                         const ast_type_qualifier &q,
-                        bool is_single_layout_merge);
+                        bool is_single_layout_merge,
+                        bool is_multiple_layouts_merge = false);
+
+   /**
+    * Validate current qualifier against the global out one.
+    */
+   bool validate_out_qualifier(YYLTYPE *loc,
+                               _mesa_glsl_parse_state *state);
 
-   bool merge_out_qualifier(YYLTYPE *loc,
-                           _mesa_glsl_parse_state *state,
-                           const ast_type_qualifier &q,
-                           ast_node* &node, bool create_node);
+   /**
+    * Merge current qualifier into the global out one.
+    */
+   bool merge_into_out_qualifier(YYLTYPE *loc,
+                                 _mesa_glsl_parse_state *state,
+                                 ast_node* &node);
 
-   bool merge_in_qualifier(YYLTYPE *loc,
-                           _mesa_glsl_parse_state *state,
-                           const ast_type_qualifier &q,
-                           ast_node* &node, bool create_node);
+   /**
+    * Validate current qualifier against the global in one.
+    */
+   bool validate_in_qualifier(YYLTYPE *loc,
+                              _mesa_glsl_parse_state *state);
+
+   /**
+    * Merge current qualifier into the global in one.
+    */
+   bool merge_into_in_qualifier(YYLTYPE *loc,
+                                _mesa_glsl_parse_state *state,
+                                ast_node* &node);
+
+   /**
+    * Push pending layout qualifiers to the global values.
+    */
+   bool push_to_global(YYLTYPE *loc,
+                       _mesa_glsl_parse_state *state);
 
    bool validate_flags(YYLTYPE *loc,
                        _mesa_glsl_parse_state *state,
-                       const char *message,
-                       const ast_type_qualifier &allowed_flags);
+                       const ast_type_qualifier &allowed_flags,
+                       const char *message, const char *name);
 
    ast_subroutine_list *subroutine_list;
 };
@@ -765,7 +857,7 @@ class ast_declarator_list;
 class ast_struct_specifier : public ast_node {
 public:
    ast_struct_specifier(const char *identifier,
-                       ast_declarator_list *declarator_list);
+                        ast_declarator_list *declarator_list);
    virtual void print(void) const;
 
    virtual ir_rvalue *hir(exec_list *instructions,
@@ -776,6 +868,7 @@ public:
    /* List of ast_declarator_list * */
    exec_list declarations;
    bool is_declaration;
+   const glsl_type *type;
 };
 
 
@@ -784,7 +877,7 @@ class ast_type_specifier : public ast_node {
 public:
    /** Construct a type specifier from a type name */
    ast_type_specifier(const char *name) 
-      : type_name(name), structure(NULL), array_specifier(NULL),
+      : type(NULL), type_name(name), structure(NULL), array_specifier(NULL),
        default_precision(ast_precision_none)
    {
       /* empty */
@@ -792,12 +885,19 @@ public:
 
    /** Construct a type specifier from a structure definition */
    ast_type_specifier(ast_struct_specifier *s)
-      : type_name(s->name), structure(s), array_specifier(NULL),
+      : type(NULL), type_name(s->name), structure(s), array_specifier(NULL),
        default_precision(ast_precision_none)
    {
       /* empty */
    }
 
+   ast_type_specifier(const glsl_type *t)
+      : type(t), type_name(t->name), structure(NULL), array_specifier(NULL),
+        default_precision(ast_precision_none)
+   {
+      /* empty */
+   }
+
    const struct glsl_type *glsl_type(const char **name,
                                     struct _mesa_glsl_parse_state *state)
       const;
@@ -806,6 +906,7 @@ public:
 
    ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *);
 
+   const struct glsl_type *type;
    const char *type_name;
    ast_struct_specifier *structure;
 
@@ -1128,6 +1229,7 @@ public:
    virtual ir_rvalue *hir(exec_list *instructions,
                          struct _mesa_glsl_parse_state *state);
 
+   ast_type_qualifier default_layout;
    ast_type_qualifier layout;
    const char *block_name;
 
@@ -1213,6 +1315,20 @@ private:
    ast_layout_expression *local_size[3];
 };
 
+class ast_warnings_toggle : public ast_node {
+public:
+   ast_warnings_toggle(bool _enable)
+      : enable(_enable)
+   {
+      /* empty */
+   }
+
+   virtual ir_rvalue *hir(exec_list *instructions,
+                          struct _mesa_glsl_parse_state *state);
+
+private:
+   bool enable;
+};
 /*@}*/
 
 extern void