const glsl_type *const constructor_type = type->glsl_type(& name, state);
+ /* constructor_type can be NULL if a variable with the same name as the
+ * structure has come into scope.
+ */
+ if (constructor_type == NULL) {
+ _mesa_glsl_error(& loc, state, "unknown type `%s' (structure name "
+ "may be shadowed by a variable with the same name)",
+ type->type_name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
/* Constructors for samplers are illegal.
*/
* correct order. These constructors follow essentially the same type
* matching rules as functions.
*/
+ if (constructor_type->is_record()) {
+ exec_list actual_parameters;
+
+ process_parameters(instructions, &actual_parameters,
+ &this->expressions, state);
+
+ exec_node *node = actual_parameters.head;
+ for (unsigned i = 0; i < constructor_type->length; i++) {
+ ir_rvalue *ir = (ir_rvalue *) node;
+
+ if (node->is_tail_sentinel()) {
+ _mesa_glsl_error(&loc, state,
+ "insufficient parameters to constructor "
+ "for `%s'",
+ constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ if (apply_implicit_conversion(constructor_type->fields.structure[i].type,
+ ir, state)) {
+ node->replace_with(ir);
+ } else {
+ _mesa_glsl_error(&loc, state,
+ "parameter type mismatch in constructor "
+ "for `%s.%s' (%s vs %s)",
+ constructor_type->name,
+ constructor_type->fields.structure[i].name,
+ ir->type->name,
+ constructor_type->fields.structure[i].type->name);
+ return ir_call::get_error_instruction(ctx);;
+ }
+
+ node = node->next;
+ }
+
+ if (!node->is_tail_sentinel()) {
+ _mesa_glsl_error(&loc, state, "too many parameters in constructor "
+ "for `%s'", constructor_type->name);
+ return ir_call::get_error_instruction(ctx);
+ }
+
+ ir_rvalue *const constant =
+ constant_record_constructor(constructor_type, &actual_parameters,
+ state);
+
+ return (constant != NULL)
+ ? constant
+ : emit_inline_record_constructor(constructor_type, instructions,
+ &actual_parameters, state);
+ }
+
if (!constructor_type->is_numeric() && !constructor_type->is_boolean())
return ir_call::get_error_instruction(ctx);
process_parameters(instructions, &actual_parameters, &this->expressions,
state);
- const glsl_type *const type =
- state->symbols->get_type(id->primary_expression.identifier);
-
- if ((type != NULL) && type->is_record()) {
- exec_node *node = actual_parameters.head;
- for (unsigned i = 0; i < type->length; i++) {
- ir_rvalue *ir = (ir_rvalue *) node;
-
- if (node->is_tail_sentinel()) {
- _mesa_glsl_error(&loc, state,
- "insufficient parameters to constructor "
- "for `%s'",
- type->name);
- return ir_call::get_error_instruction(ctx);
- }
-
- if (apply_implicit_conversion(type->fields.structure[i].type, ir,
- state)) {
- node->replace_with(ir);
- } else {
- _mesa_glsl_error(&loc, state,
- "parameter type mismatch in constructor "
- "for `%s.%s' (%s vs %s)",
- type->name,
- type->fields.structure[i].name,
- ir->type->name,
- type->fields.structure[i].type->name);
- return ir_call::get_error_instruction(ctx);;
- }
-
- node = node->next;
- }
-
- if (!node->is_tail_sentinel()) {
- _mesa_glsl_error(&loc, state, "too many parameters in constructor "
- "for `%s'", type->name);
- return ir_call::get_error_instruction(ctx);
- }
-
- ir_rvalue *const constant =
- constant_record_constructor(type, &actual_parameters, state);
-
- return (constant != NULL)
- ? constant
- : emit_inline_record_constructor(type, instructions,
- &actual_parameters, state);
- }
-
return match_function_by_name(instructions,
id->primary_expression.identifier, & loc,
&actual_parameters, state);
_mesa_glsl_initialize_types(state);
}
external_declaration_list
+ {
+ delete state->symbols;
+ state->symbols = new(ralloc_parent(state)) glsl_symbol_table;
+ _mesa_glsl_initialize_types(state);
+ }
;
version_statement:
declaration:
function_prototype ';'
{
+ state->symbols->pop_scope();
$$ = $1;
}
| init_declarator_list ';'
$$->set_location(yylloc);
$$->return_type = $1;
$$->identifier = $2;
+
+ state->symbols->add_function(new(state) ir_function($2));
+ state->symbols->push_scope();
}
;
$$ = $1;
$$->declarations.push_tail(&decl->link);
+ state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
}
| init_declarator_list ',' any_identifier '[' ']'
{
$$ = $1;
$$->declarations.push_tail(&decl->link);
+ state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
}
| init_declarator_list ',' any_identifier '[' constant_expression ']'
{
$$ = $1;
$$->declarations.push_tail(&decl->link);
+ state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
}
| init_declarator_list ',' any_identifier '[' ']' '=' initializer
{
$$ = $1;
$$->declarations.push_tail(&decl->link);
+ state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
}
| init_declarator_list ',' any_identifier '[' constant_expression ']' '=' initializer
{
$$ = $1;
$$->declarations.push_tail(&decl->link);
+ state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
}
| init_declarator_list ',' any_identifier '=' initializer
{
$$ = $1;
$$->declarations.push_tail(&decl->link);
+ state->symbols->add_variable(new(state) ir_variable(NULL, $3, ir_var_auto));
}
;
$$->set_location(yylloc);
$$->declarations.push_tail(&decl->link);
}
- | INVARIANT IDENTIFIER // Vertex only.
+ | INVARIANT variable_identifier // Vertex only.
{
void *ctx = state;
ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL);
;
layout_qualifier_id:
- IDENTIFIER
+ any_identifier
{
bool got_one = false;
YYERROR;
}
}
- | IDENTIFIER '=' INTCONSTANT
+ | any_identifier '=' INTCONSTANT
{
bool got_one = false;
;
struct_specifier:
- STRUCT IDENTIFIER '{' struct_declaration_list '}'
+ STRUCT any_identifier '{' struct_declaration_list '}'
{
void *ctx = state;
$$ = new(ctx) ast_struct_specifier($2, $4);
$$->set_location(yylloc);
+ state->symbols->add_type($2, glsl_type::void_type);
}
| STRUCT '{' struct_declaration_list '}'
{
;
struct_declarator:
- IDENTIFIER
+ any_identifier
{
void *ctx = state;
$$ = new(ctx) ast_declaration($1, false, NULL, NULL);
$$->set_location(yylloc);
+ state->symbols->add_variable(new(state) ir_variable(NULL, $1, ir_var_auto));
}
- | IDENTIFIER '[' constant_expression ']'
+ | any_identifier '[' constant_expression ']'
{
void *ctx = state;
$$ = new(ctx) ast_declaration($1, true, $3, NULL);
$$ = new(ctx) ast_compound_statement(true, NULL);
$$->set_location(yylloc);
}
- | '{' statement_list '}'
+ | '{'
+ {
+ state->symbols->push_scope();
+ }
+ statement_list '}'
{
void *ctx = state;
- $$ = new(ctx) ast_compound_statement(true, $2);
+ $$ = new(ctx) ast_compound_statement(true, $3);
$$->set_location(yylloc);
+ state->symbols->pop_scope();
}
;
{
$$ = (ast_node *) $1;
}
- | fully_specified_type IDENTIFIER '=' initializer
+ | fully_specified_type any_identifier '=' initializer
{
void *ctx = state;
ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4);
$$->set_location(yylloc);
$$->prototype = $1;
$$->body = $2;
+
+ state->symbols->pop_scope();
}
;