SPV: Implement specialization constants for ?:.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index bf26cdc..02609d0 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -1775,7 +1775,7 @@
 
         // return true if a single operand to ? : is okay for OpSelect
         const auto operandOkay = [](glslang::TIntermTyped* node) {
-            return node->getAsSymbolNode() || node->getAsConstantUnion();
+            return node->getAsSymbolNode() || node->getType().getQualifier().isConstant();
         };
 
         return operandOkay(node->getTrueBlock() ->getAsTyped()) &&
@@ -1799,6 +1799,10 @@
     // Try for OpSelect
 
     if (selectPolicy()) {
+        SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
+        if (node->getType().getQualifier().isSpecConstant())
+            spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
+
         handleAsOpSelect();
         return false;
     }
diff --git a/Test/baseResults/spv.specConstantOperations.vert.out b/Test/baseResults/spv.specConstantOperations.vert.out
index d6da726..597820b 100644
--- a/Test/baseResults/spv.specConstantOperations.vert.out
+++ b/Test/baseResults/spv.specConstantOperations.vert.out
@@ -3,7 +3,7 @@
 
 // Module Version 10000
 // Generated by (magic number): 80001
-// Id's are bound by 135
+// Id's are bound by 160
 
                               Capability Shader
                               Capability Float64
@@ -20,11 +20,18 @@
                               Name 42  "sp_uint"
                               Name 43  "sp_sint"
                               Name 45  "sp_double"
+                              Name 135  "a"
+                              Name 136  "b"
+                              Name 137  "c"
+                              Name 142  "ternayArray1"
                               Decorate 19(sp_int) SpecId 201
                               Decorate 40(sp_float) SpecId 200
                               Decorate 42(sp_uint) SpecId 202
                               Decorate 43(sp_sint) SpecId 203
                               Decorate 45(sp_double) SpecId 204
+                              Decorate 135(a) SpecId 210
+                              Decorate 136(b) SpecId 211
+                              Decorate 137(c) SpecId 212
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeInt 32 1
@@ -137,6 +144,31 @@
              132:             TypeVector 6(int) 3
              133:  132(ivec3) SpecConstantOp 79 91 91 2 1(GLSL.std.450) 0
              134:   90(ivec4) SpecConstantOp 79 91 91 1(GLSL.std.450) 2 0 3
+          135(a):      6(int) SpecConstant 4
+          136(b):      6(int) SpecConstant 6
+          137(c):    22(bool) SpecConstantTrue
+             138:    22(bool) SpecConstantOp 173 135(a) 136(b)
+             139:      6(int) SpecConstantOp 169 138 135(a) 136(b)
+             140:             TypeArray 6(int) 139
+             141:             TypePointer Private 140
+142(ternayArray1):    141(ptr) Variable Private
+             143:      6(int) Constant 13
+             144:      6(int) Constant 17
+             145:      6(int) SpecConstantOp 169 137(c) 143 144
+             146:      6(int) SpecConstantOp 169 137(c) 135(a) 144
+             147:    22(bool) ConstantTrue
+             148:      6(int) SpecConstantOp 169 147 135(a) 144
+             149:    22(bool) SpecConstantOp 173 135(a) 136(b)
+             150:      6(int) SpecConstantOp 128 143 135(a)
+             151:      6(int) SpecConstantOp 132 144 136(b)
+             152:      6(int) SpecConstantOp 169 149 150 151
+             153:    22(bool) SpecConstantOp 168 137(c)
+             154:             TypeVector 39(float) 2
+             155:   39(float) Constant 1065353216
+             156:  154(fvec2) ConstantComposite 155 155
+             157:   39(float) Constant 1073741824
+             158:  154(fvec2) ConstantComposite 157 157
+             159:  154(fvec2) SpecConstantOp 169 153 156 158
          4(main):           2 Function None 3
                5:             Label
                               Return
diff --git a/Test/spv.specConstantOperations.vert b/Test/spv.specConstantOperations.vert
index f67561c..93be12c 100644
--- a/Test/spv.specConstantOperations.vert
+++ b/Test/spv.specConstantOperations.vert
@@ -110,5 +110,15 @@
     return array[sp_int + 1];
 }
 
-void main() {}
+// ternary
+layout(constant_id = 210) const int a = 4;

+layout(constant_id = 211) const int b = 6;

+layout(constant_id = 212) const bool c = true;

+int ternayArray1[a > b ? a : b];

+const int t1 = c ? 13 : 17;

+const int t2 = c ? a : 17;

+const int t3 = true ? a : 17;

+const int t4 = a > b ? 13 + a : 17 * b;
+const vec2 v2 = !c ? vec2(1.0) : vec2(2.0);
 
+void main() {}
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
index af3e811..2854235 100644
--- a/glslang/MachineIndependent/Intermediate.cpp
+++ b/glslang/MachineIndependent/Intermediate.cpp
@@ -155,14 +155,10 @@
             return folded;
     }
 
-    // If either is a specialization constant, while the other is
-    // a constant (or specialization constant), the result is still
-    // a specialization constant, if the operation is an allowed
-    // specialization-constant operation.
-    if (( left->getType().getQualifier().isSpecConstant() && right->getType().getQualifier().isConstant()) ||
-        (right->getType().getQualifier().isSpecConstant() &&  left->getType().getQualifier().isConstant()))
-        if (isSpecializationOperation(*node))
-            node->getWritableType().getQualifier().makeSpecConstant();
+    // If can propagate spec-constantness and if the operation is an allowed
+    // specialization-constant operation, make a spec-constant.
+    if (specConstantPropagates(*left, *right) && isSpecializationOperation(*node))
+        node->getWritableType().getQualifier().makeSpecConstant();
 
     return node;
 }
@@ -1277,6 +1273,9 @@
 // a true path, and a false path.  The two paths are specified
 // as separate parameters.
 //
+// Specialization constant operations include
+//     - The ternary operator ( ? : )
+//
 // Returns the selection node created, or nullptr if one could not be.
 //
 TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc)
@@ -1320,10 +1319,16 @@
     // Make a selection node.
     //
     TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
-    node->getQualifier().makeTemporary();
     node->setLoc(loc);
     node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision);
 
+    if ((cond->getQualifier().isConstant() && specConstantPropagates(*trueBlock, *falseBlock)) ||
+        (cond->getQualifier().isSpecConstant() && trueBlock->getQualifier().isConstant() &&
+                                                 falseBlock->getQualifier().isConstant()))
+        node->getQualifier().makeSpecConstant();
+    else
+        node->getQualifier().makeTemporary();
+
     return node;
 }
 
@@ -2645,4 +2650,13 @@
     *pragmaTable = pTable;
 }
 
+// If either node is a specialization constant, while the other is
+// a constant (or specialization constant), the result is still
+// a specialization constant.
+bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TIntermTyped& node2)
+{
+    return (node1.getType().getQualifier().isSpecConstant() && node2.getType().getQualifier().isConstant()) ||
+           (node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant());
+}
+
 } // end namespace glslang
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index 29efb54..75bd679 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -440,6 +440,7 @@
     bool promoteAggregate(TIntermAggregate&);
     void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
     void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
+    bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
 
     const EShLanguage language;  // stage, known at construction time
     EShSource source;            // source language, known a bit later