reindent
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 16 Nov 2006 21:58:35 +0000 (21:58 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 16 Nov 2006 21:58:35 +0000 (21:58 +0000)
src/mesa/shader/slang/slang_assemble_typeinfo.c

index 58f4e24f256c13d81f35a1c92017540e441d9a42..340d6c1c585bed44a73ac07265b0a87c13849892 100644 (file)
  * slang_type_specifier
  */
 
-GLvoid slang_type_specifier_ctr (slang_type_specifier *self)
+GLvoid
+slang_type_specifier_ctr(slang_type_specifier * self)
 {
-       self->type = slang_spec_void;
-       self->_struct = NULL;
-       self->_array = NULL;
+   self->type = slang_spec_void;
+   self->_struct = NULL;
+   self->_array = NULL;
 }
 
-GLvoid slang_type_specifier_dtr (slang_type_specifier *self)
+GLvoid
+slang_type_specifier_dtr(slang_type_specifier * self)
 {
-       if (self->_struct != NULL)
-       {
-               slang_struct_destruct (self->_struct);
-               slang_alloc_free (self->_struct);
-       }
-       if (self->_array != NULL)
-       {
-               slang_type_specifier_dtr (self->_array);
-               slang_alloc_free (self->_array);
-       }
+   if (self->_struct != NULL) {
+      slang_struct_destruct(self->_struct);
+      slang_alloc_free(self->_struct);
+   }
+   if (self->_array != NULL) {
+      slang_type_specifier_dtr(self->_array);
+      slang_alloc_free(self->_array);
+   }
 }
 
-GLboolean slang_type_specifier_copy (slang_type_specifier *x, const slang_type_specifier *y)
+GLboolean
+slang_type_specifier_copy(slang_type_specifier * x,
+                          const slang_type_specifier * y)
 {
-       slang_type_specifier z;
-
-       slang_type_specifier_ctr (&z);
-       z.type = y->type;
-       if (z.type == slang_spec_struct)
-       {
-               z._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
-               if (z._struct == NULL)
-               {
-                       slang_type_specifier_dtr (&z);
-                       return GL_FALSE;
-               }
-               if (!slang_struct_construct (z._struct))
-               {
-                       slang_alloc_free (z._struct);
-                       slang_type_specifier_dtr (&z);
-                       return GL_FALSE;
-               }
-               if (!slang_struct_copy (z._struct, y->_struct))
-               {
-                       slang_type_specifier_dtr (&z);
-                       return GL_FALSE;
-               }
-       }
-       else if (z.type == slang_spec_array)
-       {
-               z._array = (slang_type_specifier *) slang_alloc_malloc (sizeof (slang_type_specifier));
-               if (z._array == NULL)
-               {
-                       slang_type_specifier_dtr (&z);
-                       return GL_FALSE;
-               }
-               slang_type_specifier_ctr (z._array);
-               if (!slang_type_specifier_copy (z._array, y->_array))
-               {
-                       slang_type_specifier_dtr (&z);
-                       return GL_FALSE;
-               }
-       }
-       slang_type_specifier_dtr (x);
-       *x = z;
-       return GL_TRUE;
+   slang_type_specifier z;
+
+   slang_type_specifier_ctr(&z);
+   z.type = y->type;
+   if (z.type == slang_spec_struct) {
+      z._struct = (slang_struct *) slang_alloc_malloc(sizeof(slang_struct));
+      if (z._struct == NULL) {
+         slang_type_specifier_dtr(&z);
+         return GL_FALSE;
+      }
+      if (!slang_struct_construct(z._struct)) {
+         slang_alloc_free(z._struct);
+         slang_type_specifier_dtr(&z);
+         return GL_FALSE;
+      }
+      if (!slang_struct_copy(z._struct, y->_struct)) {
+         slang_type_specifier_dtr(&z);
+         return GL_FALSE;
+      }
+   }
+   else if (z.type == slang_spec_array) {
+      z._array =
+         (slang_type_specifier *)
+         slang_alloc_malloc(sizeof(slang_type_specifier));
+      if (z._array == NULL) {
+         slang_type_specifier_dtr(&z);
+         return GL_FALSE;
+      }
+      slang_type_specifier_ctr(z._array);
+      if (!slang_type_specifier_copy(z._array, y->_array)) {
+         slang_type_specifier_dtr(&z);
+         return GL_FALSE;
+      }
+   }
+   slang_type_specifier_dtr(x);
+   *x = z;
+   return GL_TRUE;
 }
 
-GLboolean slang_type_specifier_equal (const slang_type_specifier *x, const slang_type_specifier *y)
+GLboolean
+slang_type_specifier_equal(const slang_type_specifier * x,
+                           const slang_type_specifier * y)
 {
-       if (x->type != y->type)
-               return 0;
-       if (x->type == slang_spec_struct)
-               return slang_struct_equal (x->_struct, y->_struct);
-       if (x->type == slang_spec_array)
-               return slang_type_specifier_equal (x->_array, y->_array);
-       return 1;
+   if (x->type != y->type)
+      return 0;
+   if (x->type == slang_spec_struct)
+      return slang_struct_equal(x->_struct, y->_struct);
+   if (x->type == slang_spec_array)
+      return slang_type_specifier_equal(x->_array, y->_array);
+   return 1;
 }
 
 /* slang_assembly_typeinfo */
 
-GLboolean slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti)
+GLboolean
+slang_assembly_typeinfo_construct(slang_assembly_typeinfo * ti)
 {
-       slang_type_specifier_ctr (&ti->spec);
-       ti->array_len = 0;
-       return GL_TRUE;
+   slang_type_specifier_ctr(&ti->spec);
+   ti->array_len = 0;
+   return GL_TRUE;
 }
 
-GLvoid slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *ti)
+GLvoid
+slang_assembly_typeinfo_destruct(slang_assembly_typeinfo * ti)
 {
-       slang_type_specifier_dtr (&ti->spec);
+   slang_type_specifier_dtr(&ti->spec);
 }
 
 /* _slang_typeof_operation() */
 
-static GLboolean typeof_existing_function (const char *name, slang_operation *params,
-       GLuint num_params, slang_assembly_name_space *space, slang_type_specifier *spec,
-       slang_atom_pool *atoms)
+static GLboolean
+typeof_existing_function(const char *name, slang_operation * params,
+                         GLuint num_params, slang_assembly_name_space * space,
+                         slang_type_specifier * spec, slang_atom_pool * atoms)
 {
-       slang_atom atom;
-       GLboolean exists;
-
-       atom = slang_atom_pool_atom (atoms, name);
-       if (!_slang_typeof_function (atom, params, num_params, space, spec, &exists, atoms))
-               return GL_FALSE;
-       return exists;
+   slang_atom atom;
+   GLboolean exists;
+
+   atom = slang_atom_pool_atom(atoms, name);
+   if (!_slang_typeof_function
+       (atom, params, num_params, space, spec, &exists, atoms))
+      return GL_FALSE;
+   return exists;
 }
 
-GLboolean _slang_typeof_operation (slang_assemble_ctx *A, slang_operation *op,
-       slang_assembly_typeinfo *ti)
+GLboolean
+_slang_typeof_operation(slang_assemble_ctx * A, slang_operation * op,
+                        slang_assembly_typeinfo * ti)
 {
-       return _slang_typeof_operation_ (op, &A->space, ti, A->atoms);
+   return _slang_typeof_operation_(op, &A->space, ti, A->atoms);
 }
 
-GLboolean _slang_typeof_operation_ (slang_operation *op, slang_assembly_name_space *space,
-       slang_assembly_typeinfo *ti, slang_atom_pool *atoms)
+GLboolean
+_slang_typeof_operation_(slang_operation * op,
+                         slang_assembly_name_space * space,
+                         slang_assembly_typeinfo * ti,
+                         slang_atom_pool * atoms)
 {
-       ti->can_be_referenced = GL_FALSE;
-       ti->is_swizzled = GL_FALSE;
-
-       switch (op->type)
-       {
-       case slang_oper_block_no_new_scope:
-       case slang_oper_block_new_scope:
-       case slang_oper_variable_decl:
-       case slang_oper_asm:
-       case slang_oper_break:
-       case slang_oper_continue:
-       case slang_oper_discard:
-       case slang_oper_return:
-       case slang_oper_if:
-       case slang_oper_while:
-       case slang_oper_do:
-       case slang_oper_for:
-       case slang_oper_void:
-               ti->spec.type = slang_spec_void;
-               break;
-       case slang_oper_expression:
-       case slang_oper_assign:
-       case slang_oper_addassign:
-       case slang_oper_subassign:
-       case slang_oper_mulassign:
-       case slang_oper_divassign:
-       case slang_oper_preincrement:
-       case slang_oper_predecrement:
-               if (!_slang_typeof_operation_ (op->children, space, ti, atoms))
-                       return 0;
-               break;
-       case slang_oper_literal_bool:
-       case slang_oper_logicalor:
-       case slang_oper_logicalxor:
-       case slang_oper_logicaland:
-       case slang_oper_equal:
-       case slang_oper_notequal:
-       case slang_oper_less:
-       case slang_oper_greater:
-       case slang_oper_lessequal:
-       case slang_oper_greaterequal:
-       case slang_oper_not:
-               ti->spec.type = slang_spec_bool;
-               break;
-       case slang_oper_literal_int:
-               ti->spec.type = slang_spec_int;
-               break;
-       case slang_oper_literal_float:
-               ti->spec.type = slang_spec_float;
-               break;
-       case slang_oper_identifier:
-               {
-                       slang_variable *var;
-
-                       var = _slang_locate_variable (op->locals, op->a_id, GL_TRUE);
-                       if (var == NULL)
-                               return GL_FALSE;
-                       if (!slang_type_specifier_copy (&ti->spec, &var->type.specifier))
-                               return GL_FALSE;
-                       ti->can_be_referenced = GL_TRUE;
-                       ti->array_len = var->array_len;
-               }
-               break;
-       case slang_oper_sequence:
-               /* TODO: check [0] and [1] if they match */
-               if (!_slang_typeof_operation_ (&op->children[1], space, ti, atoms))
-                       return GL_FALSE;
-               ti->can_be_referenced = GL_FALSE;
-               ti->is_swizzled = GL_FALSE;
-               break;
-       /*case slang_oper_modassign:*/
-       /*case slang_oper_lshassign:*/
-       /*case slang_oper_rshassign:*/
-       /*case slang_oper_orassign:*/
-       /*case slang_oper_xorassign:*/
-       /*case slang_oper_andassign:*/
-       case slang_oper_select:
-               /* TODO: check [1] and [2] if they match */
-               if (!_slang_typeof_operation_ (&op->children[1], space, ti, atoms))
-                       return GL_FALSE;
-               ti->can_be_referenced = GL_FALSE;
-               ti->is_swizzled = GL_FALSE;
-               break;
-       /*case slang_oper_bitor:*/
-       /*case slang_oper_bitxor:*/
-       /*case slang_oper_bitand:*/
-       /*case slang_oper_lshift:*/
-       /*case slang_oper_rshift:*/
-       case slang_oper_add:
-               if (!typeof_existing_function ("+", op->children, 2, space, &ti->spec, atoms))
-                       return GL_FALSE;
-               break;
-       case slang_oper_subtract:
-               if (!typeof_existing_function ("-", op->children, 2, space, &ti->spec, atoms))
-                       return GL_FALSE;
-               break;
-       case slang_oper_multiply:
-               if (!typeof_existing_function ("*", op->children, 2, space, &ti->spec, atoms))
-                       return GL_FALSE;
-               break;
-       case slang_oper_divide:
-               if (!typeof_existing_function ("/", op->children, 2, space, &ti->spec, atoms))
-                       return GL_FALSE;
-               break;
-       /*case slang_oper_modulus:*/
-       case slang_oper_plus:
-               if (!_slang_typeof_operation_ (op->children, space, ti, atoms))
-                       return GL_FALSE;
-               ti->can_be_referenced = GL_FALSE;
-               ti->is_swizzled = GL_FALSE;
-               break;
-       case slang_oper_minus:
-               if (!typeof_existing_function ("-", op->children, 1, space, &ti->spec, atoms))
-                       return GL_FALSE;
-               break;
-       /*case slang_oper_complement:*/
-       case slang_oper_subscript:
-               {
-                       slang_assembly_typeinfo _ti;
-
-                       if (!slang_assembly_typeinfo_construct (&_ti))
-                               return GL_FALSE;
-                       if (!_slang_typeof_operation_ (op->children, space, &_ti, atoms))
-                       {
-                               slang_assembly_typeinfo_destruct (&_ti);
-                               return GL_FALSE;
-                       }
-                       ti->can_be_referenced = _ti.can_be_referenced;
-                       if (_ti.spec.type == slang_spec_array)
-                       {
-                               if (!slang_type_specifier_copy (&ti->spec, _ti.spec._array))
-                               {
-                                       slang_assembly_typeinfo_destruct (&_ti);
-                                       return GL_FALSE;
-                               }
-                       }
-                       else
-                       {
-                               if (!_slang_type_is_vector (_ti.spec.type) && !_slang_type_is_matrix (_ti.spec.type))
-                               {
-                                       slang_assembly_typeinfo_destruct (&_ti);
-                                       return GL_FALSE;
-                               }
-                               ti->spec.type = _slang_type_base (_ti.spec.type);
-                       }
-                       slang_assembly_typeinfo_destruct (&_ti);
-               }
-               break;
-       case slang_oper_call:
-               {
-                       GLboolean exists;
-
-                       if (!_slang_typeof_function (op->a_id, op->children, op->num_children, space, &ti->spec,
-                                       &exists, atoms))
-                               return GL_FALSE;
-                       if (!exists)
-                       {
-                               slang_struct *s = slang_struct_scope_find (space->structs, op->a_id, GL_TRUE);
-                               if (s != NULL)
-                               {
-                                       ti->spec.type = slang_spec_struct;
-                                       ti->spec._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct));
-                                       if (ti->spec._struct == NULL)
-                                               return GL_FALSE;
-                                       if (!slang_struct_construct (ti->spec._struct))
-                                       {
-                                               slang_alloc_free (ti->spec._struct);
-                                               ti->spec._struct = NULL;
-                                               return GL_FALSE;
-                                       }
-                                       if (!slang_struct_copy (ti->spec._struct, s))
-                                               return GL_FALSE;
-                               }
-                               else
-                               {
-                                       const char *name;
-                                       slang_type_specifier_type type;
-
-                                       name = slang_atom_pool_id (atoms, op->a_id);
-                                       type = slang_type_specifier_type_from_string (name);
-                                       if (type == slang_spec_void)
-                                               return GL_FALSE;
-                                       ti->spec.type = type;
-                               }
-                       }
-               }
-               break;
-       case slang_oper_field:
-               {
-                       slang_assembly_typeinfo _ti;
-
-                       if (!slang_assembly_typeinfo_construct (&_ti))
-                               return GL_FALSE;
-                       if (!_slang_typeof_operation_ (op->children, space, &_ti, atoms))
-                       {
-                               slang_assembly_typeinfo_destruct (&_ti);
-                               return GL_FALSE;
-                       }
-                       if (_ti.spec.type == slang_spec_struct)
-                       {
-                               slang_variable *field;
-                               
-                               field = _slang_locate_variable (_ti.spec._struct->fields, op->a_id, GL_FALSE);
-                               if (field == NULL)
-                               {
-                                       slang_assembly_typeinfo_destruct (&_ti);
-                                       return GL_FALSE;
-                               }
-                               if (!slang_type_specifier_copy (&ti->spec, &field->type.specifier))
-                               {
-                                       slang_assembly_typeinfo_destruct (&_ti);
-                                       return GL_FALSE;
-                               }
-                               ti->can_be_referenced = _ti.can_be_referenced;
-                       }
-                       else
-                       {
-                               GLuint rows;
-                               const char *swizzle;
-                               slang_type_specifier_type base;
-
-                               /* determine the swizzle of the field expression */
-                               if (!_slang_type_is_vector (_ti.spec.type))
-                               {
-                                       slang_assembly_typeinfo_destruct (&_ti);
-                                       return GL_FALSE;
-                               }
-                               rows = _slang_type_dim (_ti.spec.type);
-                               swizzle = slang_atom_pool_id (atoms, op->a_id);
-                               if (!_slang_is_swizzle (swizzle, rows, &ti->swz))
-                               {
-                                       slang_assembly_typeinfo_destruct (&_ti);
-                                       return GL_FALSE;
-                               }
-                               ti->is_swizzled = GL_TRUE;
-                               ti->can_be_referenced = _ti.can_be_referenced && _slang_is_swizzle_mask (&ti->swz,
-                                       rows);
-                               if (_ti.is_swizzled)
-                               {
-                                       slang_swizzle swz;
-
-                                       /* swizzle the swizzle */
-                                       _slang_multiply_swizzles (&swz, &_ti.swz, &ti->swz);
-                                       ti->swz = swz;
-                               }
-                               base = _slang_type_base (_ti.spec.type);
-                               switch (ti->swz.num_components)
-                               {
-                               case 1:
-                                       ti->spec.type = base;
-                                       break;
-                               case 2:
-                                       switch (base)
-                                       {
-                                       case slang_spec_float:
-                                               ti->spec.type = slang_spec_vec2;
-                                               break;
-                                       case slang_spec_int:
-                                               ti->spec.type = slang_spec_ivec2;
-                                               break;
-                                       case slang_spec_bool:
-                                               ti->spec.type = slang_spec_bvec2;
-                                               break;
-                                       default:
-                                               break;
-                                       }
-                                       break;
-                               case 3:
-                                       switch (base)
-                                       {
-                                       case slang_spec_float:
-                                               ti->spec.type = slang_spec_vec3;
-                                               break;
-                                       case slang_spec_int:
-                                               ti->spec.type = slang_spec_ivec3;
-                                               break;
-                                       case slang_spec_bool:
-                                               ti->spec.type = slang_spec_bvec3;
-                                               break;
-                                       default:
-                                               break;
-                                       }
-                                       break;
-                               case 4:
-                                       switch (base)
-                                       {
-                                       case slang_spec_float:
-                                               ti->spec.type = slang_spec_vec4;
-                                               break;
-                                       case slang_spec_int:
-                                               ti->spec.type = slang_spec_ivec4;
-                                               break;
-                                       case slang_spec_bool:
-                                               ti->spec.type = slang_spec_bvec4;
-                                               break;
-                                       default:
-                                               break;
-                                       }
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       slang_assembly_typeinfo_destruct (&_ti);
-               }
-               break;
-       case slang_oper_postincrement:
-       case slang_oper_postdecrement:
-               if (!_slang_typeof_operation_ (op->children, space, ti, atoms))
-                       return GL_FALSE;
-               ti->can_be_referenced = GL_FALSE;
-               ti->is_swizzled = GL_FALSE;
-               break;
-       default:
-               return GL_FALSE;
-       }
-
-       return GL_TRUE;
+   ti->can_be_referenced = GL_FALSE;
+   ti->is_swizzled = GL_FALSE;
+
+   switch (op->type) {
+   case slang_oper_block_no_new_scope:
+   case slang_oper_block_new_scope:
+   case slang_oper_variable_decl:
+   case slang_oper_asm:
+   case slang_oper_break:
+   case slang_oper_continue:
+   case slang_oper_discard:
+   case slang_oper_return:
+   case slang_oper_if:
+   case slang_oper_while:
+   case slang_oper_do:
+   case slang_oper_for:
+   case slang_oper_void:
+      ti->spec.type = slang_spec_void;
+      break;
+   case slang_oper_expression:
+   case slang_oper_assign:
+   case slang_oper_addassign:
+   case slang_oper_subassign:
+   case slang_oper_mulassign:
+   case slang_oper_divassign:
+   case slang_oper_preincrement:
+   case slang_oper_predecrement:
+      if (!_slang_typeof_operation_(op->children, space, ti, atoms))
+         return 0;
+      break;
+   case slang_oper_literal_bool:
+   case slang_oper_logicalor:
+   case slang_oper_logicalxor:
+   case slang_oper_logicaland:
+   case slang_oper_equal:
+   case slang_oper_notequal:
+   case slang_oper_less:
+   case slang_oper_greater:
+   case slang_oper_lessequal:
+   case slang_oper_greaterequal:
+   case slang_oper_not:
+      ti->spec.type = slang_spec_bool;
+      break;
+   case slang_oper_literal_int:
+      ti->spec.type = slang_spec_int;
+      break;
+   case slang_oper_literal_float:
+      ti->spec.type = slang_spec_float;
+      break;
+   case slang_oper_identifier:
+      {
+         slang_variable *var;
+
+         var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE);
+         if (var == NULL)
+            return GL_FALSE;
+         if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier))
+            return GL_FALSE;
+         ti->can_be_referenced = GL_TRUE;
+         ti->array_len = var->array_len;
+      }
+      break;
+   case slang_oper_sequence:
+      /* TODO: check [0] and [1] if they match */
+      if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms))
+         return GL_FALSE;
+      ti->can_be_referenced = GL_FALSE;
+      ti->is_swizzled = GL_FALSE;
+      break;
+      /*case slang_oper_modassign: */
+      /*case slang_oper_lshassign: */
+      /*case slang_oper_rshassign: */
+      /*case slang_oper_orassign: */
+      /*case slang_oper_xorassign: */
+      /*case slang_oper_andassign: */
+   case slang_oper_select:
+      /* TODO: check [1] and [2] if they match */
+      if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms))
+         return GL_FALSE;
+      ti->can_be_referenced = GL_FALSE;
+      ti->is_swizzled = GL_FALSE;
+      break;
+      /*case slang_oper_bitor: */
+      /*case slang_oper_bitxor: */
+      /*case slang_oper_bitand: */
+      /*case slang_oper_lshift: */
+      /*case slang_oper_rshift: */
+   case slang_oper_add:
+      if (!typeof_existing_function
+          ("+", op->children, 2, space, &ti->spec, atoms))
+         return GL_FALSE;
+      break;
+   case slang_oper_subtract:
+      if (!typeof_existing_function
+          ("-", op->children, 2, space, &ti->spec, atoms))
+         return GL_FALSE;
+      break;
+   case slang_oper_multiply:
+      if (!typeof_existing_function
+          ("*", op->children, 2, space, &ti->spec, atoms))
+         return GL_FALSE;
+      break;
+   case slang_oper_divide:
+      if (!typeof_existing_function
+          ("/", op->children, 2, space, &ti->spec, atoms))
+         return GL_FALSE;
+      break;
+      /*case slang_oper_modulus: */
+   case slang_oper_plus:
+      if (!_slang_typeof_operation_(op->children, space, ti, atoms))
+         return GL_FALSE;
+      ti->can_be_referenced = GL_FALSE;
+      ti->is_swizzled = GL_FALSE;
+      break;
+   case slang_oper_minus:
+      if (!typeof_existing_function
+          ("-", op->children, 1, space, &ti->spec, atoms))
+         return GL_FALSE;
+      break;
+      /*case slang_oper_complement: */
+   case slang_oper_subscript:
+      {
+         slang_assembly_typeinfo _ti;
+
+         if (!slang_assembly_typeinfo_construct(&_ti))
+            return GL_FALSE;
+         if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) {
+            slang_assembly_typeinfo_destruct(&_ti);
+            return GL_FALSE;
+         }
+         ti->can_be_referenced = _ti.can_be_referenced;
+         if (_ti.spec.type == slang_spec_array) {
+            if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) {
+               slang_assembly_typeinfo_destruct(&_ti);
+               return GL_FALSE;
+            }
+         }
+         else {
+            if (!_slang_type_is_vector(_ti.spec.type)
+                && !_slang_type_is_matrix(_ti.spec.type)) {
+               slang_assembly_typeinfo_destruct(&_ti);
+               return GL_FALSE;
+            }
+            ti->spec.type = _slang_type_base(_ti.spec.type);
+         }
+         slang_assembly_typeinfo_destruct(&_ti);
+      }
+      break;
+   case slang_oper_call:
+      {
+         GLboolean exists;
+
+         if (!_slang_typeof_function
+             (op->a_id, op->children, op->num_children, space, &ti->spec,
+              &exists, atoms))
+            return GL_FALSE;
+         if (!exists) {
+            slang_struct *s =
+               slang_struct_scope_find(space->structs, op->a_id, GL_TRUE);
+            if (s != NULL) {
+               ti->spec.type = slang_spec_struct;
+               ti->spec._struct =
+                  (slang_struct *) slang_alloc_malloc(sizeof(slang_struct));
+               if (ti->spec._struct == NULL)
+                  return GL_FALSE;
+               if (!slang_struct_construct(ti->spec._struct)) {
+                  slang_alloc_free(ti->spec._struct);
+                  ti->spec._struct = NULL;
+                  return GL_FALSE;
+               }
+               if (!slang_struct_copy(ti->spec._struct, s))
+                  return GL_FALSE;
+            }
+            else {
+               const char *name;
+               slang_type_specifier_type type;
+
+               name = slang_atom_pool_id(atoms, op->a_id);
+               type = slang_type_specifier_type_from_string(name);
+               if (type == slang_spec_void)
+                  return GL_FALSE;
+               ti->spec.type = type;
+            }
+         }
+      }
+      break;
+   case slang_oper_field:
+      {
+         slang_assembly_typeinfo _ti;
+
+         if (!slang_assembly_typeinfo_construct(&_ti))
+            return GL_FALSE;
+         if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) {
+            slang_assembly_typeinfo_destruct(&_ti);
+            return GL_FALSE;
+         }
+         if (_ti.spec.type == slang_spec_struct) {
+            slang_variable *field;
+
+            field =
+               _slang_locate_variable(_ti.spec._struct->fields, op->a_id,
+                                      GL_FALSE);
+            if (field == NULL) {
+               slang_assembly_typeinfo_destruct(&_ti);
+               return GL_FALSE;
+            }
+            if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) {
+               slang_assembly_typeinfo_destruct(&_ti);
+               return GL_FALSE;
+            }
+            ti->can_be_referenced = _ti.can_be_referenced;
+         }
+         else {
+            GLuint rows;
+            const char *swizzle;
+            slang_type_specifier_type base;
+
+            /* determine the swizzle of the field expression */
+            if (!_slang_type_is_vector(_ti.spec.type)) {
+               slang_assembly_typeinfo_destruct(&_ti);
+               return GL_FALSE;
+            }
+            rows = _slang_type_dim(_ti.spec.type);
+            swizzle = slang_atom_pool_id(atoms, op->a_id);
+            if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) {
+               slang_assembly_typeinfo_destruct(&_ti);
+               return GL_FALSE;
+            }
+            ti->is_swizzled = GL_TRUE;
+            ti->can_be_referenced = _ti.can_be_referenced
+               && _slang_is_swizzle_mask(&ti->swz, rows);
+            if (_ti.is_swizzled) {
+               slang_swizzle swz;
+
+               /* swizzle the swizzle */
+               _slang_multiply_swizzles(&swz, &_ti.swz, &ti->swz);
+               ti->swz = swz;
+            }
+            base = _slang_type_base(_ti.spec.type);
+            switch (ti->swz.num_components) {
+            case 1:
+               ti->spec.type = base;
+               break;
+            case 2:
+               switch (base) {
+               case slang_spec_float:
+                  ti->spec.type = slang_spec_vec2;
+                  break;
+               case slang_spec_int:
+                  ti->spec.type = slang_spec_ivec2;
+                  break;
+               case slang_spec_bool:
+                  ti->spec.type = slang_spec_bvec2;
+                  break;
+               default:
+                  break;
+               }
+               break;
+            case 3:
+               switch (base) {
+               case slang_spec_float:
+                  ti->spec.type = slang_spec_vec3;
+                  break;
+               case slang_spec_int:
+                  ti->spec.type = slang_spec_ivec3;
+                  break;
+               case slang_spec_bool:
+                  ti->spec.type = slang_spec_bvec3;
+                  break;
+               default:
+                  break;
+               }
+               break;
+            case 4:
+               switch (base) {
+               case slang_spec_float:
+                  ti->spec.type = slang_spec_vec4;
+                  break;
+               case slang_spec_int:
+                  ti->spec.type = slang_spec_ivec4;
+                  break;
+               case slang_spec_bool:
+                  ti->spec.type = slang_spec_bvec4;
+                  break;
+               default:
+                  break;
+               }
+               break;
+            default:
+               break;
+            }
+         }
+         slang_assembly_typeinfo_destruct(&_ti);
+      }
+      break;
+   case slang_oper_postincrement:
+   case slang_oper_postdecrement:
+      if (!_slang_typeof_operation_(op->children, space, ti, atoms))
+         return GL_FALSE;
+      ti->can_be_referenced = GL_FALSE;
+      ti->is_swizzled = GL_FALSE;
+      break;
+   default:
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
 }
 
 /* _slang_typeof_function() */
 
-GLboolean _slang_typeof_function (slang_atom a_name, slang_operation *params, GLuint num_params,
-       slang_assembly_name_space *space, slang_type_specifier *spec, GLboolean *exists,
-       slang_atom_pool *atoms)
+GLboolean
+_slang_typeof_function(slang_atom a_name, slang_operation * params,
+                       GLuint num_params, slang_assembly_name_space * space,
+                       slang_type_specifier * spec, GLboolean * exists,
+                       slang_atom_pool * atoms)
 {
-       slang_function *fun;
-       
-       fun = _slang_locate_function (space->funcs, a_name, params, num_params, space, atoms);
-       *exists = fun != NULL;
-       if (fun == NULL)
-               return GL_TRUE;
-       return slang_type_specifier_copy (spec, &fun->header.type.specifier);
+   slang_function *fun;
+
+   fun =
+      _slang_locate_function(space->funcs, a_name, params, num_params, space,
+                             atoms);
+   *exists = fun != NULL;
+   if (fun == NULL)
+      return GL_TRUE;
+   return slang_type_specifier_copy(spec, &fun->header.type.specifier);
 }
 
 /* _slang_type_is_matrix() */
 
-GLboolean _slang_type_is_matrix (slang_type_specifier_type ty)
+GLboolean
+_slang_type_is_matrix(slang_type_specifier_type ty)
 {
-       switch (ty)
-       {
-       case slang_spec_mat2:
-       case slang_spec_mat3:
-       case slang_spec_mat4:
-               return GL_TRUE;
-       default:
-               return GL_FALSE;
-       }
+   switch (ty) {
+   case slang_spec_mat2:
+   case slang_spec_mat3:
+   case slang_spec_mat4:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
 }
 
 /* _slang_type_is_vector() */
 
-GLboolean _slang_type_is_vector (slang_type_specifier_type ty)
+GLboolean
+_slang_type_is_vector(slang_type_specifier_type ty)
 {
-       switch (ty)
-       {
-       case slang_spec_vec2:
-       case slang_spec_vec3:
-       case slang_spec_vec4:
-       case slang_spec_ivec2:
-       case slang_spec_ivec3:
-       case slang_spec_ivec4:
-       case slang_spec_bvec2:
-       case slang_spec_bvec3:
-       case slang_spec_bvec4:
-               return GL_TRUE;
-       default:
-               return GL_FALSE;
-       }
+   switch (ty) {
+   case slang_spec_vec2:
+   case slang_spec_vec3:
+   case slang_spec_vec4:
+   case slang_spec_ivec2:
+   case slang_spec_ivec3:
+   case slang_spec_ivec4:
+   case slang_spec_bvec2:
+   case slang_spec_bvec3:
+   case slang_spec_bvec4:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
 }
 
 /* _slang_type_base_of_vector() */
 
-slang_type_specifier_type _slang_type_base (slang_type_specifier_type ty)
+slang_type_specifier_type
+_slang_type_base(slang_type_specifier_type ty)
 {
-       switch (ty)
-       {
-       case slang_spec_float:
-       case slang_spec_vec2:
-       case slang_spec_vec3:
-       case slang_spec_vec4:
-               return slang_spec_float;
-       case slang_spec_int:
-       case slang_spec_ivec2:
-       case slang_spec_ivec3:
-       case slang_spec_ivec4:
-               return slang_spec_int;
-       case slang_spec_bool:
-       case slang_spec_bvec2:
-       case slang_spec_bvec3:
-       case slang_spec_bvec4:
-               return slang_spec_bool;
-       case slang_spec_mat2:
-               return slang_spec_vec2;
-       case slang_spec_mat3:
-               return slang_spec_vec3;
-       case slang_spec_mat4:
-               return slang_spec_vec4;
-       default:
-               return slang_spec_void;
-       }
+   switch (ty) {
+   case slang_spec_float:
+   case slang_spec_vec2:
+   case slang_spec_vec3:
+   case slang_spec_vec4:
+      return slang_spec_float;
+   case slang_spec_int:
+   case slang_spec_ivec2:
+   case slang_spec_ivec3:
+   case slang_spec_ivec4:
+      return slang_spec_int;
+   case slang_spec_bool:
+   case slang_spec_bvec2:
+   case slang_spec_bvec3:
+   case slang_spec_bvec4:
+      return slang_spec_bool;
+   case slang_spec_mat2:
+      return slang_spec_vec2;
+   case slang_spec_mat3:
+      return slang_spec_vec3;
+   case slang_spec_mat4:
+      return slang_spec_vec4;
+   default:
+      return slang_spec_void;
+   }
 }
 
 /* _slang_type_dim */
 
-GLuint _slang_type_dim (slang_type_specifier_type ty)
+GLuint
+_slang_type_dim(slang_type_specifier_type ty)
 {
-       switch (ty)
-       {
-       case slang_spec_float:
-       case slang_spec_int:
-       case slang_spec_bool:
-               return 1;
-       case slang_spec_vec2:
-       case slang_spec_ivec2:
-       case slang_spec_bvec2:
-       case slang_spec_mat2:
-               return 2;
-       case slang_spec_vec3:
-       case slang_spec_ivec3:
-       case slang_spec_bvec3:
-       case slang_spec_mat3:
-               return 3;
-       case slang_spec_vec4:
-       case slang_spec_ivec4:
-       case slang_spec_bvec4:
-       case slang_spec_mat4:
-               return 4;
-       default:
-               return 0;
-       }
+   switch (ty) {
+   case slang_spec_float:
+   case slang_spec_int:
+   case slang_spec_bool:
+      return 1;
+   case slang_spec_vec2:
+   case slang_spec_ivec2:
+   case slang_spec_bvec2:
+   case slang_spec_mat2:
+      return 2;
+   case slang_spec_vec3:
+   case slang_spec_ivec3:
+   case slang_spec_bvec3:
+   case slang_spec_mat3:
+      return 3;
+   case slang_spec_vec4:
+   case slang_spec_ivec4:
+   case slang_spec_bvec4:
+   case slang_spec_mat4:
+      return 4;
+   default:
+      return 0;
+   }
 }
-