diff --git a/Test/310.comp b/Test/310.comp
index 345224f2254034ae72695cba17fe39a9420765aa..7c010ead6ac16ae91f22a0aece82a7c747421737 100644
--- a/Test/310.comp
+++ b/Test/310.comp
@@ -150,3 +150,14 @@ void opac()
     countArr[2];
     countArr[i];
 }
+
+shared int atomi;
+shared uint atomu;
+
+void atoms()
+{
+    int origi = atomicAdd(atomi, 3);
+    uint origu = atomicAnd(atomu, 7u);
+    origi = atomicExchange(atomi, 4);
+    origu = atomicCompSwap(atomu, 10u, 8u);
+}
diff --git a/Test/310.frag b/Test/310.frag
index 7399159ef08feb2ed539605269d0c25dae424aba..183d911302752ccd0b3c76eb9b422651326ad9e9 100644
--- a/Test/310.frag
+++ b/Test/310.frag
@@ -43,4 +43,19 @@ void foo23()
     textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), offsets[1]);
     textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), offsets[2]);     // ERROR, offset out of range
     textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), ivec2(-10, 20)); // ERROR, offset out of range
+
+    if (gl_HelperInvocation)
+        ++outp;
+
+    int sum = gl_MaxVertexImageUniforms +
+              gl_MaxFragmentImageUniforms +
+              gl_MaxComputeImageUniforms +
+              gl_MaxCombinedImageUniforms +
+              gl_MaxCombinedShaderOutputResources;
+
+    bool b1, b2, b3, b;
+
+    b1 = mix(b2, b3, b);
+    uvec3 um3 = mix(uvec3(i), uvec3(i), bvec3(b));
+    ivec4 im4 = mix(ivec4(i), ivec4(i), bvec4(b));
 }
diff --git a/Test/450.frag b/Test/450.frag
index 73f497eca2d16be7f5163bc4b9d4c45eadb0ef1e..b321dc131c2a1f5c25103b84fc1400fd6a3a7d53 100644
--- a/Test/450.frag
+++ b/Test/450.frag
@@ -17,4 +17,19 @@ void main()
 
     float cull = gl_CullDistance[2];
     float consts = gl_MaxCullDistances + gl_MaxCombinedClipAndCullDistances;
+
+    if (gl_HelperInvocation)
+        ++v4;
+
+    int sum = gl_MaxVertexImageUniforms +
+              gl_MaxFragmentImageUniforms +
+              gl_MaxComputeImageUniforms +
+              gl_MaxCombinedImageUniforms +
+              gl_MaxCombinedShaderOutputResources;
+
+    bool b1, b3, b;
+    uint uin;
+    bvec2 b2 = mix(bvec2(b1), bvec2(b3), bvec2(b));
+    uint um = mix(uin, uin, b);
+    ivec3 im3 = mix(ivec3(uin), ivec3(uin), bvec3(b));
 }
diff --git a/Test/baseResults/310.comp.out b/Test/baseResults/310.comp.out
index 9f7040d83f67e9183e7744bd11047bf897e36a7c..97cca31c9528cb8c1f84de5f92bcbc02360fb2f8 100644
--- a/Test/baseResults/310.comp.out
+++ b/Test/baseResults/310.comp.out
@@ -187,6 +187,37 @@ ERROR: node is still EOpNull!
 0:151      indirect index (layout(binding=2 offset=4 ) highp atomic_uint)
 0:151        'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)
 0:151        'i' (uniform highp int)
+0:157  Function Definition: atoms( (void)
+0:157    Function Parameters: 
+0:159    Sequence
+0:159      Sequence
+0:159        move second child to first child (highp int)
+0:159          'origi' (highp int)
+0:159          Function Call: atomicAdd(i1;i1; (highp int)
+0:159            'atomi' (shared highp int)
+0:159            Constant:
+0:159              3 (const int)
+0:160      Sequence
+0:160        move second child to first child (highp uint)
+0:160          'origu' (highp uint)
+0:160          Function Call: atomicAnd(u1;u1; (highp uint)
+0:160            'atomu' (shared highp uint)
+0:160            Constant:
+0:160              7 (const uint)
+0:161      move second child to first child (highp int)
+0:161        'origi' (highp int)
+0:161        Function Call: atomicExchange(i1;i1; (highp int)
+0:161          'atomi' (shared highp int)
+0:161          Constant:
+0:161            4 (const int)
+0:162      move second child to first child (highp uint)
+0:162        'origu' (highp uint)
+0:162        Function Call: atomicCompSwap(u1;u1;u1; (highp uint)
+0:162          'atomu' (shared highp uint)
+0:162          Constant:
+0:162            10 (const uint)
+0:162          Constant:
+0:162            8 (const uint)
 0:?   Linker Objects
 0:?     'gl_WorkGroupSize' (const highp 3-component vector of uint)
 0:?       2 (const uint)
@@ -229,6 +260,8 @@ ERROR: node is still EOpNull!
 0:?     'counterBad' (layout(binding=1 ) uniform mediump atomic_uint)
 0:?     'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)
 0:?     'i' (uniform highp int)
+0:?     'atomi' (shared highp int)
+0:?     'atomu' (shared highp uint)
 
 
 Linked compute stage:
@@ -376,6 +409,37 @@ ERROR: node is still EOpNull!
 0:151      indirect index (layout(binding=2 offset=4 ) highp atomic_uint)
 0:151        'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)
 0:151        'i' (uniform highp int)
+0:157  Function Definition: atoms( (void)
+0:157    Function Parameters: 
+0:159    Sequence
+0:159      Sequence
+0:159        move second child to first child (highp int)
+0:159          'origi' (highp int)
+0:159          Function Call: atomicAdd(i1;i1; (highp int)
+0:159            'atomi' (shared highp int)
+0:159            Constant:
+0:159              3 (const int)
+0:160      Sequence
+0:160        move second child to first child (highp uint)
+0:160          'origu' (highp uint)
+0:160          Function Call: atomicAnd(u1;u1; (highp uint)
+0:160            'atomu' (shared highp uint)
+0:160            Constant:
+0:160              7 (const uint)
+0:161      move second child to first child (highp int)
+0:161        'origi' (highp int)
+0:161        Function Call: atomicExchange(i1;i1; (highp int)
+0:161          'atomi' (shared highp int)
+0:161          Constant:
+0:161            4 (const int)
+0:162      move second child to first child (highp uint)
+0:162        'origu' (highp uint)
+0:162        Function Call: atomicCompSwap(u1;u1;u1; (highp uint)
+0:162          'atomu' (shared highp uint)
+0:162          Constant:
+0:162            10 (const uint)
+0:162          Constant:
+0:162            8 (const uint)
 0:?   Linker Objects
 0:?     'gl_WorkGroupSize' (const highp 3-component vector of uint)
 0:?       2 (const uint)
@@ -418,4 +482,6 @@ ERROR: node is still EOpNull!
 0:?     'counterBad' (layout(binding=1 ) uniform mediump atomic_uint)
 0:?     'countArr' (layout(binding=2 offset=4 ) uniform 4-element array of highp atomic_uint)
 0:?     'i' (uniform highp int)
+0:?     'atomi' (shared highp int)
+0:?     'atomu' (shared highp uint)
 
diff --git a/Test/baseResults/310.frag.out b/Test/baseResults/310.frag.out
index 1057528bb26ef1c165dac289569a6b65a4fbadb8..eb7b53c33ffd96eae0deff44334e506e4358f78d 100644
--- a/Test/baseResults/310.frag.out
+++ b/Test/baseResults/310.frag.out
@@ -153,6 +153,45 @@ ERROR: node is still EOpNull!
 0:45        Constant:
 0:45          -10 (const int)
 0:45          20 (const int)
+0:47      Test condition and select (void)
+0:47        Condition
+0:47        'gl_HelperInvocation' (in bool)
+0:47        true case
+0:48        Pre-Increment (mediump 4-component vector of float)
+0:48          'outp' (out mediump 4-component vector of float)
+0:50      Sequence
+0:50        move second child to first child (mediump int)
+0:50          'sum' (mediump int)
+0:50          Constant:
+0:50            32 (const int)
+0:58      move second child to first child (bool)
+0:58        'b1' (bool)
+0:58        mix (bool)
+0:58          'b2' (bool)
+0:58          'b3' (bool)
+0:58          'b' (bool)
+0:59      Sequence
+0:59        move second child to first child (mediump 3-component vector of uint)
+0:59          'um3' (mediump 3-component vector of uint)
+0:59          mix (mediump 3-component vector of uint)
+0:59            Construct uvec3 (mediump 3-component vector of uint)
+0:59              Convert int to uint (mediump uint)
+0:59                'i' (uniform mediump int)
+0:59            Construct uvec3 (mediump 3-component vector of uint)
+0:59              Convert int to uint (mediump uint)
+0:59                'i' (uniform mediump int)
+0:59            Construct bvec3 (3-component vector of bool)
+0:59              'b' (bool)
+0:60      Sequence
+0:60        move second child to first child (mediump 4-component vector of int)
+0:60          'im4' (mediump 4-component vector of int)
+0:60          mix (mediump 4-component vector of int)
+0:60            Construct ivec4 (mediump 4-component vector of int)
+0:60              'i' (uniform mediump int)
+0:60            Construct ivec4 (mediump 4-component vector of int)
+0:60              'i' (uniform mediump int)
+0:60            Construct bvec4 (4-component vector of bool)
+0:60              'b' (bool)
 0:?   Linker Objects
 0:?     'gl_FragCoord' (smooth in mediump 4-component vector of float)
 0:?     'v3' (layout(location=2 ) smooth in mediump 3-component vector of float)
@@ -303,6 +342,45 @@ ERROR: node is still EOpNull!
 0:45        Constant:
 0:45          -10 (const int)
 0:45          20 (const int)
+0:47      Test condition and select (void)
+0:47        Condition
+0:47        'gl_HelperInvocation' (in bool)
+0:47        true case
+0:48        Pre-Increment (mediump 4-component vector of float)
+0:48          'outp' (out mediump 4-component vector of float)
+0:50      Sequence
+0:50        move second child to first child (mediump int)
+0:50          'sum' (mediump int)
+0:50          Constant:
+0:50            32 (const int)
+0:58      move second child to first child (bool)
+0:58        'b1' (bool)
+0:58        mix (bool)
+0:58          'b2' (bool)
+0:58          'b3' (bool)
+0:58          'b' (bool)
+0:59      Sequence
+0:59        move second child to first child (mediump 3-component vector of uint)
+0:59          'um3' (mediump 3-component vector of uint)
+0:59          mix (mediump 3-component vector of uint)
+0:59            Construct uvec3 (mediump 3-component vector of uint)
+0:59              Convert int to uint (mediump uint)
+0:59                'i' (uniform mediump int)
+0:59            Construct uvec3 (mediump 3-component vector of uint)
+0:59              Convert int to uint (mediump uint)
+0:59                'i' (uniform mediump int)
+0:59            Construct bvec3 (3-component vector of bool)
+0:59              'b' (bool)
+0:60      Sequence
+0:60        move second child to first child (mediump 4-component vector of int)
+0:60          'im4' (mediump 4-component vector of int)
+0:60          mix (mediump 4-component vector of int)
+0:60            Construct ivec4 (mediump 4-component vector of int)
+0:60              'i' (uniform mediump int)
+0:60            Construct ivec4 (mediump 4-component vector of int)
+0:60              'i' (uniform mediump int)
+0:60            Construct bvec4 (4-component vector of bool)
+0:60              'b' (bool)
 0:?   Linker Objects
 0:?     'gl_FragCoord' (smooth in mediump 4-component vector of float)
 0:?     'v3' (layout(location=2 ) smooth in mediump 3-component vector of float)
diff --git a/Test/baseResults/450.frag.out b/Test/baseResults/450.frag.out
index a928c298de40f1403e77cd161049051a6864804e..4f52569109c66da0b712c85834297acc0831a9dc 100644
--- a/Test/baseResults/450.frag.out
+++ b/Test/baseResults/450.frag.out
@@ -59,6 +59,46 @@ Shader version: 450
 0:19          'consts' (float)
 0:19          Constant:
 0:19            16.000000
+0:21      Test condition and select (void)
+0:21        Condition
+0:21        'gl_HelperInvocation' (in bool)
+0:21        true case
+0:22        Pre-Increment (4-component vector of float)
+0:22          'v4' (4-component vector of float)
+0:24      Sequence
+0:24        move second child to first child (int)
+0:24          'sum' (int)
+0:24          Constant:
+0:24            32 (const int)
+0:32      Sequence
+0:32        move second child to first child (2-component vector of bool)
+0:32          'b2' (2-component vector of bool)
+0:32          mix (2-component vector of bool)
+0:32            Construct bvec2 (2-component vector of bool)
+0:32              'b1' (bool)
+0:32            Construct bvec2 (2-component vector of bool)
+0:32              'b3' (bool)
+0:32            Construct bvec2 (2-component vector of bool)
+0:32              'b' (bool)
+0:33      Sequence
+0:33        move second child to first child (uint)
+0:33          'um' (uint)
+0:33          mix (uint)
+0:33            'uin' (uint)
+0:33            'uin' (uint)
+0:33            'b' (bool)
+0:34      Sequence
+0:34        move second child to first child (3-component vector of int)
+0:34          'im3' (3-component vector of int)
+0:34          mix (3-component vector of int)
+0:34            Construct ivec3 (3-component vector of int)
+0:34              Convert uint to int (int)
+0:34                'uin' (uint)
+0:34            Construct ivec3 (3-component vector of int)
+0:34              Convert uint to int (int)
+0:34                'uin' (uint)
+0:34            Construct bvec3 (3-component vector of bool)
+0:34              'b' (bool)
 0:?   Linker Objects
 0:?     'in1' (smooth in float)
 0:?     'in2' (smooth in 2-component vector of float)
@@ -128,6 +168,46 @@ Shader version: 450
 0:19          'consts' (float)
 0:19          Constant:
 0:19            16.000000
+0:21      Test condition and select (void)
+0:21        Condition
+0:21        'gl_HelperInvocation' (in bool)
+0:21        true case
+0:22        Pre-Increment (4-component vector of float)
+0:22          'v4' (4-component vector of float)
+0:24      Sequence
+0:24        move second child to first child (int)
+0:24          'sum' (int)
+0:24          Constant:
+0:24            32 (const int)
+0:32      Sequence
+0:32        move second child to first child (2-component vector of bool)
+0:32          'b2' (2-component vector of bool)
+0:32          mix (2-component vector of bool)
+0:32            Construct bvec2 (2-component vector of bool)
+0:32              'b1' (bool)
+0:32            Construct bvec2 (2-component vector of bool)
+0:32              'b3' (bool)
+0:32            Construct bvec2 (2-component vector of bool)
+0:32              'b' (bool)
+0:33      Sequence
+0:33        move second child to first child (uint)
+0:33          'um' (uint)
+0:33          mix (uint)
+0:33            'uin' (uint)
+0:33            'uin' (uint)
+0:33            'b' (bool)
+0:34      Sequence
+0:34        move second child to first child (3-component vector of int)
+0:34          'im3' (3-component vector of int)
+0:34          mix (3-component vector of int)
+0:34            Construct ivec3 (3-component vector of int)
+0:34              Convert uint to int (int)
+0:34                'uin' (uint)
+0:34            Construct ivec3 (3-component vector of int)
+0:34              Convert uint to int (int)
+0:34                'uin' (uint)
+0:34            Construct bvec3 (3-component vector of bool)
+0:34              'b' (bool)
 0:?   Linker Objects
 0:?     'in1' (smooth in float)
 0:?     'in2' (smooth in 2-component vector of float)
diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h
index 19e0c41b9270a533f90c053465f877dec0471664..0647a76206352f816ac46db40d2fb95ea74d668f 100644
--- a/glslang/Include/intermediate.h
+++ b/glslang/Include/intermediate.h
@@ -234,6 +234,15 @@ enum TOperator {
     EOpMemoryBarrierShared,  // compute only
     EOpGroupMemoryBarrier,   // compute only
 
+    EOpAtomicAdd,            // TODO: AST functionality: hook these up
+    EOpAtomicMin,
+    EOpAtomicMax,
+    EOpAtomicAnd,
+    EOpAtomicOr,
+    EOpAtomicXor,
+    EOpAtomicExchange,
+    EOpAtomicCompSwap,
+
     EOpAny,
     EOpAll,
 
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index 778057681bc52312d7e3d60d6a1caeb9cd2cf326..8f363d989578e9f9ab9b29fdfff3f94d721b94d0 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -372,7 +372,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "ivec2 max(ivec2  x, ivec2  y);"
             "ivec3 max(ivec3  x, ivec3  y);"
             "ivec4 max(ivec4  x, ivec4  y);"
-                     
+
             " uint max(uint   x, uint y);"
             "uvec2 max(uvec2  x, uint y);"
             "uvec3 max(uvec3  x, uint y);"
@@ -380,7 +380,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "uvec2 max(uvec2  x, uvec2  y);"
             "uvec3 max(uvec3  x, uvec3  y);"
             "uvec4 max(uvec4  x, uvec4  y);"
-                     
+
             "int    clamp(int x, int minVal, int maxVal);"
             "ivec2  clamp(ivec2  x, int minVal, int maxVal);"
             "ivec3  clamp(ivec3  x, int minVal, int maxVal);"
@@ -388,7 +388,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "ivec2  clamp(ivec2  x, ivec2  minVal, ivec2  maxVal);"
             "ivec3  clamp(ivec3  x, ivec3  minVal, ivec3  maxVal);"
             "ivec4  clamp(ivec4  x, ivec4  minVal, ivec4  maxVal);"
-                     
+
             "uint   clamp(uint x, uint minVal, uint maxVal);"
             "uvec2  clamp(uvec2  x, uint minVal, uint maxVal);"
             "uvec3  clamp(uvec3  x, uint minVal, uint maxVal);"
@@ -396,22 +396,73 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "uvec2  clamp(uvec2  x, uvec2  minVal, uvec2  maxVal);"
             "uvec3  clamp(uvec3  x, uvec3  minVal, uvec3  maxVal);"
             "uvec4  clamp(uvec4  x, uvec4  minVal, uvec4  maxVal);"
-                     
+
             "float mix(float x, float y, bool  a);"
             "vec2  mix(vec2  x, vec2  y, bvec2 a);"
             "vec3  mix(vec3  x, vec3  y, bvec3 a);"
             "vec4  mix(vec4  x, vec4  y, bvec4 a);"
-                     
+
             "bool  isnan(float x);"
             "bvec2 isnan(vec2  x);"
             "bvec3 isnan(vec3  x);"
             "bvec4 isnan(vec4  x);"
-                     
+
             "bool  isinf(float x);"
             "bvec2 isinf(vec2  x);"
             "bvec3 isinf(vec3  x);"
             "bvec4 isinf(vec4  x);"
+
+            "\n");
+    }
+
+    if (profile == EEsProfile && version >= 310 ||
+        profile != EEsProfile && version >= 430) {
+        commonBuiltins.append(
+            "uint atomicAdd(coherent inout uint, uint);"
+            " int atomicAdd(coherent inout  int,  int);"
+
+            "uint atomicMin(coherent inout uint, uint);"
+            " int atomicMin(coherent inout  int,  int);"
+            
+            "uint atomicMax(coherent inout uint, uint);"
+            " int atomicMax(coherent inout  int,  int);"
+            
+            "uint atomicAnd(coherent inout uint, uint);"
+            " int atomicAnd(coherent inout  int,  int);"
             
+            "uint atomicOr (coherent inout uint, uint);"
+            " int atomicOr (coherent inout  int,  int);"
+            
+            "uint atomicXor(coherent inout uint, uint);"
+            " int atomicXor(coherent inout  int,  int);"
+
+            "uint atomicExchange(coherent inout uint, uint);"
+            " int atomicExchange(coherent inout  int,  int);"
+
+            "uint atomicCompSwap(coherent inout uint, uint, uint);"
+            " int atomicCompSwap(coherent inout  int,  int,  int);"
+
+            "\n");
+    }
+
+    if (profile == EEsProfile && version >= 310 ||
+        profile != EEsProfile && version >= 450) {
+        commonBuiltins.append(
+            "int    mix(int    x, int    y, bool  a);"
+            "ivec2  mix(ivec2  x, ivec2  y, bvec2 a);"
+            "ivec3  mix(ivec3  x, ivec3  y, bvec3 a);"
+            "ivec4  mix(ivec4  x, ivec4  y, bvec4 a);"
+
+            "uint   mix(uint   x, uint   y, bool  a);"
+            "uvec2  mix(uvec2  x, uvec2  y, bvec2 a);"
+            "uvec3  mix(uvec3  x, uvec3  y, bvec3 a);"
+            "uvec4  mix(uvec4  x, uvec4  y, bvec4 a);"
+
+            "bool   mix(bool   x, bool   y, bool  a);"
+            "bvec2  mix(bvec2  x, bvec2  y, bvec2 a);"
+            "bvec3  mix(bvec3  x, bvec3  y, bvec3 a);"
+            "bvec4  mix(bvec4  x, bvec4  y, bvec4 a);"
+
             "\n");
     }
 
@@ -2238,26 +2289,16 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
 
         // images
         if (version >= 130) {
-            snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.maxImageUnits);
-            s.append(builtInConstant);
             snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUnitsAndFragmentOutputs = %d;", resources.maxCombinedImageUnitsAndFragmentOutputs);
             s.append(builtInConstant);
-            snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedShaderOutputResources = %d;", resources.maxCombinedShaderOutputResources);
-            s.append(builtInConstant);
             snprintf(builtInConstant, maxSize, "const int gl_MaxImageSamples = %d;", resources.maxImageSamples);
             s.append(builtInConstant);
-            snprintf(builtInConstant, maxSize, "const int gl_MaxVertexImageUniforms = %d;", resources.maxVertexImageUniforms);
-            s.append(builtInConstant);
             snprintf(builtInConstant, maxSize, "const int gl_MaxTessControlImageUniforms = %d;", resources.maxTessControlImageUniforms);
             s.append(builtInConstant);
             snprintf(builtInConstant, maxSize, "const int gl_MaxTessEvaluationImageUniforms = %d;", resources.maxTessEvaluationImageUniforms);
             s.append(builtInConstant);
             snprintf(builtInConstant, maxSize, "const int gl_MaxGeometryImageUniforms = %d;", resources.maxGeometryImageUniforms);
             s.append(builtInConstant);
-            snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentImageUniforms = %d;", resources.maxFragmentImageUniforms);
-            s.append(builtInConstant);
-            snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUniforms = %d;", resources.maxCombinedImageUniforms);
-            s.append(builtInConstant);
         }
 
         // enhanced layouts
@@ -2269,6 +2310,21 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
         }
     }
 
+    // images (some in compute below)
+    if (profile == EEsProfile && version >= 310 || profile != EEsProfile && version >= 130) {
+        snprintf(builtInConstant, maxSize, "const int gl_MaxImageUnits = %d;", resources.maxImageUnits);
+        s.append(builtInConstant);
+        snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedShaderOutputResources = %d;", resources.maxCombinedShaderOutputResources);
+        s.append(builtInConstant);
+        snprintf(builtInConstant, maxSize, "const int gl_MaxVertexImageUniforms = %d;", resources.maxVertexImageUniforms);
+        s.append(builtInConstant);
+        snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentImageUniforms = %d;", resources.maxFragmentImageUniforms);
+        s.append(builtInConstant);
+        snprintf(builtInConstant, maxSize, "const int gl_MaxCombinedImageUniforms = %d;", resources.maxCombinedImageUniforms);
+        s.append(builtInConstant);
+    }
+
+    // atomic counters (some in compute below)
     if (profile == EEsProfile && version >= 310 || profile != EEsProfile && version >= 420) {
         snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAtomicCounters = %d;", resources.               maxVertexAtomicCounters);
         s.append(builtInConstant);
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index bdbe7752f351fedb36a085b6eba0d828994b2016..eb8c5238ab545875a7283ca2cc3dca194ca805ea 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -994,6 +994,11 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* funct
                         if (argQualifier.writeonly && ! formalQualifier.writeonly)
                             error(arguments->getLoc(), message, "writeonly", "");
                     }
+                    // TODO 4.5 functionality:  A shader will fail to compile 
+                    // if the value passed to the memargument of an atomic memory function does not correspond to a buffer or
+                    // shared variable. It is acceptable to pass an element of an array or a single component of a vector to the 
+                    // memargument of an atomic memory function, as long as the underlying array or vector is a buffer or 
+                    // shared variable.
                 }
 
                 // Convert 'in' arguments
diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp
index 310350d85e65072b9382c2918fef7ee3cf61a530..9361bdc45b97a73f35d48ee72ad880a123c95c99 100644
--- a/glslang/MachineIndependent/linkValidate.cpp
+++ b/glslang/MachineIndependent/linkValidate.cpp
@@ -229,6 +229,8 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
     }
 }
 
+// TODO 4.5 link functionality: cull distance array size checking
+
 // Recursively merge the implicit array sizes through the objects' respective type trees.
 void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
 {