summaryrefslogtreecommitdiff
path: root/ast_to_hir.cpp
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-04-19 15:13:15 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-04-28 18:22:53 -0700
commit3455ce614424a5a23a23037e23d0454e476bceea (patch)
tree60a1e97550df11b1cddb9dc62bf960ad0e3ba0e2 /ast_to_hir.cpp
parent1f959ab4d68ce7c963f9d5f3edc64b457565c291 (diff)
Begin converting structure definitions to IR
Diffstat (limited to 'ast_to_hir.cpp')
-rw-r--r--ast_to_hir.cpp82
1 files changed, 81 insertions, 1 deletions
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp
index 1dc4ea25b2..2f83dd6597 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;
+}