{
const struct glsl_type *type;
- if (this->type_specifier == ast_struct) {
+ if ((this->type_specifier == ast_struct) && (this->type_name == NULL)) {
/* FINISHME: Handle annonymous structures. */
type = NULL;
} else {
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
*/
decl_type = this->type->specifier->glsl_type(& type_name, state);
+ if (is_empty_list(&this->declarations)) {
+ /* 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 (ptr, &this->declarations) {
struct ast_declaration *const decl = (struct ast_declaration * )ptr;
const struct glsl_type *var_type;
struct ir_variable *var;
- YYLTYPE loc = this->get_location();
/* FINISHME: Emit a warning if a variable declaration shadows a
* FINISHME: declaration at a higher scope.
if (sig == NULL) {
sig = new ir_function_signature(return_type);
f->add_signature(sig);
- } else if (is_definition) {
- /* Destroy all of the previous parameter information. The previous
- * parameter information comes from the function prototype, and it can
- * either include invalid parameter names or may not have names at all.
- */
- foreach_iter(exec_list_iterator, iter, sig->parameters) {
- assert(((ir_instruction *) iter.get())->as_variable() != NULL);
-
- iter.remove();
- delete iter.get();
- }
}
- hir_parameters.move_nodes_to(& sig->parameters);
+ sig->replace_parameters(&hir_parameters);
signature = sig;
/* Function declarations (prototypes) 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)
+{
+ simple_node *ptr;
+ unsigned decl_count = 0;
+
+ /* Make an initial pass over the list of structure fields to determine how
+ * many there are. Each element in this list is an ast_declarator_list.
+ * This means that we actually need to count the number of elements in the
+ * 'declarations' list in each of the elements.
+ */
+ foreach (ptr, & this->declarations) {
+ ast_declarator_list *decl_list = (ast_declarator_list *) ptr;
+ simple_node *decl_ptr;
+
+ foreach (decl_ptr, & decl_list->declarations) {
+ decl_count++;
+ }
+ }
+
+
+ /* Allocate storage for the structure fields and process the field
+ * declarations. As the declarations are processed, try to also convert
+ * the types to HIR. This ensures that structure definitions embedded in
+ * other structure definitions are processed.
+ */
+ glsl_struct_field *const fields = (glsl_struct_field *)
+ malloc(sizeof(*fields) * decl_count);
+
+ unsigned i = 0;
+ foreach (ptr, & this->declarations) {
+ ast_declarator_list *decl_list = (ast_declarator_list *) ptr;
+ simple_node *decl_ptr;
+ const char *type_name;
+
+ decl_list->type->specifier->hir(instructions, state);
+
+ const glsl_type *decl_type =
+ decl_list->type->specifier->glsl_type(& type_name, state);
+
+ foreach (decl_ptr, & decl_list->declarations) {
+ ast_declaration *const decl = (ast_declaration *) decl_ptr;
+ const struct glsl_type *const field_type =
+ (decl->is_array)
+ ? process_array_type(decl_type, decl->array_size, state)
+ : decl_type;
+
+ fields[i].type = (field_type != 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 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;
+}