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