Add functions to generate constructors for built-in types.
[mesa.git] / hir_field_selection.cpp
index 1dd81264407ac182b491db6c197ec82e71682385..5f548bfa0f87f55e669e3f1f6df4f2475eab4cba 100644 (file)
@@ -34,7 +34,7 @@
 #define I 13
 
 static bool
-generate_swizzle(const char *str, struct ir_swizzle_mask *swiz,
+generate_swizzle(const char *str, ir_dereference *deref,
                 unsigned vector_length)
 {
    /* For each possible swizzle character, this table encodes the value in
@@ -42,7 +42,7 @@ generate_swizzle(const char *str, struct ir_swizzle_mask *swiz,
     * swizzle characters (e.g., 'k'), a special value is used that will allow
     * detection of errors.
     */
-   unsigned char base_idx[26] = {
+   static const unsigned char base_idx[26] = {
    /* a  b  c  d  e  f  g  h  i  j  k  l  m */
       R, R, I, I, I, I, R, I, I, I, I, I, I,
    /* n  o  p  q  r  s  t  u  v  w  x  y  z */
@@ -66,7 +66,7 @@ generate_swizzle(const char *str, struct ir_swizzle_mask *swiz,
     * swizzle values are { 3, 2, 4, 5 }.  Since 4 and 5 are outside the range
     * [0,3], the error is detected.
     */
-   unsigned char idx_map[26] = {
+   static const unsigned char idx_map[26] = {
    /* a    b    c    d    e    f    g    h    i    j    k    l    m */
       R+3, R+2, 0,   0,   0,   0,   R+1, 0,   0,   0,   0,   0,   0,
    /* n    o    p    q    r    s    t    u    v    w    x    y    z */
@@ -74,9 +74,6 @@ generate_swizzle(const char *str, struct ir_swizzle_mask *swiz,
    };
 
    int swiz_idx[4] = { 0, 0, 0, 0 };
-   unsigned base;
-   unsigned dup_mask = 0;
-   unsigned seen_mask = 0;
    unsigned i;
 
 
@@ -86,48 +83,32 @@ generate_swizzle(const char *str, struct ir_swizzle_mask *swiz,
    if ((str[0] < 'a') || (str[0] > 'z'))
       return false;
 
-   base = base_idx[str[0] - 'a'];
+   const unsigned base = base_idx[str[0] - 'a'];
 
 
    for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
-      unsigned bit;
-
       /* Validate the next character, and, as described above, convert it to a
        * swizzle index.
        */
       if ((str[i] < 'a') || (str[i] > 'z'))
         return false;
 
-      swiz_idx[i] = idx_map[str[0] - 'a'] - base;
+      swiz_idx[i] = idx_map[str[i] - 'a'] - base;
       if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
         return false;
-
-
-      /* Track a bit-mask of the swizzle index values that have been seen.  If
-       * a value is seen more than once, set the "duplicate" flag.
-       */
-      bit = (1U << swiz_idx[i]);
-      dup_mask |= seen_mask & bit;
-      seen_mask |= bit;
    }
 
    if (str[i] != '\0')
         return false;
 
-   swiz->x = swiz_idx[0];
-   swiz->y = swiz_idx[1];
-   swiz->z = swiz_idx[2];
-   swiz->w = swiz_idx[3];
-   swiz->num_components = i;
-   swiz->has_duplicates = (dup_mask != 0);
-
+   deref->set_swizzle(swiz_idx[0], swiz_idx[1], swiz_idx[2], swiz_idx[3], i);
    return true;
 }
 
 
 struct ir_instruction *
 _mesa_ast_field_selection_to_hir(const ast_expression *expr,
-                                simple_node *instructions,
+                                exec_list *instructions,
                                 struct _mesa_glsl_parse_state *state)
 {
    ir_instruction *op;
@@ -156,17 +137,17 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
     * being applied.
     */
    loc = expr->get_location();
-   if (is_glsl_type_vector(op->type)) {
+   if (op->type->is_vector()) {
       if (generate_swizzle(expr->primary_expression.identifier, 
-                          & deref->selector.swizzle,
-                          op->type->vector_elements)) {
+                          deref, op->type->vector_elements)) {
         /* Based on the number of elements in the swizzle and the base type
          * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
          * generate the type of the resulting value.
          */
         deref->type =
-           _mesa_glsl_get_vector_type(op->type->base_type,
-                                      deref->selector.swizzle.num_components);
+           glsl_type::get_instance(op->type->base_type,
+                                   deref->selector.swizzle.num_components,
+                                   1);
       } else {
         /* FINISHME: Logging of error messages should be moved into
          * FINISHME: generate_swizzle.  This allows the generation of more