From: Ian Romanick Date: Mon, 19 Apr 2010 22:13:15 +0000 (-0700) Subject: Begin converting structure definitions to IR X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3455ce614424a5a23a23037e23d0454e476bceea;p=mesa.git Begin converting structure definitions to IR --- diff --git a/ast.h b/ast.h index d899fb1d090..41787f5c1c3 100644 --- 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; diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index 1dc4ea25b21..2f83dd6597e 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -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; +}