diff options
author | Paul Berry <[email protected]> | 2014-01-21 15:41:26 -0800 |
---|---|---|
committer | Paul Berry <[email protected]> | 2014-01-22 11:08:30 -0800 |
commit | 0da1a2cc369052643ccaea75a1722cc37652d82a (patch) | |
tree | e85839b80332c2280671c376d16719ec43a1c823 /src/glsl/glsl_parser_extras.cpp | |
parent | 6ec210989fa10847091f06fcfcab77dd07618dff (diff) |
glsl: Simplify aggregate type inference to prepare for ARB_arrays_of_arrays.
Most of the time it is not necessary to perform type inference to
compile GLSL; the type of every expression can be inferred from the
contents of the expression itself (and previous type declarations).
The exception is aggregate initializers: their type is determined by
the LHS of the variable being assigned to. For example, in the
statement:
mat2 foo = { { 1, 2 }, { 3, 4 } };
the type of { 1, 2 } is only known to be vec2 (as opposed to, say,
ivec2, uvec2, int[2], or a struct) because of the fact that the result
is being assigned to a mat2.
Previous to this patch, we handled this situation by doing some type
inference during parsing: when parsing a declaration like the one
above, we would call _mesa_set_aggregate_type(), which would infer the
type of each aggregate initializer and store it in the corresponding
ast_aggregate_initializer::constructor_type field. Since this
happened at parse time, we couldn't do the type inference using
glsl_type objects; we had to use ast_type_specifiers, which are much
more awkward to work with. Things are about to get more complicated
when we add support for ARB_arrays_of_arrays.
This patch simplifies things by postponing the call to
_mesa_set_aggregate_type() until ast-to-hir time, when we have access
to glsl_type objects. As a side benefit, we only need to have one
call to _mesa_set_aggregate_type() now, instead of six.
Reviewed-by: Matt Turner <[email protected]>
Diffstat (limited to 'src/glsl/glsl_parser_extras.cpp')
-rw-r--r-- | src/glsl/glsl_parser_extras.cpp | 136 |
1 files changed, 24 insertions, 112 deletions
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index 9a1e0a249ed..345e426b75a 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -635,25 +635,6 @@ _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, /** - * Returns the name of the type of a column of a matrix. E.g., - * - * "mat3" -> "vec3" - * "mat4x2" -> "vec2" - */ -static const char * -_mesa_ast_get_matrix_column_type_name(const char *matrix_type_name) -{ - static const char *vec_name[] = { "vec2", "vec3", "vec4" }; - - /* The number of elements in a row of a matrix is specified by the last - * character of the matrix type name. - */ - long rows = strtol(matrix_type_name + strlen(matrix_type_name) - 1, - NULL, 10); - return vec_name[rows - 2]; -} - -/** * Recurses through <type> and <expr> if <expr> is an aggregate initializer * and sets <expr>'s <constructor_type> field to <type>. Gives later functions * (process_array_constructor, et al) sufficient information to do type @@ -700,37 +681,19 @@ _mesa_ast_get_matrix_column_type_name(const char *matrix_type_name) * doesn't contain sufficient information to determine if the types match. */ void -_mesa_ast_set_aggregate_type(const ast_type_specifier *type, - ast_expression *expr, - _mesa_glsl_parse_state *state) +_mesa_ast_set_aggregate_type(const glsl_type *type, + ast_expression *expr) { - void *ctx = state; ast_aggregate_initializer *ai = (ast_aggregate_initializer *)expr; - ai->constructor_type = (ast_type_specifier *)type; - - bool is_declaration = ai->constructor_type->structure != NULL; - if (!is_declaration) { - /* Look up <type> name in the symbol table to see if it's a struct. */ - const ast_type_specifier *struct_type = - state->symbols->get_type_ast(type->type_name); - ai->constructor_type->structure = - struct_type ? new(ctx) ast_struct_specifier(*struct_type->structure) - : NULL; - } + ai->constructor_type = type; /* If the aggregate is an array, recursively set its elements' types. */ - if (type->is_array) { - /* We want to set the element type which is not an array itself, so make - * a copy of the array type and set its is_array field to false. + if (type->is_array()) { + /* Each array element has the type type->element_type(). * * E.g., if <type> if struct S[2] we want to set each element's type to * struct S. - * - * FINISHME: Update when ARB_array_of_arrays is supported. */ - const ast_type_specifier *non_array_type = - new(ctx) ast_type_specifier(type, false, NULL); - for (exec_node *expr_node = ai->expressions.head; !expr_node->is_tail_sentinel(); expr_node = expr_node->next) { @@ -738,84 +701,33 @@ _mesa_ast_set_aggregate_type(const ast_type_specifier *type, link); if (expr->oper == ast_aggregate) - _mesa_ast_set_aggregate_type(non_array_type, expr, state); + _mesa_ast_set_aggregate_type(type->element_type(), expr); } /* If the aggregate is a struct, recursively set its fields' types. */ - } else if (ai->constructor_type->structure) { - ai->constructor_type->structure->is_declaration = is_declaration; + } else if (type->is_record()) { exec_node *expr_node = ai->expressions.head; - /* Iterate through the struct's fields' declarations. E.g., iterate from - * "float a, b" to "int c" in the struct below. - * - * struct { - * float a, b; - * int c; - * } s; - */ - for (exec_node *decl_list_node = - ai->constructor_type->structure->declarations.head; - !decl_list_node->is_tail_sentinel(); - decl_list_node = decl_list_node->next) { - ast_declarator_list *decl_list = exec_node_data(ast_declarator_list, - decl_list_node, link); - - for (exec_node *decl_node = decl_list->declarations.head; - !decl_node->is_tail_sentinel() && !expr_node->is_tail_sentinel(); - decl_node = decl_node->next, expr_node = expr_node->next) { - ast_declaration *decl = exec_node_data(ast_declaration, decl_node, - link); - ast_expression *expr = exec_node_data(ast_expression, expr_node, - link); - - bool is_array = decl_list->type->specifier->is_array; - ast_expression *array_size = decl_list->type->specifier->array_size; - - /* Recognize variable declarations with the bracketed size attached - * to the type rather than the variable name as arrays. E.g., - * - * float a[2]; - * float[2] b; - * - * are both arrays, but <a>'s array_size is decl->array_size, while - * <b>'s array_size is decl_list->type->specifier->array_size. - */ - if (!is_array) { - /* FINISHME: Update when ARB_array_of_arrays is supported. */ - is_array = decl->is_array; - array_size = decl->array_size; - } - - /* Declaration shadows the <type> parameter. */ - ast_type_specifier *type = - new(ctx) ast_type_specifier(decl_list->type->specifier, - is_array, array_size); + /* Iterate through the struct's fields. */ + for (unsigned i = 0; !expr_node->is_tail_sentinel() && i < type->length; + i++, expr_node = expr_node->next) { + ast_expression *expr = exec_node_data(ast_expression, expr_node, + link); - if (expr->oper == ast_aggregate) - _mesa_ast_set_aggregate_type(type, expr, state); + if (expr->oper == ast_aggregate) { + _mesa_ast_set_aggregate_type(type->fields.structure[i].type, expr); } } - } else { - /* If the aggregate is a matrix, set its columns' types. */ - const char *name; - const glsl_type *const constructor_type = - ai->constructor_type->glsl_type(&name, state); - - if (constructor_type->is_matrix()) { - for (exec_node *expr_node = ai->expressions.head; - !expr_node->is_tail_sentinel(); - expr_node = expr_node->next) { - ast_expression *expr = exec_node_data(ast_expression, expr_node, - link); - - /* Declaration shadows the <type> parameter. */ - ast_type_specifier *type = new(ctx) - ast_type_specifier(_mesa_ast_get_matrix_column_type_name(name)); - - if (expr->oper == ast_aggregate) - _mesa_ast_set_aggregate_type(type, expr, state); - } + /* If the aggregate is a matrix, set its columns' types. */ + } else if (type->is_matrix()) { + for (exec_node *expr_node = ai->expressions.head; + !expr_node->is_tail_sentinel(); + expr_node = expr_node->next) { + ast_expression *expr = exec_node_data(ast_expression, expr_node, + link); + + if (expr->oper == ast_aggregate) + _mesa_ast_set_aggregate_type(type->column_type(), expr); } } } |