diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2010-04-01 17:25:11 -0700 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2010-04-01 17:25:11 -0700 |
commit | a4f308f0663208eec07cc320ff4a67589d4b5a7f (patch) | |
tree | b49563f777dae62ac532cdbbf9721b9675d3e86e | |
parent | 00e517616b722d6a1f62748d8c84004eeb814756 (diff) |
Allow unsized arrays to be redeclared with a size
Test glslparsertest/shaders/array11.frag now passes for the right reason.
-rw-r--r-- | ast_to_hir.cpp | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index 2eecc9f3ec..3c4b05ee79 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -1178,13 +1178,40 @@ ast_declarator_list::hir(exec_list *instructions, & loc); /* Attempt to add the variable to the symbol table. If this fails, it - * means the variable has already been declared at this scope. + * means the variable has already been declared at this scope. Arrays + * fudge this rule a little bit. + * + * From page 24 (page 30 of the PDF) of the GLSL 1.50 spec, + * + * "It is legal to declare an array without a size and then + * later re-declare the same name as an array of the same + * type and specify a size." */ if (state->symbols->name_declared_this_scope(decl->identifier)) { - YYLTYPE loc = this->get_location(); + ir_variable *const earlier = + state->symbols->get_variable(decl->identifier); + + if ((earlier != NULL) + && (earlier->type->array_size() == 0) + && var->type->is_array() + && (var->type->element_type() == earlier->type->element_type())) { + /* FINISHME: This doesn't match the qualifiers on the two + * FINISHME: declarations. It's not 100% clear whether this is + * FINISHME: required or not. + */ + /* FINISHME: Check that the array hasn't already been accessed + * FINISHME: beyond the newly defined bounds. + */ + earlier->type = var->type; + delete var; + var = NULL; + } else { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, "`%s' redeclared", + decl->identifier); + } - _mesa_glsl_error(& loc, state, "`%s' redeclared", - decl->identifier); continue; } |