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/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 9da8720..e2a0550 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -848,6 +848,17 @@
     return false;
 }
 
+bool OutputHLSL::visitSwizzle(Visit visit, TIntermSwizzle *node)
+{
+    TInfoSinkBase &out = getInfoSink();
+    if (visit == PostVisit)
+    {
+        out << ".";
+        node->writeOffsetsAsXYZW(&out);
+    }
+    return true;
+}
+
 bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
 {
     TInfoSinkBase &out = getInfoSink();
@@ -1066,42 +1077,6 @@
             return false;
         }
         break;
-      case EOpVectorSwizzle:
-        if (visit == InVisit)
-        {
-            out << ".";
-
-            TIntermAggregate *swizzle = node->getRight()->getAsAggregate();
-
-            if (swizzle)
-            {
-                TIntermSequence *sequence = swizzle->getSequence();
-
-                for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
-                {
-                    TIntermConstantUnion *element = (*sit)->getAsConstantUnion();
-
-                    if (element)
-                    {
-                        int i = element->getIConst(0);
-
-                        switch (i)
-                        {
-                        case 0: out << "x"; break;
-                        case 1: out << "y"; break;
-                        case 2: out << "z"; break;
-                        case 3: out << "w"; break;
-                        default: UNREACHABLE();
-                        }
-                    }
-                    else UNREACHABLE();
-                }
-            }
-            else UNREACHABLE();
-
-            return false;   // Fully processed
-        }
-        break;
       case EOpAdd:
           outputTriplet(out, visit, "(", " + ", ")");
           break;