From 29285882676388aacff123e8bdf025904abf8ea9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 24 Jun 2010 15:32:15 -0700 Subject: glsl2: Move the compiler to the subdirectory it will live in in Mesa. --- src/glsl/ast_to_hir.cpp | 2453 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2453 insertions(+) create mode 100644 src/glsl/ast_to_hir.cpp (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp new file mode 100644 index 0000000000..33eb27533f --- /dev/null +++ b/src/glsl/ast_to_hir.cpp @@ -0,0 +1,2453 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file ast_to_hir.c + * Convert abstract syntax to to high-level intermediate reprensentation (HIR). + * + * During the conversion to HIR, the majority of the symantic checking is + * preformed on the program. This includes: + * + * * Symbol table management + * * Type checking + * * Function binding + * + * The majority of this work could be done during parsing, and the parser could + * probably generate HIR directly. However, this results in frequent changes + * to the parser code. Since we do not assume that every system this complier + * is built on will have Flex and Bison installed, we have to store the code + * generated by these tools in our version control system. In other parts of + * the system we've seen problems where a parser was changed but the generated + * code was not committed, merge conflicts where created because two developers + * had slightly different versions of Bison installed, etc. + * + * I have also noticed that running Bison generated parsers in GDB is very + * irritating. When you get a segfault on '$$ = $1->foo', you can't very + * well 'print $1' in GDB. + * + * As a result, my preference is to put as little C code as possible in the + * parser (and lexer) sources. + */ + +#include "main/imports.h" +#include "glsl_symbol_table.h" +#include "glsl_parser_extras.h" +#include "ast.h" +#include "glsl_types.h" +#include "ir.h" + +void +_mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) +{ + _mesa_glsl_initialize_variables(instructions, state); + _mesa_glsl_initialize_constructors(instructions, state); + _mesa_glsl_initialize_functions(instructions, state); + + state->current_function = NULL; + + foreach_list_typed (ast_node, ast, link, & state->translation_unit) + ast->hir(instructions, state); +} + + +/** + * If a conversion is available, convert one operand to a different type + * + * The \c from \c ir_rvalue is converted "in place". + * + * \param to Type that the operand it to be converted to + * \param from Operand that is being converted + * \param state GLSL compiler state + * + * \return + * If a conversion is possible (or unnecessary), \c true is returned. + * Otherwise \c false is returned. + */ +static bool +apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = talloc_parent(state); + if (to->base_type == from->type->base_type) + return true; + + /* This conversion was added in GLSL 1.20. If the compilation mode is + * GLSL 1.10, the conversion is skipped. + */ + if (state->language_version < 120) + return false; + + /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec: + * + * "There are no implicit array or structure conversions. For + * example, an array of int cannot be implicitly converted to an + * array of float. There are no implicit conversions between + * signed and unsigned integers." + */ + /* FINISHME: The above comment is partially a lie. There is int/uint + * FINISHME: conversion for immediate constants. + */ + if (!to->is_float() || !from->type->is_numeric()) + return false; + + switch (from->type->base_type) { + case GLSL_TYPE_INT: + from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL); + break; + case GLSL_TYPE_UINT: + from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL); + break; + case GLSL_TYPE_BOOL: + from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL); + break; + default: + assert(0); + } + + return true; +} + + +static const struct glsl_type * +arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, + bool multiply, + struct _mesa_glsl_parse_state *state, YYLTYPE *loc) +{ + const glsl_type *type_a = value_a->type; + const glsl_type *type_b = value_b->type; + + /* From GLSL 1.50 spec, page 56: + * + * "The arithmetic binary operators add (+), subtract (-), + * multiply (*), and divide (/) operate on integer and + * floating-point scalars, vectors, and matrices." + */ + if (!type_a->is_numeric() || !type_b->is_numeric()) { + _mesa_glsl_error(loc, state, + "Operands to arithmetic operators must be numeric"); + return glsl_type::error_type; + } + + + /* "If one operand is floating-point based and the other is + * not, then the conversions from Section 4.1.10 "Implicit + * Conversions" are applied to the non-floating-point-based operand." + */ + if (!apply_implicit_conversion(type_a, value_b, state) + && !apply_implicit_conversion(type_b, value_a, state)) { + _mesa_glsl_error(loc, state, + "Could not implicitly convert operands to " + "arithmetic operator"); + return glsl_type::error_type; + } + type_a = value_a->type; + type_b = value_b->type; + + /* "If the operands are integer types, they must both be signed or + * both be unsigned." + * + * From this rule and the preceeding conversion it can be inferred that + * both types must be GLSL_TYPE_FLOAT, or GLSL_TYPE_UINT, or GLSL_TYPE_INT. + * The is_numeric check above already filtered out the case where either + * type is not one of these, so now the base types need only be tested for + * equality. + */ + if (type_a->base_type != type_b->base_type) { + _mesa_glsl_error(loc, state, + "base type mismatch for arithmetic operator"); + return glsl_type::error_type; + } + + /* "All arithmetic binary operators result in the same fundamental type + * (signed integer, unsigned integer, or floating-point) as the + * operands they operate on, after operand type conversion. After + * conversion, the following cases are valid + * + * * The two operands are scalars. In this case the operation is + * applied, resulting in a scalar." + */ + if (type_a->is_scalar() && type_b->is_scalar()) + return type_a; + + /* "* One operand is a scalar, and the other is a vector or matrix. + * In this case, the scalar operation is applied independently to each + * component of the vector or matrix, resulting in the same size + * vector or matrix." + */ + if (type_a->is_scalar()) { + if (!type_b->is_scalar()) + return type_b; + } else if (type_b->is_scalar()) { + return type_a; + } + + /* All of the combinations of , , + * , , and have been + * handled. + */ + assert(!type_a->is_scalar()); + assert(!type_b->is_scalar()); + + /* "* The two operands are vectors of the same size. In this case, the + * operation is done component-wise resulting in the same size + * vector." + */ + if (type_a->is_vector() && type_b->is_vector()) { + if (type_a == type_b) { + return type_a; + } else { + _mesa_glsl_error(loc, state, + "vector size mismatch for arithmetic operator"); + return glsl_type::error_type; + } + } + + /* All of the combinations of , , + * , , , and + * have been handled. At least one of the operands must + * be matrix. Further, since there are no integer matrix types, the base + * type of both operands must be float. + */ + assert(type_a->is_matrix() || type_b->is_matrix()); + assert(type_a->base_type == GLSL_TYPE_FLOAT); + assert(type_b->base_type == GLSL_TYPE_FLOAT); + + /* "* The operator is add (+), subtract (-), or divide (/), and the + * operands are matrices with the same number of rows and the same + * number of columns. In this case, the operation is done component- + * wise resulting in the same size matrix." + * * The operator is multiply (*), where both operands are matrices or + * one operand is a vector and the other a matrix. A right vector + * operand is treated as a column vector and a left vector operand as a + * row vector. In all these cases, it is required that the number of + * columns of the left operand is equal to the number of rows of the + * right operand. Then, the multiply (*) operation does a linear + * algebraic multiply, yielding an object that has the same number of + * rows as the left operand and the same number of columns as the right + * operand. Section 5.10 "Vector and Matrix Operations" explains in + * more detail how vectors and matrices are operated on." + */ + if (! multiply) { + if (type_a == type_b) + return type_a; + } else { + if (type_a->is_matrix() && type_b->is_matrix()) { + /* Matrix multiply. The columns of A must match the rows of B. Given + * the other previously tested constraints, this means the vector type + * of a row from A must be the same as the vector type of a column from + * B. + */ + if (type_a->row_type() == type_b->column_type()) { + /* The resulting matrix has the number of columns of matrix B and + * the number of rows of matrix A. We get the row count of A by + * looking at the size of a vector that makes up a column. The + * transpose (size of a row) is done for B. + */ + const glsl_type *const type = + glsl_type::get_instance(type_a->base_type, + type_a->column_type()->vector_elements, + type_b->row_type()->vector_elements); + assert(type != glsl_type::error_type); + + return type; + } + } else if (type_a->is_matrix()) { + /* A is a matrix and B is a column vector. Columns of A must match + * rows of B. Given the other previously tested constraints, this + * means the vector type of a row from A must be the same as the + * vector the type of B. + */ + if (type_a->row_type() == type_b) + return type_b; + } else { + assert(type_b->is_matrix()); + + /* A is a row vector and B is a matrix. Columns of A must match rows + * of B. Given the other previously tested constraints, this means + * the type of A must be the same as the vector type of a column from + * B. + */ + if (type_a == type_b->column_type()) + return type_a; + } + + _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication"); + return glsl_type::error_type; + } + + + /* "All other cases are illegal." + */ + _mesa_glsl_error(loc, state, "type mismatch"); + return glsl_type::error_type; +} + + +static const struct glsl_type * +unary_arithmetic_result_type(const struct glsl_type *type, + struct _mesa_glsl_parse_state *state, YYLTYPE *loc) +{ + /* From GLSL 1.50 spec, page 57: + * + * "The arithmetic unary operators negate (-), post- and pre-increment + * and decrement (-- and ++) operate on integer or floating-point + * values (including vectors and matrices). All unary operators work + * component-wise on their operands. These result with the same type + * they operated on." + */ + if (!type->is_numeric()) { + _mesa_glsl_error(loc, state, + "Operands to arithmetic operators must be numeric"); + return glsl_type::error_type; + } + + return type; +} + + +static const struct glsl_type * +modulus_result_type(const struct glsl_type *type_a, + const struct glsl_type *type_b, + struct _mesa_glsl_parse_state *state, YYLTYPE *loc) +{ + /* From GLSL 1.50 spec, page 56: + * "The operator modulus (%) operates on signed or unsigned integers or + * integer vectors. The operand types must both be signed or both be + * unsigned." + */ + if (!type_a->is_integer() || !type_b->is_integer() + || (type_a->base_type != type_b->base_type)) { + _mesa_glsl_error(loc, state, "type mismatch"); + return glsl_type::error_type; + } + + /* "The operands cannot be vectors of differing size. If one operand is + * a scalar and the other vector, then the scalar is applied component- + * wise to the vector, resulting in the same type as the vector. If both + * are vectors of the same size, the result is computed component-wise." + */ + if (type_a->is_vector()) { + if (!type_b->is_vector() + || (type_a->vector_elements == type_b->vector_elements)) + return type_a; + } else + return type_b; + + /* "The operator modulus (%) is not defined for any other data types + * (non-integer types)." + */ + _mesa_glsl_error(loc, state, "type mismatch"); + return glsl_type::error_type; +} + + +static const struct glsl_type * +relational_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, + struct _mesa_glsl_parse_state *state, YYLTYPE *loc) +{ + const glsl_type *type_a = value_a->type; + const glsl_type *type_b = value_b->type; + + /* From GLSL 1.50 spec, page 56: + * "The relational operators greater than (>), less than (<), greater + * than or equal (>=), and less than or equal (<=) operate only on + * scalar integer and scalar floating-point expressions." + */ + if (!type_a->is_numeric() + || !type_b->is_numeric() + || !type_a->is_scalar() + || !type_b->is_scalar()) { + _mesa_glsl_error(loc, state, + "Operands to relational operators must be scalar and " + "numeric"); + return glsl_type::error_type; + } + + /* "Either the operands' types must match, or the conversions from + * Section 4.1.10 "Implicit Conversions" will be applied to the integer + * operand, after which the types must match." + */ + if (!apply_implicit_conversion(type_a, value_b, state) + && !apply_implicit_conversion(type_b, value_a, state)) { + _mesa_glsl_error(loc, state, + "Could not implicitly convert operands to " + "relational operator"); + return glsl_type::error_type; + } + type_a = value_a->type; + type_b = value_b->type; + + if (type_a->base_type != type_b->base_type) { + _mesa_glsl_error(loc, state, "base type mismatch"); + return glsl_type::error_type; + } + + /* "The result is scalar Boolean." + */ + return glsl_type::bool_type; +} + + +/** + * Validates that a value can be assigned to a location with a specified type + * + * Validates that \c rhs can be assigned to some location. If the types are + * not an exact match but an automatic conversion is possible, \c rhs will be + * converted. + * + * \return + * \c NULL if \c rhs cannot be assigned to a location with type \c lhs_type. + * Otherwise the actual RHS to be assigned will be returned. This may be + * \c rhs, or it may be \c rhs after some type conversion. + * + * \note + * In addition to being used for assignments, this function is used to + * type-check return values. + */ +ir_rvalue * +validate_assignment(struct _mesa_glsl_parse_state *state, + const glsl_type *lhs_type, ir_rvalue *rhs) +{ + const glsl_type *rhs_type = rhs->type; + + /* If there is already some error in the RHS, just return it. Anything + * else will lead to an avalanche of error message back to the user. + */ + if (rhs_type->is_error()) + return rhs; + + /* If the types are identical, the assignment can trivially proceed. + */ + if (rhs_type == lhs_type) + return rhs; + + /* If the array element types are the same and the size of the LHS is zero, + * the assignment is okay. + * + * Note: Whole-array assignments are not permitted in GLSL 1.10, but this + * is handled by ir_dereference::is_lvalue. + */ + if (lhs_type->is_array() && rhs->type->is_array() + && (lhs_type->element_type() == rhs->type->element_type()) + && (lhs_type->array_size() == 0)) { + return rhs; + } + + /* Check for implicit conversion in GLSL 1.20 */ + if (apply_implicit_conversion(lhs_type, rhs, state)) { + rhs_type = rhs->type; + if (rhs_type == lhs_type) + return rhs; + } + + return NULL; +} + +ir_rvalue * +do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, + ir_rvalue *lhs, ir_rvalue *rhs, + YYLTYPE lhs_loc) +{ + void *ctx = talloc_parent(state); + bool error_emitted = (lhs->type->is_error() || rhs->type->is_error()); + + if (!error_emitted) { + /* FINISHME: This does not handle 'foo.bar.a.b.c[5].d = 5' */ + if (!lhs->is_lvalue()) { + _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment"); + error_emitted = true; + } + } + + ir_rvalue *new_rhs = validate_assignment(state, lhs->type, rhs); + if (new_rhs == NULL) { + _mesa_glsl_error(& lhs_loc, state, "type mismatch"); + } else { + rhs = new_rhs; + + /* If the LHS array was not declared with a size, it takes it size from + * the RHS. If the LHS is an l-value and a whole array, it must be a + * dereference of a variable. Any other case would require that the LHS + * is either not an l-value or not a whole array. + */ + if (lhs->type->array_size() == 0) { + ir_dereference *const d = lhs->as_dereference(); + + assert(d != NULL); + + ir_variable *const var = d->variable_referenced(); + + assert(var != NULL); + + if (var->max_array_access >= unsigned(rhs->type->array_size())) { + /* FINISHME: This should actually log the location of the RHS. */ + _mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to " + "previous access", + var->max_array_access); + } + + var->type = glsl_type::get_array_instance(state, + lhs->type->element_type(), + rhs->type->array_size()); + } + } + + /* Most callers of do_assignment (assign, add_assign, pre_inc/dec, + * but not post_inc) need the converted assigned value as an rvalue + * to handle things like: + * + * i = j += 1; + * + * So we always just store the computed value being assigned to a + * temporary and return a deref of that temporary. If the rvalue + * ends up not being used, the temp will get copy-propagated out. + */ + ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp"); + ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var); + instructions->push_tail(var); + instructions->push_tail(new(ctx) ir_assignment(deref_var, + rhs, + NULL)); + deref_var = new(ctx) ir_dereference_variable(var); + + instructions->push_tail(new(ctx) ir_assignment(lhs, + deref_var, + NULL)); + + return new(ctx) ir_dereference_variable(var); +} + + +/** + * Generate a new temporary and add its declaration to the instruction stream + */ +static ir_variable * +generate_temporary(const glsl_type *type, exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = talloc_parent(state); + char *name = (char *) malloc(sizeof(char) * 13); + + snprintf(name, 13, "tmp_%08X", state->temp_index); + state->temp_index++; + + ir_variable *const var = new(ctx) ir_variable(type, name); + instructions->push_tail(var); + + return var; +} + + +static ir_rvalue * +get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue) +{ + void *ctx = talloc_parent(lvalue); + ir_variable *var; + + /* FINISHME: Give unique names to the temporaries. */ + var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp"); + var->mode = ir_var_auto; + + instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), + lvalue, NULL)); + + /* Once we've created this temporary, mark it read only so it's no + * longer considered an lvalue. + */ + var->read_only = true; + + return new(ctx) ir_dereference_variable(var); +} + + +ir_rvalue * +ast_node::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + (void) instructions; + (void) state; + + return NULL; +} + + +ir_rvalue * +ast_expression::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = talloc_parent(state); + static const int operations[AST_NUM_OPERATORS] = { + -1, /* ast_assign doesn't convert to ir_expression. */ + -1, /* ast_plus doesn't convert to ir_expression. */ + ir_unop_neg, + ir_binop_add, + ir_binop_sub, + ir_binop_mul, + ir_binop_div, + ir_binop_mod, + ir_binop_lshift, + ir_binop_rshift, + ir_binop_less, + ir_binop_greater, + ir_binop_lequal, + ir_binop_gequal, + ir_binop_equal, + ir_binop_nequal, + ir_binop_bit_and, + ir_binop_bit_xor, + ir_binop_bit_or, + ir_unop_bit_not, + ir_binop_logic_and, + ir_binop_logic_xor, + ir_binop_logic_or, + ir_unop_logic_not, + + /* Note: The following block of expression types actually convert + * to multiple IR instructions. + */ + ir_binop_mul, /* ast_mul_assign */ + ir_binop_div, /* ast_div_assign */ + ir_binop_mod, /* ast_mod_assign */ + ir_binop_add, /* ast_add_assign */ + ir_binop_sub, /* ast_sub_assign */ + ir_binop_lshift, /* ast_ls_assign */ + ir_binop_rshift, /* ast_rs_assign */ + ir_binop_bit_and, /* ast_and_assign */ + ir_binop_bit_xor, /* ast_xor_assign */ + ir_binop_bit_or, /* ast_or_assign */ + + -1, /* ast_conditional doesn't convert to ir_expression. */ + ir_binop_add, /* ast_pre_inc. */ + ir_binop_sub, /* ast_pre_dec. */ + ir_binop_add, /* ast_post_inc. */ + ir_binop_sub, /* ast_post_dec. */ + -1, /* ast_field_selection doesn't conv to ir_expression. */ + -1, /* ast_array_index doesn't convert to ir_expression. */ + -1, /* ast_function_call doesn't conv to ir_expression. */ + -1, /* ast_identifier doesn't convert to ir_expression. */ + -1, /* ast_int_constant doesn't convert to ir_expression. */ + -1, /* ast_uint_constant doesn't conv to ir_expression. */ + -1, /* ast_float_constant doesn't conv to ir_expression. */ + -1, /* ast_bool_constant doesn't conv to ir_expression. */ + -1, /* ast_sequence doesn't convert to ir_expression. */ + }; + ir_rvalue *result = NULL; + ir_rvalue *op[2]; + const struct glsl_type *type = glsl_type::error_type; + bool error_emitted = false; + YYLTYPE loc; + + loc = this->get_location(); + + switch (this->oper) { + case ast_assign: { + op[0] = this->subexpressions[0]->hir(instructions, state); + op[1] = this->subexpressions[1]->hir(instructions, state); + + result = do_assignment(instructions, state, op[0], op[1], + this->subexpressions[0]->get_location()); + error_emitted = result->type->is_error(); + type = result->type; + break; + } + + case ast_plus: + op[0] = this->subexpressions[0]->hir(instructions, state); + + error_emitted = op[0]->type->is_error(); + if (type->is_error()) + op[0]->type = type; + + result = op[0]; + break; + + case ast_neg: + op[0] = this->subexpressions[0]->hir(instructions, state); + + type = unary_arithmetic_result_type(op[0]->type, state, & loc); + + error_emitted = type->is_error(); + + result = new(ctx) ir_expression(operations[this->oper], type, + op[0], NULL); + break; + + case ast_add: + case ast_sub: + case ast_mul: + case ast_div: + op[0] = this->subexpressions[0]->hir(instructions, state); + op[1] = this->subexpressions[1]->hir(instructions, state); + + type = arithmetic_result_type(op[0], op[1], + (this->oper == ast_mul), + state, & loc); + error_emitted = type->is_error(); + + result = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); + break; + + case ast_mod: + op[0] = this->subexpressions[0]->hir(instructions, state); + op[1] = this->subexpressions[1]->hir(instructions, state); + + type = modulus_result_type(op[0]->type, op[1]->type, state, & loc); + + assert(operations[this->oper] == ir_binop_mod); + + result = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); + error_emitted = type->is_error(); + break; + + case ast_lshift: + case ast_rshift: + _mesa_glsl_error(& loc, state, "FINISHME: implement bit-shift operators"); + error_emitted = true; + break; + + case ast_less: + case ast_greater: + case ast_lequal: + case ast_gequal: + op[0] = this->subexpressions[0]->hir(instructions, state); + op[1] = this->subexpressions[1]->hir(instructions, state); + + type = relational_result_type(op[0], op[1], state, & loc); + + /* The relational operators must either generate an error or result + * in a scalar boolean. See page 57 of the GLSL 1.50 spec. + */ + assert(type->is_error() + || ((type->base_type == GLSL_TYPE_BOOL) + && type->is_scalar())); + + result = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); + error_emitted = type->is_error(); + break; + + case ast_nequal: + case ast_equal: + op[0] = this->subexpressions[0]->hir(instructions, state); + op[1] = this->subexpressions[1]->hir(instructions, state); + + /* From page 58 (page 64 of the PDF) of the GLSL 1.50 spec: + * + * "The equality operators equal (==), and not equal (!=) + * operate on all types. They result in a scalar Boolean. If + * the operand types do not match, then there must be a + * conversion from Section 4.1.10 "Implicit Conversions" + * applied to one operand that can make them match, in which + * case this conversion is done." + */ + if ((!apply_implicit_conversion(op[0]->type, op[1], state) + && !apply_implicit_conversion(op[1]->type, op[0], state)) + || (op[0]->type != op[1]->type)) { + _mesa_glsl_error(& loc, state, "operands of `%s' must have the same " + "type", (this->oper == ast_equal) ? "==" : "!="); + error_emitted = true; + } else if ((state->language_version <= 110) + && (op[0]->type->is_array() || op[1]->type->is_array())) { + _mesa_glsl_error(& loc, state, "array comparisons forbidden in " + "GLSL 1.10"); + error_emitted = true; + } + + result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, + op[0], op[1]); + type = glsl_type::bool_type; + + assert(result->type == glsl_type::bool_type); + break; + + case ast_bit_and: + case ast_bit_xor: + case ast_bit_or: + case ast_bit_not: + _mesa_glsl_error(& loc, state, "FINISHME: implement bit-wise operators"); + error_emitted = true; + break; + + case ast_logic_and: { + op[0] = this->subexpressions[0]->hir(instructions, state); + + if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) { + YYLTYPE loc = this->subexpressions[0]->get_location(); + + _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean", + operator_string(this->oper)); + error_emitted = true; + } + + ir_constant *op0_const = op[0]->constant_expression_value(); + if (op0_const) { + if (op0_const->value.b[0]) { + op[1] = this->subexpressions[1]->hir(instructions, state); + + if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) { + YYLTYPE loc = this->subexpressions[1]->get_location(); + + _mesa_glsl_error(& loc, state, + "RHS of `%s' must be scalar boolean", + operator_string(this->oper)); + error_emitted = true; + } + result = op[1]; + } else { + result = op0_const; + } + type = glsl_type::bool_type; + } else { + ir_if *const stmt = new(ctx) ir_if(op[0]); + instructions->push_tail(stmt); + + op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state); + + if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) { + YYLTYPE loc = this->subexpressions[1]->get_location(); + + _mesa_glsl_error(& loc, state, + "RHS of `%s' must be scalar boolean", + operator_string(this->oper)); + error_emitted = true; + } + + ir_variable *const tmp = generate_temporary(glsl_type::bool_type, + instructions, state); + + ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); + ir_assignment *const then_assign = + new(ctx) ir_assignment(then_deref, op[1], NULL); + stmt->then_instructions.push_tail(then_assign); + + ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); + ir_assignment *const else_assign = + new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false), NULL); + stmt->else_instructions.push_tail(else_assign); + + result = new(ctx) ir_dereference_variable(tmp); + type = tmp->type; + } + break; + } + + case ast_logic_or: { + op[0] = this->subexpressions[0]->hir(instructions, state); + + if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) { + YYLTYPE loc = this->subexpressions[0]->get_location(); + + _mesa_glsl_error(& loc, state, "LHS of `%s' must be scalar boolean", + operator_string(this->oper)); + error_emitted = true; + } + + ir_constant *op0_const = op[0]->constant_expression_value(); + if (op0_const) { + if (op0_const->value.b[0]) { + result = op0_const; + } else { + op[1] = this->subexpressions[1]->hir(instructions, state); + + if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) { + YYLTYPE loc = this->subexpressions[1]->get_location(); + + _mesa_glsl_error(& loc, state, + "RHS of `%s' must be scalar boolean", + operator_string(this->oper)); + error_emitted = true; + } + result = op[1]; + } + type = glsl_type::bool_type; + } else { + ir_if *const stmt = new(ctx) ir_if(op[0]); + instructions->push_tail(stmt); + + ir_variable *const tmp = generate_temporary(glsl_type::bool_type, + instructions, state); + + op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state); + + if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) { + YYLTYPE loc = this->subexpressions[1]->get_location(); + + _mesa_glsl_error(& loc, state, "RHS of `%s' must be scalar boolean", + operator_string(this->oper)); + error_emitted = true; + } + + ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); + ir_assignment *const then_assign = + new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true), NULL); + stmt->then_instructions.push_tail(then_assign); + + ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); + ir_assignment *const else_assign = + new(ctx) ir_assignment(else_deref, op[1], NULL); + stmt->else_instructions.push_tail(else_assign); + + result = new(ctx) ir_dereference_variable(tmp); + type = tmp->type; + } + break; + } + + case ast_logic_xor: + op[0] = this->subexpressions[0]->hir(instructions, state); + op[1] = this->subexpressions[1]->hir(instructions, state); + + + result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, + op[0], op[1]); + type = glsl_type::bool_type; + break; + + case ast_logic_not: + op[0] = this->subexpressions[0]->hir(instructions, state); + + if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) { + YYLTYPE loc = this->subexpressions[0]->get_location(); + + _mesa_glsl_error(& loc, state, + "operand of `!' must be scalar boolean"); + error_emitted = true; + } + + result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, + op[0], NULL); + type = glsl_type::bool_type; + break; + + case ast_mul_assign: + case ast_div_assign: + case ast_add_assign: + case ast_sub_assign: { + op[0] = this->subexpressions[0]->hir(instructions, state); + op[1] = this->subexpressions[1]->hir(instructions, state); + + type = arithmetic_result_type(op[0], op[1], + (this->oper == ast_mul_assign), + state, & loc); + + ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); + + result = do_assignment(instructions, state, + (ir_rvalue *)op[0]->clone(NULL), temp_rhs, + this->subexpressions[0]->get_location()); + type = result->type; + error_emitted = (op[0]->type->is_error()); + + /* GLSL 1.10 does not allow array assignment. However, we don't have to + * explicitly test for this because none of the binary expression + * operators allow array operands either. + */ + + break; + } + + case ast_mod_assign: { + op[0] = this->subexpressions[0]->hir(instructions, state); + op[1] = this->subexpressions[1]->hir(instructions, state); + + type = modulus_result_type(op[0]->type, op[1]->type, state, & loc); + + assert(operations[this->oper] == ir_binop_mod); + + struct ir_rvalue *temp_rhs; + temp_rhs = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); + + result = do_assignment(instructions, state, + (ir_rvalue *)op[0]->clone(NULL), temp_rhs, + this->subexpressions[0]->get_location()); + type = result->type; + error_emitted = type->is_error(); + break; + } + + case ast_ls_assign: + case ast_rs_assign: + _mesa_glsl_error(& loc, state, + "FINISHME: implement bit-shift assignment operators"); + error_emitted = true; + break; + + case ast_and_assign: + case ast_xor_assign: + case ast_or_assign: + _mesa_glsl_error(& loc, state, + "FINISHME: implement logic assignment operators"); + error_emitted = true; + break; + + case ast_conditional: { + op[0] = this->subexpressions[0]->hir(instructions, state); + + /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec: + * + * "The ternary selection operator (?:). It operates on three + * expressions (exp1 ? exp2 : exp3). This operator evaluates the + * first expression, which must result in a scalar Boolean." + */ + if (!op[0]->type->is_boolean() || !op[0]->type->is_scalar()) { + YYLTYPE loc = this->subexpressions[0]->get_location(); + + _mesa_glsl_error(& loc, state, "?: condition must be scalar boolean"); + error_emitted = true; + } + + /* The :? operator is implemented by generating an anonymous temporary + * followed by an if-statement. The last instruction in each branch of + * the if-statement assigns a value to the anonymous temporary. This + * temporary is the r-value of the expression. + */ + exec_list then_instructions; + exec_list else_instructions; + + op[1] = this->subexpressions[1]->hir(&then_instructions, state); + op[2] = this->subexpressions[2]->hir(&else_instructions, state); + + /* From page 59 (page 65 of the PDF) of the GLSL 1.50 spec: + * + * "The second and third expressions can be any type, as + * long their types match, or there is a conversion in + * Section 4.1.10 "Implicit Conversions" that can be applied + * to one of the expressions to make their types match. This + * resulting matching type is the type of the entire + * expression." + */ + if ((!apply_implicit_conversion(op[1]->type, op[2], state) + && !apply_implicit_conversion(op[2]->type, op[1], state)) + || (op[1]->type != op[2]->type)) { + YYLTYPE loc = this->subexpressions[1]->get_location(); + + _mesa_glsl_error(& loc, state, "Second and third operands of ?: " + "operator must have matching types."); + error_emitted = true; + type = glsl_type::error_type; + } else { + type = op[1]->type; + } + + ir_constant *cond_val = op[0]->constant_expression_value(); + ir_constant *then_val = op[1]->constant_expression_value(); + ir_constant *else_val = op[2]->constant_expression_value(); + + if (then_instructions.is_empty() + && else_instructions.is_empty() + && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) { + result = (cond_val->value.b[0]) ? then_val : else_val; + } else { + ir_variable *const tmp = generate_temporary(type, + instructions, state); + + ir_if *const stmt = new(ctx) ir_if(op[0]); + instructions->push_tail(stmt); + + then_instructions.move_nodes_to(& stmt->then_instructions); + ir_dereference *const then_deref = + new(ctx) ir_dereference_variable(tmp); + ir_assignment *const then_assign = + new(ctx) ir_assignment(then_deref, op[1], NULL); + stmt->then_instructions.push_tail(then_assign); + + else_instructions.move_nodes_to(& stmt->else_instructions); + ir_dereference *const else_deref = + new(ctx) ir_dereference_variable(tmp); + ir_assignment *const else_assign = + new(ctx) ir_assignment(else_deref, op[2], NULL); + stmt->else_instructions.push_tail(else_assign); + + result = new(ctx) ir_dereference_variable(tmp); + } + break; + } + + case ast_pre_inc: + case ast_pre_dec: { + op[0] = this->subexpressions[0]->hir(instructions, state); + if (op[0]->type->base_type == GLSL_TYPE_FLOAT) + op[1] = new(ctx) ir_constant(1.0f); + else + op[1] = new(ctx) ir_constant(1); + + type = arithmetic_result_type(op[0], op[1], false, state, & loc); + + struct ir_rvalue *temp_rhs; + temp_rhs = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); + + result = do_assignment(instructions, state, + (ir_rvalue *)op[0]->clone(NULL), temp_rhs, + this->subexpressions[0]->get_location()); + type = result->type; + error_emitted = op[0]->type->is_error(); + break; + } + + case ast_post_inc: + case ast_post_dec: { + op[0] = this->subexpressions[0]->hir(instructions, state); + if (op[0]->type->base_type == GLSL_TYPE_FLOAT) + op[1] = new(ctx) ir_constant(1.0f); + else + op[1] = new(ctx) ir_constant(1); + + error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); + + type = arithmetic_result_type(op[0], op[1], false, state, & loc); + + struct ir_rvalue *temp_rhs; + temp_rhs = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); + + /* Get a temporary of a copy of the lvalue before it's modified. + * This may get thrown away later. + */ + result = get_lvalue_copy(instructions, (ir_rvalue *)op[0]->clone(NULL)); + + (void)do_assignment(instructions, state, + (ir_rvalue *)op[0]->clone(NULL), temp_rhs, + this->subexpressions[0]->get_location()); + + type = result->type; + error_emitted = op[0]->type->is_error(); + break; + } + + case ast_field_selection: + result = _mesa_ast_field_selection_to_hir(this, instructions, state); + type = result->type; + break; + + case ast_array_index: { + YYLTYPE index_loc = subexpressions[1]->get_location(); + + op[0] = subexpressions[0]->hir(instructions, state); + op[1] = subexpressions[1]->hir(instructions, state); + + error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); + + ir_rvalue *const array = op[0]; + + result = new(ctx) ir_dereference_array(op[0], op[1]); + + /* Do not use op[0] after this point. Use array. + */ + op[0] = NULL; + + + if (error_emitted) + break; + + if (!array->type->is_array() + && !array->type->is_matrix() + && !array->type->is_vector()) { + _mesa_glsl_error(& index_loc, state, + "cannot dereference non-array / non-matrix / " + "non-vector"); + error_emitted = true; + } + + if (!op[1]->type->is_integer()) { + _mesa_glsl_error(& index_loc, state, + "array index must be integer type"); + error_emitted = true; + } else if (!op[1]->type->is_scalar()) { + _mesa_glsl_error(& index_loc, state, + "array index must be scalar"); + error_emitted = true; + } + + /* If the array index is a constant expression and the array has a + * declared size, ensure that the access is in-bounds. If the array + * index is not a constant expression, ensure that the array has a + * declared size. + */ + ir_constant *const const_index = op[1]->constant_expression_value(); + if (const_index != NULL) { + const int idx = const_index->value.i[0]; + const char *type_name; + unsigned bound = 0; + + if (array->type->is_matrix()) { + type_name = "matrix"; + } else if (array->type->is_vector()) { + type_name = "vector"; + } else { + type_name = "array"; + } + + /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec: + * + * "It is illegal to declare an array with a size, and then + * later (in the same shader) index the same array with an + * integral constant expression greater than or equal to the + * declared size. It is also illegal to index an array with a + * negative constant expression." + */ + if (array->type->is_matrix()) { + if (array->type->row_type()->vector_elements <= idx) { + bound = array->type->row_type()->vector_elements; + } + } else if (array->type->is_vector()) { + if (array->type->vector_elements <= idx) { + bound = array->type->vector_elements; + } + } else { + if ((array->type->array_size() > 0) + && (array->type->array_size() <= idx)) { + bound = array->type->array_size(); + } + } + + if (bound > 0) { + _mesa_glsl_error(& loc, state, "%s index must be < %u", + type_name, bound); + error_emitted = true; + } else if (idx < 0) { + _mesa_glsl_error(& loc, state, "%s index must be >= 0", + type_name); + error_emitted = true; + } + + if (array->type->is_array()) { + /* If the array is a variable dereference, it dereferences the + * whole array, by definition. Use this to get the variable. + * + * FINISHME: Should some methods for getting / setting / testing + * FINISHME: array access limits be added to ir_dereference? + */ + ir_variable *const v = array->whole_variable_referenced(); + if ((v != NULL) && (unsigned(idx) > v->max_array_access)) + v->max_array_access = idx; + } + } + + if (error_emitted) + result->type = glsl_type::error_type; + + type = result->type; + break; + } + + case ast_function_call: + /* Should *NEVER* get here. ast_function_call should always be handled + * by ast_function_expression::hir. + */ + assert(0); + break; + + case ast_identifier: { + /* ast_identifier can appear several places in a full abstract syntax + * tree. This particular use must be at location specified in the grammar + * as 'variable_identifier'. + */ + ir_variable *var = + state->symbols->get_variable(this->primary_expression.identifier); + + result = new(ctx) ir_dereference_variable(var); + + if (var != NULL) { + type = result->type; + } else { + _mesa_glsl_error(& loc, state, "`%s' undeclared", + this->primary_expression.identifier); + + error_emitted = true; + } + break; + } + + case ast_int_constant: + type = glsl_type::int_type; + result = new(ctx) ir_constant(this->primary_expression.int_constant); + break; + + case ast_uint_constant: + type = glsl_type::uint_type; + result = new(ctx) ir_constant(this->primary_expression.uint_constant); + break; + + case ast_float_constant: + type = glsl_type::float_type; + result = new(ctx) ir_constant(this->primary_expression.float_constant); + break; + + case ast_bool_constant: + type = glsl_type::bool_type; + result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant)); + break; + + case ast_sequence: { + /* It should not be possible to generate a sequence in the AST without + * any expressions in it. + */ + assert(!this->expressions.is_empty()); + + /* The r-value of a sequence is the last expression in the sequence. If + * the other expressions in the sequence do not have side-effects (and + * therefore add instructions to the instruction list), they get dropped + * on the floor. + */ + foreach_list_typed (ast_node, ast, link, &this->expressions) + result = ast->hir(instructions, state); + + type = result->type; + + /* Any errors should have already been emitted in the loop above. + */ + error_emitted = true; + break; + } + } + + if (type->is_error() && !error_emitted) + _mesa_glsl_error(& loc, state, "type mismatch"); + + return result; +} + + +ir_rvalue * +ast_expression_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + /* It is possible to have expression statements that don't have an + * expression. This is the solitary semicolon: + * + * for (i = 0; i < 5; i++) + * ; + * + * In this case the expression will be NULL. Test for NULL and don't do + * anything in that case. + */ + if (expression != NULL) + expression->hir(instructions, state); + + /* Statements do not have r-values. + */ + return NULL; +} + + +ir_rvalue * +ast_compound_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + if (new_scope) + state->symbols->push_scope(); + + foreach_list_typed (ast_node, ast, link, &this->statements) + ast->hir(instructions, state); + + if (new_scope) + state->symbols->pop_scope(); + + /* Compound statements do not have r-values. + */ + return NULL; +} + + +static const glsl_type * +process_array_type(const glsl_type *base, ast_node *array_size, + struct _mesa_glsl_parse_state *state) +{ + unsigned length = 0; + + /* FINISHME: Reject delcarations of multidimensional arrays. */ + + if (array_size != NULL) { + exec_list dummy_instructions; + ir_rvalue *const ir = array_size->hir(& dummy_instructions, state); + YYLTYPE loc = array_size->get_location(); + + /* FINISHME: Verify that the grammar forbids side-effects in array + * FINISHME: sizes. i.e., 'vec4 [x = 12] data' + */ + assert(dummy_instructions.is_empty()); + + if (ir != NULL) { + if (!ir->type->is_integer()) { + _mesa_glsl_error(& loc, state, "array size must be integer type"); + } else if (!ir->type->is_scalar()) { + _mesa_glsl_error(& loc, state, "array size must be scalar type"); + } else { + ir_constant *const size = ir->constant_expression_value(); + + if (size == NULL) { + _mesa_glsl_error(& loc, state, "array size must be a " + "constant valued expression"); + } else if (size->value.i[0] <= 0) { + _mesa_glsl_error(& loc, state, "array size must be > 0"); + } else { + assert(size->type == ir->type); + length = size->value.u[0]; + } + } + } + } + + return glsl_type::get_array_instance(state, base, length); +} + + +const glsl_type * +ast_type_specifier::glsl_type(const char **name, + struct _mesa_glsl_parse_state *state) const +{ + const struct glsl_type *type; + + if ((this->type_specifier == ast_struct) && (this->type_name == NULL)) { + /* FINISHME: Handle annonymous structures. */ + type = NULL; + } else { + type = state->symbols->get_type(this->type_name); + *name = this->type_name; + + if (this->is_array) { + type = process_array_type(type, this->array_size, state); + } + } + + return type; +} + + +static void +apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, + struct ir_variable *var, + struct _mesa_glsl_parse_state *state, + YYLTYPE *loc) +{ + if (qual->invariant) + var->invariant = 1; + + /* FINISHME: Mark 'in' variables at global scope as read-only. */ + if (qual->constant || qual->attribute || qual->uniform + || (qual->varying && (state->target == fragment_shader))) + var->read_only = 1; + + if (qual->centroid) + var->centroid = 1; + + if (qual->attribute && state->target != vertex_shader) { + var->type = glsl_type::error_type; + _mesa_glsl_error(loc, state, + "`attribute' variables may not be declared in the " + "%s shader", + _mesa_glsl_shader_target_name(state->target)); + } + + /* From page 25 (page 31 of the PDF) of the GLSL 1.10 spec: + * + * "The varying qualifier can be used only with the data types + * float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of + * these." + */ + if (qual->varying) { + const glsl_type *non_array_type; + + if (var->type && var->type->is_array()) + non_array_type = var->type->fields.array; + else + non_array_type = var->type; + + if (non_array_type && non_array_type->base_type != GLSL_TYPE_FLOAT) { + var->type = glsl_type::error_type; + _mesa_glsl_error(loc, state, + "varying variables must be of base type float"); + } + } + + if (qual->in && qual->out) + var->mode = ir_var_inout; + else if (qual->attribute || qual->in + || (qual->varying && (state->target == fragment_shader))) + var->mode = ir_var_in; + else if (qual->out || (qual->varying && (state->target == vertex_shader))) + var->mode = ir_var_out; + else if (qual->uniform) + var->mode = ir_var_uniform; + else + var->mode = ir_var_auto; + + if (qual->uniform) + var->shader_in = true; + + /* Any 'in' or 'inout' variables at global scope must be marked as being + * shader inputs. Likewise, any 'out' or 'inout' variables at global scope + * must be marked as being shader outputs. + */ + if (state->current_function == NULL) { + switch (var->mode) { + case ir_var_in: + case ir_var_uniform: + var->shader_in = true; + break; + case ir_var_out: + var->shader_out = true; + break; + case ir_var_inout: + var->shader_in = true; + var->shader_out = true; + break; + default: + break; + } + } + + if (qual->flat) + var->interpolation = ir_var_flat; + else if (qual->noperspective) + var->interpolation = ir_var_noperspective; + else + var->interpolation = ir_var_smooth; + + if (var->type->is_array() && (state->language_version >= 120)) { + var->array_lvalue = true; + } +} + + +ir_rvalue * +ast_declarator_list::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = talloc_parent(state); + const struct glsl_type *decl_type; + const char *type_name = NULL; + ir_rvalue *result = NULL; + YYLTYPE loc = this->get_location(); + + /* 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. + */ + + decl_type = this->type->specifier->glsl_type(& type_name, state); + if (this->declarations.is_empty()) { + /* There are only two valid cases where the declaration list can be + * empty. + * + * 1. The declaration is setting the default precision of a built-in + * type (e.g., 'precision highp vec4;'). + * + * 2. Adding 'invariant' to an existing vertex shader output. + */ + + if (this->type->qualifier.invariant) { + } else if (decl_type != NULL) { + } else { + _mesa_glsl_error(& loc, state, "incomplete declaration"); + } + } + + foreach_list_typed (ast_declaration, decl, link, &this->declarations) { + const struct glsl_type *var_type; + struct ir_variable *var; + + /* FINISHME: Emit a warning if a variable declaration shadows a + * FINISHME: declaration at a higher scope. + */ + + if ((decl_type == NULL) || decl_type->is_void()) { + if (type_name != NULL) { + _mesa_glsl_error(& loc, state, + "invalid type `%s' in declaration of `%s'", + type_name, decl->identifier); + } else { + _mesa_glsl_error(& loc, state, + "invalid type in declaration of `%s'", + decl->identifier); + } + continue; + } + + if (decl->is_array) { + var_type = process_array_type(decl_type, decl->array_size, state); + } else { + var_type = decl_type; + } + + var = new(ctx) ir_variable(var_type, decl->identifier); + + /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification; + * + * "Global variables can only use the qualifiers const, + * attribute, uni form, or varying. Only one may be + * specified. + * + * Local variables can only use the qualifier const." + * + * This is relaxed in GLSL 1.30. + */ + if (state->language_version < 120) { + if (this->type->qualifier.out) { + _mesa_glsl_error(& loc, state, + "`out' qualifier in declaration of `%s' " + "only valid for function parameters in GLSL 1.10.", + decl->identifier); + } + if (this->type->qualifier.in) { + _mesa_glsl_error(& loc, state, + "`in' qualifier in declaration of `%s' " + "only valid for function parameters in GLSL 1.10.", + decl->identifier); + } + /* FINISHME: Test for other invalid qualifiers. */ + } + + apply_type_qualifier_to_variable(& this->type->qualifier, var, state, + & loc); + + /* Attempt to add the variable to the symbol table. If this fails, it + * 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)) { + 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. + */ + + if (var->type->array_size() <= (int)earlier->max_array_access) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, "array size must be > %u due to " + "previous access", + earlier->max_array_access); + } + + earlier->type = var->type; + delete var; + var = NULL; + } else { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, "`%s' redeclared", + decl->identifier); + } + + continue; + } + + /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, + * + * "Identifiers starting with "gl_" are reserved for use by + * OpenGL, and may not be declared in a shader as either a + * variable or a function." + */ + if (strncmp(decl->identifier, "gl_", 3) == 0) { + /* FINISHME: This should only trigger if we're not redefining + * FINISHME: a builtin (to add a qualifier, for example). + */ + _mesa_glsl_error(& loc, state, + "identifier `%s' uses reserved `gl_' prefix", + decl->identifier); + } + + instructions->push_tail(var); + + if (state->current_function != NULL) { + const char *mode = NULL; + const char *extra = ""; + + /* There is no need to check for 'inout' here because the parser will + * only allow that in function parameter lists. + */ + if (this->type->qualifier.attribute) { + mode = "attribute"; + } else if (this->type->qualifier.uniform) { + mode = "uniform"; + } else if (this->type->qualifier.varying) { + mode = "varying"; + } else if (this->type->qualifier.in) { + mode = "in"; + extra = " or in function parameter list"; + } else if (this->type->qualifier.out) { + mode = "out"; + extra = " or in function parameter list"; + } + + if (mode) { + _mesa_glsl_error(& loc, state, + "%s variable `%s' must be declared at " + "global scope%s", + mode, var->name, extra); + } + } else if (var->mode == ir_var_in) { + if (state->target == vertex_shader) { + bool error_emitted = false; + + /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec: + * + * "Vertex shader inputs can only be float, floating-point + * vectors, matrices, signed and unsigned integers and integer + * vectors. Vertex shader inputs can also form arrays of these + * types, but not structures." + * + * From page 31 (page 27 of the PDF) of the GLSL 1.30 spec: + * + * "Vertex shader inputs can only be float, floating-point + * vectors, matrices, signed and unsigned integers and integer + * vectors. They cannot be arrays or structures." + * + * From page 23 (page 29 of the PDF) of the GLSL 1.20 spec: + * + * "The attribute qualifier can be used only with float, + * floating-point vectors, and matrices. Attribute variables + * cannot be declared as arrays or structures." + */ + const glsl_type *check_type = var->type->is_array() + ? var->type->fields.array : var->type; + + switch (check_type->base_type) { + case GLSL_TYPE_FLOAT: + break; + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + if (state->language_version > 120) + break; + /* FALLTHROUGH */ + default: + _mesa_glsl_error(& loc, state, + "vertex shader input / attribute cannot have " + "type %s`%s'", + var->type->is_array() ? "array of " : "", + check_type->name); + error_emitted = true; + } + + if (!error_emitted && (state->language_version <= 130) + && var->type->is_array()) { + _mesa_glsl_error(& loc, state, + "vertex shader input / attribute cannot have " + "array type"); + error_emitted = true; + } + } + } + + if (decl->initializer != NULL) { + YYLTYPE initializer_loc = decl->initializer->get_location(); + + /* From page 24 (page 30 of the PDF) of the GLSL 1.10 spec: + * + * "All uniform variables are read-only and are initialized either + * directly by an application via API commands, or indirectly by + * OpenGL." + */ + if ((state->language_version <= 110) + && (var->mode == ir_var_uniform)) { + _mesa_glsl_error(& initializer_loc, state, + "cannot initialize uniforms in GLSL 1.10"); + } + + if (var->type->is_sampler()) { + _mesa_glsl_error(& initializer_loc, state, + "cannot initialize samplers"); + } + + if ((var->mode == ir_var_in) && (state->current_function == NULL)) { + _mesa_glsl_error(& initializer_loc, state, + "cannot initialize %s shader input / %s", + _mesa_glsl_shader_target_name(state->target), + (state->target == vertex_shader) + ? "attribute" : "varying"); + } + + ir_dereference *const lhs = new(ctx) ir_dereference_variable(var); + ir_rvalue *rhs = decl->initializer->hir(instructions, state); + + /* Calculate the constant value if this is a const or uniform + * declaration. + */ + if (this->type->qualifier.constant || this->type->qualifier.uniform) { + ir_constant *constant_value = rhs->constant_expression_value(); + if (!constant_value) { + _mesa_glsl_error(& initializer_loc, state, + "initializer of %s variable `%s' must be a " + "constant expression", + (this->type->qualifier.constant) + ? "const" : "uniform", + decl->identifier); + } else { + rhs = constant_value; + var->constant_value = constant_value; + } + } + + if (rhs && !rhs->type->is_error()) { + bool temp = var->read_only; + if (this->type->qualifier.constant) + var->read_only = false; + + /* Never emit code to initialize a uniform. + */ + if (!this->type->qualifier.uniform) + result = do_assignment(instructions, state, lhs, rhs, + this->get_location()); + var->read_only = temp; + } + } + + /* From page 23 (page 29 of the PDF) of the GLSL 1.10 spec: + * + * "It is an error to write to a const variable outside of + * its declaration, so they must be initialized when + * declared." + */ + if (this->type->qualifier.constant && decl->initializer == NULL) { + _mesa_glsl_error(& loc, state, + "const declaration of `%s' must be initialized"); + } + + /* Add the vairable to the symbol table after processing the initializer. + * This differs from most C-like languages, but it follows the GLSL + * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50 + * spec: + * + * "Within a declaration, the scope of a name starts immediately + * after the initializer if present or immediately after the name + * being declared if not." + */ + const bool added_variable = + state->symbols->add_variable(decl->identifier, var); + assert(added_variable); + } + + + /* Generally, variable declarations do not have r-values. However, + * one is used for the declaration in + * + * while (bool b = some_condition()) { + * ... + * } + * + * so we return the rvalue from the last seen declaration here. + */ + return result; +} + + +ir_rvalue * +ast_parameter_declarator::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = talloc_parent(state); + const struct glsl_type *type; + const char *name = NULL; + YYLTYPE loc = this->get_location(); + + type = this->type->specifier->glsl_type(& name, state); + + if (type == NULL) { + if (name != NULL) { + _mesa_glsl_error(& loc, state, + "invalid type `%s' in declaration of `%s'", + name, this->identifier); + } else { + _mesa_glsl_error(& loc, state, + "invalid type in declaration of `%s'", + this->identifier); + } + + type = glsl_type::error_type; + } + + /* From page 62 (page 68 of the PDF) of the GLSL 1.50 spec: + * + * "Functions that accept no input arguments need not use void in the + * argument list because prototypes (or definitions) are required and + * therefore there is no ambiguity when an empty argument list "( )" is + * declared. The idiom "(void)" as a parameter list is provided for + * convenience." + * + * Placing this check here prevents a void parameter being set up + * for a function, which avoids tripping up checks for main taking + * parameters and lookups of an unnamed symbol. + */ + if (type->is_void()) { + if (this->identifier != NULL) + _mesa_glsl_error(& loc, state, + "named parameter cannot have type `void'"); + + is_void = true; + return NULL; + } + + if (formal_parameter && (this->identifier == NULL)) { + _mesa_glsl_error(& loc, state, "formal parameter lacks a name"); + return NULL; + } + + is_void = false; + ir_variable *var = new(ctx) ir_variable(type, this->identifier); + + /* FINISHME: Handle array declarations. Note that this requires + * FINISHME: complete handling of constant expressions. + */ + + /* Apply any specified qualifiers to the parameter declaration. Note that + * for function parameters the default mode is 'in'. + */ + apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc); + if (var->mode == ir_var_auto) + var->mode = ir_var_in; + + instructions->push_tail(var); + + /* Parameter declarations do not have r-values. + */ + return NULL; +} + + +void +ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters, + bool formal, + exec_list *ir_parameters, + _mesa_glsl_parse_state *state) +{ + ast_parameter_declarator *void_param = NULL; + unsigned count = 0; + + foreach_list_typed (ast_parameter_declarator, param, link, ast_parameters) { + param->formal_parameter = formal; + param->hir(ir_parameters, state); + + if (param->is_void) + void_param = param; + + count++; + } + + if ((void_param != NULL) && (count > 1)) { + YYLTYPE loc = void_param->get_location(); + + _mesa_glsl_error(& loc, state, + "`void' parameter must be only parameter"); + } +} + + +ir_rvalue * +ast_function::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = talloc_parent(state); + ir_function *f = NULL; + ir_function_signature *sig = NULL; + exec_list hir_parameters; + + + /* Convert the list of function parameters to HIR now so that they can be + * used below to compare this function's signature with previously seen + * signatures for functions with the same name. + */ + ast_parameter_declarator::parameters_to_hir(& this->parameters, + is_definition, + & hir_parameters, state); + + const char *return_type_name; + const glsl_type *return_type = + this->return_type->specifier->glsl_type(& return_type_name, state); + + assert(return_type != NULL); + + /* Verify that this function's signature either doesn't match a previously + * seen signature for a function with the same name, or, if a match is found, + * that the previously seen signature does not have an associated definition. + */ + const char *const name = identifier; + f = state->symbols->get_function(name); + if (f != NULL) { + ir_function_signature *sig = f->exact_matching_signature(&hir_parameters); + if (sig != NULL) { + const char *badvar = sig->qualifiers_match(&hir_parameters); + if (badvar != NULL) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(&loc, state, "function `%s' parameter `%s' " + "qualifiers don't match prototype", name, badvar); + } + + if (sig->return_type != return_type) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(&loc, state, "function `%s' return type doesn't " + "match prototype", name); + } + + if (is_definition && sig->is_defined) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, "function `%s' redefined", name); + sig = NULL; + } + } + } else if (state->symbols->name_declared_this_scope(name)) { + /* This function name shadows a non-function use of the same name. + */ + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, "function name `%s' conflicts with " + "non-function", name); + sig = NULL; + } else { + f = new(ctx) ir_function(name); + state->symbols->add_function(f->name, f); + + /* Emit the new function header */ + instructions->push_tail(f); + } + + /* Verify the return type of main() */ + if (strcmp(name, "main") == 0) { + if (! return_type->is_void()) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, "main() must return void"); + } + + if (!hir_parameters.is_empty()) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, "main() must not take any parameters"); + } + } + + /* Finish storing the information about this new function in its signature. + */ + if (sig == NULL) { + sig = new(ctx) ir_function_signature(return_type); + f->add_signature(sig); + } + + sig->replace_parameters(&hir_parameters); + signature = sig; + + /* Function declarations (prototypes) do not have r-values. + */ + return NULL; +} + + +ir_rvalue * +ast_function_definition::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + prototype->is_definition = true; + prototype->hir(instructions, state); + + ir_function_signature *signature = prototype->signature; + + assert(state->current_function == NULL); + state->current_function = signature; + + /* Duplicate parameters declared in the prototype as concrete variables. + * Add these to the symbol table. + */ + state->symbols->push_scope(); + foreach_iter(exec_list_iterator, iter, signature->parameters) { + ir_variable *const var = ((ir_instruction *) iter.get())->as_variable(); + + assert(var != NULL); + + /* The only way a parameter would "exist" is if two parameters have + * the same name. + */ + if (state->symbols->name_declared_this_scope(var->name)) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, "parameter `%s' redeclared", var->name); + } else { + state->symbols->add_variable(var->name, var); + } + } + + /* Convert the body of the function to HIR. */ + this->body->hir(&signature->body, state); + signature->is_defined = true; + + state->symbols->pop_scope(); + + assert(state->current_function == signature); + state->current_function = NULL; + + /* Function definitions do not have r-values. + */ + return NULL; +} + + +ir_rvalue * +ast_jump_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = talloc_parent(state); + + switch (mode) { + case ast_return: { + ir_return *inst; + assert(state->current_function); + + if (opt_return_value) { + if (state->current_function->return_type->base_type == + GLSL_TYPE_VOID) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, + "`return` with a value, in function `%s' " + "returning void", + state->current_function->function_name()); + } + + ir_expression *const ret = (ir_expression *) + opt_return_value->hir(instructions, state); + assert(ret != NULL); + + /* FINISHME: Make sure the type of the return value matches the return + * FINISHME: type of the enclosing function. + */ + + inst = new(ctx) ir_return(ret); + } else { + if (state->current_function->return_type->base_type != + GLSL_TYPE_VOID) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, + "`return' with no value, in function %s returning " + "non-void", + state->current_function->function_name()); + } + inst = new(ctx) ir_return; + } + + instructions->push_tail(inst); + break; + } + + case ast_discard: + /* FINISHME: discard support */ + if (state->target != fragment_shader) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, + "`discard' may only appear in a fragment shader"); + } + break; + + case ast_break: + case ast_continue: + /* FINISHME: Handle switch-statements. They cannot contain 'continue', + * FINISHME: and they use a different IR instruction for 'break'. + */ + /* FINISHME: Correctly handle the nesting. If a switch-statement is + * FINISHME: inside a loop, a 'continue' is valid and will bind to the + * FINISHME: loop. + */ + if (state->loop_or_switch_nesting == NULL) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, + "`%s' may only appear in a loop", + (mode == ast_break) ? "break" : "continue"); + } else { + ir_loop *const loop = state->loop_or_switch_nesting->as_loop(); + + if (loop != NULL) { + ir_loop_jump *const jump = + new(ctx) ir_loop_jump((mode == ast_break) + ? ir_loop_jump::jump_break + : ir_loop_jump::jump_continue); + instructions->push_tail(jump); + } + } + + break; + } + + /* Jump instructions do not have r-values. + */ + return NULL; +} + + +ir_rvalue * +ast_selection_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = talloc_parent(state); + + ir_rvalue *const condition = this->condition->hir(instructions, state); + + /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec: + * + * "Any expression whose type evaluates to a Boolean can be used as the + * conditional expression bool-expression. Vector types are not accepted + * as the expression to if." + * + * The checks are separated so that higher quality diagnostics can be + * generated for cases where both rules are violated. + */ + if (!condition->type->is_boolean() || !condition->type->is_scalar()) { + YYLTYPE loc = this->condition->get_location(); + + _mesa_glsl_error(& loc, state, "if-statement condition must be scalar " + "boolean"); + } + + ir_if *const stmt = new(ctx) ir_if(condition); + + if (then_statement != NULL) + then_statement->hir(& stmt->then_instructions, state); + + if (else_statement != NULL) + else_statement->hir(& stmt->else_instructions, state); + + instructions->push_tail(stmt); + + /* if-statements do not have r-values. + */ + return NULL; +} + + +void +ast_iteration_statement::condition_to_hir(ir_loop *stmt, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = talloc_parent(state); + + if (condition != NULL) { + ir_rvalue *const cond = + condition->hir(& stmt->body_instructions, state); + + if ((cond == NULL) + || !cond->type->is_boolean() || !cond->type->is_scalar()) { + YYLTYPE loc = condition->get_location(); + + _mesa_glsl_error(& loc, state, + "loop condition must be scalar boolean"); + } else { + /* As the first code in the loop body, generate a block that looks + * like 'if (!condition) break;' as the loop termination condition. + */ + ir_rvalue *const not_cond = + new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond, + NULL); + + ir_if *const if_stmt = new(ctx) ir_if(not_cond); + + ir_jump *const break_stmt = + new(ctx) ir_loop_jump(ir_loop_jump::jump_break); + + if_stmt->then_instructions.push_tail(break_stmt); + stmt->body_instructions.push_tail(if_stmt); + } + } +} + + +ir_rvalue * +ast_iteration_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = talloc_parent(state); + + /* For-loops and while-loops start a new scope, but do-while loops do not. + */ + if (mode != ast_do_while) + state->symbols->push_scope(); + + if (init_statement != NULL) + init_statement->hir(instructions, state); + + ir_loop *const stmt = new(ctx) ir_loop(); + instructions->push_tail(stmt); + + /* Track the current loop and / or switch-statement nesting. + */ + ir_instruction *const nesting = state->loop_or_switch_nesting; + state->loop_or_switch_nesting = stmt; + + if (mode != ast_do_while) + condition_to_hir(stmt, state); + + if (body != NULL) + body->hir(& stmt->body_instructions, state); + + if (rest_expression != NULL) + rest_expression->hir(& stmt->body_instructions, state); + + if (mode == ast_do_while) + condition_to_hir(stmt, state); + + if (mode != ast_do_while) + state->symbols->pop_scope(); + + /* Restore previous nesting before returning. + */ + state->loop_or_switch_nesting = nesting; + + /* Loops do not have r-values. + */ + 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); + + return NULL; +} + + +ir_rvalue * +ast_struct_specifier::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = talloc_parent(state); + 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_list_typed (ast_declarator_list, decl_list, link, + &this->declarations) { + foreach_list_const (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_list_typed (ast_declarator_list, decl_list, link, + &this->declarations) { + 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_list_typed (ast_declaration, decl, link, + &decl_list->declarations) { + 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 != NULL) + ? field_type : glsl_type::error_type; + fields[i].name = decl->identifier; + i++; + } + } + + assert(i == decl_count); + + const char *name; + if (this->name == NULL) { + static unsigned anon_count = 1; + char buf[32]; + + snprintf(buf, sizeof(buf), "#anon_struct_%04x", anon_count); + anon_count++; + + name = strdup(buf); + } else { + name = this->name; + } + + glsl_type *t = new(ctx) glsl_type(fields, decl_count, name); + + YYLTYPE loc = this->get_location(); + if (!state->symbols->add_type(name, t)) { + _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name); + } else { + /* This logic is a bit tricky. It is an error to declare a structure at + * global scope if there is also a function with the same name. + */ + if ((state->current_function == NULL) + && (state->symbols->get_function(name) != NULL)) { + _mesa_glsl_error(& loc, state, "name `%s' previously defined", name); + } else { + t->generate_constructor(state->symbols); + } + + const glsl_type **s = (const glsl_type **) + realloc(state->user_structures, + sizeof(state->user_structures[0]) * + (state->num_user_structures + 1)); + if (s != NULL) { + s[state->num_user_structures] = t; + state->user_structures = s; + state->num_user_structures++; + } + } + + /* Structure type definitions do not have r-values. + */ + return NULL; +} -- cgit v1.2.3 From 18707eba1cd6c07fa8b63d0ba5b26f6433f1ae91 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 28 Jun 2010 23:38:04 -0700 Subject: glsl2: Check that returned expressions match the function return type. From my reading of the specification, implicit conversions are not allowed. ATI seems to agree, though nVidia allows it without warning. --- src/glsl/ast_to_hir.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 33eb27533f..45228649ad 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2151,9 +2151,17 @@ ast_jump_statement::hir(exec_list *instructions, opt_return_value->hir(instructions, state); assert(ret != NULL); - /* FINISHME: Make sure the type of the return value matches the return - * FINISHME: type of the enclosing function. - */ + /* Implicit conversions are not allowed for return values. */ + if (state->current_function->return_type != ret->type) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, + "`return' with wrong type %s, in function `%s' " + "returning %s", + ret->type->name, + state->current_function->function_name(), + state->current_function->return_type->name); + } inst = new(ctx) ir_return(ret); } else { -- cgit v1.2.3 From ac04c257e31fe012dac750bcf5bf3134ba07ebdc Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 29 Jun 2010 00:48:10 -0700 Subject: glsl2: Reject return types with qualifiers. Fixes piglit test return-qualifier.frag. --- src/glsl/ast_to_hir.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 45228649ad..5a13b74c03 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1984,6 +1984,7 @@ ast_function::hir(exec_list *instructions, ir_function_signature *sig = NULL; exec_list hir_parameters; + const char *const name = identifier; /* Convert the list of function parameters to HIR now so that they can be * used below to compare this function's signature with previously seen @@ -1999,11 +2000,19 @@ ast_function::hir(exec_list *instructions, assert(return_type != NULL); + /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec: + * "No qualifier is allowed on the return type of a function." + */ + if (this->return_type->has_qualifiers()) { + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(& loc, state, + "function `%s' return type has qualifiers", name); + } + /* Verify that this function's signature either doesn't match a previously * seen signature for a function with the same name, or, if a match is found, * that the previously seen signature does not have an associated definition. */ - const char *const name = identifier; f = state->symbols->get_function(name); if (f != NULL) { ir_function_signature *sig = f->exact_matching_signature(&hir_parameters); -- cgit v1.2.3 From 6de825650560198eb97f19e72b2d56e68e3d7a63 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 29 Jun 2010 09:59:40 -0700 Subject: glsl2: Check for non-void functions that don't have a return statement. This doesn't do any control flow analysis to ensure that the return statements are actually reached. Fixes piglit tests function5.frag and function-07.vert. --- src/glsl/ast_to_hir.cpp | 10 ++++++++++ src/glsl/glsl_parser_extras.h | 3 +++ 2 files changed, 13 insertions(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 5a13b74c03..c5df0b0fd0 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2097,6 +2097,7 @@ ast_function_definition::hir(exec_list *instructions, assert(state->current_function == NULL); state->current_function = signature; + state->found_return = false; /* Duplicate parameters declared in the prototype as concrete variables. * Add these to the symbol table. @@ -2128,6 +2129,14 @@ ast_function_definition::hir(exec_list *instructions, assert(state->current_function == signature); state->current_function = NULL; + if (!signature->return_type->is_void() && !state->found_return) { + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(& loc, state, "function `%s' has non-void return type " + "%s, but no return statement", + signature->function_name(), + signature->return_type->name); + } + /* Function definitions do not have r-values. */ return NULL; @@ -2186,6 +2195,7 @@ ast_jump_statement::hir(exec_list *instructions, inst = new(ctx) ir_return; } + state->found_return = true; instructions->push_tail(inst); break; } diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index cfe02e3b0c..726bafa7e4 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -51,6 +51,9 @@ struct _mesa_glsl_parse_state { */ class ir_function_signature *current_function; + /** Have we found a return statement in this function? */ + bool found_return; + /** Was there an error during compilation? */ bool error; -- cgit v1.2.3 From 12681610f54b40324e9e342dc25976c223614b81 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 25 Jun 2010 17:58:16 -0700 Subject: glsl_type: Remove vector and matrix constructor generators All scalar, vector, and matrix constructors are generated in-line during AST-to-HIR translation. There is no longer any need to generate function versions of the constructors. --- src/glsl/ast_to_hir.cpp | 1 - src/glsl/glsl_types.cpp | 365 ------------------------------------------------ src/glsl/glsl_types.h | 4 - 3 files changed, 370 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index c5df0b0fd0..54a8e9e00a 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -60,7 +60,6 @@ void _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { _mesa_glsl_initialize_variables(instructions, state); - _mesa_glsl_initialize_constructors(instructions, state); _mesa_glsl_initialize_functions(instructions, state); state->current_function = NULL; diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index 9a53fbdbcb..ff157080ff 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -210,371 +210,6 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const } -/** - * Generate the function intro for a constructor - * - * \param type Data type to be constructed - * \param count Number of parameters to this concrete constructor. Most - * types have at least two constructors. One will take a - * single scalar parameter and the other will take "N" - * scalar parameters. - * \param parameters Storage for the list of parameters. These are - * typically stored in an \c ir_function_signature. - * \param declarations Pointers to the variable declarations for the function - * parameters. These are used later to avoid having to use - * the symbol table. - */ -static ir_function_signature * -generate_constructor_intro(void *ctx, - const glsl_type *type, unsigned parameter_count, - ir_variable **declarations) -{ - /* Names of parameters used in vector and matrix constructors - */ - static const char *const names[] = { - "a", "b", "c", "d", "e", "f", "g", "h", - "i", "j", "k", "l", "m", "n", "o", "p", - }; - - assert(parameter_count <= Elements(names)); - - const glsl_type *const parameter_type = type->get_base_type(); - - ir_function_signature *const signature = new(ctx) ir_function_signature(type); - - for (unsigned i = 0; i < parameter_count; i++) { - ir_variable *var = new(ctx) ir_variable(parameter_type, names[i]); - - var->mode = ir_var_in; - signature->parameters.push_tail(var); - - declarations[i] = var; - } - - ir_variable *retval = new(ctx) ir_variable(type, "__retval"); - signature->body.push_tail(retval); - - declarations[16] = retval; - return signature; -} - - -/** - * Generate the body of a vector constructor that takes a single scalar - */ -static void -generate_vec_body_from_scalar(void *ctx, - exec_list *instructions, - ir_variable **declarations) -{ - ir_instruction *inst; - - /* Generate a single assignment of the parameter to __retval.x and return - * __retval.xxxx for however many vector components there are. - */ - ir_dereference *const lhs_ref = - new(ctx) ir_dereference_variable(declarations[16]); - ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]); - - ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1); - - inst = new(ctx) ir_assignment(lhs, rhs, NULL); - instructions->push_tail(inst); - - ir_dereference *const retref = new(ctx) ir_dereference_variable(declarations[16]); - - ir_swizzle *retval = new(ctx) ir_swizzle(retref, 0, 0, 0, 0, - declarations[16]->type->vector_elements); - - inst = new(ctx) ir_return(retval); - instructions->push_tail(inst); -} - - -/** - * Generate the body of a vector constructor that takes multiple scalars - */ -static void -generate_vec_body_from_N_scalars(void *ctx, - exec_list *instructions, - ir_variable **declarations) -{ - ir_instruction *inst; - const glsl_type *const vec_type = declarations[16]->type; - - /* Generate an assignment of each parameter to a single component of - * __retval.x and return __retval. - */ - for (unsigned i = 0; i < vec_type->vector_elements; i++) { - ir_dereference *const lhs_ref = - new(ctx) ir_dereference_variable(declarations[16]); - ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]); - - ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1); - - inst = new(ctx) ir_assignment(lhs, rhs, NULL); - instructions->push_tail(inst); - } - - ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]); - - inst = new(ctx) ir_return(retval); - instructions->push_tail(inst); -} - - -/** - * Generate the body of a matrix constructor that takes a single scalar - */ -static void -generate_mat_body_from_scalar(void *ctx, - exec_list *instructions, - ir_variable **declarations) -{ - ir_instruction *inst; - - /* Generate an assignment of the parameter to the X component of a - * temporary vector. Set the remaining fields of the vector to 0. The - * size of the vector is equal to the number of rows of the matrix. - * - * Set each column of the matrix to a successive "rotation" of the - * temporary vector. This fills the matrix with 0s, but writes the single - * scalar along the matrix's diagonal. - * - * For a mat4x3, this is equivalent to: - * - * vec3 tmp; - * mat4x3 __retval; - * tmp.x = a; - * tmp.y = 0.0; - * tmp.z = 0.0; - * __retval[0] = tmp.xyy; - * __retval[1] = tmp.yxy; - * __retval[2] = tmp.yyx; - * __retval[3] = tmp.yyy; - */ - const glsl_type *const column_type = declarations[16]->type->column_type(); - const glsl_type *const row_type = declarations[16]->type->row_type(); - - ir_variable *const column = new(ctx) ir_variable(column_type, "v"); - - instructions->push_tail(column); - - ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column); - ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]); - - ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1); - - inst = new(ctx) ir_assignment(lhs, rhs, NULL); - instructions->push_tail(inst); - - for (unsigned i = 1; i < column_type->vector_elements; i++) { - ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column); - ir_constant *const zero = new(ctx) ir_constant(0.0f); - - ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1); - - inst = new(ctx) ir_assignment(lhs, zero, NULL); - instructions->push_tail(inst); - } - - - for (unsigned i = 0; i < row_type->vector_elements; i++) { - static const unsigned swiz[] = { 1, 1, 1, 0, 1, 1, 1 }; - ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(column); - - /* This will be .xyyy when i=0, .yxyy when i=1, etc. - */ - ir_swizzle *rhs = new(ctx) ir_swizzle(rhs_ref, swiz[3 - i], swiz[4 - i], - swiz[5 - i], swiz[6 - i], - column_type->vector_elements); - - ir_constant *const idx = new(ctx) ir_constant(int(i)); - ir_dereference *const lhs = - new(ctx) ir_dereference_array(declarations[16], idx); - - inst = new(ctx) ir_assignment(lhs, rhs, NULL); - instructions->push_tail(inst); - } - - ir_dereference *const retval = new(ctx) ir_dereference_variable(declarations[16]); - inst = new(ctx) ir_return(retval); - instructions->push_tail(inst); -} - - -/** - * Generate the body of a vector constructor that takes multiple scalars - */ -static void -generate_mat_body_from_N_scalars(void *ctx, - exec_list *instructions, - ir_variable **declarations) -{ - ir_instruction *inst; - const glsl_type *const row_type = declarations[16]->type->row_type(); - const glsl_type *const column_type = declarations[16]->type->column_type(); - - /* Generate an assignment of each parameter to a single component of - * of a particular column of __retval and return __retval. - */ - for (unsigned i = 0; i < column_type->vector_elements; i++) { - for (unsigned j = 0; j < row_type->vector_elements; j++) { - ir_constant *row_index = new(ctx) ir_constant(int(i)); - ir_dereference *const row_access = - new(ctx) ir_dereference_array(declarations[16], row_index); - - ir_swizzle *component_access = new(ctx) ir_swizzle(row_access, - j, 0, 0, 0, 1); - - const unsigned param = (i * row_type->vector_elements) + j; - ir_dereference *const rhs = - new(ctx) ir_dereference_variable(declarations[param]); - - inst = new(ctx) ir_assignment(component_access, rhs, NULL); - instructions->push_tail(inst); - } - } - - ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]); - - inst = new(ctx) ir_return(retval); - instructions->push_tail(inst); -} - - -/** - * Generate the constructors for a set of GLSL types - * - * Constructor implementations are added to \c instructions, and the symbols - * are added to \c symtab. - */ -static void -generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types, - unsigned num_types, exec_list *instructions) -{ - void *ctx = symtab; - ir_variable *declarations[17]; - - for (unsigned i = 0; i < num_types; i++) { - /* Only numeric and boolean vectors and matrices get constructors here. - * Structures need to be handled elsewhere. It is expected that scalar - * constructors are never actually called, so they are not generated. - */ - if (!types[i].is_numeric() && !types[i].is_boolean()) - continue; - - if (types[i].is_scalar()) - continue; - - /* Generate the function block, add it to the symbol table, and emit it. - */ - ir_function *const f = new(ctx) ir_function(types[i].name); - - bool added = symtab->add_function(types[i].name, f); - assert(added); - - instructions->push_tail(f); - - /* Each type has several basic constructors. The total number of forms - * depends on the derived type. - * - * Vectors: 1 scalar, N scalars - * Matrices: 1 scalar, NxM scalars - * - * Several possible types of constructors are not included in this list. - * - * Scalar constructors are not included. The expectation is that the - * IR generator won't actually generate these as constructor calls. The - * expectation is that it will just generate the necessary type - * conversion. - * - * Matrix contructors from matrices are also not included. The - * expectation is that the IR generator will generate a call to the - * appropriate from-scalars constructor. - */ - ir_function_signature *const sig = - generate_constructor_intro(ctx, &types[i], 1, declarations); - f->add_signature(sig); - - if (types[i].is_vector()) { - generate_vec_body_from_scalar(ctx, &sig->body, declarations); - - ir_function_signature *const vec_sig = - generate_constructor_intro(ctx, - &types[i], types[i].vector_elements, - declarations); - f->add_signature(vec_sig); - - generate_vec_body_from_N_scalars(ctx, &vec_sig->body, declarations); - } else { - assert(types[i].is_matrix()); - - generate_mat_body_from_scalar(ctx, &sig->body, declarations); - - ir_function_signature *const mat_sig = - generate_constructor_intro(ctx, - &types[i], - (types[i].vector_elements - * types[i].matrix_columns), - declarations); - f->add_signature(mat_sig); - - generate_mat_body_from_N_scalars(ctx, &mat_sig->body, declarations); - } - } -} - - -void -generate_110_constructors(glsl_symbol_table *symtab, exec_list *instructions) -{ - generate_constructor(symtab, builtin_core_types, - Elements(builtin_core_types), instructions); -} - - -void -generate_120_constructors(glsl_symbol_table *symtab, exec_list *instructions) -{ - generate_110_constructors(symtab, instructions); - - generate_constructor(symtab, builtin_120_types, - Elements(builtin_120_types), instructions); -} - - -void -generate_130_constructors(glsl_symbol_table *symtab, exec_list *instructions) -{ - generate_120_constructors(symtab, instructions); - - generate_constructor(symtab, builtin_130_types, - Elements(builtin_130_types), instructions); -} - - -void -_mesa_glsl_initialize_constructors(exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - switch (state->language_version) { - case 110: - generate_110_constructors(state->symbols, instructions); - break; - case 120: - generate_120_constructors(state->symbols, instructions); - break; - case 130: - generate_130_constructors(state->symbols, instructions); - break; - default: - /* error */ - break; - } -} - - glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) : base_type(GLSL_TYPE_ARRAY), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h index 93cf60be8d..b753742b91 100644 --- a/src/glsl/glsl_types.h +++ b/src/glsl/glsl_types.h @@ -440,10 +440,6 @@ extern "C" { extern void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state); -extern void -_mesa_glsl_initialize_constructors(struct exec_list *instructions, - struct _mesa_glsl_parse_state *state); - #ifdef __cplusplus } #endif -- cgit v1.2.3 From 49e3577b91f44013746f7a3db411e7041b7d899e Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 28 Jun 2010 11:54:57 -0700 Subject: glsl_type: Add get_record_instance method --- src/glsl/ast_to_hir.cpp | 4 +-- src/glsl/glsl_types.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ src/glsl/glsl_types.h | 12 +++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 54a8e9e00a..664e4687c4 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2383,7 +2383,6 @@ ir_rvalue * ast_struct_specifier::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); unsigned decl_count = 0; /* Make an initial pass over the list of structure fields to determine how @@ -2446,7 +2445,8 @@ ast_struct_specifier::hir(exec_list *instructions, name = this->name; } - glsl_type *t = new(ctx) glsl_type(fields, decl_count, name); + const glsl_type *t = + glsl_type::get_record_instance(fields, decl_count, name); YYLTYPE loc = this->get_location(); if (!state->symbols->add_type(name, t)) { diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index 158659c71e..672a7f7cd1 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -32,6 +32,7 @@ extern "C" { } hash_table *glsl_type::array_types = NULL; +hash_table *glsl_type::record_types = NULL; glsl_type::glsl_type(GLenum gl_type, unsigned base_type, unsigned vector_elements, @@ -384,6 +385,77 @@ glsl_type::get_array_instance(void *ctx, const glsl_type *base, } +int +glsl_type::record_key_compare(const void *a, const void *b) +{ + const glsl_type *const key1 = (glsl_type *) a; + const glsl_type *const key2 = (glsl_type *) b; + + /* Return zero is the types match (there is zero difference) or non-zero + * otherwise. + */ + if (strcmp(key1->name, key2->name) != 0) + return 1; + + if (key1->length != key2->length) + return 1; + + for (unsigned i = 0; i < key1->length; i++) + /* FINISHME: Is the name of the structure field also significant? */ + if (key1->fields.structure[i].type != key2->fields.structure[i].type) + return 1; + + return 0; +} + + +unsigned +glsl_type::record_key_hash(const void *a) +{ + const glsl_type *const key = (glsl_type *) a; + char hash_key[128]; + unsigned size = 0; + + size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length); + + for (unsigned i = 0; i < key->length; i++) { + if (size >= sizeof(hash_key)) + break; + + size += snprintf(& hash_key[size], sizeof(hash_key) - size, + "%p", key->fields.structure[i].type); + } + + return hash_table_string_hash(& hash_key); +} + + +const glsl_type * +glsl_type::get_record_instance(const glsl_struct_field *fields, + unsigned num_fields, + const char *name) +{ + const glsl_type key(fields, num_fields, name); + + if (record_types == NULL) { + record_types = hash_table_ctor(64, record_key_hash, record_key_compare); + } + + const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key); + if (t == NULL) { + t = new(NULL) glsl_type(fields, num_fields, name); + + hash_table_insert(record_types, (void *) t, t); + } + + assert(t->base_type == GLSL_TYPE_STRUCT); + assert(t->length == num_fields); + assert(strcmp(t->name, name) == 0); + + return t; +} + + const glsl_type * glsl_type::field_type(const char *name) const { diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h index e1bfd34f4e..a1c9fae4f9 100644 --- a/src/glsl/glsl_types.h +++ b/src/glsl/glsl_types.h @@ -205,6 +205,12 @@ struct glsl_type { const glsl_type *base, unsigned elements); + /** + * Get the instance of a record type + */ + static const glsl_type *get_record_instance(const glsl_struct_field *fields, + unsigned num_fields, + const char *name); /** * Generate the constructor for this type and add it to the symbol table */ @@ -407,6 +413,12 @@ private: static int array_key_compare(const void *a, const void *b); static unsigned array_key_hash(const void *key); + /** Hash table containing the known record types. */ + static struct hash_table *record_types; + + static int record_key_compare(const void *a, const void *b); + static unsigned record_key_hash(const void *key); + /** * \name Pointers to various type singletons */ -- cgit v1.2.3 From 506199b852390e14a1d78392285bee8f06b6ede7 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 29 Jun 2010 15:59:27 -0700 Subject: glsl2: Keep the same number of components in implicit conversions. Fixes piglit test glsl-implicit-conversion-01. --- src/glsl/ast_to_hir.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 664e4687c4..ba29240092 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -109,6 +109,12 @@ apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, if (!to->is_float() || !from->type->is_numeric()) return false; + /* Convert to a floating point type with the same number of components + * as the original type - i.e. int to float, not int to vec4. + */ + to = glsl_type::get_instance(GLSL_TYPE_FLOAT, from->type->vector_elements, + from->type->matrix_columns); + switch (from->type->base_type) { case GLSL_TYPE_INT: from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL); -- cgit v1.2.3 From 953ff1283d3d52e6a6b4850c2b0b574111625010 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 25 Jun 2010 13:14:37 -0700 Subject: glsl2: Use _mesa_glsl_parse_state as the talloc parent, not glsl_shader. _mesa_glsl_parse_state should be the parent for all temporary allocation done while compiling a shader. glsl_shader should only be used as the parent for the shader's final IR---the _result_ of compilation. Since many IR instructions may be added or discarded during optimization passes, IR should not ever be allocated to glsl_shader directly. Done via sed -i s/talloc_parent(state)/state/g and s/talloc_parent(st)/st/g. This also removes a ton of talloc_parent calls, which may help performance. --- src/glsl/ast_function.cpp | 10 +-- src/glsl/ast_to_hir.cpp | 22 ++--- src/glsl/glsl_lexer.lpp | 2 +- src/glsl/glsl_parser.ypp | 174 +++++++++++++++++++-------------------- src/glsl/hir_field_selection.cpp | 2 +- src/glsl/ir_reader.cpp | 30 +++---- 6 files changed, 120 insertions(+), 120 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index f3074a362d..b681115387 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -59,7 +59,7 @@ process_call(exec_list *instructions, ir_function *f, YYLTYPE *loc, exec_list *actual_parameters, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; const ir_function_signature *sig = f->matching_signature(actual_parameters); @@ -119,7 +119,7 @@ match_function_by_name(exec_list *instructions, const char *name, YYLTYPE *loc, exec_list *actual_parameters, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; ir_function *f = state->symbols->get_function(name); if (f == NULL) { @@ -244,7 +244,7 @@ process_array_constructor(exec_list *instructions, YYLTYPE *loc, exec_list *parameters, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; /* Array constructors come in two forms: sized and unsized. Sized array * constructors look like 'vec4[2](a, b)', where 'a' and 'b' are vec4 * variables. In this case the number of parameters must exactly match the @@ -318,7 +318,7 @@ constant_record_constructor(const glsl_type *constructor_type, YYLTYPE *loc, exec_list *parameters, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; bool all_parameters_are_constant = true; exec_node *node = parameters->head; @@ -862,7 +862,7 @@ ir_rvalue * ast_function_expression::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; /* There are three sorts of function calls. * * 1. contstructors - The first subexpression is an ast_type_specifier. diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index ba29240092..53f17de7b9 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -86,7 +86,7 @@ static bool apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; if (to->base_type == from->type->base_type) return true; @@ -473,7 +473,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, ir_rvalue *lhs, ir_rvalue *rhs, YYLTYPE lhs_loc) { - void *ctx = talloc_parent(state); + void *ctx = state; bool error_emitted = (lhs->type->is_error() || rhs->type->is_error()); if (!error_emitted) { @@ -550,7 +550,7 @@ static ir_variable * generate_temporary(const glsl_type *type, exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; char *name = (char *) malloc(sizeof(char) * 13); snprintf(name, 13, "tmp_%08X", state->temp_index); @@ -600,7 +600,7 @@ ir_rvalue * ast_expression::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; static const int operations[AST_NUM_OPERATORS] = { -1, /* ast_assign doesn't convert to ir_expression. */ -1, /* ast_plus doesn't convert to ir_expression. */ @@ -1544,7 +1544,7 @@ ir_rvalue * ast_declarator_list::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; const struct glsl_type *decl_type; const char *type_name = NULL; ir_rvalue *result = NULL; @@ -1883,7 +1883,7 @@ ir_rvalue * ast_parameter_declarator::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; const struct glsl_type *type; const char *name = NULL; YYLTYPE loc = this->get_location(); @@ -1984,7 +1984,7 @@ ir_rvalue * ast_function::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; ir_function *f = NULL; ir_function_signature *sig = NULL; exec_list hir_parameters; @@ -2152,7 +2152,7 @@ ir_rvalue * ast_jump_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; switch (mode) { case ast_return: { @@ -2255,7 +2255,7 @@ ir_rvalue * ast_selection_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; ir_rvalue *const condition = this->condition->hir(instructions, state); @@ -2295,7 +2295,7 @@ void ast_iteration_statement::condition_to_hir(ir_loop *stmt, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; if (condition != NULL) { ir_rvalue *const cond = @@ -2331,7 +2331,7 @@ ir_rvalue * ast_iteration_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; /* For-loops and while-loops start a new scope, but do-while loops do not. */ diff --git a/src/glsl/glsl_lexer.lpp b/src/glsl/glsl_lexer.lpp index fa439f1278..f236a15682 100644 --- a/src/glsl/glsl_lexer.lpp +++ b/src/glsl/glsl_lexer.lpp @@ -313,7 +313,7 @@ precision return PRECISION; [_a-zA-Z][_a-zA-Z0-9]* { struct _mesa_glsl_parse_state *state = yyextra; - void *ctx = talloc_parent(state); + void *ctx = state; yylval->identifier = talloc_strdup(ctx, yytext); return IDENTIFIER; } diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp index 4132495f40..d894a968ec 100644 --- a/src/glsl/glsl_parser.ypp +++ b/src/glsl/glsl_parser.ypp @@ -255,35 +255,35 @@ variable_identifier: primary_expression: variable_identifier { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.identifier = $1; } | INTCONSTANT { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.int_constant = $1; } | UINTCONSTANT { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.uint_constant = $1; } | FLOATCONSTANT { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.float_constant = $1; } | BOOLCONSTANT { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.bool_constant = $1; @@ -298,7 +298,7 @@ postfix_expression: primary_expression | postfix_expression '[' integer_expression ']' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL); $$->set_location(yylloc); } @@ -314,20 +314,20 @@ postfix_expression: } | postfix_expression '.' IDENTIFIER { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.identifier = $3; } | postfix_expression INC_OP { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL); $$->set_location(yylloc); } | postfix_expression DEC_OP { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL); $$->set_location(yylloc); } @@ -345,7 +345,7 @@ function_call_or_method: function_call_generic | postfix_expression '.' function_call_generic { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL); $$->set_location(yylloc); } @@ -386,20 +386,20 @@ function_call_header: function_identifier: type_specifier { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_function_expression($1); $$->set_location(yylloc); } | IDENTIFIER { - void *ctx = talloc_parent(state); + void *ctx = state; ast_expression *callee = new(ctx) ast_expression($1); $$ = new(ctx) ast_function_expression(callee); $$->set_location(yylloc); } | FIELD_SELECTION { - void *ctx = talloc_parent(state); + void *ctx = state; ast_expression *callee = new(ctx) ast_expression($1); $$ = new(ctx) ast_function_expression(callee); $$->set_location(yylloc); @@ -411,19 +411,19 @@ unary_expression: postfix_expression | INC_OP unary_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL); $$->set_location(yylloc); } | DEC_OP unary_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL); $$->set_location(yylloc); } | unary_operator unary_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression($1, $2, NULL, NULL); $$->set_location(yylloc); } @@ -441,19 +441,19 @@ multiplicative_expression: unary_expression | multiplicative_expression '*' unary_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3); $$->set_location(yylloc); } | multiplicative_expression '/' unary_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_div, $1, $3); $$->set_location(yylloc); } | multiplicative_expression '%' unary_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3); $$->set_location(yylloc); } @@ -463,13 +463,13 @@ additive_expression: multiplicative_expression | additive_expression '+' multiplicative_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_add, $1, $3); $$->set_location(yylloc); } | additive_expression '-' multiplicative_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3); $$->set_location(yylloc); } @@ -479,13 +479,13 @@ shift_expression: additive_expression | shift_expression LEFT_OP additive_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3); $$->set_location(yylloc); } | shift_expression RIGHT_OP additive_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3); $$->set_location(yylloc); } @@ -495,25 +495,25 @@ relational_expression: shift_expression | relational_expression '<' shift_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_less, $1, $3); $$->set_location(yylloc); } | relational_expression '>' shift_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3); $$->set_location(yylloc); } | relational_expression LE_OP shift_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3); $$->set_location(yylloc); } | relational_expression GE_OP shift_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3); $$->set_location(yylloc); } @@ -523,13 +523,13 @@ equality_expression: relational_expression | equality_expression EQ_OP relational_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3); $$->set_location(yylloc); } | equality_expression NE_OP relational_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3); $$->set_location(yylloc); } @@ -539,7 +539,7 @@ and_expression: equality_expression | and_expression '&' equality_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); $$->set_location(yylloc); } @@ -549,7 +549,7 @@ exclusive_or_expression: and_expression | exclusive_or_expression '^' and_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3); $$->set_location(yylloc); } @@ -559,7 +559,7 @@ inclusive_or_expression: exclusive_or_expression | inclusive_or_expression '|' exclusive_or_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); $$->set_location(yylloc); } @@ -569,7 +569,7 @@ logical_and_expression: inclusive_or_expression | logical_and_expression AND_OP inclusive_or_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3); $$->set_location(yylloc); } @@ -579,7 +579,7 @@ logical_xor_expression: logical_and_expression | logical_xor_expression XOR_OP logical_and_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3); $$->set_location(yylloc); } @@ -589,7 +589,7 @@ logical_or_expression: logical_xor_expression | logical_or_expression OR_OP logical_xor_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3); $$->set_location(yylloc); } @@ -599,7 +599,7 @@ conditional_expression: logical_or_expression | logical_or_expression '?' expression ':' assignment_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5); $$->set_location(yylloc); } @@ -609,7 +609,7 @@ assignment_expression: conditional_expression | unary_expression assignment_operator assignment_expression { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression($2, $1, $3, NULL); $$->set_location(yylloc); } @@ -636,7 +636,7 @@ expression: } | expression ',' assignment_expression { - void *ctx = talloc_parent(state); + void *ctx = state; if ($1->oper != ast_sequence) { $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); $$->set_location(yylloc); @@ -700,7 +700,7 @@ function_header_with_parameters: function_header: fully_specified_type IDENTIFIER '(' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_function(); $$->set_location(yylloc); $$->return_type = $1; @@ -711,7 +711,7 @@ function_header: parameter_declarator: type_specifier IDENTIFIER { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_parameter_declarator(); $$->set_location(yylloc); $$->type = new(ctx) ast_fully_specified_type(); @@ -721,7 +721,7 @@ parameter_declarator: } | type_specifier IDENTIFIER '[' constant_expression ']' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_parameter_declarator(); $$->set_location(yylloc); $$->type = new(ctx) ast_fully_specified_type(); @@ -748,7 +748,7 @@ parameter_declaration: } | parameter_type_qualifier parameter_qualifier parameter_type_specifier { - void *ctx = talloc_parent(state); + void *ctx = state; $1.i |= $2.i; $$ = new(ctx) ast_parameter_declarator(); @@ -759,7 +759,7 @@ parameter_declaration: } | parameter_qualifier parameter_type_specifier { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_parameter_declarator(); $$->set_location(yylloc); $$->type = new(ctx) ast_fully_specified_type(); @@ -783,7 +783,7 @@ init_declarator_list: single_declaration | init_declarator_list ',' IDENTIFIER { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL); decl->set_location(yylloc); @@ -792,7 +792,7 @@ init_declarator_list: } | init_declarator_list ',' IDENTIFIER '[' ']' { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL); decl->set_location(yylloc); @@ -801,7 +801,7 @@ init_declarator_list: } | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL); decl->set_location(yylloc); @@ -810,7 +810,7 @@ init_declarator_list: } | init_declarator_list ',' IDENTIFIER '[' ']' '=' initializer { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7); decl->set_location(yylloc); @@ -819,7 +819,7 @@ init_declarator_list: } | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' '=' initializer { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8); decl->set_location(yylloc); @@ -828,7 +828,7 @@ init_declarator_list: } | init_declarator_list ',' IDENTIFIER '=' initializer { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, $5); decl->set_location(yylloc); @@ -841,7 +841,7 @@ init_declarator_list: single_declaration: fully_specified_type { - void *ctx = talloc_parent(state); + void *ctx = state; if ($1->specifier->type_specifier != ast_struct) { _mesa_glsl_error(& @1, state, "empty declaration list\n"); YYERROR; @@ -852,7 +852,7 @@ single_declaration: } | fully_specified_type IDENTIFIER { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); $$ = new(ctx) ast_declarator_list($1); @@ -861,7 +861,7 @@ single_declaration: } | fully_specified_type IDENTIFIER '[' ']' { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL); $$ = new(ctx) ast_declarator_list($1); @@ -870,7 +870,7 @@ single_declaration: } | fully_specified_type IDENTIFIER '[' constant_expression ']' { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL); $$ = new(ctx) ast_declarator_list($1); @@ -879,7 +879,7 @@ single_declaration: } | fully_specified_type IDENTIFIER '[' ']' '=' initializer { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6); $$ = new(ctx) ast_declarator_list($1); @@ -888,7 +888,7 @@ single_declaration: } | fully_specified_type IDENTIFIER '[' constant_expression ']' '=' initializer { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7); $$ = new(ctx) ast_declarator_list($1); @@ -897,7 +897,7 @@ single_declaration: } | fully_specified_type IDENTIFIER '=' initializer { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); $$ = new(ctx) ast_declarator_list($1); @@ -906,7 +906,7 @@ single_declaration: } | INVARIANT IDENTIFIER // Vertex only. { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); $$ = new(ctx) ast_declarator_list(NULL); @@ -920,14 +920,14 @@ single_declaration: fully_specified_type: type_specifier { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_fully_specified_type(); $$->set_location(yylloc); $$->specifier = $1; } | type_qualifier type_specifier { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_fully_specified_type(); $$->set_location(yylloc); $$->qualifier = $1.q; @@ -998,19 +998,19 @@ type_specifier_no_prec: type_specifier_nonarray: basic_type_specifier_nonarray { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_type_specifier($1); $$->set_location(yylloc); } | struct_specifier { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_type_specifier($1); $$->set_location(yylloc); } | IDENTIFIER { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_type_specifier($1); $$->set_location(yylloc); } @@ -1112,13 +1112,13 @@ precision_qualifier: struct_specifier: STRUCT IDENTIFIER '{' struct_declaration_list '}' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_struct_specifier($2, $4); $$->set_location(yylloc); } | STRUCT '{' struct_declaration_list '}' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_struct_specifier(NULL, $3); $$->set_location(yylloc); } @@ -1140,7 +1140,7 @@ struct_declaration_list: struct_declaration: type_specifier struct_declarator_list ';' { - void *ctx = talloc_parent(state); + void *ctx = state; ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); type->set_location(yylloc); @@ -1168,13 +1168,13 @@ struct_declarator_list: struct_declarator: IDENTIFIER { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_declaration($1, false, NULL, NULL); $$->set_location(yylloc); } | IDENTIFIER '[' constant_expression ']' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_declaration($1, true, $3, NULL); $$->set_location(yylloc); } @@ -1217,13 +1217,13 @@ simple_statement: compound_statement: '{' '}' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_compound_statement(true, NULL); $$->set_location(yylloc); } | '{' statement_list '}' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_compound_statement(true, $2); $$->set_location(yylloc); } @@ -1237,13 +1237,13 @@ statement_no_new_scope: compound_statement_no_new_scope: '{' '}' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_compound_statement(false, NULL); $$->set_location(yylloc); } | '{' statement_list '}' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_compound_statement(false, $2); $$->set_location(yylloc); } @@ -1274,13 +1274,13 @@ statement_list: expression_statement: ';' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_statement(NULL); $$->set_location(yylloc); } | expression ';' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_expression_statement($1); $$->set_location(yylloc); } @@ -1289,7 +1289,7 @@ expression_statement: selection_statement_matched: IF '(' expression ')' statement_matched ELSE statement_matched { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_selection_statement($3, $5, $7); $$->set_location(yylloc); } @@ -1298,19 +1298,19 @@ selection_statement_matched: selection_statement_unmatched: IF '(' expression ')' statement_matched { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_selection_statement($3, $5, NULL); $$->set_location(yylloc); } | IF '(' expression ')' statement_unmatched { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_selection_statement($3, $5, NULL); $$->set_location(yylloc); } | IF '(' expression ')' statement_matched ELSE statement_unmatched { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_selection_statement($3, $5, $7); $$->set_location(yylloc); } @@ -1323,7 +1323,7 @@ condition: } | fully_specified_type IDENTIFIER '=' initializer { - void *ctx = talloc_parent(state); + void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); ast_declarator_list *declarator = new(ctx) ast_declarator_list($1); decl->set_location(yylloc); @@ -1346,21 +1346,21 @@ case_label: iteration_statement: WHILE '(' condition ')' statement_no_new_scope { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, NULL, $3, NULL, $5); $$->set_location(yylloc); } | DO statement WHILE '(' expression ')' ';' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, NULL, $5, NULL, $2); $$->set_location(yylloc); } | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, $3, $4.cond, $4.rest, $6); $$->set_location(yylloc); @@ -1397,31 +1397,31 @@ for_rest_statement: jump_statement: CONTINUE ';' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); $$->set_location(yylloc); } | BREAK ';' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); $$->set_location(yylloc); } | RETURN ';' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); $$->set_location(yylloc); } | RETURN expression ';' { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2); $$->set_location(yylloc); } | DISCARD ';' // Fragment shader only. { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); $$->set_location(yylloc); } @@ -1435,7 +1435,7 @@ external_declaration: function_definition: function_prototype compound_statement_no_new_scope { - void *ctx = talloc_parent(state); + void *ctx = state; $$ = new(ctx) ast_function_definition(); $$->set_location(yylloc); $$->prototype = $1; diff --git a/src/glsl/hir_field_selection.cpp b/src/glsl/hir_field_selection.cpp index e2efff60d3..5500e09d7e 100644 --- a/src/glsl/hir_field_selection.cpp +++ b/src/glsl/hir_field_selection.cpp @@ -33,7 +33,7 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr, exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = talloc_parent(state); + void *ctx = state; ir_rvalue *result = NULL; ir_rvalue *op; diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp index 03dce0d684..5ba76e29ea 100644 --- a/src/glsl/ir_reader.cpp +++ b/src/glsl/ir_reader.cpp @@ -191,7 +191,7 @@ scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions, static ir_function * read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() < 3) { ir_read_error(st, list, "Expected (function (signature ...) ...)"); return NULL; @@ -235,7 +235,7 @@ static void read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list, bool skip_body) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() != 4) { ir_read_error(st, list, "Expected (signature (parameters ...) " "( ...))"); @@ -334,7 +334,7 @@ static ir_instruction * read_instruction(_mesa_glsl_parse_state *st, s_expression *expr, ir_loop *loop_ctx) { - void *ctx = talloc_parent(st); + void *ctx = st; s_symbol *symbol = SX_AS_SYMBOL(expr); if (symbol != NULL) { if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL) @@ -376,7 +376,7 @@ read_instruction(_mesa_glsl_parse_state *st, s_expression *expr, static ir_variable * read_declaration(_mesa_glsl_parse_state *st, s_list *list) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() != 4) { ir_read_error(st, list, "expected (declare () " ")"); @@ -448,7 +448,7 @@ read_declaration(_mesa_glsl_parse_state *st, s_list *list) static ir_if * read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() != 4) { ir_read_error(st, list, "expected (if ( ...) " "( ...))"); @@ -480,7 +480,7 @@ read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx) static ir_loop * read_loop(_mesa_glsl_parse_state *st, s_list *list) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() != 6) { ir_read_error(st, list, "expected (loop " " )"); @@ -508,7 +508,7 @@ read_loop(_mesa_glsl_parse_state *st, s_list *list) static ir_return * read_return(_mesa_glsl_parse_state *st, s_list *list) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() != 2) { ir_read_error(st, list, "expected (return )"); return NULL; @@ -564,7 +564,7 @@ read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr) static ir_assignment * read_assignment(_mesa_glsl_parse_state *st, s_list *list) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() != 4) { ir_read_error(st, list, "expected (assign )"); return NULL; @@ -599,7 +599,7 @@ read_assignment(_mesa_glsl_parse_state *st, s_list *list) static ir_call * read_call(_mesa_glsl_parse_state *st, s_list *list) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() != 3) { ir_read_error(st, list, "expected (call ( ...))"); return NULL; @@ -644,7 +644,7 @@ read_call(_mesa_glsl_parse_state *st, s_list *list) static ir_expression * read_expression(_mesa_glsl_parse_state *st, s_list *list) { - void *ctx = talloc_parent(st); + void *ctx = st; const unsigned list_length = list->length(); if (list_length < 4) { ir_read_error(st, list, "expected (expression " @@ -749,7 +749,7 @@ read_swizzle(_mesa_glsl_parse_state *st, s_list *list) static ir_constant * read_constant(_mesa_glsl_parse_state *st, s_list *list) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() != 3) { ir_read_error(st, list, "expected (constant ( ... ))"); return NULL; @@ -840,7 +840,7 @@ read_dereference(_mesa_glsl_parse_state *st, s_expression *expr) static ir_dereference * read_var_ref(_mesa_glsl_parse_state *st, s_list *list) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() != 2) { ir_read_error(st, list, "expected (var_ref )"); return NULL; @@ -863,7 +863,7 @@ read_var_ref(_mesa_glsl_parse_state *st, s_list *list) static ir_dereference * read_array_ref(_mesa_glsl_parse_state *st, s_list *list) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() != 3) { ir_read_error(st, list, "expected (array_ref )"); return NULL; @@ -884,7 +884,7 @@ read_array_ref(_mesa_glsl_parse_state *st, s_list *list) static ir_dereference * read_record_ref(_mesa_glsl_parse_state *st, s_list *list) { - void *ctx = talloc_parent(st); + void *ctx = st; if (list->length() != 3) { ir_read_error(st, list, "expected (record_ref )"); return NULL; @@ -920,7 +920,7 @@ valid_texture_list_length(ir_texture_opcode op, s_list *list) static ir_texture * read_texture(_mesa_glsl_parse_state *st, s_list *list) { - void *ctx = talloc_parent(st); + void *ctx = st; s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head); assert(tag != NULL); -- cgit v1.2.3 From c7f4ff193a6f7cfae2e4cdc6c4b9162a16226dc0 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 30 Jun 2010 11:57:43 -0700 Subject: glsl2: Fix storing of dead memory in the symbol table. decl->identifier is part of the AST, so it doesn't live very long. Instead, add var->name which is owned by var. --- src/glsl/ast_to_hir.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 53f17de7b9..a0ca7e5f6d 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1851,7 +1851,7 @@ ast_declarator_list::hir(exec_list *instructions, "const declaration of `%s' must be initialized"); } - /* Add the vairable to the symbol table after processing the initializer. + /* Add the variable to the symbol table after processing the initializer. * This differs from most C-like languages, but it follows the GLSL * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50 * spec: @@ -1861,7 +1861,7 @@ ast_declarator_list::hir(exec_list *instructions, * being declared if not." */ const bool added_variable = - state->symbols->add_variable(decl->identifier, var); + state->symbols->add_variable(var->name, var); assert(added_variable); } -- cgit v1.2.3 From 77049a702ad54e09c4102fe8c964e069944f83e5 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 30 Jun 2010 14:11:00 -0700 Subject: glsl2: Implement AST->HIR support for the "discard" instruction. --- src/glsl/ast_to_hir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index a0ca7e5f6d..7d966f848b 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2206,13 +2206,13 @@ ast_jump_statement::hir(exec_list *instructions, } case ast_discard: - /* FINISHME: discard support */ if (state->target != fragment_shader) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "`discard' may only appear in a fragment shader"); } + instructions->push_tail(new(ctx) ir_discard); break; case ast_break: -- cgit v1.2.3 From 5466b63968b98c9627b8dd207ea2bebf838b5268 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 1 Jul 2010 12:46:55 -0700 Subject: glsl2: Change order of semaintic checks on variable declarations This will make it easier to support more (valid) kinds of redeclarations. --- src/glsl/ast_to_hir.cpp | 122 ++++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 61 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 7d966f848b..9d642c1a64 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1636,67 +1636,6 @@ ast_declarator_list::hir(exec_list *instructions, apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc); - /* Attempt to add the variable to the symbol table. If this fails, it - * 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)) { - 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. - */ - - if (var->type->array_size() <= (int)earlier->max_array_access) { - YYLTYPE loc = this->get_location(); - - _mesa_glsl_error(& loc, state, "array size must be > %u due to " - "previous access", - earlier->max_array_access); - } - - earlier->type = var->type; - delete var; - var = NULL; - } else { - YYLTYPE loc = this->get_location(); - - _mesa_glsl_error(& loc, state, "`%s' redeclared", - decl->identifier); - } - - continue; - } - - /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, - * - * "Identifiers starting with "gl_" are reserved for use by - * OpenGL, and may not be declared in a shader as either a - * variable or a function." - */ - if (strncmp(decl->identifier, "gl_", 3) == 0) { - /* FINISHME: This should only trigger if we're not redefining - * FINISHME: a builtin (to add a qualifier, for example). - */ - _mesa_glsl_error(& loc, state, - "identifier `%s' uses reserved `gl_' prefix", - decl->identifier); - } - - instructions->push_tail(var); - if (state->current_function != NULL) { const char *mode = NULL; const char *extra = ""; @@ -1851,6 +1790,67 @@ ast_declarator_list::hir(exec_list *instructions, "const declaration of `%s' must be initialized"); } + /* Attempt to add the variable to the symbol table. If this fails, it + * 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)) { + 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. + */ + + if (var->type->array_size() <= (int)earlier->max_array_access) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, "array size must be > %u due to " + "previous access", + earlier->max_array_access); + } + + earlier->type = var->type; + delete var; + var = NULL; + } else { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, "`%s' redeclared", + decl->identifier); + } + + continue; + } + + /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, + * + * "Identifiers starting with "gl_" are reserved for use by + * OpenGL, and may not be declared in a shader as either a + * variable or a function." + */ + if (strncmp(decl->identifier, "gl_", 3) == 0) { + /* FINISHME: This should only trigger if we're not redefining + * FINISHME: a builtin (to add a qualifier, for example). + */ + _mesa_glsl_error(& loc, state, + "identifier `%s' uses reserved `gl_' prefix", + decl->identifier); + } + + instructions->push_tail(var); + /* Add the variable to the symbol table after processing the initializer. * This differs from most C-like languages, but it follows the GLSL * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50 -- cgit v1.2.3 From cd00d5b88caa41ebf4b407126f314832f9fdae54 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 1 Jul 2010 13:17:54 -0700 Subject: glsl2: Default delcaration of gl_TexCoord is unsized --- src/glsl/ast_to_hir.cpp | 19 ++++++++++++++++++- src/glsl/ir_variable.cpp | 26 ++++++++++++++++---------- 2 files changed, 34 insertions(+), 11 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 9d642c1a64..22d9f7ad53 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1813,7 +1813,24 @@ ast_declarator_list::hir(exec_list *instructions, * FINISHME: required or not. */ - if (var->type->array_size() <= (int)earlier->max_array_access) { + /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: + * + * "The size [of gl_TexCoord] can be at most + * gl_MaxTextureCoords." + * + * FINISHME: Every platform that supports GLSL sets + * FINISHME: gl_MaxTextureCoords to at least 4, so hard-code 4 + * FINISHME: for now. + */ + if ((strcmp("gl_TexCoord", var->name) == 0) + && (var->type->array_size() > 4)) { + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(& loc, state, "`gl_TexCoord' array size cannot " + "be larger than gl_MaxTextureCoords (%u)\n", + 4); + } else if (var->type->array_size() <= + (int)earlier->max_array_access) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "array size must be > %u due to " diff --git a/src/glsl/ir_variable.cpp b/src/glsl/ir_variable.cpp index ac168142dc..d43809ef9c 100644 --- a/src/glsl/ir_variable.cpp +++ b/src/glsl/ir_variable.cpp @@ -159,13 +159,16 @@ generate_110_vs_variables(exec_list *instructions, } generate_110_uniforms(instructions, state->symbols); - /* FINISHME: The size of this array is implementation dependent based on the - * FINISHME: value of GL_MAX_TEXTURE_COORDS. Every platform that supports - * FINISHME: GLSL sets GL_MAX_TEXTURE_COORDS to at least 4, so hard-code 4 - * FINISHME: for now. + /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: + * + * "As with all arrays, indices used to subscript gl_TexCoord must + * either be an integral constant expressions, or this array must be + * re-declared by the shader with a size. The size can be at most + * gl_MaxTextureCoords. Using indexes close to 0 may aid the + * implementation in preserving varying resources." */ const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(state->symbols, glsl_type::vec4_type, 4); + glsl_type::get_array_instance(state->symbols, glsl_type::vec4_type, 0); add_variable("gl_TexCoord", ir_var_out, VERT_RESULT_TEX0, vec4_array_type, instructions, state->symbols); @@ -246,13 +249,16 @@ generate_110_fs_variables(exec_list *instructions, } generate_110_uniforms(instructions, state->symbols); - /* FINISHME: The size of this array is implementation dependent based on the - * FINISHME: value of GL_MAX_TEXTURE_COORDS. Every platform that supports - * FINISHME: GLSL sets GL_MAX_TEXTURE_COORDS to at least 4, so hard-code 4 - * FINISHME: for now. + /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: + * + * "As with all arrays, indices used to subscript gl_TexCoord must + * either be an integral constant expressions, or this array must be + * re-declared by the shader with a size. The size can be at most + * gl_MaxTextureCoords. Using indexes close to 0 may aid the + * implementation in preserving varying resources." */ const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(state->symbols, glsl_type::vec4_type, 4); + glsl_type::get_array_instance(state->symbols, glsl_type::vec4_type, 0); add_variable("gl_TexCoord", ir_var_in, FRAG_ATTRIB_TEX0, vec4_array_type, instructions, state->symbols); -- cgit v1.2.3 From 127308b4be077e5bdf60f76320307550921e86bb Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 1 Jul 2010 13:30:50 -0700 Subject: glsl2: Add gl_MaxTextureCoords --- src/glsl/ast_to_hir.cpp | 12 ++++-------- src/glsl/glsl_parser_extras.h | 1 + src/glsl/ir_variable.cpp | 31 +++++++++++++++++-------------- src/glsl/main.cpp | 1 + src/mesa/shader/ir_to_mesa.cpp | 1 + 5 files changed, 24 insertions(+), 22 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 22d9f7ad53..fc5a652f25 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1817,20 +1817,16 @@ ast_declarator_list::hir(exec_list *instructions, * * "The size [of gl_TexCoord] can be at most * gl_MaxTextureCoords." - * - * FINISHME: Every platform that supports GLSL sets - * FINISHME: gl_MaxTextureCoords to at least 4, so hard-code 4 - * FINISHME: for now. */ + const unsigned size = unsigned(var->type->array_size()); if ((strcmp("gl_TexCoord", var->name) == 0) - && (var->type->array_size() > 4)) { + && (size > state->Const.MaxTextureCoords)) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "`gl_TexCoord' array size cannot " "be larger than gl_MaxTextureCoords (%u)\n", - 4); - } else if (var->type->array_size() <= - (int)earlier->max_array_access) { + state->Const.MaxTextureCoords); + } else if (size <= earlier->max_array_access) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "array size must be > %u due to " diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index f957a926be..3aeba83cc5 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -50,6 +50,7 @@ struct _mesa_glsl_parse_state { */ struct { unsigned MaxDrawBuffers; + unsigned MaxTextureCoords; } Const; /** diff --git a/src/glsl/ir_variable.cpp b/src/glsl/ir_variable.cpp index d43809ef9c..9daad803e9 100644 --- a/src/glsl/ir_variable.cpp +++ b/src/glsl/ir_variable.cpp @@ -96,25 +96,28 @@ add_builtin_variable(const builtin_variable *proto, exec_list *instructions, static void generate_110_uniforms(exec_list *instructions, - glsl_symbol_table *symtab) + struct _mesa_glsl_parse_state *state) { for (unsigned i = 0 ; i < Elements(builtin_110_deprecated_uniforms) ; i++) { add_builtin_variable(& builtin_110_deprecated_uniforms[i], - instructions, symtab); + instructions, state->symbols); } - /* FINISHME: The size of this array is implementation dependent based on the - * FINISHME: value of GL_MAX_TEXTURE_COORDS. Every platform that supports - * FINISHME: GLSL sets GL_MAX_TEXTURE_COORDS to at least 4, so hard-code 4 - * FINISHME: for now. - */ + ir_variable *const mtc = add_variable("gl_MaxTextureCoords", ir_var_auto, + -1, glsl_type::int_type, + instructions, state->symbols); + mtc->constant_value = new(mtc) + ir_constant(int(state->Const.MaxTextureCoords)); + + const glsl_type *const mat4_array_type = - glsl_type::get_array_instance(symtab, glsl_type::mat4_type, 4); + glsl_type::get_array_instance(state->symbols, glsl_type::mat4_type, + state->Const.MaxTextureCoords); add_variable("gl_TextureMatrix", ir_var_uniform, -1, mat4_array_type, - instructions, symtab); + instructions, state->symbols); /* FINISHME: Add support for gl_DepthRangeParameters */ /* FINISHME: Add support for gl_ClipPlane[] */ @@ -129,11 +132,11 @@ generate_110_uniforms(exec_list *instructions, * FINISHME: at least 8, so hard-code 8 for now. */ const glsl_type *const light_source_array_type = - glsl_type::get_array_instance(symtab, - symtab->get_type("gl_LightSourceParameters"), 8); + glsl_type::get_array_instance(state->symbols, + state->symbols->get_type("gl_LightSourceParameters"), 8); add_variable("gl_LightSource", ir_var_uniform, -1, light_source_array_type, - instructions, symtab); + instructions, state->symbols); /* FINISHME: Add support for gl_LightModel */ /* FINISHME: Add support for gl_FrontLightProduct[], gl_BackLightProduct[] */ @@ -157,7 +160,7 @@ generate_110_vs_variables(exec_list *instructions, add_builtin_variable(& builtin_110_deprecated_vs_variables[i], instructions, state->symbols); } - generate_110_uniforms(instructions, state->symbols); + generate_110_uniforms(instructions, state); /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: * @@ -247,7 +250,7 @@ generate_110_fs_variables(exec_list *instructions, add_builtin_variable(& builtin_110_deprecated_fs_variables[i], instructions, state->symbols); } - generate_110_uniforms(instructions, state->symbols); + generate_110_uniforms(instructions, state); /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec: * diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp index fa63853b47..c833c9cde6 100644 --- a/src/glsl/main.cpp +++ b/src/glsl/main.cpp @@ -128,6 +128,7 @@ compile_shader(struct gl_shader *shader) state->ARB_texture_rectangle_enable = true; state->Const.MaxDrawBuffers = 2; + state->Const.MaxTextureCoords = 4; const char *source = shader->Source; state->error = preprocess(state, &source, &state->info_log); diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp index 1e186354c5..14abf602af 100644 --- a/src/mesa/shader/ir_to_mesa.cpp +++ b/src/mesa/shader/ir_to_mesa.cpp @@ -1710,6 +1710,7 @@ _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader) state->ARB_texture_rectangle_enable = true; state->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers; + state->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits; const char *source = shader->Source; state->error = preprocess(state, &source, &state->info_log); -- cgit v1.2.3 From 12873fa4e332959295154edfe957c0af79af5e74 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 1 Jul 2010 14:10:19 -0700 Subject: glsl2: Don't bounds check unsize array redeclarations This along with several previous commits fix test CorrectUnsizedArray.frag. --- src/glsl/ast_to_hir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index fc5a652f25..3a7fcf16c5 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1826,7 +1826,7 @@ ast_declarator_list::hir(exec_list *instructions, _mesa_glsl_error(& loc, state, "`gl_TexCoord' array size cannot " "be larger than gl_MaxTextureCoords (%u)\n", state->Const.MaxTextureCoords); - } else if (size <= earlier->max_array_access) { + } else if ((size > 0) && (size <= earlier->max_array_access)) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "array size must be > %u due to " -- cgit v1.2.3 From 6f0823da09384cc1b557385b9e19a9cc7e901ad7 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 1 Jul 2010 20:39:08 -0700 Subject: glsl2: Support AST-to-IR translation of invariant keyword --- src/glsl/ast_to_hir.cpp | 84 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 14 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 3a7fcf16c5..3bd0bd6591 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1550,29 +1550,73 @@ ast_declarator_list::hir(exec_list *instructions, ir_rvalue *result = NULL; YYLTYPE loc = this->get_location(); + /* From page 46 (page 52 of the PDF) of the GLSL 1.50 spec: + * + * "To ensure that a particular output variable is invariant, it is + * necessary to use the invariant qualifier. It can either be used to + * qualify a previously declared variable as being invariant + * + * invariant gl_Position; // make existing gl_Position be invariant" + * + * In these cases the parser will set the 'invariant' flag in the declarator + * list, and the type will be NULL. + */ + if (this->invariant) { + assert(this->type == NULL); + + if (state->current_function != NULL) { + _mesa_glsl_error(& loc, state, + "All uses of `invariant' keyword must be at global " + "scope\n"); + } + + foreach_list_typed (ast_declaration, decl, link, &this->declarations) { + assert(!decl->is_array); + assert(decl->array_size == NULL); + assert(decl->initializer == NULL); + + ir_variable *const earlier = + state->symbols->get_variable(decl->identifier); + if (earlier == NULL) { + _mesa_glsl_error(& loc, state, + "Undeclared variable `%s' cannot be marked " + "invariant\n", decl->identifier); + } else if ((state->target == vertex_shader) + && (earlier->mode != ir_var_out)) { + _mesa_glsl_error(& loc, state, + "`%s' cannot be marked invariant, vertex shader " + "outputs only\n", decl->identifier); + } else if ((state->target == fragment_shader) + && (earlier->mode != ir_var_in)) { + _mesa_glsl_error(& loc, state, + "`%s' cannot be marked invariant, fragment shader " + "inputs only\n", decl->identifier); + } else { + earlier->invariant = true; + } + } + + /* Invariant redeclarations do not have r-values. + */ + return NULL; + } + + assert(this->type != NULL); + assert(!this->invariant); + /* 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. - */ - decl_type = this->type->specifier->glsl_type(& type_name, state); if (this->declarations.is_empty()) { - /* There are only two valid cases where the declaration list can be - * empty. - * - * 1. The declaration is setting the default precision of a built-in - * type (e.g., 'precision highp vec4;'). - * - * 2. Adding 'invariant' to an existing vertex shader output. + /* The only valid case where the declaration list can be empty is when + * the declaration is setting the default precision of a built-in type + * (e.g., 'precision highp vec4;'). */ - if (this->type->qualifier.invariant) { - } else if (decl_type != NULL) { + if (decl_type != NULL) { } else { _mesa_glsl_error(& loc, state, "incomplete declaration"); } @@ -1636,6 +1680,18 @@ ast_declarator_list::hir(exec_list *instructions, apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc); + if (this->type->qualifier.invariant) { + if ((state->target == vertex_shader) && !var->shader_out) { + _mesa_glsl_error(& loc, state, + "`%s' cannot be marked invariant, vertex shader " + "outputs only\n", var->name); + } else if ((state->target == fragment_shader) && !var->shader_in) { + _mesa_glsl_error(& loc, state, + "`%s' cannot be marked invariant, fragment shader " + "inputs only\n", var->name); + } + } + if (state->current_function != NULL) { const char *mode = NULL; const char *extra = ""; -- cgit v1.2.3 From ca088cc277ce9f986693c857f3961dc0e1a4d91c Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 6 Jul 2010 17:41:02 -0700 Subject: glsl2: Clone methods return the type of the thing being cloned This is as opposed to returning the type of the base class of the hierarchy. --- src/glsl/ast_to_hir.cpp | 10 +++++----- src/glsl/ir.h | 38 ++++++++++++++++++++----------------- src/glsl/ir_clone.cpp | 34 ++++++++++++++++----------------- src/glsl/ir_constant_expression.cpp | 2 +- src/glsl/ir_function_inlining.cpp | 2 +- 5 files changed, 45 insertions(+), 41 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 3bd0bd6591..f5e93b0254 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -961,7 +961,7 @@ ast_expression::hir(exec_list *instructions, op[0], op[1]); result = do_assignment(instructions, state, - (ir_rvalue *)op[0]->clone(NULL), temp_rhs, + op[0]->clone(NULL), temp_rhs, this->subexpressions[0]->get_location()); type = result->type; error_emitted = (op[0]->type->is_error()); @@ -987,7 +987,7 @@ ast_expression::hir(exec_list *instructions, op[0], op[1]); result = do_assignment(instructions, state, - (ir_rvalue *)op[0]->clone(NULL), temp_rhs, + op[0]->clone(NULL), temp_rhs, this->subexpressions[0]->get_location()); type = result->type; error_emitted = type->is_error(); @@ -1107,7 +1107,7 @@ ast_expression::hir(exec_list *instructions, op[0], op[1]); result = do_assignment(instructions, state, - (ir_rvalue *)op[0]->clone(NULL), temp_rhs, + op[0]->clone(NULL), temp_rhs, this->subexpressions[0]->get_location()); type = result->type; error_emitted = op[0]->type->is_error(); @@ -1133,10 +1133,10 @@ ast_expression::hir(exec_list *instructions, /* Get a temporary of a copy of the lvalue before it's modified. * This may get thrown away later. */ - result = get_lvalue_copy(instructions, (ir_rvalue *)op[0]->clone(NULL)); + result = get_lvalue_copy(instructions, op[0]->clone(NULL)); (void)do_assignment(instructions, state, - (ir_rvalue *)op[0]->clone(NULL), temp_rhs, + op[0]->clone(NULL), temp_rhs, this->subexpressions[0]->get_location()); type = result->type; diff --git a/src/glsl/ir.h b/src/glsl/ir.h index c19bd417c3..500a8c7a00 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -94,6 +94,8 @@ protected: class ir_rvalue : public ir_instruction { public: + virtual ir_rvalue *clone(struct hash_table *) const = 0; + virtual ir_rvalue * as_rvalue() { return this; @@ -154,7 +156,7 @@ class ir_variable : public ir_instruction { public: ir_variable(const struct glsl_type *, const char *); - virtual ir_instruction *clone(struct hash_table *ht) const; + virtual ir_variable *clone(struct hash_table *ht) const; virtual ir_variable *as_variable() { @@ -258,7 +260,7 @@ class ir_function_signature : public ir_instruction { public: ir_function_signature(const glsl_type *return_type); - virtual ir_instruction *clone(struct hash_table *ht) const; + virtual ir_function_signature *clone(struct hash_table *ht) const; virtual void accept(ir_visitor *v) { @@ -324,7 +326,7 @@ class ir_function : public ir_instruction { public: ir_function(const char *name); - virtual ir_instruction *clone(struct hash_table *ht) const; + virtual ir_function *clone(struct hash_table *ht) const; virtual ir_function *as_function() { @@ -394,7 +396,7 @@ public: /* empty */ } - virtual ir_instruction *clone(struct hash_table *ht) const; + virtual ir_if *clone(struct hash_table *ht) const; virtual ir_if *as_if() { @@ -426,7 +428,7 @@ public: /* empty */ } - virtual ir_instruction *clone(struct hash_table *ht) const; + virtual ir_loop *clone(struct hash_table *ht) const; virtual void accept(ir_visitor *v) { @@ -467,7 +469,7 @@ class ir_assignment : public ir_rvalue { public: ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition); - virtual ir_instruction *clone(struct hash_table *ht) const; + virtual ir_assignment *clone(struct hash_table *ht) const; virtual void accept(ir_visitor *v) { @@ -601,7 +603,7 @@ public: ir_expression(int op, const struct glsl_type *type, ir_rvalue *, ir_rvalue *); - virtual ir_instruction *clone(struct hash_table *ht) const; + virtual ir_expression *clone(struct hash_table *ht) const; static unsigned int get_num_operands(ir_expression_operation); unsigned int get_num_operands() const @@ -644,7 +646,7 @@ public: actual_parameters->move_nodes_to(& this->actual_parameters); } - virtual ir_instruction *clone(struct hash_table *ht) const; + virtual ir_call *clone(struct hash_table *ht) const; virtual ir_call *as_call() { @@ -734,7 +736,7 @@ public: /* empty */ } - virtual ir_instruction *clone(struct hash_table *) const; + virtual ir_return *clone(struct hash_table *) const; virtual ir_return *as_return() { @@ -778,7 +780,7 @@ public: this->loop = loop; } - virtual ir_instruction *clone(struct hash_table *) const; + virtual ir_loop_jump *clone(struct hash_table *) const; virtual void accept(ir_visitor *v) { @@ -819,7 +821,7 @@ public: this->condition = cond; } - virtual ir_instruction *clone(struct hash_table *ht) const; + virtual ir_discard *clone(struct hash_table *ht) const; virtual void accept(ir_visitor *v) { @@ -871,7 +873,7 @@ public: /* empty */ } - virtual ir_instruction *clone(struct hash_table *) const; + virtual ir_texture *clone(struct hash_table *) const; virtual void accept(ir_visitor *v) { @@ -961,7 +963,7 @@ public: ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask); - virtual ir_instruction *clone(struct hash_table *) const; + virtual ir_swizzle *clone(struct hash_table *) const; virtual ir_swizzle *as_swizzle() { @@ -1005,6 +1007,8 @@ private: class ir_dereference : public ir_rvalue { public: + virtual ir_dereference *clone(struct hash_table *) const = 0; + virtual ir_dereference *as_dereference() { return this; @@ -1023,7 +1027,7 @@ class ir_dereference_variable : public ir_dereference { public: ir_dereference_variable(ir_variable *var); - virtual ir_instruction *clone(struct hash_table *) const; + virtual ir_dereference_variable *clone(struct hash_table *) const; virtual ir_dereference_variable *as_dereference_variable() { @@ -1069,7 +1073,7 @@ public: ir_dereference_array(ir_variable *var, ir_rvalue *array_index); - virtual ir_instruction *clone(struct hash_table *) const; + virtual ir_dereference_array *clone(struct hash_table *) const; virtual ir_dereference_array *as_dereference_array() { @@ -1105,7 +1109,7 @@ public: ir_dereference_record(ir_variable *var, const char *field); - virtual ir_instruction *clone(struct hash_table *) const; + virtual ir_dereference_record *clone(struct hash_table *) const; /** * Get the variable that is ultimately referenced by an r-value @@ -1163,7 +1167,7 @@ public: */ ir_constant(const ir_constant *c, unsigned i); - virtual ir_instruction *clone(struct hash_table *) const; + virtual ir_constant *clone(struct hash_table *) const; virtual ir_constant *as_constant() { diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp index 74cc858bda..cf21c24d73 100644 --- a/src/glsl/ir_clone.cpp +++ b/src/glsl/ir_clone.cpp @@ -35,7 +35,7 @@ extern "C" { * This will probably be made \c virtual and moved to the base class * eventually. */ -ir_instruction * +ir_variable * ir_variable::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -55,14 +55,14 @@ ir_variable::clone(struct hash_table *ht) const return var; } -ir_instruction * +ir_swizzle * ir_swizzle::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); return new(ctx) ir_swizzle((ir_rvalue *)this->val->clone(ht), this->mask); } -ir_instruction * +ir_return * ir_return::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -74,7 +74,7 @@ ir_return::clone(struct hash_table *ht) const return new(ctx) ir_return(new_value); } -ir_instruction * +ir_discard * ir_discard::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -86,7 +86,7 @@ ir_discard::clone(struct hash_table *ht) const return new(ctx) ir_discard(new_condition); } -ir_instruction * +ir_loop_jump * ir_loop_jump::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -95,7 +95,7 @@ ir_loop_jump::clone(struct hash_table *ht) const return new(ctx) ir_loop_jump(this->mode); } -ir_instruction * +ir_if * ir_if::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -114,7 +114,7 @@ ir_if::clone(struct hash_table *ht) const return new_if; } -ir_instruction * +ir_loop * ir_loop::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -136,7 +136,7 @@ ir_loop::clone(struct hash_table *ht) const return new_loop; } -ir_instruction * +ir_call * ir_call::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -150,7 +150,7 @@ ir_call::clone(struct hash_table *ht) const return new(ctx) ir_call(this->callee, &new_parameters); } -ir_instruction * +ir_expression * ir_expression::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -164,7 +164,7 @@ ir_expression::clone(struct hash_table *ht) const return new(ctx) ir_expression(this->operation, this->type, op[0], op[1]); } -ir_instruction * +ir_dereference_variable * ir_dereference_variable::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -181,7 +181,7 @@ ir_dereference_variable::clone(struct hash_table *ht) const return new(ctx) ir_dereference_variable(new_var); } -ir_instruction * +ir_dereference_array * ir_dereference_array::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -189,7 +189,7 @@ ir_dereference_array::clone(struct hash_table *ht) const (ir_rvalue *)this->array_index->clone(ht)); } -ir_instruction * +ir_dereference_record * ir_dereference_record::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -197,7 +197,7 @@ ir_dereference_record::clone(struct hash_table *ht) const this->field); } -ir_instruction * +ir_texture * ir_texture::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); @@ -236,7 +236,7 @@ ir_texture::clone(struct hash_table *ht) const return new_tex; } -ir_instruction * +ir_assignment * ir_assignment::clone(struct hash_table *ht) const { ir_rvalue *new_condition = NULL; @@ -250,7 +250,7 @@ ir_assignment::clone(struct hash_table *ht) const new_condition); } -ir_instruction * +ir_function * ir_function::clone(struct hash_table *ht) const { (void)ht; @@ -258,7 +258,7 @@ ir_function::clone(struct hash_table *ht) const abort(); } -ir_instruction * +ir_function_signature * ir_function_signature::clone(struct hash_table *ht) const { (void)ht; @@ -266,7 +266,7 @@ ir_function_signature::clone(struct hash_table *ht) const abort(); } -ir_instruction * +ir_constant * ir_constant::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index 11c810bc48..541398a91c 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -626,7 +626,7 @@ ir_constant_visitor::visit(ir_dereference_variable *ir) ir_variable *var = ir->variable_referenced(); if (var && var->constant_value) - value = (ir_constant *)var->constant_value->clone(NULL); + value = var->constant_value->clone(NULL); } diff --git a/src/glsl/ir_function_inlining.cpp b/src/glsl/ir_function_inlining.cpp index b3d1f1d167..6fe1264b0a 100644 --- a/src/glsl/ir_function_inlining.cpp +++ b/src/glsl/ir_function_inlining.cpp @@ -137,7 +137,7 @@ ir_call::generate_inline(ir_instruction *next_ir) ir_rvalue *param = (ir_rvalue *) param_iter.get(); /* Generate a new variable for the parameter. */ - parameters[i] = (ir_variable *)sig_param->clone(ht); + parameters[i] = sig_param->clone(ht); parameters[i]->mode = ir_var_auto; next_ir->insert_before(parameters[i]); -- cgit v1.2.3 From d4d630b72c7b7f38074addda0f1b819608247d93 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 6 Jul 2010 18:31:32 -0700 Subject: glsl2: Put the declaration in the instruction stream before its initializer. This fixes a regression in the generated code from when I did the ir_validate.cpp-driven rework of assignments. --- src/glsl/ast_to_hir.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index f5e93b0254..3de754fa81 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1772,6 +1772,8 @@ ast_declarator_list::hir(exec_list *instructions, } } + instructions->push_tail(var); + if (decl->initializer != NULL) { YYLTYPE initializer_loc = decl->initializer->get_location(); @@ -1918,8 +1920,6 @@ ast_declarator_list::hir(exec_list *instructions, decl->identifier); } - instructions->push_tail(var); - /* Add the variable to the symbol table after processing the initializer. * This differs from most C-like languages, but it follows the GLSL * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50 -- cgit v1.2.3 From 2e85f993d8a014b53ad2f6d295cf66d3fb38b091 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 7 Jul 2010 11:57:16 -0700 Subject: Revert "glsl2: Put the declaration in the instruction stream before its initializer." This change causes segfaults in other tests. A fix for both sets of segfaults is coming. This reverts commit d4d630b72c7b7f38074addda0f1b819608247d93. --- src/glsl/ast_to_hir.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 3de754fa81..f5e93b0254 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1772,8 +1772,6 @@ ast_declarator_list::hir(exec_list *instructions, } } - instructions->push_tail(var); - if (decl->initializer != NULL) { YYLTYPE initializer_loc = decl->initializer->get_location(); @@ -1920,6 +1918,8 @@ ast_declarator_list::hir(exec_list *instructions, decl->identifier); } + instructions->push_tail(var); + /* Add the variable to the symbol table after processing the initializer. * This differs from most C-like languages, but it follows the GLSL * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50 -- cgit v1.2.3 From e78e0fa42b49b50ed1150f7fdb74bf942ebd6bcf Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 7 Jul 2010 12:13:34 -0700 Subject: glsl2: Put the initializer in the instruction stream after the declaration --- src/glsl/ast_to_hir.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index f5e93b0254..b21131f60f 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1772,6 +1772,13 @@ ast_declarator_list::hir(exec_list *instructions, } } + /* Process the initializer and add its instructions to a temporary + * list. This list will be added to the instruction stream (below) after + * the declaration is added. This is done because in some cases (such as + * redeclarations) the declaration may not actually be added to the + * instruction stream. + */ + exec_list intializer_instructions; if (decl->initializer != NULL) { YYLTYPE initializer_loc = decl->initializer->get_location(); @@ -1801,7 +1808,8 @@ ast_declarator_list::hir(exec_list *instructions, } ir_dereference *const lhs = new(ctx) ir_dereference_variable(var); - ir_rvalue *rhs = decl->initializer->hir(instructions, state); + ir_rvalue *rhs = decl->initializer->hir(&intializer_instructions, + state); /* Calculate the constant value if this is a const or uniform * declaration. @@ -1829,7 +1837,7 @@ ast_declarator_list::hir(exec_list *instructions, /* Never emit code to initialize a uniform. */ if (!this->type->qualifier.uniform) - result = do_assignment(instructions, state, lhs, rhs, + result = do_assignment(&intializer_instructions, state, lhs, rhs, this->get_location()); var->read_only = temp; } @@ -1919,6 +1927,7 @@ ast_declarator_list::hir(exec_list *instructions, } instructions->push_tail(var); + instructions->append_list(&intializer_instructions); /* Add the variable to the symbol table after processing the initializer. * This differs from most C-like languages, but it follows the GLSL -- cgit v1.2.3 From 43b5b03d67ce890e867c81d4a5cfc4871d711d43 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 7 Jul 2010 14:04:30 -0700 Subject: glsl2: Actually add the declaration of _post_incdec_temp. --- src/glsl/ast_to_hir.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index b21131f60f..e716b8a11e 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -571,6 +571,7 @@ get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue) /* FINISHME: Give unique names to the temporaries. */ var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp"); + instructions->push_tail(var); var->mode = ir_var_auto; instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), -- cgit v1.2.3 From dfd30ca6a95a7d95835dad78ffe1fba4d1f4ef69 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Thu, 8 Jul 2010 12:40:52 -0700 Subject: glsl2: Remove generate_temporary and global temporary counter. Most places in the code simply use a static name, which works because names are never used to look up an ir_variable. generate_temporary is simply unnecessary (and looks like it would leak memory, and isn't thread safe...) --- src/glsl/ast_to_hir.cpp | 32 +++++--------------------------- src/glsl/glsl_parser_extras.h | 3 --- src/glsl/main.cpp | 1 - src/mesa/shader/ir_to_mesa.cpp | 1 - 4 files changed, 5 insertions(+), 32 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index e716b8a11e..e03bb6394f 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -542,27 +542,6 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, return new(ctx) ir_dereference_variable(var); } - -/** - * Generate a new temporary and add its declaration to the instruction stream - */ -static ir_variable * -generate_temporary(const glsl_type *type, exec_list *instructions, - struct _mesa_glsl_parse_state *state) -{ - void *ctx = state; - char *name = (char *) malloc(sizeof(char) * 13); - - snprintf(name, 13, "tmp_%08X", state->temp_index); - state->temp_index++; - - ir_variable *const var = new(ctx) ir_variable(type, name); - instructions->push_tail(var); - - return var; -} - - static ir_rvalue * get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue) { @@ -840,8 +819,8 @@ ast_expression::hir(exec_list *instructions, error_emitted = true; } - ir_variable *const tmp = generate_temporary(glsl_type::bool_type, - instructions, state); + ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, + "and_tmp"); ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = @@ -892,8 +871,8 @@ ast_expression::hir(exec_list *instructions, ir_if *const stmt = new(ctx) ir_if(op[0]); instructions->push_tail(stmt); - ir_variable *const tmp = generate_temporary(glsl_type::bool_type, - instructions, state); + ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, + "or_tmp"); op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state); @@ -1068,8 +1047,7 @@ ast_expression::hir(exec_list *instructions, && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) { result = (cond_val->value.b[0]) ? then_val : else_val; } else { - ir_variable *const tmp = generate_temporary(type, - instructions, state); + ir_variable *const tmp = new(ctx) ir_variable(type, "conditional_tmp"); ir_if *const stmt = new(ctx) ir_if(op[0]); instructions->push_tail(stmt); diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index 16f7268181..4b28ae118d 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -67,9 +67,6 @@ struct _mesa_glsl_parse_state { /** Was there an error during compilation? */ bool error; - /** Index of last generated anonymous temporary. */ - unsigned temp_index; - /** Loop or switch statement containing the current instructions. */ class ir_instruction *loop_or_switch_nesting; diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp index 782934a8d7..dd43d12474 100644 --- a/src/glsl/main.cpp +++ b/src/glsl/main.cpp @@ -124,7 +124,6 @@ compile_shader(struct gl_shader *shader) state->symbols = new(shader) glsl_symbol_table; state->info_log = talloc_strdup(shader, ""); state->error = false; - state->temp_index = 0; state->loop_or_switch_nesting = NULL; state->ARB_texture_rectangle_enable = true; diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp index 4496daf2a5..708c6fece1 100644 --- a/src/mesa/shader/ir_to_mesa.cpp +++ b/src/mesa/shader/ir_to_mesa.cpp @@ -1938,7 +1938,6 @@ _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader) state->symbols = new(shader) glsl_symbol_table; state->info_log = talloc_strdup(shader, ""); state->error = false; - state->temp_index = 0; state->loop_or_switch_nesting = NULL; state->ARB_texture_rectangle_enable = true; -- cgit v1.2.3 From 0b9ae3befb0bf80e000b159fd44c961a144f9c36 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 12 Jul 2010 14:22:05 -0700 Subject: glsl2: Add declarations for temporaries to instruction stream Temporary variables added for &&, ||, and ?: were not being added to the instruction stream. This resulted in either test failures or Valgrind being angry after the original IR tree was destroyed by talloc_free. The talloc_free caused the ir_variables to be destroyed even though they were still referenced. --- src/glsl/ast_to_hir.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index e03bb6394f..a9ab17f421 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -821,6 +821,7 @@ ast_expression::hir(exec_list *instructions, ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, "and_tmp"); + instructions->push_tail(tmp); ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = @@ -873,6 +874,7 @@ ast_expression::hir(exec_list *instructions, ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, "or_tmp"); + instructions->push_tail(tmp); op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state); @@ -1048,6 +1050,7 @@ ast_expression::hir(exec_list *instructions, result = (cond_val->value.b[0]) ? then_val : else_val; } else { ir_variable *const tmp = new(ctx) ir_variable(type, "conditional_tmp"); + instructions->push_tail(tmp); ir_if *const stmt = new(ctx) ir_if(op[0]); instructions->push_tail(stmt); -- cgit v1.2.3 From 81d664f099a5fd5fac777480532fb4307d591451 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 12 Jul 2010 15:18:55 -0700 Subject: glsl2: Move temp declaration to correct side of if-statement in IR --- src/glsl/ast_to_hir.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index a9ab17f421..98090d2b01 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -805,6 +805,10 @@ ast_expression::hir(exec_list *instructions, } type = glsl_type::bool_type; } else { + ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, + "and_tmp"); + instructions->push_tail(tmp); + ir_if *const stmt = new(ctx) ir_if(op[0]); instructions->push_tail(stmt); @@ -819,10 +823,6 @@ ast_expression::hir(exec_list *instructions, error_emitted = true; } - ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, - "and_tmp"); - instructions->push_tail(tmp); - ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = new(ctx) ir_assignment(then_deref, op[1], NULL); @@ -869,13 +869,13 @@ ast_expression::hir(exec_list *instructions, } type = glsl_type::bool_type; } else { - ir_if *const stmt = new(ctx) ir_if(op[0]); - instructions->push_tail(stmt); - ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, "or_tmp"); instructions->push_tail(tmp); + ir_if *const stmt = new(ctx) ir_if(op[0]); + instructions->push_tail(stmt); + op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state); if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) { -- cgit v1.2.3 From 2b7c42b40ae459f7b290eb134d6dabd075aab9f0 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 16 Jul 2010 18:28:44 -0700 Subject: glsl2: Disallow non-constant array indexing for unsized arrays. Fixes piglit test unsized-array-non-const-index.vert. --- src/glsl/ast_to_hir.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 98090d2b01..41371e7536 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1233,6 +1233,8 @@ ast_expression::hir(exec_list *instructions, if ((v != NULL) && (unsigned(idx) > v->max_array_access)) v->max_array_access = idx; } + } else if (array->type->array_size() == 0) { + _mesa_glsl_error(&loc, state, "unsized array index must be constant"); } if (error_emitted) -- cgit v1.2.3 From 21b0dbd79937e9d6787f045af7d60d4b6c649ec8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 20 Jul 2010 16:47:25 -0700 Subject: glsl2: talloc the glsl_struct_field[] we use to look up structure types. Since the types are singletons across the lifetime of the compiler, repeatedly compiling a program with the same structure type defined would drop a copy of the array on the floor per compile. This is a bit tricky because the static GLSL types are not called with the talloc-based new, so we have to use the global type context, which may not be initialized yet. --- src/glsl/ast_to_hir.cpp | 4 ++-- src/glsl/glsl_types.cpp | 15 ++++++++++++++- src/glsl/glsl_types.h | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 41371e7536..f20c7ead33 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2471,8 +2471,8 @@ ast_struct_specifier::hir(exec_list *instructions, * 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); + glsl_struct_field *const fields = talloc_array(state, glsl_struct_field, + decl_count); unsigned i = 0; foreach_list_typed (ast_declarator_list, decl_list, link, diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index 6ca141ef48..77c591ed69 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -75,7 +75,20 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, name(name), length(num_fields) { - this->fields.structure = fields; + unsigned int i; + + if (glsl_type::ctx == NULL) { + glsl_type::ctx = talloc_init("glsl_type"); + assert(glsl_type::ctx != NULL); + } + + this->fields.structure = talloc_array(glsl_type::ctx, + glsl_struct_field, length); + for (i = 0; i < length; i++) { + this->fields.structure[i].type = fields[i].type; + this->fields.structure[i].name = talloc_strdup(this->fields.structure, + fields[i].name); + } } static void diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h index e869071cab..8ba9b5ff63 100644 --- a/src/glsl/glsl_types.h +++ b/src/glsl/glsl_types.h @@ -136,7 +136,7 @@ struct glsl_type { union { const struct glsl_type *array; /**< Type of array elements. */ const struct glsl_type *parameters; /**< Parameters to function. */ - const struct glsl_struct_field *structure;/**< List of struct fields. */ + struct glsl_struct_field *structure; /**< List of struct fields. */ } fields; -- cgit v1.2.3 From 7e2aa91507a5883e33473e0a94215ee3985baad1 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 19 Jul 2010 17:12:42 -0700 Subject: glsl2: Add and use new variable mode ir_var_temporary This is quite a large patch because breaking it into smaller pieces would result in the tree being intermitently broken. The big changes are: * Add the ir_var_temporary variable mode * Change the ir_variable constructor to take the mode as a parameter and correctly specify the mode for all ir_varables. * Change the linker to not cross validate ir_var_temporary variables. * Change the linker to pull all ir_var_temporary variables from global scope into 'main'. --- src/glsl/ast_function.cpp | 21 +++++++++----- src/glsl/ast_to_hir.cpp | 26 ++++++++++------- src/glsl/glsl_types.cpp | 7 ++--- src/glsl/ir.cpp | 6 ++-- src/glsl/ir.h | 5 ++-- src/glsl/ir_clone.cpp | 4 +-- src/glsl/ir_expression_flattening.cpp | 2 +- src/glsl/ir_function.cpp | 1 + src/glsl/ir_function_inlining.cpp | 3 +- src/glsl/ir_if_return.cpp | 3 +- src/glsl/ir_if_to_cond_assign.cpp | 3 +- src/glsl/ir_mat_op_to_vec.cpp | 3 +- src/glsl/ir_mod_to_fract.cpp | 3 +- src/glsl/ir_reader.cpp | 3 +- src/glsl/ir_variable.cpp | 3 +- src/glsl/ir_vec_index_to_cond_assign.cpp | 12 +++++--- src/glsl/linker.cpp | 50 ++++++++++++++++++++++++++++---- src/mesa/shader/ir_to_mesa.cpp | 1 + 18 files changed, 109 insertions(+), 47 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 643eb229a7..14c36af911 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -115,7 +115,8 @@ process_call(exec_list *instructions, ir_function *f, var = new(ctx) ir_variable(sig->return_type, talloc_asprintf(ctx, "%s_retval", - sig->function_name())); + sig->function_name()), + ir_var_temporary); instructions->push_tail(var); deref = new(ctx) ir_dereference_variable(var); @@ -509,7 +510,8 @@ emit_inline_vector_constructor(const glsl_type *type, assert(!parameters->is_empty()); ir_variable *var = new(ctx) ir_variable(type, - talloc_strdup(ctx, "vec_ctor")); + talloc_strdup(ctx, "vec_ctor"), + ir_var_temporary); instructions->push_tail(var); /* There are two kinds of vector constructors. @@ -621,7 +623,8 @@ emit_inline_matrix_constructor(const glsl_type *type, assert(!parameters->is_empty()); ir_variable *var = new(ctx) ir_variable(type, - talloc_strdup(ctx, "mat_ctor")); + talloc_strdup(ctx, "mat_ctor"), + ir_var_temporary); instructions->push_tail(var); /* There are three kinds of matrix constructors. @@ -645,7 +648,8 @@ emit_inline_matrix_constructor(const glsl_type *type, */ ir_variable *rhs_var = new(ctx) ir_variable(glsl_type::vec4_type, - talloc_strdup(ctx, "mat_ctor_vec")); + talloc_strdup(ctx, "mat_ctor_vec"), + ir_var_temporary); instructions->push_tail(rhs_var); ir_constant_data zero; @@ -759,7 +763,8 @@ emit_inline_matrix_constructor(const glsl_type *type, */ ir_variable *const rhs_var = new(ctx) ir_variable(first_param->type, - talloc_strdup(ctx, "mat_ctor_mat")); + talloc_strdup(ctx, "mat_ctor_mat"), + ir_var_temporary); instructions->push_tail(rhs_var); ir_dereference *const rhs_var_ref = @@ -825,7 +830,8 @@ emit_inline_matrix_constructor(const glsl_type *type, */ ir_variable *rhs_var = new(ctx) ir_variable(rhs->type, - talloc_strdup(ctx, "mat_ctor_vec")); + talloc_strdup(ctx, "mat_ctor_vec"), + ir_var_temporary); instructions->push_tail(rhs_var); ir_dereference *rhs_var_ref = @@ -1036,7 +1042,8 @@ ast_function_expression::hir(exec_list *instructions, continue; /* Create a temporary containing the matrix. */ - ir_variable *var = new(ctx) ir_variable(matrix->type, "matrix_tmp"); + ir_variable *var = new(ctx) ir_variable(matrix->type, "matrix_tmp", + ir_var_temporary); instructions->push_tail(var); instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), matrix, NULL)); diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index f20c7ead33..c68e136256 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -527,7 +527,8 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, * temporary and return a deref of that temporary. If the rvalue * ends up not being used, the temp will get copy-propagated out. */ - ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp"); + ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp", + ir_var_temporary); ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var); instructions->push_tail(var); instructions->push_tail(new(ctx) ir_assignment(deref_var, @@ -549,7 +550,8 @@ get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue) ir_variable *var; /* FINISHME: Give unique names to the temporaries. */ - var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp"); + var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp", + ir_var_temporary); instructions->push_tail(var); var->mode = ir_var_auto; @@ -806,7 +808,8 @@ ast_expression::hir(exec_list *instructions, type = glsl_type::bool_type; } else { ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, - "and_tmp"); + "and_tmp", + ir_var_temporary); instructions->push_tail(tmp); ir_if *const stmt = new(ctx) ir_if(op[0]); @@ -870,7 +873,8 @@ ast_expression::hir(exec_list *instructions, type = glsl_type::bool_type; } else { ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type, - "or_tmp"); + "or_tmp", + ir_var_temporary); instructions->push_tail(tmp); ir_if *const stmt = new(ctx) ir_if(op[0]); @@ -1049,7 +1053,8 @@ ast_expression::hir(exec_list *instructions, && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) { result = (cond_val->value.b[0]) ? then_val : else_val; } else { - ir_variable *const tmp = new(ctx) ir_variable(type, "conditional_tmp"); + ir_variable *const tmp = + new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary); instructions->push_tail(tmp); ir_if *const stmt = new(ctx) ir_if(op[0]); @@ -1474,6 +1479,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, } } + /* If there is no qualifier that changes the mode of the variable, leave + * the setting alone. + */ if (qual->in && qual->out) var->mode = ir_var_inout; else if (qual->attribute || qual->in @@ -1483,8 +1491,6 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, var->mode = ir_var_out; else if (qual->uniform) var->mode = ir_var_uniform; - else - var->mode = ir_var_auto; if (qual->uniform) var->shader_in = true; @@ -1633,7 +1639,7 @@ ast_declarator_list::hir(exec_list *instructions, var_type = decl_type; } - var = new(ctx) ir_variable(var_type, decl->identifier); + var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto); /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification; * @@ -1993,7 +1999,7 @@ ast_parameter_declarator::hir(exec_list *instructions, } is_void = false; - ir_variable *var = new(ctx) ir_variable(type, this->identifier); + ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_in); /* FINISHME: Handle array declarations. Note that this requires * FINISHME: complete handling of constant expressions. @@ -2003,8 +2009,6 @@ ast_parameter_declarator::hir(exec_list *instructions, * for function parameters the default mode is 'in'. */ apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc); - if (var->mode == ir_var_auto) - var->mode = ir_var_in; instructions->push_tail(var); diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index 77c591ed69..5cb327c89d 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -251,10 +251,9 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const snprintf(param_name, 10, "p%08X", i); ir_variable *var = (this->base_type == GLSL_TYPE_ARRAY) - ? new(ctx) ir_variable(fields.array, param_name) - : new(ctx) ir_variable(fields.structure[i].type, param_name); + ? new(ctx) ir_variable(fields.array, param_name, ir_var_in) + : new(ctx) ir_variable(fields.structure[i].type, param_name, ir_var_in); - var->mode = ir_var_in; declarations[i] = var; sig->parameters.push_tail(var); } @@ -264,7 +263,7 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const * the same type as the constructor. After initializing __retval, * __retval is returned. */ - ir_variable *retval = new(ctx) ir_variable(this, "__retval"); + ir_variable *retval = new(ctx) ir_variable(this, "__retval", ir_var_auto); sig->body.push_tail(retval); for (unsigned i = 0; i < length; i++) { diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index ba8ee7b9ac..146ff17af3 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -748,10 +748,12 @@ ir_swizzle::variable_referenced() return this->val->variable_referenced(); } -ir_variable::ir_variable(const struct glsl_type *type, const char *name) + +ir_variable::ir_variable(const struct glsl_type *type, const char *name, + ir_variable_mode mode) : max_array_access(0), read_only(false), centroid(false), invariant(false), shader_in(false), shader_out(false), - mode(ir_var_auto), interpolation(ir_var_smooth), array_lvalue(false) + mode(mode), interpolation(ir_var_smooth), array_lvalue(false) { this->ir_type = ir_type_variable; this->type = type; diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 3be096270d..9fd9850391 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -162,7 +162,8 @@ enum ir_variable_mode { ir_var_uniform, ir_var_in, ir_var_out, - ir_var_inout + ir_var_inout, + ir_var_temporary /**< Temporary variable generated during compilation. */ }; enum ir_variable_interpolation { @@ -174,7 +175,7 @@ enum ir_variable_interpolation { class ir_variable : public ir_instruction { public: - ir_variable(const struct glsl_type *, const char *); + ir_variable(const struct glsl_type *, const char *, ir_variable_mode); virtual ir_variable *clone(struct hash_table *ht) const; diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp index 91d6977354..f7e8794728 100644 --- a/src/glsl/ir_clone.cpp +++ b/src/glsl/ir_clone.cpp @@ -39,7 +39,8 @@ ir_variable * ir_variable::clone(struct hash_table *ht) const { void *ctx = talloc_parent(this); - ir_variable *var = new(ctx) ir_variable(type, name); + ir_variable *var = new(ctx) ir_variable(this->type, this->name, + (ir_variable_mode) this->mode); var->max_array_access = this->max_array_access; var->read_only = this->read_only; @@ -47,7 +48,6 @@ ir_variable::clone(struct hash_table *ht) const var->invariant = this->invariant; var->shader_in = this->shader_in; var->shader_out = this->shader_out; - var->mode = this->mode; var->interpolation = this->interpolation; var->array_lvalue = this->array_lvalue; var->location = this->location; diff --git a/src/glsl/ir_expression_flattening.cpp b/src/glsl/ir_expression_flattening.cpp index f18659342f..6dbebc6378 100644 --- a/src/glsl/ir_expression_flattening.cpp +++ b/src/glsl/ir_expression_flattening.cpp @@ -89,7 +89,7 @@ ir_expression_flattening_visitor::operand_to_temp(ir_rvalue *ir) if (!this->predicate(ir)) return ir; - var = new(ctx) ir_variable(ir->type, "flattening_tmp"); + var = new(ctx) ir_variable(ir->type, "flattening_tmp", ir_var_temporary); base_ir->insert_before(var); assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp index e85b18ce02..28a5c399f1 100644 --- a/src/glsl/ir_function.cpp +++ b/src/glsl/ir_function.cpp @@ -116,6 +116,7 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b) switch ((enum ir_variable_mode)(param->mode)) { case ir_var_auto: case ir_var_uniform: + case ir_var_temporary: /* These are all error conditions. It is invalid for a parameter to * a function to be declared as auto (not in, out, or inout) or * as uniform. diff --git a/src/glsl/ir_function_inlining.cpp b/src/glsl/ir_function_inlining.cpp index a3f7089cdc..05dd83f7ff 100644 --- a/src/glsl/ir_function_inlining.cpp +++ b/src/glsl/ir_function_inlining.cpp @@ -122,7 +122,8 @@ ir_call::generate_inline(ir_instruction *next_ir) /* Generate storage for the return value. */ if (this->callee->return_type) { - retval = new(ctx) ir_variable(this->callee->return_type, "__retval"); + retval = new(ctx) ir_variable(this->callee->return_type, "__retval", + ir_var_auto); next_ir->insert_before(retval); } diff --git a/src/glsl/ir_if_return.cpp b/src/glsl/ir_if_return.cpp index f68dcfb501..a9af7166b9 100644 --- a/src/glsl/ir_if_return.cpp +++ b/src/glsl/ir_if_return.cpp @@ -102,7 +102,8 @@ ir_if_return_visitor::visit_enter(ir_if *ir) } else { ir_assignment *assign; ir_variable *new_var = new(ir) ir_variable(then_return->value->type, - "if_return_tmp"); + "if_return_tmp", + ir_var_temporary); ir->insert_before(new_var); assign = new(ir) ir_assignment(new(ir) ir_dereference_variable(new_var), diff --git a/src/glsl/ir_if_to_cond_assign.cpp b/src/glsl/ir_if_to_cond_assign.cpp index 274874bbb7..0b87413941 100644 --- a/src/glsl/ir_if_to_cond_assign.cpp +++ b/src/glsl/ir_if_to_cond_assign.cpp @@ -145,7 +145,8 @@ ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir) * simpler. */ cond_var = new(mem_ctx) ir_variable(glsl_type::bool_type, - "if_to_cond_assign_condition"); + "if_to_cond_assign_condition", + ir_var_temporary); ir->insert_before(cond_var); deref = new(mem_ctx) ir_dereference_variable(cond_var); diff --git a/src/glsl/ir_mat_op_to_vec.cpp b/src/glsl/ir_mat_op_to_vec.cpp index 7bdb9057d8..742fc2a295 100644 --- a/src/glsl/ir_mat_op_to_vec.cpp +++ b/src/glsl/ir_mat_op_to_vec.cpp @@ -298,7 +298,8 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *assign) ir_assignment *assign; op_var[i] = new(base_ir) ir_variable(expr->operands[i]->type, - "mat_op_to_vec"); + "mat_op_to_vec", + ir_var_temporary); base_ir->insert_before(op_var[i]); lhs_deref = new(base_ir) ir_dereference_variable(op_var[i]); diff --git a/src/glsl/ir_mod_to_fract.cpp b/src/glsl/ir_mod_to_fract.cpp index ec1e65092d..71c9472b12 100644 --- a/src/glsl/ir_mod_to_fract.cpp +++ b/src/glsl/ir_mod_to_fract.cpp @@ -60,7 +60,8 @@ ir_mod_to_fract_visitor::visit_leave(ir_expression *ir) if (ir->operation != ir_binop_mod) return visit_continue; - ir_variable *temp = new(ir) ir_variable(ir->operands[1]->type, "mod_b"); + ir_variable *temp = new(ir) ir_variable(ir->operands[1]->type, "mod_b", + ir_var_temporary); this->base_ir->insert_before(temp); ir_assignment *assign; diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp index a1e5a7ad74..ed68496587 100644 --- a/src/glsl/ir_reader.cpp +++ b/src/glsl/ir_reader.cpp @@ -401,7 +401,8 @@ read_declaration(_mesa_glsl_parse_state *st, s_list *list) return NULL; } - ir_variable *var = new(ctx) ir_variable(type, var_name->value()); + ir_variable *var = new(ctx) ir_variable(type, var_name->value(), + ir_var_auto); foreach_iter(exec_list_iterator, it, quals->subexpressions) { s_symbol *qualifier = SX_AS_SYMBOL(it.get()); diff --git a/src/glsl/ir_variable.cpp b/src/glsl/ir_variable.cpp index 4593c18112..700c5de648 100644 --- a/src/glsl/ir_variable.cpp +++ b/src/glsl/ir_variable.cpp @@ -39,9 +39,8 @@ add_variable(const char *name, enum ir_variable_mode mode, int slot, const glsl_type *type, exec_list *instructions, glsl_symbol_table *symtab) { - ir_variable *var = new(symtab) ir_variable(type, name); + ir_variable *var = new(symtab) ir_variable(type, name, mode); - var->mode = mode; switch (var->mode) { case ir_var_auto: var->read_only = true; diff --git a/src/glsl/ir_vec_index_to_cond_assign.cpp b/src/glsl/ir_vec_index_to_cond_assign.cpp index ac420454e8..7e04389b5f 100644 --- a/src/glsl/ir_vec_index_to_cond_assign.cpp +++ b/src/glsl/ir_vec_index_to_cond_assign.cpp @@ -86,14 +86,16 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue /* Store the index to a temporary to avoid reusing its tree. */ index = new(base_ir) ir_variable(glsl_type::int_type, - "vec_index_tmp_i"); + "vec_index_tmp_i", + ir_var_temporary); base_ir->insert_before(index); deref = new(base_ir) ir_dereference_variable(index); assign = new(base_ir) ir_assignment(deref, orig_deref->array_index, NULL); base_ir->insert_before(assign); /* Temporary where we store whichever value we swizzle out. */ - var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v"); + var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v", + ir_var_temporary); base_ir->insert_before(var); /* Generate a conditional move of each vector element to the temp. */ @@ -166,14 +168,16 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir) assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); /* Store the index to a temporary to avoid reusing its tree. */ - index = new(ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i"); + index = new(ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i", + ir_var_temporary); ir->insert_before(index); deref = new(ir) ir_dereference_variable(index); assign = new(ir) ir_assignment(deref, orig_deref->array_index, NULL); ir->insert_before(assign); /* Store the RHS to a temporary to avoid reusing its tree. */ - var = new(ir) ir_variable(ir->rhs->type, "vec_index_tmp_v"); + var = new(ir) ir_variable(ir->rhs->type, "vec_index_tmp_v", + ir_var_temporary); ir->insert_before(var); deref = new(ir) ir_dereference_variable(var); assign = new(ir) ir_assignment(deref, ir->rhs, NULL); diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 4869dbe1ca..eb4eb9d20e 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -246,6 +246,8 @@ mode_string(const ir_variable *var) case ir_var_in: return "shader input"; case ir_var_out: return "shader output"; case ir_var_inout: return "shader inout"; + + case ir_var_temporary: default: assert(!"Should not get here."); return "invalid variable"; @@ -276,6 +278,12 @@ cross_validate_globals(struct gl_shader_program *prog, if (uniforms_only && (var->mode != ir_var_uniform)) continue; + /* Don't cross validate temporaries that are at global scope. These + * will eventually get pulled into the shaders 'main'. + */ + if (var->mode == ir_var_temporary) + continue; + /* If a global with this name has already been seen, verify that the * new instance has the same type. In addition, if the globals have * initializers, the values of the initializers must be the same. @@ -480,18 +488,28 @@ populate_symbol_table(gl_shader *sh) */ void remap_variables(ir_instruction *inst, glsl_symbol_table *symbols, - exec_list *instructions) + exec_list *instructions, hash_table *temps) { class remap_visitor : public ir_hierarchical_visitor { public: - remap_visitor(glsl_symbol_table *symbols, exec_list *instructions) + remap_visitor(glsl_symbol_table *symbols, exec_list *instructions, + hash_table *temps) { this->symbols = symbols; this->instructions = instructions; + this->temps = temps; } virtual ir_visitor_status visit(ir_dereference_variable *ir) { + if (ir->var->mode == ir_var_temporary) { + ir_variable *var = (ir_variable *) hash_table_find(temps, ir->var); + + assert(var != NULL); + ir->var = var; + return visit_continue; + } + ir_variable *const existing = this->symbols->get_variable(ir->var->name); if (existing != NULL) @@ -501,6 +519,7 @@ remap_variables(ir_instruction *inst, glsl_symbol_table *symbols, this->symbols->add_variable(copy->name, copy); this->instructions->push_head(copy); + ir->var = copy; } return visit_continue; @@ -509,9 +528,10 @@ remap_variables(ir_instruction *inst, glsl_symbol_table *symbols, private: glsl_symbol_table *symbols; exec_list *instructions; + hash_table *temps; }; - remap_visitor v(symbols, instructions); + remap_visitor v(symbols, instructions, temps); inst->accept(&v); } @@ -542,17 +562,32 @@ exec_node * move_non_declarations(exec_list *instructions, exec_node *last, bool make_copies, gl_shader *target) { + hash_table *temps = NULL; + + if (make_copies) + temps = hash_table_ctor(0, hash_table_pointer_hash, + hash_table_pointer_compare); + foreach_list_safe(node, instructions) { ir_instruction *inst = (ir_instruction *) node; - if (inst->as_variable() || inst->as_function()) + if (inst->as_function()) + continue; + + ir_variable *var = inst->as_variable(); + if ((var != NULL) && (var->mode != ir_var_temporary)) continue; - assert(inst->as_assignment()); + assert(inst->as_assignment() + || ((var != NULL) && (var->mode == ir_var_temporary))); if (make_copies) { inst = inst->clone(NULL); - remap_variables(inst, target->symbols, target->ir); + + if (var != NULL) + hash_table_insert(temps, inst, var); + else + remap_variables(inst, target->symbols, target->ir, temps); } else { inst->remove(); } @@ -561,6 +596,9 @@ move_non_declarations(exec_list *instructions, exec_node *last, last = inst; } + if (make_copies) + hash_table_dtor(temps); + return last; } diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp index 352b496625..7cc469f3a7 100644 --- a/src/mesa/shader/ir_to_mesa.cpp +++ b/src/mesa/shader/ir_to_mesa.cpp @@ -1133,6 +1133,7 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir) break; case ir_var_auto: + case ir_var_temporary: entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY, this->next_temp); this->variables.push_tail(entry); -- cgit v1.2.3 From f38d15b80d4e4c8ecb7a76087cdc49835f0aa271 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 20 Jul 2010 15:33:40 -0700 Subject: glsl2: glsl_type has its own talloc context, don't pass one in --- src/glsl/ast_function.cpp | 3 +-- src/glsl/ast_to_hir.cpp | 5 ++--- src/glsl/glsl_types.cpp | 11 +++++------ src/glsl/glsl_types.h | 5 ++--- src/glsl/ir_reader.cpp | 2 +- src/glsl/ir_variable.cpp | 17 +++++++---------- 6 files changed, 18 insertions(+), 25 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 14c36af911..73af882c53 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -312,8 +312,7 @@ process_array_constructor(exec_list *instructions, if (constructor_type->length == 0) { constructor_type = - glsl_type::get_array_instance(state, - constructor_type->element_type(), + glsl_type::get_array_instance(constructor_type->element_type(), parameter_count); assert(constructor_type != NULL); assert(constructor_type->length == parameter_count); diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index c68e136256..5cadcd1946 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -511,8 +511,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, var->max_array_access); } - var->type = glsl_type::get_array_instance(state, - lhs->type->element_type(), + var->type = glsl_type::get_array_instance(lhs->type->element_type(), rhs->type->array_size()); } } @@ -1407,7 +1406,7 @@ process_array_type(const glsl_type *base, ast_node *array_size, } } - return glsl_type::get_array_instance(state, base, length); + return glsl_type::get_array_instance(base, length); } diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index 5cb327c89d..de0adc0c6e 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -289,7 +289,7 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const } -glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) : +glsl_type::glsl_type(const glsl_type *array, unsigned length) : base_type(GLSL_TYPE_ARRAY), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), sampler_type(0), @@ -308,7 +308,7 @@ glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) : * NUL. */ const unsigned name_length = strlen(array->name) + 10 + 3; - char *const n = (char *) talloc_size(ctx, name_length); + char *const n = (char *) talloc_size(this->ctx, name_length); if (length == 0) snprintf(n, name_length, "%s[]", array->name); @@ -411,10 +411,9 @@ glsl_type::array_key_hash(const void *a) const glsl_type * -glsl_type::get_array_instance(void *ctx, const glsl_type *base, - unsigned array_size) +glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) { - const glsl_type key(ctx, base, array_size); + const glsl_type key(base, array_size); if (array_types == NULL) { array_types = hash_table_ctor(64, array_key_hash, array_key_compare); @@ -422,7 +421,7 @@ glsl_type::get_array_instance(void *ctx, const glsl_type *base, const glsl_type *t = (glsl_type *) hash_table_find(array_types, & key); if (t == NULL) { - t = new glsl_type(ctx, base, array_size); + t = new glsl_type(base, array_size); hash_table_insert(array_types, (void *) t, t); } diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h index 8ba9b5ff63..69fb9e3fb5 100644 --- a/src/glsl/glsl_types.h +++ b/src/glsl/glsl_types.h @@ -197,8 +197,7 @@ struct glsl_type { /** * Get the instance of an array type */ - static const glsl_type *get_array_instance(void *ctx, - const glsl_type *base, + static const glsl_type *get_array_instance(const glsl_type *base, unsigned elements); /** @@ -412,7 +411,7 @@ private: const char *name); /** Constructor for array types */ - glsl_type(void *ctx, const glsl_type *array, unsigned length); + glsl_type(const glsl_type *array, unsigned length); /** Hash table containing the known array types. */ static struct hash_table *array_types; diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp index ed68496587..8b4be4100b 100644 --- a/src/glsl/ir_reader.cpp +++ b/src/glsl/ir_reader.cpp @@ -138,7 +138,7 @@ read_type(_mesa_glsl_parse_state *st, s_expression *expr) return NULL; } - return glsl_type::get_array_instance(st, base_type, size->value()); + return glsl_type::get_array_instance(base_type, size->value()); } else if (strcmp(type_sym->value(), "struct") == 0) { assert(false); // FINISHME } else { diff --git a/src/glsl/ir_variable.cpp b/src/glsl/ir_variable.cpp index 700c5de648..0dd6d834b7 100644 --- a/src/glsl/ir_variable.cpp +++ b/src/glsl/ir_variable.cpp @@ -138,7 +138,7 @@ generate_110_uniforms(exec_list *instructions, state->Const.MaxFragmentUniformComponents); const glsl_type *const mat4_array_type = - glsl_type::get_array_instance(state->symbols, glsl_type::mat4_type, + glsl_type::get_array_instance(glsl_type::mat4_type, state->Const.MaxTextureCoords); add_variable("gl_TextureMatrix", ir_var_uniform, -1, mat4_array_type, @@ -157,8 +157,7 @@ generate_110_uniforms(exec_list *instructions, * FINISHME: at least 8, so hard-code 8 for now. */ const glsl_type *const light_source_array_type = - glsl_type::get_array_instance(state->symbols, - state->symbols->get_type("gl_LightSourceParameters"), 8); + glsl_type::get_array_instance(state->symbols->get_type("gl_LightSourceParameters"), 8); add_variable("gl_LightSource", ir_var_uniform, -1, light_source_array_type, instructions, state->symbols); @@ -196,7 +195,7 @@ generate_110_vs_variables(exec_list *instructions, * implementation in preserving varying resources." */ const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(state->symbols, glsl_type::vec4_type, 0); + glsl_type::get_array_instance(glsl_type::vec4_type, 0); add_variable("gl_TexCoord", ir_var_out, VERT_RESULT_TEX0, vec4_array_type, instructions, state->symbols); @@ -221,7 +220,6 @@ static void generate_130_vs_variables(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = state->symbols; generate_120_vs_variables(instructions, state); for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) { @@ -233,7 +231,7 @@ generate_130_vs_variables(exec_list *instructions, * FINISHME: the value of GL_MAX_CLIP_DISTANCES. */ const glsl_type *const clip_distance_array_type = - glsl_type::get_array_instance(ctx, glsl_type::float_type, 8); + glsl_type::get_array_instance(glsl_type::float_type, 8); /* FINISHME: gl_ClipDistance needs a real location assigned. */ add_variable("gl_ClipDistance", ir_var_out, -1, clip_distance_array_type, @@ -286,7 +284,7 @@ generate_110_fs_variables(exec_list *instructions, * implementation in preserving varying resources." */ const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(state->symbols, glsl_type::vec4_type, 0); + glsl_type::get_array_instance(glsl_type::vec4_type, 0); add_variable("gl_TexCoord", ir_var_in, FRAG_ATTRIB_TEX0, vec4_array_type, instructions, state->symbols); @@ -318,7 +316,7 @@ generate_ARB_draw_buffers_variables(exec_list *instructions, */ if (target == fragment_shader) { const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(state->symbols, glsl_type::vec4_type, + glsl_type::get_array_instance(glsl_type::vec4_type, state->Const.MaxDrawBuffers); ir_variable *const fd = @@ -349,14 +347,13 @@ static void generate_130_fs_variables(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - void *ctx = state->symbols; generate_120_fs_variables(instructions, state); /* FINISHME: The size of this array is implementation dependent based on * FINISHME: the value of GL_MAX_CLIP_DISTANCES. */ const glsl_type *const clip_distance_array_type = - glsl_type::get_array_instance(ctx, glsl_type::float_type, 8); + glsl_type::get_array_instance(glsl_type::float_type, 8); /* FINISHME: gl_ClipDistance needs a real location assigned. */ add_variable("gl_ClipDistance", ir_var_in, -1, clip_distance_array_type, -- cgit v1.2.3 From c24bcad9f88379ffba9e2f0ff92f22cdf60c2927 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 21 Jul 2010 11:23:51 -0700 Subject: glsl: Correctly handle unary plus operator. Previously, any occurence of the unary plus operator would trigger a bogus type mismatch error. Fix this by making the ast_plus case look more like the ast_neg case as far as type-checking is concerned. With this change the shaders/CorrectPreprocess8.frag test in piglit now passes. --- src/glsl/ast_to_hir.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 5cadcd1946..e9257eee28 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -660,9 +660,9 @@ ast_expression::hir(exec_list *instructions, case ast_plus: op[0] = this->subexpressions[0]->hir(instructions, state); - error_emitted = op[0]->type->is_error(); - if (type->is_error()) - op[0]->type = type; + type = unary_arithmetic_result_type(op[0]->type, state, & loc); + + error_emitted = type->is_error(); result = op[0]; break; -- cgit v1.2.3 From e1d71850faba23d1bea3858a8c2e05a45fd21143 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 20 Jul 2010 03:53:47 -0700 Subject: ast_to_hir: Fix bug in constant initializers. Implicit conversions were not being performed, nor was there any type checking - it was possible to have, say, var->type == float and var->constant_value->type == int. Later use of the constant expression would trigger an assertion. Fixes piglit test const-implicit-conversion.frag. --- src/glsl/ast_to_hir.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index e9257eee28..99a2183cf8 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1804,6 +1804,16 @@ ast_declarator_list::hir(exec_list *instructions, * declaration. */ if (this->type->qualifier.constant || this->type->qualifier.uniform) { + ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs); + if (new_rhs != NULL) { + rhs = new_rhs; + } else { + _mesa_glsl_error(&initializer_loc, state, + "initializer of type %s cannot be assigned to " + "variable of type %s", + rhs->type->name, var->type->name); + } + ir_constant *constant_value = rhs->constant_expression_value(); if (!constant_value) { _mesa_glsl_error(& initializer_loc, state, -- cgit v1.2.3 From 2d1ed7b1b112cf13dd7eda7f500691f4c98a1ccc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 22 Jul 2010 12:55:16 -0700 Subject: glsl2: When a "continue" happens in a "for" loop, run the loop expression. Fixes: glsl1-for-loop with continue Bug #29097 --- src/glsl/ast_to_hir.cpp | 14 ++++++++++++++ src/glsl/glsl_parser_extras.h | 1 + 2 files changed, 15 insertions(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 99a2183cf8..0cb3863b3e 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2308,6 +2308,16 @@ ast_jump_statement::hir(exec_list *instructions, } else { ir_loop *const loop = state->loop_or_switch_nesting->as_loop(); + /* Inline the for loop expression again, since we don't know + * where near the end of the loop body the normal copy of it + * is going to be placed. + */ + if (mode == ast_continue && + state->loop_or_switch_nesting_ast->rest_expression) { + state->loop_or_switch_nesting_ast->rest_expression->hir(instructions, + state); + } + if (loop != NULL) { ir_loop_jump *const jump = new(ctx) ir_loop_jump((mode == ast_break) @@ -2422,7 +2432,10 @@ ast_iteration_statement::hir(exec_list *instructions, /* Track the current loop and / or switch-statement nesting. */ ir_instruction *const nesting = state->loop_or_switch_nesting; + ast_iteration_statement *nesting_ast = state->loop_or_switch_nesting_ast; + state->loop_or_switch_nesting = stmt; + state->loop_or_switch_nesting_ast = this; if (mode != ast_do_while) condition_to_hir(stmt, state); @@ -2442,6 +2455,7 @@ ast_iteration_statement::hir(exec_list *instructions, /* Restore previous nesting before returning. */ state->loop_or_switch_nesting = nesting; + state->loop_or_switch_nesting_ast = nesting_ast; /* Loops do not have r-values. */ diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index 56f6e18e0b..3865843fd1 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -104,6 +104,7 @@ struct _mesa_glsl_parse_state { /** Loop or switch statement containing the current instructions. */ class ir_instruction *loop_or_switch_nesting; + class ast_iteration_statement *loop_or_switch_nesting_ast; /** List of structures defined in user code. */ const glsl_type **user_structures; -- cgit v1.2.3 From 47c90b144729e3edf3b5cbf5b260c1c46e429879 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 22 Jul 2010 14:56:14 -0700 Subject: glsl2: Fix expected type for multiplying vector with non-square matrix. Previously, the compiler expected the result of the multiplication to be of the same type as the vector. This is correct for square matrices, but wrong for all others. We fix this by instead expecting a vector with the same number of rows as the matrix (for the case of M*v with a column vector) or the same number of columns as the matrix (for v*M with a row vector). This fix causes the following four glean tests to now pass: glsl1-mat4x2 * vec4 glsl1-vec2 * mat4x2 multiply glsl1-vec3 * mat4x3 multiply glsl1-vec4 * mat3x4 multiply --- src/glsl/ast_to_hir.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 0cb3863b3e..5e26f21e9a 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -282,8 +282,17 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, * means the vector type of a row from A must be the same as the * vector the type of B. */ - if (type_a->row_type() == type_b) - return type_b; + if (type_a->row_type() == type_b) { + /* The resulting vector has a number of elements equal to + * the number of rows of matrix A. */ + const glsl_type *const type = + glsl_type::get_instance(type_a->base_type, + type_a->column_type()->vector_elements, + 1); + assert(type != glsl_type::error_type); + + return type; + } } else { assert(type_b->is_matrix()); @@ -292,8 +301,17 @@ arithmetic_result_type(ir_rvalue * &value_a, ir_rvalue * &value_b, * the type of A must be the same as the vector type of a column from * B. */ - if (type_a == type_b->column_type()) - return type_a; + if (type_a == type_b->column_type()) { + /* The resulting vector has a number of elements equal to + * the number of columns of matrix B. */ + const glsl_type *const type = + glsl_type::get_instance(type_a->base_type, + type_b->row_type()->vector_elements, + 1); + assert(type != glsl_type::error_type); + + return type; + } } _mesa_glsl_error(loc, state, "size mismatch for matrix multiplication"); -- cgit v1.2.3 From 9703ed05e684f4269cd8af27c94e9b6bf8781d85 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 22 Jul 2010 15:50:37 -0700 Subject: glsl2: When setting the size of an unsized array, set its deref's size too. --- src/glsl/ast_to_hir.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 5e26f21e9a..c03206fd2e 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -531,6 +531,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, var->type = glsl_type::get_array_instance(lhs->type->element_type(), rhs->type->array_size()); + d->type = var->type; } } -- cgit v1.2.3 From a0879b9dd438d78635f047cdd5ed4c72bc831b60 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 22 Jul 2010 16:30:41 -0700 Subject: glsl2: Put side effects of the RHS of logic_or in the right branch. Kind of missing the point to only do the side effects if the LHS evaluates as true. Fixes: glsl1-|| operator, short-circuit --- src/glsl/ast_to_hir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index c03206fd2e..98ea789249 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -898,7 +898,7 @@ ast_expression::hir(exec_list *instructions, ir_if *const stmt = new(ctx) ir_if(op[0]); instructions->push_tail(stmt); - op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state); + op[1] = this->subexpressions[1]->hir(&stmt->else_instructions, state); if (!op[1]->type->is_boolean() || !op[1]->type->is_scalar()) { YYLTYPE loc = this->subexpressions[1]->get_location(); -- cgit v1.2.3 From 8d8469eb2ade4fd48188403351a38f740987fb80 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 30 Jun 2010 17:48:09 -0700 Subject: glsl2: Perform some semantic checking of ARB_fcc layout qualifiers The rest cannot be handled until built-in variables (i.e., gl_FragCoord) can be redeclared to add qualifiers. --- src/glsl/ast_to_hir.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 98ea789249..d82cf33389 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1542,6 +1542,19 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, else var->interpolation = ir_var_smooth; + /* FINISHME: Apply the fragment coord convetion layout qualifiers. + */ + if ((qual->origin_upper_left || qual->pixel_center_integer) + && (strcmp(var->name, "gl_FragCoord") != 0)) { + const char *const qual_string = (qual->origin_upper_left) + ? "origin_upper_left" : "pixel_center_integer"; + + _mesa_glsl_error(loc, state, + "layout qualifier `%s' can only be applied to " + "fragment shader input `gl_FragCoord'", + qual_string); + } + if (var->type->is_array() && (state->language_version >= 120)) { var->array_lvalue = true; } -- cgit v1.2.3 From 4a962170d7cf4243d6ae156fca20a6167388925d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 28 Jul 2010 14:41:51 -0700 Subject: glsl2: Add support for redeclaring layout of gl_FragCoord for ARB_fcc. Fixes: glsl-arb-fragment-coord-conventions --- src/glsl/ast_to_hir.cpp | 15 +++++++++++++-- src/glsl/ir.h | 4 ++++ src/glsl/ir_clone.cpp | 2 ++ src/mesa/program/ir_to_mesa.cpp | 7 ++++++- 4 files changed, 25 insertions(+), 3 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index d82cf33389..8e8690c628 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -50,6 +50,7 @@ */ #include "main/imports.h" +#include "main/extensions.h" #include "glsl_symbol_table.h" #include "glsl_parser_extras.h" #include "ast.h" @@ -1542,8 +1543,8 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, else var->interpolation = ir_var_smooth; - /* FINISHME: Apply the fragment coord convetion layout qualifiers. - */ + var->pixel_center_integer = qual->pixel_center_integer; + var->origin_upper_left = qual->origin_upper_left; if ((qual->origin_upper_left || qual->pixel_center_integer) && (strcmp(var->name, "gl_FragCoord") != 0)) { const char *const qual_string = (qual->origin_upper_left) @@ -1932,6 +1933,16 @@ ast_declarator_list::hir(exec_list *instructions, earlier->type = var->type; delete var; var = NULL; + } else if (state->extensions->ARB_fragment_coord_conventions && + (earlier != NULL) && + (strcmp(var->name, "gl_FragCoord") == 0) && + earlier->type == var->type && + earlier->mode == var->mode) { + /* Allow redeclaration of gl_FragCoord for ARB_fcc layout + * qualifiers. + */ + earlier->origin_upper_left = var->origin_upper_left; + earlier->pixel_center_integer = var->pixel_center_integer; } else { YYLTYPE loc = this->get_location(); diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 7e8363106d..202685d145 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -238,6 +238,10 @@ public: */ unsigned array_lvalue:1; + /* ARB_fragment_coord_conventions */ + unsigned origin_upper_left:1; + unsigned pixel_center_integer:1; + /** * Storage location of the base of this variable * diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp index c49a732481..f97080d205 100644 --- a/src/glsl/ir_clone.cpp +++ b/src/glsl/ir_clone.cpp @@ -52,6 +52,8 @@ ir_variable::clone(struct hash_table *ht) const var->array_lvalue = this->array_lvalue; var->location = this->location; var->warn_extension = this->warn_extension; + var->origin_upper_left = this->origin_upper_left; + var->pixel_center_integer = this->pixel_center_integer; if (this->constant_value) var->constant_value = this->constant_value->clone(ht); diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index c53381e29d..a3019cc650 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -557,7 +557,12 @@ ir_to_mesa_visitor::find_variable_storage(ir_variable *var) void ir_to_mesa_visitor::visit(ir_variable *ir) { - (void)ir; + if (strcmp(ir->name, "gl_FragCoord") == 0) { + struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; + + fp->OriginUpperLeft = ir->origin_upper_left; + fp->PixelCenterInteger = ir->pixel_center_integer; + } } void -- cgit v1.2.3 From fa33d0b85403da94e3f4a7e6c868af215c076b4b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 29 Jul 2010 13:50:17 -0700 Subject: glsl2: Fix spelling of "initializer." --- src/glsl/ast_to_hir.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 8e8690c628..9591d36de8 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1800,7 +1800,7 @@ ast_declarator_list::hir(exec_list *instructions, * redeclarations) the declaration may not actually be added to the * instruction stream. */ - exec_list intializer_instructions; + exec_list initializer_instructions; if (decl->initializer != NULL) { YYLTYPE initializer_loc = decl->initializer->get_location(); @@ -1830,7 +1830,7 @@ ast_declarator_list::hir(exec_list *instructions, } ir_dereference *const lhs = new(ctx) ir_dereference_variable(var); - ir_rvalue *rhs = decl->initializer->hir(&intializer_instructions, + ir_rvalue *rhs = decl->initializer->hir(&initializer_instructions, state); /* Calculate the constant value if this is a const or uniform @@ -1869,7 +1869,8 @@ ast_declarator_list::hir(exec_list *instructions, /* Never emit code to initialize a uniform. */ if (!this->type->qualifier.uniform) - result = do_assignment(&intializer_instructions, state, lhs, rhs, + result = do_assignment(&initializer_instructions, state, + lhs, rhs, this->get_location()); var->read_only = temp; } @@ -1969,7 +1970,7 @@ ast_declarator_list::hir(exec_list *instructions, } instructions->push_tail(var); - instructions->append_list(&intializer_instructions); + instructions->append_list(&initializer_instructions); /* Add the variable to the symbol table after processing the initializer. * This differs from most C-like languages, but it follows the GLSL -- cgit v1.2.3 From 1c325af4d6b907e0a47ab7f868a2a78f054f153f Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Thu, 29 Jul 2010 15:35:22 +0300 Subject: glsl2: Fix stack smash when ternary selection is used. --- src/glsl/ast_to_hir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 9591d36de8..3522f55aac 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -658,7 +658,7 @@ ast_expression::hir(exec_list *instructions, -1, /* ast_sequence doesn't convert to ir_expression. */ }; ir_rvalue *result = NULL; - ir_rvalue *op[2]; + ir_rvalue *op[3]; const struct glsl_type *type = glsl_type::error_type; bool error_emitted = false; YYLTYPE loc; -- cgit v1.2.3 From 8273bd46877e2ea2b8a02b87a11c68102d07e1f2 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 4 Aug 2010 12:34:56 -0700 Subject: glsl2: Make the clone() method take a talloc context. In most cases, we needed to be reparenting the cloned IR to a different context (for example, to the linked shader instead of the unlinked shader), or optimization before the reparent would cause memory usage of the original object to grow and grow. --- src/glsl/ast_to_hir.cpp | 10 +-- src/glsl/ir.h | 47 +++++----- src/glsl/ir_clone.cpp | 150 ++++++++++++++----------------- src/glsl/ir_constant_expression.cpp | 7 +- src/glsl/ir_function_inlining.cpp | 6 +- src/glsl/ir_import_prototypes.cpp | 2 +- src/glsl/ir_vec_index_to_cond_assign.cpp | 8 +- src/glsl/link_functions.cpp | 6 +- src/glsl/linker.cpp | 25 +++--- 9 files changed, 130 insertions(+), 131 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 3522f55aac..b65a323a8d 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -966,7 +966,7 @@ ast_expression::hir(exec_list *instructions, op[0], op[1]); result = do_assignment(instructions, state, - op[0]->clone(NULL), temp_rhs, + op[0]->clone(ctx, NULL), temp_rhs, this->subexpressions[0]->get_location()); type = result->type; error_emitted = (op[0]->type->is_error()); @@ -992,7 +992,7 @@ ast_expression::hir(exec_list *instructions, op[0], op[1]); result = do_assignment(instructions, state, - op[0]->clone(NULL), temp_rhs, + op[0]->clone(ctx, NULL), temp_rhs, this->subexpressions[0]->get_location()); type = result->type; error_emitted = type->is_error(); @@ -1113,7 +1113,7 @@ ast_expression::hir(exec_list *instructions, op[0], op[1]); result = do_assignment(instructions, state, - op[0]->clone(NULL), temp_rhs, + op[0]->clone(ctx, NULL), temp_rhs, this->subexpressions[0]->get_location()); type = result->type; error_emitted = op[0]->type->is_error(); @@ -1139,10 +1139,10 @@ ast_expression::hir(exec_list *instructions, /* Get a temporary of a copy of the lvalue before it's modified. * This may get thrown away later. */ - result = get_lvalue_copy(instructions, op[0]->clone(NULL)); + result = get_lvalue_copy(instructions, op[0]->clone(ctx, NULL)); (void)do_assignment(instructions, state, - op[0]->clone(NULL), temp_rhs, + op[0]->clone(ctx, NULL), temp_rhs, this->subexpressions[0]->get_location()); type = result->type; diff --git a/src/glsl/ir.h b/src/glsl/ir.h index f88a243cc0..f964b36083 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -76,7 +76,8 @@ public: virtual void accept(ir_visitor *) = 0; virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0; - virtual ir_instruction *clone(struct hash_table *ht) const = 0; + virtual ir_instruction *clone(void *mem_ctx, + struct hash_table *ht) const = 0; /** * \name IR instruction downcast functions @@ -113,7 +114,7 @@ protected: class ir_rvalue : public ir_instruction { public: - virtual ir_rvalue *clone(struct hash_table *) const = 0; + virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const = 0; virtual ir_constant *constant_expression_value() = 0; @@ -175,7 +176,7 @@ class ir_variable : public ir_instruction { public: ir_variable(const struct glsl_type *, const char *, ir_variable_mode); - virtual ir_variable *clone(struct hash_table *ht) const; + virtual ir_variable *clone(void *mem_ctx, struct hash_table *ht) const; virtual ir_variable *as_variable() { @@ -283,7 +284,8 @@ class ir_function_signature : public ir_instruction { public: ir_function_signature(const glsl_type *return_type); - virtual ir_function_signature *clone(struct hash_table *ht) const; + virtual ir_function_signature *clone(void *mem_ctx, + struct hash_table *ht) const; virtual void accept(ir_visitor *v) { @@ -369,7 +371,7 @@ class ir_function : public ir_instruction { public: ir_function(const char *name); - virtual ir_function *clone(struct hash_table *ht) const; + virtual ir_function *clone(void *mem_ctx, struct hash_table *ht) const; virtual ir_function *as_function() { @@ -439,7 +441,7 @@ public: ir_type = ir_type_if; } - virtual ir_if *clone(struct hash_table *ht) const; + virtual ir_if *clone(void *mem_ctx, struct hash_table *ht) const; virtual ir_if *as_if() { @@ -471,7 +473,7 @@ public: ir_type = ir_type_loop; } - virtual ir_loop *clone(struct hash_table *ht) const; + virtual ir_loop *clone(void *mem_ctx, struct hash_table *ht) const; virtual void accept(ir_visitor *v) { @@ -512,7 +514,7 @@ class ir_assignment : public ir_instruction { public: ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition); - virtual ir_assignment *clone(struct hash_table *ht) const; + virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const; virtual ir_constant *constant_expression_value(); @@ -662,7 +664,7 @@ public: return this; } - virtual ir_expression *clone(struct hash_table *ht) const; + virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const; virtual ir_constant *constant_expression_value(); @@ -708,7 +710,7 @@ public: actual_parameters->move_nodes_to(& this->actual_parameters); } - virtual ir_call *clone(struct hash_table *ht) const; + virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const; virtual ir_constant *constant_expression_value(); @@ -805,7 +807,7 @@ public: this->ir_type = ir_type_return; } - virtual ir_return *clone(struct hash_table *) const; + virtual ir_return *clone(void *mem_ctx, struct hash_table *) const; virtual ir_return *as_return() { @@ -850,7 +852,7 @@ public: this->loop = loop; } - virtual ir_loop_jump *clone(struct hash_table *) const; + virtual ir_loop_jump *clone(void *mem_ctx, struct hash_table *) const; virtual void accept(ir_visitor *v) { @@ -893,7 +895,7 @@ public: this->condition = cond; } - virtual ir_discard *clone(struct hash_table *ht) const; + virtual ir_discard *clone(void *mem_ctx, struct hash_table *ht) const; virtual void accept(ir_visitor *v) { @@ -945,7 +947,7 @@ public: this->ir_type = ir_type_texture; } - virtual ir_texture *clone(struct hash_table *) const; + virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const; virtual ir_constant *constant_expression_value(); @@ -1037,7 +1039,7 @@ public: ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask); - virtual ir_swizzle *clone(struct hash_table *) const; + virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const; virtual ir_constant *constant_expression_value(); @@ -1083,7 +1085,7 @@ private: class ir_dereference : public ir_rvalue { public: - virtual ir_dereference *clone(struct hash_table *) const = 0; + virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0; virtual ir_dereference *as_dereference() { @@ -1103,7 +1105,8 @@ class ir_dereference_variable : public ir_dereference { public: ir_dereference_variable(ir_variable *var); - virtual ir_dereference_variable *clone(struct hash_table *) const; + virtual ir_dereference_variable *clone(void *mem_ctx, + struct hash_table *) const; virtual ir_constant *constant_expression_value(); @@ -1151,7 +1154,8 @@ public: ir_dereference_array(ir_variable *var, ir_rvalue *array_index); - virtual ir_dereference_array *clone(struct hash_table *) const; + virtual ir_dereference_array *clone(void *mem_ctx, + struct hash_table *) const; virtual ir_constant *constant_expression_value(); @@ -1189,7 +1193,8 @@ public: ir_dereference_record(ir_variable *var, const char *field); - virtual ir_dereference_record *clone(struct hash_table *) const; + virtual ir_dereference_record *clone(void *mem_ctx, + struct hash_table *) const; virtual ir_constant *constant_expression_value(); @@ -1254,7 +1259,7 @@ public: */ static ir_constant *zero(void *mem_ctx, const glsl_type *type); - virtual ir_constant *clone(struct hash_table *) const; + virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const; virtual ir_constant *constant_expression_value(); @@ -1327,7 +1332,7 @@ void validate_ir_tree(exec_list *instructions); * \param out List to hold the cloned instructions */ void -clone_ir_list(exec_list *out, const exec_list *in); +clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in); extern void _mesa_glsl_initialize_variables(exec_list *instructions, diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp index 5ea3a79afc..59831834bd 100644 --- a/src/glsl/ir_clone.cpp +++ b/src/glsl/ir_clone.cpp @@ -36,11 +36,10 @@ extern "C" { * eventually. */ ir_variable * -ir_variable::clone(struct hash_table *ht) const +ir_variable::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); - ir_variable *var = new(ctx) ir_variable(this->type, this->name, - (ir_variable_mode) this->mode); + ir_variable *var = new(mem_ctx) ir_variable(this->type, this->name, + (ir_variable_mode) this->mode); var->max_array_access = this->max_array_access; var->read_only = this->read_only; @@ -56,7 +55,7 @@ ir_variable::clone(struct hash_table *ht) const var->pixel_center_integer = this->pixel_center_integer; if (this->constant_value) - var->constant_value = this->constant_value->clone(ht); + var->constant_value = this->constant_value->clone(mem_ctx, ht); if (ht) { hash_table_insert(ht, var, (void *)const_cast(this)); @@ -66,118 +65,109 @@ ir_variable::clone(struct hash_table *ht) const } ir_swizzle * -ir_swizzle::clone(struct hash_table *ht) const +ir_swizzle::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); - return new(ctx) ir_swizzle(this->val->clone(ht), this->mask); + return new(mem_ctx) ir_swizzle(this->val->clone(mem_ctx, ht), this->mask); } ir_return * -ir_return::clone(struct hash_table *ht) const +ir_return::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); ir_rvalue *new_value = NULL; if (this->value) - new_value = this->value->clone(ht); + new_value = this->value->clone(mem_ctx, ht); - return new(ctx) ir_return(new_value); + return new(mem_ctx) ir_return(new_value); } ir_discard * -ir_discard::clone(struct hash_table *ht) const +ir_discard::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); ir_rvalue *new_condition = NULL; if (this->condition != NULL) - new_condition = this->condition->clone(ht); + new_condition = this->condition->clone(mem_ctx, ht); - return new(ctx) ir_discard(new_condition); + return new(mem_ctx) ir_discard(new_condition); } ir_loop_jump * -ir_loop_jump::clone(struct hash_table *ht) const +ir_loop_jump::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); (void)ht; - return new(ctx) ir_loop_jump(this->mode); + return new(mem_ctx) ir_loop_jump(this->mode); } ir_if * -ir_if::clone(struct hash_table *ht) const +ir_if::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); - ir_if *new_if = new(ctx) ir_if(this->condition->clone(ht)); + ir_if *new_if = new(mem_ctx) ir_if(this->condition->clone(mem_ctx, ht)); foreach_iter(exec_list_iterator, iter, this->then_instructions) { ir_instruction *ir = (ir_instruction *)iter.get(); - new_if->then_instructions.push_tail(ir->clone(ht)); + new_if->then_instructions.push_tail(ir->clone(mem_ctx, ht)); } foreach_iter(exec_list_iterator, iter, this->else_instructions) { ir_instruction *ir = (ir_instruction *)iter.get(); - new_if->else_instructions.push_tail(ir->clone(ht)); + new_if->else_instructions.push_tail(ir->clone(mem_ctx, ht)); } return new_if; } ir_loop * -ir_loop::clone(struct hash_table *ht) const +ir_loop::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); - ir_loop *new_loop = new(ctx) ir_loop(); + ir_loop *new_loop = new(mem_ctx) ir_loop(); if (this->from) - new_loop->from = this->from->clone(ht); + new_loop->from = this->from->clone(mem_ctx, ht); if (this->to) - new_loop->to = this->to->clone(ht); + new_loop->to = this->to->clone(mem_ctx, ht); if (this->increment) - new_loop->increment = this->increment->clone(ht); + new_loop->increment = this->increment->clone(mem_ctx, ht); new_loop->counter = counter; foreach_iter(exec_list_iterator, iter, this->body_instructions) { ir_instruction *ir = (ir_instruction *)iter.get(); - new_loop->body_instructions.push_tail(ir->clone(ht)); + new_loop->body_instructions.push_tail(ir->clone(mem_ctx, ht)); } return new_loop; } ir_call * -ir_call::clone(struct hash_table *ht) const +ir_call::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); exec_list new_parameters; foreach_iter(exec_list_iterator, iter, this->actual_parameters) { ir_instruction *ir = (ir_instruction *)iter.get(); - new_parameters.push_tail(ir->clone(ht)); + new_parameters.push_tail(ir->clone(mem_ctx, ht)); } - return new(ctx) ir_call(this->callee, &new_parameters); + return new(mem_ctx) ir_call(this->callee, &new_parameters); } ir_expression * -ir_expression::clone(struct hash_table *ht) const +ir_expression::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); ir_rvalue *op[2] = {NULL, NULL}; unsigned int i; for (i = 0; i < get_num_operands(); i++) { - op[i] = this->operands[i]->clone(ht); + op[i] = this->operands[i]->clone(mem_ctx, ht); } - return new(ctx) ir_expression(this->operation, this->type, op[0], op[1]); + return new(mem_ctx) ir_expression(this->operation, this->type, op[0], op[1]); } ir_dereference_variable * -ir_dereference_variable::clone(struct hash_table *ht) const +ir_dereference_variable::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); ir_variable *new_var; if (ht) { @@ -188,38 +178,36 @@ ir_dereference_variable::clone(struct hash_table *ht) const new_var = this->var; } - return new(ctx) ir_dereference_variable(new_var); + return new(mem_ctx) ir_dereference_variable(new_var); } ir_dereference_array * -ir_dereference_array::clone(struct hash_table *ht) const +ir_dereference_array::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); - return new(ctx) ir_dereference_array(this->array->clone(ht), - this->array_index->clone(ht)); + return new(mem_ctx) ir_dereference_array(this->array->clone(mem_ctx, ht), + this->array_index->clone(mem_ctx, + ht)); } ir_dereference_record * -ir_dereference_record::clone(struct hash_table *ht) const +ir_dereference_record::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); - return new(ctx) ir_dereference_record(this->record->clone(ht), - this->field); + return new(mem_ctx) ir_dereference_record(this->record->clone(mem_ctx, ht), + this->field); } ir_texture * -ir_texture::clone(struct hash_table *ht) const +ir_texture::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); - ir_texture *new_tex = new(ctx) ir_texture(this->op); + ir_texture *new_tex = new(mem_ctx) ir_texture(this->op); new_tex->type = this->type; - new_tex->sampler = this->sampler->clone(ht); - new_tex->coordinate = this->coordinate->clone(ht); + new_tex->sampler = this->sampler->clone(mem_ctx, ht); + new_tex->coordinate = this->coordinate->clone(mem_ctx, ht); if (this->projector) - new_tex->projector = this->projector->clone(ht); + new_tex->projector = this->projector->clone(mem_ctx, ht); if (this->shadow_comparitor) { - new_tex->shadow_comparitor = this->shadow_comparitor->clone(ht); + new_tex->shadow_comparitor = this->shadow_comparitor->clone(mem_ctx, ht); } for (int i = 0; i < 3; i++) @@ -229,15 +217,15 @@ ir_texture::clone(struct hash_table *ht) const case ir_tex: break; case ir_txb: - new_tex->lod_info.bias = this->lod_info.bias->clone(ht); + new_tex->lod_info.bias = this->lod_info.bias->clone(mem_ctx, ht); break; case ir_txl: case ir_txf: - new_tex->lod_info.lod = this->lod_info.lod->clone(ht); + new_tex->lod_info.lod = this->lod_info.lod->clone(mem_ctx, ht); break; case ir_txd: - new_tex->lod_info.grad.dPdx = this->lod_info.grad.dPdx->clone(ht); - new_tex->lod_info.grad.dPdy = this->lod_info.grad.dPdy->clone(ht); + new_tex->lod_info.grad.dPdx = this->lod_info.grad.dPdx->clone(mem_ctx, ht); + new_tex->lod_info.grad.dPdy = this->lod_info.grad.dPdy->clone(mem_ctx, ht); break; } @@ -245,30 +233,28 @@ ir_texture::clone(struct hash_table *ht) const } ir_assignment * -ir_assignment::clone(struct hash_table *ht) const +ir_assignment::clone(void *mem_ctx, struct hash_table *ht) const { ir_rvalue *new_condition = NULL; if (this->condition) - new_condition = this->condition->clone(ht); + new_condition = this->condition->clone(mem_ctx, ht); - void *ctx = talloc_parent(this); - return new(ctx) ir_assignment(this->lhs->clone(ht), - this->rhs->clone(ht), - new_condition); + return new(mem_ctx) ir_assignment(this->lhs->clone(mem_ctx, ht), + this->rhs->clone(mem_ctx, ht), + new_condition); } ir_function * -ir_function::clone(struct hash_table *ht) const +ir_function::clone(void *mem_ctx, struct hash_table *ht) const { - void *mem_ctx = talloc_parent(this); ir_function *copy = new(mem_ctx) ir_function(this->name); foreach_list_const(node, &this->signatures) { const ir_function_signature *const sig = (const ir_function_signature *const) node; - ir_function_signature *sig_copy = sig->clone(ht); + ir_function_signature *sig_copy = sig->clone(mem_ctx, ht); copy->add_signature(sig_copy); if (ht != NULL) @@ -280,9 +266,8 @@ ir_function::clone(struct hash_table *ht) const } ir_function_signature * -ir_function_signature::clone(struct hash_table *ht) const +ir_function_signature::clone(void *mem_ctx, struct hash_table *ht) const { - void *mem_ctx = talloc_parent(this); ir_function_signature *copy = new(mem_ctx) ir_function_signature(this->return_type); @@ -296,7 +281,7 @@ ir_function_signature::clone(struct hash_table *ht) const assert(const_cast(param)->as_variable() != NULL); - ir_variable *const param_copy = param->clone(ht); + ir_variable *const param_copy = param->clone(mem_ctx, ht); copy->parameters.push_tail(param_copy); } @@ -305,7 +290,7 @@ ir_function_signature::clone(struct hash_table *ht) const foreach_list_const(node, &this->body) { const ir_instruction *const inst = (const ir_instruction *) node; - ir_instruction *const inst_copy = inst->clone(ht); + ir_instruction *const inst_copy = inst->clone(mem_ctx, ht); copy->body.push_tail(inst_copy); } @@ -313,9 +298,8 @@ ir_function_signature::clone(struct hash_table *ht) const } ir_constant * -ir_constant::clone(struct hash_table *ht) const +ir_constant::clone(void *mem_ctx, struct hash_table *ht) const { - void *ctx = talloc_parent(this); (void)ht; switch (this->type->base_type) { @@ -323,10 +307,10 @@ ir_constant::clone(struct hash_table *ht) const case GLSL_TYPE_INT: case GLSL_TYPE_FLOAT: case GLSL_TYPE_BOOL: - return new(ctx) ir_constant(this->type, &this->value); + return new(mem_ctx) ir_constant(this->type, &this->value); case GLSL_TYPE_STRUCT: { - ir_constant *c = new(ctx) ir_constant; + ir_constant *c = new(mem_ctx) ir_constant; c->type = this->type; for (exec_node *node = this->components.head @@ -334,19 +318,19 @@ ir_constant::clone(struct hash_table *ht) const ; node = node->next) { ir_constant *const orig = (ir_constant *) node; - c->components.push_tail(orig->clone(NULL)); + c->components.push_tail(orig->clone(mem_ctx, NULL)); } return c; } case GLSL_TYPE_ARRAY: { - ir_constant *c = new(ctx) ir_constant; + ir_constant *c = new(mem_ctx) ir_constant; c->type = this->type; c->array_elements = talloc_array(c, ir_constant *, this->type->length); for (unsigned i = 0; i < this->type->length; i++) { - c->array_elements[i] = this->array_elements[i]->clone(NULL); + c->array_elements[i] = this->array_elements[i]->clone(mem_ctx, NULL); } return c; } @@ -395,14 +379,14 @@ fixup_function_calls(struct hash_table *ht, exec_list *instructions) void -clone_ir_list(exec_list *out, const exec_list *in) +clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in) { struct hash_table *ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare); foreach_list_const(node, in) { const ir_instruction *const original = (ir_instruction *) node; - ir_instruction *copy = original->clone(ht); + ir_instruction *copy = original->clone(mem_ctx, ht); out->push_tail(copy); } diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index 06bea2bef6..677353e542 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -680,7 +680,10 @@ ir_dereference_variable::constant_expression_value() if (var->mode == ir_var_uniform) return NULL; - return var->constant_value ? var->constant_value->clone(NULL) : NULL; + if (!var->constant_value) + return NULL; + + return var->constant_value->clone(talloc_parent(var), NULL); } @@ -732,7 +735,7 @@ ir_dereference_array::constant_expression_value() return new(ctx) ir_constant(array, component); } else { const unsigned index = idx->value.u[0]; - return array->get_array_element(index)->clone(NULL); + return array->get_array_element(index)->clone(ctx, NULL); } } return NULL; diff --git a/src/glsl/ir_function_inlining.cpp b/src/glsl/ir_function_inlining.cpp index 9599306243..973813774e 100644 --- a/src/glsl/ir_function_inlining.cpp +++ b/src/glsl/ir_function_inlining.cpp @@ -147,7 +147,7 @@ ir_call::generate_inline(ir_instruction *next_ir) parameters[i] = NULL; hash_table_insert(ht, param->variable_referenced(), sig_param); } else { - parameters[i] = sig_param->clone(ht); + parameters[i] = sig_param->clone(ctx, ht); parameters[i]->mode = ir_var_auto; next_ir->insert_before(parameters[i]); } @@ -169,7 +169,7 @@ ir_call::generate_inline(ir_instruction *next_ir) /* Generate the inlined body of the function. */ foreach_iter(exec_list_iterator, iter, callee->body) { ir_instruction *ir = (ir_instruction *)iter.get(); - ir_instruction *new_ir = ir->clone(ht); + ir_instruction *new_ir = ir->clone(ctx, ht); next_ir->insert_before(new_ir); visit_tree(new_ir, replace_return_with_assignment, retval); @@ -190,7 +190,7 @@ ir_call::generate_inline(ir_instruction *next_ir) sig_param->mode == ir_var_inout)) { ir_assignment *assign; - assign = new(ctx) ir_assignment(param->clone(NULL)->as_rvalue(), + assign = new(ctx) ir_assignment(param->clone(ctx, NULL)->as_rvalue(), new(ctx) ir_dereference_variable(parameters[i]), NULL); next_ir->insert_before(assign); diff --git a/src/glsl/ir_import_prototypes.cpp b/src/glsl/ir_import_prototypes.cpp index 5c5dc00ad7..e553e12a49 100644 --- a/src/glsl/ir_import_prototypes.cpp +++ b/src/glsl/ir_import_prototypes.cpp @@ -95,7 +95,7 @@ public: assert(const_cast(param)->as_variable() != NULL); - ir_variable *const param_copy = param->clone(NULL); + ir_variable *const param_copy = param->clone(mem_ctx, NULL); copy->parameters.push_tail(param_copy); } diff --git a/src/glsl/ir_vec_index_to_cond_assign.cpp b/src/glsl/ir_vec_index_to_cond_assign.cpp index dbc6f9ada8..cd8dedf2fe 100644 --- a/src/glsl/ir_vec_index_to_cond_assign.cpp +++ b/src/glsl/ir_vec_index_to_cond_assign.cpp @@ -82,6 +82,8 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue orig_deref->array->type->is_array()) return ir; + void *mem_ctx = talloc_parent(ir); + assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); /* Store the index to a temporary to avoid reusing its tree. */ @@ -109,7 +111,7 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue /* Just clone the rest of the deref chain when trying to get at the * underlying variable. */ - swizzle = new(base_ir) ir_swizzle(orig_deref->array->clone(NULL), + swizzle = new(base_ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), i, 0, 0, 0, 1); deref = new(base_ir) ir_dereference_variable(var); @@ -165,6 +167,8 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir) orig_deref->array->type->is_array()) return visit_continue; + void *mem_ctx = talloc_parent(ir); + assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT); /* Store the index to a temporary to avoid reusing its tree. */ @@ -196,7 +200,7 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir) /* Just clone the rest of the deref chain when trying to get at the * underlying variable. */ - swizzle = new(ir) ir_swizzle(orig_deref->array->clone(NULL), + swizzle = new(ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), i, 0, 0, 0, 1); deref = new(ir) ir_dereference_variable(var); diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp index fdf886f662..dfda05fcbe 100644 --- a/src/glsl/link_functions.cpp +++ b/src/glsl/link_functions.cpp @@ -143,7 +143,7 @@ public: const ir_instruction *const original = (ir_instruction *) node; assert(const_cast(original)->as_variable()); - ir_instruction *copy = original->clone(ht); + ir_instruction *copy = original->clone(linked, ht); formal_parameters.push_tail(copy); } @@ -152,7 +152,7 @@ public: foreach_list_const(node, &sig->body) { const ir_instruction *const original = (ir_instruction *) node; - ir_instruction *copy = original->clone(ht); + ir_instruction *copy = original->clone(linked, ht); linked_sig->body.push_tail(copy); } @@ -182,7 +182,7 @@ public: /* Clone the ir_variable that the dereference already has and add * it to the linked shader. */ - var = ir->var->clone(NULL); + var = ir->var->clone(linked, NULL); linked->symbols->add_variable(var->name, var); linked->ir->push_head(var); } diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index a5faff2be7..65f3697d35 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -323,7 +323,8 @@ cross_validate_globals(struct gl_shader_program *prog, * FINISHME: modify the shader, and linking with the second * FINISHME: will fail. */ - existing->constant_value = var->constant_value->clone(NULL); + existing->constant_value = + var->constant_value->clone(talloc_parent(existing), NULL); } } else variables.add_variable(var->name, var); @@ -488,16 +489,17 @@ populate_symbol_table(gl_shader *sh) * should be added. */ void -remap_variables(ir_instruction *inst, glsl_symbol_table *symbols, - exec_list *instructions, hash_table *temps) +remap_variables(ir_instruction *inst, struct gl_shader *target, + hash_table *temps) { class remap_visitor : public ir_hierarchical_visitor { public: - remap_visitor(glsl_symbol_table *symbols, exec_list *instructions, + remap_visitor(struct gl_shader *target, hash_table *temps) { - this->symbols = symbols; - this->instructions = instructions; + this->target = target; + this->symbols = target->symbols; + this->instructions = target->ir; this->temps = temps; } @@ -516,7 +518,7 @@ remap_variables(ir_instruction *inst, glsl_symbol_table *symbols, if (existing != NULL) ir->var = existing; else { - ir_variable *copy = ir->var->clone(NULL); + ir_variable *copy = ir->var->clone(this->target, NULL); this->symbols->add_variable(copy->name, copy); this->instructions->push_head(copy); @@ -527,12 +529,13 @@ remap_variables(ir_instruction *inst, glsl_symbol_table *symbols, } private: + struct gl_shader *target; glsl_symbol_table *symbols; exec_list *instructions; hash_table *temps; }; - remap_visitor v(symbols, instructions, temps); + remap_visitor v(target, temps); inst->accept(&v); } @@ -583,12 +586,12 @@ move_non_declarations(exec_list *instructions, exec_node *last, || ((var != NULL) && (var->mode == ir_var_temporary))); if (make_copies) { - inst = inst->clone(NULL); + inst = inst->clone(target, NULL); if (var != NULL) hash_table_insert(temps, inst, var); else - remap_variables(inst, target->symbols, target->ir, temps); + remap_variables(inst, target, temps); } else { inst->remove(); } @@ -713,7 +716,7 @@ link_intrastage_shaders(struct gl_shader_program *prog, gl_shader *const linked = _mesa_new_shader(NULL, 0, main->Type); linked->ir = new(linked) exec_list; - clone_ir_list(linked->ir, main->ir); + clone_ir_list(linked, linked->ir, main->ir); populate_symbol_table(linked); -- cgit v1.2.3 From 8e9ce2eb56a087c2544112700ae1abe3f96648dd Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 3 Aug 2010 15:02:35 -0700 Subject: glsl2: Don't try to construct an ir_assignment with an invalid LHS --- src/glsl/ast_to_hir.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index b65a323a8d..14c528075b 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -555,9 +555,8 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, NULL)); deref_var = new(ctx) ir_dereference_variable(var); - instructions->push_tail(new(ctx) ir_assignment(lhs, - deref_var, - NULL)); + if (!error_emitted) + instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var, NULL)); return new(ctx) ir_dereference_variable(var); } -- cgit v1.2.3 From 046bef235744e891e4a48076e1a3ff9a61a63092 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 4 Aug 2010 20:33:57 -0700 Subject: glsl2: Remove the shader_in/shader_out tracking separate from var->mode. I introduced this for ir_dead_code to distinguish function parameter outvals from varying outputs. Only, since ast_to_hir's current_function is unset when setting up function parameters (they're needed for making the function signature in the first place), all function parameter outvals were marked as shader outputs anyway. This meant that an inlined function's cloned outval was marked as a shader output and couldn't be dead-code eliminated. Instead, since ir_dead_code doesn't even look at function parameters, just use var->mode. The longest Mesa IR coming out of ir_to_mesa for Yo Frankie drops from 725 instructions to 636. --- src/glsl/ast_to_hir.cpp | 37 ++++++++++--------------------------- src/glsl/ir.cpp | 4 ---- src/glsl/ir.h | 14 ++++---------- src/glsl/ir_clone.cpp | 2 -- src/glsl/ir_dead_code.cpp | 3 ++- src/glsl/ir_variable.cpp | 12 +----------- src/glsl/linker.cpp | 2 -- 7 files changed, 17 insertions(+), 57 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 14c528075b..292c7be621 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1510,31 +1510,6 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, else if (qual->uniform) var->mode = ir_var_uniform; - if (qual->uniform) - var->shader_in = true; - - /* Any 'in' or 'inout' variables at global scope must be marked as being - * shader inputs. Likewise, any 'out' or 'inout' variables at global scope - * must be marked as being shader outputs. - */ - if (state->current_function == NULL) { - switch (var->mode) { - case ir_var_in: - case ir_var_uniform: - var->shader_in = true; - break; - case ir_var_out: - var->shader_out = true; - break; - case ir_var_inout: - var->shader_in = true; - var->shader_out = true; - break; - default: - break; - } - } - if (qual->flat) var->interpolation = ir_var_flat; else if (qual->noperspective) @@ -1702,11 +1677,19 @@ ast_declarator_list::hir(exec_list *instructions, & loc); if (this->type->qualifier.invariant) { - if ((state->target == vertex_shader) && !var->shader_out) { + if ((state->target == vertex_shader) && !(var->mode == ir_var_out || + var->mode == ir_var_inout)) { + /* FINISHME: Note that this doesn't work for invariant on + * a function signature outval + */ _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, vertex shader " "outputs only\n", var->name); - } else if ((state->target == fragment_shader) && !var->shader_in) { + } else if ((state->target == fragment_shader) && + !(var->mode == ir_var_in || var->mode == ir_var_inout)) { + /* FINISHME: Note that this doesn't work for invariant on + * a function signature inval + */ _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, fragment shader " "inputs only\n", var->name); diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index c3bade8d54..dd059e470d 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -902,7 +902,6 @@ ir_swizzle::variable_referenced() ir_variable::ir_variable(const struct glsl_type *type, const char *name, ir_variable_mode mode) : max_array_access(0), read_only(false), centroid(false), invariant(false), - shader_in(false), shader_out(false), mode(mode), interpolation(ir_var_smooth), array_lvalue(false) { this->ir_type = ir_type_variable; @@ -922,9 +921,6 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name, const char * ir_variable::interpolation_string() const { - if (!this->shader_in && !this->shader_out) - return ""; - switch (this->interpolation) { case ir_var_smooth: return "smooth"; case ir_var_flat: return "flat"; diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 98789503e0..e61485813d 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -194,10 +194,10 @@ public: /** * Get the string value for the interpolation qualifier * - * \return - * If none of \c shader_in or \c shader_out is set, an empty string will - * be returned. Otherwise the string that would be used in a shader to - * specify \c mode will be returned. + * \return The string that would be used in a shader to specify \c + * mode will be returned. + * + * This function should only be used on a shader input or output variable. */ const char *interpolation_string() const; @@ -221,12 +221,6 @@ public: unsigned read_only:1; unsigned centroid:1; unsigned invariant:1; - /** If the variable is initialized outside of the scope of the shader */ - unsigned shader_in:1; - /** - * If the variable value is later used outside of the scope of the shader. - */ - unsigned shader_out:1; unsigned mode:3; unsigned interpolation:2; diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp index 0e202164b3..a72609601a 100644 --- a/src/glsl/ir_clone.cpp +++ b/src/glsl/ir_clone.cpp @@ -45,8 +45,6 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const var->read_only = this->read_only; var->centroid = this->centroid; var->invariant = this->invariant; - var->shader_in = this->shader_in; - var->shader_out = this->shader_out; var->interpolation = this->interpolation; var->array_lvalue = this->array_lvalue; var->location = this->location; diff --git a/src/glsl/ir_dead_code.cpp b/src/glsl/ir_dead_code.cpp index 2b971b7aaa..bf032f1dc2 100644 --- a/src/glsl/ir_dead_code.cpp +++ b/src/glsl/ir_dead_code.cpp @@ -68,7 +68,8 @@ do_dead_code(exec_list *instructions) /* Remove a single dead assignment to the variable we found. * Don't do so if it's a shader output, though. */ - if (!entry->var->shader_out) { + if (entry->var->mode != ir_var_out && + entry->var->mode != ir_var_inout) { entry->assign->remove(); progress = true; } diff --git a/src/glsl/ir_variable.cpp b/src/glsl/ir_variable.cpp index 478cefc5a6..d9a16d4287 100644 --- a/src/glsl/ir_variable.cpp +++ b/src/glsl/ir_variable.cpp @@ -43,22 +43,12 @@ add_variable(const char *name, enum ir_variable_mode mode, int slot, switch (var->mode) { case ir_var_auto: - var->read_only = true; - break; case ir_var_in: - var->shader_in = true; + case ir_var_uniform: var->read_only = true; break; case ir_var_inout: - var->shader_in = true; - var->shader_out = true; - break; case ir_var_out: - var->shader_out = true; - break; - case ir_var_uniform: - var->shader_in = true; - var->read_only = true; break; default: assert(0); diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index b2953c67d1..94db57d6a5 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -1124,7 +1124,6 @@ assign_varying_locations(struct gl_shader_program *prog, * by the following stage. */ if (var->location == -1) { - var->shader_out = false; var->mode = ir_var_auto; } } @@ -1158,7 +1157,6 @@ assign_varying_locations(struct gl_shader_program *prog, /* An 'in' variable is only really a shader input if its * value is written by the previous stage. */ - var->shader_in = false; var->mode = ir_var_auto; } } -- cgit v1.2.3 From 8048226b7b1bbe8fd89f9c32fa4fadca4b8760c4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Aug 2010 14:41:09 -0700 Subject: glsl2: Insert global declarations at the top of the instruction stream. Fixes use-before-decl in glslparsertest shaders. Fixes: CorrectFull.frag CorrectModule.frag --- src/glsl/ast_to_hir.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 292c7be621..f14341c8f7 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1951,7 +1951,14 @@ ast_declarator_list::hir(exec_list *instructions, decl->identifier); } - instructions->push_tail(var); + /* Push the variable declaration to the top. It means that all + * the variable declarations will appear in a funny + * last-to-first order, but otherwise we run into trouble if a + * function is prototyped, a global var is decled, then the + * function is defined with usage of the global var. See + * glslparsertest's CorrectModule.frag. + */ + instructions->push_head(var); instructions->append_list(&initializer_instructions); /* Add the variable to the symbol table after processing the initializer. -- cgit v1.2.3 From 202604e8160157e4e80b3458175e0170d168e557 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 11 Aug 2010 16:58:25 -0700 Subject: glsl2: Don't declare a variable called sig that shadows the other one Accidentally having a variable called 'sig' within an if-statement cause the higher scope 'sig' to always be NULL. As a result a new function signature was created for a function definition even when one already existed from a prototype declaration. Fixes piglit test case glsl-function-prototype (bugzilla #29520). --- src/glsl/ast_to_hir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index f14341c8f7..9d4448f89a 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2128,7 +2128,7 @@ ast_function::hir(exec_list *instructions, */ f = state->symbols->get_function(name); if (f != NULL) { - ir_function_signature *sig = f->exact_matching_signature(&hir_parameters); + sig = f->exact_matching_signature(&hir_parameters); if (sig != NULL) { const char *badvar = sig->qualifiers_match(&hir_parameters); if (badvar != NULL) { -- cgit v1.2.3 From 768b55a5268572ff9fd03e57e92775882eb0a821 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 13 Aug 2010 16:46:43 -0700 Subject: glsl2: Remove unnecessary use of 'struct' before type names In C++ you don't have to say 'struct' or 'class' if the declaration of the type has been seen. Some compilers will complain if you use 'struct' when 'class' should have been used and vice versa. Fixes bugzilla #29539. --- src/glsl/ast.h | 5 ++--- src/glsl/ast_to_hir.cpp | 10 +++++----- src/glsl/glsl_parser.cpp | 36 ++++++++++++++++++------------------ src/glsl/glsl_parser.h | 26 +++++++++++++------------- src/glsl/glsl_parser.ypp | 36 ++++++++++++++++++------------------ src/glsl/hir_field_selection.cpp | 2 +- 6 files changed, 57 insertions(+), 58 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast.h b/src/glsl/ast.h index 7ce879bb79..44c31b6e62 100644 --- a/src/glsl/ast.h +++ b/src/glsl/ast.h @@ -29,7 +29,6 @@ #include "list.h" #include "glsl_parser_extras.h" -struct ir_instruction; struct _mesa_glsl_parse_state; struct YYLTYPE; @@ -657,8 +656,8 @@ public: extern void _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state); -extern struct ir_rvalue * -_mesa_ast_field_selection_to_hir(const struct ast_expression *expr, +extern ir_rvalue * +_mesa_ast_field_selection_to_hir(const ast_expression *expr, exec_list *instructions, struct _mesa_glsl_parse_state *state); diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 9d4448f89a..6e5d01ee26 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -986,7 +986,7 @@ ast_expression::hir(exec_list *instructions, assert(operations[this->oper] == ir_binop_mod); - struct ir_rvalue *temp_rhs; + ir_rvalue *temp_rhs; temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); @@ -1107,7 +1107,7 @@ ast_expression::hir(exec_list *instructions, type = arithmetic_result_type(op[0], op[1], false, state, & loc); - struct ir_rvalue *temp_rhs; + ir_rvalue *temp_rhs; temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); @@ -1131,7 +1131,7 @@ ast_expression::hir(exec_list *instructions, type = arithmetic_result_type(op[0], op[1], false, state, & loc); - struct ir_rvalue *temp_rhs; + ir_rvalue *temp_rhs; temp_rhs = new(ctx) ir_expression(operations[this->oper], type, op[0], op[1]); @@ -1453,7 +1453,7 @@ ast_type_specifier::glsl_type(const char **name, static void apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, - struct ir_variable *var, + ir_variable *var, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { @@ -1620,7 +1620,7 @@ ast_declarator_list::hir(exec_list *instructions, foreach_list_typed (ast_declaration, decl, link, &this->declarations) { const struct glsl_type *var_type; - struct ir_variable *var; + ir_variable *var; /* FINISHME: Emit a warning if a variable declaration shadows a * FINISHME: declaration at a higher scope. diff --git a/src/glsl/glsl_parser.cpp b/src/glsl/glsl_parser.cpp index 8756fcb721..7df9e96d16 100644 --- a/src/glsl/glsl_parser.cpp +++ b/src/glsl/glsl_parser.cpp @@ -347,21 +347,21 @@ typedef union YYSTYPE unsigned i; } type_qualifier; - struct ast_node *node; - struct ast_type_specifier *type_specifier; - struct ast_fully_specified_type *fully_specified_type; - struct ast_function *function; - struct ast_parameter_declarator *parameter_declarator; - struct ast_function_definition *function_definition; - struct ast_compound_statement *compound_statement; - struct ast_expression *expression; - struct ast_declarator_list *declarator_list; - struct ast_struct_specifier *struct_specifier; - struct ast_declaration *declaration; + ast_node *node; + ast_type_specifier *type_specifier; + ast_fully_specified_type *fully_specified_type; + ast_function *function; + ast_parameter_declarator *parameter_declarator; + ast_function_definition *function_definition; + ast_compound_statement *compound_statement; + ast_expression *expression; + ast_declarator_list *declarator_list; + ast_struct_specifier *struct_specifier; + ast_declaration *declaration; struct { - struct ast_node *cond; - struct ast_expression *rest; + ast_node *cond; + ast_expression *rest; } for_rest_statement; @@ -4609,7 +4609,7 @@ yyreduce: /* Line 1455 of yacc.c */ #line 1193 "glsl_parser.ypp" { - (yyval.node) = (struct ast_node *) (yyvsp[(1) - (1)].declarator_list); + (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].declarator_list); (yyvsp[(1) - (1)].declarator_list)->link.self_link(); ;} break; @@ -4619,7 +4619,7 @@ yyreduce: /* Line 1455 of yacc.c */ #line 1198 "glsl_parser.ypp" { - (yyval.node) = (struct ast_node *) (yyvsp[(1) - (2)].node); + (yyval.node) = (ast_node *) (yyvsp[(1) - (2)].node); (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].declarator_list)->link); ;} break; @@ -4687,7 +4687,7 @@ yyreduce: /* Line 1455 of yacc.c */ #line 1263 "glsl_parser.ypp" - { (yyval.node) = (struct ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} + { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} break; case 234: @@ -4730,7 +4730,7 @@ yyreduce: /* Line 1455 of yacc.c */ #line 1297 "glsl_parser.ypp" - { (yyval.node) = (struct ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} + { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} break; case 242: @@ -4855,7 +4855,7 @@ yyreduce: /* Line 1455 of yacc.c */ #line 1385 "glsl_parser.ypp" { - (yyval.node) = (struct ast_node *) (yyvsp[(1) - (1)].expression); + (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].expression); ;} break; diff --git a/src/glsl/glsl_parser.h b/src/glsl/glsl_parser.h index 4124c7f1d2..48a0a5fb3a 100644 --- a/src/glsl/glsl_parser.h +++ b/src/glsl/glsl_parser.h @@ -245,21 +245,21 @@ typedef union YYSTYPE unsigned i; } type_qualifier; - struct ast_node *node; - struct ast_type_specifier *type_specifier; - struct ast_fully_specified_type *fully_specified_type; - struct ast_function *function; - struct ast_parameter_declarator *parameter_declarator; - struct ast_function_definition *function_definition; - struct ast_compound_statement *compound_statement; - struct ast_expression *expression; - struct ast_declarator_list *declarator_list; - struct ast_struct_specifier *struct_specifier; - struct ast_declaration *declaration; + ast_node *node; + ast_type_specifier *type_specifier; + ast_fully_specified_type *fully_specified_type; + ast_function *function; + ast_parameter_declarator *parameter_declarator; + ast_function_definition *function_definition; + ast_compound_statement *compound_statement; + ast_expression *expression; + ast_declarator_list *declarator_list; + ast_struct_specifier *struct_specifier; + ast_declaration *declaration; struct { - struct ast_node *cond; - struct ast_expression *rest; + ast_node *cond; + ast_expression *rest; } for_rest_statement; diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp index 1ee6da1d23..e0b1d28504 100644 --- a/src/glsl/glsl_parser.ypp +++ b/src/glsl/glsl_parser.ypp @@ -59,21 +59,21 @@ unsigned i; } type_qualifier; - struct ast_node *node; - struct ast_type_specifier *type_specifier; - struct ast_fully_specified_type *fully_specified_type; - struct ast_function *function; - struct ast_parameter_declarator *parameter_declarator; - struct ast_function_definition *function_definition; - struct ast_compound_statement *compound_statement; - struct ast_expression *expression; - struct ast_declarator_list *declarator_list; - struct ast_struct_specifier *struct_specifier; - struct ast_declaration *declaration; + ast_node *node; + ast_type_specifier *type_specifier; + ast_fully_specified_type *fully_specified_type; + ast_function *function; + ast_parameter_declarator *parameter_declarator; + ast_function_definition *function_definition; + ast_compound_statement *compound_statement; + ast_expression *expression; + ast_declarator_list *declarator_list; + ast_struct_specifier *struct_specifier; + ast_declaration *declaration; struct { - struct ast_node *cond; - struct ast_expression *rest; + ast_node *cond; + ast_expression *rest; } for_rest_statement; } @@ -1191,12 +1191,12 @@ struct_specifier: struct_declaration_list: struct_declaration { - $$ = (struct ast_node *) $1; + $$ = (ast_node *) $1; $1->link.self_link(); } | struct_declaration_list struct_declaration { - $$ = (struct ast_node *) $1; + $$ = (ast_node *) $1; $$->link.insert_before(& $2->link); } ; @@ -1260,7 +1260,7 @@ statement: ; statement_matched: - compound_statement { $$ = (struct ast_node *) $1; } + compound_statement { $$ = (ast_node *) $1; } | simple_statement ; @@ -1294,7 +1294,7 @@ compound_statement: ; statement_no_new_scope: - compound_statement_no_new_scope { $$ = (struct ast_node *) $1; } + compound_statement_no_new_scope { $$ = (ast_node *) $1; } | simple_statement ; @@ -1383,7 +1383,7 @@ selection_statement_unmatched: condition: expression { - $$ = (struct ast_node *) $1; + $$ = (ast_node *) $1; } | fully_specified_type IDENTIFIER '=' initializer { diff --git a/src/glsl/hir_field_selection.cpp b/src/glsl/hir_field_selection.cpp index 6dd910d581..23045ff182 100644 --- a/src/glsl/hir_field_selection.cpp +++ b/src/glsl/hir_field_selection.cpp @@ -28,7 +28,7 @@ #include "ast.h" #include "glsl_types.h" -struct ir_rvalue * +ir_rvalue * _mesa_ast_field_selection_to_hir(const ast_expression *expr, exec_list *instructions, struct _mesa_glsl_parse_state *state) -- cgit v1.2.3 From 665d75cc5a23f8024034d0c4176fb281f94a30e9 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 18 Aug 2010 13:54:50 -0700 Subject: glsl: Fix scoping bug in if statements. Fixes glslparsertest/glsl2/scoping-01.frag (successfully compiled but should've failed) and scoping-02.frag (assertion triggered). --- src/glsl/ast_to_hir.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 6e5d01ee26..bd1ab78d4a 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2395,11 +2395,17 @@ ast_selection_statement::hir(exec_list *instructions, ir_if *const stmt = new(ctx) ir_if(condition); - if (then_statement != NULL) + if (then_statement != NULL) { + state->symbols->push_scope(); then_statement->hir(& stmt->then_instructions, state); + state->symbols->pop_scope(); + } - if (else_statement != NULL) + if (else_statement != NULL) { + state->symbols->push_scope(); else_statement->hir(& stmt->else_instructions, state); + state->symbols->pop_scope(); + } instructions->push_tail(stmt); -- cgit v1.2.3 From 826a39cb14244820e8539a2328bb52447348f184 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 20 Aug 2010 02:04:52 -0700 Subject: ast_to_hir: Fix crash when a function shadows a variable. The code would attempt to add a new signature to the ir_function, which didn't exist. Simply bailing out/returning early seems reasonable. Fixes piglit test redeclaration-02.vert, and fixes a crash in redeclaration-03.vert (the test still fails). --- src/glsl/ast_to_hir.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index bd1ab78d4a..0d2c471f45 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2149,7 +2149,6 @@ ast_function::hir(exec_list *instructions, YYLTYPE loc = this->get_location(); _mesa_glsl_error(& loc, state, "function `%s' redefined", name); - sig = NULL; } } } else if (state->symbols->name_declared_this_scope(name)) { @@ -2159,7 +2158,7 @@ ast_function::hir(exec_list *instructions, _mesa_glsl_error(& loc, state, "function name `%s' conflicts with " "non-function", name); - sig = NULL; + return NULL; } else { f = new(ctx) ir_function(name); state->symbols->add_function(f->name, f); @@ -2207,6 +2206,8 @@ ast_function_definition::hir(exec_list *instructions, prototype->hir(instructions, state); ir_function_signature *signature = prototype->signature; + if (signature == NULL) + return NULL; assert(state->current_function == NULL); state->current_function = signature; -- cgit v1.2.3 From edd180f03216d2fcb2771aeea34e7015fb2b83c3 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 20 Aug 2010 02:14:35 -0700 Subject: ast_to_hir: Reject function names that start with "gl_". Fixes piglit test redeclaration-03.vert. --- src/glsl/ast_to_hir.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 0d2c471f45..4188348626 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2099,6 +2099,18 @@ ast_function::hir(exec_list *instructions, const char *const name = identifier; + /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, + * + * "Identifiers starting with "gl_" are reserved for use by + * OpenGL, and may not be declared in a shader as either a + * variable or a function." + */ + if (strncmp(name, "gl_", 3) == 0) { + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(&loc, state, + "identifier `%s' uses reserved `gl_' prefix", name); + } + /* Convert the list of function parameters to HIR now so that they can be * used below to compare this function's signature with previously seen * signatures for functions with the same name. -- cgit v1.2.3 From e511a35fc53fb75a2401d8a94c0c35634175c575 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sat, 21 Aug 2010 15:30:34 -0700 Subject: glsl: Handle array declarations in function parameters. The 'vec4[12] foo' style already worked, but the 'vec4 foo[12]' style did not. Also, 'vec4[] foo' was wrongly accepted. Fixes piglit test cases array-19.vert and array-21.vert. May fix fd.o bug #29684 (or at least part of it). --- src/glsl/ast_to_hir.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 4188348626..397c84e343 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2040,13 +2040,22 @@ ast_parameter_declarator::hir(exec_list *instructions, return NULL; } + /* This only handles "vec4 foo[..]". The earlier specifier->glsl_type(...) + * call already handled the "vec4[..] foo" case. + */ + if (this->is_array) { + type = process_array_type(type, this->array_size, state); + } + + if (type->array_size() == 0) { + _mesa_glsl_error(&loc, state, "arrays passed as parameters must have " + "a declared size."); + type = glsl_type::error_type; + } + is_void = false; ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_in); - /* FINISHME: Handle array declarations. Note that this requires - * FINISHME: complete handling of constant expressions. - */ - /* Apply any specified qualifiers to the parameter declaration. Note that * for function parameters the default mode is 'in'. */ -- cgit v1.2.3 From 13b3d4c23d9d088a5a2b3bd657f1f163e42e4d8b Mon Sep 17 00:00:00 2001 From: Vinson Lee Date: Sat, 21 Aug 2010 16:21:41 -0700 Subject: glsl: Silence unused variable warning. The variable is actually used but only in the body of an assert. --- src/glsl/ast_to_hir.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 397c84e343..b60bb2f0a0 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1973,6 +1973,7 @@ ast_declarator_list::hir(exec_list *instructions, const bool added_variable = state->symbols->add_variable(var->name, var); assert(added_variable); + (void) added_variable; } -- cgit v1.2.3 From a721abfbd1724e83381b46fc670bb38fbde76f69 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 23 Aug 2010 10:32:01 -0700 Subject: glsl: Trim the size of uniform arrays to the maximum element used. Fixes glsl-getactiveuniform-array-size. --- src/glsl/ast_to_hir.cpp | 5 +++++ src/glsl/linker.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index b60bb2f0a0..8e4c3299aa 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1258,6 +1258,11 @@ ast_expression::hir(exec_list *instructions, } } else if (array->type->array_size() == 0) { _mesa_glsl_error(&loc, state, "unsized array index must be constant"); + } else { + if (array->type->is_array()) { + ir_variable *v = array->whole_variable_referenced(); + v->max_array_access = array->type->array_size(); + } } if (error_emitted) diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 2dc569777e..deb30d7fec 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -809,6 +809,56 @@ struct uniform_node { unsigned slots; }; +/** + * Update the sizes of linked shader uniform arrays to the maximum + * array index used. + * + * From page 81 (page 95 of the PDF) of the OpenGL 2.1 spec: + * + * If one or more elements of an array are active, + * GetActiveUniform will return the name of the array in name, + * subject to the restrictions listed above. The type of the array + * is returned in type. The size parameter contains the highest + * array element index used, plus one. The compiler or linker + * determines the highest index used. There will be only one + * active uniform reported by the GL per uniform array. + + */ +static void +update_uniform_array_sizes(struct gl_shader_program *prog) +{ + for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) { + foreach_list(node, prog->_LinkedShaders[i]->ir) { + ir_variable *const var = ((ir_instruction *) node)->as_variable(); + + if ((var == NULL) || (var->mode != ir_var_uniform) || + !var->type->is_array()) + continue; + + unsigned int size = var->max_array_access; + for (unsigned j = 0; j < prog->_NumLinkedShaders; j++) { + foreach_list(node2, prog->_LinkedShaders[j]->ir) { + ir_variable *other_var = ((ir_instruction *) node2)->as_variable(); + if (!other_var) + continue; + + if (strcmp(var->name, other_var->name) == 0 && + other_var->max_array_access > size) { + size = other_var->max_array_access; + } + } + } + if (size + 1 != var->type->fields.array->length) { + var->type = glsl_type::get_array_instance(var->type->fields.array, + size + 1); + /* FINISHME: We should update the types of array + * dereferences of this variable now. + */ + } + } + } +} + void assign_uniform_locations(struct gl_shader_program *prog) { @@ -818,6 +868,8 @@ assign_uniform_locations(struct gl_shader_program *prog) hash_table *ht = hash_table_ctor(32, hash_table_string_hash, hash_table_string_compare); + update_uniform_array_sizes(prog); + for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) { unsigned next_position = 0; -- cgit v1.2.3 From 76e96d74f49cc262ceaf2ed6c48d2f4ed21d219f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 23 Aug 2010 13:26:52 -0700 Subject: glsl: Cleanly fail when a function has an unknown return type. Bug #29608. --- src/glsl/ast_to_hir.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 8e4c3299aa..7ac24b06fe 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2138,7 +2138,13 @@ ast_function::hir(exec_list *instructions, const glsl_type *return_type = this->return_type->specifier->glsl_type(& return_type_name, state); - assert(return_type != NULL); + if (!return_type) { + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(&loc, state, + "function `%s' has undeclared return type `%s'", + name, return_type_name); + return_type = glsl_type::error_type; + } /* From page 56 (page 62 of the PDF) of the GLSL 1.30 spec: * "No qualifier is allowed on the return type of a function." -- cgit v1.2.3 From e11757bb896e3dadc54fb3d18adf4b71e3e883b3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 23 Aug 2010 14:54:06 -0700 Subject: glsl: When unable to assign the initializer for a const variable, set it to 0. This prevents assertion failures or cascading errors after we've logged the fact that we were unable to handle the initializer. Fixes unsized-array-non-const-index-2.vert --- src/glsl/ast_to_hir.cpp | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 7ac24b06fe..57e331742e 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1827,24 +1827,32 @@ ast_declarator_list::hir(exec_list *instructions, ir_rvalue *new_rhs = validate_assignment(state, var->type, rhs); if (new_rhs != NULL) { rhs = new_rhs; + + ir_constant *constant_value = rhs->constant_expression_value(); + if (!constant_value) { + _mesa_glsl_error(& initializer_loc, state, + "initializer of %s variable `%s' must be a " + "constant expression", + (this->type->qualifier.constant) + ? "const" : "uniform", + decl->identifier); + if (var->type->is_numeric()) { + /* Reduce cascading errors. */ + var->constant_value = ir_constant::zero(ctx, var->type); + } + } else { + rhs = constant_value; + var->constant_value = constant_value; + } } else { _mesa_glsl_error(&initializer_loc, state, "initializer of type %s cannot be assigned to " "variable of type %s", rhs->type->name, var->type->name); - } - - ir_constant *constant_value = rhs->constant_expression_value(); - if (!constant_value) { - _mesa_glsl_error(& initializer_loc, state, - "initializer of %s variable `%s' must be a " - "constant expression", - (this->type->qualifier.constant) - ? "const" : "uniform", - decl->identifier); - } else { - rhs = constant_value; - var->constant_value = constant_value; + if (var->type->is_numeric()) { + /* Reduce cascading errors. */ + var->constant_value = ir_constant::zero(ctx, var->type); + } } } -- cgit v1.2.3 From bfd7c9ac228c7ed8aec04c3b3aa33f40ee00b035 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 23 Aug 2010 17:51:42 +0800 Subject: glsl: Include main/core.h. Make glsl include only main/core.h from core mesa. --- src/glsl/ast_function.cpp | 2 +- src/glsl/ast_to_hir.cpp | 3 +-- src/glsl/builtin_function.cpp | 2 +- src/glsl/builtin_variables.h | 2 +- src/glsl/builtins/tools/generate_builtins.py | 2 +- src/glsl/glcpp/glcpp-parse.c | 2 +- src/glsl/glcpp/glcpp-parse.y | 2 +- src/glsl/glsl_parser_extras.cpp | 2 +- src/glsl/glsl_types.cpp | 3 +-- src/glsl/hir_field_selection.cpp | 1 - src/glsl/ir.cpp | 3 +-- src/glsl/ir_constant_expression.cpp | 2 +- src/glsl/ir_explog_to_explog2.cpp | 2 +- src/glsl/ir_set_program_inouts.cpp | 2 +- src/glsl/ir_variable.cpp | 1 - src/glsl/link_functions.cpp | 2 +- src/glsl/linker.cpp | 5 +---- src/glsl/program.h | 8 +------- 18 files changed, 16 insertions(+), 30 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index f85b308c1b..34b0f70d41 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -25,7 +25,7 @@ #include "ast.h" #include "glsl_types.h" #include "ir.h" -#include "main/macros.h" +#include "main/core.h" /* for MIN2 */ static ir_rvalue * convert_component(ir_rvalue *src, const glsl_type *desired_type); diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 57e331742e..64b142fa35 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -49,8 +49,7 @@ * parser (and lexer) sources. */ -#include "main/imports.h" -#include "main/extensions.h" +#include "main/core.h" /* for struct gl_extensions */ #include "glsl_symbol_table.h" #include "glsl_parser_extras.h" #include "ast.h" diff --git a/src/glsl/builtin_function.cpp b/src/glsl/builtin_function.cpp index 5471ba6020..a277ed6e8d 100644 --- a/src/glsl/builtin_function.cpp +++ b/src/glsl/builtin_function.cpp @@ -23,7 +23,7 @@ */ #include -#include "main/compiler.h" +#include "main/core.h" /* for struct gl_shader */ #include "glsl_parser_extras.h" #include "ir_reader.h" #include "program.h" diff --git a/src/glsl/builtin_variables.h b/src/glsl/builtin_variables.h index 2ec7d621bb..a7dbe480e9 100644 --- a/src/glsl/builtin_variables.h +++ b/src/glsl/builtin_variables.h @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include "main/mtypes.h" +#include "main/core.h" /* for slot numbers */ struct builtin_variable { enum ir_variable_mode mode; diff --git a/src/glsl/builtins/tools/generate_builtins.py b/src/glsl/builtins/tools/generate_builtins.py index 2a763d784b..c72b5b3bc1 100755 --- a/src/glsl/builtins/tools/generate_builtins.py +++ b/src/glsl/builtins/tools/generate_builtins.py @@ -116,7 +116,7 @@ if __name__ == "__main__": */ #include -#include "main/compiler.h" +#include "main/core.h" /* for struct gl_shader */ #include "glsl_parser_extras.h" #include "ir_reader.h" #include "program.h" diff --git a/src/glsl/glcpp/glcpp-parse.c b/src/glsl/glcpp/glcpp-parse.c index 2c04d7d71b..91eb0bf972 100644 --- a/src/glsl/glcpp/glcpp-parse.c +++ b/src/glsl/glcpp/glcpp-parse.c @@ -100,7 +100,7 @@ #include #include "glcpp.h" -#include "main/mtypes.h" +#include "main/core.h" /* for struct gl_extensions */ #define glcpp_print(stream, str) stream = talloc_strdup_append(stream, str) #define glcpp_printf(stream, fmt, args, ...) \ diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y index 3275496d99..3c28edf688 100644 --- a/src/glsl/glcpp/glcpp-parse.y +++ b/src/glsl/glcpp/glcpp-parse.y @@ -29,7 +29,7 @@ #include #include "glcpp.h" -#include "main/mtypes.h" +#include "main/core.h" /* for struct gl_extensions */ #define glcpp_print(stream, str) stream = talloc_strdup_append(stream, str) #define glcpp_printf(stream, fmt, args, ...) \ diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index b864218d50..bc56e4fcaf 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -27,7 +27,7 @@ extern "C" { #include -#include "main/mtypes.h" +#include "main/core.h" /* for struct __GLcontextRec */ } #include "ast.h" diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index c488f5c271..1da2fd76de 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -23,13 +23,12 @@ #include #include -#include "main/compiler.h" +#include "main/core.h" /* for Elements */ #include "glsl_symbol_table.h" #include "glsl_parser_extras.h" #include "glsl_types.h" #include "builtin_types.h" extern "C" { -#include "main/imports.h" #include "program/hash_table.h" } diff --git a/src/glsl/hir_field_selection.cpp b/src/glsl/hir_field_selection.cpp index 23045ff182..3c33127b5f 100644 --- a/src/glsl/hir_field_selection.cpp +++ b/src/glsl/hir_field_selection.cpp @@ -22,7 +22,6 @@ */ #include "ir.h" -#include "main/imports.h" #include "program/symbol_table.h" #include "glsl_parser_extras.h" #include "ast.h" diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index 4622a1f939..e5ed10d3e4 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -21,8 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ #include -#include "main/imports.h" -#include "main/macros.h" +#include "main/core.h" /* for MAX2 */ #include "ir.h" #include "ir_visitor.h" #include "glsl_types.h" diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index 942f198360..f1c175c97a 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -34,7 +34,7 @@ */ #include -#include "main/macros.h" +#include "main/core.h" /* for MAX2, MIN2, CLAMP */ #include "ir.h" #include "ir_visitor.h" #include "glsl_types.h" diff --git a/src/glsl/ir_explog_to_explog2.cpp b/src/glsl/ir_explog_to_explog2.cpp index 9bf8271081..78694a2029 100644 --- a/src/glsl/ir_explog_to_explog2.cpp +++ b/src/glsl/ir_explog_to_explog2.cpp @@ -29,7 +29,7 @@ * and log2 operations. */ -#include "main/imports.h" +#include "main/core.h" /* for log2f on MSVC */ #include "ir.h" #include "glsl_types.h" diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp index 534f602128..b3f1cc0d8b 100644 --- a/src/glsl/ir_set_program_inouts.cpp +++ b/src/glsl/ir_set_program_inouts.cpp @@ -35,7 +35,7 @@ */ extern "C" { -#include "main/mtypes.h" +#include "main/core.h" /* for struct gl_program */ #include "program/hash_table.h" } #include "ir.h" diff --git a/src/glsl/ir_variable.cpp b/src/glsl/ir_variable.cpp index 917c06743b..e638c9602f 100644 --- a/src/glsl/ir_variable.cpp +++ b/src/glsl/ir_variable.cpp @@ -21,7 +21,6 @@ * DEALINGS IN THE SOFTWARE. */ -#include "main/compiler.h" #include "ir.h" #include "glsl_parser_extras.h" #include "glsl_symbol_table.h" diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp index dfda05fcbe..6374573e61 100644 --- a/src/glsl/link_functions.cpp +++ b/src/glsl/link_functions.cpp @@ -29,7 +29,7 @@ extern "C" { #include } -#include "main/mtypes.h" +#include "main/core.h" #include "glsl_symbol_table.h" #include "glsl_parser_extras.h" #include "ir.h" diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 38d19c4c71..c5c8c9cdd6 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -72,10 +72,7 @@ extern "C" { #include } -#include "main/compiler.h" -#include "main/mtypes.h" -#include "main/macros.h" -#include "main/shaderobj.h" +#include "main/core.h" #include "glsl_symbol_table.h" #include "ir.h" #include "program.h" diff --git a/src/glsl/program.h b/src/glsl/program.h index ea2c4ab0dd..893169b6cc 100644 --- a/src/glsl/program.h +++ b/src/glsl/program.h @@ -21,13 +21,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include -#include "main/mtypes.h" - -extern "C" { -#include "program/prog_parameter.h" -#include "program/prog_uniform.h" -} +#include "main/core.h" extern void link_shaders(GLcontext *ctx, struct gl_shader_program *prog); -- cgit v1.2.3 From 5226f8c7b0025031e8540adc93ecfe0b36b8f90f Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Wed, 25 Aug 2010 22:42:13 +0300 Subject: glsl: fix crash with variable indexing into array in a struct Signed-off-by: Ian Romanick --- src/glsl/ast_to_hir.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 64b142fa35..2fec02668d 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1259,8 +1259,14 @@ ast_expression::hir(exec_list *instructions, _mesa_glsl_error(&loc, state, "unsized array index must be constant"); } else { if (array->type->is_array()) { + /* whole_variable_referenced can return NULL if the array is a + * member of a structure. In this case it is safe to not update + * the max_array_access field because it is never used for fields + * of structures. + */ ir_variable *v = array->whole_variable_referenced(); - v->max_array_access = array->type->array_size(); + if (v != NULL) + v->max_array_access = array->type->array_size(); } } -- cgit v1.2.3 From e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sat, 21 Aug 2010 20:23:18 -0700 Subject: glsl: Use a single shared namespace in the symbol table. As of 1.20, variable names, function names, and structure type names all share a single namespace, and should conflict with one another in the same scope, or hide each other in nested scopes. However, in 1.10, variables and functions can share the same name in the same scope. Structure types, however, conflict with/hide both. Fixes piglit tests redeclaration-06.vert, redeclaration-11.vert, redeclaration-19.vert, and struct-05.vert. --- src/glsl/Makefile | 1 + src/glsl/ast_to_hir.cpp | 12 +- src/glsl/builtin_function.cpp | 1 + src/glsl/builtins/tools/generate_builtins.py | 1 + src/glsl/glsl_parser.cpp | 972 ++++++++++++++------------- src/glsl/glsl_parser.h | 13 +- src/glsl/glsl_parser.ypp | 2 + src/glsl/glsl_symbol_table.cpp | 160 +++++ src/glsl/glsl_symbol_table.h | 85 +-- src/glsl/glsl_types.cpp | 11 +- src/glsl/glsl_types.h | 4 +- 11 files changed, 686 insertions(+), 576 deletions(-) create mode 100644 src/glsl/glsl_symbol_table.cpp (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/Makefile b/src/glsl/Makefile index 3fd06bc9cb..aedca0f0d1 100644 --- a/src/glsl/Makefile +++ b/src/glsl/Makefile @@ -28,6 +28,7 @@ CXX_SOURCES = \ glsl_parser.cpp \ glsl_parser_extras.cpp \ glsl_types.cpp \ + glsl_symbol_table.cpp \ hir_field_selection.cpp \ ir_algebraic.cpp \ ir_basic_block.cpp \ diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 2fec02668d..8c105e79f7 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2630,18 +2630,10 @@ ast_struct_specifier::hir(exec_list *instructions, glsl_type::get_record_instance(fields, decl_count, name); YYLTYPE loc = this->get_location(); - if (!state->symbols->add_type(name, t)) { + ir_function *ctor = t->generate_constructor(); + if (!state->symbols->add_type(name, t, ctor)) { _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name); } else { - /* This logic is a bit tricky. It is an error to declare a structure at - * global scope if there is also a function with the same name. - */ - if ((state->current_function == NULL) - && (state->symbols->get_function(name) != NULL)) { - _mesa_glsl_error(& loc, state, "name `%s' previously defined", name); - } else { - t->generate_constructor(state->symbols); - } const glsl_type **s = (const glsl_type **) realloc(state->user_structures, diff --git a/src/glsl/builtin_function.cpp b/src/glsl/builtin_function.cpp index a277ed6e8d..292ac428ba 100644 --- a/src/glsl/builtin_function.cpp +++ b/src/glsl/builtin_function.cpp @@ -40,6 +40,7 @@ read_builtins(GLenum target, const char *protos, const char **functions, unsigne new(sh) _mesa_glsl_parse_state(NULL, target, sh); st->language_version = 130; + st->symbols->language_version = 130; st->ARB_texture_rectangle_enable = true; st->EXT_texture_array_enable = true; _mesa_glsl_initialize_types(st); diff --git a/src/glsl/builtins/tools/generate_builtins.py b/src/glsl/builtins/tools/generate_builtins.py index c72b5b3bc1..b9f0ba1ad2 100755 --- a/src/glsl/builtins/tools/generate_builtins.py +++ b/src/glsl/builtins/tools/generate_builtins.py @@ -133,6 +133,7 @@ read_builtins(GLenum target, const char *protos, const char **functions, unsigne new(sh) _mesa_glsl_parse_state(NULL, target, sh); st->language_version = 130; + st->symbols->language_version = 130; st->ARB_texture_rectangle_enable = true; st->EXT_texture_array_enable = true; _mesa_glsl_initialize_types(st); diff --git a/src/glsl/glsl_parser.cpp b/src/glsl/glsl_parser.cpp index 7df9e96d16..188d128526 100644 --- a/src/glsl/glsl_parser.cpp +++ b/src/glsl/glsl_parser.cpp @@ -1,10 +1,9 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ +/* A Bison parser, made by GNU Bison 2.4.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -46,7 +45,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.4.1" +#define YYBISON_VERSION "2.4.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -114,7 +113,7 @@ /* Line 189 of yacc.c */ -#line 118 "glsl_parser.cpp" +#line 117 "glsl_parser.cpp" /* Enabling traces. */ #ifndef YYDEBUG @@ -367,7 +366,7 @@ typedef union YYSTYPE /* Line 214 of yacc.c */ -#line 371 "glsl_parser.cpp" +#line 370 "glsl_parser.cpp" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -392,7 +391,7 @@ typedef struct YYLTYPE /* Line 264 of yacc.c */ -#line 396 "glsl_parser.cpp" +#line 395 "glsl_parser.cpp" #ifdef short # undef short @@ -442,7 +441,7 @@ typedef short int yytype_int16; #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ -# if YYENABLE_NLS +# if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) @@ -799,34 +798,34 @@ static const yytype_int16 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 209, 209, 208, 217, 220, 237, 239, 243, 252, - 260, 271, 275, 282, 289, 296, 303, 310, 317, 318, - 324, 328, 335, 341, 350, 354, 358, 359, 368, 369, - 373, 374, 378, 384, 396, 400, 406, 413, 424, 425, - 431, 437, 447, 448, 449, 450, 454, 455, 461, 467, - 476, 477, 483, 492, 493, 499, 508, 509, 515, 521, - 527, 536, 537, 543, 552, 553, 562, 563, 572, 573, - 582, 583, 592, 593, 602, 603, 612, 613, 622, 623, - 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, - 642, 646, 650, 666, 670, 674, 678, 692, 696, 697, - 701, 706, 714, 725, 735, 750, 757, 762, 773, 785, - 786, 787, 788, 792, 796, 797, 806, 815, 824, 833, - 842, 855, 866, 875, 884, 893, 902, 911, 920, 934, - 941, 952, 953, 957, 964, 965, 972, 1006, 1007, 1008, - 1012, 1016, 1017, 1021, 1029, 1030, 1031, 1032, 1033, 1034, - 1035, 1036, 1037, 1041, 1042, 1050, 1051, 1057, 1066, 1072, - 1078, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, - 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, - 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, - 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, - 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, - 1136, 1137, 1141, 1152, 1163, 1177, 1183, 1192, 1197, 1205, - 1220, 1225, 1233, 1239, 1248, 1252, 1258, 1259, 1263, 1264, - 1268, 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1282, 1288, - 1297, 1298, 1302, 1308, 1317, 1327, 1339, 1345, 1354, 1363, - 1369, 1375, 1384, 1388, 1402, 1406, 1407, 1411, 1418, 1425, - 1435, 1436, 1440, 1442, 1448, 1453, 1462, 1468, 1474, 1480, - 1486, 1495, 1496, 1500 + 0, 209, 209, 208, 217, 221, 239, 241, 245, 254, + 262, 273, 277, 284, 291, 298, 305, 312, 319, 320, + 326, 330, 337, 343, 352, 356, 360, 361, 370, 371, + 375, 376, 380, 386, 398, 402, 408, 415, 426, 427, + 433, 439, 449, 450, 451, 452, 456, 457, 463, 469, + 478, 479, 485, 494, 495, 501, 510, 511, 517, 523, + 529, 538, 539, 545, 554, 555, 564, 565, 574, 575, + 584, 585, 594, 595, 604, 605, 614, 615, 624, 625, + 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, + 644, 648, 652, 668, 672, 676, 680, 694, 698, 699, + 703, 708, 716, 727, 737, 752, 759, 764, 775, 787, + 788, 789, 790, 794, 798, 799, 808, 817, 826, 835, + 844, 857, 868, 877, 886, 895, 904, 913, 922, 936, + 943, 954, 955, 959, 966, 967, 974, 1008, 1009, 1010, + 1014, 1018, 1019, 1023, 1031, 1032, 1033, 1034, 1035, 1036, + 1037, 1038, 1039, 1043, 1044, 1052, 1053, 1059, 1068, 1074, + 1080, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, + 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, + 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, + 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, + 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, + 1138, 1139, 1143, 1154, 1165, 1179, 1185, 1194, 1199, 1207, + 1222, 1227, 1235, 1241, 1250, 1254, 1260, 1261, 1265, 1266, + 1270, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1284, 1290, + 1299, 1300, 1304, 1310, 1319, 1329, 1341, 1347, 1356, 1365, + 1371, 1377, 1386, 1390, 1404, 1408, 1409, 1413, 1420, 1427, + 1437, 1438, 1442, 1444, 1450, 1455, 1464, 1470, 1476, 1482, + 1488, 1497, 1498, 1502 }; #endif @@ -2020,9 +2019,18 @@ static const yytype_uint16 yystos[] = /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ #define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif #define YYRECOVERING() (!!yyerrstatus) @@ -2079,7 +2087,7 @@ while (YYID (0)) we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ @@ -2621,7 +2629,7 @@ YYLTYPE yylloc; YYLTYPE *yylsp; /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; + YYLTYPE yyerror_range[3]; YYSIZE_T yystacksize; @@ -2668,7 +2676,7 @@ YYLTYPE yylloc; yyvsp = yyvs; yylsp = yyls; -#if YYLTYPE_IS_TRIVIAL +#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL /* Initialize the default location before parsing starts. */ yylloc.first_line = yylloc.last_line = 1; yylloc.first_column = yylloc.last_column = 1; @@ -2676,7 +2684,7 @@ YYLTYPE yylloc; /* User initialization code. */ -/* Line 1242 of yacc.c */ +/* Line 1251 of yacc.c */ #line 41 "glsl_parser.ypp" { yylloc.first_line = 1; @@ -2686,8 +2694,8 @@ YYLTYPE yylloc; yylloc.source = 0; } -/* Line 1242 of yacc.c */ -#line 2691 "glsl_parser.cpp" +/* Line 1251 of yacc.c */ +#line 2699 "glsl_parser.cpp" yylsp[0] = yylloc; goto yysetstate; @@ -2874,7 +2882,7 @@ yyreduce: { case 2: -/* Line 1455 of yacc.c */ +/* Line 1464 of yacc.c */ #line 209 "glsl_parser.ypp" { _mesa_glsl_initialize_types(state); @@ -2883,17 +2891,18 @@ yyreduce: case 4: -/* Line 1455 of yacc.c */ +/* Line 1464 of yacc.c */ #line 217 "glsl_parser.ypp" { state->language_version = 110; + state->symbols->language_version = 110; ;} break; case 5: -/* Line 1455 of yacc.c */ -#line 221 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 222 "glsl_parser.ypp" { switch ((yyvsp[(2) - (3)].n)) { case 110: @@ -2901,6 +2910,7 @@ yyreduce: case 130: /* FINISHME: Check against implementation support versions. */ state->language_version = (yyvsp[(2) - (3)].n); + state->symbols->language_version = (yyvsp[(2) - (3)].n); break; default: _mesa_glsl_error(& (yylsp[(2) - (3)]), state, "Shading language version" @@ -2912,8 +2922,8 @@ yyreduce: case 8: -/* Line 1455 of yacc.c */ -#line 244 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 246 "glsl_parser.ypp" { if (!_mesa_glsl_process_extension((yyvsp[(2) - (5)].identifier), & (yylsp[(2) - (5)]), (yyvsp[(4) - (5)].identifier), & (yylsp[(4) - (5)]), state)) { YYERROR; @@ -2923,8 +2933,8 @@ yyreduce: case 9: -/* Line 1455 of yacc.c */ -#line 253 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 255 "glsl_parser.ypp" { /* FINISHME: The NULL test is only required because 'precision' * FINISHME: statements are not yet supported. @@ -2936,8 +2946,8 @@ yyreduce: case 10: -/* Line 1455 of yacc.c */ -#line 261 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 263 "glsl_parser.ypp" { /* FINISHME: The NULL test is only required because 'precision' * FINISHME: statements are not yet supported. @@ -2949,8 +2959,8 @@ yyreduce: case 12: -/* Line 1455 of yacc.c */ -#line 276 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 278 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); @@ -2961,8 +2971,8 @@ yyreduce: case 13: -/* Line 1455 of yacc.c */ -#line 283 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 285 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); @@ -2973,8 +2983,8 @@ yyreduce: case 14: -/* Line 1455 of yacc.c */ -#line 290 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 292 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); @@ -2985,8 +2995,8 @@ yyreduce: case 15: -/* Line 1455 of yacc.c */ -#line 297 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 299 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); @@ -2997,8 +3007,8 @@ yyreduce: case 16: -/* Line 1455 of yacc.c */ -#line 304 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 306 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); @@ -3009,8 +3019,8 @@ yyreduce: case 17: -/* Line 1455 of yacc.c */ -#line 311 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 313 "glsl_parser.ypp" { (yyval.expression) = (yyvsp[(2) - (3)].expression); ;} @@ -3018,8 +3028,8 @@ yyreduce: case 19: -/* Line 1455 of yacc.c */ -#line 319 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 321 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_array_index, (yyvsp[(1) - (4)].expression), (yyvsp[(3) - (4)].expression), NULL); @@ -3029,8 +3039,8 @@ yyreduce: case 20: -/* Line 1455 of yacc.c */ -#line 325 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 327 "glsl_parser.ypp" { (yyval.expression) = (yyvsp[(1) - (1)].expression); ;} @@ -3038,8 +3048,8 @@ yyreduce: case 21: -/* Line 1455 of yacc.c */ -#line 329 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 331 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), NULL, NULL); @@ -3050,8 +3060,8 @@ yyreduce: case 22: -/* Line 1455 of yacc.c */ -#line 336 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 338 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_post_inc, (yyvsp[(1) - (2)].expression), NULL, NULL); @@ -3061,8 +3071,8 @@ yyreduce: case 23: -/* Line 1455 of yacc.c */ -#line 342 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 344 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_post_dec, (yyvsp[(1) - (2)].expression), NULL, NULL); @@ -3072,8 +3082,8 @@ yyreduce: case 27: -/* Line 1455 of yacc.c */ -#line 360 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 362 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_field_selection, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL); @@ -3083,8 +3093,8 @@ yyreduce: case 32: -/* Line 1455 of yacc.c */ -#line 379 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 381 "glsl_parser.ypp" { (yyval.expression) = (yyvsp[(1) - (2)].expression); (yyval.expression)->set_location(yylloc); @@ -3094,8 +3104,8 @@ yyreduce: case 33: -/* Line 1455 of yacc.c */ -#line 385 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 387 "glsl_parser.ypp" { (yyval.expression) = (yyvsp[(1) - (3)].expression); (yyval.expression)->set_location(yylloc); @@ -3105,8 +3115,8 @@ yyreduce: case 35: -/* Line 1455 of yacc.c */ -#line 401 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 403 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_function_expression((yyvsp[(1) - (1)].type_specifier)); @@ -3116,8 +3126,8 @@ yyreduce: case 36: -/* Line 1455 of yacc.c */ -#line 407 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 409 "glsl_parser.ypp" { void *ctx = state; ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier)); @@ -3128,8 +3138,8 @@ yyreduce: case 37: -/* Line 1455 of yacc.c */ -#line 414 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 416 "glsl_parser.ypp" { void *ctx = state; ast_expression *callee = new(ctx) ast_expression((yyvsp[(1) - (1)].identifier)); @@ -3140,8 +3150,8 @@ yyreduce: case 39: -/* Line 1455 of yacc.c */ -#line 426 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 428 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_pre_inc, (yyvsp[(2) - (2)].expression), NULL, NULL); @@ -3151,8 +3161,8 @@ yyreduce: case 40: -/* Line 1455 of yacc.c */ -#line 432 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 434 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_pre_dec, (yyvsp[(2) - (2)].expression), NULL, NULL); @@ -3162,8 +3172,8 @@ yyreduce: case 41: -/* Line 1455 of yacc.c */ -#line 438 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 440 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression((yyvsp[(1) - (2)].n), (yyvsp[(2) - (2)].expression), NULL, NULL); @@ -3173,36 +3183,36 @@ yyreduce: case 42: -/* Line 1455 of yacc.c */ -#line 447 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 449 "glsl_parser.ypp" { (yyval.n) = ast_plus; ;} break; case 43: -/* Line 1455 of yacc.c */ -#line 448 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 450 "glsl_parser.ypp" { (yyval.n) = ast_neg; ;} break; case 44: -/* Line 1455 of yacc.c */ -#line 449 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 451 "glsl_parser.ypp" { (yyval.n) = ast_logic_not; ;} break; case 45: -/* Line 1455 of yacc.c */ -#line 450 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 452 "glsl_parser.ypp" { (yyval.n) = ast_bit_not; ;} break; case 47: -/* Line 1455 of yacc.c */ -#line 456 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 458 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_mul, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3212,8 +3222,8 @@ yyreduce: case 48: -/* Line 1455 of yacc.c */ -#line 462 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 464 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_div, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3223,8 +3233,8 @@ yyreduce: case 49: -/* Line 1455 of yacc.c */ -#line 468 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 470 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_mod, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3234,8 +3244,8 @@ yyreduce: case 51: -/* Line 1455 of yacc.c */ -#line 478 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 480 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_add, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3245,8 +3255,8 @@ yyreduce: case 52: -/* Line 1455 of yacc.c */ -#line 484 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 486 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_sub, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3256,8 +3266,8 @@ yyreduce: case 54: -/* Line 1455 of yacc.c */ -#line 494 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 496 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_lshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3267,8 +3277,8 @@ yyreduce: case 55: -/* Line 1455 of yacc.c */ -#line 500 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 502 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_rshift, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3278,8 +3288,8 @@ yyreduce: case 57: -/* Line 1455 of yacc.c */ -#line 510 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 512 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_less, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3289,8 +3299,8 @@ yyreduce: case 58: -/* Line 1455 of yacc.c */ -#line 516 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 518 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_greater, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3300,8 +3310,8 @@ yyreduce: case 59: -/* Line 1455 of yacc.c */ -#line 522 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 524 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_lequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3311,8 +3321,8 @@ yyreduce: case 60: -/* Line 1455 of yacc.c */ -#line 528 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 530 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_gequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3322,8 +3332,8 @@ yyreduce: case 62: -/* Line 1455 of yacc.c */ -#line 538 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 540 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_equal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3333,8 +3343,8 @@ yyreduce: case 63: -/* Line 1455 of yacc.c */ -#line 544 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 546 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_nequal, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3344,8 +3354,8 @@ yyreduce: case 65: -/* Line 1455 of yacc.c */ -#line 554 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 556 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3355,8 +3365,8 @@ yyreduce: case 67: -/* Line 1455 of yacc.c */ -#line 564 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 566 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3366,8 +3376,8 @@ yyreduce: case 69: -/* Line 1455 of yacc.c */ -#line 574 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 576 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_bit_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3377,8 +3387,8 @@ yyreduce: case 71: -/* Line 1455 of yacc.c */ -#line 584 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 586 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_and, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3388,8 +3398,8 @@ yyreduce: case 73: -/* Line 1455 of yacc.c */ -#line 594 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 596 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_xor, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3399,8 +3409,8 @@ yyreduce: case 75: -/* Line 1455 of yacc.c */ -#line 604 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 606 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression_bin(ast_logic_or, (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression)); @@ -3410,8 +3420,8 @@ yyreduce: case 77: -/* Line 1455 of yacc.c */ -#line 614 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 616 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression(ast_conditional, (yyvsp[(1) - (5)].expression), (yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].expression)); @@ -3421,8 +3431,8 @@ yyreduce: case 79: -/* Line 1455 of yacc.c */ -#line 624 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 626 "glsl_parser.ypp" { void *ctx = state; (yyval.expression) = new(ctx) ast_expression((yyvsp[(2) - (3)].n), (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression), NULL); @@ -3432,85 +3442,85 @@ yyreduce: case 80: -/* Line 1455 of yacc.c */ -#line 632 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 634 "glsl_parser.ypp" { (yyval.n) = ast_assign; ;} break; case 81: -/* Line 1455 of yacc.c */ -#line 633 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 635 "glsl_parser.ypp" { (yyval.n) = ast_mul_assign; ;} break; case 82: -/* Line 1455 of yacc.c */ -#line 634 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 636 "glsl_parser.ypp" { (yyval.n) = ast_div_assign; ;} break; case 83: -/* Line 1455 of yacc.c */ -#line 635 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 637 "glsl_parser.ypp" { (yyval.n) = ast_mod_assign; ;} break; case 84: -/* Line 1455 of yacc.c */ -#line 636 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 638 "glsl_parser.ypp" { (yyval.n) = ast_add_assign; ;} break; case 85: -/* Line 1455 of yacc.c */ -#line 637 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 639 "glsl_parser.ypp" { (yyval.n) = ast_sub_assign; ;} break; case 86: -/* Line 1455 of yacc.c */ -#line 638 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 640 "glsl_parser.ypp" { (yyval.n) = ast_ls_assign; ;} break; case 87: -/* Line 1455 of yacc.c */ -#line 639 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 641 "glsl_parser.ypp" { (yyval.n) = ast_rs_assign; ;} break; case 88: -/* Line 1455 of yacc.c */ -#line 640 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 642 "glsl_parser.ypp" { (yyval.n) = ast_and_assign; ;} break; case 89: -/* Line 1455 of yacc.c */ -#line 641 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 643 "glsl_parser.ypp" { (yyval.n) = ast_xor_assign; ;} break; case 90: -/* Line 1455 of yacc.c */ -#line 642 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 644 "glsl_parser.ypp" { (yyval.n) = ast_or_assign; ;} break; case 91: -/* Line 1455 of yacc.c */ -#line 647 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 649 "glsl_parser.ypp" { (yyval.expression) = (yyvsp[(1) - (1)].expression); ;} @@ -3518,8 +3528,8 @@ yyreduce: case 92: -/* Line 1455 of yacc.c */ -#line 651 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 653 "glsl_parser.ypp" { void *ctx = state; if ((yyvsp[(1) - (3)].expression)->oper != ast_sequence) { @@ -3536,8 +3546,8 @@ yyreduce: case 94: -/* Line 1455 of yacc.c */ -#line 671 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 673 "glsl_parser.ypp" { (yyval.node) = (yyvsp[(1) - (2)].function); ;} @@ -3545,8 +3555,8 @@ yyreduce: case 95: -/* Line 1455 of yacc.c */ -#line 675 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 677 "glsl_parser.ypp" { (yyval.node) = (yyvsp[(1) - (2)].declarator_list); ;} @@ -3554,8 +3564,8 @@ yyreduce: case 96: -/* Line 1455 of yacc.c */ -#line 679 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 681 "glsl_parser.ypp" { if (((yyvsp[(3) - (4)].type_specifier)->type_specifier != ast_float) && ((yyvsp[(3) - (4)].type_specifier)->type_specifier != ast_int)) { @@ -3570,8 +3580,8 @@ yyreduce: case 100: -/* Line 1455 of yacc.c */ -#line 702 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 704 "glsl_parser.ypp" { (yyval.function) = (yyvsp[(1) - (2)].function); (yyval.function)->parameters.push_tail(& (yyvsp[(2) - (2)].parameter_declarator)->link); @@ -3580,8 +3590,8 @@ yyreduce: case 101: -/* Line 1455 of yacc.c */ -#line 707 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 709 "glsl_parser.ypp" { (yyval.function) = (yyvsp[(1) - (3)].function); (yyval.function)->parameters.push_tail(& (yyvsp[(3) - (3)].parameter_declarator)->link); @@ -3590,8 +3600,8 @@ yyreduce: case 102: -/* Line 1455 of yacc.c */ -#line 715 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 717 "glsl_parser.ypp" { void *ctx = state; (yyval.function) = new(ctx) ast_function(); @@ -3603,8 +3613,8 @@ yyreduce: case 103: -/* Line 1455 of yacc.c */ -#line 726 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 728 "glsl_parser.ypp" { void *ctx = state; (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); @@ -3618,8 +3628,8 @@ yyreduce: case 104: -/* Line 1455 of yacc.c */ -#line 736 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 738 "glsl_parser.ypp" { void *ctx = state; (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); @@ -3635,8 +3645,8 @@ yyreduce: case 105: -/* Line 1455 of yacc.c */ -#line 751 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 753 "glsl_parser.ypp" { (yyvsp[(1) - (3)].type_qualifier).i |= (yyvsp[(2) - (3)].type_qualifier).i; @@ -3647,8 +3657,8 @@ yyreduce: case 106: -/* Line 1455 of yacc.c */ -#line 758 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 760 "glsl_parser.ypp" { (yyval.parameter_declarator) = (yyvsp[(2) - (2)].parameter_declarator); (yyval.parameter_declarator)->type->qualifier = (yyvsp[(1) - (2)].type_qualifier).q; @@ -3657,8 +3667,8 @@ yyreduce: case 107: -/* Line 1455 of yacc.c */ -#line 763 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 765 "glsl_parser.ypp" { void *ctx = state; (yyvsp[(1) - (3)].type_qualifier).i |= (yyvsp[(2) - (3)].type_qualifier).i; @@ -3673,8 +3683,8 @@ yyreduce: case 108: -/* Line 1455 of yacc.c */ -#line 774 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 776 "glsl_parser.ypp" { void *ctx = state; (yyval.parameter_declarator) = new(ctx) ast_parameter_declarator(); @@ -3687,36 +3697,36 @@ yyreduce: case 109: -/* Line 1455 of yacc.c */ -#line 785 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 787 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; ;} break; case 110: -/* Line 1455 of yacc.c */ -#line 786 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 788 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.in = 1; ;} break; case 111: -/* Line 1455 of yacc.c */ -#line 787 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 789 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.out = 1; ;} break; case 112: -/* Line 1455 of yacc.c */ -#line 788 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 790 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.in = 1; (yyval.type_qualifier).q.out = 1; ;} break; case 115: -/* Line 1455 of yacc.c */ -#line 798 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 800 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (3)].identifier), false, NULL, NULL); @@ -3729,8 +3739,8 @@ yyreduce: case 116: -/* Line 1455 of yacc.c */ -#line 807 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 809 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), true, NULL, NULL); @@ -3743,8 +3753,8 @@ yyreduce: case 117: -/* Line 1455 of yacc.c */ -#line 816 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 818 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (6)].identifier), true, (yyvsp[(5) - (6)].expression), NULL); @@ -3757,8 +3767,8 @@ yyreduce: case 118: -/* Line 1455 of yacc.c */ -#line 825 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 827 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (7)].identifier), true, NULL, (yyvsp[(7) - (7)].expression)); @@ -3771,8 +3781,8 @@ yyreduce: case 119: -/* Line 1455 of yacc.c */ -#line 834 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 836 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (8)].identifier), true, (yyvsp[(5) - (8)].expression), (yyvsp[(8) - (8)].expression)); @@ -3785,8 +3795,8 @@ yyreduce: case 120: -/* Line 1455 of yacc.c */ -#line 843 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 845 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(3) - (5)].identifier), false, NULL, (yyvsp[(5) - (5)].expression)); @@ -3799,8 +3809,8 @@ yyreduce: case 121: -/* Line 1455 of yacc.c */ -#line 856 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 858 "glsl_parser.ypp" { void *ctx = state; if ((yyvsp[(1) - (1)].fully_specified_type)->specifier->type_specifier != ast_struct) { @@ -3815,8 +3825,8 @@ yyreduce: case 122: -/* Line 1455 of yacc.c */ -#line 867 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 869 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL); @@ -3829,8 +3839,8 @@ yyreduce: case 123: -/* Line 1455 of yacc.c */ -#line 876 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 878 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), true, NULL, NULL); @@ -3843,8 +3853,8 @@ yyreduce: case 124: -/* Line 1455 of yacc.c */ -#line 885 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 887 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (5)].identifier), true, (yyvsp[(4) - (5)].expression), NULL); @@ -3857,8 +3867,8 @@ yyreduce: case 125: -/* Line 1455 of yacc.c */ -#line 894 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 896 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (6)].identifier), true, NULL, (yyvsp[(6) - (6)].expression)); @@ -3871,8 +3881,8 @@ yyreduce: case 126: -/* Line 1455 of yacc.c */ -#line 903 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 905 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (7)].identifier), true, (yyvsp[(4) - (7)].expression), (yyvsp[(7) - (7)].expression)); @@ -3885,8 +3895,8 @@ yyreduce: case 127: -/* Line 1455 of yacc.c */ -#line 912 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 914 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression)); @@ -3899,8 +3909,8 @@ yyreduce: case 128: -/* Line 1455 of yacc.c */ -#line 921 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 923 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (2)].identifier), false, NULL, NULL); @@ -3915,8 +3925,8 @@ yyreduce: case 129: -/* Line 1455 of yacc.c */ -#line 935 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 937 "glsl_parser.ypp" { void *ctx = state; (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type(); @@ -3927,8 +3937,8 @@ yyreduce: case 130: -/* Line 1455 of yacc.c */ -#line 942 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 944 "glsl_parser.ypp" { void *ctx = state; (yyval.fully_specified_type) = new(ctx) ast_fully_specified_type(); @@ -3940,15 +3950,15 @@ yyreduce: case 131: -/* Line 1455 of yacc.c */ -#line 952 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 954 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; ;} break; case 133: -/* Line 1455 of yacc.c */ -#line 958 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 960 "glsl_parser.ypp" { (yyval.type_qualifier) = (yyvsp[(3) - (4)].type_qualifier); ;} @@ -3956,8 +3966,8 @@ yyreduce: case 135: -/* Line 1455 of yacc.c */ -#line 966 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 968 "glsl_parser.ypp" { (yyval.type_qualifier).i = (yyvsp[(1) - (3)].type_qualifier).i | (yyvsp[(3) - (3)].type_qualifier).i; ;} @@ -3965,8 +3975,8 @@ yyreduce: case 136: -/* Line 1455 of yacc.c */ -#line 973 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 975 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; @@ -4001,36 +4011,36 @@ yyreduce: case 137: -/* Line 1455 of yacc.c */ -#line 1006 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1008 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.smooth = 1; ;} break; case 138: -/* Line 1455 of yacc.c */ -#line 1007 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1009 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.flat = 1; ;} break; case 139: -/* Line 1455 of yacc.c */ -#line 1008 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1010 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.noperspective = 1; ;} break; case 140: -/* Line 1455 of yacc.c */ -#line 1012 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1014 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.constant = 1; ;} break; case 142: -/* Line 1455 of yacc.c */ -#line 1018 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1020 "glsl_parser.ypp" { (yyval.type_qualifier).i = (yyvsp[(1) - (2)].type_qualifier).i | (yyvsp[(2) - (2)].type_qualifier).i; ;} @@ -4038,8 +4048,8 @@ yyreduce: case 143: -/* Line 1455 of yacc.c */ -#line 1022 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1024 "glsl_parser.ypp" { (yyval.type_qualifier) = (yyvsp[(2) - (2)].type_qualifier); (yyval.type_qualifier).q.invariant = 1; @@ -4048,71 +4058,71 @@ yyreduce: case 144: -/* Line 1455 of yacc.c */ -#line 1029 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1031 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.constant = 1; ;} break; case 145: -/* Line 1455 of yacc.c */ -#line 1030 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1032 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.attribute = 1; ;} break; case 146: -/* Line 1455 of yacc.c */ -#line 1031 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1033 "glsl_parser.ypp" { (yyval.type_qualifier).i = (yyvsp[(1) - (2)].type_qualifier).i; (yyval.type_qualifier).q.varying = 1; ;} break; case 147: -/* Line 1455 of yacc.c */ -#line 1032 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1034 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.centroid = 1; (yyval.type_qualifier).q.varying = 1; ;} break; case 148: -/* Line 1455 of yacc.c */ -#line 1033 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1035 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.in = 1; ;} break; case 149: -/* Line 1455 of yacc.c */ -#line 1034 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1036 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.out = 1; ;} break; case 150: -/* Line 1455 of yacc.c */ -#line 1035 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1037 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.centroid = 1; (yyval.type_qualifier).q.in = 1; ;} break; case 151: -/* Line 1455 of yacc.c */ -#line 1036 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1038 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.centroid = 1; (yyval.type_qualifier).q.out = 1; ;} break; case 152: -/* Line 1455 of yacc.c */ -#line 1037 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1039 "glsl_parser.ypp" { (yyval.type_qualifier).i = 0; (yyval.type_qualifier).q.uniform = 1; ;} break; case 154: -/* Line 1455 of yacc.c */ -#line 1043 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1045 "glsl_parser.ypp" { (yyval.type_specifier) = (yyvsp[(2) - (2)].type_specifier); (yyval.type_specifier)->precision = (yyvsp[(1) - (2)].n); @@ -4121,8 +4131,8 @@ yyreduce: case 156: -/* Line 1455 of yacc.c */ -#line 1052 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1054 "glsl_parser.ypp" { (yyval.type_specifier) = (yyvsp[(1) - (3)].type_specifier); (yyval.type_specifier)->is_array = true; @@ -4132,8 +4142,8 @@ yyreduce: case 157: -/* Line 1455 of yacc.c */ -#line 1058 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1060 "glsl_parser.ypp" { (yyval.type_specifier) = (yyvsp[(1) - (4)].type_specifier); (yyval.type_specifier)->is_array = true; @@ -4143,8 +4153,8 @@ yyreduce: case 158: -/* Line 1455 of yacc.c */ -#line 1067 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1069 "glsl_parser.ypp" { void *ctx = state; (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].n)); @@ -4154,8 +4164,8 @@ yyreduce: case 159: -/* Line 1455 of yacc.c */ -#line 1073 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1075 "glsl_parser.ypp" { void *ctx = state; (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].struct_specifier)); @@ -4165,8 +4175,8 @@ yyreduce: case 160: -/* Line 1455 of yacc.c */ -#line 1079 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1081 "glsl_parser.ypp" { void *ctx = state; (yyval.type_specifier) = new(ctx) ast_type_specifier((yyvsp[(1) - (1)].identifier)); @@ -4176,365 +4186,365 @@ yyreduce: case 161: -/* Line 1455 of yacc.c */ -#line 1087 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1089 "glsl_parser.ypp" { (yyval.n) = ast_void; ;} break; case 162: -/* Line 1455 of yacc.c */ -#line 1088 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1090 "glsl_parser.ypp" { (yyval.n) = ast_float; ;} break; case 163: -/* Line 1455 of yacc.c */ -#line 1089 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1091 "glsl_parser.ypp" { (yyval.n) = ast_int; ;} break; case 164: -/* Line 1455 of yacc.c */ -#line 1090 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1092 "glsl_parser.ypp" { (yyval.n) = ast_uint; ;} break; case 165: -/* Line 1455 of yacc.c */ -#line 1091 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1093 "glsl_parser.ypp" { (yyval.n) = ast_bool; ;} break; case 166: -/* Line 1455 of yacc.c */ -#line 1092 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1094 "glsl_parser.ypp" { (yyval.n) = ast_vec2; ;} break; case 167: -/* Line 1455 of yacc.c */ -#line 1093 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1095 "glsl_parser.ypp" { (yyval.n) = ast_vec3; ;} break; case 168: -/* Line 1455 of yacc.c */ -#line 1094 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1096 "glsl_parser.ypp" { (yyval.n) = ast_vec4; ;} break; case 169: -/* Line 1455 of yacc.c */ -#line 1095 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1097 "glsl_parser.ypp" { (yyval.n) = ast_bvec2; ;} break; case 170: -/* Line 1455 of yacc.c */ -#line 1096 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1098 "glsl_parser.ypp" { (yyval.n) = ast_bvec3; ;} break; case 171: -/* Line 1455 of yacc.c */ -#line 1097 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1099 "glsl_parser.ypp" { (yyval.n) = ast_bvec4; ;} break; case 172: -/* Line 1455 of yacc.c */ -#line 1098 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1100 "glsl_parser.ypp" { (yyval.n) = ast_ivec2; ;} break; case 173: -/* Line 1455 of yacc.c */ -#line 1099 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1101 "glsl_parser.ypp" { (yyval.n) = ast_ivec3; ;} break; case 174: -/* Line 1455 of yacc.c */ -#line 1100 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1102 "glsl_parser.ypp" { (yyval.n) = ast_ivec4; ;} break; case 175: -/* Line 1455 of yacc.c */ -#line 1101 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1103 "glsl_parser.ypp" { (yyval.n) = ast_uvec2; ;} break; case 176: -/* Line 1455 of yacc.c */ -#line 1102 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1104 "glsl_parser.ypp" { (yyval.n) = ast_uvec3; ;} break; case 177: -/* Line 1455 of yacc.c */ -#line 1103 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1105 "glsl_parser.ypp" { (yyval.n) = ast_uvec4; ;} break; case 178: -/* Line 1455 of yacc.c */ -#line 1104 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1106 "glsl_parser.ypp" { (yyval.n) = ast_mat2; ;} break; case 179: -/* Line 1455 of yacc.c */ -#line 1105 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1107 "glsl_parser.ypp" { (yyval.n) = ast_mat2x3; ;} break; case 180: -/* Line 1455 of yacc.c */ -#line 1106 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1108 "glsl_parser.ypp" { (yyval.n) = ast_mat2x4; ;} break; case 181: -/* Line 1455 of yacc.c */ -#line 1107 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1109 "glsl_parser.ypp" { (yyval.n) = ast_mat3x2; ;} break; case 182: -/* Line 1455 of yacc.c */ -#line 1108 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1110 "glsl_parser.ypp" { (yyval.n) = ast_mat3; ;} break; case 183: -/* Line 1455 of yacc.c */ -#line 1109 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1111 "glsl_parser.ypp" { (yyval.n) = ast_mat3x4; ;} break; case 184: -/* Line 1455 of yacc.c */ -#line 1110 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1112 "glsl_parser.ypp" { (yyval.n) = ast_mat4x2; ;} break; case 185: -/* Line 1455 of yacc.c */ -#line 1111 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1113 "glsl_parser.ypp" { (yyval.n) = ast_mat4x3; ;} break; case 186: -/* Line 1455 of yacc.c */ -#line 1112 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1114 "glsl_parser.ypp" { (yyval.n) = ast_mat4; ;} break; case 187: -/* Line 1455 of yacc.c */ -#line 1113 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1115 "glsl_parser.ypp" { (yyval.n) = ast_sampler1d; ;} break; case 188: -/* Line 1455 of yacc.c */ -#line 1114 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1116 "glsl_parser.ypp" { (yyval.n) = ast_sampler2d; ;} break; case 189: -/* Line 1455 of yacc.c */ -#line 1115 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1117 "glsl_parser.ypp" { (yyval.n) = ast_sampler2drect; ;} break; case 190: -/* Line 1455 of yacc.c */ -#line 1116 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1118 "glsl_parser.ypp" { (yyval.n) = ast_sampler3d; ;} break; case 191: -/* Line 1455 of yacc.c */ -#line 1117 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1119 "glsl_parser.ypp" { (yyval.n) = ast_samplercube; ;} break; case 192: -/* Line 1455 of yacc.c */ -#line 1118 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1120 "glsl_parser.ypp" { (yyval.n) = ast_sampler1dshadow; ;} break; case 193: -/* Line 1455 of yacc.c */ -#line 1119 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1121 "glsl_parser.ypp" { (yyval.n) = ast_sampler2dshadow; ;} break; case 194: -/* Line 1455 of yacc.c */ -#line 1120 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1122 "glsl_parser.ypp" { (yyval.n) = ast_sampler2drectshadow; ;} break; case 195: -/* Line 1455 of yacc.c */ -#line 1121 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1123 "glsl_parser.ypp" { (yyval.n) = ast_samplercubeshadow; ;} break; case 196: -/* Line 1455 of yacc.c */ -#line 1122 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1124 "glsl_parser.ypp" { (yyval.n) = ast_sampler1darray; ;} break; case 197: -/* Line 1455 of yacc.c */ -#line 1123 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1125 "glsl_parser.ypp" { (yyval.n) = ast_sampler2darray; ;} break; case 198: -/* Line 1455 of yacc.c */ -#line 1124 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1126 "glsl_parser.ypp" { (yyval.n) = ast_sampler1darrayshadow; ;} break; case 199: -/* Line 1455 of yacc.c */ -#line 1125 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1127 "glsl_parser.ypp" { (yyval.n) = ast_sampler2darrayshadow; ;} break; case 200: -/* Line 1455 of yacc.c */ -#line 1126 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1128 "glsl_parser.ypp" { (yyval.n) = ast_isampler1d; ;} break; case 201: -/* Line 1455 of yacc.c */ -#line 1127 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1129 "glsl_parser.ypp" { (yyval.n) = ast_isampler2d; ;} break; case 202: -/* Line 1455 of yacc.c */ -#line 1128 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1130 "glsl_parser.ypp" { (yyval.n) = ast_isampler3d; ;} break; case 203: -/* Line 1455 of yacc.c */ -#line 1129 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1131 "glsl_parser.ypp" { (yyval.n) = ast_isamplercube; ;} break; case 204: -/* Line 1455 of yacc.c */ -#line 1130 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1132 "glsl_parser.ypp" { (yyval.n) = ast_isampler1darray; ;} break; case 205: -/* Line 1455 of yacc.c */ -#line 1131 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1133 "glsl_parser.ypp" { (yyval.n) = ast_isampler2darray; ;} break; case 206: -/* Line 1455 of yacc.c */ -#line 1132 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1134 "glsl_parser.ypp" { (yyval.n) = ast_usampler1d; ;} break; case 207: -/* Line 1455 of yacc.c */ -#line 1133 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1135 "glsl_parser.ypp" { (yyval.n) = ast_usampler2d; ;} break; case 208: -/* Line 1455 of yacc.c */ -#line 1134 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1136 "glsl_parser.ypp" { (yyval.n) = ast_usampler3d; ;} break; case 209: -/* Line 1455 of yacc.c */ -#line 1135 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1137 "glsl_parser.ypp" { (yyval.n) = ast_usamplercube; ;} break; case 210: -/* Line 1455 of yacc.c */ -#line 1136 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1138 "glsl_parser.ypp" { (yyval.n) = ast_usampler1darray; ;} break; case 211: -/* Line 1455 of yacc.c */ -#line 1137 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1139 "glsl_parser.ypp" { (yyval.n) = ast_usampler2darray; ;} break; case 212: -/* Line 1455 of yacc.c */ -#line 1141 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1143 "glsl_parser.ypp" { if (state->language_version < 130) _mesa_glsl_error(& (yylsp[(1) - (1)]), state, @@ -4550,8 +4560,8 @@ yyreduce: case 213: -/* Line 1455 of yacc.c */ -#line 1152 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1154 "glsl_parser.ypp" { if (state->language_version < 130) _mesa_glsl_error(& (yylsp[(1) - (1)]), state, @@ -4567,8 +4577,8 @@ yyreduce: case 214: -/* Line 1455 of yacc.c */ -#line 1163 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1165 "glsl_parser.ypp" { if (state->language_version < 130) _mesa_glsl_error(& (yylsp[(1) - (1)]), state, @@ -4584,8 +4594,8 @@ yyreduce: case 215: -/* Line 1455 of yacc.c */ -#line 1178 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1180 "glsl_parser.ypp" { void *ctx = state; (yyval.struct_specifier) = new(ctx) ast_struct_specifier((yyvsp[(2) - (5)].identifier), (yyvsp[(4) - (5)].node)); @@ -4595,8 +4605,8 @@ yyreduce: case 216: -/* Line 1455 of yacc.c */ -#line 1184 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1186 "glsl_parser.ypp" { void *ctx = state; (yyval.struct_specifier) = new(ctx) ast_struct_specifier(NULL, (yyvsp[(3) - (4)].node)); @@ -4606,8 +4616,8 @@ yyreduce: case 217: -/* Line 1455 of yacc.c */ -#line 1193 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1195 "glsl_parser.ypp" { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].declarator_list); (yyvsp[(1) - (1)].declarator_list)->link.self_link(); @@ -4616,8 +4626,8 @@ yyreduce: case 218: -/* Line 1455 of yacc.c */ -#line 1198 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1200 "glsl_parser.ypp" { (yyval.node) = (ast_node *) (yyvsp[(1) - (2)].node); (yyval.node)->link.insert_before(& (yyvsp[(2) - (2)].declarator_list)->link); @@ -4626,8 +4636,8 @@ yyreduce: case 219: -/* Line 1455 of yacc.c */ -#line 1206 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1208 "glsl_parser.ypp" { void *ctx = state; ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); @@ -4643,8 +4653,8 @@ yyreduce: case 220: -/* Line 1455 of yacc.c */ -#line 1221 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1223 "glsl_parser.ypp" { (yyval.declaration) = (yyvsp[(1) - (1)].declaration); (yyvsp[(1) - (1)].declaration)->link.self_link(); @@ -4653,8 +4663,8 @@ yyreduce: case 221: -/* Line 1455 of yacc.c */ -#line 1226 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1228 "glsl_parser.ypp" { (yyval.declaration) = (yyvsp[(1) - (3)].declaration); (yyval.declaration)->link.insert_before(& (yyvsp[(3) - (3)].declaration)->link); @@ -4663,8 +4673,8 @@ yyreduce: case 222: -/* Line 1455 of yacc.c */ -#line 1234 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1236 "glsl_parser.ypp" { void *ctx = state; (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (1)].identifier), false, NULL, NULL); @@ -4674,8 +4684,8 @@ yyreduce: case 223: -/* Line 1455 of yacc.c */ -#line 1240 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1242 "glsl_parser.ypp" { void *ctx = state; (yyval.declaration) = new(ctx) ast_declaration((yyvsp[(1) - (4)].identifier), true, (yyvsp[(3) - (4)].expression), NULL); @@ -4685,29 +4695,29 @@ yyreduce: case 228: -/* Line 1455 of yacc.c */ -#line 1263 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1265 "glsl_parser.ypp" { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} break; case 234: -/* Line 1455 of yacc.c */ -#line 1275 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1277 "glsl_parser.ypp" { (yyval.node) = NULL; ;} break; case 235: -/* Line 1455 of yacc.c */ -#line 1276 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1278 "glsl_parser.ypp" { (yyval.node) = NULL; ;} break; case 238: -/* Line 1455 of yacc.c */ -#line 1283 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1285 "glsl_parser.ypp" { void *ctx = state; (yyval.compound_statement) = new(ctx) ast_compound_statement(true, NULL); @@ -4717,8 +4727,8 @@ yyreduce: case 239: -/* Line 1455 of yacc.c */ -#line 1289 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1291 "glsl_parser.ypp" { void *ctx = state; (yyval.compound_statement) = new(ctx) ast_compound_statement(true, (yyvsp[(2) - (3)].node)); @@ -4728,15 +4738,15 @@ yyreduce: case 240: -/* Line 1455 of yacc.c */ -#line 1297 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1299 "glsl_parser.ypp" { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].compound_statement); ;} break; case 242: -/* Line 1455 of yacc.c */ -#line 1303 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1305 "glsl_parser.ypp" { void *ctx = state; (yyval.compound_statement) = new(ctx) ast_compound_statement(false, NULL); @@ -4746,8 +4756,8 @@ yyreduce: case 243: -/* Line 1455 of yacc.c */ -#line 1309 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1311 "glsl_parser.ypp" { void *ctx = state; (yyval.compound_statement) = new(ctx) ast_compound_statement(false, (yyvsp[(2) - (3)].node)); @@ -4757,8 +4767,8 @@ yyreduce: case 244: -/* Line 1455 of yacc.c */ -#line 1318 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1320 "glsl_parser.ypp" { if ((yyvsp[(1) - (1)].node) == NULL) { _mesa_glsl_error(& (yylsp[(1) - (1)]), state, " statement\n"); @@ -4772,8 +4782,8 @@ yyreduce: case 245: -/* Line 1455 of yacc.c */ -#line 1328 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1330 "glsl_parser.ypp" { if ((yyvsp[(2) - (2)].node) == NULL) { _mesa_glsl_error(& (yylsp[(2) - (2)]), state, " statement\n"); @@ -4786,8 +4796,8 @@ yyreduce: case 246: -/* Line 1455 of yacc.c */ -#line 1340 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1342 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_expression_statement(NULL); @@ -4797,8 +4807,8 @@ yyreduce: case 247: -/* Line 1455 of yacc.c */ -#line 1346 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1348 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_expression_statement((yyvsp[(1) - (2)].expression)); @@ -4808,8 +4818,8 @@ yyreduce: case 248: -/* Line 1455 of yacc.c */ -#line 1355 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1357 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_selection_statement((yyvsp[(3) - (7)].expression), (yyvsp[(5) - (7)].node), (yyvsp[(7) - (7)].node)); @@ -4819,8 +4829,8 @@ yyreduce: case 249: -/* Line 1455 of yacc.c */ -#line 1364 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1366 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_selection_statement((yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].node), NULL); @@ -4830,8 +4840,8 @@ yyreduce: case 250: -/* Line 1455 of yacc.c */ -#line 1370 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1372 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_selection_statement((yyvsp[(3) - (5)].expression), (yyvsp[(5) - (5)].node), NULL); @@ -4841,8 +4851,8 @@ yyreduce: case 251: -/* Line 1455 of yacc.c */ -#line 1376 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1378 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_selection_statement((yyvsp[(3) - (7)].expression), (yyvsp[(5) - (7)].node), (yyvsp[(7) - (7)].node)); @@ -4852,8 +4862,8 @@ yyreduce: case 252: -/* Line 1455 of yacc.c */ -#line 1385 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1387 "glsl_parser.ypp" { (yyval.node) = (ast_node *) (yyvsp[(1) - (1)].expression); ;} @@ -4861,8 +4871,8 @@ yyreduce: case 253: -/* Line 1455 of yacc.c */ -#line 1389 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1391 "glsl_parser.ypp" { void *ctx = state; ast_declaration *decl = new(ctx) ast_declaration((yyvsp[(2) - (4)].identifier), false, NULL, (yyvsp[(4) - (4)].expression)); @@ -4877,8 +4887,8 @@ yyreduce: case 257: -/* Line 1455 of yacc.c */ -#line 1412 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1414 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, @@ -4889,8 +4899,8 @@ yyreduce: case 258: -/* Line 1455 of yacc.c */ -#line 1419 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1421 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, @@ -4901,8 +4911,8 @@ yyreduce: case 259: -/* Line 1455 of yacc.c */ -#line 1426 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1428 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, @@ -4913,8 +4923,8 @@ yyreduce: case 263: -/* Line 1455 of yacc.c */ -#line 1442 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1444 "glsl_parser.ypp" { (yyval.node) = NULL; ;} @@ -4922,8 +4932,8 @@ yyreduce: case 264: -/* Line 1455 of yacc.c */ -#line 1449 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1451 "glsl_parser.ypp" { (yyval.for_rest_statement).cond = (yyvsp[(1) - (2)].node); (yyval.for_rest_statement).rest = NULL; @@ -4932,8 +4942,8 @@ yyreduce: case 265: -/* Line 1455 of yacc.c */ -#line 1454 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1456 "glsl_parser.ypp" { (yyval.for_rest_statement).cond = (yyvsp[(1) - (3)].node); (yyval.for_rest_statement).rest = (yyvsp[(3) - (3)].expression); @@ -4942,8 +4952,8 @@ yyreduce: case 266: -/* Line 1455 of yacc.c */ -#line 1463 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1465 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); @@ -4953,8 +4963,8 @@ yyreduce: case 267: -/* Line 1455 of yacc.c */ -#line 1469 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1471 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); @@ -4964,8 +4974,8 @@ yyreduce: case 268: -/* Line 1455 of yacc.c */ -#line 1475 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1477 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); @@ -4975,8 +4985,8 @@ yyreduce: case 269: -/* Line 1455 of yacc.c */ -#line 1481 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1483 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, (yyvsp[(2) - (3)].expression)); @@ -4986,8 +4996,8 @@ yyreduce: case 270: -/* Line 1455 of yacc.c */ -#line 1487 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1489 "glsl_parser.ypp" { void *ctx = state; (yyval.node) = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); @@ -4997,22 +5007,22 @@ yyreduce: case 271: -/* Line 1455 of yacc.c */ -#line 1495 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1497 "glsl_parser.ypp" { (yyval.node) = (yyvsp[(1) - (1)].function_definition); ;} break; case 272: -/* Line 1455 of yacc.c */ -#line 1496 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1498 "glsl_parser.ypp" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; case 273: -/* Line 1455 of yacc.c */ -#line 1501 "glsl_parser.ypp" +/* Line 1464 of yacc.c */ +#line 1503 "glsl_parser.ypp" { void *ctx = state; (yyval.function_definition) = new(ctx) ast_function_definition(); @@ -5024,8 +5034,8 @@ yyreduce: -/* Line 1455 of yacc.c */ -#line 5029 "glsl_parser.cpp" +/* Line 1464 of yacc.c */ +#line 5039 "glsl_parser.cpp" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -5097,7 +5107,7 @@ yyerrlab: #endif } - yyerror_range[0] = yylloc; + yyerror_range[1] = yylloc; if (yyerrstatus == 3) { @@ -5134,7 +5144,7 @@ yyerrorlab: if (/*CONSTCOND*/ 0) goto yyerrorlab; - yyerror_range[0] = yylsp[1-yylen]; + yyerror_range[1] = yylsp[1-yylen]; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); @@ -5168,7 +5178,7 @@ yyerrlab1: if (yyssp == yyss) YYABORT; - yyerror_range[0] = *yylsp; + yyerror_range[1] = *yylsp; yydestruct ("Error: popping", yystos[yystate], yyvsp, yylsp, state); YYPOPSTACK (1); @@ -5178,10 +5188,10 @@ yyerrlab1: *++yyvsp = yylval; - yyerror_range[1] = yylloc; + yyerror_range[2] = yylloc; /* Using YYLLOC is tempting, but would change the location of the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + YYLLOC_DEFAULT (yyloc, yyerror_range, 2); *++yylsp = yyloc; /* Shift the error token. */ diff --git a/src/glsl/glsl_parser.h b/src/glsl/glsl_parser.h index 48a0a5fb3a..96f9df1129 100644 --- a/src/glsl/glsl_parser.h +++ b/src/glsl/glsl_parser.h @@ -1,10 +1,9 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ +/* A Bison parser, made by GNU Bison 2.4.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2009, 2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -233,7 +232,7 @@ typedef union YYSTYPE { -/* Line 1676 of yacc.c */ +/* Line 1685 of yacc.c */ #line 52 "glsl_parser.ypp" int n; @@ -264,8 +263,8 @@ typedef union YYSTYPE -/* Line 1676 of yacc.c */ -#line 269 "glsl_parser.h" +/* Line 1685 of yacc.c */ +#line 268 "glsl_parser.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ diff --git a/src/glsl/glsl_parser.ypp b/src/glsl/glsl_parser.ypp index e0b1d28504..4b6d9fe7ea 100644 --- a/src/glsl/glsl_parser.ypp +++ b/src/glsl/glsl_parser.ypp @@ -216,6 +216,7 @@ version_statement: /* blank - no #version specified */ { state->language_version = 110; + state->symbols->language_version = 110; } | VERSION INTCONSTANT EOL { @@ -225,6 +226,7 @@ version_statement: case 130: /* FINISHME: Check against implementation support versions. */ state->language_version = $2; + state->symbols->language_version = $2; break; default: _mesa_glsl_error(& @2, state, "Shading language version" diff --git a/src/glsl/glsl_symbol_table.cpp b/src/glsl/glsl_symbol_table.cpp new file mode 100644 index 0000000000..76c440c342 --- /dev/null +++ b/src/glsl/glsl_symbol_table.cpp @@ -0,0 +1,160 @@ +/* -*- c++ -*- */ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "glsl_symbol_table.h" + +class symbol_table_entry { +public: + /* Callers of this talloc-based new need not call delete. It's + * easier to just talloc_free 'ctx' (or any of its ancestors). */ + static void* operator new(size_t size, void *ctx) + { + void *entry = talloc_size(ctx, size); + assert(entry != NULL); + return entry; + } + + /* If the user *does* call delete, that's OK, we will just + * talloc_free in that case. Here, C++ will have already called the + * destructor so tell talloc not to do that again. */ + static void operator delete(void *table) + { + talloc_set_destructor(table, NULL); + talloc_free(table); + } + + symbol_table_entry(ir_variable *v) : v(v), f(0), t(0) {} + symbol_table_entry(ir_function *f) : v(0), f(f), t(0) {} + symbol_table_entry(const glsl_type *t, ir_function *f) : v(0), f(f), t(t) {} + + ir_variable *v; + ir_function *f; + const glsl_type *t; +}; + +glsl_symbol_table::glsl_symbol_table() +{ + this->language_version = 120; + this->table = _mesa_symbol_table_ctor(); + this->mem_ctx = talloc_init("symbol table entries"); +} + +glsl_symbol_table::~glsl_symbol_table() +{ + _mesa_symbol_table_dtor(table); + talloc_free(mem_ctx); +} + +void glsl_symbol_table::push_scope() +{ + _mesa_symbol_table_push_scope(table); +} + +void glsl_symbol_table::pop_scope() +{ + _mesa_symbol_table_pop_scope(table); +} + +bool glsl_symbol_table::name_declared_this_scope(const char *name) +{ + return _mesa_symbol_table_symbol_scope(table, -1, name) == 0; +} + +bool glsl_symbol_table::add_variable(const char *name, ir_variable *v) +{ + if (this->language_version == 110) { + /* In 1.10, functions and variables have separate namespaces. */ + symbol_table_entry *existing = get_entry(name); + if (name_declared_this_scope(name)) { + /* If there's already an existing function (not a constructor!) in + * the current scope, just update the existing entry to include 'v'. + */ + if (existing->v == NULL && existing->t == NULL) { + existing->v = v; + return true; + } + } else { + /* If not declared at this scope, add a new entry. But if an existing + * entry includes a function, propagate that to this block - otherwise + * the new variable declaration would shadow the function. + */ + symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v); + if (existing != NULL) + entry->f = existing->f; + int added = _mesa_symbol_table_add_symbol(table, -1, name, entry); + assert(added == 0); + return true; + } + return false; + } + + /* 1.20+ rules: */ + symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v); + return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0; +} + +bool glsl_symbol_table::add_type(const char *name, const glsl_type *t, + ir_function *constructor) +{ + symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(t, constructor); + return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0; +} + +bool glsl_symbol_table::add_function(const char *name, ir_function *f) +{ + if (this->language_version == 110 && name_declared_this_scope(name)) { + /* In 1.10, functions and variables have separate namespaces. */ + symbol_table_entry *existing = get_entry(name); + if (existing->f == NULL) { + existing->f = f; + return true; + } + } + symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f); + return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0; +} + +ir_variable *glsl_symbol_table::get_variable(const char *name) +{ + symbol_table_entry *entry = get_entry(name); + return entry != NULL ? entry->v : NULL; +} + +const glsl_type *glsl_symbol_table::get_type(const char *name) +{ + symbol_table_entry *entry = get_entry(name); + return entry != NULL ? entry->t : NULL; +} + +ir_function *glsl_symbol_table::get_function(const char *name) +{ + symbol_table_entry *entry = get_entry(name); + return entry != NULL ? entry->f : NULL; +} + +symbol_table_entry *glsl_symbol_table::get_entry(const char *name) +{ + return (symbol_table_entry *) + _mesa_symbol_table_find_symbol(table, -1, name); +} diff --git a/src/glsl/glsl_symbol_table.h b/src/glsl/glsl_symbol_table.h index 4cb7559e9a..d71be5578b 100644 --- a/src/glsl/glsl_symbol_table.h +++ b/src/glsl/glsl_symbol_table.h @@ -34,6 +34,8 @@ extern "C" { #include "ir.h" #include "glsl_types.h" +class symbol_table_entry; + /** * Facade class for _mesa_symbol_table * @@ -42,12 +44,6 @@ extern "C" { */ struct glsl_symbol_table { private: - enum glsl_symbol_name_space { - glsl_variable_name_space = 0, - glsl_type_name_space = 1, - glsl_function_name_space = 2 - }; - static int _glsl_symbol_table_destructor (glsl_symbol_table *table) { @@ -80,33 +76,18 @@ public: talloc_free(table); } - glsl_symbol_table() - { - table = _mesa_symbol_table_ctor(); - } + glsl_symbol_table(); + ~glsl_symbol_table(); - ~glsl_symbol_table() - { - _mesa_symbol_table_dtor(table); - } + unsigned int language_version; - void push_scope() - { - _mesa_symbol_table_push_scope(table); - } - - void pop_scope() - { - _mesa_symbol_table_pop_scope(table); - } + void push_scope(); + void pop_scope(); /** * Determine whether a name was declared at the current scope */ - bool name_declared_this_scope(const char *name) - { - return _mesa_symbol_table_symbol_scope(table, -1, name) == 0; - } + bool name_declared_this_scope(const char *name); /** * \name Methods to add symbols to the table @@ -116,56 +97,26 @@ public: * reduces the clarity of the intention of code that uses these methods. */ /*@{*/ - bool add_variable(const char *name, ir_variable *v) - { - return _mesa_symbol_table_add_symbol(table, glsl_variable_name_space, - name, v) == 0; - } - - bool add_type(const char *name, const glsl_type *t) - { - return _mesa_symbol_table_add_symbol(table, glsl_type_name_space, - name, (void *) t) == 0; - } - - bool add_function(const char *name, ir_function *f) - { - return _mesa_symbol_table_add_symbol(table, glsl_function_name_space, - name, f) == 0; - } - - bool remove_function(const char *name, ir_function *f) - { - return _mesa_symbol_table_add_symbol(table, glsl_function_name_space, - name, f) == 0; - } + bool add_variable(const char *name, ir_variable *v); + bool add_type(const char *name, const glsl_type *t, + ir_function *constructor = NULL); + bool add_function(const char *name, ir_function *f); /*@}*/ /** * \name Methods to get symbols from the table */ /*@{*/ - ir_variable *get_variable(const char *name) - { - return (ir_variable *) - _mesa_symbol_table_find_symbol(table, glsl_variable_name_space, name); - } - - glsl_type *get_type(const char *name) - { - return (glsl_type *) - _mesa_symbol_table_find_symbol(table, glsl_type_name_space, name); - } - - ir_function *get_function(const char *name) - { - return (ir_function *) - _mesa_symbol_table_find_symbol(table, glsl_function_name_space, name); - } + ir_variable *get_variable(const char *name); + const glsl_type *get_type(const char *name); + ir_function *get_function(const char *name); /*@}*/ private: + symbol_table_entry *get_entry(const char *name); + struct _mesa_symbol_table *table; + void *mem_ctx; }; #endif /* GLSL_SYMBOL_TABLE */ diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp index 2e5c2ecf04..a7d02e18df 100644 --- a/src/glsl/glsl_types.cpp +++ b/src/glsl/glsl_types.cpp @@ -233,18 +233,11 @@ _mesa_glsl_release_types(void) ir_function * -glsl_type::generate_constructor(glsl_symbol_table *symtab) const +glsl_type::generate_constructor() const { - void *ctx = symtab; + void *ctx = (void *) this; - /* Generate the function name and add it to the symbol table. - */ ir_function *const f = new(ctx) ir_function(name); - - bool added = symtab->add_function(name, f); - assert(added); - (void) added; - ir_function_signature *const sig = new(ctx) ir_function_signature(this); f->add_signature(sig); diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h index 80cec635d9..3e86d2c011 100644 --- a/src/glsl/glsl_types.h +++ b/src/glsl/glsl_types.h @@ -208,9 +208,9 @@ struct glsl_type { unsigned num_fields, const char *name); /** - * Generate the constructor for this type and add it to the symbol table + * Generate the constructor for this type and return it */ - class ir_function *generate_constructor(glsl_symbol_table *) const; + class ir_function *generate_constructor() const; /** * Query the total number of scalars that make up a scalar, vector or matrix -- cgit v1.2.3 From e09591317b2470fe9c104606577d4e10255727c0 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 25 Aug 2010 16:37:46 -0700 Subject: glsl: Remove name_declared_this_scope check when adding functions. Instead, rely on the symbol table's rules. Fixes redeclaration-02.vert. --- src/glsl/ast_to_hir.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 8c105e79f7..8caf950c2d 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2197,17 +2197,16 @@ ast_function::hir(exec_list *instructions, _mesa_glsl_error(& loc, state, "function `%s' redefined", name); } } - } else if (state->symbols->name_declared_this_scope(name)) { - /* This function name shadows a non-function use of the same name. - */ - YYLTYPE loc = this->get_location(); - - _mesa_glsl_error(& loc, state, "function name `%s' conflicts with " - "non-function", name); - return NULL; } else { f = new(ctx) ir_function(name); - state->symbols->add_function(f->name, f); + if (!state->symbols->add_function(f->name, f)) { + /* This function name shadows a non-function use of the same name. */ + YYLTYPE loc = this->get_location(); + + _mesa_glsl_error(&loc, state, "function name `%s' conflicts with " + "non-function", name); + return NULL; + } /* Emit the new function header */ instructions->push_tail(f); -- cgit v1.2.3 From ac2376e6f51677ab321930b0200a79d1683cfbba Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 25 Aug 2010 17:10:16 -0700 Subject: glsl: Don't add overloads to existing structure constructors. Instead, make a new ir_function and try to add it to the symbol table. Fixes piglit test redeclaration-08.vert. --- src/glsl/ast_to_hir.cpp | 2 +- src/glsl/glsl_symbol_table.cpp | 9 +++++++-- src/glsl/glsl_symbol_table.h | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 8caf950c2d..c666da300b 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2172,7 +2172,7 @@ ast_function::hir(exec_list *instructions, * seen signature for a function with the same name, or, if a match is found, * that the previously seen signature does not have an associated definition. */ - f = state->symbols->get_function(name); + f = state->symbols->get_function(name, false); if (f != NULL) { sig = f->exact_matching_signature(&hir_parameters); if (sig != NULL) { diff --git a/src/glsl/glsl_symbol_table.cpp b/src/glsl/glsl_symbol_table.cpp index 76c440c342..11e1671335 100644 --- a/src/glsl/glsl_symbol_table.cpp +++ b/src/glsl/glsl_symbol_table.cpp @@ -147,10 +147,15 @@ const glsl_type *glsl_symbol_table::get_type(const char *name) return entry != NULL ? entry->t : NULL; } -ir_function *glsl_symbol_table::get_function(const char *name) +ir_function *glsl_symbol_table::get_function(const char *name, + bool return_constructors) { symbol_table_entry *entry = get_entry(name); - return entry != NULL ? entry->f : NULL; + // If there's a type, the function is a constructor; caller may not want it. + if (entry != NULL && (return_constructors || entry->t == NULL)) + return entry->f; + + return NULL; } symbol_table_entry *glsl_symbol_table::get_entry(const char *name) diff --git a/src/glsl/glsl_symbol_table.h b/src/glsl/glsl_symbol_table.h index d71be5578b..c90fdc3c1d 100644 --- a/src/glsl/glsl_symbol_table.h +++ b/src/glsl/glsl_symbol_table.h @@ -109,7 +109,7 @@ public: /*@{*/ ir_variable *get_variable(const char *name); const glsl_type *get_type(const char *name); - ir_function *get_function(const char *name); + ir_function *get_function(const char *name, bool return_constructors = true); /*@}*/ private: -- cgit v1.2.3 From 5d25746640ee27882b69a962459727cf924443db Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 24 Aug 2010 01:45:49 -0700 Subject: glsl: Refactor variable declaration handling. Moving the check for an earlier variable declaration helps cleanly separate out the re-declaration vs. new declaration code a bit. With that in place, conflicts between variable names and structure types or function names aren't caught by the earlier "redeclaration" error message, so check the return type on glsl_symbol_table::add_variable and issue an error there. If one occurs, don't emit the initializer. Fixes redeclaration-01.vert and redeclaration-09.vert. Signed-off-by: Ian Romanick --- src/glsl/ast_to_hir.cpp | 77 ++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 36 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index c666da300b..9b723162f6 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1887,22 +1887,22 @@ ast_declarator_list::hir(exec_list *instructions, "const declaration of `%s' must be initialized"); } - /* Attempt to add the variable to the symbol table. If this fails, it - * means the variable has already been declared at this scope. Arrays - * fudge this rule a little bit. + /* Check if this declaration is actually a re-declaration, either to + * resize an array or add qualifiers to an existing variable. * - * 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." + * This is allowed for variables in the current scope. */ - if (state->symbols->name_declared_this_scope(decl->identifier)) { - ir_variable *const earlier = - state->symbols->get_variable(decl->identifier); + ir_variable *earlier = state->symbols->get_variable(decl->identifier); + if (earlier != NULL + && state->symbols->name_declared_this_scope(decl->identifier)) { - if ((earlier != NULL) - && (earlier->type->array_size() == 0) + /* 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 ((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 @@ -1934,11 +1934,10 @@ ast_declarator_list::hir(exec_list *instructions, earlier->type = var->type; delete var; var = NULL; - } else if (state->extensions->ARB_fragment_coord_conventions && - (earlier != NULL) && - (strcmp(var->name, "gl_FragCoord") == 0) && - earlier->type == var->type && - earlier->mode == var->mode) { + } else if (state->extensions->ARB_fragment_coord_conventions + && strcmp(var->name, "gl_FragCoord") == 0 + && earlier->type == var->type + && earlier->mode == var->mode) { /* Allow redeclaration of gl_FragCoord for ARB_fcc layout * qualifiers. */ @@ -1946,15 +1945,16 @@ ast_declarator_list::hir(exec_list *instructions, earlier->pixel_center_integer = var->pixel_center_integer; } 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; } - /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, + /* By now, we know it's a new variable declaration (we didn't hit the + * above "continue"). + * + * From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, * * "Identifiers starting with "gl_" are reserved for use by * OpenGL, and may not be declared in a shader as either a @@ -1969,6 +1969,25 @@ ast_declarator_list::hir(exec_list *instructions, decl->identifier); } + /* Add the variable to the symbol table. Note that the initializer's + * IR was already processed earlier (though it hasn't been emitted yet), + * without the variable in scope. + * + * This differs from most C-like languages, but it follows the GLSL + * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50 + * spec: + * + * "Within a declaration, the scope of a name starts immediately + * after the initializer if present or immediately after the name + * being declared if not." + */ + if (!state->symbols->add_variable(var->name, var)) { + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(&loc, state, "name `%s' already taken in the " + "current scope", decl->identifier); + continue; + } + /* Push the variable declaration to the top. It means that all * the variable declarations will appear in a funny * last-to-first order, but otherwise we run into trouble if a @@ -1978,20 +1997,6 @@ ast_declarator_list::hir(exec_list *instructions, */ instructions->push_head(var); instructions->append_list(&initializer_instructions); - - /* Add the variable to the symbol table after processing the initializer. - * This differs from most C-like languages, but it follows the GLSL - * specification. From page 28 (page 34 of the PDF) of the GLSL 1.50 - * spec: - * - * "Within a declaration, the scope of a name starts immediately - * after the initializer if present or immediately after the name - * being declared if not." - */ - const bool added_variable = - state->symbols->add_variable(var->name, var); - assert(added_variable); - (void) added_variable; } -- cgit v1.2.3 From a044285e25615f2d97636fe3ba47d580c3537bc4 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 23 Aug 2010 14:52:06 -0700 Subject: glsl: Move built-ins to live beyond the global scope. Per the GLSL 1.20 specification (presumably a clarification of 1.10). Also, when creating user functions, make a new ir_function that shadows the built-in ir_function, rather than adding new signatures. User functions are supposed to hide built-ins, not overload them. Fixes piglit tests redeclaration-{04, 12, 14}.vert. --- src/glsl/ast_to_hir.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 9b723162f6..548b3d8e5a 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -64,6 +64,21 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) state->current_function = NULL; + /* Section 4.2 of the GLSL 1.20 specification states: + * "The built-in functions are scoped in a scope outside the global scope + * users declare global variables in. That is, a shader's global scope, + * available for user-defined functions and global variables, is nested + * inside the scope containing the built-in functions." + * + * Since built-in functions like ftransform() access built-in variables, + * it follows that those must be in the outer scope as well. + * + * We push scope here to create this nesting effect...but don't pop. + * This way, a shader's globals are still in the symbol table for use + * by the linker. + */ + state->symbols->push_scope(); + foreach_list_typed (ast_node, ast, link, & state->translation_unit) ast->hir(instructions, state); } @@ -1890,11 +1905,12 @@ ast_declarator_list::hir(exec_list *instructions, /* Check if this declaration is actually a re-declaration, either to * resize an array or add qualifiers to an existing variable. * - * This is allowed for variables in the current scope. + * This is allowed for variables in the current scope, or when at + * global scope (for built-ins in the implicit outer scope). */ ir_variable *earlier = state->symbols->get_variable(decl->identifier); - if (earlier != NULL - && state->symbols->name_declared_this_scope(decl->identifier)) { + if (earlier != NULL && (state->current_function == NULL || + state->symbols->name_declared_this_scope(decl->identifier))) { /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec, * @@ -2178,7 +2194,7 @@ ast_function::hir(exec_list *instructions, * that the previously seen signature does not have an associated definition. */ f = state->symbols->get_function(name, false); - if (f != NULL) { + if (f != NULL && !f->is_builtin) { sig = f->exact_matching_signature(&hir_parameters); if (sig != NULL) { const char *badvar = sig->qualifiers_match(&hir_parameters); -- cgit v1.2.3 From de3b40d8cdc42cc1cd71dd65c90d6d569d922fc6 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 26 Aug 2010 09:24:58 -0700 Subject: glsl2: Remove a couple FINISHME comments that have already been resolved --- src/glsl/ast_to_hir.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 548b3d8e5a..e0a510cc45 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -510,7 +510,6 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, bool error_emitted = (lhs->type->is_error() || rhs->type->is_error()); if (!error_emitted) { - /* FINISHME: This does not handle 'foo.bar.a.b.c[5].d = 5' */ if (!lhs->is_lvalue()) { _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment"); error_emitted = true; @@ -581,7 +580,6 @@ get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue) void *ctx = talloc_parent(lvalue); ir_variable *var; - /* FINISHME: Give unique names to the temporaries. */ var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp", ir_var_temporary); instructions->push_tail(var); @@ -1976,14 +1974,10 @@ ast_declarator_list::hir(exec_list *instructions, * OpenGL, and may not be declared in a shader as either a * variable or a function." */ - if (strncmp(decl->identifier, "gl_", 3) == 0) { - /* FINISHME: This should only trigger if we're not redefining - * FINISHME: a builtin (to add a qualifier, for example). - */ + if (strncmp(decl->identifier, "gl_", 3) == 0) _mesa_glsl_error(& loc, state, "identifier `%s' uses reserved `gl_' prefix", decl->identifier); - } /* Add the variable to the symbol table. Note that the initializer's * IR was already processed earlier (though it hasn't been emitted yet), -- cgit v1.2.3 From 1eea96326fa652029e3898e104c715e5464f11e4 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 31 Aug 2010 10:56:24 -0700 Subject: ast_to_hir: Add support for bit-wise operators (but not shifts). Previously, using bit-wise operators in some larger expression would crash on a NULL pointer dereference. This code at least doesn't crash. Fixes piglit test bitwise-01.frag. --- src/glsl/ast_to_hir.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index e0a510cc45..148afd00e8 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -802,9 +802,60 @@ ast_expression::hir(exec_list *instructions, case ast_bit_and: case ast_bit_xor: case ast_bit_or: + op[0] = this->subexpressions[0]->hir(instructions, state); + op[1] = this->subexpressions[1]->hir(instructions, state); + + if (state->language_version < 130) { + _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30"); + error_emitted = true; + } + + if (!op[0]->type->is_integer()) { + _mesa_glsl_error(&loc, state, "LHS of `%s' must be an integer", + operator_string(this->oper)); + error_emitted = true; + } + + if (!op[1]->type->is_integer()) { + _mesa_glsl_error(&loc, state, "RHS of `%s' must be an integer", + operator_string(this->oper)); + error_emitted = true; + } + + if (op[0]->type->base_type != op[1]->type->base_type) { + _mesa_glsl_error(&loc, state, "operands of `%s' must have the same " + "base type", operator_string(this->oper)); + error_emitted = true; + } + + if (op[0]->type->is_vector() && op[1]->type->is_vector() + && op[0]->type->vector_elements != op[1]->type->vector_elements) { + _mesa_glsl_error(&loc, state, "operands of `%s' cannot be vectors of " + "different sizes", operator_string(this->oper)); + error_emitted = true; + } + + type = op[0]->type->is_scalar() ? op[1]->type : op[0]->type; + result = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); + error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); + break; + case ast_bit_not: - _mesa_glsl_error(& loc, state, "FINISHME: implement bit-wise operators"); - error_emitted = true; + op[0] = this->subexpressions[0]->hir(instructions, state); + + if (state->language_version < 130) { + _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30"); + error_emitted = true; + } + + if (!op[0]->type->is_integer()) { + _mesa_glsl_error(&loc, state, "operand of `~' must be an integer"); + error_emitted = true; + } + + type = op[0]->type; + result = new(ctx) ir_expression(ir_unop_bit_not, type, op[0], NULL); break; case ast_logic_and: { -- cgit v1.2.3 From 63b80f8cc181ded154668e60ac2cf0a6a82d118f Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 1 Sep 2010 06:34:58 -0700 Subject: glsl2: Disallow function declarations within function definitions in GLSL 1.20 The GLSL 1.20 spec specifically disallows this, but it was allowed in GLSL 1.10. Fixes piglit test cases local-function-0[13].frag and bugzilla #29921. --- src/glsl/ast_to_hir.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 148afd00e8..84aa6501c5 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2193,6 +2193,25 @@ ast_function::hir(exec_list *instructions, const char *const name = identifier; + /* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec, + * + * "Function declarations (prototypes) cannot occur inside of functions; + * they must be at global scope, or for the built-in functions, outside + * the global scope." + * + * From page 27 (page 33 of the PDF) of the GLSL ES 1.00.16 spec, + * + * "User defined functions may only be defined within the global scope." + * + * Note that this language does not appear in GLSL 1.10. + */ + if ((state->current_function != NULL) && (state->language_version != 110)) { + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(&loc, state, + "declaration of function `%s' not allowed within " + "function body", name); + } + /* From page 15 (page 21 of the PDF) of the GLSL 1.10 spec, * * "Identifiers starting with "gl_" are reserved for use by @@ -2275,7 +2294,23 @@ ast_function::hir(exec_list *instructions, } /* Emit the new function header */ - instructions->push_tail(f); + if (state->current_function == NULL) + instructions->push_tail(f); + else { + /* IR invariants disallow function declarations or definitions nested + * within other function definitions. Insert the new ir_function + * block in the instruction sequence before the ir_function block + * containing the current ir_function_signature. + * + * This can only happen in a GLSL 1.10 shader. In all other GLSL + * versions this nesting is disallowed. There is a check for this at + * the top of this function. + */ + ir_function *const curr = + const_cast(state->current_function->function()); + + curr->insert_before(f); + } } /* Verify the return type of main() */ -- cgit v1.2.3 From a789ca649cb143c0c5bf3209ff1bde398fbd777e Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 1 Sep 2010 14:08:08 -0700 Subject: glsl2: Don't generate constructor functions for structures --- src/glsl/ast_to_hir.cpp | 3 +-- src/glsl/glsl_symbol_table.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 84aa6501c5..970ac0818e 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2730,8 +2730,7 @@ ast_struct_specifier::hir(exec_list *instructions, glsl_type::get_record_instance(fields, decl_count, name); YYLTYPE loc = this->get_location(); - ir_function *ctor = t->generate_constructor(); - if (!state->symbols->add_type(name, t, ctor)) { + if (!state->symbols->add_type(name, t)) { _mesa_glsl_error(& loc, state, "struct `%s' previously defined", name); } else { diff --git a/src/glsl/glsl_symbol_table.cpp b/src/glsl/glsl_symbol_table.cpp index ed71244cbf..c71f3f830c 100644 --- a/src/glsl/glsl_symbol_table.cpp +++ b/src/glsl/glsl_symbol_table.cpp @@ -127,7 +127,7 @@ bool glsl_symbol_table::add_function(const char *name, ir_function *f) if (this->language_version == 110 && name_declared_this_scope(name)) { /* In 1.10, functions and variables have separate namespaces. */ symbol_table_entry *existing = get_entry(name); - if (existing->f == NULL) { + if ((existing->f == NULL) && (existing->t == NULL)) { existing->f = f; return true; } -- cgit v1.2.3 From e466b182bbf21f62fe6542091f4af3275555db80 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 1 Sep 2010 14:16:53 -0700 Subject: glsl2: Remove unnecessary glsl_symbol_table::get_function parameter return_constructors Now that constructors are not generated as functions or stored in the symbol table, there is no need to flag whether or not constructors should be returned. --- src/glsl/ast_to_hir.cpp | 2 +- src/glsl/glsl_symbol_table.cpp | 9 ++------- src/glsl/glsl_symbol_table.h | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 970ac0818e..5bdf3da367 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2257,7 +2257,7 @@ ast_function::hir(exec_list *instructions, * seen signature for a function with the same name, or, if a match is found, * that the previously seen signature does not have an associated definition. */ - f = state->symbols->get_function(name, false); + f = state->symbols->get_function(name); if (f != NULL && !f->is_builtin) { sig = f->exact_matching_signature(&hir_parameters); if (sig != NULL) { diff --git a/src/glsl/glsl_symbol_table.cpp b/src/glsl/glsl_symbol_table.cpp index b56b087530..e9bf89b951 100644 --- a/src/glsl/glsl_symbol_table.cpp +++ b/src/glsl/glsl_symbol_table.cpp @@ -147,15 +147,10 @@ const glsl_type *glsl_symbol_table::get_type(const char *name) return entry != NULL ? entry->t : NULL; } -ir_function *glsl_symbol_table::get_function(const char *name, - bool return_constructors) +ir_function *glsl_symbol_table::get_function(const char *name) { symbol_table_entry *entry = get_entry(name); - // If there's a type, the function is a constructor; caller may not want it. - if (entry != NULL && (return_constructors || entry->t == NULL)) - return entry->f; - - return NULL; + return entry != NULL ? entry->f : NULL; } symbol_table_entry *glsl_symbol_table::get_entry(const char *name) diff --git a/src/glsl/glsl_symbol_table.h b/src/glsl/glsl_symbol_table.h index f1369b52c8..f26de52432 100644 --- a/src/glsl/glsl_symbol_table.h +++ b/src/glsl/glsl_symbol_table.h @@ -108,7 +108,7 @@ public: /*@{*/ ir_variable *get_variable(const char *name); const glsl_type *get_type(const char *name); - ir_function *get_function(const char *name, bool return_constructors = true); + ir_function *get_function(const char *name); /*@}*/ private: -- cgit v1.2.3 From f32d3df8ab2b7c6c746f46870edc4b284cea50ca Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 1 Sep 2010 20:03:17 -0700 Subject: glsl: Apply implicit conversions to structure constructor parameters. The code for handling implicit conversions should probably get refactored, but for now, this is easy. Fixes piglit test constructor-26.vert. --- src/glsl/ast_function.cpp | 11 +++++++++-- src/glsl/ast_to_hir.cpp | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src/glsl/ast_to_hir.cpp') diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 1a5a193ad5..61012b850a 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -30,6 +30,10 @@ static ir_rvalue * convert_component(ir_rvalue *src, const glsl_type *desired_type); +bool +apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, + struct _mesa_glsl_parse_state *state); + static unsigned process_parameters(exec_list *instructions, exec_list *actual_parameters, exec_list *parameters, @@ -1185,7 +1189,7 @@ ast_function_expression::hir(exec_list *instructions, if ((type != NULL) && type->is_record()) { exec_node *node = actual_parameters.head; for (unsigned i = 0; i < type->length; i++) { - ir_instruction *ir = (ir_instruction *) node; + ir_rvalue *ir = (ir_rvalue *) node; if (node->is_tail_sentinel()) { _mesa_glsl_error(&loc, state, @@ -1195,7 +1199,10 @@ ast_function_expression::hir(exec_list *instructions, return ir_call::get_error_instruction(ctx); } - if (ir->type != type->fields.structure[i].type) { + 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)", diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 5bdf3da367..762f802c2b 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -97,7 +97,7 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) * If a conversion is possible (or unnecessary), \c true is returned. * Otherwise \c false is returned. */ -static bool +bool apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, struct _mesa_glsl_parse_state *state) { -- cgit v1.2.3