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