فهرست منبع

Updated glslang.

Бранимир Караџић 6 سال پیش
والد
کامیت
5ba4893f72
30فایلهای تغییر یافته به همراه407 افزوده شده و 279 حذف شده
  1. 2 2
      3rdparty/glslang/SPIRV/SpvTools.h
  2. 1 1
      3rdparty/glslang/SPIRV/disassemble.h
  3. 1 1
      3rdparty/glslang/SPIRV/doc.h
  4. 2 1
      3rdparty/glslang/Test/baseResults/cppBad2.vert.out
  5. 2 1
      3rdparty/glslang/Test/baseResults/cppBad3.vert.out
  6. 19 0
      3rdparty/glslang/Test/baseResults/cppBad4.vert.out
  7. 19 0
      3rdparty/glslang/Test/baseResults/cppBad5.vert.out
  8. 23 0
      3rdparty/glslang/Test/baseResults/cppMerge.frag.out
  9. 1 1
      3rdparty/glslang/Test/baseResults/hlsl.automap.frag.out
  10. 1 1
      3rdparty/glslang/Test/baseResults/hlsl.reflection.binding.frag.out
  11. 5 5
      3rdparty/glslang/Test/baseResults/hlsl.reflection.vert.out
  12. 1 1
      3rdparty/glslang/Test/baseResults/hlsl.shift.per-set.frag.out
  13. 2 2
      3rdparty/glslang/Test/baseResults/reflection.linked.out
  14. 26 1
      3rdparty/glslang/Test/baseResults/reflection.options.vert.out
  15. 23 8
      3rdparty/glslang/Test/baseResults/reflection.vert.out
  16. 4 0
      3rdparty/glslang/Test/cppBad4.vert
  17. 4 0
      3rdparty/glslang/Test/cppBad5.vert
  18. 24 0
      3rdparty/glslang/Test/cppMerge.frag
  19. 7 0
      3rdparty/glslang/Test/reflection.options.vert
  20. 3 0
      3rdparty/glslang/Test/reflection.vert
  21. 2 2
      3rdparty/glslang/glslang/MachineIndependent/glslang.y
  22. 2 2
      3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp
  23. 31 19
      3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp
  24. 78 12
      3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpContext.h
  25. 83 60
      3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp
  26. 31 152
      3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp
  27. 5 5
      3rdparty/glslang/glslang/MachineIndependent/reflection.cpp
  28. 3 0
      3rdparty/glslang/gtests/AST.FromFile.cpp
  29. 1 1
      3rdparty/glslang/hlsl/hlslParseHelper.cpp
  30. 1 1
      3rdparty/glslang/known_good.json

+ 2 - 2
3rdparty/glslang/SPIRV/SpvTools.h

@@ -75,6 +75,6 @@ void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector<
 
 
 #endif
 #endif
 
 
-}; // end namespace glslang
+} // end namespace glslang
 
 
-#endif // GLSLANG_SPV_TOOLS_H
+#endif // GLSLANG_SPV_TOOLS_H

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

@@ -48,6 +48,6 @@ namespace spv {
     // disassemble with glslang custom disassembler
     // disassemble with glslang custom disassembler
     void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
     void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
 
 
-};  // end namespace spv
+}  // end namespace spv
 
 
 #endif // disassembler_H
 #endif // disassembler_H

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

@@ -255,4 +255,4 @@ const char* AccessQualifierString(int attr);
 
 
 void PrintOperands(const OperandParameters& operands, int reservedOperands);
 void PrintOperands(const OperandParameters& operands, int reservedOperands);
 
 
-};  // end namespace spv
+}  // end namespace spv

+ 2 - 1
3rdparty/glslang/Test/baseResults/cppBad2.vert.out

@@ -1,6 +1,7 @@
 cppBad2.vert
 cppBad2.vert
 ERROR: 0:3: 'macro expansion' : End of input in macro b
 ERROR: 0:3: 'macro expansion' : End of input in macro b
-ERROR: 1 compilation errors.  No code generated.
+ERROR: 0:3: '' : compilation terminated 
+ERROR: 2 compilation errors.  No code generated.
 
 
 
 
 Shader version: 100
 Shader version: 100

+ 2 - 1
3rdparty/glslang/Test/baseResults/cppBad3.vert.out

@@ -1,6 +1,7 @@
 cppBad3.vert
 cppBad3.vert
 ERROR: 0:3: 'macro expansion' : End of input in macro y
 ERROR: 0:3: 'macro expansion' : End of input in macro y
-ERROR: 1 compilation errors.  No code generated.
+ERROR: 0:3: '' : compilation terminated 
+ERROR: 2 compilation errors.  No code generated.
 
 
 
 
 Shader version: 100
 Shader version: 100

+ 19 - 0
3rdparty/glslang/Test/baseResults/cppBad4.vert.out

@@ -0,0 +1,19 @@
+cppBad4.vert
+ERROR: 0:4: 'macro expansion' : unexpected '#' g
+ERROR: 0:5: '' :  syntax error, unexpected SEMICOLON, expecting LEFT_PAREN
+ERROR: 2 compilation errors.  No code generated.
+
+
+Shader version: 100
+ERROR: node is still EOpNull!
+0:?   Linker Objects
+
+
+Linked vertex stage:
+
+ERROR: Linking vertex stage: Missing entry point: Each stage requires one entry point
+
+Shader version: 100
+ERROR: node is still EOpNull!
+0:?   Linker Objects
+

+ 19 - 0
3rdparty/glslang/Test/baseResults/cppBad5.vert.out

@@ -0,0 +1,19 @@
+cppBad5.vert
+ERROR: 0:4: 'macro expansion' : End of input in macro g
+ERROR: 0:5: '' : compilation terminated 
+ERROR: 2 compilation errors.  No code generated.
+
+
+Shader version: 100
+ERROR: node is still EOpNull!
+0:?   Linker Objects
+
+
+Linked vertex stage:
+
+ERROR: Linking vertex stage: Missing entry point: Each stage requires one entry point
+
+Shader version: 100
+ERROR: node is still EOpNull!
+0:?   Linker Objects
+

+ 23 - 0
3rdparty/glslang/Test/baseResults/cppMerge.frag.out

@@ -0,0 +1,23 @@
+cppMerge.frag
+Shader version: 450
+0:? Sequence
+0:22  Function Definition: main( ( global void)
+0:22    Function Parameters: 
+0:?   Linker Objects
+0:?     'dest1' (layout( set=0 binding=0) writeonly uniform image1D)
+0:?     'dest2' (layout( set=0 binding=0) writeonly uniform image1D)
+0:?     'dest3' (layout( set=0 binding=0) writeonly uniform image1D)
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+0:? Sequence
+0:22  Function Definition: main( ( global void)
+0:22    Function Parameters: 
+0:?   Linker Objects
+0:?     'dest1' (layout( set=0 binding=0) writeonly uniform image1D)
+0:?     'dest2' (layout( set=0 binding=0) writeonly uniform image1D)
+0:?     'dest3' (layout( set=0 binding=0) writeonly uniform image1D)
+

+ 1 - 1
3rdparty/glslang/Test/baseResults/hlsl.automap.frag.out

@@ -32,5 +32,5 @@ Buffer block reflection:
 Pipeline input reflection:
 Pipeline input reflection:
 
 
 Pipeline output reflection:
 Pipeline output reflection:
-@entryPointOutput: offset 0, type 8b52, size 0, index 0, binding -1, stages 16
+@entryPointOutput: offset 0, type 8b52, size 1, index 0, binding -1, stages 16
 
 

+ 1 - 1
3rdparty/glslang/Test/baseResults/hlsl.reflection.binding.frag.out

@@ -22,5 +22,5 @@ Buffer block reflection:
 Pipeline input reflection:
 Pipeline input reflection:
 
 
 Pipeline output reflection:
 Pipeline output reflection:
-psout.Color: offset 0, type 8b52, size 0, index 0, binding -1, stages 16
+psout.Color: offset 0, type 8b52, size 1, index 0, binding -1, stages 16
 
 

+ 5 - 5
3rdparty/glslang/Test/baseResults/hlsl.reflection.vert.out

@@ -72,11 +72,11 @@ Buffer variable reflection:
 Buffer block reflection:
 Buffer block reflection:
 
 
 Pipeline input reflection:
 Pipeline input reflection:
-attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 1
-attributeFloat2: offset 0, type 8b50, size 0, index 0, binding -1, stages 1
-attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 1
-attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 1
-attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 1
+attributeFloat: offset 0, type 1406, size 1, index 0, binding -1, stages 1
+attributeFloat2: offset 0, type 8b50, size 1, index 0, binding -1, stages 1
+attributeFloat3: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
+attributeFloat4: offset 0, type 8b52, size 1, index 0, binding -1, stages 1
+attributeMat4: offset 0, type 8b5c, size 1, index 0, binding -1, stages 1
 
 
 Pipeline output reflection:
 Pipeline output reflection:
 
 

+ 1 - 1
3rdparty/glslang/Test/baseResults/hlsl.shift.per-set.frag.out

@@ -233,5 +233,5 @@ Buffer block reflection:
 Pipeline input reflection:
 Pipeline input reflection:
 
 
 Pipeline output reflection:
 Pipeline output reflection:
-@entryPointOutput: offset 0, type 8b52, size 0, index 0, binding -1, stages 16
+@entryPointOutput: offset 0, type 8b52, size 1, index 0, binding -1, stages 16
 
 

+ 2 - 2
3rdparty/glslang/Test/baseResults/reflection.linked.out

@@ -13,8 +13,8 @@ Buffer variable reflection:
 Buffer block reflection:
 Buffer block reflection:
 
 
 Pipeline input reflection:
 Pipeline input reflection:
-vertin: offset 0, type 1406, size 0, index 0, binding -1, stages 1
+vertin: offset 0, type 1406, size 1, index 0, binding -1, stages 1
 
 
 Pipeline output reflection:
 Pipeline output reflection:
-fragout: offset 0, type 1406, size 0, index 0, binding -1, stages 16
+fragout: offset 0, type 1406, size 1, index 0, binding -1, stages 16
 
 

+ 26 - 1
3rdparty/glslang/Test/baseResults/reflection.options.vert.out

@@ -6,9 +6,33 @@ UBO.verts[1].position[0]: offset 24, type 1406, size 3, index 0, binding -1, sta
 UBO.verts[1].normal[0]: offset 36, type 1406, size 3, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
 UBO.verts[1].normal[0]: offset 36, type 1406, size 3, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
 UBO.flt[0]: offset 48, type 1406, size 8, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
 UBO.flt[0]: offset 48, type 1406, size 8, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
 UBO.unused: offset 80, type 8dc8, size 1, index 0, binding -1, stages 0
 UBO.unused: offset 80, type 8dc8, size 1, index 0, binding -1, stages 0
+UBO.uniform_multi[0][0][0]: offset 96, type 1406, size 2, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+UBO.uniform_multi[0][1][0]: offset 104, type 1406, size 2, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.uniform_multi[0][2][0]: offset 112, type 1406, size 2, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.uniform_multi[1][0][0]: offset 120, type 1406, size 2, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.uniform_multi[1][1][0]: offset 128, type 1406, size 2, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.uniform_multi[1][2][0]: offset 136, type 1406, size 2, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.uniform_multi[2][0][0]: offset 144, type 1406, size 2, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.uniform_multi[2][1][0]: offset 152, type 1406, size 2, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.uniform_multi[2][2][0]: offset 160, type 1406, size 2, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.uniform_multi[3][0][0]: offset 168, type 1406, size 2, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.uniform_multi[3][1][0]: offset 176, type 1406, size 2, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+UBO.uniform_multi[3][2][0]: offset 184, type 1406, size 2, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24
+uniform_multi[0][0][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+uniform_multi[0][1][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+uniform_multi[0][2][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+uniform_multi[1][0][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+uniform_multi[1][1][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+uniform_multi[1][2][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+uniform_multi[2][0][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+uniform_multi[2][1][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+uniform_multi[2][2][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+uniform_multi[3][0][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+uniform_multi[3][1][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+uniform_multi[3][2][0]: offset -1, type 1406, size 2, index -1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
 
 
 Uniform block reflection:
 Uniform block reflection:
-UBO: offset -1, type ffffffff, size 96, index -1, binding -1, stages 1, numMembers 6
+UBO: offset -1, type ffffffff, size 192, index -1, binding -1, stages 1, numMembers 7
 
 
 Buffer variable reflection:
 Buffer variable reflection:
 t[0].v[0].position[0]: offset 0, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
 t[0].v[0].position[0]: offset 0, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
@@ -40,4 +64,5 @@ outval.val: offset 0, type 1406, size 1, index 0, binding -1, stages 1
 outval.a: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
 outval.a: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
 outval.b[0]: offset 0, type 8b50, size 4, index 0, binding -1, stages 1
 outval.b[0]: offset 0, type 8b50, size 4, index 0, binding -1, stages 1
 outval.c: offset 0, type 8b5a, size 1, index 0, binding -1, stages 1
 outval.c: offset 0, type 8b5a, size 1, index 0, binding -1, stages 1
+outarr[0]: offset 0, type 1406, size 3, index 0, binding -1, stages 1
 
 

+ 23 - 8
3rdparty/glslang/Test/baseResults/reflection.vert.out

@@ -25,8 +25,8 @@ nested.foo.n1.a: offset 0, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.b: offset 16, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.b: offset 16, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.c: offset 20, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.c: offset 20, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.d: offset 24, type 1406, size 1, index 3, binding -1, stages 1
 nested.foo.n2.d: offset 24, type 1406, size 1, index 3, binding -1, stages 1
-deepA[0].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
-deepA[1].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepA[0].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepA[1].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
 deepB[1].d2.d1[0].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
 deepB[1].d2.d1[0].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
 deepB[1].d2.d1[1].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
 deepB[1].d2.d1[1].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
 deepB[1].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
 deepB[1].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
@@ -68,6 +68,20 @@ deepD[1].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages
 deepD[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8
 deepD[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8
 deepD[1].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[1].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1
 deepD[1].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1
 deepD[1].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1
+deepA[0].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepA[0].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepA[0].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepA[0].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepA[0].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepA[0].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepA[0].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepA[1].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepA[1].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepA[1].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepA[1].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepA[1].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
+deepA[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176
+deepA[1].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176
 abl.foo: offset 0, type 1406, size 1, index 7, binding -1, stages 1
 abl.foo: offset 0, type 1406, size 1, index 7, binding -1, stages 1
 abl2.foo: offset 0, type 1406, size 1, index 11, binding -1, stages 1
 abl2.foo: offset 0, type 1406, size 1, index 11, binding -1, stages 1
 buf1.runtimeArray: offset 4, type 1406, size 4, index 12, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
 buf1.runtimeArray: offset 4, type 1406, size 4, index 12, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
@@ -151,12 +165,13 @@ Buffer variable reflection:
 Buffer block reflection:
 Buffer block reflection:
 
 
 Pipeline input reflection:
 Pipeline input reflection:
-attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 1
-attributeFloat2: offset 0, type 8b50, size 0, index 0, binding -1, stages 1
-attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 1
-attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 1
-attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 1
-gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 1
+attributeFloat: offset 0, type 1406, size 1, index 0, binding -1, stages 1
+attributeFloat2: offset 0, type 8b50, size 1, index 0, binding -1, stages 1
+attributeFloat3: offset 0, type 8b51, size 1, index 0, binding -1, stages 1
+attributeFloat4: offset 0, type 8b52, size 1, index 0, binding -1, stages 1
+attributeMat4: offset 0, type 8b5c, size 1, index 0, binding -1, stages 1
+attributeFloatArray: offset 0, type 1406, size 3, index 0, binding -1, stages 1
+gl_InstanceID: offset 0, type 1404, size 1, index 0, binding -1, stages 1
 
 
 Pipeline output reflection:
 Pipeline output reflection:
 
 

+ 4 - 0
3rdparty/glslang/Test/cppBad4.vert

@@ -0,0 +1,4 @@
+int,i=
+#define f g(#g(y
+#define g(m)
+g(f)

+ 4 - 0
3rdparty/glslang/Test/cppBad5.vert

@@ -0,0 +1,4 @@
+int,i=
+#define f g($g(y
+#define g(m)
+g(f)

+ 24 - 0
3rdparty/glslang/Test/cppMerge.frag

@@ -0,0 +1,24 @@
+#version 450 core
+
+#define PASTER2(type, suffix) type##suffix
+#define PASTER3(type, suffix) type## suffix
+#define MAKE_TYPE1 image1D dest ## 1;
+#define MAKE_TYPE2(type, suffix) PASTER2(type, suffix)
+#define MAKE_TYPE3(type, suffix) PASTER3(type, suffix)
+
+#define PREFIX image
+#define PREFIX3 imag
+#define SUFFIX2 1D
+#define SUFFIX3 e1 D
+
+#define RESOURCE_TYPE1 MAKE_TYPE1
+#define RESOURCE_TYPE2 MAKE_TYPE2(PREFIX, SUFFIX2)
+#define RESOURCE_TYPE3 MAKE_TYPE3(PREFIX3, SUFFIX3)
+
+layout (set = 0, binding = 0) uniform writeonly RESOURCE_TYPE1
+layout (set = 0, binding = 0) uniform writeonly RESOURCE_TYPE2 dest2;
+layout (set = 0, binding = 0) uniform writeonly RESOURCE_TYPE3 dest3;
+
+void main()
+{
+}

+ 7 - 0
3rdparty/glslang/Test/reflection.options.vert

@@ -24,8 +24,11 @@ uniform UBO {
     VertexInfo verts[2];
     VertexInfo verts[2];
     float flt[8];
     float flt[8];
     uvec4 unused;
     uvec4 unused;
+    float uniform_multi[4][3][2];
 } ubo;
 } ubo;
 
 
+uniform float uniform_multi[4][3][2];
+
 struct OutputStruct {
 struct OutputStruct {
     float val;
     float val;
     vec3 a;
     vec3 a;
@@ -34,6 +37,7 @@ struct OutputStruct {
 };
 };
 
 
 out OutputStruct outval;
 out OutputStruct outval;
+out float outarr[3];
 
 
 void main()
 void main()
 {
 {
@@ -46,6 +50,9 @@ void main()
     f += multiarray.f[gl_InstanceID];
     f += multiarray.f[gl_InstanceID];
     f += ubo.verts[gl_InstanceID].position[0];
     f += ubo.verts[gl_InstanceID].position[0];
     f += ubo.flt[gl_InstanceID];
     f += ubo.flt[gl_InstanceID];
+    f += ubo.uniform_multi[0][0][0];
+    f += uniform_multi[gl_InstanceID][gl_InstanceID][gl_InstanceID];
     TriangleInfo tlocal[5] = t;
     TriangleInfo tlocal[5] = t;
     outval.val = f;
     outval.val = f;
+    outarr[2] = f;
 }
 }

+ 3 - 0
3rdparty/glslang/Test/reflection.vert

@@ -107,6 +107,7 @@ layout(location = 2) in vec2 attributeFloat2;
 in vec3 attributeFloat3;
 in vec3 attributeFloat3;
 in vec4 attributeFloat4;
 in vec4 attributeFloat4;
 in mat4 attributeMat4;
 in mat4 attributeMat4;
+in float attributeFloatArray[3];
 
 
 uniform deep3 deepA[2], deepB[2], deepC[3], deepD[2];
 uniform deep3 deepA[2], deepB[2], deepC[3], deepD[2];
 
 
@@ -212,6 +213,7 @@ void main()
         f += deepB[i].d2.d1[i].va[1].x;
         f += deepB[i].d2.d1[i].va[1].x;
         deep3 d = deepC[1];
         deep3 d = deepC[1];
         deep3 da[2] = deepD;
         deep3 da[2] = deepD;
+        deep1 db = deepA[i].d2.d1[i];
     } else
     } else
         f = ufDead3;
         f = ufDead3;
 
 
@@ -223,6 +225,7 @@ void main()
     f += attributeFloat3.x;
     f += attributeFloat3.x;
     f += attributeFloat4.x;
     f += attributeFloat4.x;
     f += attributeMat4[0][1];
     f += attributeMat4[0][1];
+    f += attributeFloatArray[2];
     f += buf1i.runtimeArray[3];
     f += buf1i.runtimeArray[3];
     f += buf2i.runtimeArray[3].c;
     f += buf2i.runtimeArray[3].c;
     f += buf3i.runtimeArray[gl_InstanceID];
     f += buf3i.runtimeArray[gl_InstanceID];

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

@@ -473,8 +473,8 @@ function_identifier
 
 
         if ($$.function == 0) {
         if ($$.function == 0) {
             // error recover
             // error recover
-            TString empty("");
-            $$.function = new TFunction(&empty, TType(EbtVoid), EOpNull);
+            TString* empty = NewPoolTString("");
+            $$.function = new TFunction(empty, TType(EbtVoid), EOpNull);
         }
         }
     }
     }
     | non_uniform_qualifier {
     | non_uniform_qualifier {

+ 2 - 2
3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp

@@ -4447,8 +4447,8 @@ yyreduce:
 
 
         if ((yyval.interm).function == 0) {
         if ((yyval.interm).function == 0) {
             // error recover
             // error recover
-            TString empty("");
-            (yyval.interm).function = new TFunction(&empty, TType(EbtVoid), EOpNull);
+            TString* empty = NewPoolTString("");
+            (yyval.interm).function = new TFunction(empty, TType(EbtVoid), EOpNull);
         }
         }
     }
     }
 #line 4455 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */
 #line 4455 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646  */

+ 31 - 19
3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp

@@ -166,29 +166,43 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
     if (existing != nullptr) {
     if (existing != nullptr) {
         if (! existing->undef) {
         if (! existing->undef) {
             // Already defined -- need to make sure they are identical:
             // Already defined -- need to make sure they are identical:
-            // "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
-            // ordering, spelling, and white-space separation, where all white-space separations are considered identical."
-            if (existing->functionLike != mac.functionLike)
-                parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define", atomStrings.getString(defAtom));
-            else if (existing->args.size() != mac.args.size())
-                parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom));
-            else {
-                if (existing->args != mac.args)
-                    parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom));
+            // "Two replacement lists are identical if and only if the
+            // preprocessing tokens in both have the same number,
+            // ordering, spelling, and white-space separation, where all
+            // white-space separations are considered identical."
+            if (existing->functionLike != mac.functionLike) {
+                parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define",
+                    atomStrings.getString(defAtom));
+            } else if (existing->args.size() != mac.args.size()) {
+                parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define",
+                    atomStrings.getString(defAtom));
+            } else {
+                if (existing->args != mac.args) {
+                    parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define",
+                       atomStrings.getString(defAtom));
+                }
+                // set up to compare the two
                 existing->body.reset();
                 existing->body.reset();
                 mac.body.reset();
                 mac.body.reset();
                 int newToken;
                 int newToken;
+                bool firstToken = true;
                 do {
                 do {
                     int oldToken;
                     int oldToken;
                     TPpToken oldPpToken;
                     TPpToken oldPpToken;
                     TPpToken newPpToken;
                     TPpToken newPpToken;
                     oldToken = existing->body.getToken(parseContext, &oldPpToken);
                     oldToken = existing->body.getToken(parseContext, &oldPpToken);
                     newToken = mac.body.getToken(parseContext, &newPpToken);
                     newToken = mac.body.getToken(parseContext, &newPpToken);
+                    // for the first token, preceding spaces don't matter
+                    if (firstToken) {
+                        newPpToken.space = oldPpToken.space;
+                        firstToken = false;
+                    }
                     if (oldToken != newToken || oldPpToken != newPpToken) {
                     if (oldToken != newToken || oldPpToken != newPpToken) {
-                        parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom));
+                        parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define",
+                            atomStrings.getString(defAtom));
                         break;
                         break;
                     }
                     }
-                } while (newToken > 0);
+                } while (newToken != EndOfInput);
             }
             }
         }
         }
         *existing = mac;
         *existing = mac;
@@ -866,8 +880,7 @@ int TPpContext::CPPextension(TPpToken* ppToken)
     if (token != PpAtomIdentifier)
     if (token != PpAtomIdentifier)
         parseContext.ppError(ppToken->loc, "extension name expected", "#extension", "");
         parseContext.ppError(ppToken->loc, "extension name expected", "#extension", "");
 
 
-    assert(strlen(ppToken->name) <= MaxTokenLength);
-    strcpy(extensionName, ppToken->name);
+    snprintf(extensionName, sizeof(extensionName), "%s", ppToken->name);
 
 
     token = scanToken(ppToken);
     token = scanToken(ppToken);
     if (token != ':') {
     if (token != ':') {
@@ -1027,7 +1040,9 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken*
             case MacroExpandNotStarted:
             case MacroExpandNotStarted:
                 break;
                 break;
             case MacroExpandError:
             case MacroExpandError:
-                token = EndOfInput;
+                // toss the rest of the pushed-input argument by scanning until tMarkerInput
+                while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput)
+                    ;
                 break;
                 break;
             case MacroExpandStarted:
             case MacroExpandStarted:
             case MacroExpandUndef:
             case MacroExpandUndef:
@@ -1039,13 +1054,10 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken*
         expandedArg->putToken(token, ppToken);
         expandedArg->putToken(token, ppToken);
     }
     }
 
 
-    if (token == EndOfInput) {
+    if (token != tMarkerInput::marker) {
         // Error, or MacroExpand ate the marker, so had bad input, recover
         // Error, or MacroExpand ate the marker, so had bad input, recover
         delete expandedArg;
         delete expandedArg;
         expandedArg = nullptr;
         expandedArg = nullptr;
-    } else {
-        // remove the marker
-        popInput();
     }
     }
 
 
     return expandedArg;
     return expandedArg;
@@ -1262,7 +1274,7 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b
 
 
             if (token == ')') {
             if (token == ')') {
                 // closing paren of call
                 // closing paren of call
-                if (in->mac->args.size() == 1 && tokenRecorded == 0)
+                if (in->mac->args.size() == 1 && !tokenRecorded)
                     break;
                     break;
                 arg++;
                 arg++;
                 break;
                 break;

+ 78 - 12
3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpContext.h

@@ -84,6 +84,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <sstream>
 #include <sstream>
 
 
 #include "../ParseHelper.h"
 #include "../ParseHelper.h"
+#include "PpTokens.h"
 
 
 /* windows only pragma */
 /* windows only pragma */
 #ifdef _MSC_VER
 #ifdef _MSC_VER
@@ -212,7 +213,8 @@ public:
         virtual int scan(TPpToken*) = 0;
         virtual int scan(TPpToken*) = 0;
         virtual int getch() = 0;
         virtual int getch() = 0;
         virtual void ungetch() = 0;
         virtual void ungetch() = 0;
-        virtual bool peekPasting() { return false; }          // true when about to see ##
+        virtual bool peekPasting() { return false; }             // true when about to see ##
+        virtual bool peekContinuedPasting(int) { return false; } // true when non-spaced tokens can paste
         virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
         virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
         virtual bool isMacroInput() { return false; }
         virtual bool isMacroInput() { return false; }
 
 
@@ -243,24 +245,79 @@ public:
     // From PpTokens.cpp
     // From PpTokens.cpp
     //
     //
 
 
+    // Capture the needed parts of a token stream for macro recording/playback.
     class TokenStream {
     class TokenStream {
     public:
     public:
-        TokenStream() : current(0) { }
+        // Manage a stream of these 'Token', which capture the relevant parts
+        // of a TPpToken, plus its atom.
+        class Token {
+        public:
+            Token(int atom, const TPpToken& ppToken) : 
+                atom(atom),
+                space(ppToken.space),
+                i64val(ppToken.i64val),
+                name(ppToken.name) { }
+            int get(TPpToken& ppToken)
+            {
+                ppToken.clear();
+                ppToken.space = space;
+                ppToken.i64val = i64val;
+                snprintf(ppToken.name, sizeof(ppToken.name), "%s", name.c_str());
+                return atom;
+            }
+            bool isAtom(int a) const { return atom == a; }
+            int getAtom() const { return atom; }
+            bool nonSpaced() const { return !space; }
+        protected:
+            Token() {}
+            int atom;
+            bool space;        // did a space precede the token?
+            long long i64val;
+            TString name;
+        };
+
+        TokenStream() : currentPos(0) { }
 
 
         void putToken(int token, TPpToken* ppToken);
         void putToken(int token, TPpToken* ppToken);
+        bool peekToken(int atom) { return !atEnd() && stream[currentPos].isAtom(atom); }
+        bool peekContinuedPasting(int atom)
+        {
+            // This is basically necessary because, for example, the PP
+            // tokenizer only accepts valid numeric-literals plus suffixes, so
+            // separates numeric-literals plus bad suffix into two tokens, which
+            // should get both pasted together as one token when token pasting.
+            //
+            // The following code is a bit more generalized than the above example.
+            if (!atEnd() && atom == PpAtomIdentifier && stream[currentPos].nonSpaced()) {
+                switch(stream[currentPos].getAtom()) {
+                    case PpAtomConstInt:
+                    case PpAtomConstUint:
+                    case PpAtomConstInt64:
+                    case PpAtomConstUint64:
+                    case PpAtomConstInt16:
+                    case PpAtomConstUint16:
+                    case PpAtomConstFloat:
+                    case PpAtomConstDouble:
+                    case PpAtomConstFloat16:
+                    case PpAtomConstString:
+                    case PpAtomIdentifier:
+                        return true;
+                    default:
+                        break;
+                }
+            }
+
+            return false;
+        }
         int getToken(TParseContextBase&, TPpToken*);
         int getToken(TParseContextBase&, TPpToken*);
-        bool atEnd() { return current >= data.size(); }
+        bool atEnd() { return currentPos >= stream.size(); }
         bool peekTokenizedPasting(bool lastTokenPastes);
         bool peekTokenizedPasting(bool lastTokenPastes);
         bool peekUntokenizedPasting();
         bool peekUntokenizedPasting();
-        void reset() { current = 0; }
+        void reset() { currentPos = 0; }
 
 
     protected:
     protected:
-        void putSubtoken(char);
-        int getSubtoken();
-        void ungetSubtoken();
-
-        TVector<unsigned char> data;
-        size_t current;
+        TVector<Token> stream;
+        size_t currentPos;
     };
     };
 
 
     //
     //
@@ -320,6 +377,10 @@ protected:
     int  getChar() { return inputStack.back()->getch(); }
     int  getChar() { return inputStack.back()->getch(); }
     void ungetChar() { inputStack.back()->ungetch(); }
     void ungetChar() { inputStack.back()->ungetch(); }
     bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); }
     bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); }
+    bool peekContinuedPasting(int a)
+    {
+        return !inputStack.empty() && inputStack.back()->peekContinuedPasting(a);
+    }
     bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
     bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
     bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); }
     bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); }
 
 
@@ -344,6 +405,7 @@ protected:
         virtual int getch() override { assert(0); return EndOfInput; }
         virtual int getch() override { assert(0); return EndOfInput; }
         virtual void ungetch() override { assert(0); }
         virtual void ungetch() override { assert(0); }
         bool peekPasting() override { return prepaste; }
         bool peekPasting() override { return prepaste; }
+        bool peekContinuedPasting(int a) override { return mac->body.peekContinuedPasting(a); }
         bool endOfReplacementList() override { return mac->body.atEnd(); }
         bool endOfReplacementList() override { return mac->body.atEnd(); }
         bool isMacroInput() override { return true; }
         bool isMacroInput() override { return true; }
 
 
@@ -418,14 +480,18 @@ protected:
 
 
     class tTokenInput : public tInput {
     class tTokenInput : public tInput {
     public:
     public:
-        tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) : tInput(pp), tokens(t), lastTokenPastes(prepasting) { }
+        tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) :
+            tInput(pp),
+            tokens(t),
+            lastTokenPastes(prepasting) { }
         virtual int scan(TPpToken *ppToken) override { return tokens->getToken(pp->parseContext, ppToken); }
         virtual int scan(TPpToken *ppToken) override { return tokens->getToken(pp->parseContext, ppToken); }
         virtual int getch() override { assert(0); return EndOfInput; }
         virtual int getch() override { assert(0); return EndOfInput; }
         virtual void ungetch() override { assert(0); }
         virtual void ungetch() override { assert(0); }
         virtual bool peekPasting() override { return tokens->peekTokenizedPasting(lastTokenPastes); }
         virtual bool peekPasting() override { return tokens->peekTokenizedPasting(lastTokenPastes); }
+        bool peekContinuedPasting(int a) override { return tokens->peekContinuedPasting(a); }
     protected:
     protected:
         TokenStream* tokens;
         TokenStream* tokens;
-        bool lastTokenPastes;     // true if the last token in the input is to be pasted, rather than consumed as a token
+        bool lastTokenPastes; // true if the last token in the input is to be pasted, rather than consumed as a token
     };
     };
 
 
     class tUngotTokenInput : public tInput {
     class tUngotTokenInput : public tInput {

+ 83 - 60
3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp

@@ -96,12 +96,19 @@ namespace glslang {
 /////////////////////////////////// Floating point constants: /////////////////////////////////
 /////////////////////////////////// Floating point constants: /////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
 
-/*
-* lFloatConst() - Scan a single- or double-precision floating point constant.  Assumes that the scanner
-*         has seen at least one digit, followed by either a decimal '.' or the
-*         letter 'e', or a precision ending (e.g., F or LF).
-*/
-
+// 
+// Scan a single- or double-precision floating point constant.
+// Assumes that the scanner has seen at least one digit,
+// followed by either a decimal '.' or the letter 'e', or a
+// precision ending (e.g., F or LF).
+//
+// This is technically not correct, as the preprocessor should just
+// accept the numeric literal along with whatever suffix it has, but
+// currently, it stops on seeing a bad suffix, treating that as the
+// next token. This effects things like token pasting, where it is
+// relevant how many tokens something was broken into.
+//
+// See peekContinuedPasting().
 int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
 int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
 {
 {
     const auto saveName = [&](int ch) {
     const auto saveName = [&](int ch) {
@@ -435,6 +442,14 @@ int TPpContext::characterLiteral(TPpToken* ppToken)
 //
 //
 // Scanner used to tokenize source stream.
 // Scanner used to tokenize source stream.
 //
 //
+// N.B. Invalid numeric suffixes are not consumed.//
+// This is technically not correct, as the preprocessor should just
+// accept the numeric literal along with whatever suffix it has, but
+// currently, it stops on seeing a bad suffix, treating that as the
+// next token. This effects things like token pasting, where it is
+// relevant how many tokens something was broken into.
+// See peekContinuedPasting().
+//
 int TPpContext::tStringInput::scan(TPpToken* ppToken)
 int TPpContext::tStringInput::scan(TPpToken* ppToken)
 {
 {
     int AlreadyComplained = 0;
     int AlreadyComplained = 0;
@@ -1056,7 +1071,7 @@ int TPpContext::tokenize(TPpToken& ppToken)
         // Handle token-pasting logic
         // Handle token-pasting logic
         token = tokenPaste(token, ppToken);
         token = tokenPaste(token, ppToken);
 
 
-        if (token == EndOfInput || token == tMarkerInput::marker) {
+        if (token == EndOfInput) {
             missingEndifCheck();
             missingEndifCheck();
             return EndOfInput;
             return EndOfInput;
         }
         }
@@ -1116,7 +1131,7 @@ int TPpContext::tokenize(TPpToken& ppToken)
             parseContext.ppError(ppToken.loc, "character literals not supported", "\'", "");
             parseContext.ppError(ppToken.loc, "character literals not supported", "\'", "");
             continue;
             continue;
         default:
         default:
-            strcpy(ppToken.name, atomStrings.getString(token));
+            snprintf(ppToken.name, sizeof(ppToken.name), "%s", atomStrings.getString(token));
             break;
             break;
         }
         }
 
 
@@ -1153,61 +1168,69 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken)
             break;
             break;
         }
         }
 
 
-        // get the token after the ##
-        token = scanToken(&pastedPpToken);
+        // Get the token(s) after the ##.
+        // Because of "space" semantics, and prior tokenization, what
+        // appeared a single token, e.g. "3A", might have been tokenized
+        // into two tokens "3" and "A", but the "A" will have 'space' set to
+        // false.  Accumulate all of these to recreate the original lexical
+        // appearing token.
+        do {
+            token = scanToken(&pastedPpToken);
 
 
-        // This covers end of argument expansion
-        if (token == tMarkerInput::marker) {
-            parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", "");
-            break;
-        }
+            // This covers end of argument expansion
+            if (token == tMarkerInput::marker) {
+                parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", "");
+                return resultToken;
+            }
 
 
-        // get the token text
-        switch (resultToken) {
-        case PpAtomIdentifier:
-            // already have the correct text in token.names
-            break;
-        case '=':
-        case '!':
-        case '-':
-        case '~':
-        case '+':
-        case '*':
-        case '/':
-        case '%':
-        case '<':
-        case '>':
-        case '|':
-        case '^':
-        case '&':
-        case PpAtomRight:
-        case PpAtomLeft:
-        case PpAtomAnd:
-        case PpAtomOr:
-        case PpAtomXor:
-            strcpy(ppToken.name, atomStrings.getString(resultToken));
-            strcpy(pastedPpToken.name, atomStrings.getString(token));
-            break;
-        default:
-            parseContext.ppError(ppToken.loc, "not supported for these tokens", "##", "");
-            return resultToken;
-        }
+            // get the token text
+            switch (resultToken) {
+            case PpAtomIdentifier:
+                // already have the correct text in token.names
+                break;
+            case '=':
+            case '!':
+            case '-':
+            case '~':
+            case '+':
+            case '*':
+            case '/':
+            case '%':
+            case '<':
+            case '>':
+            case '|':
+            case '^':
+            case '&':
+            case PpAtomRight:
+            case PpAtomLeft:
+            case PpAtomAnd:
+            case PpAtomOr:
+            case PpAtomXor:
+                snprintf(ppToken.name, sizeof(ppToken.name), "%s", atomStrings.getString(resultToken));
+                snprintf(pastedPpToken.name, sizeof(pastedPpToken.name), "%s", atomStrings.getString(token));
+                break;
+            default:
+                parseContext.ppError(ppToken.loc, "not supported for these tokens", "##", "");
+                return resultToken;
+            }
 
 
-        // combine the tokens
-        if (strlen(ppToken.name) + strlen(pastedPpToken.name) > MaxTokenLength) {
-            parseContext.ppError(ppToken.loc, "combined tokens are too long", "##", "");
-            return resultToken;
-        }
-        strncat(ppToken.name, pastedPpToken.name, MaxTokenLength - strlen(ppToken.name));
-
-        // correct the kind of token we are making, if needed (identifiers stay identifiers)
-        if (resultToken != PpAtomIdentifier) {
-            int newToken = atomStrings.getAtom(ppToken.name);
-            if (newToken > 0)
-                resultToken = newToken;
-            else
-                parseContext.ppError(ppToken.loc, "combined token is invalid", "##", "");
-        }
+            // combine the tokens
+            if (strlen(ppToken.name) + strlen(pastedPpToken.name) > MaxTokenLength) {
+                parseContext.ppError(ppToken.loc, "combined tokens are too long", "##", "");
+                return resultToken;
+            }
+            snprintf(&ppToken.name[0] + strlen(ppToken.name), sizeof(ppToken.name) - strlen(ppToken.name),
+                "%s", pastedPpToken.name);
+
+            // correct the kind of token we are making, if needed (identifiers stay identifiers)
+            if (resultToken != PpAtomIdentifier) {
+                int newToken = atomStrings.getAtom(ppToken.name);
+                if (newToken > 0)
+                    resultToken = newToken;
+                else
+                    parseContext.ppError(ppToken.loc, "combined token is invalid", "##", "");
+            }
+        } while (peekContinuedPasting(resultToken));
     }
     }
 
 
     return resultToken;
     return resultToken;

+ 31 - 152
3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp

@@ -99,151 +99,33 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 namespace glslang {
 namespace glslang {
 
 
-
-namespace {
-
-    // When recording (and playing back) should the backing name string
-    // be saved (restored)?
-    bool SaveName(int atom)
-    {
-        switch (atom) {
-        case PpAtomIdentifier:
-        case PpAtomConstString:
-        case PpAtomConstInt:
-        case PpAtomConstUint:
-        case PpAtomConstInt64:
-        case PpAtomConstUint64:
-    #ifdef AMD_EXTENSIONS
-        case PpAtomConstInt16:
-        case PpAtomConstUint16:
-    #endif
-        case PpAtomConstFloat:
-        case PpAtomConstDouble:
-        case PpAtomConstFloat16:
-            return true;
-        default:
-            return false;
-        }
-    }
-
-    // When recording (and playing back) should the numeric value
-    // be saved (restored)?
-    bool SaveValue(int atom)
-    {
-        switch (atom) {
-        case PpAtomConstInt:
-        case PpAtomConstUint:
-        case PpAtomConstInt64:
-        case PpAtomConstUint64:
-    #ifdef AMD_EXTENSIONS
-        case PpAtomConstInt16:
-        case PpAtomConstUint16:
-    #endif
-        case PpAtomConstFloat:
-        case PpAtomConstDouble:
-        case PpAtomConstFloat16:
-            return true;
-        default:
-            return false;
-        }
-    }
-}
-
-// push onto back of stream
-void TPpContext::TokenStream::putSubtoken(char subtoken)
-{
-    data.push_back(static_cast<unsigned char>(subtoken));
-}
-
-// get the next token in stream
-int TPpContext::TokenStream::getSubtoken()
-{
-    if (current < data.size())
-        return data[current++];
-    else
-        return EndOfInput;
-}
-
-// back up one position in the stream
-void TPpContext::TokenStream::ungetSubtoken()
-{
-    if (current > 0)
-        --current;
-}
-
-// Add a complete token (including backing string) to the end of a list
-// for later playback.
+// Add a token (including backing string) to the end of a macro
+// token stream, for later playback.
 void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken)
 void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken)
 {
 {
-    // save the atom
-    assert((atom & ~0xff) == 0);
-    putSubtoken(static_cast<char>(atom));
-
-    // save the backing name string
-    if (SaveName(atom)) {
-        const char* s = ppToken->name;
-        while (*s)
-            putSubtoken(*s++);
-        putSubtoken(0);
-    }
-
-    // save the numeric value
-    if (SaveValue(atom)) {
-        const char* n = reinterpret_cast<const char*>(&ppToken->i64val);
-        for (size_t i = 0; i < sizeof(ppToken->i64val); ++i)
-            putSubtoken(*n++);
-    }
+    TokenStream::Token streamToken(atom, *ppToken);
+    stream.push_back(streamToken);
 }
 }
 
 
-// Read the next token from a token stream.
-// (Not the source stream, but a stream used to hold a tokenized macro).
+// Read the next token from a macro token stream.
 int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken)
 int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken)
 {
 {
-    // get the atom
-    int atom = getSubtoken();
-    if (atom == EndOfInput)
-        return atom;
+    if (atEnd())
+        return EndOfInput;
 
 
-    // init the token
-    ppToken->clear();
+    int atom = stream[currentPos++].get(*ppToken);
     ppToken->loc = parseContext.getCurrentLoc();
     ppToken->loc = parseContext.getCurrentLoc();
 
 
-    // get the backing name string
-    if (SaveName(atom)) {
-        int ch = getSubtoken();
-        int len = 0;
-        while (ch != 0 && ch != EndOfInput) {
-            if (len < MaxTokenLength) {
-                ppToken->name[len] = (char)ch;
-                len++;
-                ch = getSubtoken();
-            } else {
-                parseContext.error(ppToken->loc, "token too long", "", "");
-                break;
-            }
-        }
-        ppToken->name[len] = 0;
-    }
-
     // Check for ##, unless the current # is the last character
     // Check for ##, unless the current # is the last character
     if (atom == '#') {
     if (atom == '#') {
-        if (current < data.size()) {
-            if (getSubtoken() == '#') {
-                parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
-                parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
-                atom = PpAtomPaste;
-            } else
-                ungetSubtoken();
+        if (peekToken('#')) {
+            parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
+            parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
+            currentPos++;
+            atom = PpAtomPaste;
         }
         }
     }
     }
 
 
-    // get the numeric value
-    if (SaveValue(atom)) {
-        char* n = reinterpret_cast<char*>(&ppToken->i64val);
-        for (size_t i = 0; i < sizeof(ppToken->i64val); ++i)
-            *n++ = (char)getSubtoken();
-    }
-
     return atom;
     return atom;
 }
 }
 
 
@@ -256,15 +138,14 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
 {
 {
     // 1. preceding ##?
     // 1. preceding ##?
 
 
-    size_t savePos = current;
-    int subtoken;
+    size_t savePos = currentPos;
     // skip white space
     // skip white space
-    do {
-        subtoken = getSubtoken();
-    } while (subtoken == ' ');
-    current = savePos;
-    if (subtoken == PpAtomPaste)
+    while (peekToken(' '))
+        ++currentPos;
+    if (peekToken(PpAtomPaste)) {
+        currentPos = savePos;
         return true;
         return true;
+    }
 
 
     // 2. last token and we've been told after this there will be a ##
     // 2. last token and we've been told after this there will be a ##
 
 
@@ -273,18 +154,18 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
     // Getting here means the last token will be pasted, after this
     // Getting here means the last token will be pasted, after this
 
 
     // Are we at the last non-whitespace token?
     // Are we at the last non-whitespace token?
-    savePos = current;
+    savePos = currentPos;
     bool moreTokens = false;
     bool moreTokens = false;
     do {
     do {
-        subtoken = getSubtoken();
-        if (subtoken == EndOfInput)
+        if (atEnd())
             break;
             break;
-        if (subtoken != ' ') {
+        if (!peekToken(' ')) {
             moreTokens = true;
             moreTokens = true;
             break;
             break;
         }
         }
+        ++currentPos;
     } while (true);
     } while (true);
-    current = savePos;
+    currentPos = savePos;
 
 
     return !moreTokens;
     return !moreTokens;
 }
 }
@@ -293,23 +174,21 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
 bool TPpContext::TokenStream::peekUntokenizedPasting()
 bool TPpContext::TokenStream::peekUntokenizedPasting()
 {
 {
     // don't return early, have to restore this
     // don't return early, have to restore this
-    size_t savePos = current;
+    size_t savePos = currentPos;
 
 
     // skip white-space
     // skip white-space
-    int subtoken;
-    do {
-        subtoken = getSubtoken();
-    } while (subtoken == ' ');
+    while (peekToken(' '))
+        ++currentPos;
 
 
     // check for ##
     // check for ##
     bool pasting = false;
     bool pasting = false;
-    if (subtoken == '#') {
-        subtoken = getSubtoken();
-        if (subtoken == '#')
+    if (peekToken('#')) {
+        ++currentPos;
+        if (peekToken('#'))
             pasting = true;
             pasting = true;
     }
     }
 
 
-    current = savePos;
+    currentPos = savePos;
 
 
     return pasting;
     return pasting;
 }
 }

+ 5 - 5
3rdparty/glslang/glslang/MachineIndependent/reflection.cpp

@@ -121,7 +121,7 @@ public:
                 }
                 }
 
 
                 // by convention if this is an arrayed block we ignore the array in the reflection
                 // by convention if this is an arrayed block we ignore the array in the reflection
-                if (type.isArray()) {
+                if (type.isArray() && type.getBasicType() == EbtBlock) {
                     blowUpIOAggregate(input, baseName, TType(type, 0));
                     blowUpIOAggregate(input, baseName, TType(type, 0));
                 } else {               
                 } else {               
                     blowUpIOAggregate(input, baseName, type);
                     blowUpIOAggregate(input, baseName, type);
@@ -130,7 +130,8 @@ public:
                 TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
                 TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
                 if (it == reflection.nameToIndex.end()) {
                 if (it == reflection.nameToIndex.end()) {
                     reflection.nameToIndex[name.c_str()] = (int)ioItems.size();
                     reflection.nameToIndex[name.c_str()] = (int)ioItems.size();
-                    ioItems.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0));
+                    ioItems.push_back(
+                        TObjectReflection(name.c_str(), type, 0, mapToGlType(type), mapToGlArraySize(type), 0));
 
 
                     EShLanguageMask& stages = ioItems.back().stages;
                     EShLanguageMask& stages = ioItems.back().stages;
                     stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
                     stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
@@ -316,8 +317,7 @@ public:
                         newBaseName.append(TString("[") + String(i) + "]");
                         newBaseName.append(TString("[") + String(i) + "]");
                     TList<TIntermBinary*>::const_iterator nextDeref = deref;
                     TList<TIntermBinary*>::const_iterator nextDeref = deref;
                     ++nextDeref;
                     ++nextDeref;
-                    TType derefType(*terminalType, 0);
-                    blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize,
+                    blowUpActiveAggregate(*terminalType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize,
                                           topLevelArrayStride, baseStorage, active);
                                           topLevelArrayStride, baseStorage, active);
 
 
                     if (offset >= 0)
                     if (offset >= 0)
@@ -704,7 +704,7 @@ public:
     // Are we at a level in a dereference chain at which individual active uniform queries are made?
     // Are we at a level in a dereference chain at which individual active uniform queries are made?
     bool isReflectionGranularity(const TType& type)
     bool isReflectionGranularity(const TType& type)
     {
     {
-        return type.getBasicType() != EbtBlock && type.getBasicType() != EbtStruct;
+        return type.getBasicType() != EbtBlock && type.getBasicType() != EbtStruct && !type.isArrayOfArrays();
     }
     }
 
 
     // For a binary operation indexing into an aggregate, chase down the base of the aggregate.
     // For a binary operation indexing into an aggregate, chase down the base of the aggregate.

+ 3 - 0
3rdparty/glslang/gtests/AST.FromFile.cpp

@@ -93,10 +93,13 @@ INSTANTIATE_TEST_CASE_P(
         "cppSimple.vert",
         "cppSimple.vert",
         "cppIndent.vert",
         "cppIndent.vert",
         "cppIntMinOverNegativeOne.frag",
         "cppIntMinOverNegativeOne.frag",
+        "cppMerge.frag",
         "cppNest.vert",
         "cppNest.vert",
         "cppBad.vert",
         "cppBad.vert",
         "cppBad2.vert",
         "cppBad2.vert",
         "cppBad3.vert",
         "cppBad3.vert",
+        "cppBad4.vert",
+        "cppBad5.vert",
         "cppComplexExpr.vert",
         "cppComplexExpr.vert",
         "cppDeepNest.frag",
         "cppDeepNest.frag",
         "cppPassMacroName.frag",
         "cppPassMacroName.frag",

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

@@ -4607,7 +4607,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
         if (nullptr == symbol) {
         if (nullptr == symbol) {
             type.getQualifier().builtIn = builtin;
             type.getQualifier().builtIn = builtin;
 
 
-            TVariable* variable = new TVariable(new TString(name), type);
+            TVariable* variable = new TVariable(NewPoolTString(name), type);
 
 
             symbolTable.insert(*variable);
             symbolTable.insert(*variable);
 
 

+ 1 - 1
3rdparty/glslang/known_good.json

@@ -5,7 +5,7 @@
       "site" : "github",
       "site" : "github",
       "subrepo" : "KhronosGroup/SPIRV-Tools",
       "subrepo" : "KhronosGroup/SPIRV-Tools",
       "subdir" : "External/spirv-tools",
       "subdir" : "External/spirv-tools",
-      "commit" : "117a1fd11f11e9bef9faa563c3d5156cc6ab529c"
+      "commit" : "5994ae2a045015004cce24802dc47c33736486ea"
     },
     },
     {
     {
       "name" : "spirv-tools/external/spirv-headers",
       "name" : "spirv-tools/external/spirv-headers",