Fix variable scoping of do-while
[platform/upstream/glslang.git] / glslang / MachineIndependent / Scan.cpp
old mode 100755 (executable)
new mode 100644 (file)
index eaedbe8..c387aed
@@ -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,23 +387,12 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["mat4"] =                    MAT4;
     (*KeywordMap)["true"] =                    BOOLCONSTANT;
     (*KeywordMap)["false"] =                   BOOLCONSTANT;
-    (*KeywordMap)["attribute"] =               ATTRIBUTE;
-    (*KeywordMap)["varying"] =                 VARYING;
-    (*KeywordMap)["buffer"] =                  BUFFER;
-    (*KeywordMap)["coherent"] =                COHERENT;
-    (*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)["superp"] =                  SUPERP;
     (*KeywordMap)["precision"] =               PRECISION;
     (*KeywordMap)["mat2x2"] =                  MAT2X2;
     (*KeywordMap)["mat2x3"] =                  MAT2X3;
@@ -403,6 +403,32 @@ void TScanContext::fillInKeywordMap()
     (*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)["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)["patch"] =                   PATCH;
+    (*KeywordMap)["sample"] =                  SAMPLE;
+    (*KeywordMap)["subroutine"] =              SUBROUTINE;
     (*KeywordMap)["dmat2"] =                   DMAT2;
     (*KeywordMap)["dmat3"] =                   DMAT3;
     (*KeywordMap)["dmat4"] =                   DMAT4;
@@ -448,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;
@@ -466,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;
@@ -544,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;
@@ -567,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;
@@ -579,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;
@@ -620,7 +682,6 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["itexture2DMSArray"] =       ITEXTURE2DMSARRAY;
     (*KeywordMap)["utexture2DMSArray"] =       UTEXTURE2DMSARRAY;
     (*KeywordMap)["texture1D"] =               TEXTURE1D;
-    (*KeywordMap)["texture3D"] =               TEXTURE3D;
     (*KeywordMap)["texture2DRect"] =           TEXTURE2DRECT;
     (*KeywordMap)["texture1DArray"] =          TEXTURE1DARRAY;
 
@@ -631,7 +692,6 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["usubpassInput"] =           USUBPASSINPUT;
     (*KeywordMap)["usubpassInputMS"] =         USUBPASSINPUTMS;
 
-#ifdef AMD_EXTENSIONS
     (*KeywordMap)["f16sampler1D"] =                 F16SAMPLER1D;
     (*KeywordMap)["f16sampler2D"] =                 F16SAMPLER2D;
     (*KeywordMap)["f16sampler3D"] =                 F16SAMPLER3D;
@@ -677,20 +737,30 @@ 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;
+    (*KeywordMap)["pervertexNV"] =             PERVERTEXNV;
     (*KeywordMap)["precise"] =                 PRECISE;
-    (*KeywordMap)["invariant"] =               INVARIANT;
-    (*KeywordMap)["packed"] =                  PACKED;
-    (*KeywordMap)["resource"] =                RESOURCE;
-    (*KeywordMap)["superp"] =                  SUPERP;
+
+    (*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;
+
+    (*KeywordMap)["fcoopmatNV"] =              FCOOPMATNV;
+    (*KeywordMap)["icoopmatNV"] =              ICOOPMATNV;
+    (*KeywordMap)["ucoopmatNV"] =              UCOOPMATNV;
 
     ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
 
@@ -731,14 +801,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.
@@ -756,7 +829,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;
@@ -778,7 +851,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", "\\", "");
@@ -815,15 +888,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();
@@ -845,8 +921,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()) {
@@ -873,20 +951,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;
 
@@ -918,75 +1009,147 @@ 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);
+    }
 
+#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.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();
     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);
 
     case COHERENT:
+    case DEVICECOHERENT:
+    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:
@@ -1005,6 +1168,7 @@ int TScanContext::tokenizeIdentifier()
     case MAT4X4:
         return matNxM();
 
+#ifndef GLSLANG_WEB
     case DMAT2:
     case DMAT3:
     case DMAT4:
@@ -1031,14 +1195,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:
@@ -1055,14 +1244,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:
@@ -1072,13 +1287,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;
 
@@ -1092,10 +1321,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();
 
@@ -1109,10 +1337,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();
 
@@ -1126,14 +1353,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:
@@ -1146,9 +1369,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:
@@ -1169,9 +1391,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();
 
@@ -1193,9 +1414,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();
 
@@ -1205,14 +1425,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();
@@ -1231,13 +1447,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();
@@ -1247,20 +1459,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:
@@ -1280,6 +1493,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;
@@ -1287,7 +1543,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);
@@ -1295,7 +1551,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);
@@ -1304,7 +1560,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);
 
@@ -1312,38 +1571,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())
@@ -1355,10 +1601,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;
 
@@ -1370,25 +1616,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:
@@ -1400,11 +1639,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
@@ -1421,7 +1657,6 @@ int TScanContext::tokenizeIdentifier()
         else
             return identifierOrType();
 
-#ifdef AMD_EXTENSIONS
     case F16SAMPLER1D:
     case F16SAMPLER2D:
     case F16SAMPLER3D:
@@ -1469,79 +1704,77 @@ 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
 
-    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 PERVERTEXNV:
+        if ((!parseContext.isEsProfile() && parseContext.version >= 450) ||
+            parseContext.extensionTurnedOn(E_GL_NV_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)
-            return identifierOrType();
-        return keyword;
+    case PERPRIMITIVENV:
+    case PERVIEWNV:
+    case PERTASKNV:
+        if ((!parseContext.isEsProfile() && parseContext.version >= 450) ||
+            (parseContext.isEsProfile() && parseContext.version >= 320) ||
+            parseContext.extensionTurnedOn(E_GL_NV_mesh_shader))
+            return keyword;
+        return identifierOrType();
 
-    case PACKED:
-        if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
-            (parseContext.profile != EEsProfile && parseContext.version < 330))
-            return reservedWord();
+    case FCOOPMATNV:
+        afterType = true;
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_NV_cooperative_matrix))
+            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 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();
+
+    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();
+#endif
 
     default:
         parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
@@ -1558,7 +1791,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;
@@ -1588,7 +1823,7 @@ int TScanContext::identifierOrReserved(bool reserved)
         return 0;
     }
 
-    if (parseContext.forwardCompatible)
+    if (parseContext.isForwardCompatible())
         parseContext.warn(loc, "using future reserved keyword", tokenText, "");
 
     return identifierOrType();
@@ -1601,13 +1836,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;
@@ -1617,9 +1852,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();
@@ -1630,10 +1865,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();
@@ -1646,7 +1881,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();
@@ -1656,16 +1891,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();
@@ -1674,19 +1913,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();
@@ -1694,17 +1933,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();