summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-04-23 13:21:22 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-04-28 18:22:54 -0700
commit82baaf428308e83ad28ca0914c13af59e8a28374 (patch)
treeb4651591b0eb218a5847800255eea6c0af461741
parent85ba37b97df8edd18b757bc475b12b66f4b117ed (diff)
glsl_type::generate_constructor_prototype now generates the function too
Also, change the name of the method to generate_constructor.
-rw-r--r--ast_function.cpp5
-rw-r--r--glsl_types.cpp30
-rw-r--r--glsl_types.h6
3 files changed, 35 insertions, 6 deletions
diff --git a/ast_function.cpp b/ast_function.cpp
index 3472b397cc..cc8e9a8039 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 720dce79a1..a293ce7286 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 1f8559aa6a..96e4c74d5b 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