Begin converting structure definitions to IR
authorIan Romanick <ian.d.romanick@intel.com>
Mon, 19 Apr 2010 22:13:15 +0000 (15:13 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 29 Apr 2010 01:22:53 +0000 (18:22 -0700)
ast.h
ast_to_hir.cpp

diff --git a/ast.h b/ast.h
index d899fb1d090a831a98bc90e49f940066668af239..41787f5c1c37e2869f393517fddbd4a7d782d99b 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -289,6 +289,9 @@ public:
    ast_struct_specifier(char *identifier, ast_node *declarator_list);
    virtual void print(void) const;
 
+   virtual ir_rvalue *hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state);
+
    char *name;
    struct simple_node declarations;
 };
@@ -378,6 +381,8 @@ public:
 
    virtual void print(void) const;
 
+   ir_rvalue *hir(exec_list *, struct _mesa_glsl_parse_state *);
+
    enum ast_types type_specifier;
 
    const char *type_name;
index 1dc4ea25b21091ebe51a8f471d2ad7b2371ad6ba..2f83dd6597e8b6dda2e01c1677f33dafb970debb 100644 (file)
@@ -1381,7 +1381,7 @@ ast_type_specifier::glsl_type(const char **name,
 {
    const struct glsl_type *type;
 
-   if (this->type_specifier == ast_struct) {
+   if ((this->type_specifier == ast_struct) && (this->type_name == NULL)) {
       /* FINISHME: Handle annonymous structures. */
       type = NULL;
    } else {
@@ -1477,6 +1477,11 @@ ast_declarator_list::hir(exec_list *instructions,
    const char *type_name = NULL;
    ir_rvalue *result = NULL;
 
+   /* The type specifier may contain a structure definition.  Process that
+    * before any of the variable declarations.
+    */
+   (void) this->type->specifier->hir(instructions, state);
+
    /* FINISHME: Handle vertex shader "invariant" declarations that do not
     * FINISHME: include a type.  These re-declare built-in variables to be
     * FINISHME: invariant.
@@ -2256,3 +2261,78 @@ ast_iteration_statement::hir(exec_list *instructions,
     */
    return NULL;
 }
+
+
+ir_rvalue *
+ast_type_specifier::hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state)
+{
+   if (this->structure != NULL)
+      return this->structure->hir(instructions, state);
+}
+
+
+ir_rvalue *
+ast_struct_specifier::hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state)
+{
+   simple_node *ptr;
+   unsigned decl_count = 0;
+
+   /* Make an initial pass over the list of structure fields to determine how
+    * many there are.  Each element in this list is an ast_declarator_list.
+    * This means that we actually need to count the number of elements in the
+    * 'declarations' list in each of the elements.
+    */
+   foreach (ptr, & this->declarations) {
+      ast_declarator_list *decl_list = (ast_declarator_list *) ptr;
+      simple_node *decl_ptr;
+
+      foreach (decl_ptr, & decl_list->declarations) {
+        decl_count++;
+      }
+   }
+
+
+   /* Allocate storage for the structure fields and process the field
+    * declarations.  As the declarations are processed, try to also convert
+    * the types to HIR.  This ensures that structure definitions embedded in
+    * other structure definitions are processed.
+    */
+   glsl_struct_field *const fields = (glsl_struct_field *)
+      malloc(sizeof(*fields) * decl_count);
+
+   unsigned i = 0;
+   foreach (ptr, & this->declarations) {
+      ast_declarator_list *decl_list = (ast_declarator_list *) ptr;
+      simple_node *decl_ptr;
+      const char *type_name;
+
+      decl_list->type->specifier->hir(instructions, state);
+
+      const glsl_type *decl_type =
+        decl_list->type->specifier->glsl_type(& type_name, state);
+
+      foreach (decl_ptr, & decl_list->declarations) {
+        ast_declaration *const decl = (ast_declaration *) decl_ptr;
+        const struct glsl_type *const field_type =
+           (decl->is_array)
+           ? process_array_type(decl_type, decl->array_size, state)
+           : decl_type;
+
+        fields[i].type = field_type;
+        fields[i].name = decl->identifier;
+        i++;
+      }
+   }
+
+   assert(i == decl_count);
+
+   glsl_type *t = new glsl_type(fields, decl_count, this->name);
+
+   state->symbols->add_type(this->name, t);
+
+   /* Structure type definitions do not have r-values.
+    */
+   return NULL;
+}