Move symbol table initialization to SymbolTable.cpp

This is needed in order to make symbol table symbols statically
allocated.

BUG=angleproject:2267
TEST=angle_unittests

Change-Id: Ia2d44fb30d49dc5d5c67643fe01280c89127a3c3
Reviewed-on: https://chromium-review.googlesource.com/889299
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/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index a53e875..dc09f54 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -708,56 +708,11 @@
     compileResources = resources;
     setResourceString();
 
-    ASSERT(symbolTable.isEmpty());
-    symbolTable.push();  // COMMON_BUILTINS
-    symbolTable.push();  // ESSL1_BUILTINS
-    symbolTable.push();  // ESSL3_BUILTINS
-    symbolTable.push();  // ESSL3_1_BUILTINS
-    symbolTable.push();  // GLSL_BUILTINS
-
-    switch (shaderType)
-    {
-        case GL_FRAGMENT_SHADER:
-            symbolTable.setDefaultPrecision(EbtInt, EbpMedium);
-            break;
-        case GL_VERTEX_SHADER:
-        case GL_COMPUTE_SHADER:
-        case GL_GEOMETRY_SHADER_EXT:
-            symbolTable.setDefaultPrecision(EbtInt, EbpHigh);
-            symbolTable.setDefaultPrecision(EbtFloat, EbpHigh);
-            break;
-        default:
-            UNREACHABLE();
-    }
-    // Set defaults for sampler types that have default precision, even those that are
-    // only available if an extension exists.
-    // New sampler types in ESSL3 don't have default precision. ESSL1 types do.
-    initSamplerDefaultPrecision(EbtSampler2D);
-    initSamplerDefaultPrecision(EbtSamplerCube);
-    // SamplerExternalOES is specified in the extension to have default precision.
-    initSamplerDefaultPrecision(EbtSamplerExternalOES);
-    // SamplerExternal2DY2YEXT is specified in the extension to have default precision.
-    initSamplerDefaultPrecision(EbtSamplerExternal2DY2YEXT);
-    // It isn't specified whether Sampler2DRect has default precision.
-    initSamplerDefaultPrecision(EbtSampler2DRect);
-
-    symbolTable.setDefaultPrecision(EbtAtomicCounter, EbpHigh);
-
-    InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
-
-    IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
-
-    symbolTable.markBuiltInInitializationFinished();
+    symbolTable.initializeBuiltIns(shaderType, shaderSpec, resources);
 
     return true;
 }
 
-void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType)
-{
-    ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd);
-    symbolTable.setDefaultPrecision(samplerType, EbpLow);
-}
-
 void TCompiler::setResourceString()
 {
     std::ostringstream strstream;
diff --git a/src/compiler/translator/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index 0afcf4c..25ba445 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -4,1148 +4,11 @@
 // found in the LICENSE file.
 //
 
-//
-// Create symbols that declare built-in definitions, add built-ins that
-// cannot be expressed in the files, and establish mappings between
-// built-in functions and operators.
-//
-
 #include "compiler/translator/Initialize.h"
-#include "compiler/translator/StaticType.h"
-
-#include "compiler/translator/IntermNode.h"
-#include "angle_gl.h"
 
 namespace sh
 {
 
-void InsertBuiltInFunctions(sh::GLenum type,
-                            ShShaderSpec spec,
-                            const ShBuiltInResources &resources,
-                            TSymbolTable &symbolTable)
-{
-    const TType *voidType = StaticType::GetBasic<EbtVoid>();
-    const TType *float1   = StaticType::GetBasic<EbtFloat>();
-    const TType *float2   = StaticType::GetBasic<EbtFloat, 2>();
-    const TType *float3   = StaticType::GetBasic<EbtFloat, 3>();
-    const TType *float4   = StaticType::GetBasic<EbtFloat, 4>();
-    const TType *int1     = StaticType::GetBasic<EbtInt>();
-    const TType *int2     = StaticType::GetBasic<EbtInt, 2>();
-    const TType *int3     = StaticType::GetBasic<EbtInt, 3>();
-    const TType *uint1    = StaticType::GetBasic<EbtUInt>();
-    const TType *bool1    = StaticType::GetBasic<EbtBool>();
-    const TType *genType  = StaticType::GetBasic<EbtGenType>();
-    const TType *genIType = StaticType::GetBasic<EbtGenIType>();
-    const TType *genUType = StaticType::GetBasic<EbtGenUType>();
-    const TType *genBType = StaticType::GetBasic<EbtGenBType>();
-
-    //
-    // Angle and Trigonometric Functions.
-    //
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpRadians, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpDegrees, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSin, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpCos, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpTan, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAsin, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAcos, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAtan, genType, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAtan, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpSinh, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpCosh, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTanh, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpAsinh, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpAcosh, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpAtanh, genType, genType);
-
-    //
-    // Exponential Functions.
-    //
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpPow, genType, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpExp, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLog, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpExp2, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLog2, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSqrt, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpInverseSqrt, genType, genType);
-
-    //
-    // Common Functions.
-    //
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAbs, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpAbs, genIType, genIType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSign, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpSign, genIType, genIType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpFloor, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTrunc, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpRound, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpRoundEven, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpCeil, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpFract, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMod, genType, genType, float1);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMod, genType, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMin, genType, genType, float1);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMin, genType, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genIType, genIType, genIType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genIType, genIType, int1);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genUType, genUType, genUType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genUType, genUType, uint1);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMax, genType, genType, float1);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMax, genType, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genIType, genIType, genIType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genIType, genIType, int1);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genUType, genUType, genUType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genUType, genUType, uint1);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpClamp, genType, genType, float1, float1);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpClamp, genType, genType, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genIType, genIType, int1, int1);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genIType, genIType, genIType, genIType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genUType, genUType, uint1, uint1);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genUType, genUType, genUType, genUType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, float1);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMix, genType, genType, genType, genBType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, float1, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSmoothStep, genType, genType, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSmoothStep, genType, float1, float1, genType);
-
-    const TType *outGenType  = StaticType::GetQualified<EbtGenType, EvqOut>();
-    const TType *outGenIType = StaticType::GetQualified<EbtGenIType, EvqOut>();
-
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpModf, genType, genType, outGenType);
-
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpIsNan, genBType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpIsInf, genBType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToUint, genUType, genType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpIntBitsToFloat, genType, genIType);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUintBitsToFloat, genType, genUType);
-
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpFrexp, genType, genType, outGenIType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpLdexp, genType, genType, genIType);
-
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpPackSnorm2x16, uint1, float2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpPackUnorm2x16, uint1, float2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpPackHalf2x16, uint1, float2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackSnorm2x16, float2, uint1);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, uint1);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, uint1);
-
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackUnorm4x8, uint1, float4);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackSnorm4x8, uint1, float4);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackUnorm4x8, float4, uint1);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackSnorm4x8, float4, uint1);
-
-    //
-    // Geometric Functions.
-    //
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLength, float1, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpDistance, float1, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpDot, float1, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpCross, float3, float3, float3);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpNormalize, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpFaceforward, genType, genType, genType,
-                                genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpReflect, genType, genType, genType);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpRefract, genType, genType, genType, float1);
-
-    const TType *mat2   = StaticType::GetBasic<EbtFloat, 2, 2>();
-    const TType *mat3   = StaticType::GetBasic<EbtFloat, 3, 3>();
-    const TType *mat4   = StaticType::GetBasic<EbtFloat, 4, 4>();
-    const TType *mat2x3 = StaticType::GetBasic<EbtFloat, 2, 3>();
-    const TType *mat3x2 = StaticType::GetBasic<EbtFloat, 3, 2>();
-    const TType *mat2x4 = StaticType::GetBasic<EbtFloat, 2, 4>();
-    const TType *mat4x2 = StaticType::GetBasic<EbtFloat, 4, 2>();
-    const TType *mat3x4 = StaticType::GetBasic<EbtFloat, 3, 4>();
-    const TType *mat4x3 = StaticType::GetBasic<EbtFloat, 4, 3>();
-
-    //
-    // Matrix Functions.
-    //
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat2, mat2, mat2);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat3, mat3, mat3);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat4, mat4, mat4);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat2x3, mat2x3, mat2x3);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat3x2, mat3x2, mat3x2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat2x4, mat2x4, mat2x4);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat4x2, mat4x2, mat4x2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat3x4, mat3x4, mat3x4);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat4x3, mat4x3, mat4x3);
-
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2, float2, float2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3, float3, float3);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4, float4, float4);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2x3, float3, float2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3x2, float2, float3);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2x4, float4, float2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4x2, float2, float4);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3x4, float4, float3);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4x3, float3, float4);
-
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2, mat2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3, mat3);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4, mat4);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2x3, mat3x2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3x2, mat2x3);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2x4, mat4x2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4x2, mat2x4);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3x4, mat4x3);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4x3, mat3x4);
-
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat3);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat4);
-
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat2, mat2);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat3, mat3);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat4, mat4);
-
-    const TType *vec  = StaticType::GetBasic<EbtVec>();
-    const TType *ivec = StaticType::GetBasic<EbtIVec>();
-    const TType *uvec = StaticType::GetBasic<EbtUVec>();
-    const TType *bvec = StaticType::GetBasic<EbtBVec>();
-
-    //
-    // Vector relational functions.
-    //
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, vec, vec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, ivec, ivec);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpLessThanComponentWise, bvec, uvec, uvec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLessThanEqualComponentWise, bvec, vec, vec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLessThanEqualComponentWise, bvec, ivec, ivec);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpLessThanEqualComponentWise, bvec, uvec, uvec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanComponentWise, bvec, vec, vec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanComponentWise, bvec, ivec, ivec);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpGreaterThanComponentWise, bvec, uvec, uvec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, vec, vec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, ivec,
-                                ivec);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, uvec, uvec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, vec, vec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, ivec, ivec);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpEqualComponentWise, bvec, uvec, uvec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, bvec, bvec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, vec, vec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, ivec, ivec);
-    symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpNotEqualComponentWise, bvec, uvec, uvec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, bvec, bvec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAny, bool1, bvec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAll, bool1, bvec);
-    symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLogicalNotComponentWise, bvec, bvec);
-
-    //
-    // Integer functions
-    //
-    const TType *outGenUType = StaticType::GetQualified<EbtGenUType, EvqOut>();
-
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genIType, genIType, int1,
-                                int1);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genUType, genUType, int1,
-                                int1);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genIType, genIType, genIType,
-                                int1, int1);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genUType, genUType, genUType,
-                                int1, int1);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldReverse, genIType, genIType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldReverse, genUType, genUType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitCount, genIType, genIType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitCount, genIType, genUType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindLSB, genIType, genIType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindLSB, genIType, genUType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindMSB, genIType, genIType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindMSB, genIType, genUType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUaddCarry, genUType, genUType, genUType,
-                                outGenUType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUsubBorrow, genUType, genUType, genUType,
-                                outGenUType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUmulExtended, voidType, genUType, genUType,
-                                outGenUType, outGenUType);
-    symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpImulExtended, voidType, genIType, genIType,
-                                outGenIType, outGenIType);
-
-    const TType *sampler2D   = StaticType::GetBasic<EbtSampler2D>();
-    const TType *samplerCube = StaticType::GetBasic<EbtSamplerCube>();
-
-    //
-    // Texture Functions for GLSL ES 1.0
-    //
-    symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2);
-    symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3);
-    symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4);
-    symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3);
-
-    if (resources.OES_EGL_image_external || resources.NV_EGL_stream_consumer_external)
-    {
-        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
-
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", samplerExternalOES, float2);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES,
-                                  float3);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES,
-                                  float4);
-    }
-
-    if (resources.ARB_texture_rectangle)
-    {
-        const TType *sampler2DRect = StaticType::GetBasic<EbtSampler2DRect>();
-
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRect", sampler2DRect, float2);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect,
-                                  float3);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect,
-                                  float4);
-    }
-
-    if (resources.EXT_shader_texture_lod)
-    {
-        /* The *Grad* variants are new to both vertex and fragment shaders; the fragment
-         * shader specific pieces are added separately below.
-         */
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                                  "texture2DGradEXT", sampler2D, float2, float2, float2);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                                  "texture2DProjGradEXT", sampler2D, float3, float2, float2);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                                  "texture2DProjGradEXT", sampler2D, float4, float2, float2);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                                  "textureCubeGradEXT", samplerCube, float3, float3, float3);
-    }
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2, float1);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3,
-                                  float1);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4,
-                                  float1);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3,
-                                  float1);
-
-        if (resources.OES_standard_derivatives)
-        {
-            symbolTable.insertBuiltInOp(ESSL1_BUILTINS, EOpDFdx,
-                                        TExtension::OES_standard_derivatives, genType, genType);
-            symbolTable.insertBuiltInOp(ESSL1_BUILTINS, EOpDFdy,
-                                        TExtension::OES_standard_derivatives, genType, genType);
-            symbolTable.insertBuiltInOp(ESSL1_BUILTINS, EOpFwidth,
-                                        TExtension::OES_standard_derivatives, genType, genType);
-        }
-
-        if (resources.EXT_shader_texture_lod)
-        {
-            symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                                      "texture2DLodEXT", sampler2D, float2, float1);
-            symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                                      "texture2DProjLodEXT", sampler2D, float3, float1);
-            symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                                      "texture2DProjLodEXT", sampler2D, float4, float1);
-            symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
-                                      "textureCubeLodEXT", samplerCube, float3, float1);
-        }
-    }
-
-    if (type == GL_VERTEX_SHADER)
-    {
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLod", sampler2D, float2,
-                                  float1);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float3,
-                                  float1);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float4,
-                                  float1);
-        symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLod", samplerCube, float3,
-                                  float1);
-    }
-
-    const TType *gvec4 = StaticType::GetBasic<EbtGVec4>();
-
-    const TType *gsampler2D      = StaticType::GetBasic<EbtGSampler2D>();
-    const TType *gsamplerCube    = StaticType::GetBasic<EbtGSamplerCube>();
-    const TType *gsampler3D      = StaticType::GetBasic<EbtGSampler3D>();
-    const TType *gsampler2DArray = StaticType::GetBasic<EbtGSampler2DArray>();
-    const TType *gsampler2DMS    = StaticType::GetBasic<EbtGSampler2DMS>();
-
-    //
-    // Texture Functions for GLSL ES 3.0
-    //
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2D, float2, float1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler3D, float3, float1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1);
-
-    if (resources.OES_EGL_image_external_essl3)
-    {
-        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
-
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
-                                  float3);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
-                                  float4);
-    }
-
-    if (resources.EXT_YUV_target)
-    {
-        const TType *samplerExternal2DY2YEXT =
-            StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
-
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture",
-                                  samplerExternal2DY2YEXT, float2);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
-                                  samplerExternal2DY2YEXT, float3);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
-                                  samplerExternal2DY2YEXT, float4);
-
-        const TType *yuvCscStandardEXT = StaticType::GetBasic<EbtYuvCscStandardEXT>();
-
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "rgb_2_yuv",
-                                  float3, yuvCscStandardEXT);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "yuv_2_rgb",
-                                  float3, yuvCscStandardEXT);
-    }
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3,
-                                  float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1);
-
-        if (resources.OES_EGL_image_external_essl3)
-        {
-            const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
-
-            symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2,
-                                      float1);
-            symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
-                                      float3, float1);
-            symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
-                                      float4, float1);
-        }
-
-        if (resources.EXT_YUV_target)
-        {
-            const TType *samplerExternal2DY2YEXT =
-                StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
-
-            symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture",
-                                      samplerExternal2DY2YEXT, float2, float1);
-            symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4,
-                                      "textureProj", samplerExternal2DY2YEXT, float3, float1);
-            symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4,
-                                      "textureProj", samplerExternal2DY2YEXT, float4, float1);
-        }
-    }
-
-    const TType *sampler2DShadow      = StaticType::GetBasic<EbtSampler2DShadow>();
-    const TType *samplerCubeShadow    = StaticType::GetBasic<EbtSamplerCubeShadow>();
-    const TType *sampler2DArrayShadow = StaticType::GetBasic<EbtSampler2DArrayShadow>();
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DArrayShadow, float4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureLod", sampler2DShadow, float3,
-                              float1);
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3,
-                                  float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4,
-                                  float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4,
-                                  float1);
-    }
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2D, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler3D, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsamplerCube, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler2DArray, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", sampler2DShadow, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2DMS);
-
-    if (resources.OES_EGL_image_external_essl3)
-    {
-        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
-
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerExternalOES, int1);
-    }
-
-    if (resources.EXT_YUV_target)
-    {
-        const TType *samplerExternal2DY2YEXT =
-            StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
-
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, int2, "textureSize",
-                                  samplerExternal2DY2YEXT, int1);
-    }
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDFdx, genType, genType);
-        symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDFdy, genType, genType);
-        symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpFwidth, genType, genType);
-    }
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3,
-                              int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3,
-                              int2);
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2,
-                                  float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3,
-                                  float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3,
-                                  int2, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3,
-                                  int2, float1);
-    }
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4,
-                              int2);
-
-    if (type == GL_FRAGMENT_SHADER)
-    {
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3,
-                                  int2, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4,
-                                  int2, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4,
-                                  int3, float1);
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow,
-                                  float4, int2, float1);
-    }
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2D, float2, float1,
-                              int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler3D, float3, float1,
-                              int3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureLodOffset", sampler2DShadow, float3,
-                              float1, int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2DArray, float3,
-                              float1, int2);
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float3, float1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float4, float1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler3D, float4, float1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLod", sampler2DShadow, float4,
-                              float1);
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float3,
-                              float1, int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float4,
-                              float1, int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler3D, float4,
-                              float1, int3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLodOffset", sampler2DShadow,
-                              float4, float1, int2);
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2D, int2, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler3D, int3, int1);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2DArray, int3, int1);
-
-    if (resources.OES_EGL_image_external_essl3)
-    {
-        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
-
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texelFetch", samplerExternalOES, int2,
-                                  int1);
-    }
-
-    if (resources.EXT_YUV_target)
-    {
-        const TType *samplerExternal2DY2YEXT =
-            StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
-
-        symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texelFetch",
-                                  samplerExternal2DY2YEXT, int2, int1);
-    }
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1,
-                              int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1,
-                              int3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3,
-                              int1, int2);
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2D, float2, float2,
-                              float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler3D, float3, float3,
-                              float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsamplerCube, float3, float3,
-                              float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DShadow, float3,
-                              float2, float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", samplerCubeShadow, float4,
-                              float3, float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2DArray, float3, float2,
-                              float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DArrayShadow, float4,
-                              float2, float2);
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2D, float2,
-                              float2, float2, int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler3D, float3,
-                              float3, float3, int3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DShadow, float3,
-                              float2, float2, int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2DArray, float3,
-                              float2, float2, int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DArrayShadow,
-                              float4, float2, float2, int2);
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float3, float2,
-                              float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float4, float2,
-                              float2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler3D, float4, float3,
-                              float3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGrad", sampler2DShadow, float4,
-                              float2, float2);
-
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float3,
-                              float2, float2, int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float4,
-                              float2, float2, int2);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4,
-                              float3, float3, int3);
-    symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow,
-                              float4, float2, float2, int2);
-
-    const TType *atomicCounter = StaticType::GetBasic<EbtAtomicCounter>();
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounter", atomicCounter);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterIncrement", atomicCounter);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterDecrement", atomicCounter);
-
-    // Insert all atomic memory functions
-    const TType *int1InOut  = StaticType::GetQualified<EbtInt, EvqInOut>();
-    const TType *uint1InOut = StaticType::GetQualified<EbtUInt, EvqInOut>();
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAdd", uint1InOut, uint1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAdd", int1InOut, int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMin", uint1InOut, uint1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMin", int1InOut, int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMax", uint1InOut, uint1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMax", int1InOut, int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAnd", uint1InOut, uint1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAnd", int1InOut, int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicOr", uint1InOut, uint1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicOr", int1InOut, int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicXor", uint1InOut, uint1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicXor", int1InOut, int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicExchange", uint1InOut, uint1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicExchange", int1InOut, int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCompSwap", uint1InOut, uint1, uint1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicCompSwap", int1InOut, int1, int1);
-
-    const TType *gimage2D      = StaticType::GetBasic<EbtGImage2D>();
-    const TType *gimage3D      = StaticType::GetBasic<EbtGImage3D>();
-    const TType *gimage2DArray = StaticType::GetBasic<EbtGImage2DArray>();
-    const TType *gimageCube    = StaticType::GetBasic<EbtGImageCube>();
-
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2D, int2, gvec4);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage3D, int3, gvec4);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2DArray, int3, gvec4);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimageCube, int3, gvec4);
-
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2D, int2);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage3D, int3);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2DArray, int3);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimageCube, int3);
-
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimage2D);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage3D);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage2DArray);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimageCube);
-
-    symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrier, voidType,
-                                                  "memoryBarrier");
-    symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierAtomicCounter,
-                                                  voidType, "memoryBarrierAtomicCounter");
-    symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierBuffer,
-                                                  voidType, "memoryBarrierBuffer");
-    symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierImage, voidType,
-                                                  "memoryBarrierImage");
-
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "texelFetch", gsampler2DMS, int2, int1);
-
-    // Insert all variations of textureGather.
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2D, float2);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2D, float2, int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2DArray, float3);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2DArray, float3,
-                              int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsamplerCube, float3);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsamplerCube, float3, int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DShadow, float2);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DShadow, float2,
-                              float1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DArrayShadow,
-                              float3);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DArrayShadow,
-                              float3, float1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", samplerCubeShadow, float3);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", samplerCubeShadow, float3,
-                              float1);
-
-    // Insert all variations of textureGatherOffset.
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2D, float2,
-                              int2);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2D, float2,
-                              int2, int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2DArray,
-                              float3, int2);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2DArray,
-                              float3, int2, int1);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGatherOffset", sampler2DShadow,
-                              float2, float1, int2);
-    symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGatherOffset", sampler2DArrayShadow,
-                              float3, float1, int2);
-
-    if (type == GL_COMPUTE_SHADER)
-    {
-        symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpBarrier, voidType,
-                                                      "barrier");
-        symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierShared,
-                                                      voidType, "memoryBarrierShared");
-        symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpGroupMemoryBarrier,
-                                                      voidType, "groupMemoryBarrier");
-    }
-
-    if (type == GL_GEOMETRY_SHADER_EXT)
-    {
-        TExtension extension = TExtension::EXT_geometry_shader;
-        symbolTable.insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension, EOpEmitVertex,
-                                                         voidType, "EmitVertex");
-        symbolTable.insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension,
-                                                         EOpEndPrimitive, voidType, "EndPrimitive");
-    }
-
-    //
-    // Depth range in window coordinates
-    //
-    TFieldList *fields       = new TFieldList();
-    TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
-    auto highpFloat1         = new TType(EbtFloat, EbpHigh, EvqGlobal, 1);
-    TField *near             = new TField(highpFloat1, ImmutableString("near"), zeroSourceLoc);
-    TField *far              = new TField(highpFloat1, ImmutableString("far"), zeroSourceLoc);
-    TField *diff             = new TField(highpFloat1, ImmutableString("diff"), zeroSourceLoc);
-    fields->push_back(near);
-    fields->push_back(far);
-    fields->push_back(diff);
-    TStructure *depthRangeStruct = new TStructure(
-        &symbolTable, ImmutableString("gl_DepthRangeParameters"), fields, SymbolType::BuiltIn);
-    symbolTable.insertStructType(COMMON_BUILTINS, depthRangeStruct);
-    TType *depthRangeType = new TType(depthRangeStruct);
-    depthRangeType->setQualifier(EvqUniform);
-    depthRangeType->realize();
-    symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_DepthRange"), depthRangeType);
-
-    //
-    // Implementation dependent built-in constants.
-    //
-    symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxVertexAttribs"),
-                                          resources.MaxVertexAttribs);
-    symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS,
-                                          ImmutableString("gl_MaxVertexUniformVectors"),
-                                          resources.MaxVertexUniformVectors);
-    symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS,
-                                          ImmutableString("gl_MaxVertexTextureImageUnits"),
-                                          resources.MaxVertexTextureImageUnits);
-    symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS,
-                                          ImmutableString("gl_MaxCombinedTextureImageUnits"),
-                                          resources.MaxCombinedTextureImageUnits);
-    symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS,
-                                          ImmutableString("gl_MaxTextureImageUnits"),
-                                          resources.MaxTextureImageUnits);
-    symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS,
-                                          ImmutableString("gl_MaxFragmentUniformVectors"),
-                                          resources.MaxFragmentUniformVectors);
-
-    symbolTable.insertConstInt<EbpMedium>(ESSL1_BUILTINS, ImmutableString("gl_MaxVaryingVectors"),
-                                          resources.MaxVaryingVectors);
-
-    symbolTable.insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxDrawBuffers"),
-                                          resources.MaxDrawBuffers);
-    if (resources.EXT_blend_func_extended)
-    {
-        symbolTable.insertConstIntExt<EbpMedium>(
-            COMMON_BUILTINS, TExtension::EXT_blend_func_extended,
-            ImmutableString("gl_MaxDualSourceDrawBuffersEXT"), resources.MaxDualSourceDrawBuffers);
-    }
-
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS,
-                                          ImmutableString("gl_MaxVertexOutputVectors"),
-                                          resources.MaxVertexOutputVectors);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS,
-                                          ImmutableString("gl_MaxFragmentInputVectors"),
-                                          resources.MaxFragmentInputVectors);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS,
-                                          ImmutableString("gl_MinProgramTexelOffset"),
-                                          resources.MinProgramTexelOffset);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_BUILTINS,
-                                          ImmutableString("gl_MaxProgramTexelOffset"),
-                                          resources.MaxProgramTexelOffset);
-
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxImageUnits"),
-                                          resources.MaxImageUnits);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxVertexImageUniforms"),
-                                          resources.MaxVertexImageUniforms);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxFragmentImageUniforms"),
-                                          resources.MaxFragmentImageUniforms);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxComputeImageUniforms"),
-                                          resources.MaxComputeImageUniforms);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxCombinedImageUniforms"),
-                                          resources.MaxCombinedImageUniforms);
-
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxCombinedShaderOutputResources"),
-                                          resources.MaxCombinedShaderOutputResources);
-
-    symbolTable.insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxComputeWorkGroupCount"),
-                                          resources.MaxComputeWorkGroupCount);
-    symbolTable.insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxComputeWorkGroupSize"),
-                                          resources.MaxComputeWorkGroupSize);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxComputeUniformComponents"),
-                                          resources.MaxComputeUniformComponents);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxComputeTextureImageUnits"),
-                                          resources.MaxComputeTextureImageUnits);
-
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxComputeAtomicCounters"),
-                                          resources.MaxComputeAtomicCounters);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxComputeAtomicCounterBuffers"),
-                                          resources.MaxComputeAtomicCounterBuffers);
-
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxVertexAtomicCounters"),
-                                          resources.MaxVertexAtomicCounters);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxFragmentAtomicCounters"),
-                                          resources.MaxFragmentAtomicCounters);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxCombinedAtomicCounters"),
-                                          resources.MaxCombinedAtomicCounters);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxAtomicCounterBindings"),
-                                          resources.MaxAtomicCounterBindings);
-
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxVertexAtomicCounterBuffers"),
-                                          resources.MaxVertexAtomicCounterBuffers);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxFragmentAtomicCounterBuffers"),
-                                          resources.MaxFragmentAtomicCounterBuffers);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxCombinedAtomicCounterBuffers"),
-                                          resources.MaxCombinedAtomicCounterBuffers);
-    symbolTable.insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
-                                          ImmutableString("gl_MaxAtomicCounterBufferSize"),
-                                          resources.MaxAtomicCounterBufferSize);
-
-    if (resources.EXT_geometry_shader)
-    {
-        TExtension ext = TExtension::EXT_geometry_shader;
-        symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                                 ImmutableString("gl_MaxGeometryInputComponents"),
-                                                 resources.MaxGeometryInputComponents);
-        symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                                 ImmutableString("gl_MaxGeometryOutputComponents"),
-                                                 resources.MaxGeometryOutputComponents);
-        symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                                 ImmutableString("gl_MaxGeometryImageUniforms"),
-                                                 resources.MaxGeometryImageUniforms);
-        symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                                 ImmutableString("gl_MaxGeometryTextureImageUnits"),
-                                                 resources.MaxGeometryTextureImageUnits);
-        symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                                 ImmutableString("gl_MaxGeometryOutputVertices"),
-                                                 resources.MaxGeometryOutputVertices);
-        symbolTable.insertConstIntExt<EbpMedium>(
-            ESSL3_1_BUILTINS, ext, ImmutableString("gl_MaxGeometryTotalOutputComponents"),
-            resources.MaxGeometryTotalOutputComponents);
-        symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                                 ImmutableString("gl_MaxGeometryUniformComponents"),
-                                                 resources.MaxGeometryUniformComponents);
-        symbolTable.insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
-                                                 ImmutableString("gl_MaxGeometryAtomicCounters"),
-                                                 resources.MaxGeometryAtomicCounters);
-        symbolTable.insertConstIntExt<EbpMedium>(
-            ESSL3_1_BUILTINS, ext, ImmutableString("gl_MaxGeometryAtomicCounterBuffers"),
-            resources.MaxGeometryAtomicCounterBuffers);
-    }
-}
-
-void IdentifyBuiltIns(sh::GLenum type,
-                      ShShaderSpec spec,
-                      const ShBuiltInResources &resources,
-                      TSymbolTable &symbolTable)
-{
-    //
-    // Insert some special built-in variables that are not in
-    // the built-in header files.
-    //
-
-    if (resources.OVR_multiview && type != GL_COMPUTE_SHADER)
-    {
-        const TType *viewIDType = StaticType::Get<EbtUInt, EbpHigh, EvqViewIDOVR, 1, 1>();
-        symbolTable.insertVariableExt(ESSL3_BUILTINS, TExtension::OVR_multiview,
-                                      ImmutableString("gl_ViewID_OVR"), viewIDType);
-
-        // ESSL 1.00 doesn't have unsigned integers, so gl_ViewID_OVR is a signed integer in ESSL
-        // 1.00. This is specified in the WEBGL_multiview spec.
-        const TType *viewIDIntType = StaticType::Get<EbtInt, EbpHigh, EvqViewIDOVR, 1, 1>();
-        symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::OVR_multiview,
-                                      ImmutableString("gl_ViewID_OVR"), viewIDIntType);
-    }
-
-    const TType *positionType    = StaticType::Get<EbtFloat, EbpHigh, EvqPosition, 4, 1>();
-    const TType *primitiveIDType = StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>();
-    const TType *layerType       = StaticType::Get<EbtInt, EbpHigh, EvqLayer, 1, 1>();
-
-    switch (type)
-    {
-        case GL_FRAGMENT_SHADER:
-        {
-            const TType *fragCoordType = StaticType::Get<EbtFloat, EbpMedium, EvqFragCoord, 4, 1>();
-            symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_FragCoord"),
-                                       fragCoordType);
-            const TType *frontFacingType = StaticType::GetQualified<EbtBool, EvqFrontFacing>();
-            symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_FrontFacing"),
-                                       frontFacingType);
-            const TType *pointCoordType =
-                StaticType::Get<EbtFloat, EbpMedium, EvqPointCoord, 2, 1>();
-            symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_PointCoord"),
-                                       pointCoordType);
-
-            const TType *fragColorType = StaticType::Get<EbtFloat, EbpMedium, EvqFragColor, 4, 1>();
-            symbolTable.insertVariable(ESSL1_BUILTINS, ImmutableString("gl_FragColor"),
-                                       fragColorType);
-
-            TType *fragDataType = new TType(EbtFloat, EbpMedium, EvqFragData, 4);
-            if (spec != SH_WEBGL2_SPEC && spec != SH_WEBGL3_SPEC)
-            {
-                fragDataType->makeArray(resources.MaxDrawBuffers);
-            }
-            else
-            {
-                fragDataType->makeArray(1u);
-            }
-            fragDataType->realize();
-            symbolTable.insertVariable(ESSL1_BUILTINS, ImmutableString("gl_FragData"),
-                                       fragDataType);
-
-            if (resources.EXT_blend_func_extended)
-            {
-                const TType *secondaryFragColorType =
-                    StaticType::Get<EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4, 1>();
-                symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
-                                              ImmutableString("gl_SecondaryFragColorEXT"),
-                                              secondaryFragColorType);
-                TType *secondaryFragDataType =
-                    new TType(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1);
-                secondaryFragDataType->makeArray(resources.MaxDualSourceDrawBuffers);
-                secondaryFragDataType->realize();
-                symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
-                                              ImmutableString("gl_SecondaryFragDataEXT"),
-                                              secondaryFragDataType);
-            }
-
-            if (resources.EXT_frag_depth)
-            {
-                TType *fragDepthEXTType =
-                    new TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
-                              EvqFragDepthEXT, 1);
-                fragDepthEXTType->realize();
-                symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_frag_depth,
-                                              ImmutableString("gl_FragDepthEXT"), fragDepthEXTType);
-            }
-
-            const TType *fragDepthType = StaticType::Get<EbtFloat, EbpHigh, EvqFragDepth, 1, 1>();
-            symbolTable.insertVariable(ESSL3_BUILTINS, ImmutableString("gl_FragDepth"),
-                                       fragDepthType);
-
-            const TType *lastFragColorType =
-                StaticType::Get<EbtFloat, EbpMedium, EvqLastFragColor, 4, 1>();
-
-            if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
-            {
-                TType *lastFragDataType = new TType(EbtFloat, EbpMedium, EvqLastFragData, 4, 1);
-                lastFragDataType->makeArray(resources.MaxDrawBuffers);
-                lastFragDataType->realize();
-
-                if (resources.EXT_shader_framebuffer_fetch)
-                {
-                    symbolTable.insertVariableExt(
-                        ESSL1_BUILTINS, TExtension::EXT_shader_framebuffer_fetch,
-                        ImmutableString("gl_LastFragData"), lastFragDataType);
-                }
-                else if (resources.NV_shader_framebuffer_fetch)
-                {
-                    symbolTable.insertVariableExt(
-                        ESSL1_BUILTINS, TExtension::NV_shader_framebuffer_fetch,
-                        ImmutableString("gl_LastFragColor"), lastFragColorType);
-                    symbolTable.insertVariableExt(
-                        ESSL1_BUILTINS, TExtension::NV_shader_framebuffer_fetch,
-                        ImmutableString("gl_LastFragData"), lastFragDataType);
-                }
-            }
-            else if (resources.ARM_shader_framebuffer_fetch)
-            {
-                symbolTable.insertVariableExt(
-                    ESSL1_BUILTINS, TExtension::ARM_shader_framebuffer_fetch,
-                    ImmutableString("gl_LastFragColorARM"), lastFragColorType);
-            }
-
-            if (resources.EXT_geometry_shader)
-            {
-                TExtension extension = TExtension::EXT_geometry_shader;
-                symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
-                                              ImmutableString("gl_PrimitiveID"), primitiveIDType);
-                symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
-                                              ImmutableString("gl_Layer"), layerType);
-            }
-
-            break;
-        }
-        case GL_VERTEX_SHADER:
-        {
-            symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_Position"),
-                                       positionType);
-            const TType *pointSizeType = StaticType::Get<EbtFloat, EbpMedium, EvqPointSize, 1, 1>();
-            symbolTable.insertVariable(COMMON_BUILTINS, ImmutableString("gl_PointSize"),
-                                       pointSizeType);
-            const TType *instanceIDType = StaticType::Get<EbtInt, EbpHigh, EvqInstanceID, 1, 1>();
-            symbolTable.insertVariable(ESSL3_BUILTINS, ImmutableString("gl_InstanceID"),
-                                       instanceIDType);
-            const TType *vertexIDType = StaticType::Get<EbtInt, EbpHigh, EvqVertexID, 1, 1>();
-            symbolTable.insertVariable(ESSL3_BUILTINS, ImmutableString("gl_VertexID"),
-                                       vertexIDType);
-
-            // For internal use by ANGLE - not exposed to the parser.
-            const TType *viewportIndexType =
-                StaticType::Get<EbtInt, EbpHigh, EvqViewportIndex, 1, 1>();
-            symbolTable.insertVariable(GLSL_BUILTINS, ImmutableString("gl_ViewportIndex"),
-                                       viewportIndexType);
-            // gl_Layer exists in other shader stages in ESSL, but not in vertex shader so far.
-            symbolTable.insertVariable(GLSL_BUILTINS, ImmutableString("gl_Layer"), layerType);
-            break;
-        }
-        case GL_COMPUTE_SHADER:
-        {
-            const TType *numWorkGroupsType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqNumWorkGroups, 3, 1>();
-            symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_NumWorkGroups"),
-                                       numWorkGroupsType);
-            const TType *workGroupSizeType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupSize, 3, 1>();
-            symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_WorkGroupSize"),
-                                       workGroupSizeType);
-            const TType *workGroupIDType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupID, 3, 1>();
-            symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_WorkGroupID"),
-                                       workGroupIDType);
-            const TType *localInvocationIDType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationID, 3, 1>();
-            symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_LocalInvocationID"),
-                                       localInvocationIDType);
-            const TType *globalInvocationIDType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3, 1>();
-            symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_GlobalInvocationID"),
-                                       globalInvocationIDType);
-            const TType *localInvocationIndexType =
-                StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1, 1>();
-            symbolTable.insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_LocalInvocationIndex"),
-                                       localInvocationIndexType);
-            break;
-        }
-
-        case GL_GEOMETRY_SHADER_EXT:
-        {
-            TExtension extension = TExtension::EXT_geometry_shader;
-
-            // Add built-in interface block gl_PerVertex and the built-in array gl_in.
-            // TODO(jiawei.shao@intel.com): implement GL_EXT_geometry_point_size.
-            TFieldList *glPerVertexFieldList = new TFieldList();
-            TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
-            TField *glPositionField =
-                new TField(new TType(*positionType), ImmutableString("gl_Position"), zeroSourceLoc);
-            glPerVertexFieldList->push_back(glPositionField);
-
-            const ImmutableString glPerVertexString("gl_PerVertex");
-            TInterfaceBlock *glPerVertexInBlock =
-                new TInterfaceBlock(&symbolTable, glPerVertexString, glPerVertexFieldList,
-                                    TLayoutQualifier::Create(), SymbolType::BuiltIn, extension);
-            symbolTable.insertInterfaceBlock(ESSL3_1_BUILTINS, glPerVertexInBlock);
-
-            // The array size of gl_in is undefined until we get a valid input primitive
-            // declaration.
-            TType *glInType =
-                new TType(glPerVertexInBlock, EvqPerVertexIn, TLayoutQualifier::Create());
-            glInType->makeArray(0u);
-            glInType->realize();
-            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_in"),
-                                          glInType);
-
-            TInterfaceBlock *glPerVertexOutBlock =
-                new TInterfaceBlock(&symbolTable, glPerVertexString, glPerVertexFieldList,
-                                    TLayoutQualifier::Create(), SymbolType::BuiltIn);
-            TType *glPositionInBlockType = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
-            glPositionInBlockType->setInterfaceBlock(glPerVertexOutBlock);
-            glPositionInBlockType->realize();
-            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
-                                          ImmutableString("gl_Position"), glPositionInBlockType);
-
-            const TType *primitiveIDInType =
-                StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveIDIn, 1, 1>();
-            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
-                                          ImmutableString("gl_PrimitiveIDIn"), primitiveIDInType);
-            const TType *invocationIDType =
-                StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>();
-            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
-                                          ImmutableString("gl_InvocationID"), invocationIDType);
-            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension,
-                                          ImmutableString("gl_PrimitiveID"), primitiveIDType);
-            symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_Layer"),
-                                          layerType);
-
-            break;
-        }
-        default:
-            UNREACHABLE();
-    }
-}
-
 void InitExtensionBehavior(const ShBuiltInResources &resources, TExtensionBehavior &extBehavior)
 {
     if (resources.OES_standard_derivatives)
diff --git a/src/compiler/translator/Initialize.h b/src/compiler/translator/Initialize.h
index 2e61218..290af56 100644
--- a/src/compiler/translator/Initialize.h
+++ b/src/compiler/translator/Initialize.h
@@ -14,16 +14,6 @@
 namespace sh
 {
 
-void InsertBuiltInFunctions(sh::GLenum type,
-                            ShShaderSpec spec,
-                            const ShBuiltInResources &resources,
-                            TSymbolTable &table);
-
-void IdentifyBuiltIns(sh::GLenum type,
-                      ShShaderSpec spec,
-                      const ShBuiltInResources &resources,
-                      TSymbolTable &symbolTable);
-
 void InitExtensionBehavior(const ShBuiltInResources &resources,
                            TExtensionBehavior &extensionBehavior);
 
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index f183edb..d844dbf 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -13,6 +13,7 @@
 
 #include "compiler/translator/SymbolTable.h"
 
+#include "angle_gl.h"
 #include "compiler/translator/ImmutableString.h"
 #include "compiler/translator/IntermNode.h"
 
@@ -381,6 +382,49 @@
     return insert(level, interfaceBlock);
 }
 
+template <TPrecision precision>
+bool TSymbolTable::insertConstInt(ESymbolLevel level, const ImmutableString &name, int value)
+{
+    TVariable *constant = new TVariable(
+        this, name, StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(), SymbolType::BuiltIn);
+    TConstantUnion *unionArray = new TConstantUnion[1];
+    unionArray[0].setIConst(value);
+    constant->shareConstPointer(unionArray);
+    return insert(level, constant);
+}
+
+template <TPrecision precision>
+bool TSymbolTable::insertConstIntExt(ESymbolLevel level,
+                                     TExtension ext,
+                                     const ImmutableString &name,
+                                     int value)
+{
+    TVariable *constant = new TVariable(
+        this, name, StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(), SymbolType::BuiltIn, ext);
+    TConstantUnion *unionArray = new TConstantUnion[1];
+    unionArray[0].setIConst(value);
+    constant->shareConstPointer(unionArray);
+    return insert(level, constant);
+}
+
+template <TPrecision precision>
+bool TSymbolTable::insertConstIvec3(ESymbolLevel level,
+                                    const ImmutableString &name,
+                                    const std::array<int, 3> &values)
+{
+    TVariable *constantIvec3 = new TVariable(
+        this, name, StaticType::Get<EbtInt, precision, EvqConst, 3, 1>(), SymbolType::BuiltIn);
+
+    TConstantUnion *unionArray = new TConstantUnion[3];
+    for (size_t index = 0u; index < 3u; ++index)
+    {
+        unionArray[index].setIConst(values[index]);
+    }
+    constantIvec3->shareConstPointer(unionArray);
+
+    return insert(level, constantIvec3);
+}
+
 void TSymbolTable::insertBuiltIn(ESymbolLevel level,
                                  TOperator op,
                                  TExtension ext,
@@ -696,4 +740,1070 @@
     return ++mUniqueIdCounter;
 }
 
+void TSymbolTable::initializeBuiltIns(sh::GLenum type,
+                                      ShShaderSpec spec,
+                                      const ShBuiltInResources &resources)
+{
+    ASSERT(isEmpty());
+    push();  // COMMON_BUILTINS
+    push();  // ESSL1_BUILTINS
+    push();  // ESSL3_BUILTINS
+    push();  // ESSL3_1_BUILTINS
+    push();  // GLSL_BUILTINS
+
+    switch (type)
+    {
+        case GL_FRAGMENT_SHADER:
+            setDefaultPrecision(EbtInt, EbpMedium);
+            break;
+        case GL_VERTEX_SHADER:
+        case GL_COMPUTE_SHADER:
+        case GL_GEOMETRY_SHADER_EXT:
+            setDefaultPrecision(EbtInt, EbpHigh);
+            setDefaultPrecision(EbtFloat, EbpHigh);
+            break;
+        default:
+            UNREACHABLE();
+    }
+    // Set defaults for sampler types that have default precision, even those that are
+    // only available if an extension exists.
+    // New sampler types in ESSL3 don't have default precision. ESSL1 types do.
+    initSamplerDefaultPrecision(EbtSampler2D);
+    initSamplerDefaultPrecision(EbtSamplerCube);
+    // SamplerExternalOES is specified in the extension to have default precision.
+    initSamplerDefaultPrecision(EbtSamplerExternalOES);
+    // SamplerExternal2DY2YEXT is specified in the extension to have default precision.
+    initSamplerDefaultPrecision(EbtSamplerExternal2DY2YEXT);
+    // It isn't specified whether Sampler2DRect has default precision.
+    initSamplerDefaultPrecision(EbtSampler2DRect);
+
+    setDefaultPrecision(EbtAtomicCounter, EbpHigh);
+
+    initializeBuiltInFunctions(type, spec, resources);
+    initializeBuiltInVariables(type, spec, resources);
+    markBuiltInInitializationFinished();
+}
+
+void TSymbolTable::initSamplerDefaultPrecision(TBasicType samplerType)
+{
+    ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd);
+    setDefaultPrecision(samplerType, EbpLow);
+}
+
+void TSymbolTable::initializeBuiltInFunctions(sh::GLenum type,
+                                              ShShaderSpec spec,
+                                              const ShBuiltInResources &resources)
+{
+    const TType *voidType = StaticType::GetBasic<EbtVoid>();
+    const TType *float1   = StaticType::GetBasic<EbtFloat>();
+    const TType *float2   = StaticType::GetBasic<EbtFloat, 2>();
+    const TType *float3   = StaticType::GetBasic<EbtFloat, 3>();
+    const TType *float4   = StaticType::GetBasic<EbtFloat, 4>();
+    const TType *int1     = StaticType::GetBasic<EbtInt>();
+    const TType *int2     = StaticType::GetBasic<EbtInt, 2>();
+    const TType *int3     = StaticType::GetBasic<EbtInt, 3>();
+    const TType *uint1    = StaticType::GetBasic<EbtUInt>();
+    const TType *bool1    = StaticType::GetBasic<EbtBool>();
+    const TType *genType  = StaticType::GetBasic<EbtGenType>();
+    const TType *genIType = StaticType::GetBasic<EbtGenIType>();
+    const TType *genUType = StaticType::GetBasic<EbtGenUType>();
+    const TType *genBType = StaticType::GetBasic<EbtGenBType>();
+
+    //
+    // Angle and Trigonometric Functions.
+    //
+    insertBuiltInOp(COMMON_BUILTINS, EOpRadians, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpDegrees, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpSin, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpCos, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpTan, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpAsin, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpAcos, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpAtan, genType, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpAtan, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpSinh, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpCosh, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpTanh, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpAsinh, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpAcosh, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpAtanh, genType, genType);
+
+    //
+    // Exponential Functions.
+    //
+    insertBuiltInOp(COMMON_BUILTINS, EOpPow, genType, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpExp, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpLog, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpExp2, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpLog2, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpSqrt, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpInverseSqrt, genType, genType);
+
+    //
+    // Common Functions.
+    //
+    insertBuiltInOp(COMMON_BUILTINS, EOpAbs, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpAbs, genIType, genIType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpSign, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpSign, genIType, genIType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpFloor, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpTrunc, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpRound, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpRoundEven, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpCeil, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpFract, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpMod, genType, genType, float1);
+    insertBuiltInOp(COMMON_BUILTINS, EOpMod, genType, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpMin, genType, genType, float1);
+    insertBuiltInOp(COMMON_BUILTINS, EOpMin, genType, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genIType, genIType, genIType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genIType, genIType, int1);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genUType, genUType, genUType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genUType, genUType, uint1);
+    insertBuiltInOp(COMMON_BUILTINS, EOpMax, genType, genType, float1);
+    insertBuiltInOp(COMMON_BUILTINS, EOpMax, genType, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genIType, genIType, genIType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genIType, genIType, int1);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genUType, genUType, genUType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genUType, genUType, uint1);
+    insertBuiltInOp(COMMON_BUILTINS, EOpClamp, genType, genType, float1, float1);
+    insertBuiltInOp(COMMON_BUILTINS, EOpClamp, genType, genType, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genIType, genIType, int1, int1);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genIType, genIType, genIType, genIType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genUType, genUType, uint1, uint1);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genUType, genUType, genUType, genUType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, float1);
+    insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMix, genType, genType, genType, genBType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, float1, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpSmoothStep, genType, genType, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpSmoothStep, genType, float1, float1, genType);
+
+    const TType *outGenType  = StaticType::GetQualified<EbtGenType, EvqOut>();
+    const TType *outGenIType = StaticType::GetQualified<EbtGenIType, EvqOut>();
+
+    insertBuiltInOp(ESSL3_BUILTINS, EOpModf, genType, genType, outGenType);
+
+    insertBuiltInOp(ESSL3_BUILTINS, EOpIsNan, genBType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpIsInf, genBType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToUint, genUType, genType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpIntBitsToFloat, genType, genIType);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpUintBitsToFloat, genType, genUType);
+
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpFrexp, genType, genType, outGenIType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpLdexp, genType, genType, genIType);
+
+    insertBuiltInOp(ESSL3_BUILTINS, EOpPackSnorm2x16, uint1, float2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpPackUnorm2x16, uint1, float2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpPackHalf2x16, uint1, float2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackSnorm2x16, float2, uint1);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, uint1);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, uint1);
+
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackUnorm4x8, uint1, float4);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackSnorm4x8, uint1, float4);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackUnorm4x8, float4, uint1);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackSnorm4x8, float4, uint1);
+
+    //
+    // Geometric Functions.
+    //
+    insertBuiltInOp(COMMON_BUILTINS, EOpLength, float1, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpDistance, float1, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpDot, float1, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpCross, float3, float3, float3);
+    insertBuiltInOp(COMMON_BUILTINS, EOpNormalize, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpFaceforward, genType, genType, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpReflect, genType, genType, genType);
+    insertBuiltInOp(COMMON_BUILTINS, EOpRefract, genType, genType, genType, float1);
+
+    const TType *mat2   = StaticType::GetBasic<EbtFloat, 2, 2>();
+    const TType *mat3   = StaticType::GetBasic<EbtFloat, 3, 3>();
+    const TType *mat4   = StaticType::GetBasic<EbtFloat, 4, 4>();
+    const TType *mat2x3 = StaticType::GetBasic<EbtFloat, 2, 3>();
+    const TType *mat3x2 = StaticType::GetBasic<EbtFloat, 3, 2>();
+    const TType *mat2x4 = StaticType::GetBasic<EbtFloat, 2, 4>();
+    const TType *mat4x2 = StaticType::GetBasic<EbtFloat, 4, 2>();
+    const TType *mat3x4 = StaticType::GetBasic<EbtFloat, 3, 4>();
+    const TType *mat4x3 = StaticType::GetBasic<EbtFloat, 4, 3>();
+
+    //
+    // Matrix Functions.
+    //
+    insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat2, mat2, mat2);
+    insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat3, mat3, mat3);
+    insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat4, mat4, mat4);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat2x3, mat2x3, mat2x3);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat3x2, mat3x2, mat3x2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat2x4, mat2x4, mat2x4);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat4x2, mat4x2, mat4x2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat3x4, mat3x4, mat3x4);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat4x3, mat4x3, mat4x3);
+
+    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2, float2, float2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3, float3, float3);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4, float4, float4);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2x3, float3, float2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3x2, float2, float3);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2x4, float4, float2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4x2, float2, float4);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3x4, float4, float3);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4x3, float3, float4);
+
+    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2, mat2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3, mat3);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4, mat4);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2x3, mat3x2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3x2, mat2x3);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2x4, mat4x2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4x2, mat2x4);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3x4, mat4x3);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4x3, mat3x4);
+
+    insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat3);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat4);
+
+    insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat2, mat2);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat3, mat3);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat4, mat4);
+
+    const TType *vec  = StaticType::GetBasic<EbtVec>();
+    const TType *ivec = StaticType::GetBasic<EbtIVec>();
+    const TType *uvec = StaticType::GetBasic<EbtUVec>();
+    const TType *bvec = StaticType::GetBasic<EbtBVec>();
+
+    //
+    // Vector relational functions.
+    //
+    insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, vec, vec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, ivec, ivec);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpLessThanComponentWise, bvec, uvec, uvec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpLessThanEqualComponentWise, bvec, vec, vec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpLessThanEqualComponentWise, bvec, ivec, ivec);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpLessThanEqualComponentWise, bvec, uvec, uvec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanComponentWise, bvec, vec, vec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanComponentWise, bvec, ivec, ivec);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpGreaterThanComponentWise, bvec, uvec, uvec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, vec, vec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, ivec, ivec);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, uvec, uvec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, vec, vec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, ivec, ivec);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpEqualComponentWise, bvec, uvec, uvec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, bvec, bvec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, vec, vec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, ivec, ivec);
+    insertBuiltInOp(ESSL3_BUILTINS, EOpNotEqualComponentWise, bvec, uvec, uvec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, bvec, bvec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpAny, bool1, bvec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpAll, bool1, bvec);
+    insertBuiltInOp(COMMON_BUILTINS, EOpLogicalNotComponentWise, bvec, bvec);
+
+    //
+    // Integer functions
+    //
+    const TType *outGenUType = StaticType::GetQualified<EbtGenUType, EvqOut>();
+
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genIType, genIType, int1, int1);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genUType, genUType, int1, int1);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genIType, genIType, genIType, int1, int1);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genUType, genUType, genUType, int1, int1);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldReverse, genIType, genIType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldReverse, genUType, genUType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitCount, genIType, genIType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitCount, genIType, genUType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindLSB, genIType, genIType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindLSB, genIType, genUType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindMSB, genIType, genIType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindMSB, genIType, genUType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpUaddCarry, genUType, genUType, genUType, outGenUType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpUsubBorrow, genUType, genUType, genUType, outGenUType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpUmulExtended, voidType, genUType, genUType, outGenUType,
+                    outGenUType);
+    insertBuiltInOp(ESSL3_1_BUILTINS, EOpImulExtended, voidType, genIType, genIType, outGenIType,
+                    outGenIType);
+
+    const TType *sampler2D   = StaticType::GetBasic<EbtSampler2D>();
+    const TType *samplerCube = StaticType::GetBasic<EbtSamplerCube>();
+
+    //
+    // Texture Functions for GLSL ES 1.0
+    //
+    insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2);
+    insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3);
+    insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4);
+    insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3);
+
+    if (resources.OES_EGL_image_external || resources.NV_EGL_stream_consumer_external)
+    {
+        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
+
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", samplerExternalOES, float2);
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float3);
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float4);
+    }
+
+    if (resources.ARB_texture_rectangle)
+    {
+        const TType *sampler2DRect = StaticType::GetBasic<EbtSampler2DRect>();
+
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRect", sampler2DRect, float2);
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, float3);
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, float4);
+    }
+
+    if (resources.EXT_shader_texture_lod)
+    {
+        /* The *Grad* variants are new to both vertex and fragment shaders; the fragment
+         * shader specific pieces are added separately below.
+         */
+        insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
+                      "texture2DGradEXT", sampler2D, float2, float2, float2);
+        insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
+                      "texture2DProjGradEXT", sampler2D, float3, float2, float2);
+        insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
+                      "texture2DProjGradEXT", sampler2D, float4, float2, float2);
+        insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
+                      "textureCubeGradEXT", samplerCube, float3, float3, float3);
+    }
+
+    if (type == GL_FRAGMENT_SHADER)
+    {
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2, float1);
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3, float1);
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4, float1);
+        insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3, float1);
+
+        if (resources.OES_standard_derivatives)
+        {
+            insertBuiltInOp(ESSL1_BUILTINS, EOpDFdx, TExtension::OES_standard_derivatives, genType,
+                            genType);
+            insertBuiltInOp(ESSL1_BUILTINS, EOpDFdy, TExtension::OES_standard_derivatives, genType,
+                            genType);
+            insertBuiltInOp(ESSL1_BUILTINS, EOpFwidth, TExtension::OES_standard_derivatives,
+                            genType, genType);
+        }
+
+        if (resources.EXT_shader_texture_lod)
+        {
+            insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
+                          "texture2DLodEXT", sampler2D, float2, float1);
+            insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
+                          "texture2DProjLodEXT", sampler2D, float3, float1);
+            insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
+                          "texture2DProjLodEXT", sampler2D, float4, float1);
+            insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4,
+                          "textureCubeLodEXT", samplerCube, float3, float1);
+        }
+    }
+
+    if (type == GL_VERTEX_SHADER)
+    {
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLod", sampler2D, float2, float1);
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float3, float1);
+        insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float4, float1);
+        insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLod", samplerCube, float3, float1);
+    }
+
+    const TType *gvec4 = StaticType::GetBasic<EbtGVec4>();
+
+    const TType *gsampler2D      = StaticType::GetBasic<EbtGSampler2D>();
+    const TType *gsamplerCube    = StaticType::GetBasic<EbtGSamplerCube>();
+    const TType *gsampler3D      = StaticType::GetBasic<EbtGSampler3D>();
+    const TType *gsampler2DArray = StaticType::GetBasic<EbtGSampler2DArray>();
+    const TType *gsampler2DMS    = StaticType::GetBasic<EbtGSampler2DMS>();
+
+    //
+    // Texture Functions for GLSL ES 3.0
+    //
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2D, float2, float1);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler3D, float3, float1);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1);
+
+    if (resources.OES_EGL_image_external_essl3)
+    {
+        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
+
+        insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2);
+        insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES, float3);
+        insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES, float4);
+    }
+
+    if (resources.EXT_YUV_target)
+    {
+        const TType *samplerExternal2DY2YEXT = StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
+
+        insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture",
+                      samplerExternal2DY2YEXT, float2);
+        insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
+                      samplerExternal2DY2YEXT, float3);
+        insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
+                      samplerExternal2DY2YEXT, float4);
+
+        const TType *yuvCscStandardEXT = StaticType::GetBasic<EbtYuvCscStandardEXT>();
+
+        insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "rgb_2_yuv", float3,
+                      yuvCscStandardEXT);
+        insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "yuv_2_rgb", float3,
+                      yuvCscStandardEXT);
+    }
+
+    if (type == GL_FRAGMENT_SHADER)
+    {
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1);
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3, float1);
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3, float1);
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3, float1);
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1);
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1);
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1);
+
+        if (resources.OES_EGL_image_external_essl3)
+        {
+            const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
+
+            insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2, float1);
+            insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES, float3,
+                          float1);
+            insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES, float4,
+                          float1);
+        }
+
+        if (resources.EXT_YUV_target)
+        {
+            const TType *samplerExternal2DY2YEXT =
+                StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
+
+            insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture",
+                          samplerExternal2DY2YEXT, float2, float1);
+            insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
+                          samplerExternal2DY2YEXT, float3, float1);
+            insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj",
+                          samplerExternal2DY2YEXT, float4, float1);
+        }
+    }
+
+    const TType *sampler2DShadow      = StaticType::GetBasic<EbtSampler2DShadow>();
+    const TType *samplerCubeShadow    = StaticType::GetBasic<EbtSamplerCubeShadow>();
+    const TType *sampler2DArrayShadow = StaticType::GetBasic<EbtSampler2DArrayShadow>();
+
+    insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DArrayShadow, float4);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureLod", sampler2DShadow, float3, float1);
+
+    if (type == GL_FRAGMENT_SHADER)
+    {
+        insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3, float1);
+        insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4, float1);
+        insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4, float1);
+    }
+
+    insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2D, int1);
+    insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler3D, int1);
+    insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsamplerCube, int1);
+    insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler2DArray, int1);
+    insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", sampler2DShadow, int1);
+    insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1);
+    insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1);
+    insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2DMS);
+
+    if (resources.OES_EGL_image_external_essl3)
+    {
+        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
+
+        insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerExternalOES, int1);
+    }
+
+    if (resources.EXT_YUV_target)
+    {
+        const TType *samplerExternal2DY2YEXT = StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
+
+        insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, int2, "textureSize",
+                      samplerExternal2DY2YEXT, int1);
+    }
+
+    if (type == GL_FRAGMENT_SHADER)
+    {
+        insertBuiltInOp(ESSL3_BUILTINS, EOpDFdx, genType, genType);
+        insertBuiltInOp(ESSL3_BUILTINS, EOpDFdy, genType, genType);
+        insertBuiltInOp(ESSL3_BUILTINS, EOpFwidth, genType, genType);
+    }
+
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2);
+
+    if (type == GL_FRAGMENT_SHADER)
+    {
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2, float1);
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3, float1);
+        insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2,
+                      float1);
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2,
+                      float1);
+    }
+
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2);
+
+    if (type == GL_FRAGMENT_SHADER)
+    {
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2, float1);
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2, float1);
+        insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3, float1);
+        insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2,
+                      float1);
+    }
+
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2D, float2, float1, int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler3D, float3, float1, int3);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureLodOffset", sampler2DShadow, float3, float1,
+                  int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2DArray, float3, float1, int2);
+
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float3, float1);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float4, float1);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler3D, float4, float1);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLod", sampler2DShadow, float4, float1);
+
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float3, float1, int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float4, float1, int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler3D, float4, float1, int3);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLodOffset", sampler2DShadow, float4, float1,
+                  int2);
+
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2D, int2, int1);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler3D, int3, int1);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2DArray, int3, int1);
+
+    if (resources.OES_EGL_image_external_essl3)
+    {
+        const TType *samplerExternalOES = StaticType::GetBasic<EbtSamplerExternalOES>();
+
+        insertBuiltIn(ESSL3_BUILTINS, float4, "texelFetch", samplerExternalOES, int2, int1);
+    }
+
+    if (resources.EXT_YUV_target)
+    {
+        const TType *samplerExternal2DY2YEXT = StaticType::GetBasic<EbtSamplerExternal2DY2YEXT>();
+
+        insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texelFetch",
+                      samplerExternal2DY2YEXT, int2, int1);
+    }
+
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1, int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1, int3);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3, int1, int2);
+
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2D, float2, float2, float2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler3D, float3, float3, float3);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsamplerCube, float3, float3, float3);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DShadow, float3, float2, float2);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", samplerCubeShadow, float4, float3, float3);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2DArray, float3, float2, float2);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DArrayShadow, float4, float2,
+                  float2);
+
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2D, float2, float2, float2,
+                  int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler3D, float3, float3, float3,
+                  int3);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DShadow, float3, float2,
+                  float2, int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2DArray, float3, float2,
+                  float2, int2);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DArrayShadow, float4, float2,
+                  float2, int2);
+
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float3, float2, float2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float4, float2, float2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler3D, float4, float3, float3);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGrad", sampler2DShadow, float4, float2,
+                  float2);
+
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float3, float2,
+                  float2, int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float4, float2,
+                  float2, int2);
+    insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4, float3,
+                  float3, int3);
+    insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow, float4, float2,
+                  float2, int2);
+
+    const TType *atomicCounter = StaticType::GetBasic<EbtAtomicCounter>();
+    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounter", atomicCounter);
+    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterIncrement", atomicCounter);
+    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterDecrement", atomicCounter);
+
+    // Insert all atomic memory functions
+    const TType *int1InOut  = StaticType::GetQualified<EbtInt, EvqInOut>();
+    const TType *uint1InOut = StaticType::GetQualified<EbtUInt, EvqInOut>();
+    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAdd", uint1InOut, uint1);
+    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAdd", int1InOut, int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMin", uint1InOut, uint1);
+    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMin", int1InOut, int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMax", uint1InOut, uint1);
+    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMax", int1InOut, int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAnd", uint1InOut, uint1);
+    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAnd", int1InOut, int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicOr", uint1InOut, uint1);
+    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicOr", int1InOut, int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicXor", uint1InOut, uint1);
+    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicXor", int1InOut, int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicExchange", uint1InOut, uint1);
+    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicExchange", int1InOut, int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCompSwap", uint1InOut, uint1, uint1);
+    insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicCompSwap", int1InOut, int1, int1);
+
+    const TType *gimage2D      = StaticType::GetBasic<EbtGImage2D>();
+    const TType *gimage3D      = StaticType::GetBasic<EbtGImage3D>();
+    const TType *gimage2DArray = StaticType::GetBasic<EbtGImage2DArray>();
+    const TType *gimageCube    = StaticType::GetBasic<EbtGImageCube>();
+
+    insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2D, int2, gvec4);
+    insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage3D, int3, gvec4);
+    insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2DArray, int3, gvec4);
+    insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimageCube, int3, gvec4);
+
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2D, int2);
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage3D, int3);
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2DArray, int3);
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimageCube, int3);
+
+    insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimage2D);
+    insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage3D);
+    insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage2DArray);
+    insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimageCube);
+
+    insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrier, voidType,
+                                      "memoryBarrier");
+    insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierAtomicCounter, voidType,
+                                      "memoryBarrierAtomicCounter");
+    insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierBuffer, voidType,
+                                      "memoryBarrierBuffer");
+    insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierImage, voidType,
+                                      "memoryBarrierImage");
+
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "texelFetch", gsampler2DMS, int2, int1);
+
+    // Insert all variations of textureGather.
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2D, float2);
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2D, float2, int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2DArray, float3);
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2DArray, float3, int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsamplerCube, float3);
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsamplerCube, float3, int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DShadow, float2);
+    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DShadow, float2, float1);
+    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DArrayShadow, float3);
+    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DArrayShadow, float3, float1);
+    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", samplerCubeShadow, float3);
+    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", samplerCubeShadow, float3, float1);
+
+    // Insert all variations of textureGatherOffset.
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2D, float2, int2);
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2D, float2, int2, int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2DArray, float3, int2);
+    insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2DArray, float3, int2,
+                  int1);
+    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGatherOffset", sampler2DShadow, float2, float1,
+                  int2);
+    insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGatherOffset", sampler2DArrayShadow, float3,
+                  float1, int2);
+
+    if (type == GL_COMPUTE_SHADER)
+    {
+        insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpBarrier, voidType, "barrier");
+        insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierShared, voidType,
+                                          "memoryBarrierShared");
+        insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpGroupMemoryBarrier, voidType,
+                                          "groupMemoryBarrier");
+    }
+
+    if (type == GL_GEOMETRY_SHADER_EXT)
+    {
+        TExtension extension = TExtension::EXT_geometry_shader;
+        insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension, EOpEmitVertex, voidType,
+                                             "EmitVertex");
+        insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension, EOpEndPrimitive, voidType,
+                                             "EndPrimitive");
+    }
+}
+
+void TSymbolTable::initializeBuiltInVariables(sh::GLenum type,
+                                              ShShaderSpec spec,
+                                              const ShBuiltInResources &resources)
+{
+    const TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
+
+    //
+    // Depth range in window coordinates
+    //
+    TFieldList *fields = new TFieldList();
+    auto highpFloat1   = new TType(EbtFloat, EbpHigh, EvqGlobal, 1);
+    TField *near       = new TField(highpFloat1, ImmutableString("near"), zeroSourceLoc);
+    TField *far        = new TField(highpFloat1, ImmutableString("far"), zeroSourceLoc);
+    TField *diff       = new TField(highpFloat1, ImmutableString("diff"), zeroSourceLoc);
+    fields->push_back(near);
+    fields->push_back(far);
+    fields->push_back(diff);
+    TStructure *depthRangeStruct = new TStructure(this, ImmutableString("gl_DepthRangeParameters"),
+                                                  fields, SymbolType::BuiltIn);
+    insertStructType(COMMON_BUILTINS, depthRangeStruct);
+    TType *depthRangeType = new TType(depthRangeStruct);
+    depthRangeType->setQualifier(EvqUniform);
+    depthRangeType->realize();
+    insertVariable(COMMON_BUILTINS, ImmutableString("gl_DepthRange"), depthRangeType);
+
+    //
+    // Implementation dependent built-in constants.
+    //
+    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxVertexAttribs"),
+                              resources.MaxVertexAttribs);
+    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxVertexUniformVectors"),
+                              resources.MaxVertexUniformVectors);
+    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxVertexTextureImageUnits"),
+                              resources.MaxVertexTextureImageUnits);
+    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxCombinedTextureImageUnits"),
+                              resources.MaxCombinedTextureImageUnits);
+    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxTextureImageUnits"),
+                              resources.MaxTextureImageUnits);
+    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxFragmentUniformVectors"),
+                              resources.MaxFragmentUniformVectors);
+
+    insertConstInt<EbpMedium>(ESSL1_BUILTINS, ImmutableString("gl_MaxVaryingVectors"),
+                              resources.MaxVaryingVectors);
+
+    insertConstInt<EbpMedium>(COMMON_BUILTINS, ImmutableString("gl_MaxDrawBuffers"),
+                              resources.MaxDrawBuffers);
+    if (resources.EXT_blend_func_extended)
+    {
+        insertConstIntExt<EbpMedium>(COMMON_BUILTINS, TExtension::EXT_blend_func_extended,
+                                     ImmutableString("gl_MaxDualSourceDrawBuffersEXT"),
+                                     resources.MaxDualSourceDrawBuffers);
+    }
+
+    insertConstInt<EbpMedium>(ESSL3_BUILTINS, ImmutableString("gl_MaxVertexOutputVectors"),
+                              resources.MaxVertexOutputVectors);
+    insertConstInt<EbpMedium>(ESSL3_BUILTINS, ImmutableString("gl_MaxFragmentInputVectors"),
+                              resources.MaxFragmentInputVectors);
+    insertConstInt<EbpMedium>(ESSL3_BUILTINS, ImmutableString("gl_MinProgramTexelOffset"),
+                              resources.MinProgramTexelOffset);
+    insertConstInt<EbpMedium>(ESSL3_BUILTINS, ImmutableString("gl_MaxProgramTexelOffset"),
+                              resources.MaxProgramTexelOffset);
+
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxImageUnits"),
+                              resources.MaxImageUnits);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxVertexImageUniforms"),
+                              resources.MaxVertexImageUniforms);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxFragmentImageUniforms"),
+                              resources.MaxFragmentImageUniforms);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeImageUniforms"),
+                              resources.MaxComputeImageUniforms);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxCombinedImageUniforms"),
+                              resources.MaxCombinedImageUniforms);
+
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+                              ImmutableString("gl_MaxCombinedShaderOutputResources"),
+                              resources.MaxCombinedShaderOutputResources);
+
+    insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeWorkGroupCount"),
+                              resources.MaxComputeWorkGroupCount);
+    insertConstIvec3<EbpHigh>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeWorkGroupSize"),
+                              resources.MaxComputeWorkGroupSize);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeUniformComponents"),
+                              resources.MaxComputeUniformComponents);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeTextureImageUnits"),
+                              resources.MaxComputeTextureImageUnits);
+
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxComputeAtomicCounters"),
+                              resources.MaxComputeAtomicCounters);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+                              ImmutableString("gl_MaxComputeAtomicCounterBuffers"),
+                              resources.MaxComputeAtomicCounterBuffers);
+
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxVertexAtomicCounters"),
+                              resources.MaxVertexAtomicCounters);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxFragmentAtomicCounters"),
+                              resources.MaxFragmentAtomicCounters);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxCombinedAtomicCounters"),
+                              resources.MaxCombinedAtomicCounters);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxAtomicCounterBindings"),
+                              resources.MaxAtomicCounterBindings);
+
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxVertexAtomicCounterBuffers"),
+                              resources.MaxVertexAtomicCounterBuffers);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+                              ImmutableString("gl_MaxFragmentAtomicCounterBuffers"),
+                              resources.MaxFragmentAtomicCounterBuffers);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS,
+                              ImmutableString("gl_MaxCombinedAtomicCounterBuffers"),
+                              resources.MaxCombinedAtomicCounterBuffers);
+    insertConstInt<EbpMedium>(ESSL3_1_BUILTINS, ImmutableString("gl_MaxAtomicCounterBufferSize"),
+                              resources.MaxAtomicCounterBufferSize);
+
+    if (resources.EXT_geometry_shader)
+    {
+        TExtension ext = TExtension::EXT_geometry_shader;
+        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
+                                     ImmutableString("gl_MaxGeometryInputComponents"),
+                                     resources.MaxGeometryInputComponents);
+        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
+                                     ImmutableString("gl_MaxGeometryOutputComponents"),
+                                     resources.MaxGeometryOutputComponents);
+        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
+                                     ImmutableString("gl_MaxGeometryImageUniforms"),
+                                     resources.MaxGeometryImageUniforms);
+        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
+                                     ImmutableString("gl_MaxGeometryTextureImageUnits"),
+                                     resources.MaxGeometryTextureImageUnits);
+        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
+                                     ImmutableString("gl_MaxGeometryOutputVertices"),
+                                     resources.MaxGeometryOutputVertices);
+        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
+                                     ImmutableString("gl_MaxGeometryTotalOutputComponents"),
+                                     resources.MaxGeometryTotalOutputComponents);
+        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
+                                     ImmutableString("gl_MaxGeometryUniformComponents"),
+                                     resources.MaxGeometryUniformComponents);
+        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
+                                     ImmutableString("gl_MaxGeometryAtomicCounters"),
+                                     resources.MaxGeometryAtomicCounters);
+        insertConstIntExt<EbpMedium>(ESSL3_1_BUILTINS, ext,
+                                     ImmutableString("gl_MaxGeometryAtomicCounterBuffers"),
+                                     resources.MaxGeometryAtomicCounterBuffers);
+    }
+
+    //
+    // Insert some special built-in variables that are not in
+    // the built-in header files.
+    //
+
+    if (resources.OVR_multiview && type != GL_COMPUTE_SHADER)
+    {
+        const TType *viewIDType = StaticType::Get<EbtUInt, EbpHigh, EvqViewIDOVR, 1, 1>();
+        insertVariableExt(ESSL3_BUILTINS, TExtension::OVR_multiview,
+                          ImmutableString("gl_ViewID_OVR"), viewIDType);
+
+        // ESSL 1.00 doesn't have unsigned integers, so gl_ViewID_OVR is a signed integer in ESSL
+        // 1.00. This is specified in the WEBGL_multiview spec.
+        const TType *viewIDIntType = StaticType::Get<EbtInt, EbpHigh, EvqViewIDOVR, 1, 1>();
+        insertVariableExt(ESSL1_BUILTINS, TExtension::OVR_multiview,
+                          ImmutableString("gl_ViewID_OVR"), viewIDIntType);
+    }
+
+    const TType *positionType    = StaticType::Get<EbtFloat, EbpHigh, EvqPosition, 4, 1>();
+    const TType *primitiveIDType = StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>();
+    const TType *layerType       = StaticType::Get<EbtInt, EbpHigh, EvqLayer, 1, 1>();
+
+    switch (type)
+    {
+        case GL_FRAGMENT_SHADER:
+        {
+            const TType *fragCoordType = StaticType::Get<EbtFloat, EbpMedium, EvqFragCoord, 4, 1>();
+            insertVariable(COMMON_BUILTINS, ImmutableString("gl_FragCoord"), fragCoordType);
+            const TType *frontFacingType = StaticType::GetQualified<EbtBool, EvqFrontFacing>();
+            insertVariable(COMMON_BUILTINS, ImmutableString("gl_FrontFacing"), frontFacingType);
+            const TType *pointCoordType =
+                StaticType::Get<EbtFloat, EbpMedium, EvqPointCoord, 2, 1>();
+            insertVariable(COMMON_BUILTINS, ImmutableString("gl_PointCoord"), pointCoordType);
+
+            const TType *fragColorType = StaticType::Get<EbtFloat, EbpMedium, EvqFragColor, 4, 1>();
+            insertVariable(ESSL1_BUILTINS, ImmutableString("gl_FragColor"), fragColorType);
+
+            TType *fragDataType = new TType(EbtFloat, EbpMedium, EvqFragData, 4);
+            if (spec != SH_WEBGL2_SPEC && spec != SH_WEBGL3_SPEC)
+            {
+                fragDataType->makeArray(resources.MaxDrawBuffers);
+            }
+            else
+            {
+                fragDataType->makeArray(1u);
+            }
+            fragDataType->realize();
+            insertVariable(ESSL1_BUILTINS, ImmutableString("gl_FragData"), fragDataType);
+
+            if (resources.EXT_blend_func_extended)
+            {
+                const TType *secondaryFragColorType =
+                    StaticType::Get<EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4, 1>();
+                insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
+                                  ImmutableString("gl_SecondaryFragColorEXT"),
+                                  secondaryFragColorType);
+                TType *secondaryFragDataType =
+                    new TType(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1);
+                secondaryFragDataType->makeArray(resources.MaxDualSourceDrawBuffers);
+                secondaryFragDataType->realize();
+                insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended,
+                                  ImmutableString("gl_SecondaryFragDataEXT"),
+                                  secondaryFragDataType);
+            }
+
+            if (resources.EXT_frag_depth)
+            {
+                TType *fragDepthEXTType =
+                    new TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
+                              EvqFragDepthEXT, 1);
+                fragDepthEXTType->realize();
+                insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_frag_depth,
+                                  ImmutableString("gl_FragDepthEXT"), fragDepthEXTType);
+            }
+
+            const TType *fragDepthType = StaticType::Get<EbtFloat, EbpHigh, EvqFragDepth, 1, 1>();
+            insertVariable(ESSL3_BUILTINS, ImmutableString("gl_FragDepth"), fragDepthType);
+
+            const TType *lastFragColorType =
+                StaticType::Get<EbtFloat, EbpMedium, EvqLastFragColor, 4, 1>();
+
+            if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
+            {
+                TType *lastFragDataType = new TType(EbtFloat, EbpMedium, EvqLastFragData, 4, 1);
+                lastFragDataType->makeArray(resources.MaxDrawBuffers);
+                lastFragDataType->realize();
+
+                if (resources.EXT_shader_framebuffer_fetch)
+                {
+                    insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_shader_framebuffer_fetch,
+                                      ImmutableString("gl_LastFragData"), lastFragDataType);
+                }
+                else if (resources.NV_shader_framebuffer_fetch)
+                {
+                    insertVariableExt(ESSL1_BUILTINS, TExtension::NV_shader_framebuffer_fetch,
+                                      ImmutableString("gl_LastFragColor"), lastFragColorType);
+                    insertVariableExt(ESSL1_BUILTINS, TExtension::NV_shader_framebuffer_fetch,
+                                      ImmutableString("gl_LastFragData"), lastFragDataType);
+                }
+            }
+            else if (resources.ARM_shader_framebuffer_fetch)
+            {
+                insertVariableExt(ESSL1_BUILTINS, TExtension::ARM_shader_framebuffer_fetch,
+                                  ImmutableString("gl_LastFragColorARM"), lastFragColorType);
+            }
+
+            if (resources.EXT_geometry_shader)
+            {
+                TExtension extension = TExtension::EXT_geometry_shader;
+                insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_PrimitiveID"),
+                                  primitiveIDType);
+                insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_Layer"),
+                                  layerType);
+            }
+
+            break;
+        }
+        case GL_VERTEX_SHADER:
+        {
+            insertVariable(COMMON_BUILTINS, ImmutableString("gl_Position"), positionType);
+            const TType *pointSizeType = StaticType::Get<EbtFloat, EbpMedium, EvqPointSize, 1, 1>();
+            insertVariable(COMMON_BUILTINS, ImmutableString("gl_PointSize"), pointSizeType);
+            const TType *instanceIDType = StaticType::Get<EbtInt, EbpHigh, EvqInstanceID, 1, 1>();
+            insertVariable(ESSL3_BUILTINS, ImmutableString("gl_InstanceID"), instanceIDType);
+            const TType *vertexIDType = StaticType::Get<EbtInt, EbpHigh, EvqVertexID, 1, 1>();
+            insertVariable(ESSL3_BUILTINS, ImmutableString("gl_VertexID"), vertexIDType);
+
+            // For internal use by ANGLE - not exposed to the parser.
+            const TType *viewportIndexType =
+                StaticType::Get<EbtInt, EbpHigh, EvqViewportIndex, 1, 1>();
+            insertVariable(GLSL_BUILTINS, ImmutableString("gl_ViewportIndex"), viewportIndexType);
+            // gl_Layer exists in other shader stages in ESSL, but not in vertex shader so far.
+            insertVariable(GLSL_BUILTINS, ImmutableString("gl_Layer"), layerType);
+            break;
+        }
+        case GL_COMPUTE_SHADER:
+        {
+            const TType *numWorkGroupsType =
+                StaticType::Get<EbtUInt, EbpUndefined, EvqNumWorkGroups, 3, 1>();
+            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_NumWorkGroups"),
+                           numWorkGroupsType);
+            const TType *workGroupSizeType =
+                StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupSize, 3, 1>();
+            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_WorkGroupSize"),
+                           workGroupSizeType);
+            const TType *workGroupIDType =
+                StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupID, 3, 1>();
+            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_WorkGroupID"), workGroupIDType);
+            const TType *localInvocationIDType =
+                StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationID, 3, 1>();
+            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_LocalInvocationID"),
+                           localInvocationIDType);
+            const TType *globalInvocationIDType =
+                StaticType::Get<EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3, 1>();
+            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_GlobalInvocationID"),
+                           globalInvocationIDType);
+            const TType *localInvocationIndexType =
+                StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1, 1>();
+            insertVariable(ESSL3_1_BUILTINS, ImmutableString("gl_LocalInvocationIndex"),
+                           localInvocationIndexType);
+            break;
+        }
+
+        case GL_GEOMETRY_SHADER_EXT:
+        {
+            TExtension extension = TExtension::EXT_geometry_shader;
+
+            // Add built-in interface block gl_PerVertex and the built-in array gl_in.
+            // TODO(jiawei.shao@intel.com): implement GL_EXT_geometry_point_size.
+            TFieldList *glPerVertexFieldList = new TFieldList();
+            TField *glPositionField =
+                new TField(new TType(*positionType), ImmutableString("gl_Position"), zeroSourceLoc);
+            glPerVertexFieldList->push_back(glPositionField);
+
+            const ImmutableString glPerVertexString("gl_PerVertex");
+            TInterfaceBlock *glPerVertexInBlock =
+                new TInterfaceBlock(this, glPerVertexString, glPerVertexFieldList,
+                                    TLayoutQualifier::Create(), SymbolType::BuiltIn, extension);
+            insertInterfaceBlock(ESSL3_1_BUILTINS, glPerVertexInBlock);
+
+            // The array size of gl_in is undefined until we get a valid input primitive
+            // declaration.
+            TType *glInType =
+                new TType(glPerVertexInBlock, EvqPerVertexIn, TLayoutQualifier::Create());
+            glInType->makeArray(0u);
+            glInType->realize();
+            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_in"), glInType);
+
+            TInterfaceBlock *glPerVertexOutBlock =
+                new TInterfaceBlock(this, glPerVertexString, glPerVertexFieldList,
+                                    TLayoutQualifier::Create(), SymbolType::BuiltIn);
+            TType *glPositionInBlockType = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+            glPositionInBlockType->setInterfaceBlock(glPerVertexOutBlock);
+            glPositionInBlockType->realize();
+            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_Position"),
+                              glPositionInBlockType);
+
+            const TType *primitiveIDInType =
+                StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveIDIn, 1, 1>();
+            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_PrimitiveIDIn"),
+                              primitiveIDInType);
+            const TType *invocationIDType =
+                StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>();
+            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_InvocationID"),
+                              invocationIDType);
+            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_PrimitiveID"),
+                              primitiveIDType);
+            insertVariableExt(ESSL3_1_BUILTINS, extension, ImmutableString("gl_Layer"), layerType);
+
+            break;
+        }
+        default:
+            UNREACHABLE();
+    }
+}
+
 }  // namespace sh
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index 089e069..5ff31a6 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -90,6 +90,66 @@
     // Functions are always declared at global scope.
     void declareUserDefinedFunction(TFunction *function, bool insertUnmangledName);
 
+    // These return the TFunction pointer to keep using to refer to this function.
+    const TFunction *markUserDefinedFunctionHasPrototypeDeclaration(
+        const ImmutableString &mangledName,
+        bool *hadPrototypeDeclarationOut);
+    const TFunction *setUserDefinedFunctionParameterNamesFromDefinition(const TFunction *function,
+                                                                        bool *wasDefinedOut);
+
+    // find() is guaranteed not to retain a reference to the ImmutableString, so an ImmutableString
+    // with a reference to a short-lived char * is fine to pass here.
+    const TSymbol *find(const ImmutableString &name, int shaderVersion) const;
+
+    const TSymbol *findGlobal(const ImmutableString &name) const;
+
+    const TSymbol *findBuiltIn(const ImmutableString &name, int shaderVersion) const;
+
+    const TSymbol *findBuiltIn(const ImmutableString &name,
+                               int shaderVersion,
+                               bool includeGLSLBuiltins) const;
+
+    void setDefaultPrecision(TBasicType type, TPrecision prec)
+    {
+        int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
+        // Uses map operator [], overwrites the current value
+        (*precisionStack[indexOfLastElement])[type] = prec;
+    }
+
+    // Searches down the precisionStack for a precision qualifier
+    // for the specified TBasicType
+    TPrecision getDefaultPrecision(TBasicType type) const;
+
+    // This records invariant varyings declared through
+    // "invariant varying_name;".
+    void addInvariantVarying(const std::string &originalName);
+
+    // If this returns false, the varying could still be invariant
+    // if it is set as invariant during the varying variable
+    // declaration - this piece of information is stored in the
+    // variable's type, not here.
+    bool isVaryingInvariant(const std::string &originalName) const;
+
+    void setGlobalInvariant(bool invariant);
+
+    const TSymbolUniqueId nextUniqueId() { return TSymbolUniqueId(this); }
+
+    // Checks whether there is a built-in accessible by a shader with the specified version.
+    bool hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion);
+
+    void initializeBuiltIns(sh::GLenum type,
+                            ShShaderSpec spec,
+                            const ShBuiltInResources &resources);
+    void clearCompilationResults();
+
+  private:
+    friend class TSymbolUniqueId;
+    int nextUniqueIdValue();
+
+    class TSymbolTableLevel;
+
+    ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
+
     // The insert* entry points are used when initializing the symbol table with built-ins.
     // They return the created symbol / true in case the declaration was successful, and nullptr /
     // false if the declaration failed due to redefinition.
@@ -187,64 +247,6 @@
                                               const TType *rvalue,
                                               const char *name);
 
-    // These return the TFunction pointer to keep using to refer to this function.
-    const TFunction *markUserDefinedFunctionHasPrototypeDeclaration(
-        const ImmutableString &mangledName,
-        bool *hadPrototypeDeclarationOut);
-    const TFunction *setUserDefinedFunctionParameterNamesFromDefinition(const TFunction *function,
-                                                                        bool *wasDefinedOut);
-
-    // find() is guaranteed not to retain a reference to the ImmutableString, so an ImmutableString
-    // with a reference to a short-lived char * is fine to pass here.
-    const TSymbol *find(const ImmutableString &name, int shaderVersion) const;
-
-    const TSymbol *findGlobal(const ImmutableString &name) const;
-
-    const TSymbol *findBuiltIn(const ImmutableString &name, int shaderVersion) const;
-
-    const TSymbol *findBuiltIn(const ImmutableString &name,
-                               int shaderVersion,
-                               bool includeGLSLBuiltins) const;
-
-    void setDefaultPrecision(TBasicType type, TPrecision prec)
-    {
-        int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
-        // Uses map operator [], overwrites the current value
-        (*precisionStack[indexOfLastElement])[type] = prec;
-    }
-
-    // Searches down the precisionStack for a precision qualifier
-    // for the specified TBasicType
-    TPrecision getDefaultPrecision(TBasicType type) const;
-
-    // This records invariant varyings declared through
-    // "invariant varying_name;".
-    void addInvariantVarying(const std::string &originalName);
-
-    // If this returns false, the varying could still be invariant
-    // if it is set as invariant during the varying variable
-    // declaration - this piece of information is stored in the
-    // variable's type, not here.
-    bool isVaryingInvariant(const std::string &originalName) const;
-
-    void setGlobalInvariant(bool invariant);
-
-    const TSymbolUniqueId nextUniqueId() { return TSymbolUniqueId(this); }
-
-    // Checks whether there is a built-in accessible by a shader with the specified version.
-    bool hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion);
-
-    void markBuiltInInitializationFinished();
-    void clearCompilationResults();
-
-  private:
-    friend class TSymbolUniqueId;
-    int nextUniqueIdValue();
-
-    class TSymbolTableLevel;
-
-    ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }
-
     TVariable *insertVariable(ESymbolLevel level,
                               const ImmutableString &name,
                               const TType *type,
@@ -260,6 +262,16 @@
 
     bool hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level);
 
+    void initSamplerDefaultPrecision(TBasicType samplerType);
+
+    void initializeBuiltInFunctions(sh::GLenum type,
+                                    ShShaderSpec spec,
+                                    const ShBuiltInResources &resources);
+    void initializeBuiltInVariables(sh::GLenum type,
+                                    ShShaderSpec spec,
+                                    const ShBuiltInResources &resources);
+    void markBuiltInInitializationFinished();
+
     std::vector<TSymbolTableLevel *> table;
     typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
     std::vector<PrecisionStackLevel *> precisionStack;
@@ -272,49 +284,6 @@
     int mUserDefinedUniqueIdsStart;
 };
 
-template <TPrecision precision>
-bool TSymbolTable::insertConstInt(ESymbolLevel level, const ImmutableString &name, int value)
-{
-    TVariable *constant = new TVariable(
-        this, name, StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(), SymbolType::BuiltIn);
-    TConstantUnion *unionArray = new TConstantUnion[1];
-    unionArray[0].setIConst(value);
-    constant->shareConstPointer(unionArray);
-    return insert(level, constant);
-}
-
-template <TPrecision precision>
-bool TSymbolTable::insertConstIntExt(ESymbolLevel level,
-                                     TExtension ext,
-                                     const ImmutableString &name,
-                                     int value)
-{
-    TVariable *constant = new TVariable(
-        this, name, StaticType::Get<EbtInt, precision, EvqConst, 1, 1>(), SymbolType::BuiltIn, ext);
-    TConstantUnion *unionArray = new TConstantUnion[1];
-    unionArray[0].setIConst(value);
-    constant->shareConstPointer(unionArray);
-    return insert(level, constant);
-}
-
-template <TPrecision precision>
-bool TSymbolTable::insertConstIvec3(ESymbolLevel level,
-                                    const ImmutableString &name,
-                                    const std::array<int, 3> &values)
-{
-    TVariable *constantIvec3 = new TVariable(
-        this, name, StaticType::Get<EbtInt, precision, EvqConst, 3, 1>(), SymbolType::BuiltIn);
-
-    TConstantUnion *unionArray = new TConstantUnion[3];
-    for (size_t index = 0u; index < 3u; ++index)
-    {
-        unionArray[index].setIConst(values[index]);
-    }
-    constantIvec3->shareConstPointer(unionArray);
-
-    return insert(level, constantIvec3);
-}
-
 }  // namespace sh
 
 #endif  // COMPILER_TRANSLATOR_SYMBOLTABLE_H_