Browse Source

Updated glslang.

Бранимир Караџић 1 year ago
parent
commit
2e511a7d4c
42 changed files with 1660 additions and 1379 deletions
  1. 33 18
      3rdparty/glslang/SPIRV/GlslangToSpv.cpp
  2. 9 8
      3rdparty/glslang/SPIRV/GlslangToSpv.h
  3. 2 1
      3rdparty/glslang/SPIRV/Logger.h
  4. 16 1
      3rdparty/glslang/SPIRV/SPVRemapper.h
  5. 73 16
      3rdparty/glslang/SPIRV/SpvBuilder.cpp
  6. 15 8
      3rdparty/glslang/SPIRV/SpvBuilder.h
  7. 1 1
      3rdparty/glslang/SPIRV/SpvPostProcess.cpp
  8. 6 1
      3rdparty/glslang/SPIRV/SpvTools.cpp
  9. 22 18
      3rdparty/glslang/SPIRV/SpvTools.h
  10. 1 1
      3rdparty/glslang/SPIRV/disassemble.cpp
  11. 3 1
      3rdparty/glslang/SPIRV/disassemble.h
  12. 1 1
      3rdparty/glslang/SPIRV/doc.cpp
  13. 14 0
      3rdparty/glslang/SPIRV/spirv.hpp
  14. 9 0
      3rdparty/glslang/SPIRV/spvIR.h
  15. 15 3
      3rdparty/glslang/StandAlone/StandAlone.cpp
  16. 2 2
      3rdparty/glslang/build_info.h
  17. 12 1
      3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp
  18. 1 1
      3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp
  19. 426 452
      3rdparty/glslang/glslang/HLSL/hlslScanContext.cpp
  20. 0 15
      3rdparty/glslang/glslang/Include/Types.h
  21. 1 0
      3rdparty/glslang/glslang/Include/glslang_c_interface.h
  22. 1 0
      3rdparty/glslang/glslang/Include/glslang_c_shader_types.h
  23. 13 2
      3rdparty/glslang/glslang/Include/intermediate.h
  24. 4 1
      3rdparty/glslang/glslang/Include/visibility.h
  25. 6 3
      3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp
  26. 471 493
      3rdparty/glslang/glslang/MachineIndependent/Scan.cpp
  27. 60 37
      3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp
  28. 1 1
      3rdparty/glslang/glslang/MachineIndependent/SymbolTable.cpp
  29. 6 2
      3rdparty/glslang/glslang/MachineIndependent/glslang.y
  30. 268 264
      3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp
  31. 2 11
      3rdparty/glslang/glslang/MachineIndependent/iomapper.h
  32. 102 0
      3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp
  33. 2 0
      3rdparty/glslang/glslang/MachineIndependent/localintermediate.h
  34. 4 2
      3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp
  35. 2 1
      3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp
  36. 4 1
      3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpContext.h
  37. 2 1
      3rdparty/glslang/glslang/MachineIndependent/propagateNoContraction.h
  38. 3 2
      3rdparty/glslang/glslang/MachineIndependent/reflection.h
  39. 2 1
      3rdparty/glslang/glslang/OSDependent/osinclude.h
  40. 5 4
      3rdparty/glslang/glslang/Public/ResourceLimits.h
  41. 35 0
      3rdparty/glslang/glslang/Public/ShaderLang.h
  42. 5 4
      3rdparty/glslang/glslang/Public/resource_limits_c.h

+ 33 - 18
3rdparty/glslang/SPIRV/GlslangToSpv.cpp

@@ -1558,7 +1558,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
         else {
             builder.setEmitSpirvDebugInfo();
         }
-        builder.setDebugSourceFile(glslangIntermediate->getSourceFile());
+        builder.setDebugMainSourceFile(glslangIntermediate->getSourceFile());
 
         // Set the source shader's text. If for SPV version 1.0, include
         // a preamble in comments stating the OpModuleProcessed instructions.
@@ -2858,9 +2858,16 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
                                                             // SPIR-V, for an out parameter
     std::vector<spv::Id> temporaryLvalues;                  // temporaries to pass, as proxies for complexLValues
 
-    auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ?
-        invertedType :
-        convertGlslangToSpvType(node->getType()); };
+    auto resultType = [&invertedType, &node, this](){
+        if (invertedType != spv::NoType) {
+            return invertedType;
+        } else {
+            auto ret = convertGlslangToSpvType(node->getType());
+            // convertGlslangToSpvType may clobber the debug location, reset it
+            builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
+            return ret;
+        }
+    };
 
     // try texturing
     result = createImageTextureFunctionCall(node);
@@ -2917,8 +2924,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
 
                 return false;
             } else {
-                if (node->getOp() == glslang::EOpScope)
-                    builder.enterLexicalBlock(0);
+                if (node->getOp() == glslang::EOpScope) {
+                    auto loc = node->getLoc();
+                    builder.enterLexicalBlock(loc.line, loc.column);
+                }
             }
         } else {
             if (sequenceDepth > 1 && node->getOp() == glslang::EOpScope)
@@ -2967,6 +2976,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
                 currentFunction->setDebugLineInfo(sourceFileId, loc.line, loc.column);
             }
         } else {
+            if (options.generateDebugInfo) {
+                if (glslangIntermediate->getSource() == glslang::EShSourceGlsl && node->getSequence().size() > 1) {
+                    auto endLoc = node->getSequence()[1]->getAsAggregate()->getEndLoc();
+                    builder.setDebugSourceLocation(endLoc.line, endLoc.getFilename());
+                }
+            }
             if (inEntryPoint)
                 entryPointTerminated = true;
             builder.leaveFunction();
@@ -4120,7 +4135,7 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
         if (codeSegments[s])
             codeSegments[s]->traverse(this);
         else
-            builder.addSwitchBreak();
+            builder.addSwitchBreak(true);
     }
     breakForLoop.pop();
 
@@ -4144,7 +4159,7 @@ void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* n
 bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIntermLoop* node)
 {
     auto blocks = builder.makeNewLoop();
-    builder.createBranch(&blocks.head);
+    builder.createBranch(true, &blocks.head);
 
     // Loop control:
     std::vector<unsigned int> operands;
@@ -4161,7 +4176,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
     builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control, operands);
     if (node->testFirst() && node->getTest()) {
         spv::Block& test = builder.makeNewBlock();
-        builder.createBranch(&test);
+        builder.createBranch(true, &test);
 
         builder.setBuildPoint(&test);
         node->getTest()->traverse(this);
@@ -4172,22 +4187,22 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
         breakForLoop.push(true);
         if (node->getBody())
             node->getBody()->traverse(this);
-        builder.createBranch(&blocks.continue_target);
+        builder.createBranch(true, &blocks.continue_target);
         breakForLoop.pop();
 
         builder.setBuildPoint(&blocks.continue_target);
         if (node->getTerminal())
             node->getTerminal()->traverse(this);
-        builder.createBranch(&blocks.head);
+        builder.createBranch(true, &blocks.head);
     } else {
         builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
-        builder.createBranch(&blocks.body);
+        builder.createBranch(true, &blocks.body);
 
         breakForLoop.push(true);
         builder.setBuildPoint(&blocks.body);
         if (node->getBody())
             node->getBody()->traverse(this);
-        builder.createBranch(&blocks.continue_target);
+        builder.createBranch(true, &blocks.continue_target);
         breakForLoop.pop();
 
         builder.setBuildPoint(&blocks.continue_target);
@@ -4202,7 +4217,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
             // TODO: unless there was a break/return/discard instruction
             // somewhere in the body, this is an infinite loop, so we should
             // issue a warning.
-            builder.createBranch(&blocks.head);
+            builder.createBranch(true, &blocks.head);
         }
     }
     builder.setBuildPoint(&blocks.merge);
@@ -4238,7 +4253,7 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
         if (breakForLoop.top())
             builder.createLoopExit();
         else
-            builder.addSwitchBreak();
+            builder.addSwitchBreak(false);
         break;
     case glslang::EOpContinue:
         builder.createLoopContinue();
@@ -4868,7 +4883,7 @@ bool TGlslangToSpvTraverser::filterMember(const glslang::TType& member)
     }
 
     return false;
-};
+}
 
 // Do full recursive conversion of a glslang structure (or block) type to a SPIR-V Id.
 // explicitLayout can be kept the same throughout the hierarchical recursive walk.
@@ -10296,7 +10311,7 @@ spv::Id TGlslangToSpvTraverser::getExtBuiltins(const char* name)
     }
 }
 
-};  // end anonymous namespace
+} // end anonymous namespace
 
 namespace glslang {
 
@@ -10433,4 +10448,4 @@ void GlslangToSpv(const TIntermediate& intermediate, std::vector<unsigned int>&
     GetThreadPoolAllocator().pop();
 }
 
-}; // end namespace glslang
+} // end namespace glslang

+ 9 - 8
3rdparty/glslang/SPIRV/GlslangToSpv.h

@@ -39,6 +39,7 @@
 #include <vector>
 
 #include "Logger.h"
+#include "glslang/Include/visibility.h"
 
 namespace glslang {
 class TIntermediate;
@@ -56,13 +57,13 @@ struct SpvOptions {
     bool optimizerAllowExpandedIDBound{false};
 };
 
-void GetSpirvVersion(std::string&);
-int GetSpirvGeneratorVersion();
-void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
-                  SpvOptions* options = nullptr);
-void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
-                  spv::SpvBuildLogger* logger, SpvOptions* options = nullptr);
-bool OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
-bool OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
+GLSLANG_EXPORT void GetSpirvVersion(std::string&);
+GLSLANG_EXPORT int GetSpirvGeneratorVersion();
+GLSLANG_EXPORT void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
+                                 SpvOptions* options = nullptr);
+GLSLANG_EXPORT void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
+                                 spv::SpvBuildLogger* logger, SpvOptions* options = nullptr);
+GLSLANG_EXPORT bool OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
+GLSLANG_EXPORT bool OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
 
 }

+ 2 - 1
3rdparty/glslang/SPIRV/Logger.h

@@ -37,12 +37,13 @@
 
 #include <string>
 #include <vector>
+#include "glslang/Include/visibility.h"
 
 namespace spv {
 
 // A class for holding all SPIR-V build status messages, including
 // missing/TBD functionalities, warnings, and errors.
-class SpvBuildLogger {
+class GLSLANG_EXPORT SpvBuildLogger {
 public:
     SpvBuildLogger() {}
 

+ 16 - 1
3rdparty/glslang/SPIRV/SPVRemapper.h

@@ -41,6 +41,21 @@
 #include <cstdlib>
 #include <exception>
 
+#ifdef GLSLANG_IS_SHARED_LIBRARY
+    #ifdef _WIN32
+        #ifdef GLSLANG_EXPORTING
+            #define GLSLANG_EXPORT __declspec(dllexport)
+        #else
+            #define GLSLANG_EXPORT __declspec(dllimport)
+        #endif
+    #elif __GNUC__ >= 4
+        #define GLSLANG_EXPORT __attribute__((visibility("default")))
+    #endif
+#endif // GLSLANG_IS_SHARED_LIBRARY
+#ifndef GLSLANG_EXPORT
+#define GLSLANG_EXPORT
+#endif
+
 namespace spv {
 
 class spirvbin_base_t
@@ -83,7 +98,7 @@ namespace spv {
 static inline constexpr Id NoResult = 0;
 
 // class to hold SPIR-V binary data for remapping, DCE, and debug stripping
-class spirvbin_t : public spirvbin_base_t
+class GLSLANG_EXPORT spirvbin_t : public spirvbin_base_t
 {
 public:
    spirvbin_t(int verbose = 0) : entryPoint(spv::NoResult), largestNewId(0), verbose(verbose), errorLatch(false)

+ 73 - 16
3rdparty/glslang/SPIRV/SpvBuilder.cpp

@@ -439,6 +439,43 @@ Id Builder::makeCooperativeMatrixTypeKHR(Id component, Id scope, Id rows, Id col
     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
     module.mapInstruction(type);
 
+    if (emitNonSemanticShaderDebugInfo)
+    {
+        // Find a name for one of the parameters. It can either come from debuginfo for another
+        // type, or an OpName from a constant.
+        auto const findName = [&](Id id) {
+            Id id2 = debugId[id];
+            for (auto &t : groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic]) {
+                if (t->getResultId() == id2) {
+                    for (auto &s : strings) {
+                        if (s->getResultId() == t->getIdOperand(2)) {
+                            return s->getNameString();
+                        }
+                    }
+                }
+            }
+            for (auto &t : names) {
+                if (t->getIdOperand(0) == id) {
+                    return t->getNameString();
+                }
+            }
+            return "unknown";
+        };
+        std::string debugName = "coopmat<";
+        debugName += std::string(findName(component)) + ", ";
+        if (isConstantScalar(scope)) {
+            debugName += std::string("gl_Scope") + std::string(spv::ScopeToString((spv::Scope)getConstantScalar(scope))) + ", ";
+        } else {
+            debugName += std::string(findName(scope)) + ", ";
+        }
+        debugName += std::string(findName(rows)) + ", ";
+        debugName += std::string(findName(cols)) + ">";
+        // There's no nonsemantic debug info instruction for cooperative matrix types,
+        // use opaque composite instead.
+        auto const debugResultId = makeCompositeDebugType({}, debugName.c_str(), NonSemanticShaderDebugInfo100Structure, true);
+        debugId[type->getResultId()] = debugResultId;
+    }
+
     return type->getResultId();
 }
 
@@ -2182,6 +2219,10 @@ void Builder::addInstruction(std::unique_ptr<Instruction> inst) {
     buildPoint->addInstruction(std::move(inst));
 }
 
+void Builder::addInstructionNoDebugInfo(std::unique_ptr<Instruction> inst) {
+    buildPoint->addInstruction(std::move(inst));
+}
+
 // Comments in header
 Function* Builder::makeEntryPoint(const char* entryPoint)
 {
@@ -2320,7 +2361,7 @@ Id Builder::makeDebugFunction([[maybe_unused]] Function* function, Id nameId, Id
     return funcId;
 }
 
-Id Builder::makeDebugLexicalBlock(uint32_t line) {
+Id Builder::makeDebugLexicalBlock(uint32_t line, uint32_t column) {
     assert(!currentDebugScopeId.empty());
 
     Id lexId = getUniqueId();
@@ -2330,7 +2371,7 @@ Id Builder::makeDebugLexicalBlock(uint32_t line) {
     lex->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLexicalBlock);
     lex->addIdOperand(makeDebugSource(currentFileId));
     lex->addIdOperand(makeUintConstant(line));
-    lex->addIdOperand(makeUintConstant(0)); // column
+    lex->addIdOperand(makeUintConstant(column)); // column
     lex->addIdOperand(currentDebugScopeId.top()); // scope
     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(lex));
     module.mapInstruction(lex);
@@ -2363,10 +2404,14 @@ void Builder::makeReturn(bool implicit, Id retVal)
 }
 
 // Comments in header
-void Builder::enterLexicalBlock(uint32_t line)
+void Builder::enterLexicalBlock(uint32_t line, uint32_t column)
 {
+    if (!emitNonSemanticShaderDebugInfo) {
+        return;
+    }
+
     // Generate new lexical scope debug instruction
-    Id lexId = makeDebugLexicalBlock(line);
+    Id lexId = makeDebugLexicalBlock(line, column);
     currentDebugScopeId.push(lexId);
     dirtyScopeTracker = true;
 }
@@ -2374,6 +2419,10 @@ void Builder::enterLexicalBlock(uint32_t line)
 // Comments in header
 void Builder::leaveLexicalBlock()
 {
+    if (!emitNonSemanticShaderDebugInfo) {
+        return;
+    }
+
     // Pop current scope from stack and clear current scope
     currentDebugScopeId.pop();
     dirtyScopeTracker = true;
@@ -3659,6 +3708,7 @@ Builder::If::If(Id cond, unsigned int ctrl, Builder& gb) :
     // Save the current block, so that we can add in the flow control split when
     // makeEndIf is called.
     headerBlock = builder.getBuildPoint();
+    builder.createSelectionMerge(mergeBlock, control);
 
     function->addBlock(thenBlock);
     builder.setBuildPoint(thenBlock);
@@ -3668,7 +3718,7 @@ Builder::If::If(Id cond, unsigned int ctrl, Builder& gb) :
 void Builder::If::makeBeginElse()
 {
     // Close out the "then" by having it jump to the mergeBlock
-    builder.createBranch(mergeBlock);
+    builder.createBranch(true, mergeBlock);
 
     // Make the first else block and add it to the function
     elseBlock = new Block(builder.getUniqueId(), *function);
@@ -3682,11 +3732,10 @@ void Builder::If::makeBeginElse()
 void Builder::If::makeEndIf()
 {
     // jump to the merge block
-    builder.createBranch(mergeBlock);
+    builder.createBranch(true, mergeBlock);
 
     // Go back to the headerBlock and make the flow control split
     builder.setBuildPoint(headerBlock);
-    builder.createSelectionMerge(mergeBlock, control);
     if (elseBlock)
         builder.createConditionalBranch(condition, thenBlock, elseBlock);
     else
@@ -3732,10 +3781,10 @@ void Builder::makeSwitch(Id selector, unsigned int control, int numSegments, con
 }
 
 // Comments in header
-void Builder::addSwitchBreak()
+void Builder::addSwitchBreak(bool implicit)
 {
     // branch to the top of the merge block stack
-    createBranch(switchMerges.top());
+    createBranch(implicit, switchMerges.top());
     createAndSetNoPredecessorBlock("post-switch-break");
 }
 
@@ -3746,7 +3795,7 @@ void Builder::nextSwitchSegment(std::vector<Block*>& segmentBlock, int nextSegme
     if (lastSegment >= 0) {
         // Close out previous segment by jumping, if necessary, to next segment
         if (! buildPoint->isTerminated())
-            createBranch(segmentBlock[nextSegment]);
+            createBranch(true, segmentBlock[nextSegment]);
     }
     Block* block = segmentBlock[nextSegment];
     block->getParent().addBlock(block);
@@ -3758,7 +3807,7 @@ void Builder::endSwitch(std::vector<Block*>& /*segmentBlock*/)
 {
     // Close out previous segment by jumping, if necessary, to next segment
     if (! buildPoint->isTerminated())
-        addSwitchBreak();
+        addSwitchBreak(true);
 
     switchMerges.top()->getParent().addBlock(switchMerges.top());
     setBuildPoint(switchMerges.top());
@@ -3791,14 +3840,14 @@ Builder::LoopBlocks& Builder::makeNewLoop()
 
 void Builder::createLoopContinue()
 {
-    createBranch(&loops.top().continue_target);
+    createBranch(false, &loops.top().continue_target);
     // Set up a block for dead code.
     createAndSetNoPredecessorBlock("post-loop-continue");
 }
 
 void Builder::createLoopExit()
 {
-    createBranch(&loops.top().merge);
+    createBranch(false, &loops.top().merge);
     // Set up a block for dead code.
     createAndSetNoPredecessorBlock("post-loop-break");
 }
@@ -4240,11 +4289,16 @@ void Builder::createAndSetNoPredecessorBlock(const char* /*name*/)
 }
 
 // Comments in header
-void Builder::createBranch(Block* block)
+void Builder::createBranch(bool implicit, Block* block)
 {
     Instruction* branch = new Instruction(OpBranch);
     branch->addIdOperand(block->getId());
-    addInstruction(std::unique_ptr<Instruction>(branch));
+    if (implicit) {
+        addInstructionNoDebugInfo(std::unique_ptr<Instruction>(branch));
+    }
+    else {
+        addInstruction(std::unique_ptr<Instruction>(branch));
+    }
     block->addPredecessor(buildPoint);
 }
 
@@ -4277,7 +4331,10 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els
     branch->addIdOperand(condition);
     branch->addIdOperand(thenBlock->getId());
     branch->addIdOperand(elseBlock->getId());
-    addInstruction(std::unique_ptr<Instruction>(branch));
+
+    // A conditional branch is always attached to a condition expression
+    addInstructionNoDebugInfo(std::unique_ptr<Instruction>(branch));
+
     thenBlock->addPredecessor(buildPoint);
     elseBlock->addPredecessor(buildPoint);
 }

+ 15 - 8
3rdparty/glslang/SPIRV/SpvBuilder.h

@@ -48,6 +48,7 @@
 #define SpvBuilder_H
 
 #include "Logger.h"
+#define SPV_ENABLE_UTILITY_CODE
 #include "spirv.hpp"
 #include "spvIR.h"
 namespace spv {
@@ -108,7 +109,7 @@ public:
     spv::Id getMainFileId() const { return mainFileId; }
 
     // Initialize the main source file name
-    void setDebugSourceFile(const std::string& file)
+    void setDebugMainSourceFile(const std::string& file)
     {
         if (trackDebugInfo) {
             dirtyLineTracker = true;
@@ -246,7 +247,7 @@ public:
     Id makeDebugValue(Id const debugLocalVariable, Id const value);
     Id makeDebugFunctionType(Id returnType, const std::vector<Id>& paramTypes);
     Id makeDebugFunction(Function* function, Id nameId, Id funcTypeId);
-    Id makeDebugLexicalBlock(uint32_t line);
+    Id makeDebugLexicalBlock(uint32_t line, uint32_t column);
     std::string unmangleFunctionName(std::string const& name) const;
 
     // Initialize non-semantic debug information for a function, including those of:
@@ -420,8 +421,7 @@ public:
     // Also reset current last DebugScope and current source line to unknown
     void setBuildPoint(Block* bp) {
         buildPoint = bp;
-        // TODO: Technically, change of build point should set line tracker dirty. But we'll have bad line info for
-        //       branch instructions. Commenting this for now because at least this matches the old behavior.
+        dirtyLineTracker = true;
         dirtyScopeTracker = true;
     }
     Block* getBuildPoint() const { return buildPoint; }
@@ -430,6 +430,11 @@ public:
     // Optionally, additional debug info instructions may also be prepended.
     void addInstruction(std::unique_ptr<Instruction> inst);
 
+    // Append an instruction to the end of the current build point without prepending any debug instructions.
+    // This is useful for insertion of some debug info instructions themselves or some control flow instructions
+    // that are attached to its predecessor instruction.
+    void addInstructionNoDebugInfo(std::unique_ptr<Instruction> inst);
+
     // Make the entry-point function. The returned pointer is only valid
     // for the lifetime of this builder.
     Function* makeEntryPoint(const char*);
@@ -446,7 +451,7 @@ public:
     void makeReturn(bool implicit, Id retVal = 0);
 
     // Initialize state and generate instructions for new lexical scope
-    void enterLexicalBlock(uint32_t line);
+    void enterLexicalBlock(uint32_t line, uint32_t column);
 
     // Set state and generate instructions to exit current lexical scope
     void leaveLexicalBlock();
@@ -643,7 +648,7 @@ public:
                     const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB);
 
     // Add a branch to the innermost switch's merge block.
-    void addSwitchBreak();
+    void addSwitchBreak(bool implicit);
 
     // Move to the next code segment, passing in the return argument in makeSwitch()
     void nextSwitchSegment(std::vector<Block*>& segmentBB, int segment);
@@ -865,7 +870,9 @@ public:
 
     void dump(std::vector<unsigned int>&) const;
 
-    void createBranch(Block* block);
+    // Add a branch to the target block.
+    // If set implicit, the branch instruction shouldn't have debug source location.
+    void createBranch(bool implicit, Block* block);
     void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
     void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
         const std::vector<unsigned int>& operands);
@@ -997,6 +1004,6 @@ public:
     SpvBuildLogger* logger;
 };  // end Builder class
 
-};  // end spv namespace
+} // end spv namespace
 
 #endif // SpvBuilder_H

+ 1 - 1
3rdparty/glslang/SPIRV/SpvPostProcess.cpp

@@ -548,4 +548,4 @@ void Builder::postProcess(bool compileOnly)
     postProcessSamplers();
 }
 
-}; // end spv namespace
+} // end spv namespace

+ 6 - 1
3rdparty/glslang/SPIRV/SpvTools.cpp

@@ -82,6 +82,11 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog
     return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
 }
 
+spv_target_env MapToSpirvToolsEnv(const glslang::TIntermediate& intermediate, spv::SpvBuildLogger* logger)
+{
+    return MapToSpirvToolsEnv(intermediate.getSpv(), logger);
+}
+
 // Callback passed to spvtools::Optimizer::SetMessageConsumer
 void OptimizerMesssageConsumer(spv_message_level_t level, const char *source,
         const spv_position_t &position, const char *message)
@@ -304,6 +309,6 @@ void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate,
     optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
 }
 
-}; // end namespace glslang
+} // end namespace glslang
 
 #endif

+ 22 - 18
3rdparty/glslang/SPIRV/SpvTools.h

@@ -49,6 +49,7 @@
 #endif
 
 #include "glslang/MachineIndependent/Versions.h"
+#include "glslang/Include/visibility.h"
 #include "GlslangToSpv.h"
 #include "Logger.h"
 
@@ -59,44 +60,47 @@ namespace glslang {
 class TIntermediate;
 
 // Translate glslang's view of target versioning to what SPIRV-Tools uses.
-spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger);
+GLSLANG_EXPORT spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger);
+GLSLANG_EXPORT spv_target_env MapToSpirvToolsEnv(const glslang::TIntermediate& intermediate, spv::SpvBuildLogger* logger);
 
 // Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment.
-void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
+GLSLANG_EXPORT void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
 
 // Use the SPIRV-Tools disassembler to print SPIR-V with a provided SPIR-V environment.
-void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv,
-                           spv_target_env requested_context);
+GLSLANG_EXPORT void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv,
+                                          spv_target_env requested_context);
 
 // Apply the SPIRV-Tools validator to generated SPIR-V.
-void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
-                        spv::SpvBuildLogger*, bool prelegalization);
+GLSLANG_EXPORT void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
+                                       spv::SpvBuildLogger*, bool prelegalization);
 
 // Apply the SPIRV-Tools optimizer to generated SPIR-V.  HLSL SPIR-V is legalized in the process.
-void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
-                         spv::SpvBuildLogger*, const SpvOptions*);
+GLSLANG_EXPORT void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
+                                        spv::SpvBuildLogger*, const SpvOptions*);
 
 // Apply the SPIRV-Tools EliminateDeadInputComponents pass to generated SPIR-V. Put result in |spirv|.
-void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector<unsigned int>& spirv,
-                                            spv::SpvBuildLogger*);
+GLSLANG_EXPORT void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector<unsigned int>& spirv,
+                                                           spv::SpvBuildLogger*);
 
 // Apply the SPIRV-Tools AnalyzeDeadOutputStores pass to generated SPIR-V. Put result in |live_locs|.
 // Return true if the result is valid.
-bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
-                                       std::unordered_set<uint32_t>* live_locs,
-                                       std::unordered_set<uint32_t>* live_builtins, spv::SpvBuildLogger*);
+GLSLANG_EXPORT bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
+                                                      std::unordered_set<uint32_t>* live_locs,
+                                                      std::unordered_set<uint32_t>* live_builtins,
+                                                      spv::SpvBuildLogger*);
 
 // Apply the SPIRV-Tools EliminateDeadOutputStores and AggressiveDeadCodeElimination passes to generated SPIR-V using
 // |live_locs|. Put result in |spirv|.
-void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
-                                         std::unordered_set<uint32_t>* live_locs,
-                                         std::unordered_set<uint32_t>* live_builtins, spv::SpvBuildLogger*);
+GLSLANG_EXPORT void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector<unsigned int>& spirv,
+                                                        std::unordered_set<uint32_t>* live_locs,
+                                                        std::unordered_set<uint32_t>* live_builtins,
+                                                        spv::SpvBuildLogger*);
 
 // Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V.  This is implicitly done by
 // SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if
 // optimization is disabled.
-void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate,
-        std::vector<unsigned int>& spirv, spv::SpvBuildLogger*);
+GLSLANG_EXPORT void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate,
+                                             std::vector<unsigned int>& spirv, spv::SpvBuildLogger*);
 
 #endif
 

+ 1 - 1
3rdparty/glslang/SPIRV/disassemble.cpp

@@ -825,4 +825,4 @@ void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
     SpirvStream.processInstructions();
 }
 
-}; // end namespace spv
+} // end namespace spv

+ 3 - 1
3rdparty/glslang/SPIRV/disassemble.h

@@ -43,10 +43,12 @@
 #include <iostream>
 #include <vector>
 
+#include "glslang/Include/visibility.h"
+
 namespace spv {
 
     // disassemble with glslang custom disassembler
-    void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
+    GLSLANG_EXPORT void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
 
 }  // end namespace spv
 

+ 1 - 1
3rdparty/glslang/SPIRV/doc.cpp

@@ -3491,4 +3491,4 @@ void Parameterize()
     });
 }
 
-}; // end spv namespace
+} // end spv namespace

+ 14 - 0
3rdparty/glslang/SPIRV/spirv.hpp

@@ -2772,6 +2772,20 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
     case OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break;
     }
 }
+
+inline const char* ScopeToString(Scope value) {
+    switch (value) {
+    case ScopeCrossDevice: return "CrossDevice";
+    case ScopeDevice: return "Device";
+    case ScopeWorkgroup: return "Workgroup";
+    case ScopeSubgroup: return "Subgroup";
+    case ScopeInvocation: return "Invocation";
+    case ScopeQueueFamily: return "QueueFamily";
+    case ScopeShaderCallKHR: return "ShaderCallKHR";
+    default: return "Unknown";
+    }
+}
+
 #endif /* SPV_ENABLE_UTILITY_CODE */
 
 // Overload bitwise operators for mask bit combining

+ 9 - 0
3rdparty/glslang/SPIRV/spvIR.h

@@ -189,6 +189,15 @@ public:
             out.push_back(operands[op]);
     }
 
+    const char *getNameString() const {
+        if (opCode == OpString) {
+            return (const char *)&operands[0];
+        } else {
+            assert(opCode == OpName);
+            return (const char *)&operands[1];
+        }
+    }
+
 protected:
     Instruction(const Instruction&);
     Id resultId;

+ 15 - 3
3rdparty/glslang/StandAlone/StandAlone.cpp

@@ -109,6 +109,7 @@ enum TOptions : uint64_t {
     EOptionDumpBareVersion = (1ull << 31),
     EOptionCompileOnly = (1ull << 32),
     EOptionDisplayErrorColumn = (1ull << 33),
+    EOptionLinkTimeOptimization = (1ull << 34),
 };
 bool targetHlslFunctionality1 = false;
 bool SpvToolsDisassembler = false;
@@ -899,6 +900,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                         Options |= EOptionCompileOnly;
                     } else if (lowerword == "error-column") {
                         Options |= EOptionDisplayErrorColumn;
+                    } else if (lowerword == "lto") {
+                        Options |= EOptionLinkTimeOptimization;
                     } else if (lowerword == "help") {
                         usage();
                         break;
@@ -1083,6 +1086,10 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
     if ((Options & EOptionDumpReflection) && !(Options & EOptionLinkProgram))
         Error("reflection requires -l for linking");
 
+    // link time optimization makes no sense unless linking
+    if ((Options & EOptionLinkTimeOptimization) && !(Options & EOptionLinkProgram))
+        Error("link time optimization requires -l for linking");
+
     // -o or -x makes no sense if there is no target binary
     if (binaryFileName && (Options & EOptionSpv) == 0)
         Error("no binary generation requested (e.g., -V)");
@@ -1167,6 +1174,8 @@ void SetMessageOptions(EShMessages& messages)
         messages = (EShMessages)(messages | EShMsgAbsolutePath);
     if (Options & EOptionDisplayErrorColumn)
         messages = (EShMessages)(messages | EShMsgDisplayErrorColumn);
+    if (Options & EOptionLinkTimeOptimization)
+        messages = (EShMessages)(messages | EShMsgLinkTimeOptimization);
 }
 
 //
@@ -1507,9 +1516,9 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
 
     std::vector<std::string> outputFiles;
 
-#ifdef ENABLE_SPIRV
     // Dump SPIR-V
     if (Options & EOptionSpv) {
+#ifdef ENABLE_SPIRV
         CompileOrLinkFailed.fetch_or(CompileFailed);
         CompileOrLinkFailed.fetch_or(LinkFailed);
         if (static_cast<bool>(CompileOrLinkFailed.load()))
@@ -1569,8 +1578,10 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
                 }
             }
         }
-    }
+#else
+        Error("This configuration of glslang does not have SPIR-V support");
 #endif
+    }
 
     CompileOrLinkFailed.fetch_or(CompileFailed);
     CompileOrLinkFailed.fetch_or(LinkFailed);
@@ -2133,7 +2144,8 @@ void usage()
            "                                    initialized with the shader binary code\n"
            "  --no-link                         Only compile shader; do not link (GLSL-only)\n"
            "                                    NOTE: this option will set the export linkage\n"
-           "                                          attribute on all functions\n");
+           "                                          attribute on all functions\n"
+           "  --lto                             perform link time optimization\n");
 
     exit(EFailUsage);
 }

+ 2 - 2
3rdparty/glslang/build_info.h

@@ -34,8 +34,8 @@
 #ifndef GLSLANG_BUILD_INFO
 #define GLSLANG_BUILD_INFO
 
-#define GLSLANG_VERSION_MAJOR 14
-#define GLSLANG_VERSION_MINOR 3
+#define GLSLANG_VERSION_MAJOR 15
+#define GLSLANG_VERSION_MINOR 0
 #define GLSLANG_VERSION_PATCH 0
 #define GLSLANG_VERSION_FLAVOR ""
 

+ 12 - 1
3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp

@@ -63,6 +63,7 @@ static_assert(sizeof(glslang_version_t) == sizeof(glslang::Version), "");
 typedef struct glslang_shader_s {
     glslang::TShader* shader;
     std::string preprocessedGLSL;
+    std::vector<std::string> baseResourceSetBinding;
 } glslang_shader_t;
 
 typedef struct glslang_program_s {
@@ -323,7 +324,7 @@ static EProfile c_shader_profile(glslang_profile_t profile)
 GLSLANG_EXPORT glslang_shader_t* glslang_shader_create(const glslang_input_t* input)
 {
     if (!input || !input->code) {
-        printf("Error creating shader: null input(%p)/input->code\n", input);
+        printf("Error creating shader: null input(%p)/input->code\n", (void*)input);
 
         if (input)
             printf("input->code = %p\n", input->code);
@@ -389,6 +390,16 @@ GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_name(glslang_shader
     shader->shader->setGlobalUniformBlockName(name);
 }
 
+GLSLANG_EXPORT void glslang_shader_set_resource_set_binding(glslang_shader_t* shader, const char *const *bindings, unsigned int num_bindings) {
+    shader->baseResourceSetBinding.clear();
+
+    for (unsigned int i = 0; i < num_bindings; ++i) {
+        shader->baseResourceSetBinding.push_back(std::string(bindings[i]));
+    }
+
+    shader->shader->setResourceSetBinding(shader->baseResourceSetBinding);
+}
+
 GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader)
 {
     return shader->preprocessedGLSL.c_str();

+ 1 - 1
3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp

@@ -1439,7 +1439,7 @@ int HlslParseContext::findSubtreeOffset(const TType& type, int subset, const TVe
         return offsets[subset];
     TType derefType(type, 0);
     return findSubtreeOffset(derefType, offsets[subset], offsets);
-};
+}
 
 // Find and return the split IO TVariable for id, or nullptr if none.
 TVariable* HlslParseContext::getSplitNonIoVar(long long id) const

+ 426 - 452
3rdparty/glslang/glslang/HLSL/hlslScanContext.cpp

@@ -78,414 +78,396 @@ struct str_hash
 };
 
 // A single global usable by all threads, by all versions, by all languages.
-// After a single process-level initialization, this is read only and thread safe
-std::unordered_map<const char*, glslang::EHlslTokenClass, str_hash, str_eq>* KeywordMap = nullptr;
-std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
-std::unordered_map<const char*, glslang::TBuiltInVariable, str_hash, str_eq>* SemanticMap = nullptr;
-
+const std::unordered_map<const char*, glslang::EHlslTokenClass, str_hash, str_eq> KeywordMap {
+    {"static",glslang::EHTokStatic},
+    {"const",glslang::EHTokConst},
+    {"unorm",glslang::EHTokUnorm},
+    {"snorm",glslang::EHTokSNorm},
+    {"extern",glslang::EHTokExtern},
+    {"uniform",glslang::EHTokUniform},
+    {"volatile",glslang::EHTokVolatile},
+    {"precise",glslang::EHTokPrecise},
+    {"shared",glslang::EHTokShared},
+    {"groupshared",glslang::EHTokGroupShared},
+    {"linear",glslang::EHTokLinear},
+    {"centroid",glslang::EHTokCentroid},
+    {"nointerpolation",glslang::EHTokNointerpolation},
+    {"noperspective",glslang::EHTokNoperspective},
+    {"sample",glslang::EHTokSample},
+    {"row_major",glslang::EHTokRowMajor},
+    {"column_major",glslang::EHTokColumnMajor},
+    {"packoffset",glslang::EHTokPackOffset},
+    {"in",glslang::EHTokIn},
+    {"out",glslang::EHTokOut},
+    {"inout",glslang::EHTokInOut},
+    {"layout",glslang::EHTokLayout},
+    {"globallycoherent",glslang::EHTokGloballyCoherent},
+    {"inline",glslang::EHTokInline},
+
+    {"point",glslang::EHTokPoint},
+    {"line",glslang::EHTokLine},
+    {"triangle",glslang::EHTokTriangle},
+    {"lineadj",glslang::EHTokLineAdj},
+    {"triangleadj",glslang::EHTokTriangleAdj},
+
+    {"PointStream",glslang::EHTokPointStream},
+    {"LineStream",glslang::EHTokLineStream},
+    {"TriangleStream",glslang::EHTokTriangleStream},
+
+    {"InputPatch",glslang::EHTokInputPatch},
+    {"OutputPatch",glslang::EHTokOutputPatch},
+
+    {"Buffer",glslang::EHTokBuffer},
+    {"vector",glslang::EHTokVector},
+    {"matrix",glslang::EHTokMatrix},
+
+    {"void",glslang::EHTokVoid},
+    {"string",glslang::EHTokString},
+    {"bool",glslang::EHTokBool},
+    {"int",glslang::EHTokInt},
+    {"uint",glslang::EHTokUint},
+    {"uint64_t",glslang::EHTokUint64},
+    {"dword",glslang::EHTokDword},
+    {"half",glslang::EHTokHalf},
+    {"float",glslang::EHTokFloat},
+    {"double",glslang::EHTokDouble},
+    {"min16float",glslang::EHTokMin16float},
+    {"min10float",glslang::EHTokMin10float},
+    {"min16int",glslang::EHTokMin16int},
+    {"min12int",glslang::EHTokMin12int},
+    {"min16uint",glslang::EHTokMin16uint},
+
+    {"bool1",glslang::EHTokBool1},
+    {"bool2",glslang::EHTokBool2},
+    {"bool3",glslang::EHTokBool3},
+    {"bool4",glslang::EHTokBool4},
+    {"float1",glslang::EHTokFloat1},
+    {"float2",glslang::EHTokFloat2},
+    {"float3",glslang::EHTokFloat3},
+    {"float4",glslang::EHTokFloat4},
+    {"int1",glslang::EHTokInt1},
+    {"int2",glslang::EHTokInt2},
+    {"int3",glslang::EHTokInt3},
+    {"int4",glslang::EHTokInt4},
+    {"double1",glslang::EHTokDouble1},
+    {"double2",glslang::EHTokDouble2},
+    {"double3",glslang::EHTokDouble3},
+    {"double4",glslang::EHTokDouble4},
+    {"uint1",glslang::EHTokUint1},
+    {"uint2",glslang::EHTokUint2},
+    {"uint3",glslang::EHTokUint3},
+    {"uint4",glslang::EHTokUint4},
+
+    {"half1",glslang::EHTokHalf1},
+    {"half2",glslang::EHTokHalf2},
+    {"half3",glslang::EHTokHalf3},
+    {"half4",glslang::EHTokHalf4},
+    {"min16float1",glslang::EHTokMin16float1},
+    {"min16float2",glslang::EHTokMin16float2},
+    {"min16float3",glslang::EHTokMin16float3},
+    {"min16float4",glslang::EHTokMin16float4},
+    {"min10float1",glslang::EHTokMin10float1},
+    {"min10float2",glslang::EHTokMin10float2},
+    {"min10float3",glslang::EHTokMin10float3},
+    {"min10float4",glslang::EHTokMin10float4},
+    {"min16int1",glslang::EHTokMin16int1},
+    {"min16int2",glslang::EHTokMin16int2},
+    {"min16int3",glslang::EHTokMin16int3},
+    {"min16int4",glslang::EHTokMin16int4},
+    {"min12int1",glslang::EHTokMin12int1},
+    {"min12int2",glslang::EHTokMin12int2},
+    {"min12int3",glslang::EHTokMin12int3},
+    {"min12int4",glslang::EHTokMin12int4},
+    {"min16uint1",glslang::EHTokMin16uint1},
+    {"min16uint2",glslang::EHTokMin16uint2},
+    {"min16uint3",glslang::EHTokMin16uint3},
+    {"min16uint4",glslang::EHTokMin16uint4},
+
+    {"bool1x1",glslang::EHTokBool1x1},
+    {"bool1x2",glslang::EHTokBool1x2},
+    {"bool1x3",glslang::EHTokBool1x3},
+    {"bool1x4",glslang::EHTokBool1x4},
+    {"bool2x1",glslang::EHTokBool2x1},
+    {"bool2x2",glslang::EHTokBool2x2},
+    {"bool2x3",glslang::EHTokBool2x3},
+    {"bool2x4",glslang::EHTokBool2x4},
+    {"bool3x1",glslang::EHTokBool3x1},
+    {"bool3x2",glslang::EHTokBool3x2},
+    {"bool3x3",glslang::EHTokBool3x3},
+    {"bool3x4",glslang::EHTokBool3x4},
+    {"bool4x1",glslang::EHTokBool4x1},
+    {"bool4x2",glslang::EHTokBool4x2},
+    {"bool4x3",glslang::EHTokBool4x3},
+    {"bool4x4",glslang::EHTokBool4x4},
+    {"int1x1",glslang::EHTokInt1x1},
+    {"int1x2",glslang::EHTokInt1x2},
+    {"int1x3",glslang::EHTokInt1x3},
+    {"int1x4",glslang::EHTokInt1x4},
+    {"int2x1",glslang::EHTokInt2x1},
+    {"int2x2",glslang::EHTokInt2x2},
+    {"int2x3",glslang::EHTokInt2x3},
+    {"int2x4",glslang::EHTokInt2x4},
+    {"int3x1",glslang::EHTokInt3x1},
+    {"int3x2",glslang::EHTokInt3x2},
+    {"int3x3",glslang::EHTokInt3x3},
+    {"int3x4",glslang::EHTokInt3x4},
+    {"int4x1",glslang::EHTokInt4x1},
+    {"int4x2",glslang::EHTokInt4x2},
+    {"int4x3",glslang::EHTokInt4x3},
+    {"int4x4",glslang::EHTokInt4x4},
+    {"uint1x1",glslang::EHTokUint1x1},
+    {"uint1x2",glslang::EHTokUint1x2},
+    {"uint1x3",glslang::EHTokUint1x3},
+    {"uint1x4",glslang::EHTokUint1x4},
+    {"uint2x1",glslang::EHTokUint2x1},
+    {"uint2x2",glslang::EHTokUint2x2},
+    {"uint2x3",glslang::EHTokUint2x3},
+    {"uint2x4",glslang::EHTokUint2x4},
+    {"uint3x1",glslang::EHTokUint3x1},
+    {"uint3x2",glslang::EHTokUint3x2},
+    {"uint3x3",glslang::EHTokUint3x3},
+    {"uint3x4",glslang::EHTokUint3x4},
+    {"uint4x1",glslang::EHTokUint4x1},
+    {"uint4x2",glslang::EHTokUint4x2},
+    {"uint4x3",glslang::EHTokUint4x3},
+    {"uint4x4",glslang::EHTokUint4x4},
+    {"bool1x1",glslang::EHTokBool1x1},
+    {"bool1x2",glslang::EHTokBool1x2},
+    {"bool1x3",glslang::EHTokBool1x3},
+    {"bool1x4",glslang::EHTokBool1x4},
+    {"bool2x1",glslang::EHTokBool2x1},
+    {"bool2x2",glslang::EHTokBool2x2},
+    {"bool2x3",glslang::EHTokBool2x3},
+    {"bool2x4",glslang::EHTokBool2x4},
+    {"bool3x1",glslang::EHTokBool3x1},
+    {"bool3x2",glslang::EHTokBool3x2},
+    {"bool3x3",glslang::EHTokBool3x3},
+    {"bool3x4",glslang::EHTokBool3x4},
+    {"bool4x1",glslang::EHTokBool4x1},
+    {"bool4x2",glslang::EHTokBool4x2},
+    {"bool4x3",glslang::EHTokBool4x3},
+    {"bool4x4",glslang::EHTokBool4x4},
+    {"float1x1",glslang::EHTokFloat1x1},
+    {"float1x2",glslang::EHTokFloat1x2},
+    {"float1x3",glslang::EHTokFloat1x3},
+    {"float1x4",glslang::EHTokFloat1x4},
+    {"float2x1",glslang::EHTokFloat2x1},
+    {"float2x2",glslang::EHTokFloat2x2},
+    {"float2x3",glslang::EHTokFloat2x3},
+    {"float2x4",glslang::EHTokFloat2x4},
+    {"float3x1",glslang::EHTokFloat3x1},
+    {"float3x2",glslang::EHTokFloat3x2},
+    {"float3x3",glslang::EHTokFloat3x3},
+    {"float3x4",glslang::EHTokFloat3x4},
+    {"float4x1",glslang::EHTokFloat4x1},
+    {"float4x2",glslang::EHTokFloat4x2},
+    {"float4x3",glslang::EHTokFloat4x3},
+    {"float4x4",glslang::EHTokFloat4x4},
+    {"half1x1",glslang::EHTokHalf1x1},
+    {"half1x2",glslang::EHTokHalf1x2},
+    {"half1x3",glslang::EHTokHalf1x3},
+    {"half1x4",glslang::EHTokHalf1x4},
+    {"half2x1",glslang::EHTokHalf2x1},
+    {"half2x2",glslang::EHTokHalf2x2},
+    {"half2x3",glslang::EHTokHalf2x3},
+    {"half2x4",glslang::EHTokHalf2x4},
+    {"half3x1",glslang::EHTokHalf3x1},
+    {"half3x2",glslang::EHTokHalf3x2},
+    {"half3x3",glslang::EHTokHalf3x3},
+    {"half3x4",glslang::EHTokHalf3x4},
+    {"half4x1",glslang::EHTokHalf4x1},
+    {"half4x2",glslang::EHTokHalf4x2},
+    {"half4x3",glslang::EHTokHalf4x3},
+    {"half4x4",glslang::EHTokHalf4x4},
+    {"double1x1",glslang::EHTokDouble1x1},
+    {"double1x2",glslang::EHTokDouble1x2},
+    {"double1x3",glslang::EHTokDouble1x3},
+    {"double1x4",glslang::EHTokDouble1x4},
+    {"double2x1",glslang::EHTokDouble2x1},
+    {"double2x2",glslang::EHTokDouble2x2},
+    {"double2x3",glslang::EHTokDouble2x3},
+    {"double2x4",glslang::EHTokDouble2x4},
+    {"double3x1",glslang::EHTokDouble3x1},
+    {"double3x2",glslang::EHTokDouble3x2},
+    {"double3x3",glslang::EHTokDouble3x3},
+    {"double3x4",glslang::EHTokDouble3x4},
+    {"double4x1",glslang::EHTokDouble4x1},
+    {"double4x2",glslang::EHTokDouble4x2},
+    {"double4x3",glslang::EHTokDouble4x3},
+    {"double4x4",glslang::EHTokDouble4x4},
+    {"min16float1x1",glslang::EHTokMin16float1x1},
+    {"min16float1x2",glslang::EHTokMin16float1x2},
+    {"min16float1x3",glslang::EHTokMin16float1x3},
+    {"min16float1x4",glslang::EHTokMin16float1x4},
+    {"min16float2x1",glslang::EHTokMin16float2x1},
+    {"min16float2x2",glslang::EHTokMin16float2x2},
+    {"min16float2x3",glslang::EHTokMin16float2x3},
+    {"min16float2x4",glslang::EHTokMin16float2x4},
+    {"min16float3x1",glslang::EHTokMin16float3x1},
+    {"min16float3x2",glslang::EHTokMin16float3x2},
+    {"min16float3x3",glslang::EHTokMin16float3x3},
+    {"min16float3x4",glslang::EHTokMin16float3x4},
+    {"min16float4x1",glslang::EHTokMin16float4x1},
+    {"min16float4x2",glslang::EHTokMin16float4x2},
+    {"min16float4x3",glslang::EHTokMin16float4x3},
+    {"min16float4x4",glslang::EHTokMin16float4x4},
+    {"min10float1x1",glslang::EHTokMin10float1x1},
+    {"min10float1x2",glslang::EHTokMin10float1x2},
+    {"min10float1x3",glslang::EHTokMin10float1x3},
+    {"min10float1x4",glslang::EHTokMin10float1x4},
+    {"min10float2x1",glslang::EHTokMin10float2x1},
+    {"min10float2x2",glslang::EHTokMin10float2x2},
+    {"min10float2x3",glslang::EHTokMin10float2x3},
+    {"min10float2x4",glslang::EHTokMin10float2x4},
+    {"min10float3x1",glslang::EHTokMin10float3x1},
+    {"min10float3x2",glslang::EHTokMin10float3x2},
+    {"min10float3x3",glslang::EHTokMin10float3x3},
+    {"min10float3x4",glslang::EHTokMin10float3x4},
+    {"min10float4x1",glslang::EHTokMin10float4x1},
+    {"min10float4x2",glslang::EHTokMin10float4x2},
+    {"min10float4x3",glslang::EHTokMin10float4x3},
+    {"min10float4x4",glslang::EHTokMin10float4x4},
+    {"min16int1x1",glslang::EHTokMin16int1x1},
+    {"min16int1x2",glslang::EHTokMin16int1x2},
+    {"min16int1x3",glslang::EHTokMin16int1x3},
+    {"min16int1x4",glslang::EHTokMin16int1x4},
+    {"min16int2x1",glslang::EHTokMin16int2x1},
+    {"min16int2x2",glslang::EHTokMin16int2x2},
+    {"min16int2x3",glslang::EHTokMin16int2x3},
+    {"min16int2x4",glslang::EHTokMin16int2x4},
+    {"min16int3x1",glslang::EHTokMin16int3x1},
+    {"min16int3x2",glslang::EHTokMin16int3x2},
+    {"min16int3x3",glslang::EHTokMin16int3x3},
+    {"min16int3x4",glslang::EHTokMin16int3x4},
+    {"min16int4x1",glslang::EHTokMin16int4x1},
+    {"min16int4x2",glslang::EHTokMin16int4x2},
+    {"min16int4x3",glslang::EHTokMin16int4x3},
+    {"min16int4x4",glslang::EHTokMin16int4x4},
+    {"min12int1x1",glslang::EHTokMin12int1x1},
+    {"min12int1x2",glslang::EHTokMin12int1x2},
+    {"min12int1x3",glslang::EHTokMin12int1x3},
+    {"min12int1x4",glslang::EHTokMin12int1x4},
+    {"min12int2x1",glslang::EHTokMin12int2x1},
+    {"min12int2x2",glslang::EHTokMin12int2x2},
+    {"min12int2x3",glslang::EHTokMin12int2x3},
+    {"min12int2x4",glslang::EHTokMin12int2x4},
+    {"min12int3x1",glslang::EHTokMin12int3x1},
+    {"min12int3x2",glslang::EHTokMin12int3x2},
+    {"min12int3x3",glslang::EHTokMin12int3x3},
+    {"min12int3x4",glslang::EHTokMin12int3x4},
+    {"min12int4x1",glslang::EHTokMin12int4x1},
+    {"min12int4x2",glslang::EHTokMin12int4x2},
+    {"min12int4x3",glslang::EHTokMin12int4x3},
+    {"min12int4x4",glslang::EHTokMin12int4x4},
+    {"min16uint1x1",glslang::EHTokMin16uint1x1},
+    {"min16uint1x2",glslang::EHTokMin16uint1x2},
+    {"min16uint1x3",glslang::EHTokMin16uint1x3},
+    {"min16uint1x4",glslang::EHTokMin16uint1x4},
+    {"min16uint2x1",glslang::EHTokMin16uint2x1},
+    {"min16uint2x2",glslang::EHTokMin16uint2x2},
+    {"min16uint2x3",glslang::EHTokMin16uint2x3},
+    {"min16uint2x4",glslang::EHTokMin16uint2x4},
+    {"min16uint3x1",glslang::EHTokMin16uint3x1},
+    {"min16uint3x2",glslang::EHTokMin16uint3x2},
+    {"min16uint3x3",glslang::EHTokMin16uint3x3},
+    {"min16uint3x4",glslang::EHTokMin16uint3x4},
+    {"min16uint4x1",glslang::EHTokMin16uint4x1},
+    {"min16uint4x2",glslang::EHTokMin16uint4x2},
+    {"min16uint4x3",glslang::EHTokMin16uint4x3},
+    {"min16uint4x4",glslang::EHTokMin16uint4x4},
+
+    {"sampler",glslang::EHTokSampler},
+    {"sampler1D",glslang::EHTokSampler1d},
+    {"sampler2D",glslang::EHTokSampler2d},
+    {"sampler3D",glslang::EHTokSampler3d},
+    {"samplerCUBE",glslang::EHTokSamplerCube},
+    {"sampler_state",glslang::EHTokSamplerState},
+    {"SamplerState",glslang::EHTokSamplerState},
+    {"SamplerComparisonState",glslang::EHTokSamplerComparisonState},
+    {"texture",glslang::EHTokTexture},
+    {"Texture1D",glslang::EHTokTexture1d},
+    {"Texture1DArray",glslang::EHTokTexture1darray},
+    {"Texture2D",glslang::EHTokTexture2d},
+    {"Texture2DArray",glslang::EHTokTexture2darray},
+    {"Texture3D",glslang::EHTokTexture3d},
+    {"TextureCube",glslang::EHTokTextureCube},
+    {"TextureCubeArray",glslang::EHTokTextureCubearray},
+    {"Texture2DMS",glslang::EHTokTexture2DMS},
+    {"Texture2DMSArray",glslang::EHTokTexture2DMSarray},
+    {"RWTexture1D",glslang::EHTokRWTexture1d},
+    {"RWTexture1DArray",glslang::EHTokRWTexture1darray},
+    {"RWTexture2D",glslang::EHTokRWTexture2d},
+    {"RWTexture2DArray",glslang::EHTokRWTexture2darray},
+    {"RWTexture3D",glslang::EHTokRWTexture3d},
+    {"RWBuffer",glslang::EHTokRWBuffer},
+    {"SubpassInput",glslang::EHTokSubpassInput},
+    {"SubpassInputMS",glslang::EHTokSubpassInputMS},
+
+    {"AppendStructuredBuffer",glslang::EHTokAppendStructuredBuffer},
+    {"ByteAddressBuffer",glslang::EHTokByteAddressBuffer},
+    {"ConsumeStructuredBuffer",glslang::EHTokConsumeStructuredBuffer},
+    {"RWByteAddressBuffer",glslang::EHTokRWByteAddressBuffer},
+    {"RWStructuredBuffer",glslang::EHTokRWStructuredBuffer},
+    {"StructuredBuffer",glslang::EHTokStructuredBuffer},
+    {"TextureBuffer",glslang::EHTokTextureBuffer},
+
+    {"class",glslang::EHTokClass},
+    {"struct",glslang::EHTokStruct},
+    {"cbuffer",glslang::EHTokCBuffer},
+    {"ConstantBuffer",glslang::EHTokConstantBuffer},
+    {"tbuffer",glslang::EHTokTBuffer},
+    {"typedef",glslang::EHTokTypedef},
+    {"this",glslang::EHTokThis},
+    {"namespace",glslang::EHTokNamespace},
+
+    {"true",glslang::EHTokBoolConstant},
+    {"false",glslang::EHTokBoolConstant},
+
+    {"for",glslang::EHTokFor},
+    {"do",glslang::EHTokDo},
+    {"while",glslang::EHTokWhile},
+    {"break",glslang::EHTokBreak},
+    {"continue",glslang::EHTokContinue},
+    {"if",glslang::EHTokIf},
+    {"else",glslang::EHTokElse},
+    {"discard",glslang::EHTokDiscard},
+    {"return",glslang::EHTokReturn},
+    {"switch",glslang::EHTokSwitch},
+    {"case",glslang::EHTokCase},
+    {"default",glslang::EHTokDefault},
 };
 
-namespace glslang {
-
-void HlslScanContext::fillInKeywordMap()
-{
-    if (KeywordMap != nullptr) {
-        // this is really an error, as this should called only once per process
-        // but, the only risk is if two threads called simultaneously
-        return;
-    }
-    KeywordMap = new std::unordered_map<const char*, EHlslTokenClass, str_hash, str_eq>;
-
-    (*KeywordMap)["static"] =                  EHTokStatic;
-    (*KeywordMap)["const"] =                   EHTokConst;
-    (*KeywordMap)["unorm"] =                   EHTokUnorm;
-    (*KeywordMap)["snorm"] =                   EHTokSNorm;
-    (*KeywordMap)["extern"] =                  EHTokExtern;
-    (*KeywordMap)["uniform"] =                 EHTokUniform;
-    (*KeywordMap)["volatile"] =                EHTokVolatile;
-    (*KeywordMap)["precise"] =                 EHTokPrecise;
-    (*KeywordMap)["shared"] =                  EHTokShared;
-    (*KeywordMap)["groupshared"] =             EHTokGroupShared;
-    (*KeywordMap)["linear"] =                  EHTokLinear;
-    (*KeywordMap)["centroid"] =                EHTokCentroid;
-    (*KeywordMap)["nointerpolation"] =         EHTokNointerpolation;
-    (*KeywordMap)["noperspective"] =           EHTokNoperspective;
-    (*KeywordMap)["sample"] =                  EHTokSample;
-    (*KeywordMap)["row_major"] =               EHTokRowMajor;
-    (*KeywordMap)["column_major"] =            EHTokColumnMajor;
-    (*KeywordMap)["packoffset"] =              EHTokPackOffset;
-    (*KeywordMap)["in"] =                      EHTokIn;
-    (*KeywordMap)["out"] =                     EHTokOut;
-    (*KeywordMap)["inout"] =                   EHTokInOut;
-    (*KeywordMap)["layout"] =                  EHTokLayout;
-    (*KeywordMap)["globallycoherent"] =        EHTokGloballyCoherent;
-    (*KeywordMap)["inline"] =                  EHTokInline;
-
-    (*KeywordMap)["point"] =                   EHTokPoint;
-    (*KeywordMap)["line"] =                    EHTokLine;
-    (*KeywordMap)["triangle"] =                EHTokTriangle;
-    (*KeywordMap)["lineadj"] =                 EHTokLineAdj;
-    (*KeywordMap)["triangleadj"] =             EHTokTriangleAdj;
-
-    (*KeywordMap)["PointStream"] =             EHTokPointStream;
-    (*KeywordMap)["LineStream"] =              EHTokLineStream;
-    (*KeywordMap)["TriangleStream"] =          EHTokTriangleStream;
-
-    (*KeywordMap)["InputPatch"] =              EHTokInputPatch;
-    (*KeywordMap)["OutputPatch"] =             EHTokOutputPatch;
-
-    (*KeywordMap)["Buffer"] =                  EHTokBuffer;
-    (*KeywordMap)["vector"] =                  EHTokVector;
-    (*KeywordMap)["matrix"] =                  EHTokMatrix;
-
-    (*KeywordMap)["void"] =                    EHTokVoid;
-    (*KeywordMap)["string"] =                  EHTokString;
-    (*KeywordMap)["bool"] =                    EHTokBool;
-    (*KeywordMap)["int"] =                     EHTokInt;
-    (*KeywordMap)["uint"] =                    EHTokUint;
-    (*KeywordMap)["uint64_t"] =                EHTokUint64;
-    (*KeywordMap)["dword"] =                   EHTokDword;
-    (*KeywordMap)["half"] =                    EHTokHalf;
-    (*KeywordMap)["float"] =                   EHTokFloat;
-    (*KeywordMap)["double"] =                  EHTokDouble;
-    (*KeywordMap)["min16float"] =              EHTokMin16float;
-    (*KeywordMap)["min10float"] =              EHTokMin10float;
-    (*KeywordMap)["min16int"] =                EHTokMin16int;
-    (*KeywordMap)["min12int"] =                EHTokMin12int;
-    (*KeywordMap)["min16uint"] =               EHTokMin16uint;
-
-    (*KeywordMap)["bool1"] =                   EHTokBool1;
-    (*KeywordMap)["bool2"] =                   EHTokBool2;
-    (*KeywordMap)["bool3"] =                   EHTokBool3;
-    (*KeywordMap)["bool4"] =                   EHTokBool4;
-    (*KeywordMap)["float1"] =                  EHTokFloat1;
-    (*KeywordMap)["float2"] =                  EHTokFloat2;
-    (*KeywordMap)["float3"] =                  EHTokFloat3;
-    (*KeywordMap)["float4"] =                  EHTokFloat4;
-    (*KeywordMap)["int1"] =                    EHTokInt1;
-    (*KeywordMap)["int2"] =                    EHTokInt2;
-    (*KeywordMap)["int3"] =                    EHTokInt3;
-    (*KeywordMap)["int4"] =                    EHTokInt4;
-    (*KeywordMap)["double1"] =                 EHTokDouble1;
-    (*KeywordMap)["double2"] =                 EHTokDouble2;
-    (*KeywordMap)["double3"] =                 EHTokDouble3;
-    (*KeywordMap)["double4"] =                 EHTokDouble4;
-    (*KeywordMap)["uint1"] =                   EHTokUint1;
-    (*KeywordMap)["uint2"] =                   EHTokUint2;
-    (*KeywordMap)["uint3"] =                   EHTokUint3;
-    (*KeywordMap)["uint4"] =                   EHTokUint4;
-
-    (*KeywordMap)["half1"] =                   EHTokHalf1;
-    (*KeywordMap)["half2"] =                   EHTokHalf2;
-    (*KeywordMap)["half3"] =                   EHTokHalf3;
-    (*KeywordMap)["half4"] =                   EHTokHalf4;
-    (*KeywordMap)["min16float1"] =             EHTokMin16float1;
-    (*KeywordMap)["min16float2"] =             EHTokMin16float2;
-    (*KeywordMap)["min16float3"] =             EHTokMin16float3;
-    (*KeywordMap)["min16float4"] =             EHTokMin16float4;
-    (*KeywordMap)["min10float1"] =             EHTokMin10float1;
-    (*KeywordMap)["min10float2"] =             EHTokMin10float2;
-    (*KeywordMap)["min10float3"] =             EHTokMin10float3;
-    (*KeywordMap)["min10float4"] =             EHTokMin10float4;
-    (*KeywordMap)["min16int1"] =               EHTokMin16int1;
-    (*KeywordMap)["min16int2"] =               EHTokMin16int2;
-    (*KeywordMap)["min16int3"] =               EHTokMin16int3;
-    (*KeywordMap)["min16int4"] =               EHTokMin16int4;
-    (*KeywordMap)["min12int1"] =               EHTokMin12int1;
-    (*KeywordMap)["min12int2"] =               EHTokMin12int2;
-    (*KeywordMap)["min12int3"] =               EHTokMin12int3;
-    (*KeywordMap)["min12int4"] =               EHTokMin12int4;
-    (*KeywordMap)["min16uint1"] =              EHTokMin16uint1;
-    (*KeywordMap)["min16uint2"] =              EHTokMin16uint2;
-    (*KeywordMap)["min16uint3"] =              EHTokMin16uint3;
-    (*KeywordMap)["min16uint4"] =              EHTokMin16uint4;
-
-    (*KeywordMap)["bool1x1"] =                 EHTokBool1x1;
-    (*KeywordMap)["bool1x2"] =                 EHTokBool1x2;
-    (*KeywordMap)["bool1x3"] =                 EHTokBool1x3;
-    (*KeywordMap)["bool1x4"] =                 EHTokBool1x4;
-    (*KeywordMap)["bool2x1"] =                 EHTokBool2x1;
-    (*KeywordMap)["bool2x2"] =                 EHTokBool2x2;
-    (*KeywordMap)["bool2x3"] =                 EHTokBool2x3;
-    (*KeywordMap)["bool2x4"] =                 EHTokBool2x4;
-    (*KeywordMap)["bool3x1"] =                 EHTokBool3x1;
-    (*KeywordMap)["bool3x2"] =                 EHTokBool3x2;
-    (*KeywordMap)["bool3x3"] =                 EHTokBool3x3;
-    (*KeywordMap)["bool3x4"] =                 EHTokBool3x4;
-    (*KeywordMap)["bool4x1"] =                 EHTokBool4x1;
-    (*KeywordMap)["bool4x2"] =                 EHTokBool4x2;
-    (*KeywordMap)["bool4x3"] =                 EHTokBool4x3;
-    (*KeywordMap)["bool4x4"] =                 EHTokBool4x4;
-    (*KeywordMap)["int1x1"] =                  EHTokInt1x1;
-    (*KeywordMap)["int1x2"] =                  EHTokInt1x2;
-    (*KeywordMap)["int1x3"] =                  EHTokInt1x3;
-    (*KeywordMap)["int1x4"] =                  EHTokInt1x4;
-    (*KeywordMap)["int2x1"] =                  EHTokInt2x1;
-    (*KeywordMap)["int2x2"] =                  EHTokInt2x2;
-    (*KeywordMap)["int2x3"] =                  EHTokInt2x3;
-    (*KeywordMap)["int2x4"] =                  EHTokInt2x4;
-    (*KeywordMap)["int3x1"] =                  EHTokInt3x1;
-    (*KeywordMap)["int3x2"] =                  EHTokInt3x2;
-    (*KeywordMap)["int3x3"] =                  EHTokInt3x3;
-    (*KeywordMap)["int3x4"] =                  EHTokInt3x4;
-    (*KeywordMap)["int4x1"] =                  EHTokInt4x1;
-    (*KeywordMap)["int4x2"] =                  EHTokInt4x2;
-    (*KeywordMap)["int4x3"] =                  EHTokInt4x3;
-    (*KeywordMap)["int4x4"] =                  EHTokInt4x4;
-    (*KeywordMap)["uint1x1"] =                 EHTokUint1x1;
-    (*KeywordMap)["uint1x2"] =                 EHTokUint1x2;
-    (*KeywordMap)["uint1x3"] =                 EHTokUint1x3;
-    (*KeywordMap)["uint1x4"] =                 EHTokUint1x4;
-    (*KeywordMap)["uint2x1"] =                 EHTokUint2x1;
-    (*KeywordMap)["uint2x2"] =                 EHTokUint2x2;
-    (*KeywordMap)["uint2x3"] =                 EHTokUint2x3;
-    (*KeywordMap)["uint2x4"] =                 EHTokUint2x4;
-    (*KeywordMap)["uint3x1"] =                 EHTokUint3x1;
-    (*KeywordMap)["uint3x2"] =                 EHTokUint3x2;
-    (*KeywordMap)["uint3x3"] =                 EHTokUint3x3;
-    (*KeywordMap)["uint3x4"] =                 EHTokUint3x4;
-    (*KeywordMap)["uint4x1"] =                 EHTokUint4x1;
-    (*KeywordMap)["uint4x2"] =                 EHTokUint4x2;
-    (*KeywordMap)["uint4x3"] =                 EHTokUint4x3;
-    (*KeywordMap)["uint4x4"] =                 EHTokUint4x4;
-    (*KeywordMap)["bool1x1"] =                 EHTokBool1x1;
-    (*KeywordMap)["bool1x2"] =                 EHTokBool1x2;
-    (*KeywordMap)["bool1x3"] =                 EHTokBool1x3;
-    (*KeywordMap)["bool1x4"] =                 EHTokBool1x4;
-    (*KeywordMap)["bool2x1"] =                 EHTokBool2x1;
-    (*KeywordMap)["bool2x2"] =                 EHTokBool2x2;
-    (*KeywordMap)["bool2x3"] =                 EHTokBool2x3;
-    (*KeywordMap)["bool2x4"] =                 EHTokBool2x4;
-    (*KeywordMap)["bool3x1"] =                 EHTokBool3x1;
-    (*KeywordMap)["bool3x2"] =                 EHTokBool3x2;
-    (*KeywordMap)["bool3x3"] =                 EHTokBool3x3;
-    (*KeywordMap)["bool3x4"] =                 EHTokBool3x4;
-    (*KeywordMap)["bool4x1"] =                 EHTokBool4x1;
-    (*KeywordMap)["bool4x2"] =                 EHTokBool4x2;
-    (*KeywordMap)["bool4x3"] =                 EHTokBool4x3;
-    (*KeywordMap)["bool4x4"] =                 EHTokBool4x4;
-    (*KeywordMap)["float1x1"] =                EHTokFloat1x1;
-    (*KeywordMap)["float1x2"] =                EHTokFloat1x2;
-    (*KeywordMap)["float1x3"] =                EHTokFloat1x3;
-    (*KeywordMap)["float1x4"] =                EHTokFloat1x4;
-    (*KeywordMap)["float2x1"] =                EHTokFloat2x1;
-    (*KeywordMap)["float2x2"] =                EHTokFloat2x2;
-    (*KeywordMap)["float2x3"] =                EHTokFloat2x3;
-    (*KeywordMap)["float2x4"] =                EHTokFloat2x4;
-    (*KeywordMap)["float3x1"] =                EHTokFloat3x1;
-    (*KeywordMap)["float3x2"] =                EHTokFloat3x2;
-    (*KeywordMap)["float3x3"] =                EHTokFloat3x3;
-    (*KeywordMap)["float3x4"] =                EHTokFloat3x4;
-    (*KeywordMap)["float4x1"] =                EHTokFloat4x1;
-    (*KeywordMap)["float4x2"] =                EHTokFloat4x2;
-    (*KeywordMap)["float4x3"] =                EHTokFloat4x3;
-    (*KeywordMap)["float4x4"] =                EHTokFloat4x4;
-    (*KeywordMap)["half1x1"] =                 EHTokHalf1x1;
-    (*KeywordMap)["half1x2"] =                 EHTokHalf1x2;
-    (*KeywordMap)["half1x3"] =                 EHTokHalf1x3;
-    (*KeywordMap)["half1x4"] =                 EHTokHalf1x4;
-    (*KeywordMap)["half2x1"] =                 EHTokHalf2x1;
-    (*KeywordMap)["half2x2"] =                 EHTokHalf2x2;
-    (*KeywordMap)["half2x3"] =                 EHTokHalf2x3;
-    (*KeywordMap)["half2x4"] =                 EHTokHalf2x4;
-    (*KeywordMap)["half3x1"] =                 EHTokHalf3x1;
-    (*KeywordMap)["half3x2"] =                 EHTokHalf3x2;
-    (*KeywordMap)["half3x3"] =                 EHTokHalf3x3;
-    (*KeywordMap)["half3x4"] =                 EHTokHalf3x4;
-    (*KeywordMap)["half4x1"] =                 EHTokHalf4x1;
-    (*KeywordMap)["half4x2"] =                 EHTokHalf4x2;
-    (*KeywordMap)["half4x3"] =                 EHTokHalf4x3;
-    (*KeywordMap)["half4x4"] =                 EHTokHalf4x4;
-    (*KeywordMap)["double1x1"] =               EHTokDouble1x1;
-    (*KeywordMap)["double1x2"] =               EHTokDouble1x2;
-    (*KeywordMap)["double1x3"] =               EHTokDouble1x3;
-    (*KeywordMap)["double1x4"] =               EHTokDouble1x4;
-    (*KeywordMap)["double2x1"] =               EHTokDouble2x1;
-    (*KeywordMap)["double2x2"] =               EHTokDouble2x2;
-    (*KeywordMap)["double2x3"] =               EHTokDouble2x3;
-    (*KeywordMap)["double2x4"] =               EHTokDouble2x4;
-    (*KeywordMap)["double3x1"] =               EHTokDouble3x1;
-    (*KeywordMap)["double3x2"] =               EHTokDouble3x2;
-    (*KeywordMap)["double3x3"] =               EHTokDouble3x3;
-    (*KeywordMap)["double3x4"] =               EHTokDouble3x4;
-    (*KeywordMap)["double4x1"] =               EHTokDouble4x1;
-    (*KeywordMap)["double4x2"] =               EHTokDouble4x2;
-    (*KeywordMap)["double4x3"] =               EHTokDouble4x3;
-    (*KeywordMap)["double4x4"] =               EHTokDouble4x4;
-    (*KeywordMap)["min16float1x1"] =           EHTokMin16float1x1;
-    (*KeywordMap)["min16float1x2"] =           EHTokMin16float1x2;
-    (*KeywordMap)["min16float1x3"] =           EHTokMin16float1x3;
-    (*KeywordMap)["min16float1x4"] =           EHTokMin16float1x4;
-    (*KeywordMap)["min16float2x1"] =           EHTokMin16float2x1;
-    (*KeywordMap)["min16float2x2"] =           EHTokMin16float2x2;
-    (*KeywordMap)["min16float2x3"] =           EHTokMin16float2x3;
-    (*KeywordMap)["min16float2x4"] =           EHTokMin16float2x4;
-    (*KeywordMap)["min16float3x1"] =           EHTokMin16float3x1;
-    (*KeywordMap)["min16float3x2"] =           EHTokMin16float3x2;
-    (*KeywordMap)["min16float3x3"] =           EHTokMin16float3x3;
-    (*KeywordMap)["min16float3x4"] =           EHTokMin16float3x4;
-    (*KeywordMap)["min16float4x1"] =           EHTokMin16float4x1;
-    (*KeywordMap)["min16float4x2"] =           EHTokMin16float4x2;
-    (*KeywordMap)["min16float4x3"] =           EHTokMin16float4x3;
-    (*KeywordMap)["min16float4x4"] =           EHTokMin16float4x4;
-    (*KeywordMap)["min10float1x1"] =           EHTokMin10float1x1;
-    (*KeywordMap)["min10float1x2"] =           EHTokMin10float1x2;
-    (*KeywordMap)["min10float1x3"] =           EHTokMin10float1x3;
-    (*KeywordMap)["min10float1x4"] =           EHTokMin10float1x4;
-    (*KeywordMap)["min10float2x1"] =           EHTokMin10float2x1;
-    (*KeywordMap)["min10float2x2"] =           EHTokMin10float2x2;
-    (*KeywordMap)["min10float2x3"] =           EHTokMin10float2x3;
-    (*KeywordMap)["min10float2x4"] =           EHTokMin10float2x4;
-    (*KeywordMap)["min10float3x1"] =           EHTokMin10float3x1;
-    (*KeywordMap)["min10float3x2"] =           EHTokMin10float3x2;
-    (*KeywordMap)["min10float3x3"] =           EHTokMin10float3x3;
-    (*KeywordMap)["min10float3x4"] =           EHTokMin10float3x4;
-    (*KeywordMap)["min10float4x1"] =           EHTokMin10float4x1;
-    (*KeywordMap)["min10float4x2"] =           EHTokMin10float4x2;
-    (*KeywordMap)["min10float4x3"] =           EHTokMin10float4x3;
-    (*KeywordMap)["min10float4x4"] =           EHTokMin10float4x4;
-    (*KeywordMap)["min16int1x1"] =             EHTokMin16int1x1;
-    (*KeywordMap)["min16int1x2"] =             EHTokMin16int1x2;
-    (*KeywordMap)["min16int1x3"] =             EHTokMin16int1x3;
-    (*KeywordMap)["min16int1x4"] =             EHTokMin16int1x4;
-    (*KeywordMap)["min16int2x1"] =             EHTokMin16int2x1;
-    (*KeywordMap)["min16int2x2"] =             EHTokMin16int2x2;
-    (*KeywordMap)["min16int2x3"] =             EHTokMin16int2x3;
-    (*KeywordMap)["min16int2x4"] =             EHTokMin16int2x4;
-    (*KeywordMap)["min16int3x1"] =             EHTokMin16int3x1;
-    (*KeywordMap)["min16int3x2"] =             EHTokMin16int3x2;
-    (*KeywordMap)["min16int3x3"] =             EHTokMin16int3x3;
-    (*KeywordMap)["min16int3x4"] =             EHTokMin16int3x4;
-    (*KeywordMap)["min16int4x1"] =             EHTokMin16int4x1;
-    (*KeywordMap)["min16int4x2"] =             EHTokMin16int4x2;
-    (*KeywordMap)["min16int4x3"] =             EHTokMin16int4x3;
-    (*KeywordMap)["min16int4x4"] =             EHTokMin16int4x4;
-    (*KeywordMap)["min12int1x1"] =             EHTokMin12int1x1;
-    (*KeywordMap)["min12int1x2"] =             EHTokMin12int1x2;
-    (*KeywordMap)["min12int1x3"] =             EHTokMin12int1x3;
-    (*KeywordMap)["min12int1x4"] =             EHTokMin12int1x4;
-    (*KeywordMap)["min12int2x1"] =             EHTokMin12int2x1;
-    (*KeywordMap)["min12int2x2"] =             EHTokMin12int2x2;
-    (*KeywordMap)["min12int2x3"] =             EHTokMin12int2x3;
-    (*KeywordMap)["min12int2x4"] =             EHTokMin12int2x4;
-    (*KeywordMap)["min12int3x1"] =             EHTokMin12int3x1;
-    (*KeywordMap)["min12int3x2"] =             EHTokMin12int3x2;
-    (*KeywordMap)["min12int3x3"] =             EHTokMin12int3x3;
-    (*KeywordMap)["min12int3x4"] =             EHTokMin12int3x4;
-    (*KeywordMap)["min12int4x1"] =             EHTokMin12int4x1;
-    (*KeywordMap)["min12int4x2"] =             EHTokMin12int4x2;
-    (*KeywordMap)["min12int4x3"] =             EHTokMin12int4x3;
-    (*KeywordMap)["min12int4x4"] =             EHTokMin12int4x4;
-    (*KeywordMap)["min16uint1x1"] =            EHTokMin16uint1x1;
-    (*KeywordMap)["min16uint1x2"] =            EHTokMin16uint1x2;
-    (*KeywordMap)["min16uint1x3"] =            EHTokMin16uint1x3;
-    (*KeywordMap)["min16uint1x4"] =            EHTokMin16uint1x4;
-    (*KeywordMap)["min16uint2x1"] =            EHTokMin16uint2x1;
-    (*KeywordMap)["min16uint2x2"] =            EHTokMin16uint2x2;
-    (*KeywordMap)["min16uint2x3"] =            EHTokMin16uint2x3;
-    (*KeywordMap)["min16uint2x4"] =            EHTokMin16uint2x4;
-    (*KeywordMap)["min16uint3x1"] =            EHTokMin16uint3x1;
-    (*KeywordMap)["min16uint3x2"] =            EHTokMin16uint3x2;
-    (*KeywordMap)["min16uint3x3"] =            EHTokMin16uint3x3;
-    (*KeywordMap)["min16uint3x4"] =            EHTokMin16uint3x4;
-    (*KeywordMap)["min16uint4x1"] =            EHTokMin16uint4x1;
-    (*KeywordMap)["min16uint4x2"] =            EHTokMin16uint4x2;
-    (*KeywordMap)["min16uint4x3"] =            EHTokMin16uint4x3;
-    (*KeywordMap)["min16uint4x4"] =            EHTokMin16uint4x4;
-
-    (*KeywordMap)["sampler"] =                 EHTokSampler;
-    (*KeywordMap)["sampler1D"] =               EHTokSampler1d;
-    (*KeywordMap)["sampler2D"] =               EHTokSampler2d;
-    (*KeywordMap)["sampler3D"] =               EHTokSampler3d;
-    (*KeywordMap)["samplerCUBE"] =             EHTokSamplerCube;
-    (*KeywordMap)["sampler_state"] =           EHTokSamplerState;
-    (*KeywordMap)["SamplerState"] =            EHTokSamplerState;
-    (*KeywordMap)["SamplerComparisonState"] =  EHTokSamplerComparisonState;
-    (*KeywordMap)["texture"] =                 EHTokTexture;
-    (*KeywordMap)["Texture1D"] =               EHTokTexture1d;
-    (*KeywordMap)["Texture1DArray"] =          EHTokTexture1darray;
-    (*KeywordMap)["Texture2D"] =               EHTokTexture2d;
-    (*KeywordMap)["Texture2DArray"] =          EHTokTexture2darray;
-    (*KeywordMap)["Texture3D"] =               EHTokTexture3d;
-    (*KeywordMap)["TextureCube"] =             EHTokTextureCube;
-    (*KeywordMap)["TextureCubeArray"] =        EHTokTextureCubearray;
-    (*KeywordMap)["Texture2DMS"] =             EHTokTexture2DMS;
-    (*KeywordMap)["Texture2DMSArray"] =        EHTokTexture2DMSarray;
-    (*KeywordMap)["RWTexture1D"] =             EHTokRWTexture1d;
-    (*KeywordMap)["RWTexture1DArray"] =        EHTokRWTexture1darray;
-    (*KeywordMap)["RWTexture2D"] =             EHTokRWTexture2d;
-    (*KeywordMap)["RWTexture2DArray"] =        EHTokRWTexture2darray;
-    (*KeywordMap)["RWTexture3D"] =             EHTokRWTexture3d;
-    (*KeywordMap)["RWBuffer"] =                EHTokRWBuffer;
-    (*KeywordMap)["SubpassInput"] =            EHTokSubpassInput;
-    (*KeywordMap)["SubpassInputMS"] =          EHTokSubpassInputMS;
-
-    (*KeywordMap)["AppendStructuredBuffer"] =  EHTokAppendStructuredBuffer;
-    (*KeywordMap)["ByteAddressBuffer"] =       EHTokByteAddressBuffer;
-    (*KeywordMap)["ConsumeStructuredBuffer"] = EHTokConsumeStructuredBuffer;
-    (*KeywordMap)["RWByteAddressBuffer"] =     EHTokRWByteAddressBuffer;
-    (*KeywordMap)["RWStructuredBuffer"] =      EHTokRWStructuredBuffer;
-    (*KeywordMap)["StructuredBuffer"] =        EHTokStructuredBuffer;
-    (*KeywordMap)["TextureBuffer"] =           EHTokTextureBuffer;
-
-    (*KeywordMap)["class"] =                   EHTokClass;
-    (*KeywordMap)["struct"] =                  EHTokStruct;
-    (*KeywordMap)["cbuffer"] =                 EHTokCBuffer;
-    (*KeywordMap)["ConstantBuffer"] =          EHTokConstantBuffer;
-    (*KeywordMap)["tbuffer"] =                 EHTokTBuffer;
-    (*KeywordMap)["typedef"] =                 EHTokTypedef;
-    (*KeywordMap)["this"] =                    EHTokThis;
-    (*KeywordMap)["namespace"] =               EHTokNamespace;
-
-    (*KeywordMap)["true"] =                    EHTokBoolConstant;
-    (*KeywordMap)["false"] =                   EHTokBoolConstant;
-
-    (*KeywordMap)["for"] =                     EHTokFor;
-    (*KeywordMap)["do"] =                      EHTokDo;
-    (*KeywordMap)["while"] =                   EHTokWhile;
-    (*KeywordMap)["break"] =                   EHTokBreak;
-    (*KeywordMap)["continue"] =                EHTokContinue;
-    (*KeywordMap)["if"] =                      EHTokIf;
-    (*KeywordMap)["else"] =                    EHTokElse;
-    (*KeywordMap)["discard"] =                 EHTokDiscard;
-    (*KeywordMap)["return"] =                  EHTokReturn;
-    (*KeywordMap)["switch"] =                  EHTokSwitch;
-    (*KeywordMap)["case"] =                    EHTokCase;
-    (*KeywordMap)["default"] =                 EHTokDefault;
-
-    // TODO: get correct set here
-    ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
-
-    ReservedSet->insert("auto");
-    ReservedSet->insert("catch");
-    ReservedSet->insert("char");
-    ReservedSet->insert("const_cast");
-    ReservedSet->insert("enum");
-    ReservedSet->insert("explicit");
-    ReservedSet->insert("friend");
-    ReservedSet->insert("goto");
-    ReservedSet->insert("long");
-    ReservedSet->insert("mutable");
-    ReservedSet->insert("new");
-    ReservedSet->insert("operator");
-    ReservedSet->insert("private");
-    ReservedSet->insert("protected");
-    ReservedSet->insert("public");
-    ReservedSet->insert("reinterpret_cast");
-    ReservedSet->insert("short");
-    ReservedSet->insert("signed");
-    ReservedSet->insert("sizeof");
-    ReservedSet->insert("static_cast");
-    ReservedSet->insert("template");
-    ReservedSet->insert("throw");
-    ReservedSet->insert("try");
-    ReservedSet->insert("typename");
-    ReservedSet->insert("union");
-    ReservedSet->insert("unsigned");
-    ReservedSet->insert("using");
-    ReservedSet->insert("virtual");
-
-    SemanticMap = new std::unordered_map<const char*, glslang::TBuiltInVariable, str_hash, str_eq>;
+const std::unordered_set<const char*, str_hash, str_eq> ReservedSet {
+    "auto",
+    "catch",
+    "char",
+    "const_cast",
+    "enum",
+    "explicit",
+    "friend",
+    "goto",
+    "long",
+    "mutable",
+    "new",
+    "operator",
+    "private",
+    "protected",
+    "public",
+    "reinterpret_cast",
+    "short",
+    "signed",
+    "sizeof",
+    "static_cast",
+    "template",
+    "throw",
+    "try",
+    "typename",
+    "union",
+    "unsigned",
+    "using",
+    "virtual",
+};
+std::unordered_map<const char*, glslang::TBuiltInVariable, str_hash, str_eq> SemanticMap { 
 
     // in DX9, all outputs had to have a semantic associated with them, that was either consumed
     // by the system or was a specific register assignment
@@ -494,49 +476,41 @@ void HlslScanContext::fillInKeywordMap()
     // Also, in DX10 if a SV value is present as the input of a stage, but isn't appropriate for that
     // stage, it would just be ignored as it is likely there as part of an output struct from one stage
     // to the next
-    bool bParseDX9 = false;
-    if (bParseDX9) {
-        (*SemanticMap)["PSIZE"] = EbvPointSize;
-        (*SemanticMap)["FOG"] =   EbvFogFragCoord;
-        (*SemanticMap)["DEPTH"] = EbvFragDepth;
-        (*SemanticMap)["VFACE"] = EbvFace;
-        (*SemanticMap)["VPOS"] =  EbvFragCoord;
-    }
-
-    (*SemanticMap)["SV_POSITION"] =               EbvPosition;
-    (*SemanticMap)["SV_VERTEXID"] =               EbvVertexIndex;
-    (*SemanticMap)["SV_VIEWPORTARRAYINDEX"] =     EbvViewportIndex;
-    (*SemanticMap)["SV_TESSFACTOR"] =             EbvTessLevelOuter;
-    (*SemanticMap)["SV_SAMPLEINDEX"] =            EbvSampleId;
-    (*SemanticMap)["SV_RENDERTARGETARRAYINDEX"] = EbvLayer;
-    (*SemanticMap)["SV_PRIMITIVEID"] =            EbvPrimitiveId;
-    (*SemanticMap)["SV_OUTPUTCONTROLPOINTID"] =   EbvInvocationId;
-    (*SemanticMap)["SV_ISFRONTFACE"] =            EbvFace;
-    (*SemanticMap)["SV_VIEWID"] =                 EbvViewIndex;
-    (*SemanticMap)["SV_INSTANCEID"] =             EbvInstanceIndex;
-    (*SemanticMap)["SV_INSIDETESSFACTOR"] =       EbvTessLevelInner;
-    (*SemanticMap)["SV_GSINSTANCEID"] =           EbvInvocationId;
-    (*SemanticMap)["SV_DISPATCHTHREADID"] =       EbvGlobalInvocationId;
-    (*SemanticMap)["SV_GROUPTHREADID"] =          EbvLocalInvocationId;
-    (*SemanticMap)["SV_GROUPINDEX"] =             EbvLocalInvocationIndex;
-    (*SemanticMap)["SV_GROUPID"] =                EbvWorkGroupId;
-    (*SemanticMap)["SV_DOMAINLOCATION"] =         EbvTessCoord;
-    (*SemanticMap)["SV_DEPTH"] =                  EbvFragDepth;
-    (*SemanticMap)["SV_COVERAGE"] =               EbvSampleMask;
-    (*SemanticMap)["SV_DEPTHGREATEREQUAL"] =      EbvFragDepthGreater;
-    (*SemanticMap)["SV_DEPTHLESSEQUAL"] =         EbvFragDepthLesser;
-    (*SemanticMap)["SV_STENCILREF"] =             EbvFragStencilRef;
+#if 0
+    (*SemanticMap)["PSIZE"] = EbvPointSize;
+    (*SemanticMap)["FOG"] =   EbvFogFragCoord;
+    (*SemanticMap)["DEPTH"] = EbvFragDepth;
+    (*SemanticMap)["VFACE"] = EbvFace;
+    (*SemanticMap)["VPOS"] =  EbvFragCoord;
+#endif
+
+    {"SV_POSITION",glslang::EbvPosition},
+    {"SV_VERTEXID",glslang::EbvVertexIndex},
+    {"SV_VIEWPORTARRAYINDEX",glslang::EbvViewportIndex},
+    {"SV_TESSFACTOR",glslang::EbvTessLevelOuter},
+    {"SV_SAMPLEINDEX",glslang::EbvSampleId},
+    {"SV_RENDERTARGETARRAYINDEX",glslang::EbvLayer},
+    {"SV_PRIMITIVEID",glslang::EbvPrimitiveId},
+    {"SV_OUTPUTCONTROLPOINTID",glslang::EbvInvocationId},
+    {"SV_ISFRONTFACE",glslang::EbvFace},
+    {"SV_VIEWID",glslang::EbvViewIndex},
+    {"SV_INSTANCEID",glslang::EbvInstanceIndex},
+    {"SV_INSIDETESSFACTOR",glslang::EbvTessLevelInner},
+    {"SV_GSINSTANCEID",glslang::EbvInvocationId},
+    {"SV_DISPATCHTHREADID",glslang::EbvGlobalInvocationId},
+    {"SV_GROUPTHREADID",glslang::EbvLocalInvocationId},
+    {"SV_GROUPINDEX",glslang::EbvLocalInvocationIndex},
+    {"SV_GROUPID",glslang::EbvWorkGroupId},
+    {"SV_DOMAINLOCATION",glslang::EbvTessCoord},
+    {"SV_DEPTH",glslang::EbvFragDepth},
+    {"SV_COVERAGE",glslang::EbvSampleMask},
+    {"SV_DEPTHGREATEREQUAL",glslang::EbvFragDepthGreater},
+    {"SV_DEPTHLESSEQUAL",glslang::EbvFragDepthLesser},
+    {"SV_STENCILREF", glslang::EbvFragStencilRef},
+};
 }
 
-void HlslScanContext::deleteKeywordMap()
-{
-    delete KeywordMap;
-    KeywordMap = nullptr;
-    delete ReservedSet;
-    ReservedSet = nullptr;
-    delete SemanticMap;
-    SemanticMap = nullptr;
-}
+namespace glslang {
 
 // Wrapper for tokenizeClass() to get everything inside the token.
 void HlslScanContext::tokenize(HlslToken& token)
@@ -547,8 +521,8 @@ void HlslScanContext::tokenize(HlslToken& token)
 
 glslang::TBuiltInVariable HlslScanContext::mapSemantic(const char* upperCase)
 {
-    auto it = SemanticMap->find(upperCase);
-    if (it != SemanticMap->end())
+    auto it = SemanticMap.find(upperCase);
+    if (it != SemanticMap.end())
         return it->second;
     else
         return glslang::EbvNone;
@@ -664,11 +638,11 @@ EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
 
 EHlslTokenClass HlslScanContext::tokenizeIdentifier()
 {
-    if (ReservedSet->find(tokenText) != ReservedSet->end())
+    if (ReservedSet.find(tokenText) != ReservedSet.end())
         return reservedWord();
 
-    auto it = KeywordMap->find(tokenText);
-    if (it == KeywordMap->end()) {
+    auto it = KeywordMap.find(tokenText);
+    if (it == KeywordMap.end()) {
         // Should have an identifier of some sort
         return identifierOrType();
     }

+ 0 - 15
3rdparty/glslang/glslang/Include/Types.h

@@ -307,21 +307,6 @@ typedef TVector<TTypeLoc> TTypeList;
 
 typedef TVector<TString*> TIdentifierList;
 
-//
-// Following are a series of helper enums for managing layouts and qualifiers,
-// used for TPublicType, TType, others.
-//
-
-enum TLayoutPacking {
-    ElpNone,
-    ElpShared,      // default, but different than saying nothing
-    ElpStd140,
-    ElpStd430,
-    ElpPacked,
-    ElpScalar,
-    ElpCount        // If expanding, see bitfield width below
-};
-
 enum TLayoutMatrix {
     ElmNone,
     ElmRowMajor,

+ 1 - 0
3rdparty/glslang/glslang/Include/glslang_c_interface.h

@@ -259,6 +259,7 @@ GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int opt
 GLSLANG_EXPORT void glslang_shader_set_glsl_version(glslang_shader_t* shader, int version);
 GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_set_and_binding(glslang_shader_t* shader, unsigned int set, unsigned int binding);
 GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_name(glslang_shader_t* shader, const char *name);
+GLSLANG_EXPORT void glslang_shader_set_resource_set_binding(glslang_shader_t* shader, const char *const *bindings, unsigned int num_bindings);
 GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input);
 GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input);
 GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader);

+ 1 - 0
3rdparty/glslang/glslang/Include/glslang_c_shader_types.h

@@ -176,6 +176,7 @@ typedef enum {
     GLSLANG_MSG_ENHANCED                    = (1 << 15),
     GLSLANG_MSG_ABSOLUTE_PATH               = (1 << 16),
     GLSLANG_MSG_DISPLAY_ERROR_COLUMN        = (1 << 17),
+    GLSLANG_MSG_LINK_TIME_OPTIMIZATION_BIT  = (1 << 18),
     LAST_ELEMENT_MARKER(GLSLANG_MSG_COUNT),
 } glslang_messages_t;
 

+ 13 - 2
3rdparty/glslang/glslang/Include/intermediate.h

@@ -1694,8 +1694,12 @@ typedef TVector<TStorageQualifier> TQualifierList;
 //
 class TIntermAggregate : public TIntermOperator {
 public:
-    TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(nullptr) { }
-    TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(nullptr) { }
+    TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(nullptr) { 
+        endLoc.init();
+    }
+    TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(nullptr) {
+        endLoc.init();
+    }
     ~TIntermAggregate() { delete pragmaTable; }
     virtual       TIntermAggregate* getAsAggregate()       { return this; }
     virtual const TIntermAggregate* getAsAggregate() const { return this; }
@@ -1719,6 +1723,9 @@ public:
     void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
     const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
 
+    void setEndLoc(TSourceLoc loc) { endLoc = loc; }
+    TSourceLoc getEndLoc() const { return endLoc; }
+
     void setLinkType(TLinkType l) { linkType = l; }
     TLinkType getLinkType() const { return linkType; }
 protected:
@@ -1733,6 +1740,10 @@ protected:
     TPragmaTable* pragmaTable;
     TSpirvInstruction spirvInst;
     TLinkType linkType = ELinkNone;
+
+    // Marking the end source location of the aggregate.
+    // This is currently only set for a compound statement or a function body, pointing to '}'.
+    TSourceLoc endLoc;
 };
 
 //

+ 4 - 1
3rdparty/glslang/glslang/Include/visibility.h

@@ -48,4 +48,7 @@
 #define GLSLANG_EXPORT
 #endif
 
-
+// Symbols marked with this macro are only meant for public use by the test suite
+// and do not appear in publicly installed headers. They are not considered to be
+// part of the glslang library ABI.
+#define GLSLANG_EXPORT_FOR_TESTS GLSLANG_EXPORT

+ 6 - 3
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp

@@ -9924,8 +9924,8 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
 
     if (publicType.shaderQualifiers.layoutDerivativeGroupQuads) {
         if (publicType.qualifier.storage == EvqVaryingIn) {
-            if ((intermediate.getLocalSize(0) & 1) ||
-                (intermediate.getLocalSize(1) & 1))
+            if ((intermediate.getLocalSizeSpecId(0) == TQualifier::layoutNotSet && (intermediate.getLocalSize(0) & 1)) ||
+                (intermediate.getLocalSizeSpecId(1) == TQualifier::layoutNotSet && (intermediate.getLocalSize(1) & 1)))
                 error(loc, "requires local_size_x and local_size_y to be multiple of two", "derivative_group_quadsNV", "");
             else
                 intermediate.setLayoutDerivativeMode(LayoutDerivativeGroupQuads);
@@ -9935,7 +9935,10 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
     }
     if (publicType.shaderQualifiers.layoutDerivativeGroupLinear) {
         if (publicType.qualifier.storage == EvqVaryingIn) {
-            if((intermediate.getLocalSize(0) *
+            if (intermediate.getLocalSizeSpecId(0) == TQualifier::layoutNotSet &&
+                intermediate.getLocalSizeSpecId(1) == TQualifier::layoutNotSet &&
+                intermediate.getLocalSizeSpecId(2) == TQualifier::layoutNotSet &&
+                (intermediate.getLocalSize(0) *
                 intermediate.getLocalSize(1) *
                 intermediate.getLocalSize(2)) % 4 != 0)
                 error(loc, "requires total group size to be multiple of four", "derivative_group_linearNV", "");

+ 471 - 493
3rdparty/glslang/glslang/MachineIndependent/Scan.cpp

@@ -322,503 +322,481 @@ struct str_hash
 };
 
 // A single global usable by all threads, by all versions, by all languages.
-// After a single process-level initialization, this is read only and thread safe
-std::unordered_map<const char*, int, str_hash, str_eq>* KeywordMap = nullptr;
-std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
-
-}
-
-namespace glslang {
-
-void TScanContext::fillInKeywordMap()
-{
-    if (KeywordMap != nullptr) {
-        // this is really an error, as this should called only once per process
-        // but, the only risk is if two threads called simultaneously
-        return;
-    }
-    KeywordMap = new std::unordered_map<const char*, int, str_hash, str_eq>;
-
-    (*KeywordMap)["const"] =                   CONST;
-    (*KeywordMap)["uniform"] =                 UNIFORM;
-    (*KeywordMap)["tileImageEXT"] =            TILEIMAGEEXT;
-    (*KeywordMap)["buffer"] =                  BUFFER;
-    (*KeywordMap)["in"] =                      IN;
-    (*KeywordMap)["out"] =                     OUT;
-    (*KeywordMap)["smooth"] =                  SMOOTH;
-    (*KeywordMap)["flat"] =                    FLAT;
-    (*KeywordMap)["centroid"] =                CENTROID;
-    (*KeywordMap)["invariant"] =               INVARIANT;
-    (*KeywordMap)["packed"] =                  PACKED;
-    (*KeywordMap)["resource"] =                RESOURCE;
-    (*KeywordMap)["inout"] =                   INOUT;
-    (*KeywordMap)["struct"] =                  STRUCT;
-    (*KeywordMap)["break"] =                   BREAK;
-    (*KeywordMap)["continue"] =                CONTINUE;
-    (*KeywordMap)["do"] =                      DO;
-    (*KeywordMap)["for"] =                     FOR;
-    (*KeywordMap)["while"] =                   WHILE;
-    (*KeywordMap)["switch"] =                  SWITCH;
-    (*KeywordMap)["case"] =                    CASE;
-    (*KeywordMap)["default"] =                 DEFAULT;
-    (*KeywordMap)["if"] =                      IF;
-    (*KeywordMap)["else"] =                    ELSE;
-    (*KeywordMap)["discard"] =                 DISCARD;
-    (*KeywordMap)["terminateInvocation"] =     TERMINATE_INVOCATION;
-    (*KeywordMap)["terminateRayEXT"] =         TERMINATE_RAY;
-    (*KeywordMap)["ignoreIntersectionEXT"] =   IGNORE_INTERSECTION;
-    (*KeywordMap)["return"] =                  RETURN;
-    (*KeywordMap)["void"] =                    VOID;
-    (*KeywordMap)["bool"] =                    BOOL;
-    (*KeywordMap)["float"] =                   FLOAT;
-    (*KeywordMap)["int"] =                     INT;
-    (*KeywordMap)["bvec2"] =                   BVEC2;
-    (*KeywordMap)["bvec3"] =                   BVEC3;
-    (*KeywordMap)["bvec4"] =                   BVEC4;
-    (*KeywordMap)["vec2"] =                    VEC2;
-    (*KeywordMap)["vec3"] =                    VEC3;
-    (*KeywordMap)["vec4"] =                    VEC4;
-    (*KeywordMap)["ivec2"] =                   IVEC2;
-    (*KeywordMap)["ivec3"] =                   IVEC3;
-    (*KeywordMap)["ivec4"] =                   IVEC4;
-    (*KeywordMap)["mat2"] =                    MAT2;
-    (*KeywordMap)["mat3"] =                    MAT3;
-    (*KeywordMap)["mat4"] =                    MAT4;
-    (*KeywordMap)["true"] =                    BOOLCONSTANT;
-    (*KeywordMap)["false"] =                   BOOLCONSTANT;
-    (*KeywordMap)["layout"] =                  LAYOUT;
-    (*KeywordMap)["shared"] =                  SHARED;
-    (*KeywordMap)["highp"] =                   HIGH_PRECISION;
-    (*KeywordMap)["mediump"] =                 MEDIUM_PRECISION;
-    (*KeywordMap)["lowp"] =                    LOW_PRECISION;
-    (*KeywordMap)["superp"] =                  SUPERP;
-    (*KeywordMap)["precision"] =               PRECISION;
-    (*KeywordMap)["mat2x2"] =                  MAT2X2;
-    (*KeywordMap)["mat2x3"] =                  MAT2X3;
-    (*KeywordMap)["mat2x4"] =                  MAT2X4;
-    (*KeywordMap)["mat3x2"] =                  MAT3X2;
-    (*KeywordMap)["mat3x3"] =                  MAT3X3;
-    (*KeywordMap)["mat3x4"] =                  MAT3X4;
-    (*KeywordMap)["mat4x2"] =                  MAT4X2;
-    (*KeywordMap)["mat4x3"] =                  MAT4X3;
-    (*KeywordMap)["mat4x4"] =                  MAT4X4;
-    (*KeywordMap)["uint"] =                    UINT;
-    (*KeywordMap)["uvec2"] =                   UVEC2;
-    (*KeywordMap)["uvec3"] =                   UVEC3;
-    (*KeywordMap)["uvec4"] =                   UVEC4;
-
-    (*KeywordMap)["nonuniformEXT"] =           NONUNIFORM;
-    (*KeywordMap)["demote"] =                  DEMOTE;
-    (*KeywordMap)["attribute"] =               ATTRIBUTE;
-    (*KeywordMap)["varying"] =                 VARYING;
-    (*KeywordMap)["noperspective"] =           NOPERSPECTIVE;
-    (*KeywordMap)["coherent"] =                COHERENT;
-    (*KeywordMap)["devicecoherent"] =          DEVICECOHERENT;
-    (*KeywordMap)["queuefamilycoherent"] =     QUEUEFAMILYCOHERENT;
-    (*KeywordMap)["workgroupcoherent"] =       WORKGROUPCOHERENT;
-    (*KeywordMap)["subgroupcoherent"] =        SUBGROUPCOHERENT;
-    (*KeywordMap)["shadercallcoherent"] =      SHADERCALLCOHERENT;
-    (*KeywordMap)["nonprivate"] =              NONPRIVATE;
-    (*KeywordMap)["restrict"] =                RESTRICT;
-    (*KeywordMap)["readonly"] =                READONLY;
-    (*KeywordMap)["writeonly"] =               WRITEONLY;
-    (*KeywordMap)["atomic_uint"] =             ATOMIC_UINT;
-    (*KeywordMap)["volatile"] =                VOLATILE;
-    (*KeywordMap)["patch"] =                   PATCH;
-    (*KeywordMap)["sample"] =                  SAMPLE;
-    (*KeywordMap)["subroutine"] =              SUBROUTINE;
-    (*KeywordMap)["dmat2"] =                   DMAT2;
-    (*KeywordMap)["dmat3"] =                   DMAT3;
-    (*KeywordMap)["dmat4"] =                   DMAT4;
-    (*KeywordMap)["dmat2x2"] =                 DMAT2X2;
-    (*KeywordMap)["dmat2x3"] =                 DMAT2X3;
-    (*KeywordMap)["dmat2x4"] =                 DMAT2X4;
-    (*KeywordMap)["dmat3x2"] =                 DMAT3X2;
-    (*KeywordMap)["dmat3x3"] =                 DMAT3X3;
-    (*KeywordMap)["dmat3x4"] =                 DMAT3X4;
-    (*KeywordMap)["dmat4x2"] =                 DMAT4X2;
-    (*KeywordMap)["dmat4x3"] =                 DMAT4X3;
-    (*KeywordMap)["dmat4x4"] =                 DMAT4X4;
-    (*KeywordMap)["image1D"] =                 IMAGE1D;
-    (*KeywordMap)["iimage1D"] =                IIMAGE1D;
-    (*KeywordMap)["uimage1D"] =                UIMAGE1D;
-    (*KeywordMap)["image2D"] =                 IMAGE2D;
-    (*KeywordMap)["iimage2D"] =                IIMAGE2D;
-    (*KeywordMap)["uimage2D"] =                UIMAGE2D;
-    (*KeywordMap)["image3D"] =                 IMAGE3D;
-    (*KeywordMap)["iimage3D"] =                IIMAGE3D;
-    (*KeywordMap)["uimage3D"] =                UIMAGE3D;
-    (*KeywordMap)["image2DRect"] =             IMAGE2DRECT;
-    (*KeywordMap)["iimage2DRect"] =            IIMAGE2DRECT;
-    (*KeywordMap)["uimage2DRect"] =            UIMAGE2DRECT;
-    (*KeywordMap)["imageCube"] =               IMAGECUBE;
-    (*KeywordMap)["iimageCube"] =              IIMAGECUBE;
-    (*KeywordMap)["uimageCube"] =              UIMAGECUBE;
-    (*KeywordMap)["imageBuffer"] =             IMAGEBUFFER;
-    (*KeywordMap)["iimageBuffer"] =            IIMAGEBUFFER;
-    (*KeywordMap)["uimageBuffer"] =            UIMAGEBUFFER;
-    (*KeywordMap)["image1DArray"] =            IMAGE1DARRAY;
-    (*KeywordMap)["iimage1DArray"] =           IIMAGE1DARRAY;
-    (*KeywordMap)["uimage1DArray"] =           UIMAGE1DARRAY;
-    (*KeywordMap)["image2DArray"] =            IMAGE2DARRAY;
-    (*KeywordMap)["iimage2DArray"] =           IIMAGE2DARRAY;
-    (*KeywordMap)["uimage2DArray"] =           UIMAGE2DARRAY;
-    (*KeywordMap)["imageCubeArray"] =          IMAGECUBEARRAY;
-    (*KeywordMap)["iimageCubeArray"] =         IIMAGECUBEARRAY;
-    (*KeywordMap)["uimageCubeArray"] =         UIMAGECUBEARRAY;
-    (*KeywordMap)["image2DMS"] =               IMAGE2DMS;
-    (*KeywordMap)["iimage2DMS"] =              IIMAGE2DMS;
-    (*KeywordMap)["uimage2DMS"] =              UIMAGE2DMS;
-    (*KeywordMap)["image2DMSArray"] =          IMAGE2DMSARRAY;
-    (*KeywordMap)["iimage2DMSArray"] =         IIMAGE2DMSARRAY;
-    (*KeywordMap)["uimage2DMSArray"] =         UIMAGE2DMSARRAY;
-    (*KeywordMap)["i64image1D"] =              I64IMAGE1D;
-    (*KeywordMap)["u64image1D"] =              U64IMAGE1D;
-    (*KeywordMap)["i64image2D"] =              I64IMAGE2D;
-    (*KeywordMap)["u64image2D"] =              U64IMAGE2D;
-    (*KeywordMap)["i64image3D"] =              I64IMAGE3D;
-    (*KeywordMap)["u64image3D"] =              U64IMAGE3D;
-    (*KeywordMap)["i64image2DRect"] =          I64IMAGE2DRECT;
-    (*KeywordMap)["u64image2DRect"] =          U64IMAGE2DRECT;
-    (*KeywordMap)["i64imageCube"] =            I64IMAGECUBE;
-    (*KeywordMap)["u64imageCube"] =            U64IMAGECUBE;
-    (*KeywordMap)["i64imageBuffer"] =          I64IMAGEBUFFER;
-    (*KeywordMap)["u64imageBuffer"] =          U64IMAGEBUFFER;
-    (*KeywordMap)["i64image1DArray"] =         I64IMAGE1DARRAY;
-    (*KeywordMap)["u64image1DArray"] =         U64IMAGE1DARRAY;
-    (*KeywordMap)["i64image2DArray"] =         I64IMAGE2DARRAY;
-    (*KeywordMap)["u64image2DArray"] =         U64IMAGE2DARRAY;
-    (*KeywordMap)["i64imageCubeArray"] =       I64IMAGECUBEARRAY;
-    (*KeywordMap)["u64imageCubeArray"] =       U64IMAGECUBEARRAY;
-    (*KeywordMap)["i64image2DMS"] =            I64IMAGE2DMS;
-    (*KeywordMap)["u64image2DMS"] =            U64IMAGE2DMS;
-    (*KeywordMap)["i64image2DMSArray"] =       I64IMAGE2DMSARRAY;
-    (*KeywordMap)["u64image2DMSArray"] =       U64IMAGE2DMSARRAY;
-    (*KeywordMap)["double"] =                  DOUBLE;
-    (*KeywordMap)["dvec2"] =                   DVEC2;
-    (*KeywordMap)["dvec3"] =                   DVEC3;
-    (*KeywordMap)["dvec4"] =                   DVEC4;
-    (*KeywordMap)["int64_t"] =                 INT64_T;
-    (*KeywordMap)["uint64_t"] =                UINT64_T;
-    (*KeywordMap)["i64vec2"] =                 I64VEC2;
-    (*KeywordMap)["i64vec3"] =                 I64VEC3;
-    (*KeywordMap)["i64vec4"] =                 I64VEC4;
-    (*KeywordMap)["u64vec2"] =                 U64VEC2;
-    (*KeywordMap)["u64vec3"] =                 U64VEC3;
-    (*KeywordMap)["u64vec4"] =                 U64VEC4;
+const std::unordered_map<const char*, int, str_hash, str_eq> KeywordMap {
+    {"const",CONST},
+    {"uniform",UNIFORM},
+    {"tileImageEXT",TILEIMAGEEXT},
+    {"buffer",BUFFER},
+    {"in",IN},
+    {"out",OUT},
+    {"smooth",SMOOTH},
+    {"flat",FLAT},
+    {"centroid",CENTROID},
+    {"invariant",INVARIANT},
+    {"packed",PACKED},
+    {"resource",RESOURCE},
+    {"inout",INOUT},
+    {"struct",STRUCT},
+    {"break",BREAK},
+    {"continue",CONTINUE},
+    {"do",DO},
+    {"for",FOR},
+    {"while",WHILE},
+    {"switch",SWITCH},
+    {"case",CASE},
+    {"default",DEFAULT},
+    {"if",IF},
+    {"else",ELSE},
+    {"discard",DISCARD},
+    {"terminateInvocation",TERMINATE_INVOCATION},
+    {"terminateRayEXT",TERMINATE_RAY},
+    {"ignoreIntersectionEXT",IGNORE_INTERSECTION},
+    {"return",RETURN},
+    {"void",VOID},
+    {"bool",BOOL},
+    {"float",FLOAT},
+    {"int",INT},
+    {"bvec2",BVEC2},
+    {"bvec3",BVEC3},
+    {"bvec4",BVEC4},
+    {"vec2",VEC2},
+    {"vec3",VEC3},
+    {"vec4",VEC4},
+    {"ivec2",IVEC2},
+    {"ivec3",IVEC3},
+    {"ivec4",IVEC4},
+    {"mat2",MAT2},
+    {"mat3",MAT3},
+    {"mat4",MAT4},
+    {"true",BOOLCONSTANT},
+    {"false",BOOLCONSTANT},
+    {"layout",LAYOUT},
+    {"shared",SHARED},
+    {"highp",HIGH_PRECISION},
+    {"mediump",MEDIUM_PRECISION},
+    {"lowp",LOW_PRECISION},
+    {"superp",SUPERP},
+    {"precision",PRECISION},
+    {"mat2x2",MAT2X2},
+    {"mat2x3",MAT2X3},
+    {"mat2x4",MAT2X4},
+    {"mat3x2",MAT3X2},
+    {"mat3x3",MAT3X3},
+    {"mat3x4",MAT3X4},
+    {"mat4x2",MAT4X2},
+    {"mat4x3",MAT4X3},
+    {"mat4x4",MAT4X4},
+    {"uint",UINT},
+    {"uvec2",UVEC2},
+    {"uvec3",UVEC3},
+    {"uvec4",UVEC4},
+
+    {"nonuniformEXT",NONUNIFORM},
+    {"demote",DEMOTE},
+    {"attribute",ATTRIBUTE},
+    {"varying",VARYING},
+    {"noperspective",NOPERSPECTIVE},
+    {"coherent",COHERENT},
+    {"devicecoherent",DEVICECOHERENT},
+    {"queuefamilycoherent",QUEUEFAMILYCOHERENT},
+    {"workgroupcoherent",WORKGROUPCOHERENT},
+    {"subgroupcoherent",SUBGROUPCOHERENT},
+    {"shadercallcoherent",SHADERCALLCOHERENT},
+    {"nonprivate",NONPRIVATE},
+    {"restrict",RESTRICT},
+    {"readonly",READONLY},
+    {"writeonly",WRITEONLY},
+    {"atomic_uint",ATOMIC_UINT},
+    {"volatile",VOLATILE},
+    {"patch",PATCH},
+    {"sample",SAMPLE},
+    {"subroutine",SUBROUTINE},
+    {"dmat2",DMAT2},
+    {"dmat3",DMAT3},
+    {"dmat4",DMAT4},
+    {"dmat2x2",DMAT2X2},
+    {"dmat2x3",DMAT2X3},
+    {"dmat2x4",DMAT2X4},
+    {"dmat3x2",DMAT3X2},
+    {"dmat3x3",DMAT3X3},
+    {"dmat3x4",DMAT3X4},
+    {"dmat4x2",DMAT4X2},
+    {"dmat4x3",DMAT4X3},
+    {"dmat4x4",DMAT4X4},
+    {"image1D",IMAGE1D},
+    {"iimage1D",IIMAGE1D},
+    {"uimage1D",UIMAGE1D},
+    {"image2D",IMAGE2D},
+    {"iimage2D",IIMAGE2D},
+    {"uimage2D",UIMAGE2D},
+    {"image3D",IMAGE3D},
+    {"iimage3D",IIMAGE3D},
+    {"uimage3D",UIMAGE3D},
+    {"image2DRect",IMAGE2DRECT},
+    {"iimage2DRect",IIMAGE2DRECT},
+    {"uimage2DRect",UIMAGE2DRECT},
+    {"imageCube",IMAGECUBE},
+    {"iimageCube",IIMAGECUBE},
+    {"uimageCube",UIMAGECUBE},
+    {"imageBuffer",IMAGEBUFFER},
+    {"iimageBuffer",IIMAGEBUFFER},
+    {"uimageBuffer",UIMAGEBUFFER},
+    {"image1DArray",IMAGE1DARRAY},
+    {"iimage1DArray",IIMAGE1DARRAY},
+    {"uimage1DArray",UIMAGE1DARRAY},
+    {"image2DArray",IMAGE2DARRAY},
+    {"iimage2DArray",IIMAGE2DARRAY},
+    {"uimage2DArray",UIMAGE2DARRAY},
+    {"imageCubeArray",IMAGECUBEARRAY},
+    {"iimageCubeArray",IIMAGECUBEARRAY},
+    {"uimageCubeArray",UIMAGECUBEARRAY},
+    {"image2DMS",IMAGE2DMS},
+    {"iimage2DMS",IIMAGE2DMS},
+    {"uimage2DMS",UIMAGE2DMS},
+    {"image2DMSArray",IMAGE2DMSARRAY},
+    {"iimage2DMSArray",IIMAGE2DMSARRAY},
+    {"uimage2DMSArray",UIMAGE2DMSARRAY},
+    {"i64image1D",I64IMAGE1D},
+    {"u64image1D",U64IMAGE1D},
+    {"i64image2D",I64IMAGE2D},
+    {"u64image2D",U64IMAGE2D},
+    {"i64image3D",I64IMAGE3D},
+    {"u64image3D",U64IMAGE3D},
+    {"i64image2DRect",I64IMAGE2DRECT},
+    {"u64image2DRect",U64IMAGE2DRECT},
+    {"i64imageCube",I64IMAGECUBE},
+    {"u64imageCube",U64IMAGECUBE},
+    {"i64imageBuffer",I64IMAGEBUFFER},
+    {"u64imageBuffer",U64IMAGEBUFFER},
+    {"i64image1DArray",I64IMAGE1DARRAY},
+    {"u64image1DArray",U64IMAGE1DARRAY},
+    {"i64image2DArray",I64IMAGE2DARRAY},
+    {"u64image2DArray",U64IMAGE2DARRAY},
+    {"i64imageCubeArray",I64IMAGECUBEARRAY},
+    {"u64imageCubeArray",U64IMAGECUBEARRAY},
+    {"i64image2DMS",I64IMAGE2DMS},
+    {"u64image2DMS",U64IMAGE2DMS},
+    {"i64image2DMSArray",I64IMAGE2DMSARRAY},
+    {"u64image2DMSArray",U64IMAGE2DMSARRAY},
+    {"double",DOUBLE},
+    {"dvec2",DVEC2},
+    {"dvec3",DVEC3},
+    {"dvec4",DVEC4},
+    {"int64_t",INT64_T},
+    {"uint64_t",UINT64_T},
+    {"i64vec2",I64VEC2},
+    {"i64vec3",I64VEC3},
+    {"i64vec4",I64VEC4},
+    {"u64vec2",U64VEC2},
+    {"u64vec3",U64VEC3},
+    {"u64vec4",U64VEC4},
 
     // GL_EXT_shader_explicit_arithmetic_types
-    (*KeywordMap)["int8_t"] =                  INT8_T;
-    (*KeywordMap)["i8vec2"] =                  I8VEC2;
-    (*KeywordMap)["i8vec3"] =                  I8VEC3;
-    (*KeywordMap)["i8vec4"] =                  I8VEC4;
-    (*KeywordMap)["uint8_t"] =                 UINT8_T;
-    (*KeywordMap)["u8vec2"] =                  U8VEC2;
-    (*KeywordMap)["u8vec3"] =                  U8VEC3;
-    (*KeywordMap)["u8vec4"] =                  U8VEC4;
-
-    (*KeywordMap)["int16_t"] =                 INT16_T;
-    (*KeywordMap)["i16vec2"] =                 I16VEC2;
-    (*KeywordMap)["i16vec3"] =                 I16VEC3;
-    (*KeywordMap)["i16vec4"] =                 I16VEC4;
-    (*KeywordMap)["uint16_t"] =                UINT16_T;
-    (*KeywordMap)["u16vec2"] =                 U16VEC2;
-    (*KeywordMap)["u16vec3"] =                 U16VEC3;
-    (*KeywordMap)["u16vec4"] =                 U16VEC4;
-
-    (*KeywordMap)["int32_t"] =                 INT32_T;
-    (*KeywordMap)["i32vec2"] =                 I32VEC2;
-    (*KeywordMap)["i32vec3"] =                 I32VEC3;
-    (*KeywordMap)["i32vec4"] =                 I32VEC4;
-    (*KeywordMap)["uint32_t"] =                UINT32_T;
-    (*KeywordMap)["u32vec2"] =                 U32VEC2;
-    (*KeywordMap)["u32vec3"] =                 U32VEC3;
-    (*KeywordMap)["u32vec4"] =                 U32VEC4;
-
-    (*KeywordMap)["float16_t"] =               FLOAT16_T;
-    (*KeywordMap)["f16vec2"] =                 F16VEC2;
-    (*KeywordMap)["f16vec3"] =                 F16VEC3;
-    (*KeywordMap)["f16vec4"] =                 F16VEC4;
-    (*KeywordMap)["f16mat2"] =                 F16MAT2;
-    (*KeywordMap)["f16mat3"] =                 F16MAT3;
-    (*KeywordMap)["f16mat4"] =                 F16MAT4;
-    (*KeywordMap)["f16mat2x2"] =               F16MAT2X2;
-    (*KeywordMap)["f16mat2x3"] =               F16MAT2X3;
-    (*KeywordMap)["f16mat2x4"] =               F16MAT2X4;
-    (*KeywordMap)["f16mat3x2"] =               F16MAT3X2;
-    (*KeywordMap)["f16mat3x3"] =               F16MAT3X3;
-    (*KeywordMap)["f16mat3x4"] =               F16MAT3X4;
-    (*KeywordMap)["f16mat4x2"] =               F16MAT4X2;
-    (*KeywordMap)["f16mat4x3"] =               F16MAT4X3;
-    (*KeywordMap)["f16mat4x4"] =               F16MAT4X4;
-
-    (*KeywordMap)["float32_t"] =               FLOAT32_T;
-    (*KeywordMap)["f32vec2"] =                 F32VEC2;
-    (*KeywordMap)["f32vec3"] =                 F32VEC3;
-    (*KeywordMap)["f32vec4"] =                 F32VEC4;
-    (*KeywordMap)["f32mat2"] =                 F32MAT2;
-    (*KeywordMap)["f32mat3"] =                 F32MAT3;
-    (*KeywordMap)["f32mat4"] =                 F32MAT4;
-    (*KeywordMap)["f32mat2x2"] =               F32MAT2X2;
-    (*KeywordMap)["f32mat2x3"] =               F32MAT2X3;
-    (*KeywordMap)["f32mat2x4"] =               F32MAT2X4;
-    (*KeywordMap)["f32mat3x2"] =               F32MAT3X2;
-    (*KeywordMap)["f32mat3x3"] =               F32MAT3X3;
-    (*KeywordMap)["f32mat3x4"] =               F32MAT3X4;
-    (*KeywordMap)["f32mat4x2"] =               F32MAT4X2;
-    (*KeywordMap)["f32mat4x3"] =               F32MAT4X3;
-    (*KeywordMap)["f32mat4x4"] =               F32MAT4X4;
-    (*KeywordMap)["float64_t"] =               FLOAT64_T;
-    (*KeywordMap)["f64vec2"] =                 F64VEC2;
-    (*KeywordMap)["f64vec3"] =                 F64VEC3;
-    (*KeywordMap)["f64vec4"] =                 F64VEC4;
-    (*KeywordMap)["f64mat2"] =                 F64MAT2;
-    (*KeywordMap)["f64mat3"] =                 F64MAT3;
-    (*KeywordMap)["f64mat4"] =                 F64MAT4;
-    (*KeywordMap)["f64mat2x2"] =               F64MAT2X2;
-    (*KeywordMap)["f64mat2x3"] =               F64MAT2X3;
-    (*KeywordMap)["f64mat2x4"] =               F64MAT2X4;
-    (*KeywordMap)["f64mat3x2"] =               F64MAT3X2;
-    (*KeywordMap)["f64mat3x3"] =               F64MAT3X3;
-    (*KeywordMap)["f64mat3x4"] =               F64MAT3X4;
-    (*KeywordMap)["f64mat4x2"] =               F64MAT4X2;
-    (*KeywordMap)["f64mat4x3"] =               F64MAT4X3;
-    (*KeywordMap)["f64mat4x4"] =               F64MAT4X4;
+    {"int8_t",INT8_T},
+    {"i8vec2",I8VEC2},
+    {"i8vec3",I8VEC3},
+    {"i8vec4",I8VEC4},
+    {"uint8_t",UINT8_T},
+    {"u8vec2",U8VEC2},
+    {"u8vec3",U8VEC3},
+    {"u8vec4",U8VEC4},
+
+    {"int16_t",INT16_T},
+    {"i16vec2",I16VEC2},
+    {"i16vec3",I16VEC3},
+    {"i16vec4",I16VEC4},
+    {"uint16_t",UINT16_T},
+    {"u16vec2",U16VEC2},
+    {"u16vec3",U16VEC3},
+    {"u16vec4",U16VEC4},
+
+    {"int32_t",INT32_T},
+    {"i32vec2",I32VEC2},
+    {"i32vec3",I32VEC3},
+    {"i32vec4",I32VEC4},
+    {"uint32_t",UINT32_T},
+    {"u32vec2",U32VEC2},
+    {"u32vec3",U32VEC3},
+    {"u32vec4",U32VEC4},
+
+    {"float16_t",FLOAT16_T},
+    {"f16vec2",F16VEC2},
+    {"f16vec3",F16VEC3},
+    {"f16vec4",F16VEC4},
+    {"f16mat2",F16MAT2},
+    {"f16mat3",F16MAT3},
+    {"f16mat4",F16MAT4},
+    {"f16mat2x2",F16MAT2X2},
+    {"f16mat2x3",F16MAT2X3},
+    {"f16mat2x4",F16MAT2X4},
+    {"f16mat3x2",F16MAT3X2},
+    {"f16mat3x3",F16MAT3X3},
+    {"f16mat3x4",F16MAT3X4},
+    {"f16mat4x2",F16MAT4X2},
+    {"f16mat4x3",F16MAT4X3},
+    {"f16mat4x4",F16MAT4X4},
+
+    {"float32_t",FLOAT32_T},
+    {"f32vec2",F32VEC2},
+    {"f32vec3",F32VEC3},
+    {"f32vec4",F32VEC4},
+    {"f32mat2",F32MAT2},
+    {"f32mat3",F32MAT3},
+    {"f32mat4",F32MAT4},
+    {"f32mat2x2",F32MAT2X2},
+    {"f32mat2x3",F32MAT2X3},
+    {"f32mat2x4",F32MAT2X4},
+    {"f32mat3x2",F32MAT3X2},
+    {"f32mat3x3",F32MAT3X3},
+    {"f32mat3x4",F32MAT3X4},
+    {"f32mat4x2",F32MAT4X2},
+    {"f32mat4x3",F32MAT4X3},
+    {"f32mat4x4",F32MAT4X4},
+    {"float64_t",FLOAT64_T},
+    {"f64vec2",F64VEC2},
+    {"f64vec3",F64VEC3},
+    {"f64vec4",F64VEC4},
+    {"f64mat2",F64MAT2},
+    {"f64mat3",F64MAT3},
+    {"f64mat4",F64MAT4},
+    {"f64mat2x2",F64MAT2X2},
+    {"f64mat2x3",F64MAT2X3},
+    {"f64mat2x4",F64MAT2X4},
+    {"f64mat3x2",F64MAT3X2},
+    {"f64mat3x3",F64MAT3X3},
+    {"f64mat3x4",F64MAT3X4},
+    {"f64mat4x2",F64MAT4X2},
+    {"f64mat4x3",F64MAT4X3},
+    {"f64mat4x4",F64MAT4X4},
 
     // GL_EXT_spirv_intrinsics
-    (*KeywordMap)["spirv_instruction"] =       SPIRV_INSTRUCTION;
-    (*KeywordMap)["spirv_execution_mode"] =    SPIRV_EXECUTION_MODE;
-    (*KeywordMap)["spirv_execution_mode_id"] = SPIRV_EXECUTION_MODE_ID;
-    (*KeywordMap)["spirv_decorate"] =          SPIRV_DECORATE;
-    (*KeywordMap)["spirv_decorate_id"] =       SPIRV_DECORATE_ID;
-    (*KeywordMap)["spirv_decorate_string"] =   SPIRV_DECORATE_STRING;
-    (*KeywordMap)["spirv_type"] =              SPIRV_TYPE;
-    (*KeywordMap)["spirv_storage_class"] =     SPIRV_STORAGE_CLASS;
-    (*KeywordMap)["spirv_by_reference"] =      SPIRV_BY_REFERENCE;
-    (*KeywordMap)["spirv_literal"] =           SPIRV_LITERAL;
-
-    (*KeywordMap)["sampler2D"] =               SAMPLER2D;
-    (*KeywordMap)["samplerCube"] =             SAMPLERCUBE;
-    (*KeywordMap)["samplerCubeShadow"] =       SAMPLERCUBESHADOW;
-    (*KeywordMap)["sampler2DArray"] =          SAMPLER2DARRAY;
-    (*KeywordMap)["sampler2DArrayShadow"] =    SAMPLER2DARRAYSHADOW;
-    (*KeywordMap)["isampler2D"] =              ISAMPLER2D;
-    (*KeywordMap)["isampler3D"] =              ISAMPLER3D;
-    (*KeywordMap)["isamplerCube"] =            ISAMPLERCUBE;
-    (*KeywordMap)["isampler2DArray"] =         ISAMPLER2DARRAY;
-    (*KeywordMap)["usampler2D"] =              USAMPLER2D;
-    (*KeywordMap)["usampler3D"] =              USAMPLER3D;
-    (*KeywordMap)["usamplerCube"] =            USAMPLERCUBE;
-    (*KeywordMap)["usampler2DArray"] =         USAMPLER2DARRAY;
-    (*KeywordMap)["sampler3D"] =               SAMPLER3D;
-    (*KeywordMap)["sampler2DShadow"] =         SAMPLER2DSHADOW;
-
-    (*KeywordMap)["texture2D"] =               TEXTURE2D;
-    (*KeywordMap)["textureCube"] =             TEXTURECUBE;
-    (*KeywordMap)["texture2DArray"] =          TEXTURE2DARRAY;
-    (*KeywordMap)["itexture2D"] =              ITEXTURE2D;
-    (*KeywordMap)["itexture3D"] =              ITEXTURE3D;
-    (*KeywordMap)["itextureCube"] =            ITEXTURECUBE;
-    (*KeywordMap)["itexture2DArray"] =         ITEXTURE2DARRAY;
-    (*KeywordMap)["utexture2D"] =              UTEXTURE2D;
-    (*KeywordMap)["utexture3D"] =              UTEXTURE3D;
-    (*KeywordMap)["utextureCube"] =            UTEXTURECUBE;
-    (*KeywordMap)["utexture2DArray"] =         UTEXTURE2DARRAY;
-    (*KeywordMap)["texture3D"] =               TEXTURE3D;
-
-    (*KeywordMap)["sampler"] =                 SAMPLER;
-    (*KeywordMap)["samplerShadow"] =           SAMPLERSHADOW;
-
-    (*KeywordMap)["textureCubeArray"] =        TEXTURECUBEARRAY;
-    (*KeywordMap)["itextureCubeArray"] =       ITEXTURECUBEARRAY;
-    (*KeywordMap)["utextureCubeArray"] =       UTEXTURECUBEARRAY;
-    (*KeywordMap)["samplerCubeArray"] =        SAMPLERCUBEARRAY;
-    (*KeywordMap)["samplerCubeArrayShadow"] =  SAMPLERCUBEARRAYSHADOW;
-    (*KeywordMap)["isamplerCubeArray"] =       ISAMPLERCUBEARRAY;
-    (*KeywordMap)["usamplerCubeArray"] =       USAMPLERCUBEARRAY;
-    (*KeywordMap)["sampler1DArrayShadow"] =    SAMPLER1DARRAYSHADOW;
-    (*KeywordMap)["isampler1DArray"] =         ISAMPLER1DARRAY;
-    (*KeywordMap)["usampler1D"] =              USAMPLER1D;
-    (*KeywordMap)["isampler1D"] =              ISAMPLER1D;
-    (*KeywordMap)["usampler1DArray"] =         USAMPLER1DARRAY;
-    (*KeywordMap)["samplerBuffer"] =           SAMPLERBUFFER;
-    (*KeywordMap)["isampler2DRect"] =          ISAMPLER2DRECT;
-    (*KeywordMap)["usampler2DRect"] =          USAMPLER2DRECT;
-    (*KeywordMap)["isamplerBuffer"] =          ISAMPLERBUFFER;
-    (*KeywordMap)["usamplerBuffer"] =          USAMPLERBUFFER;
-    (*KeywordMap)["sampler2DMS"] =             SAMPLER2DMS;
-    (*KeywordMap)["isampler2DMS"] =            ISAMPLER2DMS;
-    (*KeywordMap)["usampler2DMS"] =            USAMPLER2DMS;
-    (*KeywordMap)["sampler2DMSArray"] =        SAMPLER2DMSARRAY;
-    (*KeywordMap)["isampler2DMSArray"] =       ISAMPLER2DMSARRAY;
-    (*KeywordMap)["usampler2DMSArray"] =       USAMPLER2DMSARRAY;
-    (*KeywordMap)["sampler1D"] =               SAMPLER1D;
-    (*KeywordMap)["sampler1DShadow"] =         SAMPLER1DSHADOW;
-    (*KeywordMap)["sampler2DRect"] =           SAMPLER2DRECT;
-    (*KeywordMap)["sampler2DRectShadow"] =     SAMPLER2DRECTSHADOW;
-    (*KeywordMap)["sampler1DArray"] =          SAMPLER1DARRAY;
-
-    (*KeywordMap)["samplerExternalOES"] =      SAMPLEREXTERNALOES; // GL_OES_EGL_image_external
-
-    (*KeywordMap)["__samplerExternal2DY2YEXT"] = SAMPLEREXTERNAL2DY2YEXT; // GL_EXT_YUV_target
-
-    (*KeywordMap)["itexture1DArray"] =         ITEXTURE1DARRAY;
-    (*KeywordMap)["utexture1D"] =              UTEXTURE1D;
-    (*KeywordMap)["itexture1D"] =              ITEXTURE1D;
-    (*KeywordMap)["utexture1DArray"] =         UTEXTURE1DARRAY;
-    (*KeywordMap)["textureBuffer"] =           TEXTUREBUFFER;
-    (*KeywordMap)["itexture2DRect"] =          ITEXTURE2DRECT;
-    (*KeywordMap)["utexture2DRect"] =          UTEXTURE2DRECT;
-    (*KeywordMap)["itextureBuffer"] =          ITEXTUREBUFFER;
-    (*KeywordMap)["utextureBuffer"] =          UTEXTUREBUFFER;
-    (*KeywordMap)["texture2DMS"] =             TEXTURE2DMS;
-    (*KeywordMap)["itexture2DMS"] =            ITEXTURE2DMS;
-    (*KeywordMap)["utexture2DMS"] =            UTEXTURE2DMS;
-    (*KeywordMap)["texture2DMSArray"] =        TEXTURE2DMSARRAY;
-    (*KeywordMap)["itexture2DMSArray"] =       ITEXTURE2DMSARRAY;
-    (*KeywordMap)["utexture2DMSArray"] =       UTEXTURE2DMSARRAY;
-    (*KeywordMap)["texture1D"] =               TEXTURE1D;
-    (*KeywordMap)["texture2DRect"] =           TEXTURE2DRECT;
-    (*KeywordMap)["texture1DArray"] =          TEXTURE1DARRAY;
-
-    (*KeywordMap)["attachmentEXT"] =           ATTACHMENTEXT;
-    (*KeywordMap)["iattachmentEXT"] =          IATTACHMENTEXT;
-    (*KeywordMap)["uattachmentEXT"] =          UATTACHMENTEXT;
-
-    (*KeywordMap)["subpassInput"] =            SUBPASSINPUT;
-    (*KeywordMap)["subpassInputMS"] =          SUBPASSINPUTMS;
-    (*KeywordMap)["isubpassInput"] =           ISUBPASSINPUT;
-    (*KeywordMap)["isubpassInputMS"] =         ISUBPASSINPUTMS;
-    (*KeywordMap)["usubpassInput"] =           USUBPASSINPUT;
-    (*KeywordMap)["usubpassInputMS"] =         USUBPASSINPUTMS;
-
-    (*KeywordMap)["f16sampler1D"] =                 F16SAMPLER1D;
-    (*KeywordMap)["f16sampler2D"] =                 F16SAMPLER2D;
-    (*KeywordMap)["f16sampler3D"] =                 F16SAMPLER3D;
-    (*KeywordMap)["f16sampler2DRect"] =             F16SAMPLER2DRECT;
-    (*KeywordMap)["f16samplerCube"] =               F16SAMPLERCUBE;
-    (*KeywordMap)["f16sampler1DArray"] =            F16SAMPLER1DARRAY;
-    (*KeywordMap)["f16sampler2DArray"] =            F16SAMPLER2DARRAY;
-    (*KeywordMap)["f16samplerCubeArray"] =          F16SAMPLERCUBEARRAY;
-    (*KeywordMap)["f16samplerBuffer"] =             F16SAMPLERBUFFER;
-    (*KeywordMap)["f16sampler2DMS"] =               F16SAMPLER2DMS;
-    (*KeywordMap)["f16sampler2DMSArray"] =          F16SAMPLER2DMSARRAY;
-    (*KeywordMap)["f16sampler1DShadow"] =           F16SAMPLER1DSHADOW;
-    (*KeywordMap)["f16sampler2DShadow"] =           F16SAMPLER2DSHADOW;
-    (*KeywordMap)["f16sampler2DRectShadow"] =       F16SAMPLER2DRECTSHADOW;
-    (*KeywordMap)["f16samplerCubeShadow"] =         F16SAMPLERCUBESHADOW;
-    (*KeywordMap)["f16sampler1DArrayShadow"] =      F16SAMPLER1DARRAYSHADOW;
-    (*KeywordMap)["f16sampler2DArrayShadow"] =      F16SAMPLER2DARRAYSHADOW;
-    (*KeywordMap)["f16samplerCubeArrayShadow"] =    F16SAMPLERCUBEARRAYSHADOW;
-
-    (*KeywordMap)["f16image1D"] =                   F16IMAGE1D;
-    (*KeywordMap)["f16image2D"] =                   F16IMAGE2D;
-    (*KeywordMap)["f16image3D"] =                   F16IMAGE3D;
-    (*KeywordMap)["f16image2DRect"] =               F16IMAGE2DRECT;
-    (*KeywordMap)["f16imageCube"] =                 F16IMAGECUBE;
-    (*KeywordMap)["f16image1DArray"] =              F16IMAGE1DARRAY;
-    (*KeywordMap)["f16image2DArray"] =              F16IMAGE2DARRAY;
-    (*KeywordMap)["f16imageCubeArray"] =            F16IMAGECUBEARRAY;
-    (*KeywordMap)["f16imageBuffer"] =               F16IMAGEBUFFER;
-    (*KeywordMap)["f16image2DMS"] =                 F16IMAGE2DMS;
-    (*KeywordMap)["f16image2DMSArray"] =            F16IMAGE2DMSARRAY;
-
-    (*KeywordMap)["f16texture1D"] =                 F16TEXTURE1D;
-    (*KeywordMap)["f16texture2D"] =                 F16TEXTURE2D;
-    (*KeywordMap)["f16texture3D"] =                 F16TEXTURE3D;
-    (*KeywordMap)["f16texture2DRect"] =             F16TEXTURE2DRECT;
-    (*KeywordMap)["f16textureCube"] =               F16TEXTURECUBE;
-    (*KeywordMap)["f16texture1DArray"] =            F16TEXTURE1DARRAY;
-    (*KeywordMap)["f16texture2DArray"] =            F16TEXTURE2DARRAY;
-    (*KeywordMap)["f16textureCubeArray"] =          F16TEXTURECUBEARRAY;
-    (*KeywordMap)["f16textureBuffer"] =             F16TEXTUREBUFFER;
-    (*KeywordMap)["f16texture2DMS"] =               F16TEXTURE2DMS;
-    (*KeywordMap)["f16texture2DMSArray"] =          F16TEXTURE2DMSARRAY;
-
-    (*KeywordMap)["f16subpassInput"] =              F16SUBPASSINPUT;
-    (*KeywordMap)["f16subpassInputMS"] =            F16SUBPASSINPUTMS;
-    (*KeywordMap)["__explicitInterpAMD"] =     EXPLICITINTERPAMD;
-    (*KeywordMap)["pervertexNV"] =             PERVERTEXNV;
-    (*KeywordMap)["pervertexEXT"] =            PERVERTEXEXT;
-    (*KeywordMap)["precise"] =                 PRECISE;
-
-    (*KeywordMap)["rayPayloadNV"] =            PAYLOADNV;
-    (*KeywordMap)["rayPayloadEXT"] =           PAYLOADEXT;
-    (*KeywordMap)["rayPayloadInNV"] =          PAYLOADINNV;
-    (*KeywordMap)["rayPayloadInEXT"] =         PAYLOADINEXT;
-    (*KeywordMap)["hitAttributeNV"] =          HITATTRNV;
-    (*KeywordMap)["hitAttributeEXT"] =         HITATTREXT;
-    (*KeywordMap)["callableDataNV"] =          CALLDATANV;
-    (*KeywordMap)["callableDataEXT"] =         CALLDATAEXT;
-    (*KeywordMap)["callableDataInNV"] =        CALLDATAINNV;
-    (*KeywordMap)["callableDataInEXT"] =       CALLDATAINEXT;
-    (*KeywordMap)["accelerationStructureNV"] = ACCSTRUCTNV;
-    (*KeywordMap)["accelerationStructureEXT"]   = ACCSTRUCTEXT;
-    (*KeywordMap)["rayQueryEXT"] =              RAYQUERYEXT;
-    (*KeywordMap)["perprimitiveNV"] =          PERPRIMITIVENV;
-    (*KeywordMap)["perviewNV"] =               PERVIEWNV;
-    (*KeywordMap)["taskNV"] =                  PERTASKNV;
-    (*KeywordMap)["perprimitiveEXT"] =         PERPRIMITIVEEXT;
-    (*KeywordMap)["taskPayloadSharedEXT"] =    TASKPAYLOADWORKGROUPEXT;
-
-    (*KeywordMap)["fcoopmatNV"] =              FCOOPMATNV;
-    (*KeywordMap)["icoopmatNV"] =              ICOOPMATNV;
-    (*KeywordMap)["ucoopmatNV"] =              UCOOPMATNV;
-
-    (*KeywordMap)["coopmat"] =                 COOPMAT;
-
-    (*KeywordMap)["hitObjectNV"] =             HITOBJECTNV;
-    (*KeywordMap)["hitObjectAttributeNV"] =    HITOBJECTATTRNV;
-
-    ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
-
-    ReservedSet->insert("common");
-    ReservedSet->insert("partition");
-    ReservedSet->insert("active");
-    ReservedSet->insert("asm");
-    ReservedSet->insert("class");
-    ReservedSet->insert("union");
-    ReservedSet->insert("enum");
-    ReservedSet->insert("typedef");
-    ReservedSet->insert("template");
-    ReservedSet->insert("this");
-    ReservedSet->insert("goto");
-    ReservedSet->insert("inline");
-    ReservedSet->insert("noinline");
-    ReservedSet->insert("public");
-    ReservedSet->insert("static");
-    ReservedSet->insert("extern");
-    ReservedSet->insert("external");
-    ReservedSet->insert("interface");
-    ReservedSet->insert("long");
-    ReservedSet->insert("short");
-    ReservedSet->insert("half");
-    ReservedSet->insert("fixed");
-    ReservedSet->insert("unsigned");
-    ReservedSet->insert("input");
-    ReservedSet->insert("output");
-    ReservedSet->insert("hvec2");
-    ReservedSet->insert("hvec3");
-    ReservedSet->insert("hvec4");
-    ReservedSet->insert("fvec2");
-    ReservedSet->insert("fvec3");
-    ReservedSet->insert("fvec4");
-    ReservedSet->insert("sampler3DRect");
-    ReservedSet->insert("filter");
-    ReservedSet->insert("sizeof");
-    ReservedSet->insert("cast");
-    ReservedSet->insert("namespace");
-    ReservedSet->insert("using");
-}
+    {"spirv_instruction",SPIRV_INSTRUCTION},
+    {"spirv_execution_mode",SPIRV_EXECUTION_MODE},
+    {"spirv_execution_mode_id",SPIRV_EXECUTION_MODE_ID},
+    {"spirv_decorate",SPIRV_DECORATE},
+    {"spirv_decorate_id",SPIRV_DECORATE_ID},
+    {"spirv_decorate_string",SPIRV_DECORATE_STRING},
+    {"spirv_type",SPIRV_TYPE},
+    {"spirv_storage_class",SPIRV_STORAGE_CLASS},
+    {"spirv_by_reference",SPIRV_BY_REFERENCE},
+    {"spirv_literal",SPIRV_LITERAL},
+
+    {"sampler2D",SAMPLER2D},
+    {"samplerCube",SAMPLERCUBE},
+    {"samplerCubeShadow",SAMPLERCUBESHADOW},
+    {"sampler2DArray",SAMPLER2DARRAY},
+    {"sampler2DArrayShadow",SAMPLER2DARRAYSHADOW},
+    {"isampler2D",ISAMPLER2D},
+    {"isampler3D",ISAMPLER3D},
+    {"isamplerCube",ISAMPLERCUBE},
+    {"isampler2DArray",ISAMPLER2DARRAY},
+    {"usampler2D",USAMPLER2D},
+    {"usampler3D",USAMPLER3D},
+    {"usamplerCube",USAMPLERCUBE},
+    {"usampler2DArray",USAMPLER2DARRAY},
+    {"sampler3D",SAMPLER3D},
+    {"sampler2DShadow",SAMPLER2DSHADOW},
+
+    {"texture2D",TEXTURE2D},
+    {"textureCube",TEXTURECUBE},
+    {"texture2DArray",TEXTURE2DARRAY},
+    {"itexture2D",ITEXTURE2D},
+    {"itexture3D",ITEXTURE3D},
+    {"itextureCube",ITEXTURECUBE},
+    {"itexture2DArray",ITEXTURE2DARRAY},
+    {"utexture2D",UTEXTURE2D},
+    {"utexture3D",UTEXTURE3D},
+    {"utextureCube",UTEXTURECUBE},
+    {"utexture2DArray",UTEXTURE2DARRAY},
+    {"texture3D",TEXTURE3D},
+
+    {"sampler",SAMPLER},
+    {"samplerShadow",SAMPLERSHADOW},
+
+    {"textureCubeArray",TEXTURECUBEARRAY},
+    {"itextureCubeArray",ITEXTURECUBEARRAY},
+    {"utextureCubeArray",UTEXTURECUBEARRAY},
+    {"samplerCubeArray",SAMPLERCUBEARRAY},
+    {"samplerCubeArrayShadow",SAMPLERCUBEARRAYSHADOW},
+    {"isamplerCubeArray",ISAMPLERCUBEARRAY},
+    {"usamplerCubeArray",USAMPLERCUBEARRAY},
+    {"sampler1DArrayShadow",SAMPLER1DARRAYSHADOW},
+    {"isampler1DArray",ISAMPLER1DARRAY},
+    {"usampler1D",USAMPLER1D},
+    {"isampler1D",ISAMPLER1D},
+    {"usampler1DArray",USAMPLER1DARRAY},
+    {"samplerBuffer",SAMPLERBUFFER},
+    {"isampler2DRect",ISAMPLER2DRECT},
+    {"usampler2DRect",USAMPLER2DRECT},
+    {"isamplerBuffer",ISAMPLERBUFFER},
+    {"usamplerBuffer",USAMPLERBUFFER},
+    {"sampler2DMS",SAMPLER2DMS},
+    {"isampler2DMS",ISAMPLER2DMS},
+    {"usampler2DMS",USAMPLER2DMS},
+    {"sampler2DMSArray",SAMPLER2DMSARRAY},
+    {"isampler2DMSArray",ISAMPLER2DMSARRAY},
+    {"usampler2DMSArray",USAMPLER2DMSARRAY},
+    {"sampler1D",SAMPLER1D},
+    {"sampler1DShadow",SAMPLER1DSHADOW},
+    {"sampler2DRect",SAMPLER2DRECT},
+    {"sampler2DRectShadow",SAMPLER2DRECTSHADOW},
+    {"sampler1DArray",SAMPLER1DARRAY},
+
+    {"samplerExternalOES",     SAMPLEREXTERNALOES}, // GL_OES_EGL_image_external
+    {"__samplerExternal2DY2YEXT", SAMPLEREXTERNAL2DY2YEXT}, // GL_EXT_YUV_target
+
+    {"itexture1DArray",ITEXTURE1DARRAY},
+    {"utexture1D",UTEXTURE1D},
+    {"itexture1D",ITEXTURE1D},
+    {"utexture1DArray",UTEXTURE1DARRAY},
+    {"textureBuffer",TEXTUREBUFFER},
+    {"itexture2DRect",ITEXTURE2DRECT},
+    {"utexture2DRect",UTEXTURE2DRECT},
+    {"itextureBuffer",ITEXTUREBUFFER},
+    {"utextureBuffer",UTEXTUREBUFFER},
+    {"texture2DMS",TEXTURE2DMS},
+    {"itexture2DMS",ITEXTURE2DMS},
+    {"utexture2DMS",UTEXTURE2DMS},
+    {"texture2DMSArray",TEXTURE2DMSARRAY},
+    {"itexture2DMSArray",ITEXTURE2DMSARRAY},
+    {"utexture2DMSArray",UTEXTURE2DMSARRAY},
+    {"texture1D",TEXTURE1D},
+    {"texture2DRect",TEXTURE2DRECT},
+    {"texture1DArray",TEXTURE1DARRAY},
+
+    {"attachmentEXT",ATTACHMENTEXT},
+    {"iattachmentEXT",IATTACHMENTEXT},
+    {"uattachmentEXT",UATTACHMENTEXT},
+
+    {"subpassInput",SUBPASSINPUT},
+    {"subpassInputMS",SUBPASSINPUTMS},
+    {"isubpassInput",ISUBPASSINPUT},
+    {"isubpassInputMS",ISUBPASSINPUTMS},
+    {"usubpassInput",USUBPASSINPUT},
+    {"usubpassInputMS",USUBPASSINPUTMS},
+
+    {"f16sampler1D",F16SAMPLER1D},
+    {"f16sampler2D",F16SAMPLER2D},
+    {"f16sampler3D",F16SAMPLER3D},
+    {"f16sampler2DRect",F16SAMPLER2DRECT},
+    {"f16samplerCube",F16SAMPLERCUBE},
+    {"f16sampler1DArray",F16SAMPLER1DARRAY},
+    {"f16sampler2DArray",F16SAMPLER2DARRAY},
+    {"f16samplerCubeArray",F16SAMPLERCUBEARRAY},
+    {"f16samplerBuffer",F16SAMPLERBUFFER},
+    {"f16sampler2DMS",F16SAMPLER2DMS},
+    {"f16sampler2DMSArray",F16SAMPLER2DMSARRAY},
+    {"f16sampler1DShadow",F16SAMPLER1DSHADOW},
+    {"f16sampler2DShadow",F16SAMPLER2DSHADOW},
+    {"f16sampler2DRectShadow",F16SAMPLER2DRECTSHADOW},
+    {"f16samplerCubeShadow",F16SAMPLERCUBESHADOW},
+    {"f16sampler1DArrayShadow",F16SAMPLER1DARRAYSHADOW},
+    {"f16sampler2DArrayShadow",F16SAMPLER2DARRAYSHADOW},
+    {"f16samplerCubeArrayShadow",F16SAMPLERCUBEARRAYSHADOW},
+
+    {"f16image1D",F16IMAGE1D},
+    {"f16image2D",F16IMAGE2D},
+    {"f16image3D",F16IMAGE3D},
+    {"f16image2DRect",F16IMAGE2DRECT},
+    {"f16imageCube",F16IMAGECUBE},
+    {"f16image1DArray",F16IMAGE1DARRAY},
+    {"f16image2DArray",F16IMAGE2DARRAY},
+    {"f16imageCubeArray",F16IMAGECUBEARRAY},
+    {"f16imageBuffer",F16IMAGEBUFFER},
+    {"f16image2DMS",F16IMAGE2DMS},
+    {"f16image2DMSArray",F16IMAGE2DMSARRAY},
+
+    {"f16texture1D",F16TEXTURE1D},
+    {"f16texture2D",F16TEXTURE2D},
+    {"f16texture3D",F16TEXTURE3D},
+    {"f16texture2DRect",F16TEXTURE2DRECT},
+    {"f16textureCube",F16TEXTURECUBE},
+    {"f16texture1DArray",F16TEXTURE1DARRAY},
+    {"f16texture2DArray",F16TEXTURE2DARRAY},
+    {"f16textureCubeArray",F16TEXTURECUBEARRAY},
+    {"f16textureBuffer",F16TEXTUREBUFFER},
+    {"f16texture2DMS",F16TEXTURE2DMS},
+    {"f16texture2DMSArray",F16TEXTURE2DMSARRAY},
+
+    {"f16subpassInput",F16SUBPASSINPUT},
+    {"f16subpassInputMS",F16SUBPASSINPUTMS},
+    {"__explicitInterpAMD",EXPLICITINTERPAMD},
+    {"pervertexNV",PERVERTEXNV},
+    {"pervertexEXT",PERVERTEXEXT},
+    {"precise",PRECISE},
+
+    {"rayPayloadNV",PAYLOADNV},
+    {"rayPayloadEXT",PAYLOADEXT},
+    {"rayPayloadInNV",PAYLOADINNV},
+    {"rayPayloadInEXT",PAYLOADINEXT},
+    {"hitAttributeNV",HITATTRNV},
+    {"hitAttributeEXT",HITATTREXT},
+    {"callableDataNV",CALLDATANV},
+    {"callableDataEXT",CALLDATAEXT},
+    {"callableDataInNV",CALLDATAINNV},
+    {"callableDataInEXT",CALLDATAINEXT},
+    {"accelerationStructureNV",ACCSTRUCTNV},
+    {"accelerationStructureEXT",ACCSTRUCTEXT},
+    {"rayQueryEXT",RAYQUERYEXT},
+    {"perprimitiveNV",PERPRIMITIVENV},
+    {"perviewNV",PERVIEWNV},
+    {"taskNV",PERTASKNV},
+    {"perprimitiveEXT",PERPRIMITIVEEXT},
+    {"taskPayloadSharedEXT",TASKPAYLOADWORKGROUPEXT},
+
+    {"fcoopmatNV",FCOOPMATNV},
+    {"icoopmatNV",ICOOPMATNV},
+    {"ucoopmatNV",UCOOPMATNV},
+
+    {"coopmat",COOPMAT},
+
+    {"hitObjectNV",HITOBJECTNV},
+    {"hitObjectAttributeNV",HITOBJECTATTRNV},
+};
+const std::unordered_set<const char*, str_hash, str_eq> ReservedSet {
+    "common",
+    "partition",
+    "active",
+    "asm",
+    "class",
+    "union",
+    "enum",
+    "typedef",
+    "template",
+    "this",
+    "goto",
+    "inline",
+    "noinline",
+    "public",
+    "static",
+    "extern",
+    "external",
+    "interface",
+    "long",
+    "short",
+    "half",
+    "fixed",
+    "unsigned",
+    "input",
+    "output",
+    "hvec2",
+    "hvec3",
+    "hvec4",
+    "fvec2",
+    "fvec3",
+    "fvec4",
+    "sampler3DRect",
+    "filter",
+    "sizeof",
+    "cast",
+    "namespace",
+    "using",
+};
 
-void TScanContext::deleteKeywordMap()
-{
-    delete KeywordMap;
-    KeywordMap = nullptr;
-    delete ReservedSet;
-    ReservedSet = nullptr;
 }
 
+namespace glslang {
+
 // Called by yylex to get the next token.
 // Returning 0 implies end of input.
 int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
@@ -924,11 +902,11 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
 
 int TScanContext::tokenizeIdentifier()
 {
-    if (ReservedSet->find(tokenText) != ReservedSet->end())
+    if (ReservedSet.find(tokenText) != ReservedSet.end())
         return reservedWord();
 
-    auto it = KeywordMap->find(tokenText);
-    if (it == KeywordMap->end()) {
+    auto it = KeywordMap.find(tokenText);
+    if (it == KeywordMap.end()) {
         // Should have an identifier of some sort
         return identifierOrType();
     }

+ 60 - 37
3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp

@@ -297,18 +297,21 @@ int CommonIndex(EProfile profile, EShLanguage language)
 //
 // To initialize per-stage shared tables, with the common table already complete.
 //
-void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int version, EProfile profile, const SpvVersion& spvVersion,
+bool InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int version, EProfile profile, const SpvVersion& spvVersion,
                                 EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable,
                                 TSymbolTable** symbolTables)
 {
     (*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]);
-    InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source,
-                          infoSink, *symbolTables[language]);
+    if (!InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source,
+                          infoSink, *symbolTables[language]))
+        return false;
     builtInParseables.identifyBuiltIns(version, profile, spvVersion, language, *symbolTables[language]);
     if (profile == EEsProfile && version >= 300)
         (*symbolTables[language]).setNoBuiltInRedeclarations();
     if (version == 110)
         (*symbolTables[language]).setSeparateNameSpaces();
+
+    return true;
 }
 
 //
@@ -317,6 +320,7 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi
 //
 bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable,  TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
 {
+    bool success = true;
     std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
 
     if (builtInParseables == nullptr)
@@ -325,70 +329,70 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable,  TS
     builtInParseables->initialize(version, profile, spvVersion);
 
     // do the common tables
-    InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangVertex, source,
+    success &= InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangVertex, source,
                           infoSink, *commonTable[EPcGeneral]);
     if (profile == EEsProfile)
-        InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangFragment, source,
+        success &= InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangFragment, source,
                               infoSink, *commonTable[EPcFragment]);
 
     // do the per-stage tables
 
     // always have vertex and fragment
-    InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangVertex, source,
+    success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangVertex, source,
                                infoSink, commonTable, symbolTables);
-    InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source,
+    success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source,
                                infoSink, commonTable, symbolTables);
 
     // check for tessellation
     if ((profile != EEsProfile && version >= 150) ||
         (profile == EEsProfile && version >= 310)) {
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessControl, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessControl, source,
                                    infoSink, commonTable, symbolTables);
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessEvaluation, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessEvaluation, source,
                                    infoSink, commonTable, symbolTables);
     }
 
     // check for geometry
     if ((profile != EEsProfile && version >= 150) ||
         (profile == EEsProfile && version >= 310))
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source,
                                    infoSink, commonTable, symbolTables);
 
     // check for compute
     if ((profile != EEsProfile && version >= 420) ||
         (profile == EEsProfile && version >= 310))
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
                                    infoSink, commonTable, symbolTables);
 
     // check for ray tracing stages
     if (profile != EEsProfile && version >= 450) {
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGen, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGen, source,
             infoSink, commonTable, symbolTables);
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersect, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersect, source,
             infoSink, commonTable, symbolTables);
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHit, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHit, source,
             infoSink, commonTable, symbolTables);
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHit, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHit, source,
             infoSink, commonTable, symbolTables);
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMiss, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMiss, source,
             infoSink, commonTable, symbolTables);
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallable, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallable, source,
             infoSink, commonTable, symbolTables);
     }
 
     // check for mesh
     if ((profile != EEsProfile && version >= 450) ||
         (profile == EEsProfile && version >= 320))
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMesh, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMesh, source,
                                    infoSink, commonTable, symbolTables);
 
     // check for task
     if ((profile != EEsProfile && version >= 450) ||
         (profile == EEsProfile && version >= 320))
-        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTask, source,
+        success &= InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTask, source,
                                    infoSink, commonTable, symbolTables);
 
-    return true;
+    return success;
 }
 
 bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable& symbolTable, int version,
@@ -400,7 +404,8 @@ bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& inf
         return false;
 
     builtInParseables->initialize(*resources, version, profile, spvVersion, language);
-    InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, language, source, infoSink, symbolTable);
+    if (!InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, language, source, infoSink, symbolTable))
+        return false;
     builtInParseables->identifyBuiltIns(version, profile, spvVersion, language, symbolTable, *resources);
 
     return true;
@@ -418,9 +423,10 @@ bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& inf
 // This only gets done the first time any thread needs a particular symbol table
 // (lazy evaluation).
 //
-void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
+bool SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
 {
     TInfoSink infoSink;
+    bool success;
 
     // Make sure only one thread tries to do this at a time
 #ifndef DISABLE_THREAD_SUPPORT
@@ -432,8 +438,9 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
     int spvVersionIndex = MapSpvVersionToIndex(spvVersion);
     int profileIndex = MapProfileToIndex(profile);
     int sourceIndex = MapSourceToIndex(source);
-    if (CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][EPcGeneral])
-        return;
+    if (CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][EPcGeneral]) {
+        return true;
+    }
 
     // Switch to a new pool
     TPoolAllocator& previousAllocator = GetThreadPoolAllocator();
@@ -449,7 +456,10 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
         stageTables[stage] = new TSymbolTable;
 
     // Generate the local symbol tables using the new pool
-    InitializeSymbolTables(infoSink, commonTable, stageTables, version, profile, spvVersion, source);
+    if (!InitializeSymbolTables(infoSink, commonTable, stageTables, version, profile, spvVersion, source)) {
+        success = false;
+        goto cleanup;
+    }
 
     // Switch to the process-global pool
     SetThreadPoolAllocator(PerProcessGPA);
@@ -471,7 +481,9 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
             SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->readOnly();
         }
     }
+    success = true;
 
+cleanup:
     // Clean up the local tables before deleting the pool they used.
     for (int precClass = 0; precClass < EPcCount; ++precClass)
         delete commonTable[precClass];
@@ -480,6 +492,8 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
 
     delete builtInPoolAllocator;
     SetThreadPoolAllocator(&previousAllocator);
+
+    return success;
 }
 
 // Function to Print all builtins
@@ -915,7 +929,9 @@ bool ProcessDeferred(
             intermediate.addSourceText(strings[numPre + s], lengths[numPre + s]);
         }
     }
-    SetupBuiltinSymbolTable(version, profile, spvVersion, source);
+    if (!SetupBuiltinSymbolTable(version, profile, spvVersion, source)) {
+        return false;
+    }
 
     TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
                                                   [MapSpvVersionToIndex(spvVersion)]
@@ -1324,11 +1340,6 @@ int ShInitialize()
     if (PerProcessGPA == nullptr)
         PerProcessGPA = new TPoolAllocator();
 
-    glslang::TScanContext::fillInKeywordMap();
-#ifdef ENABLE_HLSL
-    glslang::HlslScanContext::fillInKeywordMap();
-#endif
-
     return 1;
 }
 
@@ -1417,11 +1428,6 @@ int ShFinalize()
         PerProcessGPA = nullptr;
     }
 
-    glslang::TScanContext::deleteKeywordMap();
-#ifdef ENABLE_HLSL
-    glslang::HlslScanContext::deleteKeywordMap();
-#endif
-
     return 1;
 }
 
@@ -1726,6 +1732,10 @@ public:
     virtual bool compile(TIntermNode*, int = 0, EProfile = ENoProfile) { return true; }
 };
 
+TIoMapper* GetGlslIoMapper() {
+    return static_cast<TIoMapper*>(new TGlslIoMapper());
+}
+
 TShader::TShader(EShLanguage s)
     : stage(s), lengths(nullptr), stringNames(nullptr), preamble(""), overrideVersion(0)
 {
@@ -2045,7 +2055,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
 //
 // Return true if no errors.
 //
-bool TProgram::crossStageCheck(EShMessages) {
+bool TProgram::crossStageCheck(EShMessages messages) {
 
     // make temporary intermediates to hold the linkage symbols for each linking interface
     // while we do the checks
@@ -2100,6 +2110,13 @@ bool TProgram::crossStageCheck(EShMessages) {
         error |= (activeStages[i - 1]->getNumErrors() != 0);
     }
 
+    // if requested, optimize cross stage IO
+    if (messages & EShMsgLinkTimeOptimization) {
+        for (unsigned int i = 1; i < activeStages.size(); ++i) {
+            activeStages[i - 1]->optimizeStageIO(*infoSink, *activeStages[i]);
+        }
+    }
+
     return !error;
 }
 
@@ -2174,6 +2191,12 @@ int TProgram::getNumAtomicCounters() const                            { return r
 const TObjectReflection& TProgram::getAtomicCounter(int index) const  { return reflection->getAtomicCounter(index); }
 void TProgram::dumpReflection() { if (reflection != nullptr) reflection->dump(); }
 
+TIoMapResolver* TProgram::getGlslIoResolver(EShLanguage stage) {
+    auto *intermediate = getIntermediate(stage);
+    if (!intermediate)
+        return NULL;
+    return static_cast<TIoMapResolver*>(new TDefaultGlslIoResolver(*intermediate));
+}
 //
 // I/O mapping implementation.
 //

+ 1 - 1
3rdparty/glslang/glslang/MachineIndependent/SymbolTable.cpp

@@ -169,7 +169,7 @@ void TType::buildMangledName(TString& mangledName) const
                 if (arraySizes->getDimNode(i)->getAsSymbolNode())
                     snprintf(buf, maxSize, "s%lld", arraySizes->getDimNode(i)->getAsSymbolNode()->getId());
                 else
-                    snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i));
+                    snprintf(buf, maxSize, "s%p", (void*)(arraySizes->getDimNode(i)));
             } else
                 snprintf(buf, maxSize, "%d", arraySizes->getDimSize(i));
             mangledName += '[';

+ 6 - 2
3rdparty/glslang/glslang/MachineIndependent/glslang.y

@@ -3773,8 +3773,10 @@ compound_statement
         --parseContext.statementNestingLevel;
     }
       RIGHT_BRACE {
-        if ($3 && $3->getAsAggregate())
+        if ($3 && $3->getAsAggregate()) {
             $3->getAsAggregate()->setOperator(parseContext.intermediate.getDebugInfo() ? EOpScope : EOpSequence);
+            $3->getAsAggregate()->setEndLoc($5.loc);
+        }
         $$ = $3;
     }
     ;
@@ -3810,8 +3812,10 @@ compound_statement_no_new_scope
         $$ = 0;
     }
     | LEFT_BRACE statement_list RIGHT_BRACE {
-        if ($2 && $2->getAsAggregate())
+        if ($2 && $2->getAsAggregate()) {
             $2->getAsAggregate()->setOperator(EOpSequence);
+            $2->getAsAggregate()->setEndLoc($3.loc);
+        }
         $$ = $2;
     }
     ;

File diff suppressed because it is too large
+ 268 - 264
3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp


+ 2 - 11
3rdparty/glslang/glslang/MachineIndependent/iomapper.h

@@ -189,16 +189,6 @@ protected:
 
 typedef std::map<TString, TVarEntryInfo> TVarLiveMap;
 
-// I/O mapper
-class TIoMapper {
-public:
-    TIoMapper() {}
-    virtual ~TIoMapper() {}
-    // grow the reflection stage by stage
-    bool virtual addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*);
-    bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
-};
-
 // I/O mapper for GLSL
 class TGlslIoMapper : public TIoMapper {
 public:
@@ -206,10 +196,11 @@ public:
     virtual ~TGlslIoMapper();
     // If set, the uniform block with the given name will be changed to be backed by
     // push_constant if it's size is <= maxSize
-    void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) {
+    bool setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) override {
         autoPushConstantBlockName = name;
         autoPushConstantMaxSize = maxSize;
         autoPushConstantBlockPacking = packing;
+        return true;
     }
     // grow the reflection stage by stage
     bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;

+ 102 - 0
3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp

@@ -49,6 +49,7 @@
 #include "localintermediate.h"
 #include "../Include/InfoSink.h"
 #include "SymbolTable.h"
+#include "LiveTraverser.h"
 
 namespace glslang {
 
@@ -187,6 +188,107 @@ void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) {
     }
 }
 
+void TIntermediate::optimizeStageIO(TInfoSink&, TIntermediate& unit)
+{
+    // don't do any input/output demotion on compute, raytracing, or task/mesh stages
+    // TODO: support task/mesh
+    if (getStage() > EShLangFragment || unit.getStage() > EShLangFragment) {
+        return;
+    }
+
+    class TIOTraverser : public TLiveTraverser {
+    public:
+        TIOTraverser(TIntermediate& i, bool all, TIntermSequence& sequence, TStorageQualifier storage)
+            : TLiveTraverser(i, all, true, false, false), sequence(sequence), storage(storage)
+        {
+        }
+
+        virtual void visitSymbol(TIntermSymbol* symbol)
+        {
+            if (symbol->getQualifier().storage == storage) {
+                sequence.push_back(symbol);
+            }
+        }
+
+    private:
+        TIntermSequence& sequence;
+        TStorageQualifier storage;
+    };
+
+    // live symbols only
+    TIntermSequence unitLiveInputs;
+
+    TIOTraverser unitTraverser(unit, false, unitLiveInputs, EvqVaryingIn);
+    unitTraverser.pushFunction(unit.getEntryPointMangledName().c_str());
+    while (! unitTraverser.destinations.empty()) {
+        TIntermNode* destination = unitTraverser.destinations.back();
+        unitTraverser.destinations.pop_back();
+        destination->traverse(&unitTraverser);
+    }
+
+    TIntermSequence allOutputs;
+    TIntermSequence unitAllInputs;
+
+    TIOTraverser allTraverser(*this, true, allOutputs, EvqVaryingOut);
+    getTreeRoot()->traverse(&allTraverser);
+
+    TIOTraverser unitAllTraverser(unit, true, unitAllInputs, EvqVaryingIn);
+    unit.getTreeRoot()->traverse(&unitAllTraverser);
+
+    // find outputs not consumed by the next stage
+    std::for_each(allOutputs.begin(), allOutputs.end(), [&unitLiveInputs, &unitAllInputs](TIntermNode* output) {
+        // don't do anything to builtins
+        if (output->getAsSymbolNode()->getAccessName().compare(0, 3, "gl_") == 0)
+            return;
+
+        // don't demote block outputs (for now)
+        if (output->getAsSymbolNode()->getBasicType() == EbtBlock)
+            return;
+
+        // check if the (loose) output has a matching loose input
+        auto isMatchingInput = [output](TIntermNode* input) {
+            return output->getAsSymbolNode()->getAccessName() == input->getAsSymbolNode()->getAccessName();
+        };
+
+        // check if the (loose) output has a matching block member input
+        auto isMatchingInputBlockMember = [output](TIntermNode* input) {
+            // ignore loose inputs
+            if (input->getAsSymbolNode()->getBasicType() != EbtBlock)
+                return false;
+
+            // don't demote loose outputs with matching input block members
+            auto isMatchingBlockMember = [output](TTypeLoc type) {
+                return type.type->getFieldName() == output->getAsSymbolNode()->getName();
+            };
+            const TTypeList* members = input->getAsSymbolNode()->getType().getStruct();
+            return std::any_of(members->begin(), members->end(), isMatchingBlockMember);
+        };
+
+        // determine if the input/output pair should be demoted
+        // do the faster (and more likely) loose-loose check first
+        if (std::none_of(unitLiveInputs.begin(), unitLiveInputs.end(), isMatchingInput) && 
+            std::none_of(unitAllInputs.begin(), unitAllInputs.end(), isMatchingInputBlockMember)) {
+            // demote any input matching the output
+            auto demoteMatchingInputs = [output](TIntermNode* input) {
+                if (output->getAsSymbolNode()->getAccessName() == input->getAsSymbolNode()->getAccessName()) {
+                    // demote input to a plain variable
+                    TIntermSymbol* symbol = input->getAsSymbolNode();
+                    symbol->getQualifier().storage = EvqGlobal;
+                    symbol->getQualifier().clearInterstage();
+                    symbol->getQualifier().clearLayout();
+                }
+            };
+
+            // demote all matching outputs to a plain variable
+            TIntermSymbol* symbol = output->getAsSymbolNode();
+            symbol->getQualifier().storage = EvqGlobal;
+            symbol->getQualifier().clearInterstage();
+            symbol->getQualifier().clearLayout();
+            std::for_each(unitAllInputs.begin(), unitAllInputs.end(), demoteMatchingInputs);
+        }
+    });
+}
+
 void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
 {
     if (unit.getNumEntryPoints() > 0) {

+ 2 - 0
3rdparty/glslang/glslang/MachineIndependent/localintermediate.h

@@ -1051,6 +1051,7 @@ public:
     void mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly);
     void mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit);
     void checkStageIO(TInfoSink&, TIntermediate&);
+    void optimizeStageIO(TInfoSink&, TIntermediate&);
 
     bool buildConvertOp(TBasicType dst, TBasicType src, TOperator& convertOp) const;
     TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const;
@@ -1063,6 +1064,7 @@ public:
     int checkLocationRT(int set, int location);
     int addUsedOffsets(int binding, int offset, int numOffsets);
     bool addUsedConstantId(int id);
+    GLSLANG_EXPORT_FOR_TESTS
     static int computeTypeLocationSize(const TType&, EShLanguage);
     static int computeTypeUniformLocationSize(const TType&);
 

+ 4 - 2
3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp

@@ -241,6 +241,7 @@ int TPpContext::CPPundef(TPpToken* ppToken)
 */
 int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
 {
+    inElseSkip = true;
     int depth = 0;
     int token = scanToken(ppToken);
 
@@ -297,7 +298,7 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
                     elseSeen[elsetracker] = false;
                     --elsetracker;
                 }
-
+                inElseSkip = false;
                 return CPPif(ppToken);
             }
         } else if (nextAtom == PpAtomElse) {
@@ -311,7 +312,8 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
                 parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
         }
     }
-
+    
+    inElseSkip = false;
     return token;
 }
 

+ 2 - 1
3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp

@@ -88,7 +88,8 @@ TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, T
     preamble(nullptr), strings(nullptr), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false),
     rootFileName(rootFileName),
     currentSourceFile(rootFileName),
-    disableEscapeSequences(false)
+    disableEscapeSequences(false),
+    inElseSkip(false)
 {
     ifdepth = 0;
     for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)

+ 4 - 1
3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpContext.h

@@ -371,7 +371,7 @@ protected:
                 break;
             popInput();
         }
-        if (!inputStack.empty() && inputStack.back()->isStringInput()) {
+        if (!inputStack.empty() && inputStack.back()->isStringInput() && !inElseSkip) {
             if (token == '\n') {
                 bool seenNumSign = false;
                 for (int i = 0; i < (int)lastLineTokens.size() - 1;) {
@@ -732,6 +732,9 @@ protected:
 
     std::istringstream strtodStream;
     bool disableEscapeSequences;
+    // True if we're skipping a section enclosed by #if/#ifdef/#elif/#else which was evaluated to
+    // be inactive, e.g. #if 0
+    bool inElseSkip;
 };
 
 } // end namespace glslang

+ 2 - 1
3rdparty/glslang/glslang/MachineIndependent/propagateNoContraction.h

@@ -52,4 +52,5 @@ namespace glslang {
 // 'noContraction' means the object is 'precise'; and for arithmetic operation
 // nodes, it means the operation should not be contracted.
 void PropagateNoContraction(const glslang::TIntermediate& intermediate);
-};
+
+} // end namespace glslang

+ 3 - 2
3rdparty/glslang/glslang/MachineIndependent/reflection.h

@@ -37,8 +37,8 @@
 #define _REFLECTION_INCLUDED
 
 #include "../Public/ShaderLang.h"
-#include "../Include/Types.h"
-
+#include "../Include/BaseTypes.h"
+#include "../Include/visibility.h"
 #include <list>
 #include <set>
 
@@ -65,6 +65,7 @@ public:
     virtual ~TReflection() {}
 
     // grow the reflection stage by stage
+    GLSLANG_EXPORT_FOR_TESTS
     bool addStage(EShLanguage, const TIntermediate&);
 
     // for mapping a uniform index to a uniform object's description

+ 2 - 1
3rdparty/glslang/glslang/OSDependent/osinclude.h

@@ -35,9 +35,10 @@
 #ifndef __OSINCLUDE_H
 #define __OSINCLUDE_H
 
+#include "../Include/visibility.h"
 namespace glslang {
 
-void OS_DumpMemoryCounters();
+GLSLANG_EXPORT void OS_DumpMemoryCounters();
 
 } // end namespace glslang
 

+ 5 - 4
3rdparty/glslang/glslang/Public/ResourceLimits.h

@@ -38,20 +38,21 @@
 #include <string>
 
 #include "../Include/ResourceLimits.h"
+#include "../Include/visibility.h"
 
 // Return pointer to user-writable Resource to pass through API in
 // future-proof way.
-extern TBuiltInResource* GetResources();
+GLSLANG_EXPORT extern TBuiltInResource* GetResources();
 
 // These are the default resources for TBuiltInResources, used for both
 //  - parsing this string for the case where the user didn't supply one,
 //  - dumping out a template for user construction of a config file.
-extern const TBuiltInResource* GetDefaultResources();
+GLSLANG_EXPORT extern const TBuiltInResource* GetDefaultResources();
 
 // Returns the DefaultTBuiltInResource as a human-readable string.
-std::string GetDefaultTBuiltInResourceString();
+GLSLANG_EXPORT std::string GetDefaultTBuiltInResourceString();
 
 // Decodes the resource limits from |config| to |resources|.
-void DecodeResourceLimits(TBuiltInResource* resources, char* config);
+GLSLANG_EXPORT void DecodeResourceLimits(TBuiltInResource* resources, char* config);
 
 #endif  // _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_

+ 35 - 0
3rdparty/glslang/glslang/Public/ShaderLang.h

@@ -173,6 +173,21 @@ typedef enum {
     LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 7),
 } EShTargetLanguageVersion;
 
+//
+// Following are a series of helper enums for managing layouts and qualifiers,
+// used for TPublicType, TType, others.
+//
+
+enum TLayoutPacking {
+    ElpNone,
+    ElpShared, // default, but different than saying nothing
+    ElpStd140,
+    ElpStd430,
+    ElpPacked,
+    ElpScalar,
+    ElpCount // If expanding, see bitfield width below
+};
+
 struct TInputLanguage {
     EShSource languageFamily; // redundant information with other input, this one overrides when not EShSourceNone
     EShLanguage stage;        // redundant information with other input, this one overrides when not EShSourceNone
@@ -256,6 +271,7 @@ enum EShMessages : unsigned {
     EShMsgEnhanced             = (1 << 15), // enhanced message readability
     EShMsgAbsolutePath         = (1 << 16), // Output Absolute path for messages
     EShMsgDisplayErrorColumn   = (1 << 17), // Display error message column aswell as line
+    EShMsgLinkTimeOptimization = (1 << 18), // perform cross-stage optimizations during linking
     LAST_ELEMENT_MARKER(EShMsgCount),
 };
 
@@ -400,6 +416,7 @@ GLSLANG_EXPORT int GetKhronosToolId();
 class TIntermediate;
 class TProgram;
 class TPoolAllocator;
+class TIoMapResolver;
 
 // Call this exactly once per process before using anything else
 GLSLANG_EXPORT bool InitializeProcess();
@@ -838,6 +855,20 @@ public:
     virtual void addStage(EShLanguage stage, TIntermediate& stageIntermediate) = 0;
 };
 
+// I/O mapper
+class TIoMapper {
+public:
+    TIoMapper() {}
+    virtual ~TIoMapper() {}
+    // grow the reflection stage by stage
+    bool virtual addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*);
+    bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
+    bool virtual setAutoPushConstantBlock(const char*, unsigned int, TLayoutPacking) { return false; }
+};
+
+// Get the default GLSL IO mapper
+GLSLANG_EXPORT TIoMapper* GetGlslIoMapper();
+
 // Make one TProgram per set of shaders that will get linked together.  Add all
 // the shaders that are to be linked together.  After calling shader.parse()
 // for all shaders, call link().
@@ -945,6 +976,10 @@ public:
     const TType *getAttributeTType(int index) const    { return getPipeInput(index).getType(); }
 
     GLSLANG_EXPORT void dumpReflection();
+
+    // Get the IO resolver to use for mapIO
+    GLSLANG_EXPORT TIoMapResolver* getGlslIoResolver(EShLanguage stage);
+
     // I/O mapping: apply base offsets and map live unbound variables
     // If resolver is not provided it uses the previous approach
     // and respects auto assignment and offsets.

+ 5 - 4
3rdparty/glslang/glslang/Public/resource_limits_c.h

@@ -30,25 +30,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_
 
 #include "../Include/glslang_c_interface.h"
+#include "../Include/visibility.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 // Returns a struct that can be use to create custom resource values.
-glslang_resource_t* glslang_resource(void);
+GLSLANG_EXPORT glslang_resource_t* glslang_resource(void);
 
 // These are the default resources for TBuiltInResources, used for both
 //  - parsing this string for the case where the user didn't supply one,
 //  - dumping out a template for user construction of a config file.
-const glslang_resource_t* glslang_default_resource(void);
+GLSLANG_EXPORT const glslang_resource_t* glslang_default_resource(void);
 
 // Returns the DefaultTBuiltInResource as a human-readable string.
 // NOTE: User is responsible for freeing this string.
-const char* glslang_default_resource_string();
+GLSLANG_EXPORT const char* glslang_default_resource_string();
 
 // Decodes the resource limits from |config| to |resources|.
-void glslang_decode_resource_limits(glslang_resource_t* resources, char* config);
+GLSLANG_EXPORT void glslang_decode_resource_limits(glslang_resource_t* resources, char* config);
 
 #ifdef __cplusplus
 }

Some files were not shown because too many files changed in this diff