Add support for GL_NV_shader_invocation_reorder. (#3054)
[platform/upstream/glslang.git] / glslang / MachineIndependent / Scan.cpp
index 31ed7cf..c20048a 100644 (file)
@@ -2,6 +2,8 @@
 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
 // Copyright (C) 2013 LunarG, Inc.
 // Copyright (C) 2017 ARM Limited.
+// Copyright (C) 2020 Google, Inc.
+// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 //
 // All rights reserved.
 //
@@ -187,17 +189,15 @@ bool TInputScanner::scanVersion(int& version, EProfile& profile, bool& notFirstT
         if (lookingInMiddle) {
             notFirstToken = true;
             // make forward progress by finishing off the current line plus extra new lines
-            if (peek() == '\n' || peek() == '\r') {
-                while (peek() == '\n' || peek() == '\r')
-                    get();
-            } else
+            if (peek() != '\n' && peek() != '\r') {
                 do {
                     c = get();
                 } while (c != EndOfInput && c != '\n' && c != '\r');
-                while (peek() == '\n' || peek() == '\r')
-                    get();
-                if (peek() == EndOfInput)
-                    return true;
+            }
+            while (peek() == '\n' || peek() == '\r')
+                get();
+            if (peek() == EndOfInput)
+                return true;
         }
         lookingInMiddle = true;
 
@@ -324,7 +324,9 @@ struct str_hash
 // A single global usable by all threads, by all versions, by all languages.
 // After a single process-level initialization, this is read only and thread safe
 std::unordered_map<const char*, int, str_hash, str_eq>* KeywordMap = nullptr;
+#ifndef GLSLANG_WEB
 std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
+#endif
 
 };
 
@@ -341,9 +343,15 @@ void TScanContext::fillInKeywordMap()
 
     (*KeywordMap)["const"] =                   CONST;
     (*KeywordMap)["uniform"] =                 UNIFORM;
-    (*KeywordMap)["nonuniformEXT"] =           NONUNIFORM;
+    (*KeywordMap)["buffer"] =                  BUFFER;
     (*KeywordMap)["in"] =                      IN;
     (*KeywordMap)["out"] =                     OUT;
+    (*KeywordMap)["smooth"] =                  SMOOTH;
+    (*KeywordMap)["flat"] =                    FLAT;
+    (*KeywordMap)["centroid"] =                CENTROID;
+    (*KeywordMap)["invariant"] =               INVARIANT;
+    (*KeywordMap)["packed"] =                  PACKED;
+    (*KeywordMap)["resource"] =                RESOURCE;
     (*KeywordMap)["inout"] =                   INOUT;
     (*KeywordMap)["struct"] =                  STRUCT;
     (*KeywordMap)["break"] =                   BREAK;
@@ -357,6 +365,9 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["if"] =                      IF;
     (*KeywordMap)["else"] =                    ELSE;
     (*KeywordMap)["discard"] =                 DISCARD;
+    (*KeywordMap)["terminateInvocation"] =     TERMINATE_INVOCATION;
+    (*KeywordMap)["terminateRayEXT"] =         TERMINATE_RAY;
+    (*KeywordMap)["ignoreIntersectionEXT"] =   IGNORE_INTERSECTION;
     (*KeywordMap)["return"] =                  RETURN;
     (*KeywordMap)["void"] =                    VOID;
     (*KeywordMap)["bool"] =                    BOOL;
@@ -376,38 +387,48 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["mat4"] =                    MAT4;
     (*KeywordMap)["true"] =                    BOOLCONSTANT;
     (*KeywordMap)["false"] =                   BOOLCONSTANT;
+    (*KeywordMap)["layout"] =                  LAYOUT;
+    (*KeywordMap)["shared"] =                  SHARED;
+    (*KeywordMap)["highp"] =                   HIGH_PRECISION;
+    (*KeywordMap)["mediump"] =                 MEDIUM_PRECISION;
+    (*KeywordMap)["lowp"] =                    LOW_PRECISION;
+    (*KeywordMap)["superp"] =                  SUPERP;
+    (*KeywordMap)["precision"] =               PRECISION;
+    (*KeywordMap)["mat2x2"] =                  MAT2X2;
+    (*KeywordMap)["mat2x3"] =                  MAT2X3;
+    (*KeywordMap)["mat2x4"] =                  MAT2X4;
+    (*KeywordMap)["mat3x2"] =                  MAT3X2;
+    (*KeywordMap)["mat3x3"] =                  MAT3X3;
+    (*KeywordMap)["mat3x4"] =                  MAT3X4;
+    (*KeywordMap)["mat4x2"] =                  MAT4X2;
+    (*KeywordMap)["mat4x3"] =                  MAT4X3;
+    (*KeywordMap)["mat4x4"] =                  MAT4X4;
+    (*KeywordMap)["uint"] =                    UINT;
+    (*KeywordMap)["uvec2"] =                   UVEC2;
+    (*KeywordMap)["uvec3"] =                   UVEC3;
+    (*KeywordMap)["uvec4"] =                   UVEC4;
+
+#ifndef GLSLANG_WEB
+    (*KeywordMap)["nonuniformEXT"] =           NONUNIFORM;
+    (*KeywordMap)["demote"] =                  DEMOTE;
     (*KeywordMap)["attribute"] =               ATTRIBUTE;
     (*KeywordMap)["varying"] =                 VARYING;
-    (*KeywordMap)["buffer"] =                  BUFFER;
+    (*KeywordMap)["noperspective"] =           NOPERSPECTIVE;
     (*KeywordMap)["coherent"] =                COHERENT;
     (*KeywordMap)["devicecoherent"] =          DEVICECOHERENT;
     (*KeywordMap)["queuefamilycoherent"] =     QUEUEFAMILYCOHERENT;
     (*KeywordMap)["workgroupcoherent"] =       WORKGROUPCOHERENT;
     (*KeywordMap)["subgroupcoherent"] =        SUBGROUPCOHERENT;
+    (*KeywordMap)["shadercallcoherent"] =      SHADERCALLCOHERENT;
     (*KeywordMap)["nonprivate"] =              NONPRIVATE;
     (*KeywordMap)["restrict"] =                RESTRICT;
     (*KeywordMap)["readonly"] =                READONLY;
     (*KeywordMap)["writeonly"] =               WRITEONLY;
     (*KeywordMap)["atomic_uint"] =             ATOMIC_UINT;
     (*KeywordMap)["volatile"] =                VOLATILE;
-    (*KeywordMap)["layout"] =                  LAYOUT;
-    (*KeywordMap)["shared"] =                  SHARED;
     (*KeywordMap)["patch"] =                   PATCH;
     (*KeywordMap)["sample"] =                  SAMPLE;
     (*KeywordMap)["subroutine"] =              SUBROUTINE;
-    (*KeywordMap)["highp"] =                   HIGH_PRECISION;
-    (*KeywordMap)["mediump"] =                 MEDIUM_PRECISION;
-    (*KeywordMap)["lowp"] =                    LOW_PRECISION;
-    (*KeywordMap)["precision"] =               PRECISION;
-    (*KeywordMap)["mat2x2"] =                  MAT2X2;
-    (*KeywordMap)["mat2x3"] =                  MAT2X3;
-    (*KeywordMap)["mat2x4"] =                  MAT2X4;
-    (*KeywordMap)["mat3x2"] =                  MAT3X2;
-    (*KeywordMap)["mat3x3"] =                  MAT3X3;
-    (*KeywordMap)["mat3x4"] =                  MAT3X4;
-    (*KeywordMap)["mat4x2"] =                  MAT4X2;
-    (*KeywordMap)["mat4x3"] =                  MAT4X3;
-    (*KeywordMap)["mat4x4"] =                  MAT4X4;
     (*KeywordMap)["dmat2"] =                   DMAT2;
     (*KeywordMap)["dmat3"] =                   DMAT3;
     (*KeywordMap)["dmat4"] =                   DMAT4;
@@ -453,15 +474,32 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["image2DMSArray"] =          IMAGE2DMSARRAY;
     (*KeywordMap)["iimage2DMSArray"] =         IIMAGE2DMSARRAY;
     (*KeywordMap)["uimage2DMSArray"] =         UIMAGE2DMSARRAY;
+    (*KeywordMap)["i64image1D"] =              I64IMAGE1D;
+    (*KeywordMap)["u64image1D"] =              U64IMAGE1D;
+    (*KeywordMap)["i64image2D"] =              I64IMAGE2D;
+    (*KeywordMap)["u64image2D"] =              U64IMAGE2D;
+    (*KeywordMap)["i64image3D"] =              I64IMAGE3D;
+    (*KeywordMap)["u64image3D"] =              U64IMAGE3D;
+    (*KeywordMap)["i64image2DRect"] =          I64IMAGE2DRECT;
+    (*KeywordMap)["u64image2DRect"] =          U64IMAGE2DRECT;
+    (*KeywordMap)["i64imageCube"] =            I64IMAGECUBE;
+    (*KeywordMap)["u64imageCube"] =            U64IMAGECUBE;
+    (*KeywordMap)["i64imageBuffer"] =          I64IMAGEBUFFER;
+    (*KeywordMap)["u64imageBuffer"] =          U64IMAGEBUFFER;
+    (*KeywordMap)["i64image1DArray"] =         I64IMAGE1DARRAY;
+    (*KeywordMap)["u64image1DArray"] =         U64IMAGE1DARRAY;
+    (*KeywordMap)["i64image2DArray"] =         I64IMAGE2DARRAY;
+    (*KeywordMap)["u64image2DArray"] =         U64IMAGE2DARRAY;
+    (*KeywordMap)["i64imageCubeArray"] =       I64IMAGECUBEARRAY;
+    (*KeywordMap)["u64imageCubeArray"] =       U64IMAGECUBEARRAY;
+    (*KeywordMap)["i64image2DMS"] =            I64IMAGE2DMS;
+    (*KeywordMap)["u64image2DMS"] =            U64IMAGE2DMS;
+    (*KeywordMap)["i64image2DMSArray"] =       I64IMAGE2DMSARRAY;
+    (*KeywordMap)["u64image2DMSArray"] =       U64IMAGE2DMSARRAY;
     (*KeywordMap)["double"] =                  DOUBLE;
     (*KeywordMap)["dvec2"] =                   DVEC2;
     (*KeywordMap)["dvec3"] =                   DVEC3;
     (*KeywordMap)["dvec4"] =                   DVEC4;
-    (*KeywordMap)["uint"] =                    UINT;
-    (*KeywordMap)["uvec2"] =                   UVEC2;
-    (*KeywordMap)["uvec3"] =                   UVEC3;
-    (*KeywordMap)["uvec4"] =                   UVEC4;
-
     (*KeywordMap)["int64_t"] =                 INT64_T;
     (*KeywordMap)["uint64_t"] =                UINT64_T;
     (*KeywordMap)["i64vec2"] =                 I64VEC2;
@@ -471,7 +509,7 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["u64vec3"] =                 U64VEC3;
     (*KeywordMap)["u64vec4"] =                 U64VEC4;
 
-    // GL_KHX_shader_explicit_arithmetic_types
+    // GL_EXT_shader_explicit_arithmetic_types
     (*KeywordMap)["int8_t"] =                  INT8_T;
     (*KeywordMap)["i8vec2"] =                  I8VEC2;
     (*KeywordMap)["i8vec3"] =                  I8VEC3;
@@ -549,18 +587,21 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["f64mat4x3"] =               F64MAT4X3;
     (*KeywordMap)["f64mat4x4"] =               F64MAT4X4;
 
+    // GL_EXT_spirv_intrinsics
+    (*KeywordMap)["spirv_instruction"] =       SPIRV_INSTRUCTION;
+    (*KeywordMap)["spirv_execution_mode"] =    SPIRV_EXECUTION_MODE;
+    (*KeywordMap)["spirv_execution_mode_id"] = SPIRV_EXECUTION_MODE_ID;
+    (*KeywordMap)["spirv_decorate"] =          SPIRV_DECORATE;
+    (*KeywordMap)["spirv_decorate_id"] =       SPIRV_DECORATE_ID;
+    (*KeywordMap)["spirv_decorate_string"] =   SPIRV_DECORATE_STRING;
+    (*KeywordMap)["spirv_type"] =              SPIRV_TYPE;
+    (*KeywordMap)["spirv_storage_class"] =     SPIRV_STORAGE_CLASS;
+    (*KeywordMap)["spirv_by_reference"] =      SPIRV_BY_REFERENCE;
+    (*KeywordMap)["spirv_literal"] =           SPIRV_LITERAL;
+#endif
+
     (*KeywordMap)["sampler2D"] =               SAMPLER2D;
     (*KeywordMap)["samplerCube"] =             SAMPLERCUBE;
-    (*KeywordMap)["samplerCubeArray"] =        SAMPLERCUBEARRAY;
-    (*KeywordMap)["samplerCubeArrayShadow"] =  SAMPLERCUBEARRAYSHADOW;
-    (*KeywordMap)["isamplerCubeArray"] =       ISAMPLERCUBEARRAY;
-    (*KeywordMap)["usamplerCubeArray"] =       USAMPLERCUBEARRAY;
-    (*KeywordMap)["sampler1DArrayShadow"] =    SAMPLER1DARRAYSHADOW;
-    (*KeywordMap)["isampler1DArray"] =         ISAMPLER1DARRAY;
-    (*KeywordMap)["usampler1D"] =              USAMPLER1D;
-    (*KeywordMap)["isampler1D"] =              ISAMPLER1D;
-    (*KeywordMap)["usampler1DArray"] =         USAMPLER1DARRAY;
-    (*KeywordMap)["samplerBuffer"] =           SAMPLERBUFFER;
     (*KeywordMap)["samplerCubeShadow"] =       SAMPLERCUBESHADOW;
     (*KeywordMap)["sampler2DArray"] =          SAMPLER2DARRAY;
     (*KeywordMap)["sampler2DArrayShadow"] =    SAMPLER2DARRAYSHADOW;
@@ -572,6 +613,39 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["usampler3D"] =              USAMPLER3D;
     (*KeywordMap)["usamplerCube"] =            USAMPLERCUBE;
     (*KeywordMap)["usampler2DArray"] =         USAMPLER2DARRAY;
+    (*KeywordMap)["sampler3D"] =               SAMPLER3D;
+    (*KeywordMap)["sampler2DShadow"] =         SAMPLER2DSHADOW;
+
+    (*KeywordMap)["texture2D"] =               TEXTURE2D;
+    (*KeywordMap)["textureCube"] =             TEXTURECUBE;
+    (*KeywordMap)["texture2DArray"] =          TEXTURE2DARRAY;
+    (*KeywordMap)["itexture2D"] =              ITEXTURE2D;
+    (*KeywordMap)["itexture3D"] =              ITEXTURE3D;
+    (*KeywordMap)["itextureCube"] =            ITEXTURECUBE;
+    (*KeywordMap)["itexture2DArray"] =         ITEXTURE2DARRAY;
+    (*KeywordMap)["utexture2D"] =              UTEXTURE2D;
+    (*KeywordMap)["utexture3D"] =              UTEXTURE3D;
+    (*KeywordMap)["utextureCube"] =            UTEXTURECUBE;
+    (*KeywordMap)["utexture2DArray"] =         UTEXTURE2DARRAY;
+    (*KeywordMap)["texture3D"] =               TEXTURE3D;
+
+    (*KeywordMap)["sampler"] =                 SAMPLER;
+    (*KeywordMap)["samplerShadow"] =           SAMPLERSHADOW;
+
+#ifndef GLSLANG_WEB
+    (*KeywordMap)["textureCubeArray"] =        TEXTURECUBEARRAY;
+    (*KeywordMap)["itextureCubeArray"] =       ITEXTURECUBEARRAY;
+    (*KeywordMap)["utextureCubeArray"] =       UTEXTURECUBEARRAY;
+    (*KeywordMap)["samplerCubeArray"] =        SAMPLERCUBEARRAY;
+    (*KeywordMap)["samplerCubeArrayShadow"] =  SAMPLERCUBEARRAYSHADOW;
+    (*KeywordMap)["isamplerCubeArray"] =       ISAMPLERCUBEARRAY;
+    (*KeywordMap)["usamplerCubeArray"] =       USAMPLERCUBEARRAY;
+    (*KeywordMap)["sampler1DArrayShadow"] =    SAMPLER1DARRAYSHADOW;
+    (*KeywordMap)["isampler1DArray"] =         ISAMPLER1DARRAY;
+    (*KeywordMap)["usampler1D"] =              USAMPLER1D;
+    (*KeywordMap)["isampler1D"] =              ISAMPLER1D;
+    (*KeywordMap)["usampler1DArray"] =         USAMPLER1DARRAY;
+    (*KeywordMap)["samplerBuffer"] =           SAMPLERBUFFER;
     (*KeywordMap)["isampler2DRect"] =          ISAMPLER2DRECT;
     (*KeywordMap)["usampler2DRect"] =          USAMPLER2DRECT;
     (*KeywordMap)["isamplerBuffer"] =          ISAMPLERBUFFER;
@@ -584,36 +658,19 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["usampler2DMSArray"] =       USAMPLER2DMSARRAY;
     (*KeywordMap)["sampler1D"] =               SAMPLER1D;
     (*KeywordMap)["sampler1DShadow"] =         SAMPLER1DSHADOW;
-    (*KeywordMap)["sampler3D"] =               SAMPLER3D;
-    (*KeywordMap)["sampler2DShadow"] =         SAMPLER2DSHADOW;
     (*KeywordMap)["sampler2DRect"] =           SAMPLER2DRECT;
     (*KeywordMap)["sampler2DRectShadow"] =     SAMPLER2DRECTSHADOW;
     (*KeywordMap)["sampler1DArray"] =          SAMPLER1DARRAY;
 
     (*KeywordMap)["samplerExternalOES"] =      SAMPLEREXTERNALOES; // GL_OES_EGL_image_external
 
-    (*KeywordMap)["sampler"] =                 SAMPLER;
-    (*KeywordMap)["samplerShadow"] =           SAMPLERSHADOW;
+    (*KeywordMap)["__samplerExternal2DY2YEXT"] = SAMPLEREXTERNAL2DY2YEXT; // GL_EXT_YUV_target
 
-    (*KeywordMap)["texture2D"] =               TEXTURE2D;
-    (*KeywordMap)["textureCube"] =             TEXTURECUBE;
-    (*KeywordMap)["textureCubeArray"] =        TEXTURECUBEARRAY;
-    (*KeywordMap)["itextureCubeArray"] =       ITEXTURECUBEARRAY;
-    (*KeywordMap)["utextureCubeArray"] =       UTEXTURECUBEARRAY;
     (*KeywordMap)["itexture1DArray"] =         ITEXTURE1DARRAY;
     (*KeywordMap)["utexture1D"] =              UTEXTURE1D;
     (*KeywordMap)["itexture1D"] =              ITEXTURE1D;
     (*KeywordMap)["utexture1DArray"] =         UTEXTURE1DARRAY;
     (*KeywordMap)["textureBuffer"] =           TEXTUREBUFFER;
-    (*KeywordMap)["texture2DArray"] =          TEXTURE2DARRAY;
-    (*KeywordMap)["itexture2D"] =              ITEXTURE2D;
-    (*KeywordMap)["itexture3D"] =              ITEXTURE3D;
-    (*KeywordMap)["itextureCube"] =            ITEXTURECUBE;
-    (*KeywordMap)["itexture2DArray"] =         ITEXTURE2DARRAY;
-    (*KeywordMap)["utexture2D"] =              UTEXTURE2D;
-    (*KeywordMap)["utexture3D"] =              UTEXTURE3D;
-    (*KeywordMap)["utextureCube"] =            UTEXTURECUBE;
-    (*KeywordMap)["utexture2DArray"] =         UTEXTURE2DARRAY;
     (*KeywordMap)["itexture2DRect"] =          ITEXTURE2DRECT;
     (*KeywordMap)["utexture2DRect"] =          UTEXTURE2DRECT;
     (*KeywordMap)["itextureBuffer"] =          ITEXTUREBUFFER;
@@ -625,7 +682,6 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["itexture2DMSArray"] =       ITEXTURE2DMSARRAY;
     (*KeywordMap)["utexture2DMSArray"] =       UTEXTURE2DMSARRAY;
     (*KeywordMap)["texture1D"] =               TEXTURE1D;
-    (*KeywordMap)["texture3D"] =               TEXTURE3D;
     (*KeywordMap)["texture2DRect"] =           TEXTURE2DRECT;
     (*KeywordMap)["texture1DArray"] =          TEXTURE1DARRAY;
 
@@ -636,7 +692,6 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["usubpassInput"] =           USUBPASSINPUT;
     (*KeywordMap)["usubpassInputMS"] =         USUBPASSINPUTMS;
 
-#ifdef AMD_EXTENSIONS
     (*KeywordMap)["f16sampler1D"] =                 F16SAMPLER1D;
     (*KeywordMap)["f16sampler2D"] =                 F16SAMPLER2D;
     (*KeywordMap)["f16sampler3D"] =                 F16SAMPLER3D;
@@ -682,33 +737,36 @@ void TScanContext::fillInKeywordMap()
 
     (*KeywordMap)["f16subpassInput"] =              F16SUBPASSINPUT;
     (*KeywordMap)["f16subpassInputMS"] =            F16SUBPASSINPUTMS;
-#endif
-
-    (*KeywordMap)["noperspective"] =           NOPERSPECTIVE;
-    (*KeywordMap)["smooth"] =                  SMOOTH;
-    (*KeywordMap)["flat"] =                    FLAT;
-#ifdef AMD_EXTENSIONS
     (*KeywordMap)["__explicitInterpAMD"] =     EXPLICITINTERPAMD;
-#endif
-    (*KeywordMap)["centroid"] =                CENTROID;
-#ifdef NV_EXTENSIONS
     (*KeywordMap)["pervertexNV"] =             PERVERTEXNV;
-#endif
+    (*KeywordMap)["pervertexEXT"] =            PERVERTEXEXT;
     (*KeywordMap)["precise"] =                 PRECISE;
-    (*KeywordMap)["invariant"] =               INVARIANT;
-    (*KeywordMap)["packed"] =                  PACKED;
-    (*KeywordMap)["resource"] =                RESOURCE;
-    (*KeywordMap)["superp"] =                  SUPERP;
 
-#ifdef NV_EXTENSIONS
-    (*KeywordMap)["rayPayloadNVX"] =            PAYLOADNV;
-    (*KeywordMap)["rayPayloadInNVX"] =          PAYLOADINNV;
-    (*KeywordMap)["hitAttributeNVX"] =          HITATTRNV;
-    (*KeywordMap)["accelerationStructureNVX"] = ACCSTRUCTNV;
+    (*KeywordMap)["rayPayloadNV"] =            PAYLOADNV;
+    (*KeywordMap)["rayPayloadEXT"] =           PAYLOADEXT;
+    (*KeywordMap)["rayPayloadInNV"] =          PAYLOADINNV;
+    (*KeywordMap)["rayPayloadInEXT"] =         PAYLOADINEXT;
+    (*KeywordMap)["hitAttributeNV"] =          HITATTRNV;
+    (*KeywordMap)["hitAttributeEXT"] =         HITATTREXT;
+    (*KeywordMap)["callableDataNV"] =          CALLDATANV;
+    (*KeywordMap)["callableDataEXT"] =         CALLDATAEXT;
+    (*KeywordMap)["callableDataInNV"] =        CALLDATAINNV;
+    (*KeywordMap)["callableDataInEXT"] =       CALLDATAINEXT;
+    (*KeywordMap)["accelerationStructureNV"] = ACCSTRUCTNV;
+    (*KeywordMap)["accelerationStructureEXT"]   = ACCSTRUCTEXT;
+    (*KeywordMap)["rayQueryEXT"] =              RAYQUERYEXT;
     (*KeywordMap)["perprimitiveNV"] =          PERPRIMITIVENV;
     (*KeywordMap)["perviewNV"] =               PERVIEWNV;
     (*KeywordMap)["taskNV"] =                  PERTASKNV;
-#endif
+    (*KeywordMap)["perprimitiveEXT"] =         PERPRIMITIVEEXT;
+    (*KeywordMap)["taskPayloadSharedEXT"] =    TASKPAYLOADWORKGROUPEXT;
+
+    (*KeywordMap)["fcoopmatNV"] =              FCOOPMATNV;
+    (*KeywordMap)["icoopmatNV"] =              ICOOPMATNV;
+    (*KeywordMap)["ucoopmatNV"] =              UCOOPMATNV;
+
+    (*KeywordMap)["hitObjectNV"] =             HITOBJECTNV;
+    (*KeywordMap)["hitObjectAttributeNV"] =    HITOBJECTATTRNV;
 
     ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
 
@@ -749,14 +807,17 @@ void TScanContext::fillInKeywordMap()
     ReservedSet->insert("cast");
     ReservedSet->insert("namespace");
     ReservedSet->insert("using");
+#endif
 }
 
 void TScanContext::deleteKeywordMap()
 {
     delete KeywordMap;
     KeywordMap = nullptr;
+#ifndef GLSLANG_WEB
     delete ReservedSet;
     ReservedSet = nullptr;
+#endif
 }
 
 // Called by yylex to get the next token.
@@ -774,7 +835,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
         loc = ppToken.loc;
         parserToken->sType.lex.loc = loc;
         switch (token) {
-        case ';':  afterType = false;   return SEMICOLON;
+        case ';':  afterType = false; afterBuffer = false; return SEMICOLON;
         case ',':  afterType = false;   return COMMA;
         case ':':                       return COLON;
         case '=':  afterType = false;   return EQUAL;
@@ -796,7 +857,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
         case '?':                       return QUESTION;
         case '[':                       return LEFT_BRACKET;
         case ']':                       return RIGHT_BRACKET;
-        case '{':  afterStruct = false; return LEFT_BRACE;
+        case '{':  afterStruct = false; afterBuffer = false; return LEFT_BRACE;
         case '}':                       return RIGHT_BRACE;
         case '\\':
             parseContext.error(loc, "illegal use of escape character", "\\", "");
@@ -833,15 +894,18 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
             parseContext.error(loc, "not supported", "::", "");
             break;
 
+        case PpAtomConstString:        parserToken->sType.lex.string = NewPoolTString(tokenText);     return STRING_LITERAL;
         case PpAtomConstInt:           parserToken->sType.lex.i    = ppToken.ival;       return INTCONSTANT;
         case PpAtomConstUint:          parserToken->sType.lex.i    = ppToken.ival;       return UINTCONSTANT;
+        case PpAtomConstFloat:         parserToken->sType.lex.d    = ppToken.dval;       return FLOATCONSTANT;
+#ifndef GLSLANG_WEB
         case PpAtomConstInt16:         parserToken->sType.lex.i    = ppToken.ival;       return INT16CONSTANT;
         case PpAtomConstUint16:        parserToken->sType.lex.i    = ppToken.ival;       return UINT16CONSTANT;
         case PpAtomConstInt64:         parserToken->sType.lex.i64  = ppToken.i64val;     return INT64CONSTANT;
         case PpAtomConstUint64:        parserToken->sType.lex.i64  = ppToken.i64val;     return UINT64CONSTANT;
-        case PpAtomConstFloat:         parserToken->sType.lex.d    = ppToken.dval;       return FLOATCONSTANT;
         case PpAtomConstDouble:        parserToken->sType.lex.d    = ppToken.dval;       return DOUBLECONSTANT;
         case PpAtomConstFloat16:       parserToken->sType.lex.d    = ppToken.dval;       return FLOAT16CONSTANT;
+#endif
         case PpAtomIdentifier:
         {
             int token = tokenizeIdentifier();
@@ -863,8 +927,10 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
 
 int TScanContext::tokenizeIdentifier()
 {
+#ifndef GLSLANG_WEB
     if (ReservedSet->find(tokenText) != ReservedSet->end())
         return reservedWord();
+#endif
 
     auto it = KeywordMap->find(tokenText);
     if (it == KeywordMap->end()) {
@@ -891,20 +957,33 @@ int TScanContext::tokenizeIdentifier()
     case CASE:
         return keyword;
 
-    case STRUCT:
-        afterStruct = true;
+    case TERMINATE_INVOCATION:
+        if (!parseContext.extensionTurnedOn(E_GL_EXT_terminate_invocation))
+            return identifierOrType();
         return keyword;
 
-    case NONUNIFORM:
-        if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier))
-            return keyword;
-        else
+    case TERMINATE_RAY:
+    case IGNORE_INTERSECTION:
+        if (!parseContext.extensionTurnedOn(E_GL_EXT_ray_tracing))
             return identifierOrType();
+        return keyword;
+
+    case BUFFER:
+        afterBuffer = true;
+        if ((parseContext.isEsProfile() && parseContext.version < 310) ||
+            (!parseContext.isEsProfile() && (parseContext.version < 430 &&
+            !parseContext.extensionTurnedOn(E_GL_ARB_shader_storage_buffer_object))))
+            return identifierOrType();
+        return keyword;
+
+    case STRUCT:
+        afterStruct = true;
+        return keyword;
 
     case SWITCH:
     case DEFAULT:
-        if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
-            (parseContext.profile != EEsProfile && parseContext.version < 130))
+        if ((parseContext.isEsProfile() && parseContext.version < 300) ||
+            (!parseContext.isEsProfile() && parseContext.version < 130))
             reservedWord();
         return keyword;
 
@@ -936,32 +1015,88 @@ int TScanContext::tokenizeIdentifier()
             parserToken->sType.lex.b = false;
         return keyword;
 
-    case ATTRIBUTE:
-    case VARYING:
-        if (parseContext.profile == EEsProfile && parseContext.version >= 300)
+    case SMOOTH:
+        if ((parseContext.isEsProfile() && parseContext.version < 300) ||
+            (!parseContext.isEsProfile() && parseContext.version < 130))
+            return identifierOrType();
+        return keyword;
+    case FLAT:
+        if (parseContext.isEsProfile() && parseContext.version < 300)
             reservedWord();
+        else if (!parseContext.isEsProfile() && parseContext.version < 130)
+            return identifierOrType();
         return keyword;
-
-    case BUFFER:
-        if ((parseContext.profile == EEsProfile && parseContext.version < 310) ||
-            (parseContext.profile != EEsProfile && parseContext.version < 430))
+    case CENTROID:
+        if (parseContext.version < 120)
+            return identifierOrType();
+        return keyword;
+    case INVARIANT:
+        if (!parseContext.isEsProfile() && parseContext.version < 120)
             return identifierOrType();
         return keyword;
+    case PACKED:
+        if ((parseContext.isEsProfile() && parseContext.version < 300) ||
+            (!parseContext.isEsProfile() && parseContext.version < 140))
+            return reservedWord();
+        return identifierOrType();
+
+    case RESOURCE:
+    {
+        bool reserved = (parseContext.isEsProfile() && parseContext.version >= 300) ||
+                        (!parseContext.isEsProfile() && parseContext.version >= 420);
+        return identifierOrReserved(reserved);
+    }
+    case SUPERP:
+    {
+        bool reserved = parseContext.isEsProfile() || parseContext.version >= 130;
+        return identifierOrReserved(reserved);
+    }
 
-#ifdef NV_EXTENSIONS
+#ifndef GLSLANG_WEB
+    case NOPERSPECTIVE:
+        if (parseContext.extensionTurnedOn(E_GL_NV_shader_noperspective_interpolation))
+            return keyword;
+        return es30ReservedFromGLSL(130);
+
+    case NONUNIFORM:
+        if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier))
+            return keyword;
+        else
+            return identifierOrType();
+    case ATTRIBUTE:
+    case VARYING:
+        if (parseContext.isEsProfile() && parseContext.version >= 300)
+            reservedWord();
+        return keyword;
     case PAYLOADNV:
     case PAYLOADINNV:
     case HITATTRNV:
+    case CALLDATANV:
+    case CALLDATAINNV:
     case ACCSTRUCTNV:
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            (parseContext.profile != EEsProfile && parseContext.version >= 460
-                 && parseContext.extensionTurnedOn(E_GL_NVX_raytracing)))
+            parseContext.extensionTurnedOn(E_GL_NV_ray_tracing))
+            return keyword;
+        return identifierOrType();
+    case PAYLOADEXT:
+    case PAYLOADINEXT:
+    case HITATTREXT:
+    case CALLDATAEXT:
+    case CALLDATAINEXT:
+    case ACCSTRUCTEXT:
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_ray_tracing) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_ray_query))
+            return keyword;
+        return identifierOrType();
+    case RAYQUERYEXT:
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            (!parseContext.isEsProfile() && parseContext.version >= 460
+                 && parseContext.extensionTurnedOn(E_GL_EXT_ray_query)))
             return keyword;
         return identifierOrType();
-#endif
-
     case ATOMIC_UINT:
-        if ((parseContext.profile == EEsProfile && parseContext.version >= 310) ||
+        if ((parseContext.isEsProfile() && parseContext.version >= 310) ||
             parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters))
             return keyword;
         return es30ReservedFromGLSL(420);
@@ -971,57 +1106,56 @@ int TScanContext::tokenizeIdentifier()
     case QUEUEFAMILYCOHERENT:
     case WORKGROUPCOHERENT:
     case SUBGROUPCOHERENT:
+    case SHADERCALLCOHERENT:
     case NONPRIVATE:
     case RESTRICT:
     case READONLY:
     case WRITEONLY:
-        if (parseContext.profile == EEsProfile && parseContext.version >= 310)
+        if (parseContext.isEsProfile() && parseContext.version >= 310)
             return keyword;
         return es30ReservedFromGLSL(parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store) ? 130 : 420);
-
     case VOLATILE:
-        if (parseContext.profile == EEsProfile && parseContext.version >= 310)
+        if (parseContext.isEsProfile() && parseContext.version >= 310)
             return keyword;
-        if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile ||
+        if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.isEsProfile() ||
             (parseContext.version < 420 && ! parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))))
             reservedWord();
         return keyword;
-
-    case LAYOUT:
-    {
-        const int numLayoutExts = 2;
-        const char* layoutExts[numLayoutExts] = { E_GL_ARB_shading_language_420pack,
-                                                  E_GL_ARB_explicit_attrib_location };
-        if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
-            (parseContext.profile != EEsProfile && parseContext.version < 140 &&
-            ! parseContext.extensionsTurnedOn(numLayoutExts, layoutExts)))
-            return identifierOrType();
-        return keyword;
-    }
-    case SHARED:
-        if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
-            (parseContext.profile != EEsProfile && parseContext.version < 140))
-            return identifierOrType();
-        return keyword;
-
     case PATCH:
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            (parseContext.profile == EEsProfile &&
+            (parseContext.isEsProfile() &&
              (parseContext.version >= 320 ||
               parseContext.extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))) ||
-            (parseContext.profile != EEsProfile && parseContext.extensionTurnedOn(E_GL_ARB_tessellation_shader)))
+            (!parseContext.isEsProfile() && parseContext.extensionTurnedOn(E_GL_ARB_tessellation_shader)))
             return keyword;
 
         return es30ReservedFromGLSL(400);
 
     case SAMPLE:
-        if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
+        if ((parseContext.isEsProfile() && parseContext.version >= 320) ||
             parseContext.extensionsTurnedOn(1, &E_GL_OES_shader_multisample_interpolation))
             return keyword;
         return es30ReservedFromGLSL(400);
 
     case SUBROUTINE:
         return es30ReservedFromGLSL(400);
+#endif
+    case SHARED:
+        if ((parseContext.isEsProfile() && parseContext.version < 300) ||
+            (!parseContext.isEsProfile() && parseContext.version < 140))
+            return identifierOrType();
+        return keyword;
+    case LAYOUT:
+    {
+        const int numLayoutExts = 2;
+        const char* layoutExts[numLayoutExts] = { E_GL_ARB_shading_language_420pack,
+                                                  E_GL_ARB_explicit_attrib_location };
+        if ((parseContext.isEsProfile() && parseContext.version < 300) ||
+            (!parseContext.isEsProfile() && parseContext.version < 140 &&
+            ! parseContext.extensionsTurnedOn(numLayoutExts, layoutExts)))
+            return identifierOrType();
+        return keyword;
+    }
 
     case HIGH_PRECISION:
     case MEDIUM_PRECISION:
@@ -1040,6 +1174,7 @@ int TScanContext::tokenizeIdentifier()
     case MAT4X4:
         return matNxM();
 
+#ifndef GLSLANG_WEB
     case DMAT2:
     case DMAT3:
     case DMAT4:
@@ -1066,14 +1201,39 @@ int TScanContext::tokenizeIdentifier()
         afterType = true;
         return firstGenerationImage(false);
 
+    case I64IMAGE1D:
+    case U64IMAGE1D:
+    case I64IMAGE1DARRAY:
+    case U64IMAGE1DARRAY:
+    case I64IMAGE2DRECT:
+    case U64IMAGE2DRECT:
+        afterType = true;
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_image_int64)) {
+            return firstGenerationImage(false);
+        }
+        return identifierOrType();
+
     case IMAGEBUFFER:
     case IIMAGEBUFFER:
     case UIMAGEBUFFER:
         afterType = true;
-        if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
+        if ((parseContext.isEsProfile() && parseContext.version >= 320) ||
             parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
             return keyword;
         return firstGenerationImage(false);
+        
+    case I64IMAGEBUFFER:
+    case U64IMAGEBUFFER:
+        afterType = true;        
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_image_int64)) {
+            if ((parseContext.isEsProfile() && parseContext.version >= 320) ||
+                parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
+                return keyword;
+            return firstGenerationImage(false);
+        }
+        return identifierOrType();
 
     case IMAGE2D:
     case IIMAGE2D:
@@ -1090,14 +1250,40 @@ int TScanContext::tokenizeIdentifier()
         afterType = true;
         return firstGenerationImage(true);
 
+    case I64IMAGE2D:
+    case U64IMAGE2D:
+    case I64IMAGE3D:
+    case U64IMAGE3D:
+    case I64IMAGECUBE:
+    case U64IMAGECUBE:
+    case I64IMAGE2DARRAY:
+    case U64IMAGE2DARRAY:
+        afterType = true;
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_image_int64))
+            return firstGenerationImage(true);
+        return identifierOrType();
+        
     case IMAGECUBEARRAY:
     case IIMAGECUBEARRAY:
     case UIMAGECUBEARRAY:
         afterType = true;
-        if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
+        if ((parseContext.isEsProfile() && parseContext.version >= 320) ||
             parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array))
             return keyword;
         return secondGenerationImage();
+        
+    case I64IMAGECUBEARRAY:
+    case U64IMAGECUBEARRAY:
+        afterType = true;
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_image_int64)) {
+            if ((parseContext.isEsProfile() && parseContext.version >= 320) ||
+                parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array))
+                return keyword;
+            return secondGenerationImage();
+        }
+        return identifierOrType();
 
     case IMAGE2DMS:
     case IIMAGE2DMS:
@@ -1107,13 +1293,27 @@ int TScanContext::tokenizeIdentifier()
     case UIMAGE2DMSARRAY:
         afterType = true;
         return secondGenerationImage();
+        
+    case I64IMAGE2DMS:
+    case U64IMAGE2DMS:
+    case I64IMAGE2DMSARRAY:
+    case U64IMAGE2DMSARRAY:
+        afterType = true;
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_image_int64)) {
+            return secondGenerationImage();
+        }
+        return identifierOrType();
 
     case DOUBLE:
     case DVEC2:
     case DVEC3:
     case DVEC4:
         afterType = true;
-        if (parseContext.profile == EEsProfile || parseContext.version < 400)
+        if (parseContext.isEsProfile() || parseContext.version < 150 ||
+            (!parseContext.symbolTable.atBuiltInLevel() &&
+              (parseContext.version < 400 && !parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) &&
+              (parseContext.version < 410 && !parseContext.extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit)))))
             reservedWord();
         return keyword;
 
@@ -1127,10 +1327,9 @@ int TScanContext::tokenizeIdentifier()
     case U64VEC4:
         afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
-             (parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) ||
-              parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
-              parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int64))))
+            parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int64))
             return keyword;
         return identifierOrType();
 
@@ -1144,10 +1343,9 @@ int TScanContext::tokenizeIdentifier()
     case U8VEC4:
         afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            ((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
-              parseContext.extensionTurnedOn(E_GL_EXT_shader_8bit_storage) ||
-              parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int8)) &&
-              parseContext.profile != EEsProfile && parseContext.version >= 450))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_8bit_storage) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8))
             return keyword;
         return identifierOrType();
 
@@ -1161,14 +1359,10 @@ int TScanContext::tokenizeIdentifier()
     case U16VEC4:
         afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
-             (
-#ifdef AMD_EXTENSIONS
-              parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) ||
-#endif
-              parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
-              parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
-              parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int16))))
+            parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16))
             return keyword;
         return identifierOrType();
     case INT32_T:
@@ -1181,9 +1375,8 @@ int TScanContext::tokenizeIdentifier()
     case U32VEC4:
         afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-           ((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
-             parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int32)) &&
-             parseContext.profile != EEsProfile && parseContext.version >= 450))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32))
             return keyword;
         return identifierOrType();
     case FLOAT32_T:
@@ -1204,9 +1397,8 @@ int TScanContext::tokenizeIdentifier()
     case F32MAT4X4:
         afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            ((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
-              parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float32)) &&
-              parseContext.profile != EEsProfile && parseContext.version >= 450))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32))
             return keyword;
         return identifierOrType();
 
@@ -1228,9 +1420,8 @@ int TScanContext::tokenizeIdentifier()
     case F64MAT4X4:
         afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            ((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
-              parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float64)) &&
-              parseContext.profile != EEsProfile && parseContext.version >= 450))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64))
             return keyword;
         return identifierOrType();
 
@@ -1240,14 +1431,10 @@ int TScanContext::tokenizeIdentifier()
     case F16VEC4:
         afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
-             (
-#ifdef AMD_EXTENSIONS
-              parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
-#endif
-              parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
-              parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
-              parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float16))))
+            parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16))
             return keyword;
 
         return identifierOrType();
@@ -1266,13 +1453,9 @@ int TScanContext::tokenizeIdentifier()
     case F16MAT4X4:
         afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
-             (
-#ifdef AMD_EXTENSIONS
-              parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
-#endif
-              parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
-              parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float16))))
+            parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16))
             return keyword;
 
         return identifierOrType();
@@ -1282,20 +1465,21 @@ int TScanContext::tokenizeIdentifier()
     case ISAMPLERCUBEARRAY:
     case USAMPLERCUBEARRAY:
         afterType = true;
-        if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
+        if ((parseContext.isEsProfile() && parseContext.version >= 320) ||
             parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array))
             return keyword;
-        if (parseContext.profile == EEsProfile || (parseContext.version < 400 && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_cube_map_array)))
+        if (parseContext.isEsProfile() || (parseContext.version < 400 && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_cube_map_array)))
             reservedWord();
         return keyword;
 
-    case ISAMPLER1D:
-    case ISAMPLER1DARRAY:
-    case SAMPLER1DARRAYSHADOW:
-    case USAMPLER1D:
-    case USAMPLER1DARRAY:
-        afterType = true;
-        return es30ReservedFromGLSL(130);
+    case TEXTURECUBEARRAY:
+    case ITEXTURECUBEARRAY:
+    case UTEXTURECUBEARRAY:
+        if (parseContext.spvVersion.vulkan > 0)
+            return keyword;
+        else
+            return identifierOrType();
+#endif
 
     case UINT:
     case UVEC2:
@@ -1315,6 +1499,49 @@ int TScanContext::tokenizeIdentifier()
         afterType = true;
         return nonreservedKeyword(300, 130);
 
+    case SAMPLER3D:
+        afterType = true;
+        if (parseContext.isEsProfile() && parseContext.version < 300) {
+            if (!parseContext.extensionTurnedOn(E_GL_OES_texture_3D))
+                reservedWord();
+        }
+        return keyword;
+
+    case SAMPLER2DSHADOW:
+        afterType = true;
+        if (parseContext.isEsProfile() && parseContext.version < 300) {
+            if (!parseContext.extensionTurnedOn(E_GL_EXT_shadow_samplers))
+                reservedWord();
+        }
+        return keyword;
+
+    case TEXTURE2D:
+    case TEXTURECUBE:
+    case TEXTURE2DARRAY:
+    case ITEXTURE2D:
+    case ITEXTURE3D:
+    case ITEXTURECUBE:
+    case ITEXTURE2DARRAY:
+    case UTEXTURE2D:
+    case UTEXTURE3D:
+    case UTEXTURECUBE:
+    case UTEXTURE2DARRAY:
+    case TEXTURE3D:
+    case SAMPLER:
+    case SAMPLERSHADOW:
+        if (parseContext.spvVersion.vulkan > 0)
+            return keyword;
+        else
+            return identifierOrType();
+
+#ifndef GLSLANG_WEB
+    case ISAMPLER1D:
+    case ISAMPLER1DARRAY:
+    case SAMPLER1DARRAYSHADOW:
+    case USAMPLER1D:
+    case USAMPLER1DARRAY:
+        afterType = true;
+        return es30ReservedFromGLSL(130);
     case ISAMPLER2DRECT:
     case USAMPLER2DRECT:
         afterType = true;
@@ -1322,7 +1549,7 @@ int TScanContext::tokenizeIdentifier()
 
     case SAMPLERBUFFER:
         afterType = true;
-        if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
+        if ((parseContext.isEsProfile() && parseContext.version >= 320) ||
             parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
             return keyword;
         return es30ReservedFromGLSL(130);
@@ -1330,7 +1557,7 @@ int TScanContext::tokenizeIdentifier()
     case ISAMPLERBUFFER:
     case USAMPLERBUFFER:
         afterType = true;
-        if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
+        if ((parseContext.isEsProfile() && parseContext.version >= 320) ||
             parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
             return keyword;
         return es30ReservedFromGLSL(140);
@@ -1339,7 +1566,10 @@ int TScanContext::tokenizeIdentifier()
     case ISAMPLER2DMS:
     case USAMPLER2DMS:
         afterType = true;
-        if (parseContext.profile == EEsProfile && parseContext.version >= 310)
+        if (parseContext.isEsProfile() && parseContext.version >= 310)
+            return keyword;
+        if (!parseContext.isEsProfile() && (parseContext.version > 140 ||
+            (parseContext.version == 140 && parseContext.extensionsTurnedOn(1, &E_GL_ARB_texture_multisample))))
             return keyword;
         return es30ReservedFromGLSL(150);
 
@@ -1347,38 +1577,25 @@ int TScanContext::tokenizeIdentifier()
     case ISAMPLER2DMSARRAY:
     case USAMPLER2DMSARRAY:
         afterType = true;
-        if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
+        if ((parseContext.isEsProfile() && parseContext.version >= 320) ||
             parseContext.extensionsTurnedOn(1, &E_GL_OES_texture_storage_multisample_2d_array))
             return keyword;
+        if (!parseContext.isEsProfile() && (parseContext.version > 140 ||
+            (parseContext.version == 140 && parseContext.extensionsTurnedOn(1, &E_GL_ARB_texture_multisample))))
+            return keyword;
         return es30ReservedFromGLSL(150);
 
     case SAMPLER1D:
     case SAMPLER1DSHADOW:
         afterType = true;
-        if (parseContext.profile == EEsProfile)
+        if (parseContext.isEsProfile())
             reservedWord();
         return keyword;
 
-    case SAMPLER3D:
-        afterType = true;
-        if (parseContext.profile == EEsProfile && parseContext.version < 300) {
-            if (!parseContext.extensionTurnedOn(E_GL_OES_texture_3D))
-                reservedWord();
-        }
-        return keyword;
-
-    case SAMPLER2DSHADOW:
-        afterType = true;
-        if (parseContext.profile == EEsProfile && parseContext.version < 300) {
-            if (!parseContext.extensionTurnedOn(E_GL_EXT_shadow_samplers))
-                reservedWord();
-        }
-        return keyword;
-
     case SAMPLER2DRECT:
     case SAMPLER2DRECTSHADOW:
         afterType = true;
-        if (parseContext.profile == EEsProfile)
+        if (parseContext.isEsProfile())
             reservedWord();
         else if (parseContext.version < 140 && ! parseContext.symbolTable.atBuiltInLevel() && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_rectangle)) {
             if (parseContext.relaxedErrors())
@@ -1390,10 +1607,10 @@ int TScanContext::tokenizeIdentifier()
 
     case SAMPLER1DARRAY:
         afterType = true;
-        if (parseContext.profile == EEsProfile && parseContext.version == 300)
+        if (parseContext.isEsProfile() && parseContext.version == 300)
             reservedWord();
-        else if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
-                 (parseContext.profile != EEsProfile && parseContext.version < 130))
+        else if ((parseContext.isEsProfile() && parseContext.version < 300) ||
+                 (!parseContext.isEsProfile() && parseContext.version < 130))
             return identifierOrType();
         return keyword;
 
@@ -1405,25 +1622,18 @@ int TScanContext::tokenizeIdentifier()
             return keyword;
         return identifierOrType();
 
-    case TEXTURE2D:
-    case TEXTURECUBE:
-    case TEXTURECUBEARRAY:
-    case ITEXTURECUBEARRAY:
-    case UTEXTURECUBEARRAY:
+    case SAMPLEREXTERNAL2DY2YEXT:
+        afterType = true;
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_YUV_target))
+            return keyword;
+        return identifierOrType();
+
     case ITEXTURE1DARRAY:
     case UTEXTURE1D:
     case ITEXTURE1D:
     case UTEXTURE1DARRAY:
     case TEXTUREBUFFER:
-    case TEXTURE2DARRAY:
-    case ITEXTURE2D:
-    case ITEXTURE3D:
-    case ITEXTURECUBE:
-    case ITEXTURE2DARRAY:
-    case UTEXTURE2D:
-    case UTEXTURE3D:
-    case UTEXTURECUBE:
-    case UTEXTURE2DARRAY:
     case ITEXTURE2DRECT:
     case UTEXTURE2DRECT:
     case ITEXTUREBUFFER:
@@ -1435,11 +1645,8 @@ int TScanContext::tokenizeIdentifier()
     case ITEXTURE2DMSARRAY:
     case UTEXTURE2DMSARRAY:
     case TEXTURE1D:
-    case TEXTURE3D:
     case TEXTURE2DRECT:
     case TEXTURE1DARRAY:
-    case SAMPLER:
-    case SAMPLERSHADOW:
         if (parseContext.spvVersion.vulkan > 0)
             return keyword;
         else
@@ -1456,7 +1663,6 @@ int TScanContext::tokenizeIdentifier()
         else
             return identifierOrType();
 
-#ifdef AMD_EXTENSIONS
     case F16SAMPLER1D:
     case F16SAMPLER2D:
     case F16SAMPLER3D:
@@ -1504,96 +1710,100 @@ int TScanContext::tokenizeIdentifier()
     case F16SUBPASSINPUTMS:
         afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch) &&
-             parseContext.profile != EEsProfile && parseContext.version >= 450))
+            parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch))
             return keyword;
         return identifierOrType();
-#endif
-
-    case NOPERSPECTIVE:
-#ifdef NV_EXTENSIONS
-        if (parseContext.profile == EEsProfile && parseContext.version >= 300 &&
-            parseContext.extensionTurnedOn(E_GL_NV_shader_noperspective_interpolation))
-            return keyword;
-#endif
-        return es30ReservedFromGLSL(130);
 
-    case SMOOTH:
-        if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
-            (parseContext.profile != EEsProfile && parseContext.version < 130))
-            return identifierOrType();
-        return keyword;
-
-#ifdef AMD_EXTENSIONS
     case EXPLICITINTERPAMD:
-        if (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
-            parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter))
+        if (parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter))
             return keyword;
         return identifierOrType();
-#endif
 
-#ifdef NV_EXTENSIONS
     case PERVERTEXNV:
-        if (((parseContext.profile != EEsProfile && parseContext.version >= 450) ||
-            (parseContext.profile == EEsProfile && parseContext.version >= 320)) &&
+        if ((!parseContext.isEsProfile() && parseContext.version >= 450) ||
             parseContext.extensionTurnedOn(E_GL_NV_fragment_shader_barycentric))
             return keyword;
         return identifierOrType();
-#endif
 
-    case FLAT:
-        if (parseContext.profile == EEsProfile && parseContext.version < 300)
-            reservedWord();
-        else if (parseContext.profile != EEsProfile && parseContext.version < 130)
-            return identifierOrType();
-        return keyword;
-
-    case CENTROID:
-        if (parseContext.version < 120)
-            return identifierOrType();
-        return keyword;
+    case PERVERTEXEXT:
+        if ((!parseContext.isEsProfile() && parseContext.version >= 450) ||
+            parseContext.extensionTurnedOn(E_GL_EXT_fragment_shader_barycentric))
+            return keyword;
+        return identifierOrType();
 
     case PRECISE:
-        if ((parseContext.profile == EEsProfile &&
+        if ((parseContext.isEsProfile() &&
              (parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5))) ||
-            (parseContext.profile != EEsProfile && parseContext.version >= 400))
+            (!parseContext.isEsProfile() && parseContext.version >= 400))
             return keyword;
-        if (parseContext.profile == EEsProfile && parseContext.version == 310) {
+        if (parseContext.isEsProfile() && parseContext.version == 310) {
             reservedWord();
             return keyword;
         }
         return identifierOrType();
 
-    case INVARIANT:
-        if (parseContext.profile != EEsProfile && parseContext.version < 120)
+    case PERPRIMITIVENV:
+    case PERVIEWNV:
+    case PERTASKNV:
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_NV_mesh_shader))
+            return keyword;
+        return identifierOrType();
+
+    case PERPRIMITIVEEXT:
+    case TASKPAYLOADWORKGROUPEXT:
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_mesh_shader))
+            return keyword;
+        return identifierOrType();
+
+    case FCOOPMATNV:
+        afterType = true;
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_NV_cooperative_matrix))
+            return keyword;
+        return identifierOrType();
+
+    case UCOOPMATNV:
+    case ICOOPMATNV:
+        afterType = true;
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_NV_integer_cooperative_matrix))
+            return keyword;
+        return identifierOrType();
+
+    case DEMOTE:
+        if (parseContext.extensionTurnedOn(E_GL_EXT_demote_to_helper_invocation))
+            return keyword;
+        else
             return identifierOrType();
-        return keyword;
 
-    case PACKED:
-        if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
-            (parseContext.profile != EEsProfile && parseContext.version < 330))
-            return reservedWord();
+    case SPIRV_INSTRUCTION:
+    case SPIRV_EXECUTION_MODE:
+    case SPIRV_EXECUTION_MODE_ID:
+    case SPIRV_DECORATE:
+    case SPIRV_DECORATE_ID:
+    case SPIRV_DECORATE_STRING:
+    case SPIRV_TYPE:
+    case SPIRV_STORAGE_CLASS:
+    case SPIRV_BY_REFERENCE:
+    case SPIRV_LITERAL:
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
+            return keyword;
         return identifierOrType();
 
-    case RESOURCE:
-    {
-        bool reserved = (parseContext.profile == EEsProfile && parseContext.version >= 300) ||
-                        (parseContext.profile != EEsProfile && parseContext.version >= 420);
-        return identifierOrReserved(reserved);
-    }
-    case SUPERP:
-    {
-        bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130;
-        return identifierOrReserved(reserved);
-    }
+    case HITOBJECTNV:
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            (!parseContext.isEsProfile() && parseContext.version >= 460
+                 && parseContext.extensionTurnedOn(E_GL_NV_shader_invocation_reorder)))
+            return keyword;
+        return identifierOrType();
 
-#ifdef NV_EXTENSIONS
-    case PERPRIMITIVENV:
-    case PERVIEWNV:
-    case PERTASKNV:
-        if ((parseContext.profile != EEsProfile && parseContext.version >= 450) ||
-            (parseContext.profile == EEsProfile && parseContext.version >= 320) ||
-            parseContext.extensionTurnedOn(E_GL_NV_mesh_shader))
+    case HITOBJECTATTRNV:
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            (!parseContext.isEsProfile() && parseContext.version >= 460
+                 && parseContext.extensionTurnedOn(E_GL_NV_shader_invocation_reorder)))
             return keyword;
         return identifierOrType();
 #endif
@@ -1613,7 +1823,9 @@ int TScanContext::identifierOrType()
     parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string);
     if ((afterType == false && afterStruct == false) && parserToken->sType.lex.symbol != nullptr) {
         if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) {
-            if (variable->isUserType()) {
+            if (variable->isUserType() &&
+                // treat redeclaration of forward-declared buffer/uniform reference as an identifier
+                !(variable->getType().isReference() && afterBuffer)) {
                 afterType = true;
 
                 return TYPE_NAME;
@@ -1643,7 +1855,7 @@ int TScanContext::identifierOrReserved(bool reserved)
         return 0;
     }
 
-    if (parseContext.forwardCompatible)
+    if (parseContext.isForwardCompatible())
         parseContext.warn(loc, "using future reserved keyword", tokenText, "");
 
     return identifierOrType();
@@ -1656,13 +1868,13 @@ int TScanContext::es30ReservedFromGLSL(int version)
     if (parseContext.symbolTable.atBuiltInLevel())
         return keyword;
 
-    if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
-        (parseContext.profile != EEsProfile && parseContext.version < version)) {
-            if (parseContext.forwardCompatible)
+    if ((parseContext.isEsProfile() && parseContext.version < 300) ||
+        (!parseContext.isEsProfile() && parseContext.version < version)) {
+            if (parseContext.isForwardCompatible())
                 parseContext.warn(loc, "future reserved word in ES 300 and keyword in GLSL", tokenText, "");
 
             return identifierOrType();
-    } else if (parseContext.profile == EEsProfile && parseContext.version >= 300)
+    } else if (parseContext.isEsProfile() && parseContext.version >= 300)
         reservedWord();
 
     return keyword;
@@ -1672,9 +1884,9 @@ int TScanContext::es30ReservedFromGLSL(int version)
 // showed up, both in an es version and a non-ES version.
 int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion)
 {
-    if ((parseContext.profile == EEsProfile && parseContext.version < esVersion) ||
-        (parseContext.profile != EEsProfile && parseContext.version < nonEsVersion)) {
-        if (parseContext.forwardCompatible)
+    if ((parseContext.isEsProfile() && parseContext.version < esVersion) ||
+        (!parseContext.isEsProfile() && parseContext.version < nonEsVersion)) {
+        if (parseContext.isForwardCompatible())
             parseContext.warn(loc, "using future keyword", tokenText, "");
 
         return identifierOrType();
@@ -1685,10 +1897,10 @@ int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion)
 
 int TScanContext::precisionKeyword()
 {
-    if (parseContext.profile == EEsProfile || parseContext.version >= 130)
+    if (parseContext.isEsProfile() || parseContext.version >= 130)
         return keyword;
 
-    if (parseContext.forwardCompatible)
+    if (parseContext.isForwardCompatible())
         parseContext.warn(loc, "using ES precision qualifier keyword", tokenText, "");
 
     return identifierOrType();
@@ -1701,7 +1913,7 @@ int TScanContext::matNxM()
     if (parseContext.version > 110)
         return keyword;
 
-    if (parseContext.forwardCompatible)
+    if (parseContext.isForwardCompatible())
         parseContext.warn(loc, "using future non-square matrix type keyword", tokenText, "");
 
     return identifierOrType();
@@ -1711,16 +1923,20 @@ int TScanContext::dMat()
 {
     afterType = true;
 
-    if (parseContext.profile == EEsProfile && parseContext.version >= 300) {
+    if (parseContext.isEsProfile() && parseContext.version >= 300) {
         reservedWord();
 
         return keyword;
     }
 
-    if (parseContext.profile != EEsProfile && parseContext.version >= 400)
+    if (!parseContext.isEsProfile() && (parseContext.version >= 400 ||
+        parseContext.symbolTable.atBuiltInLevel() ||
+        (parseContext.version >= 150 && parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64)) ||
+        (parseContext.version >= 150 && parseContext.extensionTurnedOn(E_GL_ARB_vertex_attrib_64bit)
+         && parseContext.language == EShLangVertex)))
         return keyword;
 
-    if (parseContext.forwardCompatible)
+    if (parseContext.isForwardCompatible())
         parseContext.warn(loc, "using future type keyword", tokenText, "");
 
     return identifierOrType();
@@ -1729,19 +1945,19 @@ int TScanContext::dMat()
 int TScanContext::firstGenerationImage(bool inEs310)
 {
     if (parseContext.symbolTable.atBuiltInLevel() ||
-        (parseContext.profile != EEsProfile && (parseContext.version >= 420 ||
+        (!parseContext.isEsProfile() && (parseContext.version >= 420 ||
          parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))) ||
-        (inEs310 && parseContext.profile == EEsProfile && parseContext.version >= 310))
+        (inEs310 && parseContext.isEsProfile() && parseContext.version >= 310))
         return keyword;
 
-    if ((parseContext.profile == EEsProfile && parseContext.version >= 300) ||
-        (parseContext.profile != EEsProfile && parseContext.version >= 130)) {
+    if ((parseContext.isEsProfile() && parseContext.version >= 300) ||
+        (!parseContext.isEsProfile() && parseContext.version >= 130)) {
         reservedWord();
 
         return keyword;
     }
 
-    if (parseContext.forwardCompatible)
+    if (parseContext.isForwardCompatible())
         parseContext.warn(loc, "using future type keyword", tokenText, "");
 
     return identifierOrType();
@@ -1749,17 +1965,17 @@ int TScanContext::firstGenerationImage(bool inEs310)
 
 int TScanContext::secondGenerationImage()
 {
-    if (parseContext.profile == EEsProfile && parseContext.version >= 310) {
+    if (parseContext.isEsProfile() && parseContext.version >= 310) {
         reservedWord();
         return keyword;
     }
 
     if (parseContext.symbolTable.atBuiltInLevel() ||
-        (parseContext.profile != EEsProfile &&
+        (!parseContext.isEsProfile() &&
          (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))))
         return keyword;
 
-    if (parseContext.forwardCompatible)
+    if (parseContext.isForwardCompatible())
         parseContext.warn(loc, "using future type keyword", tokenText, "");
 
     return identifierOrType();