ir_reader: rvalues are instructions too!
[mesa.git] / ast_function.cpp
index 91d4f15a3b7b932839bd63c91b2aeeff80b33365..3472b397cc1f0dcdcaea1495b163304c037f739f 100644 (file)
@@ -38,7 +38,7 @@ process_parameters(exec_list *instructions, exec_list *actual_parameters,
    if (first != NULL) {
       simple_node *ptr = first;
       do {
-        ir_instruction *const result =
+        ir_rvalue *const result =
            ((ast_node *) ptr)->hir(instructions, state);
         ptr = ptr->next;
 
@@ -63,6 +63,35 @@ process_call(exec_list *instructions, ir_function *f,
    (void) instructions;
 
    if (sig != NULL) {
+      /* Verify that 'out' and 'inout' actual parameters are lvalues.  This
+       * isn't done in ir_function::matching_signature because that function
+       * cannot generate the necessary diagnostics.
+       */
+      exec_list_iterator actual_iter = actual_parameters->iterator();
+      exec_list_iterator formal_iter = sig->parameters.iterator();
+
+      while (actual_iter.has_next()) {
+        ir_rvalue *actual = (ir_rvalue *) actual_iter.get();
+        ir_variable *formal = (ir_variable *) formal_iter.get();
+
+        assert(actual != NULL);
+        assert(formal != NULL);
+
+        if ((formal->mode == ir_var_out)
+            || (formal->mode == ir_var_inout)) {
+           if (! actual->is_lvalue()) {
+              /* FINISHME: Log a better diagnostic here.  There is no way
+               * FINISHME: to tell the user which parameter is invalid.
+               */
+              _mesa_glsl_error(loc, state, "`%s' parameter is not lvalue",
+                               (formal->mode == ir_var_out) ? "out" : "inout");
+           }
+        }
+
+        actual_iter.next();
+        formal_iter.next();
+      }
+
       /* FINISHME: The list of actual parameters needs to be modified to
        * FINISHME: include any necessary conversions.
        */
@@ -130,7 +159,7 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
         return new ir_expression(ir_unop_f2i, desired_type, src, NULL);
       else {
         assert(b == GLSL_TYPE_BOOL);
-        assert(!"FINISHME: Convert bool to int / uint.");
+        return new ir_expression(ir_unop_f2b, desired_type, src, NULL);
       }
    case GLSL_TYPE_FLOAT:
       switch (b) {
@@ -139,7 +168,7 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
       case GLSL_TYPE_INT:
         return new ir_expression(ir_unop_i2f, desired_type, src, NULL);
       case GLSL_TYPE_BOOL:
-        assert(!"FINISHME: Convert bool to float.");
+        return new ir_expression(ir_unop_b2f, desired_type, src, NULL);
       }
       break;
    case GLSL_TYPE_BOOL: {
@@ -233,7 +262,7 @@ process_array_constructor(exec_list *instructions,
 
    if (constructor_type->length == 0) {
       constructor_type =
-        glsl_type::get_array_instance(constructor_type->get_base_type(),
+        glsl_type::get_array_instance(constructor_type->element_type(),
                                       parameter_count);
       assert(constructor_type != NULL);
       assert(constructor_type->length == parameter_count);