glsl_type::generate_constructor_prototype now generates the function too
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 23 Apr 2010 20:21:22 +0000 (13:21 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 29 Apr 2010 01:22:54 +0000 (18:22 -0700)
Also, change the name of the method to generate_constructor.

ast_function.cpp
glsl_types.cpp
glsl_types.h

index 3472b397cc1f0dcdcaea1495b163304c037f739f..cc8e9a8039b3ec5214e3c0e22f894f9bd668ac89 100644 (file)
@@ -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 =
index 720dce79a1db108646d2c4f5bc341766524bf6ad..a293ce728602a90a674fdeb35686b7b6d98646b0 100644 (file)
@@ -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;
 }
 
index 1f8559aa6a40d0d969e3afe432287b9276d132d7..96e4c74d5b5c556f009f2cd5abc8276e2d4fdfeb 100644 (file)
@@ -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