From: Ian Romanick Date: Fri, 23 Apr 2010 20:21:22 +0000 (-0700) Subject: glsl_type::generate_constructor_prototype now generates the function too X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=82baaf428308e83ad28ca0914c13af59e8a28374;p=mesa.git glsl_type::generate_constructor_prototype now generates the function too Also, change the name of the method to generate_constructor. --- diff --git a/ast_function.cpp b/ast_function.cpp index 3472b397cc1..cc8e9a8039b 100644 --- a/ast_function.cpp +++ b/ast_function.cpp @@ -271,11 +271,10 @@ process_array_constructor(exec_list *instructions, ir_function *f = state->symbols->get_function(constructor_type->name); /* If the constructor for this type of array does not exist, generate the - * prototype and add it to the symbol table. The code will be generated - * later. + * prototype and add it to the symbol table. */ if (f == NULL) { - f = constructor_type->generate_constructor_prototype(state->symbols); + f = constructor_type->generate_constructor(state->symbols); } ir_rvalue *const r = diff --git a/glsl_types.cpp b/glsl_types.cpp index 720dce79a1d..a293ce72860 100644 --- a/glsl_types.cpp +++ b/glsl_types.cpp @@ -133,7 +133,7 @@ const glsl_type *glsl_type::get_base_type() const ir_function * -glsl_type::generate_constructor_prototype(glsl_symbol_table *symtab) const +glsl_type::generate_constructor(glsl_symbol_table *symtab) const { /* Generate the function name and add it to the symbol table. */ @@ -145,6 +145,8 @@ glsl_type::generate_constructor_prototype(glsl_symbol_table *symtab) const ir_function_signature *const sig = new ir_function_signature(this); f->add_signature(sig); + ir_variable **declarations = + (ir_variable **) malloc(sizeof(ir_variable *) * this->length); for (unsigned i = 0; i < length; i++) { char *const param_name = (char *) malloc(10); @@ -155,9 +157,35 @@ glsl_type::generate_constructor_prototype(glsl_symbol_table *symtab) const : new ir_variable(fields.structure[i].type, param_name); var->mode = ir_var_in; + declarations[i] = var; sig->parameters.push_tail(var); } + /* Generate the body of the constructor. The body assigns each of the + * parameters to a portion of a local variable called __retval that has + * the same type as the constructor. After initializing __retval, + * __retval is returned. + */ + ir_variable *retval = new ir_variable(this, "__retval"); + sig->body.push_tail(retval); + + for (unsigned i = 0; i < length; i++) { + ir_dereference *const lhs = (this->base_type == GLSL_TYPE_ARRAY) + ? new ir_dereference(retval, new ir_constant(i)) + : new ir_dereference(retval, fields.structure[i].name); + + ir_dereference *const rhs = new ir_dereference(declarations[i]); + ir_instruction *const assign = new ir_assignment(lhs, rhs, NULL); + + sig->body.push_tail(assign); + } + + free(declarations); + + ir_dereference *const retref = new ir_dereference(retval); + ir_instruction *const inst = new ir_return(retref); + sig->body.push_tail(inst); + return f; } diff --git a/glsl_types.h b/glsl_types.h index 1f8559aa6a4..96e4c74d5b5 100644 --- a/glsl_types.h +++ b/glsl_types.h @@ -199,8 +199,10 @@ struct glsl_type { static const glsl_type *get_array_instance(const glsl_type *base, unsigned elements); - class ir_function *generate_constructor_prototype(class glsl_symbol_table *) - const; + /** + * Generate the constructor for this type and add it to the symbol table + */ + class ir_function *generate_constructor(class glsl_symbol_table *) const; /** * Query the total number of scalars that make up a scalar, vector or matrix