Split vector swizzle AST nodes into a different node class

This avoids creating a weird aggregate node with a sequence of
constant union nodes to store the offsets. They're stored neatly
inside a vector instead. This makes code that needs to iterate
over the swizzle offsets much simpler.

BUG=angleproject:1490
TEST=angle_unittests

Change-Id: I156b95723529ee05a94d30295ffb6d0952a98564
Reviewed-on: https://chromium-review.googlesource.com/390832
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index e67f0d0..458f9a5 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -247,6 +247,18 @@
 {
     TIntermSymbol *symNode    = node->getAsSymbolNode();
     TIntermBinary *binaryNode = node->getAsBinaryNode();
+    TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+
+    if (swizzleNode)
+    {
+        bool ok = checkCanBeLValue(line, op, swizzleNode->getOperand());
+        if (ok && swizzleNode->hasDuplicateOffsets())
+        {
+            error(line, " l-value of swizzle cannot have duplicate components", op);
+            return false;
+        }
+        return ok;
+    }
 
     if (binaryNode)
     {
@@ -257,34 +269,10 @@
             case EOpIndexDirectStruct:
             case EOpIndexDirectInterfaceBlock:
                 return checkCanBeLValue(line, op, binaryNode->getLeft());
-            case EOpVectorSwizzle:
-            {
-                bool ok = checkCanBeLValue(line, op, binaryNode->getLeft());
-                if (ok)
-                {
-                    int offsetCount[4] = {0, 0, 0, 0};
-
-                    TIntermAggregate *swizzleOffsets = binaryNode->getRight()->getAsAggregate();
-
-                    for (const auto &offset : *swizzleOffsets->getSequence())
-                    {
-                        int value = offset->getAsTyped()->getAsConstantUnion()->getIConst(0);
-                        offsetCount[value]++;
-                        if (offsetCount[value] > 1)
-                        {
-                            error(line, " l-value of swizzle cannot have duplicate components", op);
-                            return false;
-                        }
-                    }
-                }
-
-                return ok;
-            }
             default:
                 break;
         }
         error(line, " l-value required", op);
-
         return false;
     }
 
@@ -2770,9 +2758,7 @@
             fields.offsets[0] = 0;
         }
 
-        TIntermTyped *index = intermediate.addSwizzle(fields, fieldLocation);
-        return intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation,
-                                     &mDiagnostics);
+        return TIntermediate::AddSwizzle(baseExpression, fields, dotLocation);
     }
     else if (baseExpression->getBasicType() == EbtStruct)
     {