Home | History | Annotate | Download | only in MachineIndependent
      1 //
      2 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
      3 // Copyright (C) 2013 LunarG, Inc.
      4 // Copyright (C) 2017 ARM Limited.
      5 //
      6 // All rights reserved.
      7 //
      8 // Redistribution and use in source and binary forms, with or without
      9 // modification, are permitted provided that the following conditions
     10 // are met:
     11 //
     12 //    Redistributions of source code must retain the above copyright
     13 //    notice, this list of conditions and the following disclaimer.
     14 //
     15 //    Redistributions in binary form must reproduce the above
     16 //    copyright notice, this list of conditions and the following
     17 //    disclaimer in the documentation and/or other materials provided
     18 //    with the distribution.
     19 //
     20 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
     21 //    contributors may be used to endorse or promote products derived
     22 //    from this software without specific prior written permission.
     23 //
     24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     27 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     28 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     31 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     32 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     34 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35 // POSSIBILITY OF SUCH DAMAGE.
     36 //
     37 
     38 //
     39 // GLSL scanning, leveraging the scanning done by the preprocessor.
     40 //
     41 
     42 #include <cstring>
     43 #include <unordered_map>
     44 #include <unordered_set>
     45 
     46 #include "../Include/Types.h"
     47 #include "SymbolTable.h"
     48 #include "ParseHelper.h"
     49 #include "attribute.h"
     50 #include "glslang_tab.cpp.h"
     51 #include "ScanContext.h"
     52 #include "Scan.h"
     53 
     54 // preprocessor includes
     55 #include "preprocessor/PpContext.h"
     56 #include "preprocessor/PpTokens.h"
     57 
     58 // Required to avoid missing prototype warnings for some compilers
     59 int yylex(YYSTYPE*, glslang::TParseContext&);
     60 
     61 namespace glslang {
     62 
     63 // read past any white space
     64 void TInputScanner::consumeWhiteSpace(bool& foundNonSpaceTab)
     65 {
     66     int c = peek();  // don't accidentally consume anything other than whitespace
     67     while (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
     68         if (c == '\r' || c == '\n')
     69             foundNonSpaceTab = true;
     70         get();
     71         c = peek();
     72     }
     73 }
     74 
     75 // return true if a comment was actually consumed
     76 bool TInputScanner::consumeComment()
     77 {
     78     if (peek() != '/')
     79         return false;
     80 
     81     get();  // consume the '/'
     82     int c = peek();
     83     if (c == '/') {
     84 
     85         // a '//' style comment
     86         get();  // consume the second '/'
     87         c = get();
     88         do {
     89             while (c != EndOfInput && c != '\\' && c != '\r' && c != '\n')
     90                 c = get();
     91 
     92             if (c == EndOfInput || c == '\r' || c == '\n') {
     93                 while (c == '\r' || c == '\n')
     94                     c = get();
     95 
     96                 // we reached the end of the comment
     97                 break;
     98             } else {
     99                 // it's a '\', so we need to keep going, after skipping what's escaped
    100 
    101                 // read the skipped character
    102                 c = get();
    103 
    104                 // if it's a two-character newline, skip both characters
    105                 if (c == '\r' && peek() == '\n')
    106                     get();
    107                 c = get();
    108             }
    109         } while (true);
    110 
    111         // put back the last non-comment character
    112         if (c != EndOfInput)
    113             unget();
    114 
    115         return true;
    116     } else if (c == '*') {
    117 
    118         // a '/*' style comment
    119         get();  // consume the '*'
    120         c = get();
    121         do {
    122             while (c != EndOfInput && c != '*')
    123                 c = get();
    124             if (c == '*') {
    125                 c = get();
    126                 if (c == '/')
    127                     break;  // end of comment
    128                 // not end of comment
    129             } else // end of input
    130                 break;
    131         } while (true);
    132 
    133         return true;
    134     } else {
    135         // it's not a comment, put the '/' back
    136         unget();
    137 
    138         return false;
    139     }
    140 }
    141 
    142 // skip whitespace, then skip a comment, rinse, repeat
    143 void TInputScanner::consumeWhitespaceComment(bool& foundNonSpaceTab)
    144 {
    145     do {
    146         consumeWhiteSpace(foundNonSpaceTab);
    147 
    148         // if not starting a comment now, then done
    149         int c = peek();
    150         if (c != '/' || c == EndOfInput)
    151             return;
    152 
    153         // skip potential comment
    154         foundNonSpaceTab = true;
    155         if (! consumeComment())
    156             return;
    157 
    158     } while (true);
    159 }
    160 
    161 // Returns true if there was non-white space (e.g., a comment, newline) before the #version
    162 // or no #version was found; otherwise, returns false.  There is no error case, it always
    163 // succeeds, but will leave version == 0 if no #version was found.
    164 //
    165 // Sets notFirstToken based on whether tokens (beyond white space and comments)
    166 // appeared before the #version.
    167 //
    168 // N.B. does not attempt to leave input in any particular known state.  The assumption
    169 // is that scanning will start anew, following the rules for the chosen version/profile,
    170 // and with a corresponding parsing context.
    171 //
    172 bool TInputScanner::scanVersion(int& version, EProfile& profile, bool& notFirstToken)
    173 {
    174     // This function doesn't have to get all the semantics correct,
    175     // just find the #version if there is a correct one present.
    176     // The preprocessor will have the responsibility of getting all the semantics right.
    177 
    178     bool versionNotFirst = false;  // means not first WRT comments and white space, nothing more
    179     notFirstToken = false;         // means not first WRT to real tokens
    180     version = 0;                   // means not found
    181     profile = ENoProfile;
    182 
    183     bool foundNonSpaceTab = false;
    184     bool lookingInMiddle = false;
    185     int c;
    186     do {
    187         if (lookingInMiddle) {
    188             notFirstToken = true;
    189             // make forward progress by finishing off the current line plus extra new lines
    190             if (peek() == '\n' || peek() == '\r') {
    191                 while (peek() == '\n' || peek() == '\r')
    192                     get();
    193             } else
    194                 do {
    195                     c = get();
    196                 } while (c != EndOfInput && c != '\n' && c != '\r');
    197                 while (peek() == '\n' || peek() == '\r')
    198                     get();
    199                 if (peek() == EndOfInput)
    200                     return true;
    201         }
    202         lookingInMiddle = true;
    203 
    204         // Nominal start, skipping the desktop allowed comments and white space, but tracking if
    205         // something else was found for ES:
    206         consumeWhitespaceComment(foundNonSpaceTab);
    207         if (foundNonSpaceTab)
    208             versionNotFirst = true;
    209 
    210         // "#"
    211         if (get() != '#') {
    212             versionNotFirst = true;
    213             continue;
    214         }
    215 
    216         // whitespace
    217         do {
    218             c = get();
    219         } while (c == ' ' || c == '\t');
    220 
    221         // "version"
    222         if (    c != 'v' ||
    223             get() != 'e' ||
    224             get() != 'r' ||
    225             get() != 's' ||
    226             get() != 'i' ||
    227             get() != 'o' ||
    228             get() != 'n') {
    229             versionNotFirst = true;
    230             continue;
    231         }
    232 
    233         // whitespace
    234         do {
    235             c = get();
    236         } while (c == ' ' || c == '\t');
    237 
    238         // version number
    239         while (c >= '0' && c <= '9') {
    240             version = 10 * version + (c - '0');
    241             c = get();
    242         }
    243         if (version == 0) {
    244             versionNotFirst = true;
    245             continue;
    246         }
    247 
    248         // whitespace
    249         while (c == ' ' || c == '\t')
    250             c = get();
    251 
    252         // profile
    253         const int maxProfileLength = 13;  // not including any 0
    254         char profileString[maxProfileLength];
    255         int profileLength;
    256         for (profileLength = 0; profileLength < maxProfileLength; ++profileLength) {
    257             if (c == EndOfInput || c == ' ' || c == '\t' || c == '\n' || c == '\r')
    258                 break;
    259             profileString[profileLength] = (char)c;
    260             c = get();
    261         }
    262         if (c != EndOfInput && c != ' ' && c != '\t' && c != '\n' && c != '\r') {
    263             versionNotFirst = true;
    264             continue;
    265         }
    266 
    267         if (profileLength == 2 && strncmp(profileString, "es", profileLength) == 0)
    268             profile = EEsProfile;
    269         else if (profileLength == 4 && strncmp(profileString, "core", profileLength) == 0)
    270             profile = ECoreProfile;
    271         else if (profileLength == 13 && strncmp(profileString, "compatibility", profileLength) == 0)
    272             profile = ECompatibilityProfile;
    273 
    274         return versionNotFirst;
    275     } while (true);
    276 }
    277 
    278 // Fill this in when doing glslang-level scanning, to hand back to the parser.
    279 class TParserToken {
    280 public:
    281     explicit TParserToken(YYSTYPE& b) : sType(b) { }
    282 
    283     YYSTYPE& sType;
    284 protected:
    285     TParserToken(TParserToken&);
    286     TParserToken& operator=(TParserToken&);
    287 };
    288 
    289 } // end namespace glslang
    290 
    291 // This is the function the glslang parser (i.e., bison) calls to get its next token
    292 int yylex(YYSTYPE* glslangTokenDesc, glslang::TParseContext& parseContext)
    293 {
    294     glslang::TParserToken token(*glslangTokenDesc);
    295 
    296     return parseContext.getScanContext()->tokenize(parseContext.getPpContext(), token);
    297 }
    298 
    299 namespace {
    300 
    301 struct str_eq
    302 {
    303     bool operator()(const char* lhs, const char* rhs) const
    304     {
    305         return strcmp(lhs, rhs) == 0;
    306     }
    307 };
    308 
    309 struct str_hash
    310 {
    311     size_t operator()(const char* str) const
    312     {
    313         // djb2
    314         unsigned long hash = 5381;
    315         int c;
    316 
    317         while ((c = *str++) != 0)
    318             hash = ((hash << 5) + hash) + c;
    319 
    320         return hash;
    321     }
    322 };
    323 
    324 // A single global usable by all threads, by all versions, by all languages.
    325 // After a single process-level initialization, this is read only and thread safe
    326 std::unordered_map<const char*, int, str_hash, str_eq>* KeywordMap = nullptr;
    327 std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
    328 
    329 };
    330 
    331 namespace glslang {
    332 
    333 void TScanContext::fillInKeywordMap()
    334 {
    335     if (KeywordMap != nullptr) {
    336         // this is really an error, as this should called only once per process
    337         // but, the only risk is if two threads called simultaneously
    338         return;
    339     }
    340     KeywordMap = new std::unordered_map<const char*, int, str_hash, str_eq>;
    341 
    342     (*KeywordMap)["const"] =                   CONST;
    343     (*KeywordMap)["uniform"] =                 UNIFORM;
    344     (*KeywordMap)["nonuniformEXT"] =           NONUNIFORM;
    345     (*KeywordMap)["in"] =                      IN;
    346     (*KeywordMap)["out"] =                     OUT;
    347     (*KeywordMap)["inout"] =                   INOUT;
    348     (*KeywordMap)["struct"] =                  STRUCT;
    349     (*KeywordMap)["break"] =                   BREAK;
    350     (*KeywordMap)["continue"] =                CONTINUE;
    351     (*KeywordMap)["do"] =                      DO;
    352     (*KeywordMap)["for"] =                     FOR;
    353     (*KeywordMap)["while"] =                   WHILE;
    354     (*KeywordMap)["switch"] =                  SWITCH;
    355     (*KeywordMap)["case"] =                    CASE;
    356     (*KeywordMap)["default"] =                 DEFAULT;
    357     (*KeywordMap)["if"] =                      IF;
    358     (*KeywordMap)["else"] =                    ELSE;
    359     (*KeywordMap)["discard"] =                 DISCARD;
    360     (*KeywordMap)["return"] =                  RETURN;
    361     (*KeywordMap)["void"] =                    VOID;
    362     (*KeywordMap)["bool"] =                    BOOL;
    363     (*KeywordMap)["float"] =                   FLOAT;
    364     (*KeywordMap)["int"] =                     INT;
    365     (*KeywordMap)["bvec2"] =                   BVEC2;
    366     (*KeywordMap)["bvec3"] =                   BVEC3;
    367     (*KeywordMap)["bvec4"] =                   BVEC4;
    368     (*KeywordMap)["vec2"] =                    VEC2;
    369     (*KeywordMap)["vec3"] =                    VEC3;
    370     (*KeywordMap)["vec4"] =                    VEC4;
    371     (*KeywordMap)["ivec2"] =                   IVEC2;
    372     (*KeywordMap)["ivec3"] =                   IVEC3;
    373     (*KeywordMap)["ivec4"] =                   IVEC4;
    374     (*KeywordMap)["mat2"] =                    MAT2;
    375     (*KeywordMap)["mat3"] =                    MAT3;
    376     (*KeywordMap)["mat4"] =                    MAT4;
    377     (*KeywordMap)["true"] =                    BOOLCONSTANT;
    378     (*KeywordMap)["false"] =                   BOOLCONSTANT;
    379     (*KeywordMap)["attribute"] =               ATTRIBUTE;
    380     (*KeywordMap)["varying"] =                 VARYING;
    381     (*KeywordMap)["buffer"] =                  BUFFER;
    382     (*KeywordMap)["coherent"] =                COHERENT;
    383     (*KeywordMap)["devicecoherent"] =          DEVICECOHERENT;
    384     (*KeywordMap)["queuefamilycoherent"] =     QUEUEFAMILYCOHERENT;
    385     (*KeywordMap)["workgroupcoherent"] =       WORKGROUPCOHERENT;
    386     (*KeywordMap)["subgroupcoherent"] =        SUBGROUPCOHERENT;
    387     (*KeywordMap)["nonprivate"] =              NONPRIVATE;
    388     (*KeywordMap)["restrict"] =                RESTRICT;
    389     (*KeywordMap)["readonly"] =                READONLY;
    390     (*KeywordMap)["writeonly"] =               WRITEONLY;
    391     (*KeywordMap)["atomic_uint"] =             ATOMIC_UINT;
    392     (*KeywordMap)["volatile"] =                VOLATILE;
    393     (*KeywordMap)["layout"] =                  LAYOUT;
    394     (*KeywordMap)["shared"] =                  SHARED;
    395     (*KeywordMap)["patch"] =                   PATCH;
    396     (*KeywordMap)["sample"] =                  SAMPLE;
    397     (*KeywordMap)["subroutine"] =              SUBROUTINE;
    398     (*KeywordMap)["highp"] =                   HIGH_PRECISION;
    399     (*KeywordMap)["mediump"] =                 MEDIUM_PRECISION;
    400     (*KeywordMap)["lowp"] =                    LOW_PRECISION;
    401     (*KeywordMap)["precision"] =               PRECISION;
    402     (*KeywordMap)["mat2x2"] =                  MAT2X2;
    403     (*KeywordMap)["mat2x3"] =                  MAT2X3;
    404     (*KeywordMap)["mat2x4"] =                  MAT2X4;
    405     (*KeywordMap)["mat3x2"] =                  MAT3X2;
    406     (*KeywordMap)["mat3x3"] =                  MAT3X3;
    407     (*KeywordMap)["mat3x4"] =                  MAT3X4;
    408     (*KeywordMap)["mat4x2"] =                  MAT4X2;
    409     (*KeywordMap)["mat4x3"] =                  MAT4X3;
    410     (*KeywordMap)["mat4x4"] =                  MAT4X4;
    411     (*KeywordMap)["dmat2"] =                   DMAT2;
    412     (*KeywordMap)["dmat3"] =                   DMAT3;
    413     (*KeywordMap)["dmat4"] =                   DMAT4;
    414     (*KeywordMap)["dmat2x2"] =                 DMAT2X2;
    415     (*KeywordMap)["dmat2x3"] =                 DMAT2X3;
    416     (*KeywordMap)["dmat2x4"] =                 DMAT2X4;
    417     (*KeywordMap)["dmat3x2"] =                 DMAT3X2;
    418     (*KeywordMap)["dmat3x3"] =                 DMAT3X3;
    419     (*KeywordMap)["dmat3x4"] =                 DMAT3X4;
    420     (*KeywordMap)["dmat4x2"] =                 DMAT4X2;
    421     (*KeywordMap)["dmat4x3"] =                 DMAT4X3;
    422     (*KeywordMap)["dmat4x4"] =                 DMAT4X4;
    423     (*KeywordMap)["image1D"] =                 IMAGE1D;
    424     (*KeywordMap)["iimage1D"] =                IIMAGE1D;
    425     (*KeywordMap)["uimage1D"] =                UIMAGE1D;
    426     (*KeywordMap)["image2D"] =                 IMAGE2D;
    427     (*KeywordMap)["iimage2D"] =                IIMAGE2D;
    428     (*KeywordMap)["uimage2D"] =                UIMAGE2D;
    429     (*KeywordMap)["image3D"] =                 IMAGE3D;
    430     (*KeywordMap)["iimage3D"] =                IIMAGE3D;
    431     (*KeywordMap)["uimage3D"] =                UIMAGE3D;
    432     (*KeywordMap)["image2DRect"] =             IMAGE2DRECT;
    433     (*KeywordMap)["iimage2DRect"] =            IIMAGE2DRECT;
    434     (*KeywordMap)["uimage2DRect"] =            UIMAGE2DRECT;
    435     (*KeywordMap)["imageCube"] =               IMAGECUBE;
    436     (*KeywordMap)["iimageCube"] =              IIMAGECUBE;
    437     (*KeywordMap)["uimageCube"] =              UIMAGECUBE;
    438     (*KeywordMap)["imageBuffer"] =             IMAGEBUFFER;
    439     (*KeywordMap)["iimageBuffer"] =            IIMAGEBUFFER;
    440     (*KeywordMap)["uimageBuffer"] =            UIMAGEBUFFER;
    441     (*KeywordMap)["image1DArray"] =            IMAGE1DARRAY;
    442     (*KeywordMap)["iimage1DArray"] =           IIMAGE1DARRAY;
    443     (*KeywordMap)["uimage1DArray"] =           UIMAGE1DARRAY;
    444     (*KeywordMap)["image2DArray"] =            IMAGE2DARRAY;
    445     (*KeywordMap)["iimage2DArray"] =           IIMAGE2DARRAY;
    446     (*KeywordMap)["uimage2DArray"] =           UIMAGE2DARRAY;
    447     (*KeywordMap)["imageCubeArray"] =          IMAGECUBEARRAY;
    448     (*KeywordMap)["iimageCubeArray"] =         IIMAGECUBEARRAY;
    449     (*KeywordMap)["uimageCubeArray"] =         UIMAGECUBEARRAY;
    450     (*KeywordMap)["image2DMS"] =               IMAGE2DMS;
    451     (*KeywordMap)["iimage2DMS"] =              IIMAGE2DMS;
    452     (*KeywordMap)["uimage2DMS"] =              UIMAGE2DMS;
    453     (*KeywordMap)["image2DMSArray"] =          IMAGE2DMSARRAY;
    454     (*KeywordMap)["iimage2DMSArray"] =         IIMAGE2DMSARRAY;
    455     (*KeywordMap)["uimage2DMSArray"] =         UIMAGE2DMSARRAY;
    456     (*KeywordMap)["double"] =                  DOUBLE;
    457     (*KeywordMap)["dvec2"] =                   DVEC2;
    458     (*KeywordMap)["dvec3"] =                   DVEC3;
    459     (*KeywordMap)["dvec4"] =                   DVEC4;
    460     (*KeywordMap)["uint"] =                    UINT;
    461     (*KeywordMap)["uvec2"] =                   UVEC2;
    462     (*KeywordMap)["uvec3"] =                   UVEC3;
    463     (*KeywordMap)["uvec4"] =                   UVEC4;
    464 
    465     (*KeywordMap)["int64_t"] =                 INT64_T;
    466     (*KeywordMap)["uint64_t"] =                UINT64_T;
    467     (*KeywordMap)["i64vec2"] =                 I64VEC2;
    468     (*KeywordMap)["i64vec3"] =                 I64VEC3;
    469     (*KeywordMap)["i64vec4"] =                 I64VEC4;
    470     (*KeywordMap)["u64vec2"] =                 U64VEC2;
    471     (*KeywordMap)["u64vec3"] =                 U64VEC3;
    472     (*KeywordMap)["u64vec4"] =                 U64VEC4;
    473 
    474     // GL_EXT_shader_explicit_arithmetic_types
    475     (*KeywordMap)["int8_t"] =                  INT8_T;
    476     (*KeywordMap)["i8vec2"] =                  I8VEC2;
    477     (*KeywordMap)["i8vec3"] =                  I8VEC3;
    478     (*KeywordMap)["i8vec4"] =                  I8VEC4;
    479     (*KeywordMap)["uint8_t"] =                 UINT8_T;
    480     (*KeywordMap)["u8vec2"] =                  U8VEC2;
    481     (*KeywordMap)["u8vec3"] =                  U8VEC3;
    482     (*KeywordMap)["u8vec4"] =                  U8VEC4;
    483 
    484     (*KeywordMap)["int16_t"] =                 INT16_T;
    485     (*KeywordMap)["i16vec2"] =                 I16VEC2;
    486     (*KeywordMap)["i16vec3"] =                 I16VEC3;
    487     (*KeywordMap)["i16vec4"] =                 I16VEC4;
    488     (*KeywordMap)["uint16_t"] =                UINT16_T;
    489     (*KeywordMap)["u16vec2"] =                 U16VEC2;
    490     (*KeywordMap)["u16vec3"] =                 U16VEC3;
    491     (*KeywordMap)["u16vec4"] =                 U16VEC4;
    492 
    493     (*KeywordMap)["int32_t"] =                 INT32_T;
    494     (*KeywordMap)["i32vec2"] =                 I32VEC2;
    495     (*KeywordMap)["i32vec3"] =                 I32VEC3;
    496     (*KeywordMap)["i32vec4"] =                 I32VEC4;
    497     (*KeywordMap)["uint32_t"] =                UINT32_T;
    498     (*KeywordMap)["u32vec2"] =                 U32VEC2;
    499     (*KeywordMap)["u32vec3"] =                 U32VEC3;
    500     (*KeywordMap)["u32vec4"] =                 U32VEC4;
    501 
    502     (*KeywordMap)["float16_t"] =               FLOAT16_T;
    503     (*KeywordMap)["f16vec2"] =                 F16VEC2;
    504     (*KeywordMap)["f16vec3"] =                 F16VEC3;
    505     (*KeywordMap)["f16vec4"] =                 F16VEC4;
    506     (*KeywordMap)["f16mat2"] =                 F16MAT2;
    507     (*KeywordMap)["f16mat3"] =                 F16MAT3;
    508     (*KeywordMap)["f16mat4"] =                 F16MAT4;
    509     (*KeywordMap)["f16mat2x2"] =               F16MAT2X2;
    510     (*KeywordMap)["f16mat2x3"] =               F16MAT2X3;
    511     (*KeywordMap)["f16mat2x4"] =               F16MAT2X4;
    512     (*KeywordMap)["f16mat3x2"] =               F16MAT3X2;
    513     (*KeywordMap)["f16mat3x3"] =               F16MAT3X3;
    514     (*KeywordMap)["f16mat3x4"] =               F16MAT3X4;
    515     (*KeywordMap)["f16mat4x2"] =               F16MAT4X2;
    516     (*KeywordMap)["f16mat4x3"] =               F16MAT4X3;
    517     (*KeywordMap)["f16mat4x4"] =               F16MAT4X4;
    518 
    519     (*KeywordMap)["float32_t"] =               FLOAT32_T;
    520     (*KeywordMap)["f32vec2"] =                 F32VEC2;
    521     (*KeywordMap)["f32vec3"] =                 F32VEC3;
    522     (*KeywordMap)["f32vec4"] =                 F32VEC4;
    523     (*KeywordMap)["f32mat2"] =                 F32MAT2;
    524     (*KeywordMap)["f32mat3"] =                 F32MAT3;
    525     (*KeywordMap)["f32mat4"] =                 F32MAT4;
    526     (*KeywordMap)["f32mat2x2"] =               F32MAT2X2;
    527     (*KeywordMap)["f32mat2x3"] =               F32MAT2X3;
    528     (*KeywordMap)["f32mat2x4"] =               F32MAT2X4;
    529     (*KeywordMap)["f32mat3x2"] =               F32MAT3X2;
    530     (*KeywordMap)["f32mat3x3"] =               F32MAT3X3;
    531     (*KeywordMap)["f32mat3x4"] =               F32MAT3X4;
    532     (*KeywordMap)["f32mat4x2"] =               F32MAT4X2;
    533     (*KeywordMap)["f32mat4x3"] =               F32MAT4X3;
    534     (*KeywordMap)["f32mat4x4"] =               F32MAT4X4;
    535     (*KeywordMap)["float64_t"] =               FLOAT64_T;
    536     (*KeywordMap)["f64vec2"] =                 F64VEC2;
    537     (*KeywordMap)["f64vec3"] =                 F64VEC3;
    538     (*KeywordMap)["f64vec4"] =                 F64VEC4;
    539     (*KeywordMap)["f64mat2"] =                 F64MAT2;
    540     (*KeywordMap)["f64mat3"] =                 F64MAT3;
    541     (*KeywordMap)["f64mat4"] =                 F64MAT4;
    542     (*KeywordMap)["f64mat2x2"] =               F64MAT2X2;
    543     (*KeywordMap)["f64mat2x3"] =               F64MAT2X3;
    544     (*KeywordMap)["f64mat2x4"] =               F64MAT2X4;
    545     (*KeywordMap)["f64mat3x2"] =               F64MAT3X2;
    546     (*KeywordMap)["f64mat3x3"] =               F64MAT3X3;
    547     (*KeywordMap)["f64mat3x4"] =               F64MAT3X4;
    548     (*KeywordMap)["f64mat4x2"] =               F64MAT4X2;
    549     (*KeywordMap)["f64mat4x3"] =               F64MAT4X3;
    550     (*KeywordMap)["f64mat4x4"] =               F64MAT4X4;
    551 
    552     (*KeywordMap)["sampler2D"] =               SAMPLER2D;
    553     (*KeywordMap)["samplerCube"] =             SAMPLERCUBE;
    554     (*KeywordMap)["samplerCubeArray"] =        SAMPLERCUBEARRAY;
    555     (*KeywordMap)["samplerCubeArrayShadow"] =  SAMPLERCUBEARRAYSHADOW;
    556     (*KeywordMap)["isamplerCubeArray"] =       ISAMPLERCUBEARRAY;
    557     (*KeywordMap)["usamplerCubeArray"] =       USAMPLERCUBEARRAY;
    558     (*KeywordMap)["sampler1DArrayShadow"] =    SAMPLER1DARRAYSHADOW;
    559     (*KeywordMap)["isampler1DArray"] =         ISAMPLER1DARRAY;
    560     (*KeywordMap)["usampler1D"] =              USAMPLER1D;
    561     (*KeywordMap)["isampler1D"] =              ISAMPLER1D;
    562     (*KeywordMap)["usampler1DArray"] =         USAMPLER1DARRAY;
    563     (*KeywordMap)["samplerBuffer"] =           SAMPLERBUFFER;
    564     (*KeywordMap)["samplerCubeShadow"] =       SAMPLERCUBESHADOW;
    565     (*KeywordMap)["sampler2DArray"] =          SAMPLER2DARRAY;
    566     (*KeywordMap)["sampler2DArrayShadow"] =    SAMPLER2DARRAYSHADOW;
    567     (*KeywordMap)["isampler2D"] =              ISAMPLER2D;
    568     (*KeywordMap)["isampler3D"] =              ISAMPLER3D;
    569     (*KeywordMap)["isamplerCube"] =            ISAMPLERCUBE;
    570     (*KeywordMap)["isampler2DArray"] =         ISAMPLER2DARRAY;
    571     (*KeywordMap)["usampler2D"] =              USAMPLER2D;
    572     (*KeywordMap)["usampler3D"] =              USAMPLER3D;
    573     (*KeywordMap)["usamplerCube"] =            USAMPLERCUBE;
    574     (*KeywordMap)["usampler2DArray"] =         USAMPLER2DARRAY;
    575     (*KeywordMap)["isampler2DRect"] =          ISAMPLER2DRECT;
    576     (*KeywordMap)["usampler2DRect"] =          USAMPLER2DRECT;
    577     (*KeywordMap)["isamplerBuffer"] =          ISAMPLERBUFFER;
    578     (*KeywordMap)["usamplerBuffer"] =          USAMPLERBUFFER;
    579     (*KeywordMap)["sampler2DMS"] =             SAMPLER2DMS;
    580     (*KeywordMap)["isampler2DMS"] =            ISAMPLER2DMS;
    581     (*KeywordMap)["usampler2DMS"] =            USAMPLER2DMS;
    582     (*KeywordMap)["sampler2DMSArray"] =        SAMPLER2DMSARRAY;
    583     (*KeywordMap)["isampler2DMSArray"] =       ISAMPLER2DMSARRAY;
    584     (*KeywordMap)["usampler2DMSArray"] =       USAMPLER2DMSARRAY;
    585     (*KeywordMap)["sampler1D"] =               SAMPLER1D;
    586     (*KeywordMap)["sampler1DShadow"] =         SAMPLER1DSHADOW;
    587     (*KeywordMap)["sampler3D"] =               SAMPLER3D;
    588     (*KeywordMap)["sampler2DShadow"] =         SAMPLER2DSHADOW;
    589     (*KeywordMap)["sampler2DRect"] =           SAMPLER2DRECT;
    590     (*KeywordMap)["sampler2DRectShadow"] =     SAMPLER2DRECTSHADOW;
    591     (*KeywordMap)["sampler1DArray"] =          SAMPLER1DARRAY;
    592 
    593     (*KeywordMap)["samplerExternalOES"] =      SAMPLEREXTERNALOES; // GL_OES_EGL_image_external
    594 
    595     (*KeywordMap)["sampler"] =                 SAMPLER;
    596     (*KeywordMap)["samplerShadow"] =           SAMPLERSHADOW;
    597 
    598     (*KeywordMap)["texture2D"] =               TEXTURE2D;
    599     (*KeywordMap)["textureCube"] =             TEXTURECUBE;
    600     (*KeywordMap)["textureCubeArray"] =        TEXTURECUBEARRAY;
    601     (*KeywordMap)["itextureCubeArray"] =       ITEXTURECUBEARRAY;
    602     (*KeywordMap)["utextureCubeArray"] =       UTEXTURECUBEARRAY;
    603     (*KeywordMap)["itexture1DArray"] =         ITEXTURE1DARRAY;
    604     (*KeywordMap)["utexture1D"] =              UTEXTURE1D;
    605     (*KeywordMap)["itexture1D"] =              ITEXTURE1D;
    606     (*KeywordMap)["utexture1DArray"] =         UTEXTURE1DARRAY;
    607     (*KeywordMap)["textureBuffer"] =           TEXTUREBUFFER;
    608     (*KeywordMap)["texture2DArray"] =          TEXTURE2DARRAY;
    609     (*KeywordMap)["itexture2D"] =              ITEXTURE2D;
    610     (*KeywordMap)["itexture3D"] =              ITEXTURE3D;
    611     (*KeywordMap)["itextureCube"] =            ITEXTURECUBE;
    612     (*KeywordMap)["itexture2DArray"] =         ITEXTURE2DARRAY;
    613     (*KeywordMap)["utexture2D"] =              UTEXTURE2D;
    614     (*KeywordMap)["utexture3D"] =              UTEXTURE3D;
    615     (*KeywordMap)["utextureCube"] =            UTEXTURECUBE;
    616     (*KeywordMap)["utexture2DArray"] =         UTEXTURE2DARRAY;
    617     (*KeywordMap)["itexture2DRect"] =          ITEXTURE2DRECT;
    618     (*KeywordMap)["utexture2DRect"] =          UTEXTURE2DRECT;
    619     (*KeywordMap)["itextureBuffer"] =          ITEXTUREBUFFER;
    620     (*KeywordMap)["utextureBuffer"] =          UTEXTUREBUFFER;
    621     (*KeywordMap)["texture2DMS"] =             TEXTURE2DMS;
    622     (*KeywordMap)["itexture2DMS"] =            ITEXTURE2DMS;
    623     (*KeywordMap)["utexture2DMS"] =            UTEXTURE2DMS;
    624     (*KeywordMap)["texture2DMSArray"] =        TEXTURE2DMSARRAY;
    625     (*KeywordMap)["itexture2DMSArray"] =       ITEXTURE2DMSARRAY;
    626     (*KeywordMap)["utexture2DMSArray"] =       UTEXTURE2DMSARRAY;
    627     (*KeywordMap)["texture1D"] =               TEXTURE1D;
    628     (*KeywordMap)["texture3D"] =               TEXTURE3D;
    629     (*KeywordMap)["texture2DRect"] =           TEXTURE2DRECT;
    630     (*KeywordMap)["texture1DArray"] =          TEXTURE1DARRAY;
    631 
    632     (*KeywordMap)["subpassInput"] =            SUBPASSINPUT;
    633     (*KeywordMap)["subpassInputMS"] =          SUBPASSINPUTMS;
    634     (*KeywordMap)["isubpassInput"] =           ISUBPASSINPUT;
    635     (*KeywordMap)["isubpassInputMS"] =         ISUBPASSINPUTMS;
    636     (*KeywordMap)["usubpassInput"] =           USUBPASSINPUT;
    637     (*KeywordMap)["usubpassInputMS"] =         USUBPASSINPUTMS;
    638 
    639 #ifdef AMD_EXTENSIONS
    640     (*KeywordMap)["f16sampler1D"] =                 F16SAMPLER1D;
    641     (*KeywordMap)["f16sampler2D"] =                 F16SAMPLER2D;
    642     (*KeywordMap)["f16sampler3D"] =                 F16SAMPLER3D;
    643     (*KeywordMap)["f16sampler2DRect"] =             F16SAMPLER2DRECT;
    644     (*KeywordMap)["f16samplerCube"] =               F16SAMPLERCUBE;
    645     (*KeywordMap)["f16sampler1DArray"] =            F16SAMPLER1DARRAY;
    646     (*KeywordMap)["f16sampler2DArray"] =            F16SAMPLER2DARRAY;
    647     (*KeywordMap)["f16samplerCubeArray"] =          F16SAMPLERCUBEARRAY;
    648     (*KeywordMap)["f16samplerBuffer"] =             F16SAMPLERBUFFER;
    649     (*KeywordMap)["f16sampler2DMS"] =               F16SAMPLER2DMS;
    650     (*KeywordMap)["f16sampler2DMSArray"] =          F16SAMPLER2DMSARRAY;
    651     (*KeywordMap)["f16sampler1DShadow"] =           F16SAMPLER1DSHADOW;
    652     (*KeywordMap)["f16sampler2DShadow"] =           F16SAMPLER2DSHADOW;
    653     (*KeywordMap)["f16sampler2DRectShadow"] =       F16SAMPLER2DRECTSHADOW;
    654     (*KeywordMap)["f16samplerCubeShadow"] =         F16SAMPLERCUBESHADOW;
    655     (*KeywordMap)["f16sampler1DArrayShadow"] =      F16SAMPLER1DARRAYSHADOW;
    656     (*KeywordMap)["f16sampler2DArrayShadow"] =      F16SAMPLER2DARRAYSHADOW;
    657     (*KeywordMap)["f16samplerCubeArrayShadow"] =    F16SAMPLERCUBEARRAYSHADOW;
    658 
    659     (*KeywordMap)["f16image1D"] =                   F16IMAGE1D;
    660     (*KeywordMap)["f16image2D"] =                   F16IMAGE2D;
    661     (*KeywordMap)["f16image3D"] =                   F16IMAGE3D;
    662     (*KeywordMap)["f16image2DRect"] =               F16IMAGE2DRECT;
    663     (*KeywordMap)["f16imageCube"] =                 F16IMAGECUBE;
    664     (*KeywordMap)["f16image1DArray"] =              F16IMAGE1DARRAY;
    665     (*KeywordMap)["f16image2DArray"] =              F16IMAGE2DARRAY;
    666     (*KeywordMap)["f16imageCubeArray"] =            F16IMAGECUBEARRAY;
    667     (*KeywordMap)["f16imageBuffer"] =               F16IMAGEBUFFER;
    668     (*KeywordMap)["f16image2DMS"] =                 F16IMAGE2DMS;
    669     (*KeywordMap)["f16image2DMSArray"] =            F16IMAGE2DMSARRAY;
    670 
    671     (*KeywordMap)["f16texture1D"] =                 F16TEXTURE1D;
    672     (*KeywordMap)["f16texture2D"] =                 F16TEXTURE2D;
    673     (*KeywordMap)["f16texture3D"] =                 F16TEXTURE3D;
    674     (*KeywordMap)["f16texture2DRect"] =             F16TEXTURE2DRECT;
    675     (*KeywordMap)["f16textureCube"] =               F16TEXTURECUBE;
    676     (*KeywordMap)["f16texture1DArray"] =            F16TEXTURE1DARRAY;
    677     (*KeywordMap)["f16texture2DArray"] =            F16TEXTURE2DARRAY;
    678     (*KeywordMap)["f16textureCubeArray"] =          F16TEXTURECUBEARRAY;
    679     (*KeywordMap)["f16textureBuffer"] =             F16TEXTUREBUFFER;
    680     (*KeywordMap)["f16texture2DMS"] =               F16TEXTURE2DMS;
    681     (*KeywordMap)["f16texture2DMSArray"] =          F16TEXTURE2DMSARRAY;
    682 
    683     (*KeywordMap)["f16subpassInput"] =              F16SUBPASSINPUT;
    684     (*KeywordMap)["f16subpassInputMS"] =            F16SUBPASSINPUTMS;
    685 #endif
    686 
    687     (*KeywordMap)["noperspective"] =           NOPERSPECTIVE;
    688     (*KeywordMap)["smooth"] =                  SMOOTH;
    689     (*KeywordMap)["flat"] =                    FLAT;
    690 #ifdef AMD_EXTENSIONS
    691     (*KeywordMap)["__explicitInterpAMD"] =     EXPLICITINTERPAMD;
    692 #endif
    693     (*KeywordMap)["centroid"] =                CENTROID;
    694 #ifdef NV_EXTENSIONS
    695     (*KeywordMap)["pervertexNV"] =             PERVERTEXNV;
    696 #endif
    697     (*KeywordMap)["precise"] =                 PRECISE;
    698     (*KeywordMap)["invariant"] =               INVARIANT;
    699     (*KeywordMap)["packed"] =                  PACKED;
    700     (*KeywordMap)["resource"] =                RESOURCE;
    701     (*KeywordMap)["superp"] =                  SUPERP;
    702 
    703 #ifdef NV_EXTENSIONS
    704     (*KeywordMap)["rayPayloadNV"] =            PAYLOADNV;
    705     (*KeywordMap)["rayPayloadInNV"] =          PAYLOADINNV;
    706     (*KeywordMap)["hitAttributeNV"] =          HITATTRNV;
    707     (*KeywordMap)["callableDataNV"] =          CALLDATANV;
    708     (*KeywordMap)["callableDataInNV"] =        CALLDATAINNV;
    709     (*KeywordMap)["accelerationStructureNV"] = ACCSTRUCTNV;
    710     (*KeywordMap)["perprimitiveNV"] =          PERPRIMITIVENV;
    711     (*KeywordMap)["perviewNV"] =               PERVIEWNV;
    712     (*KeywordMap)["taskNV"] =                  PERTASKNV;
    713 #endif
    714 
    715     ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
    716 
    717     ReservedSet->insert("common");
    718     ReservedSet->insert("partition");
    719     ReservedSet->insert("active");
    720     ReservedSet->insert("asm");
    721     ReservedSet->insert("class");
    722     ReservedSet->insert("union");
    723     ReservedSet->insert("enum");
    724     ReservedSet->insert("typedef");
    725     ReservedSet->insert("template");
    726     ReservedSet->insert("this");
    727     ReservedSet->insert("goto");
    728     ReservedSet->insert("inline");
    729     ReservedSet->insert("noinline");
    730     ReservedSet->insert("public");
    731     ReservedSet->insert("static");
    732     ReservedSet->insert("extern");
    733     ReservedSet->insert("external");
    734     ReservedSet->insert("interface");
    735     ReservedSet->insert("long");
    736     ReservedSet->insert("short");
    737     ReservedSet->insert("half");
    738     ReservedSet->insert("fixed");
    739     ReservedSet->insert("unsigned");
    740     ReservedSet->insert("input");
    741     ReservedSet->insert("output");
    742     ReservedSet->insert("hvec2");
    743     ReservedSet->insert("hvec3");
    744     ReservedSet->insert("hvec4");
    745     ReservedSet->insert("fvec2");
    746     ReservedSet->insert("fvec3");
    747     ReservedSet->insert("fvec4");
    748     ReservedSet->insert("sampler3DRect");
    749     ReservedSet->insert("filter");
    750     ReservedSet->insert("sizeof");
    751     ReservedSet->insert("cast");
    752     ReservedSet->insert("namespace");
    753     ReservedSet->insert("using");
    754 }
    755 
    756 void TScanContext::deleteKeywordMap()
    757 {
    758     delete KeywordMap;
    759     KeywordMap = nullptr;
    760     delete ReservedSet;
    761     ReservedSet = nullptr;
    762 }
    763 
    764 // Called by yylex to get the next token.
    765 // Returning 0 implies end of input.
    766 int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
    767 {
    768     do {
    769         parserToken = &token;
    770         TPpToken ppToken;
    771         int token = pp->tokenize(ppToken);
    772         if (token == EndOfInput)
    773             return 0;
    774 
    775         tokenText = ppToken.name;
    776         loc = ppToken.loc;
    777         parserToken->sType.lex.loc = loc;
    778         switch (token) {
    779         case ';':  afterType = false; afterBuffer = false; return SEMICOLON;
    780         case ',':  afterType = false;   return COMMA;
    781         case ':':                       return COLON;
    782         case '=':  afterType = false;   return EQUAL;
    783         case '(':  afterType = false;   return LEFT_PAREN;
    784         case ')':  afterType = false;   return RIGHT_PAREN;
    785         case '.':  field = true;        return DOT;
    786         case '!':                       return BANG;
    787         case '-':                       return DASH;
    788         case '~':                       return TILDE;
    789         case '+':                       return PLUS;
    790         case '*':                       return STAR;
    791         case '/':                       return SLASH;
    792         case '%':                       return PERCENT;
    793         case '<':                       return LEFT_ANGLE;
    794         case '>':                       return RIGHT_ANGLE;
    795         case '|':                       return VERTICAL_BAR;
    796         case '^':                       return CARET;
    797         case '&':                       return AMPERSAND;
    798         case '?':                       return QUESTION;
    799         case '[':                       return LEFT_BRACKET;
    800         case ']':                       return RIGHT_BRACKET;
    801         case '{':  afterStruct = false; afterBuffer = false; return LEFT_BRACE;
    802         case '}':                       return RIGHT_BRACE;
    803         case '\\':
    804             parseContext.error(loc, "illegal use of escape character", "\\", "");
    805             break;
    806 
    807         case PPAtomAddAssign:          return ADD_ASSIGN;
    808         case PPAtomSubAssign:          return SUB_ASSIGN;
    809         case PPAtomMulAssign:          return MUL_ASSIGN;
    810         case PPAtomDivAssign:          return DIV_ASSIGN;
    811         case PPAtomModAssign:          return MOD_ASSIGN;
    812 
    813         case PpAtomRight:              return RIGHT_OP;
    814         case PpAtomLeft:               return LEFT_OP;
    815 
    816         case PpAtomRightAssign:        return RIGHT_ASSIGN;
    817         case PpAtomLeftAssign:         return LEFT_ASSIGN;
    818         case PpAtomAndAssign:          return AND_ASSIGN;
    819         case PpAtomOrAssign:           return OR_ASSIGN;
    820         case PpAtomXorAssign:          return XOR_ASSIGN;
    821 
    822         case PpAtomAnd:                return AND_OP;
    823         case PpAtomOr:                 return OR_OP;
    824         case PpAtomXor:                return XOR_OP;
    825 
    826         case PpAtomEQ:                 return EQ_OP;
    827         case PpAtomGE:                 return GE_OP;
    828         case PpAtomNE:                 return NE_OP;
    829         case PpAtomLE:                 return LE_OP;
    830 
    831         case PpAtomDecrement:          return DEC_OP;
    832         case PpAtomIncrement:          return INC_OP;
    833 
    834         case PpAtomColonColon:
    835             parseContext.error(loc, "not supported", "::", "");
    836             break;
    837 
    838         case PpAtomConstInt:           parserToken->sType.lex.i    = ppToken.ival;       return INTCONSTANT;
    839         case PpAtomConstUint:          parserToken->sType.lex.i    = ppToken.ival;       return UINTCONSTANT;
    840         case PpAtomConstInt16:         parserToken->sType.lex.i    = ppToken.ival;       return INT16CONSTANT;
    841         case PpAtomConstUint16:        parserToken->sType.lex.i    = ppToken.ival;       return UINT16CONSTANT;
    842         case PpAtomConstInt64:         parserToken->sType.lex.i64  = ppToken.i64val;     return INT64CONSTANT;
    843         case PpAtomConstUint64:        parserToken->sType.lex.i64  = ppToken.i64val;     return UINT64CONSTANT;
    844         case PpAtomConstFloat:         parserToken->sType.lex.d    = ppToken.dval;       return FLOATCONSTANT;
    845         case PpAtomConstDouble:        parserToken->sType.lex.d    = ppToken.dval;       return DOUBLECONSTANT;
    846         case PpAtomConstFloat16:       parserToken->sType.lex.d    = ppToken.dval;       return FLOAT16CONSTANT;
    847         case PpAtomIdentifier:
    848         {
    849             int token = tokenizeIdentifier();
    850             field = false;
    851             return token;
    852         }
    853 
    854         case EndOfInput:               return 0;
    855 
    856         default:
    857             char buf[2];
    858             buf[0] = (char)token;
    859             buf[1] = 0;
    860             parseContext.error(loc, "unexpected token", buf, "");
    861             break;
    862         }
    863     } while (true);
    864 }
    865 
    866 int TScanContext::tokenizeIdentifier()
    867 {
    868     if (ReservedSet->find(tokenText) != ReservedSet->end())
    869         return reservedWord();
    870 
    871     auto it = KeywordMap->find(tokenText);
    872     if (it == KeywordMap->end()) {
    873         // Should have an identifier of some sort
    874         return identifierOrType();
    875     }
    876     keyword = it->second;
    877 
    878     switch (keyword) {
    879     case CONST:
    880     case UNIFORM:
    881     case IN:
    882     case OUT:
    883     case INOUT:
    884     case BREAK:
    885     case CONTINUE:
    886     case DO:
    887     case FOR:
    888     case WHILE:
    889     case IF:
    890     case ELSE:
    891     case DISCARD:
    892     case RETURN:
    893     case CASE:
    894         return keyword;
    895 
    896     case STRUCT:
    897         afterStruct = true;
    898         return keyword;
    899 
    900     case NONUNIFORM:
    901         if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier))
    902             return keyword;
    903         else
    904             return identifierOrType();
    905 
    906     case SWITCH:
    907     case DEFAULT:
    908         if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
    909             (parseContext.profile != EEsProfile && parseContext.version < 130))
    910             reservedWord();
    911         return keyword;
    912 
    913     case VOID:
    914     case BOOL:
    915     case FLOAT:
    916     case INT:
    917     case BVEC2:
    918     case BVEC3:
    919     case BVEC4:
    920     case VEC2:
    921     case VEC3:
    922     case VEC4:
    923     case IVEC2:
    924     case IVEC3:
    925     case IVEC4:
    926     case MAT2:
    927     case MAT3:
    928     case MAT4:
    929     case SAMPLER2D:
    930     case SAMPLERCUBE:
    931         afterType = true;
    932         return keyword;
    933 
    934     case BOOLCONSTANT:
    935         if (strcmp("true", tokenText) == 0)
    936             parserToken->sType.lex.b = true;
    937         else
    938             parserToken->sType.lex.b = false;
    939         return keyword;
    940 
    941     case ATTRIBUTE:
    942     case VARYING:
    943         if (parseContext.profile == EEsProfile && parseContext.version >= 300)
    944             reservedWord();
    945         return keyword;
    946 
    947     case BUFFER:
    948         afterBuffer = true;
    949         if ((parseContext.profile == EEsProfile && parseContext.version < 310) ||
    950             (parseContext.profile != EEsProfile && parseContext.version < 430))
    951             return identifierOrType();
    952         return keyword;
    953 
    954 #ifdef NV_EXTENSIONS
    955     case PAYLOADNV:
    956     case PAYLOADINNV:
    957     case HITATTRNV:
    958     case CALLDATANV:
    959     case CALLDATAINNV:
    960     case ACCSTRUCTNV:
    961         if (parseContext.symbolTable.atBuiltInLevel() ||
    962             (parseContext.profile != EEsProfile && parseContext.version >= 460
    963                  && parseContext.extensionTurnedOn(E_GL_NV_ray_tracing)))
    964             return keyword;
    965         return identifierOrType();
    966 #endif
    967 
    968     case ATOMIC_UINT:
    969         if ((parseContext.profile == EEsProfile && parseContext.version >= 310) ||
    970             parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters))
    971             return keyword;
    972         return es30ReservedFromGLSL(420);
    973 
    974     case COHERENT:
    975     case DEVICECOHERENT:
    976     case QUEUEFAMILYCOHERENT:
    977     case WORKGROUPCOHERENT:
    978     case SUBGROUPCOHERENT:
    979     case NONPRIVATE:
    980     case RESTRICT:
    981     case READONLY:
    982     case WRITEONLY:
    983         if (parseContext.profile == EEsProfile && parseContext.version >= 310)
    984             return keyword;
    985         return es30ReservedFromGLSL(parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store) ? 130 : 420);
    986 
    987     case VOLATILE:
    988         if (parseContext.profile == EEsProfile && parseContext.version >= 310)
    989             return keyword;
    990         if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile ||
    991             (parseContext.version < 420 && ! parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))))
    992             reservedWord();
    993         return keyword;
    994 
    995     case LAYOUT:
    996     {
    997         const int numLayoutExts = 2;
    998         const char* layoutExts[numLayoutExts] = { E_GL_ARB_shading_language_420pack,
    999                                                   E_GL_ARB_explicit_attrib_location };
   1000         if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
   1001             (parseContext.profile != EEsProfile && parseContext.version < 140 &&
   1002             ! parseContext.extensionsTurnedOn(numLayoutExts, layoutExts)))
   1003             return identifierOrType();
   1004         return keyword;
   1005     }
   1006     case SHARED:
   1007         if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
   1008             (parseContext.profile != EEsProfile && parseContext.version < 140))
   1009             return identifierOrType();
   1010         return keyword;
   1011 
   1012     case PATCH:
   1013         if (parseContext.symbolTable.atBuiltInLevel() ||
   1014             (parseContext.profile == EEsProfile &&
   1015              (parseContext.version >= 320 ||
   1016               parseContext.extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))) ||
   1017             (parseContext.profile != EEsProfile && parseContext.extensionTurnedOn(E_GL_ARB_tessellation_shader)))
   1018             return keyword;
   1019 
   1020         return es30ReservedFromGLSL(400);
   1021 
   1022     case SAMPLE:
   1023         if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
   1024             parseContext.extensionsTurnedOn(1, &E_GL_OES_shader_multisample_interpolation))
   1025             return keyword;
   1026         return es30ReservedFromGLSL(400);
   1027 
   1028     case SUBROUTINE:
   1029         return es30ReservedFromGLSL(400);
   1030 
   1031     case HIGH_PRECISION:
   1032     case MEDIUM_PRECISION:
   1033     case LOW_PRECISION:
   1034     case PRECISION:
   1035         return precisionKeyword();
   1036 
   1037     case MAT2X2:
   1038     case MAT2X3:
   1039     case MAT2X4:
   1040     case MAT3X2:
   1041     case MAT3X3:
   1042     case MAT3X4:
   1043     case MAT4X2:
   1044     case MAT4X3:
   1045     case MAT4X4:
   1046         return matNxM();
   1047 
   1048     case DMAT2:
   1049     case DMAT3:
   1050     case DMAT4:
   1051     case DMAT2X2:
   1052     case DMAT2X3:
   1053     case DMAT2X4:
   1054     case DMAT3X2:
   1055     case DMAT3X3:
   1056     case DMAT3X4:
   1057     case DMAT4X2:
   1058     case DMAT4X3:
   1059     case DMAT4X4:
   1060         return dMat();
   1061 
   1062     case IMAGE1D:
   1063     case IIMAGE1D:
   1064     case UIMAGE1D:
   1065     case IMAGE1DARRAY:
   1066     case IIMAGE1DARRAY:
   1067     case UIMAGE1DARRAY:
   1068     case IMAGE2DRECT:
   1069     case IIMAGE2DRECT:
   1070     case UIMAGE2DRECT:
   1071         afterType = true;
   1072         return firstGenerationImage(false);
   1073 
   1074     case IMAGEBUFFER:
   1075     case IIMAGEBUFFER:
   1076     case UIMAGEBUFFER:
   1077         afterType = true;
   1078         if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
   1079             parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
   1080             return keyword;
   1081         return firstGenerationImage(false);
   1082 
   1083     case IMAGE2D:
   1084     case IIMAGE2D:
   1085     case UIMAGE2D:
   1086     case IMAGE3D:
   1087     case IIMAGE3D:
   1088     case UIMAGE3D:
   1089     case IMAGECUBE:
   1090     case IIMAGECUBE:
   1091     case UIMAGECUBE:
   1092     case IMAGE2DARRAY:
   1093     case IIMAGE2DARRAY:
   1094     case UIMAGE2DARRAY:
   1095         afterType = true;
   1096         return firstGenerationImage(true);
   1097 
   1098     case IMAGECUBEARRAY:
   1099     case IIMAGECUBEARRAY:
   1100     case UIMAGECUBEARRAY:
   1101         afterType = true;
   1102         if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
   1103             parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array))
   1104             return keyword;
   1105         return secondGenerationImage();
   1106 
   1107     case IMAGE2DMS:
   1108     case IIMAGE2DMS:
   1109     case UIMAGE2DMS:
   1110     case IMAGE2DMSARRAY:
   1111     case IIMAGE2DMSARRAY:
   1112     case UIMAGE2DMSARRAY:
   1113         afterType = true;
   1114         return secondGenerationImage();
   1115 
   1116     case DOUBLE:
   1117     case DVEC2:
   1118     case DVEC3:
   1119     case DVEC4:
   1120         afterType = true;
   1121         if (parseContext.profile == EEsProfile || parseContext.version < 400)
   1122             reservedWord();
   1123         return keyword;
   1124 
   1125     case INT64_T:
   1126     case UINT64_T:
   1127     case I64VEC2:
   1128     case I64VEC3:
   1129     case I64VEC4:
   1130     case U64VEC2:
   1131     case U64VEC3:
   1132     case U64VEC4:
   1133         afterType = true;
   1134         if (parseContext.symbolTable.atBuiltInLevel() ||
   1135             (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
   1136              (parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) ||
   1137               parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
   1138               parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int64))))
   1139             return keyword;
   1140         return identifierOrType();
   1141 
   1142     case INT8_T:
   1143     case UINT8_T:
   1144     case I8VEC2:
   1145     case I8VEC3:
   1146     case I8VEC4:
   1147     case U8VEC2:
   1148     case U8VEC3:
   1149     case U8VEC4:
   1150         afterType = true;
   1151         if (parseContext.symbolTable.atBuiltInLevel() ||
   1152             ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
   1153               parseContext.extensionTurnedOn(E_GL_EXT_shader_8bit_storage) ||
   1154               parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8)) &&
   1155               parseContext.profile != EEsProfile && parseContext.version >= 450))
   1156             return keyword;
   1157         return identifierOrType();
   1158 
   1159     case INT16_T:
   1160     case UINT16_T:
   1161     case I16VEC2:
   1162     case I16VEC3:
   1163     case I16VEC4:
   1164     case U16VEC2:
   1165     case U16VEC3:
   1166     case U16VEC4:
   1167         afterType = true;
   1168         if (parseContext.symbolTable.atBuiltInLevel() ||
   1169             (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
   1170              (
   1171 #ifdef AMD_EXTENSIONS
   1172               parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) ||
   1173 #endif
   1174               parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
   1175               parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
   1176               parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16))))
   1177             return keyword;
   1178         return identifierOrType();
   1179     case INT32_T:
   1180     case UINT32_T:
   1181     case I32VEC2:
   1182     case I32VEC3:
   1183     case I32VEC4:
   1184     case U32VEC2:
   1185     case U32VEC3:
   1186     case U32VEC4:
   1187         afterType = true;
   1188         if (parseContext.symbolTable.atBuiltInLevel() ||
   1189            ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
   1190              parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32)) &&
   1191              parseContext.profile != EEsProfile && parseContext.version >= 450))
   1192             return keyword;
   1193         return identifierOrType();
   1194     case FLOAT32_T:
   1195     case F32VEC2:
   1196     case F32VEC3:
   1197     case F32VEC4:
   1198     case F32MAT2:
   1199     case F32MAT3:
   1200     case F32MAT4:
   1201     case F32MAT2X2:
   1202     case F32MAT2X3:
   1203     case F32MAT2X4:
   1204     case F32MAT3X2:
   1205     case F32MAT3X3:
   1206     case F32MAT3X4:
   1207     case F32MAT4X2:
   1208     case F32MAT4X3:
   1209     case F32MAT4X4:
   1210         afterType = true;
   1211         if (parseContext.symbolTable.atBuiltInLevel() ||
   1212             ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
   1213               parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32)) &&
   1214               parseContext.profile != EEsProfile && parseContext.version >= 450))
   1215             return keyword;
   1216         return identifierOrType();
   1217 
   1218     case FLOAT64_T:
   1219     case F64VEC2:
   1220     case F64VEC3:
   1221     case F64VEC4:
   1222     case F64MAT2:
   1223     case F64MAT3:
   1224     case F64MAT4:
   1225     case F64MAT2X2:
   1226     case F64MAT2X3:
   1227     case F64MAT2X4:
   1228     case F64MAT3X2:
   1229     case F64MAT3X3:
   1230     case F64MAT3X4:
   1231     case F64MAT4X2:
   1232     case F64MAT4X3:
   1233     case F64MAT4X4:
   1234         afterType = true;
   1235         if (parseContext.symbolTable.atBuiltInLevel() ||
   1236             ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
   1237               parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64)) &&
   1238               parseContext.profile != EEsProfile && parseContext.version >= 450))
   1239             return keyword;
   1240         return identifierOrType();
   1241 
   1242     case FLOAT16_T:
   1243     case F16VEC2:
   1244     case F16VEC3:
   1245     case F16VEC4:
   1246         afterType = true;
   1247         if (parseContext.symbolTable.atBuiltInLevel() ||
   1248             (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
   1249              (
   1250 #ifdef AMD_EXTENSIONS
   1251               parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
   1252 #endif
   1253               parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
   1254               parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
   1255               parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16))))
   1256             return keyword;
   1257 
   1258         return identifierOrType();
   1259 
   1260     case F16MAT2:
   1261     case F16MAT3:
   1262     case F16MAT4:
   1263     case F16MAT2X2:
   1264     case F16MAT2X3:
   1265     case F16MAT2X4:
   1266     case F16MAT3X2:
   1267     case F16MAT3X3:
   1268     case F16MAT3X4:
   1269     case F16MAT4X2:
   1270     case F16MAT4X3:
   1271     case F16MAT4X4:
   1272         afterType = true;
   1273         if (parseContext.symbolTable.atBuiltInLevel() ||
   1274             (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
   1275              (
   1276 #ifdef AMD_EXTENSIONS
   1277               parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
   1278 #endif
   1279               parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
   1280               parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16))))
   1281             return keyword;
   1282 
   1283         return identifierOrType();
   1284 
   1285     case SAMPLERCUBEARRAY:
   1286     case SAMPLERCUBEARRAYSHADOW:
   1287     case ISAMPLERCUBEARRAY:
   1288     case USAMPLERCUBEARRAY:
   1289         afterType = true;
   1290         if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
   1291             parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array))
   1292             return keyword;
   1293         if (parseContext.profile == EEsProfile || (parseContext.version < 400 && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_cube_map_array)))
   1294             reservedWord();
   1295         return keyword;
   1296 
   1297     case ISAMPLER1D:
   1298     case ISAMPLER1DARRAY:
   1299     case SAMPLER1DARRAYSHADOW:
   1300     case USAMPLER1D:
   1301     case USAMPLER1DARRAY:
   1302         afterType = true;
   1303         return es30ReservedFromGLSL(130);
   1304 
   1305     case UINT:
   1306     case UVEC2:
   1307     case UVEC3:
   1308     case UVEC4:
   1309     case SAMPLERCUBESHADOW:
   1310     case SAMPLER2DARRAY:
   1311     case SAMPLER2DARRAYSHADOW:
   1312     case ISAMPLER2D:
   1313     case ISAMPLER3D:
   1314     case ISAMPLERCUBE:
   1315     case ISAMPLER2DARRAY:
   1316     case USAMPLER2D:
   1317     case USAMPLER3D:
   1318     case USAMPLERCUBE:
   1319     case USAMPLER2DARRAY:
   1320         afterType = true;
   1321         return nonreservedKeyword(300, 130);
   1322 
   1323     case ISAMPLER2DRECT:
   1324     case USAMPLER2DRECT:
   1325         afterType = true;
   1326         return es30ReservedFromGLSL(140);
   1327 
   1328     case SAMPLERBUFFER:
   1329         afterType = true;
   1330         if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
   1331             parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
   1332             return keyword;
   1333         return es30ReservedFromGLSL(130);
   1334 
   1335     case ISAMPLERBUFFER:
   1336     case USAMPLERBUFFER:
   1337         afterType = true;
   1338         if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
   1339             parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
   1340             return keyword;
   1341         return es30ReservedFromGLSL(140);
   1342 
   1343     case SAMPLER2DMS:
   1344     case ISAMPLER2DMS:
   1345     case USAMPLER2DMS:
   1346         afterType = true;
   1347         if (parseContext.profile == EEsProfile && parseContext.version >= 310)
   1348             return keyword;
   1349         return es30ReservedFromGLSL(150);
   1350 
   1351     case SAMPLER2DMSARRAY:
   1352     case ISAMPLER2DMSARRAY:
   1353     case USAMPLER2DMSARRAY:
   1354         afterType = true;
   1355         if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
   1356             parseContext.extensionsTurnedOn(1, &E_GL_OES_texture_storage_multisample_2d_array))
   1357             return keyword;
   1358         return es30ReservedFromGLSL(150);
   1359 
   1360     case SAMPLER1D:
   1361     case SAMPLER1DSHADOW:
   1362         afterType = true;
   1363         if (parseContext.profile == EEsProfile)
   1364             reservedWord();
   1365         return keyword;
   1366 
   1367     case SAMPLER3D:
   1368         afterType = true;
   1369         if (parseContext.profile == EEsProfile && parseContext.version < 300) {
   1370             if (!parseContext.extensionTurnedOn(E_GL_OES_texture_3D))
   1371                 reservedWord();
   1372         }
   1373         return keyword;
   1374 
   1375     case SAMPLER2DSHADOW:
   1376         afterType = true;
   1377         if (parseContext.profile == EEsProfile && parseContext.version < 300) {
   1378             if (!parseContext.extensionTurnedOn(E_GL_EXT_shadow_samplers))
   1379                 reservedWord();
   1380         }
   1381         return keyword;
   1382 
   1383     case SAMPLER2DRECT:
   1384     case SAMPLER2DRECTSHADOW:
   1385         afterType = true;
   1386         if (parseContext.profile == EEsProfile)
   1387             reservedWord();
   1388         else if (parseContext.version < 140 && ! parseContext.symbolTable.atBuiltInLevel() && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_rectangle)) {
   1389             if (parseContext.relaxedErrors())
   1390                 parseContext.requireExtensions(loc, 1, &E_GL_ARB_texture_rectangle, "texture-rectangle sampler keyword");
   1391             else
   1392                 reservedWord();
   1393         }
   1394         return keyword;
   1395 
   1396     case SAMPLER1DARRAY:
   1397         afterType = true;
   1398         if (parseContext.profile == EEsProfile && parseContext.version == 300)
   1399             reservedWord();
   1400         else if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
   1401                  (parseContext.profile != EEsProfile && parseContext.version < 130))
   1402             return identifierOrType();
   1403         return keyword;
   1404 
   1405     case SAMPLEREXTERNALOES:
   1406         afterType = true;
   1407         if (parseContext.symbolTable.atBuiltInLevel() ||
   1408             parseContext.extensionTurnedOn(E_GL_OES_EGL_image_external) ||
   1409             parseContext.extensionTurnedOn(E_GL_OES_EGL_image_external_essl3))
   1410             return keyword;
   1411         return identifierOrType();
   1412 
   1413     case TEXTURE2D:
   1414     case TEXTURECUBE:
   1415     case TEXTURECUBEARRAY:
   1416     case ITEXTURECUBEARRAY:
   1417     case UTEXTURECUBEARRAY:
   1418     case ITEXTURE1DARRAY:
   1419     case UTEXTURE1D:
   1420     case ITEXTURE1D:
   1421     case UTEXTURE1DARRAY:
   1422     case TEXTUREBUFFER:
   1423     case TEXTURE2DARRAY:
   1424     case ITEXTURE2D:
   1425     case ITEXTURE3D:
   1426     case ITEXTURECUBE:
   1427     case ITEXTURE2DARRAY:
   1428     case UTEXTURE2D:
   1429     case UTEXTURE3D:
   1430     case UTEXTURECUBE:
   1431     case UTEXTURE2DARRAY:
   1432     case ITEXTURE2DRECT:
   1433     case UTEXTURE2DRECT:
   1434     case ITEXTUREBUFFER:
   1435     case UTEXTUREBUFFER:
   1436     case TEXTURE2DMS:
   1437     case ITEXTURE2DMS:
   1438     case UTEXTURE2DMS:
   1439     case TEXTURE2DMSARRAY:
   1440     case ITEXTURE2DMSARRAY:
   1441     case UTEXTURE2DMSARRAY:
   1442     case TEXTURE1D:
   1443     case TEXTURE3D:
   1444     case TEXTURE2DRECT:
   1445     case TEXTURE1DARRAY:
   1446     case SAMPLER:
   1447     case SAMPLERSHADOW:
   1448         if (parseContext.spvVersion.vulkan > 0)
   1449             return keyword;
   1450         else
   1451             return identifierOrType();
   1452 
   1453     case SUBPASSINPUT:
   1454     case SUBPASSINPUTMS:
   1455     case ISUBPASSINPUT:
   1456     case ISUBPASSINPUTMS:
   1457     case USUBPASSINPUT:
   1458     case USUBPASSINPUTMS:
   1459         if (parseContext.spvVersion.vulkan > 0)
   1460             return keyword;
   1461         else
   1462             return identifierOrType();
   1463 
   1464 #ifdef AMD_EXTENSIONS
   1465     case F16SAMPLER1D:
   1466     case F16SAMPLER2D:
   1467     case F16SAMPLER3D:
   1468     case F16SAMPLER2DRECT:
   1469     case F16SAMPLERCUBE:
   1470     case F16SAMPLER1DARRAY:
   1471     case F16SAMPLER2DARRAY:
   1472     case F16SAMPLERCUBEARRAY:
   1473     case F16SAMPLERBUFFER:
   1474     case F16SAMPLER2DMS:
   1475     case F16SAMPLER2DMSARRAY:
   1476     case F16SAMPLER1DSHADOW:
   1477     case F16SAMPLER2DSHADOW:
   1478     case F16SAMPLER1DARRAYSHADOW:
   1479     case F16SAMPLER2DARRAYSHADOW:
   1480     case F16SAMPLER2DRECTSHADOW:
   1481     case F16SAMPLERCUBESHADOW:
   1482     case F16SAMPLERCUBEARRAYSHADOW:
   1483 
   1484     case F16IMAGE1D:
   1485     case F16IMAGE2D:
   1486     case F16IMAGE3D:
   1487     case F16IMAGE2DRECT:
   1488     case F16IMAGECUBE:
   1489     case F16IMAGE1DARRAY:
   1490     case F16IMAGE2DARRAY:
   1491     case F16IMAGECUBEARRAY:
   1492     case F16IMAGEBUFFER:
   1493     case F16IMAGE2DMS:
   1494     case F16IMAGE2DMSARRAY:
   1495 
   1496     case F16TEXTURE1D:
   1497     case F16TEXTURE2D:
   1498     case F16TEXTURE3D:
   1499     case F16TEXTURE2DRECT:
   1500     case F16TEXTURECUBE:
   1501     case F16TEXTURE1DARRAY:
   1502     case F16TEXTURE2DARRAY:
   1503     case F16TEXTURECUBEARRAY:
   1504     case F16TEXTUREBUFFER:
   1505     case F16TEXTURE2DMS:
   1506     case F16TEXTURE2DMSARRAY:
   1507 
   1508     case F16SUBPASSINPUT:
   1509     case F16SUBPASSINPUTMS:
   1510         afterType = true;
   1511         if (parseContext.symbolTable.atBuiltInLevel() ||
   1512             (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch) &&
   1513              parseContext.profile != EEsProfile && parseContext.version >= 450))
   1514             return keyword;
   1515         return identifierOrType();
   1516 #endif
   1517 
   1518     case NOPERSPECTIVE:
   1519 #ifdef NV_EXTENSIONS
   1520         if (parseContext.profile == EEsProfile && parseContext.version >= 300 &&
   1521             parseContext.extensionTurnedOn(E_GL_NV_shader_noperspective_interpolation))
   1522             return keyword;
   1523 #endif
   1524         return es30ReservedFromGLSL(130);
   1525 
   1526     case SMOOTH:
   1527         if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
   1528             (parseContext.profile != EEsProfile && parseContext.version < 130))
   1529             return identifierOrType();
   1530         return keyword;
   1531 
   1532 #ifdef AMD_EXTENSIONS
   1533     case EXPLICITINTERPAMD:
   1534         if (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
   1535             parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter))
   1536             return keyword;
   1537         return identifierOrType();
   1538 #endif
   1539 
   1540 #ifdef NV_EXTENSIONS
   1541     case PERVERTEXNV:
   1542         if (((parseContext.profile != EEsProfile && parseContext.version >= 450) ||
   1543             (parseContext.profile == EEsProfile && parseContext.version >= 320)) &&
   1544             parseContext.extensionTurnedOn(E_GL_NV_fragment_shader_barycentric))
   1545             return keyword;
   1546         return identifierOrType();
   1547 #endif
   1548 
   1549     case FLAT:
   1550         if (parseContext.profile == EEsProfile && parseContext.version < 300)
   1551             reservedWord();
   1552         else if (parseContext.profile != EEsProfile && parseContext.version < 130)
   1553             return identifierOrType();
   1554         return keyword;
   1555 
   1556     case CENTROID:
   1557         if (parseContext.version < 120)
   1558             return identifierOrType();
   1559         return keyword;
   1560 
   1561     case PRECISE:
   1562         if ((parseContext.profile == EEsProfile &&
   1563              (parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5))) ||
   1564             (parseContext.profile != EEsProfile && parseContext.version >= 400))
   1565             return keyword;
   1566         if (parseContext.profile == EEsProfile && parseContext.version == 310) {
   1567             reservedWord();
   1568             return keyword;
   1569         }
   1570         return identifierOrType();
   1571 
   1572     case INVARIANT:
   1573         if (parseContext.profile != EEsProfile && parseContext.version < 120)
   1574             return identifierOrType();
   1575         return keyword;
   1576 
   1577     case PACKED:
   1578         if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
   1579             (parseContext.profile != EEsProfile && parseContext.version < 330))
   1580             return reservedWord();
   1581         return identifierOrType();
   1582 
   1583     case RESOURCE:
   1584     {
   1585         bool reserved = (parseContext.profile == EEsProfile && parseContext.version >= 300) ||
   1586                         (parseContext.profile != EEsProfile && parseContext.version >= 420);
   1587         return identifierOrReserved(reserved);
   1588     }
   1589     case SUPERP:
   1590     {
   1591         bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130;
   1592         return identifierOrReserved(reserved);
   1593     }
   1594 
   1595 #ifdef NV_EXTENSIONS
   1596     case PERPRIMITIVENV:
   1597     case PERVIEWNV:
   1598     case PERTASKNV:
   1599         if ((parseContext.profile != EEsProfile && parseContext.version >= 450) ||
   1600             (parseContext.profile == EEsProfile && parseContext.version >= 320) ||
   1601             parseContext.extensionTurnedOn(E_GL_NV_mesh_shader))
   1602             return keyword;
   1603         return identifierOrType();
   1604 #endif
   1605 
   1606     default:
   1607         parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
   1608         return 0;
   1609     }
   1610 }
   1611 
   1612 int TScanContext::identifierOrType()
   1613 {
   1614     parserToken->sType.lex.string = NewPoolTString(tokenText);
   1615     if (field)
   1616         return IDENTIFIER;
   1617 
   1618     parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string);
   1619     if ((afterType == false && afterStruct == false) && parserToken->sType.lex.symbol != nullptr) {
   1620         if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) {
   1621             if (variable->isUserType() &&
   1622                 // treat redeclaration of forward-declared buffer/uniform reference as an identifier
   1623                 !(variable->getType().getBasicType() == EbtReference && afterBuffer)) {
   1624                 afterType = true;
   1625 
   1626                 return TYPE_NAME;
   1627             }
   1628         }
   1629     }
   1630 
   1631     return IDENTIFIER;
   1632 }
   1633 
   1634 // Give an error for use of a reserved symbol.
   1635 // However, allow built-in declarations to use reserved words, to allow
   1636 // extension support before the extension is enabled.
   1637 int TScanContext::reservedWord()
   1638 {
   1639     if (! parseContext.symbolTable.atBuiltInLevel())
   1640         parseContext.error(loc, "Reserved word.", tokenText, "", "");
   1641 
   1642     return 0;
   1643 }
   1644 
   1645 int TScanContext::identifierOrReserved(bool reserved)
   1646 {
   1647     if (reserved) {
   1648         reservedWord();
   1649 
   1650         return 0;
   1651     }
   1652 
   1653     if (parseContext.forwardCompatible)
   1654         parseContext.warn(loc, "using future reserved keyword", tokenText, "");
   1655 
   1656     return identifierOrType();
   1657 }
   1658 
   1659 // For keywords that suddenly showed up on non-ES (not previously reserved)
   1660 // but then got reserved by ES 3.0.
   1661 int TScanContext::es30ReservedFromGLSL(int version)
   1662 {
   1663     if (parseContext.symbolTable.atBuiltInLevel())
   1664         return keyword;
   1665 
   1666     if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
   1667         (parseContext.profile != EEsProfile && parseContext.version < version)) {
   1668             if (parseContext.forwardCompatible)
   1669                 parseContext.warn(loc, "future reserved word in ES 300 and keyword in GLSL", tokenText, "");
   1670 
   1671             return identifierOrType();
   1672     } else if (parseContext.profile == EEsProfile && parseContext.version >= 300)
   1673         reservedWord();
   1674 
   1675     return keyword;
   1676 }
   1677 
   1678 // For a keyword that was never reserved, until it suddenly
   1679 // showed up, both in an es version and a non-ES version.
   1680 int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion)
   1681 {
   1682     if ((parseContext.profile == EEsProfile && parseContext.version < esVersion) ||
   1683         (parseContext.profile != EEsProfile && parseContext.version < nonEsVersion)) {
   1684         if (parseContext.forwardCompatible)
   1685             parseContext.warn(loc, "using future keyword", tokenText, "");
   1686 
   1687         return identifierOrType();
   1688     }
   1689 
   1690     return keyword;
   1691 }
   1692 
   1693 int TScanContext::precisionKeyword()
   1694 {
   1695     if (parseContext.profile == EEsProfile || parseContext.version >= 130)
   1696         return keyword;
   1697 
   1698     if (parseContext.forwardCompatible)
   1699         parseContext.warn(loc, "using ES precision qualifier keyword", tokenText, "");
   1700 
   1701     return identifierOrType();
   1702 }
   1703 
   1704 int TScanContext::matNxM()
   1705 {
   1706     afterType = true;
   1707 
   1708     if (parseContext.version > 110)
   1709         return keyword;
   1710 
   1711     if (parseContext.forwardCompatible)
   1712         parseContext.warn(loc, "using future non-square matrix type keyword", tokenText, "");
   1713 
   1714     return identifierOrType();
   1715 }
   1716 
   1717 int TScanContext::dMat()
   1718 {
   1719     afterType = true;
   1720 
   1721     if (parseContext.profile == EEsProfile && parseContext.version >= 300) {
   1722         reservedWord();
   1723 
   1724         return keyword;
   1725     }
   1726 
   1727     if (parseContext.profile != EEsProfile && parseContext.version >= 400)
   1728         return keyword;
   1729 
   1730     if (parseContext.forwardCompatible)
   1731         parseContext.warn(loc, "using future type keyword", tokenText, "");
   1732 
   1733     return identifierOrType();
   1734 }
   1735 
   1736 int TScanContext::firstGenerationImage(bool inEs310)
   1737 {
   1738     if (parseContext.symbolTable.atBuiltInLevel() ||
   1739         (parseContext.profile != EEsProfile && (parseContext.version >= 420 ||
   1740          parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))) ||
   1741         (inEs310 && parseContext.profile == EEsProfile && parseContext.version >= 310))
   1742         return keyword;
   1743 
   1744     if ((parseContext.profile == EEsProfile && parseContext.version >= 300) ||
   1745         (parseContext.profile != EEsProfile && parseContext.version >= 130)) {
   1746         reservedWord();
   1747 
   1748         return keyword;
   1749     }
   1750 
   1751     if (parseContext.forwardCompatible)
   1752         parseContext.warn(loc, "using future type keyword", tokenText, "");
   1753 
   1754     return identifierOrType();
   1755 }
   1756 
   1757 int TScanContext::secondGenerationImage()
   1758 {
   1759     if (parseContext.profile == EEsProfile && parseContext.version >= 310) {
   1760         reservedWord();
   1761         return keyword;
   1762     }
   1763 
   1764     if (parseContext.symbolTable.atBuiltInLevel() ||
   1765         (parseContext.profile != EEsProfile &&
   1766          (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))))
   1767         return keyword;
   1768 
   1769     if (parseContext.forwardCompatible)
   1770         parseContext.warn(loc, "using future type keyword", tokenText, "");
   1771 
   1772     return identifierOrType();
   1773 }
   1774 
   1775 } // end namespace glslang
   1776