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