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