Split ternary node class from TIntermSelection

Ternary operator nodes are typed parts of expressions, they always
have two children and the children are also guaranteed to be
TIntermTyped. "If" selection nodes can't be a part of an expression,
they can have either one or two children and the children are code
blocks. Due to all of these differences it makes sense to store these
using two different AST node classes.

BUG=angleproject:1490
TEST=angle_unittests

Change-Id: I913ab1d806e3cdb5c21106f078cc9c0b6c72ac54
Reviewed-on: https://chromium-review.googlesource.com/384512
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 6391782..9d77da2 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -1456,9 +1456,8 @@
                 // case statements into non-empty case statements, disallowing fall-through from them.
                 // Also no need to output ; after selection (if) statements or sequences. This is done just
                 // for code clarity.
-                TIntermSelection *asSelection = (*sit)->getAsSelectionNode();
-                ASSERT(asSelection == nullptr || !asSelection->usesTernaryOperator());
-                if ((*sit)->getAsCaseNode() == nullptr && asSelection == nullptr && !IsSequence(*sit))
+                if ((*sit)->getAsCaseNode() == nullptr && (*sit)->getAsSelectionNode() == nullptr &&
+                    !IsSequence(*sit))
                     out << ";\n";
             }
 
@@ -1982,11 +1981,18 @@
     }
 }
 
+bool OutputHLSL::visitTernary(Visit, TIntermTernary *)
+{
+    // Ternary ops should have been already converted to something else in the AST. HLSL ternary
+    // operator doesn't short-circuit, so it's not the same as the GLSL ternary operator.
+    UNREACHABLE();
+    return false;
+}
+
 bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
 {
     TInfoSinkBase &out = getInfoSink();
 
-    ASSERT(!node->usesTernaryOperator());
     ASSERT(mInsideFunction);
 
     // D3D errors when there is a gradient operation in a loop in an unflattened if.