Merge remote-tracking branch 'aosp/master-ndk' into merge-shaderc
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 33b4764..e7b22e5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,6 +2,9 @@
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
option(ENABLE_AMD_EXTENSIONS "Enables support of AMD-specific extensions" ON)
+option(ENABLE_GLSLANG_BINARIES "Builds glslangValidator and spirv-remap" ON)
+
+option(ENABLE_NV_EXTENSIONS "Enables support of Nvidia-specific extensions" ON)
enable_testing()
@@ -13,6 +16,10 @@
add_definitions(-DAMD_EXTENSIONS)
endif(ENABLE_AMD_EXTENSIONS)
+if(ENABLE_NV_EXTENSIONS)
+ add_definitions(-DNV_EXTENSIONS)
+endif(ENABLE_NV_EXTENSIONS)
+
if(WIN32)
set(CMAKE_DEBUG_POSTFIX "d")
include(ChooseMSVCCRT.cmake)
@@ -52,7 +59,9 @@
add_subdirectory(glslang)
add_subdirectory(OGLCompilersDLL)
-add_subdirectory(StandAlone)
+if(ENABLE_GLSLANG_BINARIES)
+ add_subdirectory(StandAlone)
+endif()
add_subdirectory(SPIRV)
add_subdirectory(hlsl)
add_subdirectory(gtests)
diff --git a/SPIRV/CMakeLists.txt b/SPIRV/CMakeLists.txt
index 2c65d71..c538e84 100755
--- a/SPIRV/CMakeLists.txt
+++ b/SPIRV/CMakeLists.txt
@@ -33,6 +33,11 @@
GLSL.ext.AMD.h)
endif(ENABLE_AMD_EXTENSIONS)
+if(ENABLE_NV_EXTENSIONS)
+ set(HEADERS
+ GLSL.ext.NV.h)
+endif(ENABLE_NV_EXTENSIONS)
+
add_library(SPIRV STATIC ${SOURCES} ${HEADERS})
set_property(TARGET SPIRV PROPERTY FOLDER glslang)
diff --git a/SPIRV/GLSL.ext.NV.h b/SPIRV/GLSL.ext.NV.h
new file mode 100644
index 0000000..adfcb0f
--- /dev/null
+++ b/SPIRV/GLSL.ext.NV.h
@@ -0,0 +1,49 @@
+/*
+** Copyright (c) 2014-2016 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and/or associated documentation files (the "Materials"),
+** to deal in the Materials without restriction, including without limitation
+** the rights to use, copy, modify, merge, publish, distribute, sublicense,
+** and/or sell copies of the Materials, and to permit persons to whom the
+** Materials are furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Materials.
+**
+** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
+** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
+** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
+** IN THE MATERIALS.
+*/
+
+#ifndef GLSLextNV_H
+#define GLSLextNV_H
+
+enum BuiltIn;
+enum Decoration;
+enum Op;
+
+static const int GLSLextNVVersion = 100;
+static const int GLSLextNVRevision = 2;
+
+//SPV_NV_sample_mask_override_coverage
+const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
+
+static const Decoration OverrideCoverageNV = static_cast<Decoration>(5248);
+
+
+//SPV_NV_geometry_shader_passthrough
+const char* const E_SPV_NV_geometry_shader_passthrough = "SPV_NV_geometry_shader_passthrough";
+
+static const Decoration PassthroughNV = static_cast<Decoration>(5250);
+
+static const Capability GeometryShaderPassthroughNV = static_cast<Capability>(5251);
+#endif // #ifndef GLSLextNV_H
\ No newline at end of file
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 15af947..3c287a7 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -47,6 +47,9 @@
#ifdef AMD_EXTENSIONS
#include "GLSL.ext.AMD.h"
#endif
+#ifdef NV_EXTENSIONS
+ #include "GLSL.ext.NV.h"
+#endif
}
// Glslang includes
@@ -436,6 +439,7 @@
return spv::DecorationMax;
}
+
// Translate a glslang built-in variable to a SPIR-V built in decoration. Also generate
// associated capabilities when required. For some built-in variables, a capability
// is generated only when using the variable in an executable instruction, but not when
@@ -4127,7 +4131,8 @@
spv::Op opCode = spv::OpNop;
std::vector<spv::Id> spvGroupOperands;
- if (op == glslang::EOpBallot || op == glslang::EOpReadFirstInvocation) {
+ if (op == glslang::EOpBallot || op == glslang::EOpReadFirstInvocation ||
+ op == glslang::EOpReadInvocation) {
builder.addExtension(spv::E_SPV_KHR_shader_ballot);
builder.addCapability(spv::CapabilitySubgroupBallotKHR);
} else {
@@ -4167,7 +4172,7 @@
}
case glslang::EOpReadInvocation:
- opCode = spv::OpGroupBroadcast;
+ opCode = spv::OpSubgroupReadInvocationKHR;
if (builder.isVectorType(typeId))
return CreateInvocationsVectorOperation(opCode, typeId, operands);
break;
@@ -4279,13 +4284,15 @@
assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin ||
op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax ||
op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast ||
+ op == spv::OpSubgroupReadInvocationKHR ||
op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD || op == spv::OpGroupSMinNonUniformAMD ||
op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD || op == spv::OpGroupSMaxNonUniformAMD ||
op == spv::OpGroupFAddNonUniformAMD || op == spv::OpGroupIAddNonUniformAMD);
#else
assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin ||
op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax ||
- op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast);
+ op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast ||
+ op == spv::OpSubgroupReadInvocationKHR);
#endif
// Handle group invocation operations scalar by scalar.
@@ -4305,13 +4312,16 @@
std::vector<unsigned int> indexes;
indexes.push_back(comp);
spv::Id scalar = builder.createCompositeExtract(operands[0], scalarType, indexes);
-
std::vector<spv::Id> spvGroupOperands;
- spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
- if (op == spv::OpGroupBroadcast) {
+ if (op == spv::OpSubgroupReadInvocationKHR) {
+ spvGroupOperands.push_back(scalar);
+ spvGroupOperands.push_back(operands[1]);
+ } else if (op == spv::OpGroupBroadcast) {
+ spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
spvGroupOperands.push_back(scalar);
spvGroupOperands.push_back(operands[1]);
} else {
+ spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
spvGroupOperands.push_back(spv::GroupOperationReduce);
spvGroupOperands.push_back(scalar);
}
@@ -4721,6 +4731,26 @@
if (builtIn != spv::BuiltInMax)
addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
+#ifdef NV_EXTENSIONS
+ if (builtIn == spv::BuiltInSampleMask) {
+ spv::Decoration decoration;
+ // GL_NV_sample_mask_override_coverage extension
+ if (glslangIntermediate->getLayoutOverrideCoverage())
+ decoration = (spv::Decoration)spv::OverrideCoverageNV;
+ else
+ decoration = (spv::Decoration)spv::DecorationMax;
+ addDecoration(id, decoration);
+ if (decoration != spv::DecorationMax) {
+ builder.addExtension(spv::E_SPV_NV_sample_mask_override_coverage);
+ }
+ }
+ if (symbol->getQualifier().layoutPassthrough) {
+ addDecoration(id, spv::PassthroughNV);
+ builder.addCapability(spv::GeometryShaderPassthroughNV);
+ builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
+ }
+#endif
+
return id;
}
diff --git a/SPIRV/SPVRemapper.cpp b/SPIRV/SPVRemapper.cpp
index 5c551fb..f30963b 100755
--- a/SPIRV/SPVRemapper.cpp
+++ b/SPIRV/SPVRemapper.cpp
@@ -327,12 +327,10 @@
bound(maxBound); // reset header ID bound to as big as it now needs to be
}
+ // Mark debug instructions for stripping
void spirvbin_t::stripDebug()
{
- if ((options & STRIP) == 0)
- return;
-
- // build local Id and name maps
+ // Strip instructions in the stripOp set: debug info.
process(
[&](spv::Op opCode, unsigned start) {
// remember opcodes we want to strip later
@@ -343,6 +341,32 @@
op_fn_nop);
}
+ // Mark instructions that refer to now-removed IDs for stripping
+ void spirvbin_t::stripDeadRefs()
+ {
+ process(
+ [&](spv::Op opCode, unsigned start) {
+ // strip opcodes pointing to removed data
+ switch (opCode) {
+ case spv::OpName:
+ case spv::OpMemberName:
+ case spv::OpDecorate:
+ case spv::OpMemberDecorate:
+ if (idPosR.find(asId(start+1)) == idPosR.end())
+ stripInst(start);
+ break;
+ default:
+ break; // leave it alone
+ }
+
+ return true;
+ },
+ op_fn_nop);
+
+ strip();
+ }
+
+ // Update local maps of ID, type, etc positions
void spirvbin_t::buildLocalMaps()
{
msg(2, 2, std::string("build local maps: "));
@@ -351,7 +375,6 @@
idMapL.clear();
// preserve nameMap, so we don't clear that.
fnPos.clear();
- fnPosDCE.clear();
fnCalls.clear();
typeConstPos.clear();
idPosR.clear();
@@ -366,10 +389,6 @@
// build local Id and name maps
process(
[&](spv::Op opCode, unsigned start) {
- // remember opcodes we want to strip later
- if ((options & STRIP) && isStripOp(opCode))
- stripInst(start);
-
unsigned word = start+1;
spv::Id typeId = spv::NoResult;
@@ -957,7 +976,6 @@
if (call_it == fnCalls.end() || call_it->second == 0) {
changed = true;
stripRange.push_back(fn->second);
- fnPosDCE.insert(*fn);
// decrease counts of called functions
process(
@@ -1011,11 +1029,15 @@
// Remove single-use function variables + associated decorations and names
process(
[&](spv::Op opCode, unsigned start) {
- if ((opCode == spv::OpVariable && varUseCount[asId(start+2)] == 1) ||
- (opCode == spv::OpDecorate && varUseCount[asId(start+1)] == 1) ||
- (opCode == spv::OpName && varUseCount[asId(start+1)] == 1)) {
- stripInst(start);
- }
+ spv::Id id = spv::NoResult;
+ if (opCode == spv::OpVariable)
+ id = asId(start+2);
+ if (opCode == spv::OpDecorate || opCode == spv::OpName)
+ id = asId(start+1);
+
+ if (id != spv::NoResult && varUseCount[id] == 1)
+ stripInst(start);
+
return true;
},
op_fn_nop);
@@ -1276,25 +1298,31 @@
// Set up opcode tables from SpvDoc
spv::Parameterize();
- validate(); // validate header
- buildLocalMaps();
+ validate(); // validate header
+ buildLocalMaps(); // build ID maps
msg(3, 4, std::string("ID bound: ") + std::to_string(bound()));
+ if (options & STRIP) stripDebug();
strip(); // strip out data we decided to eliminate
if (options & OPT_LOADSTORE) optLoadStore();
if (options & OPT_FWD_LS) forwardLoadStores();
if (options & DCE_FUNCS) dceFuncs();
if (options & DCE_VARS) dceVars();
if (options & DCE_TYPES) dceTypes();
- strip(); // strip out data we decided to eliminate
+
+ strip(); // strip out data we decided to eliminate
+ stripDeadRefs(); // remove references to things we DCEed
+ // after the last strip, we must clean any debug info referring to now-deleted data
if (options & MAP_TYPES) mapTypeConst();
if (options & MAP_NAMES) mapNames();
if (options & MAP_FUNCS) mapFnBodies();
- mapRemainder(); // map any unmapped IDs
- applyMap(); // Now remap each shader to the new IDs we've come up with
+ if (options & MAP_ALL) {
+ mapRemainder(); // map any unmapped IDs
+ applyMap(); // Now remap each shader to the new IDs we've come up with
+ }
}
// remap from a memory image
diff --git a/SPIRV/SPVRemapper.h b/SPIRV/SPVRemapper.h
index b3c686a..77c9658 100755
--- a/SPIRV/SPVRemapper.h
+++ b/SPIRV/SPVRemapper.h
@@ -239,7 +239,8 @@
void applyMap(); // remap per local name map
void mapRemainder(); // map any IDs we haven't touched yet
- void stripDebug(); // strip debug info
+ void stripDebug(); // strip all debug info
+ void stripDeadRefs(); // strips debug info for now-dead references after DCE
void strip(); // remove debug symbols
std::vector<spirword_t> spv; // SPIR words
@@ -264,7 +265,6 @@
// Function start and end. use unordered_map because we'll have
// many fewer functions than IDs.
std::unordered_map<spv::Id, range_t> fnPos;
- std::unordered_map<spv::Id, range_t> fnPosDCE; // deleted functions
// Which functions are called, anywhere in the module, with a call count
std::unordered_map<spv::Id, int> fnCalls;
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 04b0f04..b0b74b2 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -2144,6 +2144,7 @@
std::vector<unsigned> oldSwizzle = accessChain.swizzle;
accessChain.swizzle.resize(0);
for (unsigned int i = 0; i < swizzle.size(); ++i) {
+ assert(swizzle[i] < oldSwizzle.size());
accessChain.swizzle.push_back(oldSwizzle[swizzle[i]]);
}
} else
diff --git a/SPIRV/disassemble.cpp b/SPIRV/disassemble.cpp
index b1023b9..cbc9a9b 100644
--- a/SPIRV/disassemble.cpp
+++ b/SPIRV/disassemble.cpp
@@ -54,6 +54,9 @@
#ifdef AMD_EXTENSIONS
#include "GLSL.ext.AMD.h"
#endif
+#ifdef NV_EXTENSIONS
+ #include "GLSL.ext.NV.h"
+#endif
}
}
const char* GlslStd450DebugNames[spv::GLSLstd450Count];
@@ -64,6 +67,10 @@
static const char* GLSLextAMDGetDebugNames(const char*, unsigned);
#endif
+#ifdef NV_EXTENSIONS
+static const char* GLSLextNVGetDebugNames(const char*, unsigned);
+#endif
+
static void Kill(std::ostream& out, const char* message)
{
out << std::endl << "Disassembly failed: " << message << std::endl;
@@ -76,6 +83,9 @@
#ifdef AMD_EXTENSIONS
GLSLextAMDInst,
#endif
+#ifdef NV_EXTENSIONS
+ GLSLextNVInst,
+#endif
OpenCLExtInst,
};
@@ -470,6 +480,11 @@
strcmp(spv::E_SPV_AMD_gcn_shader, name) == 0) {
extInstSet = GLSLextAMDInst;
#endif
+#ifdef NV_EXTENSIONS
+ }else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 ||
+ strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0) {
+ extInstSet = GLSLextNVInst;
+#endif
}
unsigned entrypoint = stream[word - 1];
if (extInstSet == GLSL450Inst) {
@@ -480,6 +495,11 @@
} else if (extInstSet == GLSLextAMDInst) {
out << "(" << GLSLextAMDGetDebugNames(name, entrypoint) << ")";
#endif
+#ifdef NV_EXTENSIONS
+ }
+ else if (extInstSet == GLSLextNVInst) {
+ out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
+#endif
}
}
break;
@@ -631,6 +651,23 @@
}
#endif
+
+#ifdef NV_EXTENSIONS
+static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
+{
+ if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0 ||
+ strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0) {
+ switch (entrypoint) {
+ case OverrideCoverageNV: return "OverrideCoverageNV";
+ case PassthroughNV: return "PassthroughNV";
+ case GeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
+ default: return "Bad";
+ }
+ }
+ return "Bad";
+}
+#endif
+
void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
{
SpirvStream SpirvStream(out, stream);
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index 0e68c7e..b20944f 100755
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -51,6 +51,9 @@
#ifdef AMD_EXTENSIONS
#include "GLSL.ext.AMD.h"
#endif
+#ifdef NV_EXTENSIONS
+ #include "GLSL.ext.NV.h"
+#endif
}
}
@@ -256,6 +259,10 @@
#ifdef AMD_EXTENSIONS
case 4999: return "ExplicitInterpAMD";
#endif
+#ifdef NV_EXTENSIONS
+ case 5248: return "OverrideCoverageNV";
+ case 5250: return "PassthroughNV";
+#endif
}
}
@@ -812,6 +819,11 @@
case 4423: return "SubgroupBallotKHR";
case 4427: return "DrawParameters";
+
+#ifdef NV_EXTENSIONS
+ case 5251: return "GeometryShaderPassthroughNV";
+#endif
+
}
}
@@ -1146,6 +1158,7 @@
case 4421: return "OpSubgroupBallotKHR";
case 4422: return "OpSubgroupFirstInvocationKHR";
+ case 4432: return "OpSubgroupReadInvocationKHR";
#ifdef AMD_EXTENSIONS
case 5000: return "OpGroupIAddNonUniformAMD";
@@ -2758,6 +2771,10 @@
InstructionDesc[OpSubgroupFirstInvocationKHR].operands.push(OperandId, "'Value'");
+ InstructionDesc[OpSubgroupReadInvocationKHR].capabilities.push_back(CapabilityGroups);
+ InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Value'");
+ InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Index'");
+
#ifdef AMD_EXTENSIONS
InstructionDesc[OpGroupIAddNonUniformAMD].capabilities.push_back(CapabilityGroups);
InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandScope, "'Execution'");
diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp
index bb3c3f4..088b1af 100755
--- a/SPIRV/spirv.hpp
+++ b/SPIRV/spirv.hpp
@@ -905,6 +905,7 @@
OpImageSparseRead = 320,
OpSubgroupBallotKHR = 4421,
OpSubgroupFirstInvocationKHR = 4422,
+ OpSubgroupReadInvocationKHR = 4432,
OpMax = 0x7fffffff,
};
diff --git a/Test/baseResults/120.vert.out b/Test/baseResults/120.vert.out
index 94a97b5..c63d95a 100644
--- a/Test/baseResults/120.vert.out
+++ b/Test/baseResults/120.vert.out
@@ -77,9 +77,8 @@
ERROR: 0:192: 'assign' : l-value required (can't modify a const)
ERROR: 0:195: 'gl_ModelViewMatrix' : identifiers starting with "gl_" are reserved
ERROR: 0:200: 'token pasting (##)' : not supported for this version or the enabled extensions
-ERROR: 0:200: '##' : token pasting not implemented (internal error)
-ERROR: 0:200: '' : syntax error
-ERROR: 80 compilation errors. No code generated.
+ERROR: 0:203: 'token pasting (##)' : not supported for this version or the enabled extensions
+ERROR: 79 compilation errors. No code generated.
Shader version: 120
@@ -427,7 +426,8 @@
0:? 'c2D' (in 2-component vector of float)
0:? 'c3D' (in 3-component vector of float)
0:? 'v4' (uniform 4-component vector of float)
-0:? 'abc' (global int)
+0:? 'abcdef' (global int)
+0:? 'qrstuv' (global int)
Linked vertex stage:
@@ -499,5 +499,6 @@
0:? 'c2D' (in 2-component vector of float)
0:? 'c3D' (in 3-component vector of float)
0:? 'v4' (uniform 4-component vector of float)
-0:? 'abc' (global int)
+0:? 'abcdef' (global int)
+0:? 'qrstuv' (global int)
diff --git a/Test/baseResults/130.vert.out b/Test/baseResults/130.vert.out
index 1b3a0e1..7ca32a1 100644
--- a/Test/baseResults/130.vert.out
+++ b/Test/baseResults/130.vert.out
@@ -3,9 +3,7 @@
ERROR: 0:59: '=' : cannot convert from 'temp float' to 'temp int'
ERROR: 0:61: 'texelFetch' : no matching overloaded function found
ERROR: 0:61: 'assign' : cannot convert from 'const float' to 'temp int'
-ERROR: 0:75: '##' : token pasting not implemented (internal error)
-ERROR: 0:75: '' : syntax error
-ERROR: 6 compilation errors. No code generated.
+ERROR: 4 compilation errors. No code generated.
Shader version: 130
@@ -149,7 +147,8 @@
0:? 'v4' (uniform 4-component vector of float)
0:? 'gl_ClipDistance' (smooth out implicitly-sized array of float ClipDistance)
0:? 'gl_TexCoord' (smooth out implicitly-sized array of 4-component vector of float TexCoord)
-0:? 'abc' (global int)
+0:? 'abcdef' (global int)
+0:? 'qrstuv' (global int)
0:? 'gl_VertexID' (gl_VertexId int VertexId)
@@ -281,6 +280,7 @@
0:? 'v4' (uniform 4-component vector of float)
0:? 'gl_ClipDistance' (smooth out 2-element array of float ClipDistance)
0:? 'gl_TexCoord' (smooth out 1-element array of 4-component vector of float TexCoord)
-0:? 'abc' (global int)
+0:? 'abcdef' (global int)
+0:? 'qrstuv' (global int)
0:? 'gl_VertexID' (gl_VertexId int VertexId)
diff --git a/Test/baseResults/cppBad.vert.out b/Test/baseResults/cppBad.vert.out
index 1fb18ec..d808e72 100755
--- a/Test/baseResults/cppBad.vert.out
+++ b/Test/baseResults/cppBad.vert.out
@@ -3,8 +3,9 @@
ERROR: 0:2: '#if' : unexpected tokens following directive
ERROR: 0:5: 'string' : End of line in string
ERROR: 0:5: 'macro expansion' : expected '(' following n
+ERROR: 0:5: '""' : string literals not supported
ERROR: 0:5: '' : syntax error
-ERROR: 5 compilation errors. No code generated.
+ERROR: 6 compilation errors. No code generated.
Shader version: 100
diff --git a/Test/baseResults/hlsl.array.implicit-size.frag.out b/Test/baseResults/hlsl.array.implicit-size.frag.out
index 5674cb4..5f20362 100644
--- a/Test/baseResults/hlsl.array.implicit-size.frag.out
+++ b/Test/baseResults/hlsl.array.implicit-size.frag.out
@@ -41,38 +41,38 @@
0:28 1.000000
0:28 2.000000
0:28 3.000000
-0:30 move second child to first child (temp 4-component vector of float)
-0:30 color: direct index for structure (temp 4-component vector of float)
-0:30 'ps_output' (out structure{temp 4-component vector of float color})
-0:30 Constant:
-0:30 0 (const int)
-0:30 Construct vec4 (temp 4-component vector of float)
-0:30 add (temp float)
-0:30 add (temp float)
-0:30 add (temp float)
-0:30 add (temp float)
-0:30 direct index (temp float)
-0:30 'g_array' (global 5-element array of float)
-0:30 Constant:
-0:30 0 (const int)
-0:30 direct index (temp float)
-0:30 'g_array' (global 5-element array of float)
-0:30 Constant:
-0:30 4 (const int)
-0:30 direct index (temp float)
-0:30 'l_array' (temp 3-element array of float)
-0:30 Constant:
-0:30 1 (const int)
-0:30 f: direct index for structure (temp float)
-0:30 direct index (temp structure{temp int i, temp float f})
-0:30 'g_mystruct' (global 2-element array of structure{temp int i, temp float f})
-0:30 Constant:
-0:30 0 (const int)
-0:30 Constant:
-0:30 1 (const int)
-0:30 indirect index (temp float)
-0:30 'g_array' (global 5-element array of float)
-0:30 'idx' (temp void)
+0:31 move second child to first child (temp 4-component vector of float)
+0:31 color: direct index for structure (temp 4-component vector of float)
+0:31 'ps_output' (out structure{temp 4-component vector of float color})
+0:31 Constant:
+0:31 0 (const int)
+0:31 Construct vec4 (temp 4-component vector of float)
+0:31 add (temp float)
+0:31 add (temp float)
+0:31 add (temp float)
+0:31 add (temp float)
+0:31 direct index (temp float)
+0:31 'g_array' (global 5-element array of float)
+0:31 Constant:
+0:31 0 (const int)
+0:31 direct index (temp float)
+0:31 'g_array' (global 5-element array of float)
+0:31 Constant:
+0:31 4 (const int)
+0:31 direct index (temp float)
+0:31 'l_array' (temp 3-element array of float)
+0:31 Constant:
+0:31 1 (const int)
+0:31 f: direct index for structure (temp float)
+0:31 direct index (temp structure{temp int i, temp float f})
+0:31 'g_mystruct' (global 2-element array of structure{temp int i, temp float f})
+0:31 Constant:
+0:31 0 (const int)
+0:31 Constant:
+0:31 1 (const int)
+0:31 indirect index (temp float)
+0:31 'g_array' (global 5-element array of float)
+0:31 'idx' (temp int)
0:? Linker Objects
0:? 'g_array' (global 5-element array of float)
0:? 'g_array_unused' (global 7-element array of float)
@@ -125,38 +125,38 @@
0:28 1.000000
0:28 2.000000
0:28 3.000000
-0:30 move second child to first child (temp 4-component vector of float)
-0:30 color: direct index for structure (temp 4-component vector of float)
-0:30 'ps_output' (out structure{temp 4-component vector of float color})
-0:30 Constant:
-0:30 0 (const int)
-0:30 Construct vec4 (temp 4-component vector of float)
-0:30 add (temp float)
-0:30 add (temp float)
-0:30 add (temp float)
-0:30 add (temp float)
-0:30 direct index (temp float)
-0:30 'g_array' (global 5-element array of float)
-0:30 Constant:
-0:30 0 (const int)
-0:30 direct index (temp float)
-0:30 'g_array' (global 5-element array of float)
-0:30 Constant:
-0:30 4 (const int)
-0:30 direct index (temp float)
-0:30 'l_array' (temp 3-element array of float)
-0:30 Constant:
-0:30 1 (const int)
-0:30 f: direct index for structure (temp float)
-0:30 direct index (temp structure{temp int i, temp float f})
-0:30 'g_mystruct' (global 2-element array of structure{temp int i, temp float f})
-0:30 Constant:
-0:30 0 (const int)
-0:30 Constant:
-0:30 1 (const int)
-0:30 indirect index (temp float)
-0:30 'g_array' (global 5-element array of float)
-0:30 'idx' (temp void)
+0:31 move second child to first child (temp 4-component vector of float)
+0:31 color: direct index for structure (temp 4-component vector of float)
+0:31 'ps_output' (out structure{temp 4-component vector of float color})
+0:31 Constant:
+0:31 0 (const int)
+0:31 Construct vec4 (temp 4-component vector of float)
+0:31 add (temp float)
+0:31 add (temp float)
+0:31 add (temp float)
+0:31 add (temp float)
+0:31 direct index (temp float)
+0:31 'g_array' (global 5-element array of float)
+0:31 Constant:
+0:31 0 (const int)
+0:31 direct index (temp float)
+0:31 'g_array' (global 5-element array of float)
+0:31 Constant:
+0:31 4 (const int)
+0:31 direct index (temp float)
+0:31 'l_array' (temp 3-element array of float)
+0:31 Constant:
+0:31 1 (const int)
+0:31 f: direct index for structure (temp float)
+0:31 direct index (temp structure{temp int i, temp float f})
+0:31 'g_mystruct' (global 2-element array of structure{temp int i, temp float f})
+0:31 Constant:
+0:31 0 (const int)
+0:31 Constant:
+0:31 1 (const int)
+0:31 indirect index (temp float)
+0:31 'g_array' (global 5-element array of float)
+0:31 'idx' (temp int)
0:? Linker Objects
0:? 'g_array' (global 5-element array of float)
0:? 'g_array_unused' (global 7-element array of float)
@@ -228,7 +228,7 @@
49: TypePointer Private 6(float)
52: 32(int) Constant 4
56: TypePointer Function 6(float)
- 63: TypePointer Function 2
+ 63: TypePointer Function 32(int)
70: TypePointer Function 7(fvec4)
4(PixelShaderFunction): 2 Function None 3
5: Label
@@ -254,7 +254,7 @@
60: 49(ptr) AccessChain 37(g_mystruct) 48 38
61: 6(float) Load 60
62: 6(float) FAdd 59 61
- 65: 2 Load 64(idx)
+ 65: 32(int) Load 64(idx)
66: 49(ptr) AccessChain 18(g_array) 65
67: 6(float) Load 66
68: 6(float) FAdd 62 67
diff --git a/Test/baseResults/hlsl.identifier.sample.frag.out b/Test/baseResults/hlsl.identifier.sample.frag.out
index 8e74081..35e88e9 100644
--- a/Test/baseResults/hlsl.identifier.sample.frag.out
+++ b/Test/baseResults/hlsl.identifier.sample.frag.out
@@ -12,18 +12,27 @@
0:12 Function Parameters:
0:? Sequence
0:15 Sequence
-0:15 move second child to first child (temp int)
-0:15 'sample' (temp int)
-0:15 Constant:
-0:15 3 (const int)
+0:15 move second child to first child (temp 4-component vector of float)
+0:15 'sample' (temp 4-component vector of float)
+0:? Constant:
+0:? 3.000000
+0:? 4.000000
+0:? 5.000000
+0:? 6.000000
0:17 Sequence
0:17 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
-0:? Constant:
-0:? 0.000000
-0:? 0.000000
-0:? 0.000000
-0:? 0.000000
+0:17 vector swizzle (temp 4-component vector of float)
+0:17 'sample' (temp 4-component vector of float)
+0:17 Sequence
+0:17 Constant:
+0:17 0 (const int)
+0:17 Constant:
+0:17 1 (const int)
+0:17 Constant:
+0:17 2 (const int)
+0:17 Constant:
+0:17 3 (const int)
0:17 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
@@ -45,54 +54,67 @@
0:12 Function Parameters:
0:? Sequence
0:15 Sequence
-0:15 move second child to first child (temp int)
-0:15 'sample' (temp int)
-0:15 Constant:
-0:15 3 (const int)
+0:15 move second child to first child (temp 4-component vector of float)
+0:15 'sample' (temp 4-component vector of float)
+0:? Constant:
+0:? 3.000000
+0:? 4.000000
+0:? 5.000000
+0:? 6.000000
0:17 Sequence
0:17 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
-0:? Constant:
-0:? 0.000000
-0:? 0.000000
-0:? 0.000000
-0:? 0.000000
+0:17 vector swizzle (temp 4-component vector of float)
+0:17 'sample' (temp 4-component vector of float)
+0:17 Sequence
+0:17 Constant:
+0:17 0 (const int)
+0:17 Constant:
+0:17 1 (const int)
+0:17 Constant:
+0:17 2 (const int)
+0:17 Constant:
+0:17 3 (const int)
0:17 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 24
+// Id's are bound by 28
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "main" 20
+ EntryPoint Fragment 4 "main" 25
ExecutionMode 4 OriginUpperLeft
Name 4 "main"
Name 10 "sample(i1;"
Name 9 "x"
- Name 15 "sample"
- Name 20 "@entryPointOutput"
- Decorate 20(@entryPointOutput) Location 0
+ Name 18 "sample"
+ Name 25 "@entryPointOutput"
+ Decorate 25(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
8: TypeFunction 6(int) 7(ptr)
- 16: 6(int) Constant 3
- 17: TypeFloat 32
- 18: TypeVector 17(float) 4
- 19: TypePointer Output 18(fvec4)
-20(@entryPointOutput): 19(ptr) Variable Output
- 21: 17(float) Constant 0
- 22: 18(fvec4) ConstantComposite 21 21 21 21
+ 15: TypeFloat 32
+ 16: TypeVector 15(float) 4
+ 17: TypePointer Function 16(fvec4)
+ 19: 15(float) Constant 1077936128
+ 20: 15(float) Constant 1082130432
+ 21: 15(float) Constant 1084227584
+ 22: 15(float) Constant 1086324736
+ 23: 16(fvec4) ConstantComposite 19 20 21 22
+ 24: TypePointer Output 16(fvec4)
+25(@entryPointOutput): 24(ptr) Variable Output
4(main): 2 Function None 3
5: Label
- 15(sample): 7(ptr) Variable Function
- Store 15(sample) 16
- Store 20(@entryPointOutput) 22
+ 18(sample): 17(ptr) Variable Function
+ Store 18(sample) 23
+ 26: 16(fvec4) Load 18(sample)
+ Store 25(@entryPointOutput) 26
Return
FunctionEnd
10(sample(i1;): 6(int) Function None 8
diff --git a/Test/baseResults/remap.basic.dcefunc.frag.out b/Test/baseResults/remap.basic.dcefunc.frag.out
index 99b4d55..c28d90a 100644
--- a/Test/baseResults/remap.basic.dcefunc.frag.out
+++ b/Test/baseResults/remap.basic.dcefunc.frag.out
@@ -3,34 +3,33 @@
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 19
+// Id's are bound by 22
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "main" 14 16
+ EntryPoint Fragment 4 "main" 17 19
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
- Name 9 "dead_fn("
- Name 14 "outf4"
- Name 16 "inf"
+ Name 17 "outf4"
+ Name 19 "inf"
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 3
8: TypeFunction 7(fvec3)
- 10: 6(float) Constant 0
- 11: 7(fvec3) ConstantComposite 10 10 10
- 12: TypeVector 6(float) 4
- 13: TypePointer Output 12(fvec4)
- 14(outf4): 13(ptr) Variable Output
- 15: TypePointer Input 6(float)
- 16(inf): 15(ptr) Variable Input
+ 11: 6(float) Constant 0
+ 12: 7(fvec3) ConstantComposite 11 11 11
+ 15: TypeVector 6(float) 4
+ 16: TypePointer Output 15(fvec4)
+ 17(outf4): 16(ptr) Variable Output
+ 18: TypePointer Input 6(float)
+ 19(inf): 18(ptr) Variable Input
4(main): 2 Function None 3
5: Label
- 17: 6(float) Load 16(inf)
- 18: 12(fvec4) CompositeConstruct 17 17 17 17
- Store 14(outf4) 18
+ 20: 6(float) Load 19(inf)
+ 21: 15(fvec4) CompositeConstruct 20 20 20 20
+ Store 17(outf4) 21
Return
FunctionEnd
diff --git a/Test/baseResults/remap.basic.none.frag.out b/Test/baseResults/remap.basic.none.frag.out
index 39e56b2..44f5747 100644
--- a/Test/baseResults/remap.basic.none.frag.out
+++ b/Test/baseResults/remap.basic.none.frag.out
@@ -3,18 +3,18 @@
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 20
+// Id's are bound by 22
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "main" 15 17
+ EntryPoint Fragment 4 "main" 17 19
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
Name 9 "dead_fn("
- Name 15 "outf4"
- Name 17 "inf"
+ Name 17 "outf4"
+ Name 19 "inf"
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@@ -22,16 +22,16 @@
8: TypeFunction 7(fvec3)
11: 6(float) Constant 0
12: 7(fvec3) ConstantComposite 11 11 11
- 13: TypeVector 6(float) 4
- 14: TypePointer Output 13(fvec4)
- 15(outf4): 14(ptr) Variable Output
- 16: TypePointer Input 6(float)
- 17(inf): 16(ptr) Variable Input
+ 15: TypeVector 6(float) 4
+ 16: TypePointer Output 15(fvec4)
+ 17(outf4): 16(ptr) Variable Output
+ 18: TypePointer Input 6(float)
+ 19(inf): 18(ptr) Variable Input
4(main): 2 Function None 3
5: Label
- 18: 6(float) Load 17(inf)
- 19: 13(fvec4) CompositeConstruct 18 18 18 18
- Store 15(outf4) 19
+ 20: 6(float) Load 19(inf)
+ 21: 15(fvec4) CompositeConstruct 20 20 20 20
+ Store 17(outf4) 21
Return
FunctionEnd
9(dead_fn(): 7(fvec3) Function None 8
diff --git a/Test/baseResults/remap.basic.strip.frag.out b/Test/baseResults/remap.basic.strip.frag.out
index 27c0874..ab1a003 100644
--- a/Test/baseResults/remap.basic.strip.frag.out
+++ b/Test/baseResults/remap.basic.strip.frag.out
@@ -3,12 +3,12 @@
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 20
+// Id's are bound by 22
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "main" 15 17
+ EntryPoint Fragment 4 "main" 17 19
ExecutionMode 4 OriginUpperLeft
2: TypeVoid
3: TypeFunction 2
@@ -17,16 +17,16 @@
8: TypeFunction 7(fvec3)
11: 6(float) Constant 0
12: 7(fvec3) ConstantComposite 11 11 11
- 13: TypeVector 6(float) 4
- 14: TypePointer Output 13(fvec4)
- 15: 14(ptr) Variable Output
- 16: TypePointer Input 6(float)
- 17: 16(ptr) Variable Input
+ 15: TypeVector 6(float) 4
+ 16: TypePointer Output 15(fvec4)
+ 17: 16(ptr) Variable Output
+ 18: TypePointer Input 6(float)
+ 19: 18(ptr) Variable Input
4: 2 Function None 3
5: Label
- 18: 6(float) Load 17
- 19: 13(fvec4) CompositeConstruct 18 18 18 18
- Store 15 19
+ 20: 6(float) Load 19
+ 21: 15(fvec4) CompositeConstruct 20 20 20 20
+ Store 17 21
Return
FunctionEnd
9: 7(fvec3) Function None 8
diff --git a/Test/baseResults/remap.hlsl.sample.basic.none.frag.out b/Test/baseResults/remap.hlsl.sample.basic.none.frag.out
index 28c384c..51ad1a8 100644
--- a/Test/baseResults/remap.hlsl.sample.basic.none.frag.out
+++ b/Test/baseResults/remap.hlsl.sample.basic.none.frag.out
@@ -3,7 +3,7 @@
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 190
+// Id's are bound by 191
Capability Shader
Capability Sampled1D
@@ -57,9 +57,9 @@
Name 173 "psout"
Name 180 "Color"
Name 184 "Depth"
- Name 187 "g_sSamp2d"
- Name 188 "g_sSamp2D_b"
- Name 189 "g_tTex1df4a"
+ Name 188 "g_sSamp2d"
+ Name 189 "g_sSamp2D_b"
+ Name 190 "g_tTex1df4a"
Decorate 41(g_tTex1df4) DescriptorSet 0
Decorate 41(g_tTex1df4) Binding 0
Decorate 45(g_sSamp) DescriptorSet 0
@@ -77,10 +77,10 @@
Decorate 165(g_tTexcdu4) DescriptorSet 0
Decorate 180(Color) Location 0
Decorate 184(Depth) BuiltIn FragDepth
- Decorate 187(g_sSamp2d) DescriptorSet 0
- Decorate 188(g_sSamp2D_b) DescriptorSet 0
- Decorate 189(g_tTex1df4a) DescriptorSet 0
- Decorate 189(g_tTex1df4a) Binding 1
+ Decorate 188(g_sSamp2d) DescriptorSet 0
+ Decorate 189(g_sSamp2D_b) DescriptorSet 0
+ Decorate 190(g_tTex1df4a) DescriptorSet 0
+ Decorate 190(g_tTex1df4a) Binding 1
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
@@ -184,9 +184,9 @@
180(Color): 179(ptr) Variable Output
183: TypePointer Output 35(float)
184(Depth): 183(ptr) Variable Output
- 187(g_sSamp2d): 44(ptr) Variable UniformConstant
-188(g_sSamp2D_b): 44(ptr) Variable UniformConstant
-189(g_tTex1df4a): 40(ptr) Variable UniformConstant
+ 188(g_sSamp2d): 44(ptr) Variable UniformConstant
+189(g_sSamp2D_b): 44(ptr) Variable UniformConstant
+190(g_tTex1df4a): 40(ptr) Variable UniformConstant
4(main): 2 Function None 3
5: Label
9(mtest): 8(ptr) Variable Function
diff --git a/Test/baseResults/remap.hlsl.sample.basic.strip.frag.out b/Test/baseResults/remap.hlsl.sample.basic.strip.frag.out
index 10a8938..f95d7ef 100644
--- a/Test/baseResults/remap.hlsl.sample.basic.strip.frag.out
+++ b/Test/baseResults/remap.hlsl.sample.basic.strip.frag.out
@@ -3,7 +3,7 @@
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 190
+// Id's are bound by 191
Capability Shader
Capability Sampled1D
@@ -28,10 +28,10 @@
Decorate 165 DescriptorSet 0
Decorate 180 Location 0
Decorate 184 BuiltIn FragDepth
- Decorate 187 DescriptorSet 0
Decorate 188 DescriptorSet 0
Decorate 189 DescriptorSet 0
- Decorate 189 Binding 1
+ Decorate 190 DescriptorSet 0
+ Decorate 190 Binding 1
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
@@ -135,9 +135,9 @@
180: 179(ptr) Variable Output
183: TypePointer Output 35(float)
184: 183(ptr) Variable Output
- 187: 44(ptr) Variable UniformConstant
188: 44(ptr) Variable UniformConstant
- 189: 40(ptr) Variable UniformConstant
+ 189: 44(ptr) Variable UniformConstant
+ 190: 40(ptr) Variable UniformConstant
4: 2 Function None 3
5: Label
9: 8(ptr) Variable Function
diff --git a/Test/baseResults/remap.hlsl.templatetypes.none.frag.out b/Test/baseResults/remap.hlsl.templatetypes.none.frag.out
index c3fab1a..027f020 100644
--- a/Test/baseResults/remap.hlsl.templatetypes.none.frag.out
+++ b/Test/baseResults/remap.hlsl.templatetypes.none.frag.out
@@ -1,13 +1,13 @@
remap.hlsl.templatetypes.none.frag
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 149
+// Id's are bound by 150
Capability Shader
Capability Float64
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "main" 146 148
+ EntryPoint Fragment 4 "main" 146 149
ExecutionMode 4 OriginUpperLeft
Name 4 "main"
Name 9 "r00"
@@ -39,9 +39,9 @@
Name 136 "r65"
Name 141 "r66"
Name 146 "@entryPointOutput"
- Name 148 "input"
+ Name 149 "input"
Decorate 146(@entryPointOutput) Location 0
- Decorate 148(input) Location 0
+ Decorate 149(input) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@@ -157,8 +157,8 @@
144: 139 ConstantComposite 72 126 142 143
145: TypePointer Output 6(float)
146(@entryPointOutput): 145(ptr) Variable Output
- 147: TypePointer Input 7(fvec4)
- 148(input): 147(ptr) Variable Input
+ 148: TypePointer Input 7(fvec4)
+ 149(input): 148(ptr) Variable Input
4(main): 2 Function None 3
5: Label
9(r00): 8(ptr) Variable Function
diff --git a/Test/baseResults/remap.similar_1a.none.frag.out b/Test/baseResults/remap.similar_1a.none.frag.out
index ad1273a..910ef42 100644
--- a/Test/baseResults/remap.similar_1a.none.frag.out
+++ b/Test/baseResults/remap.similar_1a.none.frag.out
@@ -3,12 +3,12 @@
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 82
+// Id's are bound by 86
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "main" 50 69 71
+ EntryPoint Fragment 4 "main" 53 73 75
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
@@ -18,13 +18,13 @@
Name 13 "bound"
Name 17 "r"
Name 19 "x"
- Name 42 "param"
- Name 50 "ini4"
- Name 69 "outf4"
- Name 71 "inf"
- Name 74 "param"
+ Name 44 "param"
+ Name 53 "ini4"
+ Name 73 "outf4"
+ Name 75 "inf"
Name 78 "param"
- Decorate 50(ini4) Flat
+ Name 82 "param"
+ Decorate 53(ini4) Flat
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
@@ -37,35 +37,35 @@
28: TypeBool
30: 8(float) Constant 1056964608
34: 6(int) Constant 1
- 38: 6(int) Constant 2
- 48: TypeVector 6(int) 4
- 49: TypePointer Input 48(ivec4)
- 50(ini4): 49(ptr) Variable Input
- 51: TypeInt 32 0
- 52: 51(int) Constant 1
- 53: TypePointer Input 6(int)
- 56: 51(int) Constant 2
- 61: 51(int) Constant 0
- 67: TypeVector 8(float) 4
- 68: TypePointer Output 67(fvec4)
- 69(outf4): 68(ptr) Variable Output
- 70: TypePointer Input 8(float)
- 71(inf): 70(ptr) Variable Input
+ 40: 6(int) Constant 2
+ 51: TypeVector 6(int) 4
+ 52: TypePointer Input 51(ivec4)
+ 53(ini4): 52(ptr) Variable Input
+ 54: TypeInt 32 0
+ 55: 54(int) Constant 1
+ 56: TypePointer Input 6(int)
+ 59: 54(int) Constant 2
+ 64: 54(int) Constant 0
+ 71: TypeVector 8(float) 4
+ 72: TypePointer Output 71(fvec4)
+ 73(outf4): 72(ptr) Variable Output
+ 74: TypePointer Input 8(float)
+ 75(inf): 74(ptr) Variable Input
4(main): 2 Function None 3
5: Label
- 74(param): 7(ptr) Variable Function
78(param): 7(ptr) Variable Function
- 72: 8(float) Load 71(inf)
- 73: 6(int) ConvertFToS 72
- Store 74(param) 73
- 75: 8(float) FunctionCall 11(Test1(i1;) 74(param)
- 76: 8(float) Load 71(inf)
+ 82(param): 7(ptr) Variable Function
+ 76: 8(float) Load 75(inf)
77: 6(int) ConvertFToS 76
Store 78(param) 77
- 79: 8(float) FunctionCall 14(Test2(i1;) 78(param)
- 80: 8(float) FAdd 75 79
- 81: 67(fvec4) CompositeConstruct 80 80 80 80
- Store 69(outf4) 81
+ 79: 8(float) FunctionCall 11(Test1(i1;) 78(param)
+ 80: 8(float) Load 75(inf)
+ 81: 6(int) ConvertFToS 80
+ Store 82(param) 81
+ 83: 8(float) FunctionCall 14(Test2(i1;) 82(param)
+ 84: 8(float) FAdd 79 83
+ 85: 71(fvec4) CompositeConstruct 84 84 84 84
+ Store 73(outf4) 85
Return
FunctionEnd
11(Test1(i1;): 8(float) Function None 9
@@ -101,31 +101,31 @@
14(Test2(i1;): 8(float) Function None 9
13(bound): 7(ptr) FunctionParameter
15: Label
- 42(param): 7(ptr) Variable Function
- 37: 6(int) Load 13(bound)
- 39: 28(bool) SGreaterThan 37 38
- SelectionMerge 41 None
- BranchConditional 39 40 45
- 40: Label
- 43: 6(int) Load 13(bound)
- Store 42(param) 43
- 44: 8(float) FunctionCall 11(Test1(i1;) 42(param)
- ReturnValue 44
- 45: Label
- 46: 6(int) Load 13(bound)
- 47: 6(int) IMul 46 38
- 54: 53(ptr) AccessChain 50(ini4) 52
- 55: 6(int) Load 54
- 57: 53(ptr) AccessChain 50(ini4) 56
+ 44(param): 7(ptr) Variable Function
+ 39: 6(int) Load 13(bound)
+ 41: 28(bool) SGreaterThan 39 40
+ SelectionMerge 43 None
+ BranchConditional 41 42 48
+ 42: Label
+ 45: 6(int) Load 13(bound)
+ Store 44(param) 45
+ 46: 8(float) FunctionCall 11(Test1(i1;) 44(param)
+ ReturnValue 46
+ 48: Label
+ 49: 6(int) Load 13(bound)
+ 50: 6(int) IMul 49 40
+ 57: 56(ptr) AccessChain 53(ini4) 55
58: 6(int) Load 57
- 59: 6(int) IMul 55 58
- 60: 6(int) IAdd 47 59
- 62: 53(ptr) AccessChain 50(ini4) 61
- 63: 6(int) Load 62
- 64: 6(int) IAdd 60 63
- 65: 8(float) ConvertSToF 64
- ReturnValue 65
- 41: Label
- 66: 8(float) Undef
- ReturnValue 66
+ 60: 56(ptr) AccessChain 53(ini4) 59
+ 61: 6(int) Load 60
+ 62: 6(int) IMul 58 61
+ 63: 6(int) IAdd 50 62
+ 65: 56(ptr) AccessChain 53(ini4) 64
+ 66: 6(int) Load 65
+ 67: 6(int) IAdd 63 66
+ 68: 8(float) ConvertSToF 67
+ ReturnValue 68
+ 43: Label
+ 70: 8(float) Undef
+ ReturnValue 70
FunctionEnd
diff --git a/Test/baseResults/remap.similar_1b.none.frag.out b/Test/baseResults/remap.similar_1b.none.frag.out
index b86fd4b..ce79e00 100644
--- a/Test/baseResults/remap.similar_1b.none.frag.out
+++ b/Test/baseResults/remap.similar_1b.none.frag.out
@@ -3,12 +3,12 @@
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 87
+// Id's are bound by 91
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "main" 55 74 76
+ EntryPoint Fragment 4 "main" 58 78 80
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
@@ -18,13 +18,13 @@
Name 13 "bound"
Name 17 "r"
Name 19 "x"
- Name 47 "param"
- Name 55 "ini4"
- Name 74 "outf4"
- Name 76 "inf"
- Name 79 "param"
+ Name 49 "param"
+ Name 58 "ini4"
+ Name 78 "outf4"
+ Name 80 "inf"
Name 83 "param"
- Decorate 55(ini4) Flat
+ Name 87 "param"
+ Decorate 58(ini4) Flat
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
@@ -38,36 +38,36 @@
30: 8(float) Constant 1056964608
34: 6(int) Constant 1
36: 8(float) Constant 1045220557
- 41: 6(int) Constant 2
- 51: 6(int) Constant 4
- 53: TypeVector 6(int) 4
- 54: TypePointer Input 53(ivec4)
- 55(ini4): 54(ptr) Variable Input
- 56: TypeInt 32 0
- 57: 56(int) Constant 1
- 58: TypePointer Input 6(int)
- 61: 56(int) Constant 2
- 66: 56(int) Constant 0
- 72: TypeVector 8(float) 4
- 73: TypePointer Output 72(fvec4)
- 74(outf4): 73(ptr) Variable Output
- 75: TypePointer Input 8(float)
- 76(inf): 75(ptr) Variable Input
+ 43: 6(int) Constant 2
+ 54: 6(int) Constant 4
+ 56: TypeVector 6(int) 4
+ 57: TypePointer Input 56(ivec4)
+ 58(ini4): 57(ptr) Variable Input
+ 59: TypeInt 32 0
+ 60: 59(int) Constant 1
+ 61: TypePointer Input 6(int)
+ 64: 59(int) Constant 2
+ 69: 59(int) Constant 0
+ 76: TypeVector 8(float) 4
+ 77: TypePointer Output 76(fvec4)
+ 78(outf4): 77(ptr) Variable Output
+ 79: TypePointer Input 8(float)
+ 80(inf): 79(ptr) Variable Input
4(main): 2 Function None 3
5: Label
- 79(param): 7(ptr) Variable Function
83(param): 7(ptr) Variable Function
- 77: 8(float) Load 76(inf)
- 78: 6(int) ConvertFToS 77
- Store 79(param) 78
- 80: 8(float) FunctionCall 11(Test1(i1;) 79(param)
- 81: 8(float) Load 76(inf)
+ 87(param): 7(ptr) Variable Function
+ 81: 8(float) Load 80(inf)
82: 6(int) ConvertFToS 81
Store 83(param) 82
- 84: 8(float) FunctionCall 14(Test2(i1;) 83(param)
- 85: 8(float) FAdd 80 84
- 86: 72(fvec4) CompositeConstruct 85 85 85 85
- Store 74(outf4) 86
+ 84: 8(float) FunctionCall 11(Test1(i1;) 83(param)
+ 85: 8(float) Load 80(inf)
+ 86: 6(int) ConvertFToS 85
+ Store 87(param) 86
+ 88: 8(float) FunctionCall 14(Test2(i1;) 87(param)
+ 89: 8(float) FAdd 84 88
+ 90: 76(fvec4) CompositeConstruct 89 89 89 89
+ Store 78(outf4) 90
Return
FunctionEnd
11(Test1(i1;): 8(float) Function None 9
@@ -106,32 +106,32 @@
14(Test2(i1;): 8(float) Function None 9
13(bound): 7(ptr) FunctionParameter
15: Label
- 47(param): 7(ptr) Variable Function
- 40: 6(int) Load 13(bound)
- 42: 28(bool) SGreaterThan 40 41
- SelectionMerge 44 None
- BranchConditional 42 43 49
- 43: Label
- 45: 6(int) Load 13(bound)
- 46: 6(int) IMul 45 41
- Store 47(param) 46
- 48: 8(float) FunctionCall 11(Test1(i1;) 47(param)
- ReturnValue 48
- 49: Label
- 50: 6(int) Load 13(bound)
- 52: 6(int) IMul 50 51
- 59: 58(ptr) AccessChain 55(ini4) 57
- 60: 6(int) Load 59
- 62: 58(ptr) AccessChain 55(ini4) 61
+ 49(param): 7(ptr) Variable Function
+ 42: 6(int) Load 13(bound)
+ 44: 28(bool) SGreaterThan 42 43
+ SelectionMerge 46 None
+ BranchConditional 44 45 52
+ 45: Label
+ 47: 6(int) Load 13(bound)
+ 48: 6(int) IMul 47 43
+ Store 49(param) 48
+ 50: 8(float) FunctionCall 11(Test1(i1;) 49(param)
+ ReturnValue 50
+ 52: Label
+ 53: 6(int) Load 13(bound)
+ 55: 6(int) IMul 53 54
+ 62: 61(ptr) AccessChain 58(ini4) 60
63: 6(int) Load 62
- 64: 6(int) IMul 60 63
- 65: 6(int) IAdd 52 64
- 67: 58(ptr) AccessChain 55(ini4) 66
- 68: 6(int) Load 67
- 69: 6(int) IAdd 65 68
- 70: 8(float) ConvertSToF 69
- ReturnValue 70
- 44: Label
- 71: 8(float) Undef
- ReturnValue 71
+ 65: 61(ptr) AccessChain 58(ini4) 64
+ 66: 6(int) Load 65
+ 67: 6(int) IMul 63 66
+ 68: 6(int) IAdd 55 67
+ 70: 61(ptr) AccessChain 58(ini4) 69
+ 71: 6(int) Load 70
+ 72: 6(int) IAdd 68 71
+ 73: 8(float) ConvertSToF 72
+ ReturnValue 73
+ 46: Label
+ 75: 8(float) Undef
+ ReturnValue 75
FunctionEnd
diff --git a/Test/baseResults/remap.switch.none.frag.out b/Test/baseResults/remap.switch.none.frag.out
index 5d373cc..68d075b 100644
--- a/Test/baseResults/remap.switch.none.frag.out
+++ b/Test/baseResults/remap.switch.none.frag.out
@@ -5,7 +5,7 @@
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 44
+// Id's are bound by 48
Capability Shader
1: ExtInstImport "GLSL.std.450"
@@ -20,8 +20,8 @@
Decorate 23(FragColor) RelaxedPrecision
Decorate 23(FragColor) Location 0
Decorate 29 RelaxedPrecision
- Decorate 35 RelaxedPrecision
- Decorate 41 RelaxedPrecision
+ Decorate 36 RelaxedPrecision
+ Decorate 43 RelaxedPrecision
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@@ -36,12 +36,12 @@
23(FragColor): 22(ptr) Variable Output
24: 10(int) Constant 0
27: 6(float) Constant 0
- 30: 10(int) Constant 1
- 33: 6(float) Constant 1065353216
- 36: 10(int) Constant 2
- 39: 6(float) Constant 1073741824
- 42: 6(float) Constant 3212836864
- 43: 7(fvec4) ConstantComposite 42 42 42 42
+ 31: 10(int) Constant 1
+ 34: 6(float) Constant 1065353216
+ 38: 10(int) Constant 2
+ 41: 6(float) Constant 1073741824
+ 45: 6(float) Constant 3212836864
+ 46: 7(fvec4) ConstantComposite 45 45 45 45
4(main): 2 Function None 3
5: Label
13: 12(ptr) AccessChain 9(in0) 11
@@ -53,7 +53,7 @@
case 1: 18
case 2: 19
20: Label
- Store 23(FragColor) 43
+ Store 23(FragColor) 46
Branch 21
17: Label
25: 12(ptr) AccessChain 9(in0) 24
@@ -63,18 +63,18 @@
Store 23(FragColor) 29
Branch 21
18: Label
- 31: 12(ptr) AccessChain 9(in0) 30
- 32: 6(float) Load 31
- 34: 6(float) FAdd 32 33
- 35: 7(fvec4) CompositeConstruct 34 34 34 34
- Store 23(FragColor) 35
+ 32: 12(ptr) AccessChain 9(in0) 31
+ 33: 6(float) Load 32
+ 35: 6(float) FAdd 33 34
+ 36: 7(fvec4) CompositeConstruct 35 35 35 35
+ Store 23(FragColor) 36
Branch 21
19: Label
- 37: 12(ptr) AccessChain 9(in0) 36
- 38: 6(float) Load 37
- 40: 6(float) FAdd 38 39
- 41: 7(fvec4) CompositeConstruct 40 40 40 40
- Store 23(FragColor) 41
+ 39: 12(ptr) AccessChain 9(in0) 38
+ 40: 6(float) Load 39
+ 42: 6(float) FAdd 40 41
+ 43: 7(fvec4) CompositeConstruct 42 42 42 42
+ Store 23(FragColor) 43
Branch 21
21: Label
Return
diff --git a/Test/baseResults/spv.GeometryShaderPassthrough.geom.out b/Test/baseResults/spv.GeometryShaderPassthrough.geom.out
new file mode 100644
index 0000000..05aeb97
--- /dev/null
+++ b/Test/baseResults/spv.GeometryShaderPassthrough.geom.out
@@ -0,0 +1,46 @@
+spv.GeometryShaderPassthrough.geom
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 15
+
+ Capability Geometry
+ Capability GeometryShaderPassthroughNV
+ Extension "SPV_NV_geometry_shader_passthrough"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Geometry 4 "main" 10 14
+ ExecutionMode 4 Triangles
+ ExecutionMode 4 Invocations 1
+ ExecutionMode 4 OutputVertices
+ Source GLSL 450
+ SourceExtension "GL_NV_geometry_shader_passthrough"
+ Name 4 "main"
+ Name 8 "gl_PerVertex"
+ MemberName 8(gl_PerVertex) 0 "gl_Position"
+ Name 10 ""
+ Name 12 "Inputs"
+ MemberName 12(Inputs) 0 "texcoord"
+ MemberName 12(Inputs) 1 "baseColor"
+ Name 14 ""
+ MemberDecorate 8(gl_PerVertex) 0 BuiltIn Position
+ Decorate 8(gl_PerVertex) Block
+ Decorate 10 PassthroughNV
+ Decorate 12(Inputs) Block
+ Decorate 14 PassthroughNV
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeFloat 32
+ 7: TypeVector 6(float) 4
+ 8(gl_PerVertex): TypeStruct 7(fvec4)
+ 9: TypePointer Input 8(gl_PerVertex)
+ 10: 9(ptr) Variable Input
+ 11: TypeVector 6(float) 2
+ 12(Inputs): TypeStruct 11(fvec2) 7(fvec4)
+ 13: TypePointer Input 12(Inputs)
+ 14: 13(ptr) Variable Input
+ 4(main): 2 Function None 3
+ 5: Label
+ Return
+ FunctionEnd
diff --git a/Test/baseResults/spv.sampleMaskOverrideCoverage.frag.out b/Test/baseResults/spv.sampleMaskOverrideCoverage.frag.out
new file mode 100644
index 0000000..6bae6bd
--- /dev/null
+++ b/Test/baseResults/spv.sampleMaskOverrideCoverage.frag.out
@@ -0,0 +1,42 @@
+spv.sampleMaskOverrideCoverage.frag
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 20
+
+ Capability Shader
+ Capability SampleRateShading
+ Extension "SPV_NV_sample_mask_override_coverage"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "main" 11 19
+ ExecutionMode 4 OriginUpperLeft
+ Source GLSL 450
+ SourceExtension "GL_NV_sample_mask_override_coverage"
+ Name 4 "main"
+ Name 11 "gl_SampleMask"
+ Name 19 "color"
+ Decorate 11(gl_SampleMask) BuiltIn SampleMask
+ Decorate 11(gl_SampleMask) OverrideCoverageNV
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 1
+ 7: TypeInt 32 0
+ 8: 7(int) Constant 1
+ 9: TypeArray 6(int) 8
+ 10: TypePointer Output 9
+11(gl_SampleMask): 10(ptr) Variable Output
+ 12: 6(int) Constant 0
+ 13: 6(int) Constant 4294967295
+ 14: TypePointer Output 6(int)
+ 16: TypeFloat 32
+ 17: TypeVector 16(float) 4
+ 18: TypePointer Input 17(fvec4)
+ 19(color): 18(ptr) Variable Input
+ 4(main): 2 Function None 3
+ 5: Label
+ 15: 14(ptr) AccessChain 11(gl_SampleMask) 12
+ Store 15 13
+ Return
+ FunctionEnd
diff --git a/Test/baseResults/spv.shaderBallot.comp.out b/Test/baseResults/spv.shaderBallot.comp.out
index 4f03312..b8d5e3a 100644
--- a/Test/baseResults/spv.shaderBallot.comp.out
+++ b/Test/baseResults/spv.shaderBallot.comp.out
@@ -3,11 +3,10 @@
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 299
+// Id's are bound by 298
Capability Shader
Capability Int64
- Capability Groups
Capability SubgroupBallotKHR
Extension "SPV_KHR_shader_ballot"
1: ExtInstImport "GLSL.std.450"
@@ -45,7 +44,7 @@
Decorate 52(Buffers) BufferBlock
Decorate 55(data) DescriptorSet 0
Decorate 55(data) Binding 0
- Decorate 298 BuiltIn WorkgroupSize
+ Decorate 297 BuiltIn WorkgroupSize
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 0
@@ -77,23 +76,22 @@
57: 50(int) Constant 0
58: 6(int) Constant 0
59: TypePointer Uniform 48(float)
- 63: 6(int) Constant 3
- 67: 50(int) Constant 1
- 68: TypeVector 48(float) 2
- 69: TypePointer Uniform 49(fvec4)
- 83: 50(int) Constant 2
- 84: TypeVector 48(float) 3
- 100: 50(int) Constant 3
- 115: TypePointer Uniform 50(int)
- 122: TypeVector 50(int) 2
- 123: TypePointer Uniform 51(ivec4)
- 137: TypeVector 50(int) 3
- 167: TypePointer Uniform 6(int)
- 174: TypePointer Uniform 38(ivec4)
- 188: TypeVector 6(int) 3
- 296: 6(int) Constant 8
- 297: 6(int) Constant 1
- 298: 188(ivec3) ConstantComposite 296 296 297
+ 66: 50(int) Constant 1
+ 67: TypeVector 48(float) 2
+ 68: TypePointer Uniform 49(fvec4)
+ 82: 50(int) Constant 2
+ 83: TypeVector 48(float) 3
+ 99: 50(int) Constant 3
+ 114: TypePointer Uniform 50(int)
+ 121: TypeVector 50(int) 2
+ 122: TypePointer Uniform 51(ivec4)
+ 136: TypeVector 50(int) 3
+ 166: TypePointer Uniform 6(int)
+ 173: TypePointer Uniform 38(ivec4)
+ 187: TypeVector 6(int) 3
+ 295: 6(int) Constant 8
+ 296: 6(int) Constant 1
+ 297: 187(ivec3) ConstantComposite 295 295 296
4(main): 2 Function None 3
5: Label
8(invocation): 7(ptr) Variable Function
@@ -121,256 +119,256 @@
44: 17(int) Bitcast 43
45: 36(bool) IEqual 35 44
SelectionMerge 47 None
- BranchConditional 45 46 217
+ BranchConditional 45 46 216
46: Label
56: 6(int) Load 8(invocation)
60: 59(ptr) AccessChain 55(data) 57 57 58
61: 48(float) Load 60
62: 6(int) Load 8(invocation)
- 64: 48(float) GroupBroadcast 63 61 62
- 65: 59(ptr) AccessChain 55(data) 56 57 58
- Store 65 64
- 66: 6(int) Load 8(invocation)
- 70: 69(ptr) AccessChain 55(data) 67 57
- 71: 49(fvec4) Load 70
- 72: 68(fvec2) VectorShuffle 71 71 0 1
- 73: 6(int) Load 8(invocation)
- 74: 48(float) CompositeExtract 72 0
- 75: 48(float) GroupBroadcast 63 74 73
- 76: 48(float) CompositeExtract 72 1
- 77: 48(float) GroupBroadcast 63 76 73
- 78: 68(fvec2) CompositeConstruct 75 77
- 79: 69(ptr) AccessChain 55(data) 66 57
- 80: 49(fvec4) Load 79
- 81: 49(fvec4) VectorShuffle 80 78 4 5 2 3
- Store 79 81
- 82: 6(int) Load 8(invocation)
- 85: 69(ptr) AccessChain 55(data) 83 57
- 86: 49(fvec4) Load 85
- 87: 84(fvec3) VectorShuffle 86 86 0 1 2
- 88: 6(int) Load 8(invocation)
- 89: 48(float) CompositeExtract 87 0
- 90: 48(float) GroupBroadcast 63 89 88
- 91: 48(float) CompositeExtract 87 1
- 92: 48(float) GroupBroadcast 63 91 88
- 93: 48(float) CompositeExtract 87 2
- 94: 48(float) GroupBroadcast 63 93 88
- 95: 84(fvec3) CompositeConstruct 90 92 94
- 96: 69(ptr) AccessChain 55(data) 82 57
- 97: 49(fvec4) Load 96
- 98: 49(fvec4) VectorShuffle 97 95 4 5 6 3
- Store 96 98
- 99: 6(int) Load 8(invocation)
- 101: 69(ptr) AccessChain 55(data) 100 57
- 102: 49(fvec4) Load 101
- 103: 6(int) Load 8(invocation)
- 104: 48(float) CompositeExtract 102 0
- 105: 48(float) GroupBroadcast 63 104 103
- 106: 48(float) CompositeExtract 102 1
- 107: 48(float) GroupBroadcast 63 106 103
- 108: 48(float) CompositeExtract 102 2
- 109: 48(float) GroupBroadcast 63 108 103
- 110: 48(float) CompositeExtract 102 3
- 111: 48(float) GroupBroadcast 63 110 103
- 112: 49(fvec4) CompositeConstruct 105 107 109 111
- 113: 69(ptr) AccessChain 55(data) 99 57
- Store 113 112
- 114: 6(int) Load 8(invocation)
- 116: 115(ptr) AccessChain 55(data) 57 67 58
- 117: 50(int) Load 116
- 118: 6(int) Load 8(invocation)
- 119: 50(int) GroupBroadcast 63 117 118
- 120: 115(ptr) AccessChain 55(data) 114 67 58
- Store 120 119
- 121: 6(int) Load 8(invocation)
- 124: 123(ptr) AccessChain 55(data) 67 67
- 125: 51(ivec4) Load 124
- 126: 122(ivec2) VectorShuffle 125 125 0 1
- 127: 6(int) Load 8(invocation)
- 128: 50(int) CompositeExtract 126 0
- 129: 50(int) GroupBroadcast 63 128 127
- 130: 50(int) CompositeExtract 126 1
- 131: 50(int) GroupBroadcast 63 130 127
- 132: 122(ivec2) CompositeConstruct 129 131
- 133: 123(ptr) AccessChain 55(data) 121 67
- 134: 51(ivec4) Load 133
- 135: 51(ivec4) VectorShuffle 134 132 4 5 2 3
- Store 133 135
- 136: 6(int) Load 8(invocation)
- 138: 123(ptr) AccessChain 55(data) 83 67
- 139: 51(ivec4) Load 138
- 140: 137(ivec3) VectorShuffle 139 139 0 1 2
- 141: 6(int) Load 8(invocation)
- 142: 50(int) CompositeExtract 140 0
- 143: 50(int) GroupBroadcast 63 142 141
- 144: 50(int) CompositeExtract 140 1
- 145: 50(int) GroupBroadcast 63 144 141
- 146: 50(int) CompositeExtract 140 2
- 147: 50(int) GroupBroadcast 63 146 141
- 148: 137(ivec3) CompositeConstruct 143 145 147
- 149: 123(ptr) AccessChain 55(data) 136 67
- 150: 51(ivec4) Load 149
- 151: 51(ivec4) VectorShuffle 150 148 4 5 6 3
- Store 149 151
- 152: 6(int) Load 8(invocation)
- 153: 123(ptr) AccessChain 55(data) 100 67
- 154: 51(ivec4) Load 153
- 155: 6(int) Load 8(invocation)
- 156: 50(int) CompositeExtract 154 0
- 157: 50(int) GroupBroadcast 63 156 155
- 158: 50(int) CompositeExtract 154 1
- 159: 50(int) GroupBroadcast 63 158 155
- 160: 50(int) CompositeExtract 154 2
- 161: 50(int) GroupBroadcast 63 160 155
- 162: 50(int) CompositeExtract 154 3
- 163: 50(int) GroupBroadcast 63 162 155
- 164: 51(ivec4) CompositeConstruct 157 159 161 163
- 165: 123(ptr) AccessChain 55(data) 152 67
- Store 165 164
- 166: 6(int) Load 8(invocation)
- 168: 167(ptr) AccessChain 55(data) 57 83 58
- 169: 6(int) Load 168
- 170: 6(int) Load 8(invocation)
- 171: 6(int) GroupBroadcast 63 169 170
- 172: 167(ptr) AccessChain 55(data) 166 83 58
- Store 172 171
- 173: 6(int) Load 8(invocation)
- 175: 174(ptr) AccessChain 55(data) 67 83
- 176: 38(ivec4) Load 175
- 177: 42(ivec2) VectorShuffle 176 176 0 1
- 178: 6(int) Load 8(invocation)
- 179: 6(int) CompositeExtract 177 0
- 180: 6(int) GroupBroadcast 63 179 178
- 181: 6(int) CompositeExtract 177 1
- 182: 6(int) GroupBroadcast 63 181 178
- 183: 42(ivec2) CompositeConstruct 180 182
- 184: 174(ptr) AccessChain 55(data) 173 83
- 185: 38(ivec4) Load 184
- 186: 38(ivec4) VectorShuffle 185 183 4 5 2 3
- Store 184 186
- 187: 6(int) Load 8(invocation)
- 189: 174(ptr) AccessChain 55(data) 83 83
- 190: 38(ivec4) Load 189
- 191: 188(ivec3) VectorShuffle 190 190 0 1 2
- 192: 6(int) Load 8(invocation)
- 193: 6(int) CompositeExtract 191 0
- 194: 6(int) GroupBroadcast 63 193 192
- 195: 6(int) CompositeExtract 191 1
- 196: 6(int) GroupBroadcast 63 195 192
- 197: 6(int) CompositeExtract 191 2
- 198: 6(int) GroupBroadcast 63 197 192
- 199: 188(ivec3) CompositeConstruct 194 196 198
- 200: 174(ptr) AccessChain 55(data) 187 83
- 201: 38(ivec4) Load 200
- 202: 38(ivec4) VectorShuffle 201 199 4 5 6 3
- Store 200 202
- 203: 6(int) Load 8(invocation)
- 204: 174(ptr) AccessChain 55(data) 100 83
- 205: 38(ivec4) Load 204
- 206: 6(int) Load 8(invocation)
- 207: 6(int) CompositeExtract 205 0
- 208: 6(int) GroupBroadcast 63 207 206
- 209: 6(int) CompositeExtract 205 1
- 210: 6(int) GroupBroadcast 63 209 206
- 211: 6(int) CompositeExtract 205 2
- 212: 6(int) GroupBroadcast 63 211 206
- 213: 6(int) CompositeExtract 205 3
- 214: 6(int) GroupBroadcast 63 213 206
- 215: 38(ivec4) CompositeConstruct 208 210 212 214
- 216: 174(ptr) AccessChain 55(data) 203 83
- Store 216 215
+ 63: 48(float) SubgroupReadInvocationKHR 61 62
+ 64: 59(ptr) AccessChain 55(data) 56 57 58
+ Store 64 63
+ 65: 6(int) Load 8(invocation)
+ 69: 68(ptr) AccessChain 55(data) 66 57
+ 70: 49(fvec4) Load 69
+ 71: 67(fvec2) VectorShuffle 70 70 0 1
+ 72: 6(int) Load 8(invocation)
+ 73: 48(float) CompositeExtract 71 0
+ 74: 48(float) SubgroupReadInvocationKHR 73 72
+ 75: 48(float) CompositeExtract 71 1
+ 76: 48(float) SubgroupReadInvocationKHR 75 72
+ 77: 67(fvec2) CompositeConstruct 74 76
+ 78: 68(ptr) AccessChain 55(data) 65 57
+ 79: 49(fvec4) Load 78
+ 80: 49(fvec4) VectorShuffle 79 77 4 5 2 3
+ Store 78 80
+ 81: 6(int) Load 8(invocation)
+ 84: 68(ptr) AccessChain 55(data) 82 57
+ 85: 49(fvec4) Load 84
+ 86: 83(fvec3) VectorShuffle 85 85 0 1 2
+ 87: 6(int) Load 8(invocation)
+ 88: 48(float) CompositeExtract 86 0
+ 89: 48(float) SubgroupReadInvocationKHR 88 87
+ 90: 48(float) CompositeExtract 86 1
+ 91: 48(float) SubgroupReadInvocationKHR 90 87
+ 92: 48(float) CompositeExtract 86 2
+ 93: 48(float) SubgroupReadInvocationKHR 92 87
+ 94: 83(fvec3) CompositeConstruct 89 91 93
+ 95: 68(ptr) AccessChain 55(data) 81 57
+ 96: 49(fvec4) Load 95
+ 97: 49(fvec4) VectorShuffle 96 94 4 5 6 3
+ Store 95 97
+ 98: 6(int) Load 8(invocation)
+ 100: 68(ptr) AccessChain 55(data) 99 57
+ 101: 49(fvec4) Load 100
+ 102: 6(int) Load 8(invocation)
+ 103: 48(float) CompositeExtract 101 0
+ 104: 48(float) SubgroupReadInvocationKHR 103 102
+ 105: 48(float) CompositeExtract 101 1
+ 106: 48(float) SubgroupReadInvocationKHR 105 102
+ 107: 48(float) CompositeExtract 101 2
+ 108: 48(float) SubgroupReadInvocationKHR 107 102
+ 109: 48(float) CompositeExtract 101 3
+ 110: 48(float) SubgroupReadInvocationKHR 109 102
+ 111: 49(fvec4) CompositeConstruct 104 106 108 110
+ 112: 68(ptr) AccessChain 55(data) 98 57
+ Store 112 111
+ 113: 6(int) Load 8(invocation)
+ 115: 114(ptr) AccessChain 55(data) 57 66 58
+ 116: 50(int) Load 115
+ 117: 6(int) Load 8(invocation)
+ 118: 50(int) SubgroupReadInvocationKHR 116 117
+ 119: 114(ptr) AccessChain 55(data) 113 66 58
+ Store 119 118
+ 120: 6(int) Load 8(invocation)
+ 123: 122(ptr) AccessChain 55(data) 66 66
+ 124: 51(ivec4) Load 123
+ 125: 121(ivec2) VectorShuffle 124 124 0 1
+ 126: 6(int) Load 8(invocation)
+ 127: 50(int) CompositeExtract 125 0
+ 128: 50(int) SubgroupReadInvocationKHR 127 126
+ 129: 50(int) CompositeExtract 125 1
+ 130: 50(int) SubgroupReadInvocationKHR 129 126
+ 131: 121(ivec2) CompositeConstruct 128 130
+ 132: 122(ptr) AccessChain 55(data) 120 66
+ 133: 51(ivec4) Load 132
+ 134: 51(ivec4) VectorShuffle 133 131 4 5 2 3
+ Store 132 134
+ 135: 6(int) Load 8(invocation)
+ 137: 122(ptr) AccessChain 55(data) 82 66
+ 138: 51(ivec4) Load 137
+ 139: 136(ivec3) VectorShuffle 138 138 0 1 2
+ 140: 6(int) Load 8(invocation)
+ 141: 50(int) CompositeExtract 139 0
+ 142: 50(int) SubgroupReadInvocationKHR 141 140
+ 143: 50(int) CompositeExtract 139 1
+ 144: 50(int) SubgroupReadInvocationKHR 143 140
+ 145: 50(int) CompositeExtract 139 2
+ 146: 50(int) SubgroupReadInvocationKHR 145 140
+ 147: 136(ivec3) CompositeConstruct 142 144 146
+ 148: 122(ptr) AccessChain 55(data) 135 66
+ 149: 51(ivec4) Load 148
+ 150: 51(ivec4) VectorShuffle 149 147 4 5 6 3
+ Store 148 150
+ 151: 6(int) Load 8(invocation)
+ 152: 122(ptr) AccessChain 55(data) 99 66
+ 153: 51(ivec4) Load 152
+ 154: 6(int) Load 8(invocation)
+ 155: 50(int) CompositeExtract 153 0
+ 156: 50(int) SubgroupReadInvocationKHR 155 154
+ 157: 50(int) CompositeExtract 153 1
+ 158: 50(int) SubgroupReadInvocationKHR 157 154
+ 159: 50(int) CompositeExtract 153 2
+ 160: 50(int) SubgroupReadInvocationKHR 159 154
+ 161: 50(int) CompositeExtract 153 3
+ 162: 50(int) SubgroupReadInvocationKHR 161 154
+ 163: 51(ivec4) CompositeConstruct 156 158 160 162
+ 164: 122(ptr) AccessChain 55(data) 151 66
+ Store 164 163
+ 165: 6(int) Load 8(invocation)
+ 167: 166(ptr) AccessChain 55(data) 57 82 58
+ 168: 6(int) Load 167
+ 169: 6(int) Load 8(invocation)
+ 170: 6(int) SubgroupReadInvocationKHR 168 169
+ 171: 166(ptr) AccessChain 55(data) 165 82 58
+ Store 171 170
+ 172: 6(int) Load 8(invocation)
+ 174: 173(ptr) AccessChain 55(data) 66 82
+ 175: 38(ivec4) Load 174
+ 176: 42(ivec2) VectorShuffle 175 175 0 1
+ 177: 6(int) Load 8(invocation)
+ 178: 6(int) CompositeExtract 176 0
+ 179: 6(int) SubgroupReadInvocationKHR 178 177
+ 180: 6(int) CompositeExtract 176 1
+ 181: 6(int) SubgroupReadInvocationKHR 180 177
+ 182: 42(ivec2) CompositeConstruct 179 181
+ 183: 173(ptr) AccessChain 55(data) 172 82
+ 184: 38(ivec4) Load 183
+ 185: 38(ivec4) VectorShuffle 184 182 4 5 2 3
+ Store 183 185
+ 186: 6(int) Load 8(invocation)
+ 188: 173(ptr) AccessChain 55(data) 82 82
+ 189: 38(ivec4) Load 188
+ 190: 187(ivec3) VectorShuffle 189 189 0 1 2
+ 191: 6(int) Load 8(invocation)
+ 192: 6(int) CompositeExtract 190 0
+ 193: 6(int) SubgroupReadInvocationKHR 192 191
+ 194: 6(int) CompositeExtract 190 1
+ 195: 6(int) SubgroupReadInvocationKHR 194 191
+ 196: 6(int) CompositeExtract 190 2
+ 197: 6(int) SubgroupReadInvocationKHR 196 191
+ 198: 187(ivec3) CompositeConstruct 193 195 197
+ 199: 173(ptr) AccessChain 55(data) 186 82
+ 200: 38(ivec4) Load 199
+ 201: 38(ivec4) VectorShuffle 200 198 4 5 6 3
+ Store 199 201
+ 202: 6(int) Load 8(invocation)
+ 203: 173(ptr) AccessChain 55(data) 99 82
+ 204: 38(ivec4) Load 203
+ 205: 6(int) Load 8(invocation)
+ 206: 6(int) CompositeExtract 204 0
+ 207: 6(int) SubgroupReadInvocationKHR 206 205
+ 208: 6(int) CompositeExtract 204 1
+ 209: 6(int) SubgroupReadInvocationKHR 208 205
+ 210: 6(int) CompositeExtract 204 2
+ 211: 6(int) SubgroupReadInvocationKHR 210 205
+ 212: 6(int) CompositeExtract 204 3
+ 213: 6(int) SubgroupReadInvocationKHR 212 205
+ 214: 38(ivec4) CompositeConstruct 207 209 211 213
+ 215: 173(ptr) AccessChain 55(data) 202 82
+ Store 215 214
Branch 47
- 217: Label
- 218: 6(int) Load 8(invocation)
- 219: 59(ptr) AccessChain 55(data) 57 57 58
- 220: 48(float) Load 219
- 221: 48(float) SubgroupFirstInvocationKHR 220
- 222: 59(ptr) AccessChain 55(data) 218 57 58
- Store 222 221
- 223: 6(int) Load 8(invocation)
- 224: 69(ptr) AccessChain 55(data) 67 57
- 225: 49(fvec4) Load 224
- 226: 68(fvec2) VectorShuffle 225 225 0 1
- 227: 68(fvec2) SubgroupFirstInvocationKHR 226
- 228: 69(ptr) AccessChain 55(data) 223 57
- 229: 49(fvec4) Load 228
- 230: 49(fvec4) VectorShuffle 229 227 4 5 2 3
- Store 228 230
- 231: 6(int) Load 8(invocation)
- 232: 69(ptr) AccessChain 55(data) 83 57
- 233: 49(fvec4) Load 232
- 234: 84(fvec3) VectorShuffle 233 233 0 1 2
- 235: 84(fvec3) SubgroupFirstInvocationKHR 234
- 236: 69(ptr) AccessChain 55(data) 231 57
- 237: 49(fvec4) Load 236
- 238: 49(fvec4) VectorShuffle 237 235 4 5 6 3
- Store 236 238
- 239: 6(int) Load 8(invocation)
- 240: 69(ptr) AccessChain 55(data) 100 57
- 241: 49(fvec4) Load 240
- 242: 49(fvec4) SubgroupFirstInvocationKHR 241
- 243: 69(ptr) AccessChain 55(data) 239 57
- Store 243 242
- 244: 6(int) Load 8(invocation)
- 245: 115(ptr) AccessChain 55(data) 57 67 58
- 246: 50(int) Load 245
- 247: 50(int) SubgroupFirstInvocationKHR 246
- 248: 115(ptr) AccessChain 55(data) 244 67 58
- Store 248 247
- 249: 6(int) Load 8(invocation)
- 250: 123(ptr) AccessChain 55(data) 67 67
- 251: 51(ivec4) Load 250
- 252: 122(ivec2) VectorShuffle 251 251 0 1
- 253: 122(ivec2) SubgroupFirstInvocationKHR 252
- 254: 123(ptr) AccessChain 55(data) 249 67
- 255: 51(ivec4) Load 254
- 256: 51(ivec4) VectorShuffle 255 253 4 5 2 3
- Store 254 256
- 257: 6(int) Load 8(invocation)
- 258: 123(ptr) AccessChain 55(data) 83 67
- 259: 51(ivec4) Load 258
- 260: 137(ivec3) VectorShuffle 259 259 0 1 2
- 261: 137(ivec3) SubgroupFirstInvocationKHR 260
- 262: 123(ptr) AccessChain 55(data) 257 67
- 263: 51(ivec4) Load 262
- 264: 51(ivec4) VectorShuffle 263 261 4 5 6 3
- Store 262 264
- 265: 6(int) Load 8(invocation)
- 266: 123(ptr) AccessChain 55(data) 100 67
- 267: 51(ivec4) Load 266
- 268: 51(ivec4) SubgroupFirstInvocationKHR 267
- 269: 123(ptr) AccessChain 55(data) 265 67
- Store 269 268
- 270: 6(int) Load 8(invocation)
- 271: 167(ptr) AccessChain 55(data) 57 83 58
- 272: 6(int) Load 271
- 273: 6(int) SubgroupFirstInvocationKHR 272
- 274: 167(ptr) AccessChain 55(data) 270 83 58
- Store 274 273
- 275: 6(int) Load 8(invocation)
- 276: 174(ptr) AccessChain 55(data) 67 83
- 277: 38(ivec4) Load 276
- 278: 42(ivec2) VectorShuffle 277 277 0 1
- 279: 42(ivec2) SubgroupFirstInvocationKHR 278
- 280: 174(ptr) AccessChain 55(data) 275 83
- 281: 38(ivec4) Load 280
- 282: 38(ivec4) VectorShuffle 281 279 4 5 2 3
- Store 280 282
- 283: 6(int) Load 8(invocation)
- 284: 174(ptr) AccessChain 55(data) 83 83
- 285: 38(ivec4) Load 284
- 286: 188(ivec3) VectorShuffle 285 285 0 1 2
- 287: 188(ivec3) SubgroupFirstInvocationKHR 286
- 288: 174(ptr) AccessChain 55(data) 283 83
- 289: 38(ivec4) Load 288
- 290: 38(ivec4) VectorShuffle 289 287 4 5 6 3
- Store 288 290
- 291: 6(int) Load 8(invocation)
- 292: 174(ptr) AccessChain 55(data) 100 83
- 293: 38(ivec4) Load 292
- 294: 38(ivec4) SubgroupFirstInvocationKHR 293
- 295: 174(ptr) AccessChain 55(data) 291 83
- Store 295 294
+ 216: Label
+ 217: 6(int) Load 8(invocation)
+ 218: 59(ptr) AccessChain 55(data) 57 57 58
+ 219: 48(float) Load 218
+ 220: 48(float) SubgroupFirstInvocationKHR 219
+ 221: 59(ptr) AccessChain 55(data) 217 57 58
+ Store 221 220
+ 222: 6(int) Load 8(invocation)
+ 223: 68(ptr) AccessChain 55(data) 66 57
+ 224: 49(fvec4) Load 223
+ 225: 67(fvec2) VectorShuffle 224 224 0 1
+ 226: 67(fvec2) SubgroupFirstInvocationKHR 225
+ 227: 68(ptr) AccessChain 55(data) 222 57
+ 228: 49(fvec4) Load 227
+ 229: 49(fvec4) VectorShuffle 228 226 4 5 2 3
+ Store 227 229
+ 230: 6(int) Load 8(invocation)
+ 231: 68(ptr) AccessChain 55(data) 82 57
+ 232: 49(fvec4) Load 231
+ 233: 83(fvec3) VectorShuffle 232 232 0 1 2
+ 234: 83(fvec3) SubgroupFirstInvocationKHR 233
+ 235: 68(ptr) AccessChain 55(data) 230 57
+ 236: 49(fvec4) Load 235
+ 237: 49(fvec4) VectorShuffle 236 234 4 5 6 3
+ Store 235 237
+ 238: 6(int) Load 8(invocation)
+ 239: 68(ptr) AccessChain 55(data) 99 57
+ 240: 49(fvec4) Load 239
+ 241: 49(fvec4) SubgroupFirstInvocationKHR 240
+ 242: 68(ptr) AccessChain 55(data) 238 57
+ Store 242 241
+ 243: 6(int) Load 8(invocation)
+ 244: 114(ptr) AccessChain 55(data) 57 66 58
+ 245: 50(int) Load 244
+ 246: 50(int) SubgroupFirstInvocationKHR 245
+ 247: 114(ptr) AccessChain 55(data) 243 66 58
+ Store 247 246
+ 248: 6(int) Load 8(invocation)
+ 249: 122(ptr) AccessChain 55(data) 66 66
+ 250: 51(ivec4) Load 249
+ 251: 121(ivec2) VectorShuffle 250 250 0 1
+ 252: 121(ivec2) SubgroupFirstInvocationKHR 251
+ 253: 122(ptr) AccessChain 55(data) 248 66
+ 254: 51(ivec4) Load 253
+ 255: 51(ivec4) VectorShuffle 254 252 4 5 2 3
+ Store 253 255
+ 256: 6(int) Load 8(invocation)
+ 257: 122(ptr) AccessChain 55(data) 82 66
+ 258: 51(ivec4) Load 257
+ 259: 136(ivec3) VectorShuffle 258 258 0 1 2
+ 260: 136(ivec3) SubgroupFirstInvocationKHR 259
+ 261: 122(ptr) AccessChain 55(data) 256 66
+ 262: 51(ivec4) Load 261
+ 263: 51(ivec4) VectorShuffle 262 260 4 5 6 3
+ Store 261 263
+ 264: 6(int) Load 8(invocation)
+ 265: 122(ptr) AccessChain 55(data) 99 66
+ 266: 51(ivec4) Load 265
+ 267: 51(ivec4) SubgroupFirstInvocationKHR 266
+ 268: 122(ptr) AccessChain 55(data) 264 66
+ Store 268 267
+ 269: 6(int) Load 8(invocation)
+ 270: 166(ptr) AccessChain 55(data) 57 82 58
+ 271: 6(int) Load 270
+ 272: 6(int) SubgroupFirstInvocationKHR 271
+ 273: 166(ptr) AccessChain 55(data) 269 82 58
+ Store 273 272
+ 274: 6(int) Load 8(invocation)
+ 275: 173(ptr) AccessChain 55(data) 66 82
+ 276: 38(ivec4) Load 275
+ 277: 42(ivec2) VectorShuffle 276 276 0 1
+ 278: 42(ivec2) SubgroupFirstInvocationKHR 277
+ 279: 173(ptr) AccessChain 55(data) 274 82
+ 280: 38(ivec4) Load 279
+ 281: 38(ivec4) VectorShuffle 280 278 4 5 2 3
+ Store 279 281
+ 282: 6(int) Load 8(invocation)
+ 283: 173(ptr) AccessChain 55(data) 82 82
+ 284: 38(ivec4) Load 283
+ 285: 187(ivec3) VectorShuffle 284 284 0 1 2
+ 286: 187(ivec3) SubgroupFirstInvocationKHR 285
+ 287: 173(ptr) AccessChain 55(data) 282 82
+ 288: 38(ivec4) Load 287
+ 289: 38(ivec4) VectorShuffle 288 286 4 5 6 3
+ Store 287 289
+ 290: 6(int) Load 8(invocation)
+ 291: 173(ptr) AccessChain 55(data) 99 82
+ 292: 38(ivec4) Load 291
+ 293: 38(ivec4) SubgroupFirstInvocationKHR 292
+ 294: 173(ptr) AccessChain 55(data) 290 82
+ Store 294 293
Branch 47
47: Label
Return
diff --git a/Test/baseResults/tokenPaste.vert.out b/Test/baseResults/tokenPaste.vert.out
new file mode 100755
index 0000000..b0f7d10
--- /dev/null
+++ b/Test/baseResults/tokenPaste.vert.out
@@ -0,0 +1,112 @@
+tokenPaste.vert
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+ERROR: 0:38: '##' : unexpected location
+ERROR: 0:40: '##' : unexpected location; end of replacement list
+ERROR: 0:49: '##' : combined tokens are too long
+ERROR: 0:52: '##' : not supported for these tokens
+ERROR: 0:69: '##' : combined token is invalid
+ERROR: 5 compilation errors. No code generated.
+
+
+Shader version: 450
+ERROR: node is still EOpNull!
+0:52 Sequence
+0:52 move second child to first child (temp int)
+0:52 'a' (global int)
+0:52 Constant:
+0:52 11 (const int)
+0:58 Sequence
+0:58 move second child to first child (temp int)
+0:58 'cop' (global int)
+0:58 Constant:
+0:58 160 (const int)
+0:59 Sequence
+0:59 move second child to first child (temp bool)
+0:59 'dop' (global bool)
+0:59 Constant:
+0:59 true (const bool)
+0:63 Function Definition: ShouldntExpandToThis( (global void)
+0:63 Function Parameters:
+0:65 Sequence
+0:65 Sequence
+0:65 move second child to first child (temp int)
+0:65 'e' (temp int)
+0:65 Constant:
+0:65 16 (const int)
+0:66 right shift second child into first child (temp int)
+0:66 'e' (temp int)
+0:66 Constant:
+0:66 2 (const int)
+0:69 Sequence
+0:69 move second child to first child (temp bool)
+0:69 'f' (temp bool)
+0:69 Compare Greater Than (temp bool)
+0:69 'e' (temp int)
+0:69 Constant:
+0:69 5 (const int)
+0:? Linker Objects
+0:? 'SecondExpansion' (global int)
+0:? 'PostPasteExpansion' (global int)
+0:? 'foo27' (global float)
+0:? 'foo155' (uniform float)
+0:? 'foo719' (global float)
+0:? 'barfoo' (uniform float)
+0:? 'argless' (global float)
+0:? 'dc1' (global float)
+0:? 'dc2' (global float)
+0:? 'foo875' (uniform float)
+0:? 'ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345' (global float)
+0:? 'a' (global int)
+0:? 'aop' (const int)
+0:? 10 (const int)
+0:? 'bop' (const int)
+0:? 4 (const int)
+0:? 'cop' (global int)
+0:? 'dop' (global bool)
+0:? 'gl_VertexID' (gl_VertexId int VertexId)
+0:? 'gl_InstanceID' (gl_InstanceId int InstanceId)
+
+
+Linked vertex stage:
+
+ERROR: Linking vertex stage: Missing entry point: Each stage requires one entry point
+
+Shader version: 450
+ERROR: node is still EOpNull!
+0:52 Sequence
+0:52 move second child to first child (temp int)
+0:52 'a' (global int)
+0:52 Constant:
+0:52 11 (const int)
+0:58 Sequence
+0:58 move second child to first child (temp int)
+0:58 'cop' (global int)
+0:58 Constant:
+0:58 160 (const int)
+0:59 Sequence
+0:59 move second child to first child (temp bool)
+0:59 'dop' (global bool)
+0:59 Constant:
+0:59 true (const bool)
+0:? Linker Objects
+0:? 'SecondExpansion' (global int)
+0:? 'PostPasteExpansion' (global int)
+0:? 'foo27' (global float)
+0:? 'foo155' (uniform float)
+0:? 'foo719' (global float)
+0:? 'barfoo' (uniform float)
+0:? 'argless' (global float)
+0:? 'dc1' (global float)
+0:? 'dc2' (global float)
+0:? 'foo875' (uniform float)
+0:? 'ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345' (global float)
+0:? 'a' (global int)
+0:? 'aop' (const int)
+0:? 10 (const int)
+0:? 'bop' (const int)
+0:? 4 (const int)
+0:? 'cop' (global int)
+0:? 'dop' (global bool)
+0:? 'gl_VertexID' (gl_VertexId int VertexId)
+0:? 'gl_InstanceID' (gl_InstanceId int InstanceId)
+
diff --git a/Test/hlsl.array.implicit-size.frag b/Test/hlsl.array.implicit-size.frag
index 78a9283..e7a54f4 100644
--- a/Test/hlsl.array.implicit-size.frag
+++ b/Test/hlsl.array.implicit-size.frag
@@ -26,6 +26,7 @@
{
// local array sized from initializers
float l_array[] = { 1, 2, 3 };
+ int idx;
ps_output.color = g_array[0] + g_array[4] + l_array[1] + g_mystruct[0].f + g_array[idx];
}
diff --git a/Test/hlsl.identifier.sample.frag b/Test/hlsl.identifier.sample.frag
index 3281a9a..d3f8242 100644
--- a/Test/hlsl.identifier.sample.frag
+++ b/Test/hlsl.identifier.sample.frag
@@ -12,7 +12,7 @@
{
// HLSL allows this as an identifier as well.
// However, this is not true of other qualifier keywords such as "linear".
- int sample = 3;
+ float4 sample = float4(3,4,5,6);
- return float4(0,0,0,0);
+ return sample.rgba; // 'sample' can participate in an expression.
}
diff --git a/Test/spv.GeometryShaderPassthrough.geom b/Test/spv.GeometryShaderPassthrough.geom
new file mode 100644
index 0000000..9e6fe4c
--- /dev/null
+++ b/Test/spv.GeometryShaderPassthrough.geom
@@ -0,0 +1,17 @@
+#version 450
+#extension GL_NV_geometry_shader_passthrough : require
+
+layout(triangles) in;
+
+layout(passthrough) in gl_PerVertex {
+ vec4 gl_Position;
+};
+
+layout(passthrough) in Inputs {
+vec2 texcoord;
+vec4 baseColor;
+};
+
+void main()
+{
+}
\ No newline at end of file
diff --git a/Test/spv.sampleMaskOverrideCoverage.frag b/Test/spv.sampleMaskOverrideCoverage.frag
new file mode 100644
index 0000000..dd84062
--- /dev/null
+++ b/Test/spv.sampleMaskOverrideCoverage.frag
@@ -0,0 +1,7 @@
+#version 450
+#extension GL_NV_sample_mask_override_coverage : enable
+in vec4 color;
+layout(override_coverage) out int gl_SampleMask[];
+void main() {
+ gl_SampleMask[0] = int(0xFFFFFFFF);
+}
\ No newline at end of file
diff --git a/Test/tokenPaste.vert b/Test/tokenPaste.vert
new file mode 100644
index 0000000..c30892f
--- /dev/null
+++ b/Test/tokenPaste.vert
@@ -0,0 +1,70 @@
+#version 450
+
+// side test verifies multiple rounds of argument expansion
+#define bear SecondExpansion
+#define mmmB bear
+#define mmmA(a) a
+int mmmA(mmmB); // mmmB -> bear, and then in mmmA(), bear -> SecondExpansion
+
+// pasting skips the first round of expansion
+#define mmcatmmdog PostPasteExpansion
+#define mmcat cat
+#define mmdog dog
+#define mmp(a,b) a## b
+int mmp(mmcat, mmdog); // mmcat/mmdog not expanded, mmcatmmdog -> PostPasteExpansion
+
+// multi-token pre
+#define mmtokpastepre(a) a##27
+mmtokpastepre(float foo); // should declare "float foo27;"
+
+// multi-token post
+#define mmtokpastepost(a) uni ##a
+mmtokpastepost(form float foo155); // should declare "uniform float foo155;"
+
+// non-first argument
+#define foo ShouldntExpandToThis
+#define semi ;
+#define bothpaste(a,b) a##b
+float bothpaste(foo, 719); // should declare "float foo719;"
+#define secpaste(a,b) a bar ## b
+secpaste(uniform float, foo semi) // should declare "uniform float barfoo;"
+
+// no args
+#define noArg fl##oat
+noArg argless;
+
+// bad location
+#define bad1 ## float
+bad1 dc1;
+#define bad2 float ##
+bad2 dc2;
+
+// multiple ##
+#define multiPaste(a, b, c) a##or##b flo##at foo##c
+multiPaste(unif, m, 875);
+
+// too long
+#define simplePaste(a,b) a##b
+// 1020 + 5 characters
+float simplePaste(ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345, 12345);
+
+// non-identifiers
+int a = simplePaste(11,12);
+
+// operators
+#define MAKE_OP(L, R) L ## R
+const int aop = 10;
+const int bop = 4;
+int cop = aop MAKE_OP(<, <) bop;
+bool dop = aop MAKE_OP(!,=) bop;
+
+#define MAKE_OP3(L, M, R) L ## M ## R
+
+void foo()
+{
+ int e = 16;
+ e MAKE_OP3(>,>,=) 2;
+
+ // recovery from bad op
+ bool f = e MAKE_OP(>,!) 5;
+}
diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index 8745c7a..ae40465 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -599,6 +599,9 @@
layoutFormat = ElfNone;
layoutPushConstant = false;
+#ifdef NV_EXTENSIONS
+ layoutPassthrough = false;
+#endif
}
bool hasLayout() const
{
@@ -652,6 +655,10 @@
bool layoutPushConstant;
+#ifdef NV_EXTENSIONS
+ bool layoutPassthrough;
+#endif
+
bool hasUniformLayout() const
{
return hasMatrix() ||
@@ -920,6 +927,10 @@
TLayoutDepth layoutDepth;
bool blendEquation; // true if any blend equation was specified
+#ifdef NV_EXTENSIONS
+ bool layoutOverrideCoverage; // true if layout override_coverage set
+#endif
+
void init()
{
geometry = ElgNone;
@@ -939,6 +950,9 @@
earlyFragmentTests = false;
layoutDepth = EldNone;
blendEquation = false;
+#ifdef NV_EXTENSIONS
+ layoutOverrideCoverage = false;
+#endif
}
// Merge in characteristics from the 'src' qualifier. They can override when
@@ -975,6 +989,10 @@
layoutDepth = src.layoutDepth;
if (src.blendEquation)
blendEquation = src.blendEquation;
+#ifdef NV_EXTENSIONS
+ if (src.layoutOverrideCoverage)
+ layoutOverrideCoverage = src.layoutOverrideCoverage;
+#endif
}
};
@@ -1525,6 +1543,13 @@
p += snprintf(p, end - p, "constant_id=%d ", qualifier.layoutSpecConstantId);
if (qualifier.layoutPushConstant)
p += snprintf(p, end - p, "push_constant ");
+
+#ifdef NV_EXTENSIONS
+ if (qualifier.layoutPassthrough)
+ p += snprintf(p, end - p, "passthrough ");
+#endif
+
+
p += snprintf(p, end - p, ") ");
}
}
diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h
index 5fda0eb..5306125 100644
--- a/glslang/Include/revision.h
+++ b/glslang/Include/revision.h
@@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run).
-#define GLSLANG_REVISION "Overload400-PrecQual.1689"
-#define GLSLANG_DATE "12-Dec-2016"
+#define GLSLANG_REVISION "Overload400-PrecQual.1721"
+#define GLSLANG_DATE "21-Dec-2016"
diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp
index 804626f..61b6f67 100644
--- a/glslang/MachineIndependent/Constant.cpp
+++ b/glslang/MachineIndependent/Constant.cpp
@@ -57,7 +57,7 @@
u.d = x;
int bitPatternL = u.i[0];
int bitPatternH = u.i[1];
- return (bitPatternH & 0x7ff80000) == 0x7ff80000 &&
+ return (bitPatternH & 0x7ff80000) == 0x7ff80000 &&
((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0);
}
@@ -68,7 +68,7 @@
u.d = x;
int bitPatternL = u.i[0];
int bitPatternH = u.i[1];
- return (bitPatternH & 0x7ff00000) == 0x7ff00000 &&
+ return (bitPatternH & 0x7ff00000) == 0x7ff00000 &&
(bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0;
}
@@ -131,7 +131,7 @@
TConstUnionArray smearedArray(newComps, rightNode->getConstArray()[0]);
rightUnionArray = smearedArray;
} else if (constComps > 1 && newComps == 1) {
- // for a case like vec4 f = 1.2 + vec4(2,3,4,5);
+ // for a case like vec4 f = 1.2 + vec4(2,3,4,5);
newComps = constComps;
rightUnionArray = rightNode->getConstArray();
TConstUnionArray smearedArray(newComps, getConstArray()[0]);
@@ -626,7 +626,7 @@
//
// Do constant folding for an aggregate node that has all its children
// as constants and an operator that requires constant folding.
-//
+//
TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
{
if (! areAllChildConst(aggrNode))
@@ -802,7 +802,7 @@
break;
case EOpSmoothStep:
{
- double t = (childConstUnions[2][arg2comp].getDConst() - childConstUnions[0][arg0comp].getDConst()) /
+ double t = (childConstUnions[2][arg2comp].getDConst() - childConstUnions[0][arg0comp].getDConst()) /
(childConstUnions[1][arg1comp].getDConst() - childConstUnions[0][arg0comp].getDConst());
if (t < 0.0)
t = 0.0;
@@ -841,7 +841,7 @@
newConstArray[2] = childConstUnions[0][0] * childConstUnions[1][1] - childConstUnions[0][1] * childConstUnions[1][0];
break;
case EOpFaceForward:
- // If dot(Nref, I) < 0 return N, otherwise return –N: Arguments are (N, I, Nref).
+ // If dot(Nref, I) < 0 return N, otherwise return -N: Arguments are (N, I, Nref).
dot = childConstUnions[1].dot(childConstUnions[2]);
for (int comp = 0; comp < numComps; ++comp) {
if (dot < 0.0)
@@ -968,7 +968,7 @@
}
//
-// Make a constant vector node or constant scalar node, representing a given
+// Make a constant vector node or constant scalar node, representing a given
// constant vector and constant swizzle into it.
//
TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TVectorFields& fields, const TSourceLoc& loc)
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
index 9b6d4c6..999fd5d 100644
--- a/glslang/MachineIndependent/Intermediate.cpp
+++ b/glslang/MachineIndependent/Intermediate.cpp
@@ -2241,7 +2241,7 @@
{
TOperator op = node.getOp();
TIntermSequence& args = node.getSequence();
- const int numArgs = args.size();
+ const int numArgs = static_cast<int>(args.size());
// Presently, only hlsl does intrinsic promotions.
if (getSource() != EShSourceHlsl)
diff --git a/glslang/MachineIndependent/ParseContextBase.cpp b/glslang/MachineIndependent/ParseContextBase.cpp
index d084af8..d86e19d 100644
--- a/glslang/MachineIndependent/ParseContextBase.cpp
+++ b/glslang/MachineIndependent/ParseContextBase.cpp
@@ -472,7 +472,7 @@
void TParseContextBase::finish()
{
if (!parsingBuiltins) {
- // Transfer te linkage symbols to AST nodes
+ // Transfer the linkage symbols to AST nodes
for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i)
intermediate.addSymbolLinkageNode(linkage, **i);
intermediate.addSymbolLinkageNodes(linkage, getLanguage(), symbolTable);
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index ed043e0..67bb883 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -604,7 +604,11 @@
void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
{
if (! type.isArray() && ! symbolTable.atBuiltInLevel()) {
- if (type.getQualifier().isArrayedIo(language))
+ if (type.getQualifier().isArrayedIo(language)
+#ifdef NV_EXTENSIONS
+ && !type.getQualifier().layoutPassthrough
+#endif
+ )
error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str());
}
}
@@ -3304,6 +3308,9 @@
identifier == "gl_BackSecondaryColor" ||
identifier == "gl_SecondaryColor" ||
(identifier == "gl_Color" && language == EShLangFragment) ||
+#ifdef NV_EXTENSIONS
+ identifier == "gl_SampleMask" ||
+#endif
identifier == "gl_TexCoord") {
// Find the existing symbol, if any.
@@ -3381,8 +3388,16 @@
if (! intermediate.setDepth(publicType.layoutDepth))
error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str());
}
-
}
+#ifdef NV_EXTENSIONS
+ else if (identifier == "gl_SampleMask") {
+ if (!publicType.layoutOverrideCoverage) {
+ error(loc, "redeclaration only allowed for override_coverage layout", "redeclaration", symbol->getName().c_str());
+ }
+ intermediate.setLayoutOverrideCoverage();
+ }
+#endif
+
// TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above
return symbol;
@@ -3448,6 +3463,20 @@
// - remove unused members
// - ensure remaining qualifiers/types match
TType& type = block->getWritableType();
+
+#ifdef NV_EXTENSIONS
+ // if gl_PerVertex is redeclared for the purpose of passing through "gl_Position"
+ // for passthrough purpose, the redclared block should have the same qualifers as
+ // the current one
+ if (currentBlockQualifier.layoutPassthrough)
+ {
+ type.getQualifier().layoutPassthrough = currentBlockQualifier.layoutPassthrough;
+ type.getQualifier().storage = currentBlockQualifier.storage;
+ type.getQualifier().layoutStream = currentBlockQualifier.layoutStream;
+ type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer;
+ }
+#endif
+
TTypeList::iterator member = type.getWritableStruct()->begin();
size_t numOriginalMembersFound = 0;
while (member != type.getStruct()->end()) {
@@ -3917,6 +3946,14 @@
publicType.shaderQualifiers.geometry = ElgTriangleStrip;
return;
}
+#ifdef NV_EXTENSIONS
+ if (id == "passthrough") {
+ requireExtensions(loc, 1, &E_SPV_NV_geometry_shader_passthrough, "geometry shader passthrough");
+ publicType.qualifier.layoutPassthrough = true;
+ intermediate.setGeoPassthroughEXT();
+ return;
+ }
+#endif
} else {
assert(language == EShLangTessEvaluation);
@@ -4005,6 +4042,13 @@
error(loc, "unknown blend equation", "blend_support", "");
return;
}
+#ifdef NV_EXTENSIONS
+ if (id == "override_coverage") {
+ requireExtensions(loc, 1, &E_GL_NV_sample_mask_override_coverage, "sample mask override coverage");
+ publicType.shaderQualifiers.layoutOverrideCoverage = true;
+ return;
+ }
+#endif
}
error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
}
@@ -4310,6 +4354,11 @@
if (src.layoutPushConstant)
dst.layoutPushConstant = true;
+
+#ifdef NV_EXTENSIONS
+ if (src.layoutPassthrough)
+ dst.layoutPassthrough = true;
+#endif
}
}
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
index 6234db6..f850f08 100644
--- a/glslang/MachineIndependent/ParseHelper.h
+++ b/glslang/MachineIndependent/ParseHelper.h
@@ -49,8 +49,7 @@
#include "SymbolTable.h"
#include "localintermediate.h"
#include "Scan.h"
-#include <functional>
-
+#include <cstdarg>
#include <functional>
namespace glslang {
@@ -238,23 +237,23 @@
bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); };
void setPrecisionDefaults();
- void setLimits(const TBuiltInResource&);
- bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false);
+ void setLimits(const TBuiltInResource&) override;
+ bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
void parserError(const char* s); // for bison's yyerror
void reservedErrorCheck(const TSourceLoc&, const TString&);
- void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op);
- bool lineContinuationCheck(const TSourceLoc&, bool endOfComment);
- bool lineDirectiveShouldSetNextLine() const;
+ void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override;
+ bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override;
+ bool lineDirectiveShouldSetNextLine() const override;
bool builtInName(const TString&);
- void handlePragma(const TSourceLoc&, const TVector<TString>&);
+ void handlePragma(const TSourceLoc&, const TVector<TString>&) override;
TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
void checkIndex(const TSourceLoc&, const TType&, int& index);
void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
- void makeEditable(TSymbol*&);
+ void makeEditable(TSymbol*&) override;
bool isIoResizeArray(const TType&) const;
void fixIoArraySize(const TSourceLoc&, TType&);
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
diff --git a/glslang/MachineIndependent/Scan.cpp b/glslang/MachineIndependent/Scan.cpp
index 3750645..3ea316d 100644
--- a/glslang/MachineIndependent/Scan.cpp
+++ b/glslang/MachineIndependent/Scan.cpp
@@ -638,13 +638,14 @@
do {
parserToken = &token;
TPpToken ppToken;
- tokenText = pp->tokenize(&ppToken);
- if (tokenText == nullptr || tokenText[0] == 0)
+ int token = pp->tokenize(ppToken);
+ if (token == EndOfInput)
return 0;
+ tokenText = ppToken.name;
loc = ppToken.loc;
parserToken->sType.lex.loc = loc;
- switch (ppToken.token) {
+ switch (token) {
case ';': afterType = false; return SEMICOLON;
case ',': afterType = false; return COMMA;
case ':': return COLON;
@@ -673,11 +674,11 @@
parseContext.error(loc, "illegal use of escape character", "\\", "");
break;
- case PpAtomAdd: return ADD_ASSIGN;
- case PpAtomSub: return SUB_ASSIGN;
- case PpAtomMul: return MUL_ASSIGN;
- case PpAtomDiv: return DIV_ASSIGN;
- case PpAtomMod: return MOD_ASSIGN;
+ case PPAtomAddAssign: return ADD_ASSIGN;
+ case PPAtomSubAssign: return SUB_ASSIGN;
+ case PPAtomMulAssign: return MUL_ASSIGN;
+ case PPAtomDivAssign: return DIV_ASSIGN;
+ case PPAtomModAssign: return MOD_ASSIGN;
case PpAtomRight: return RIGHT_OP;
case PpAtomLeft: return LEFT_OP;
@@ -720,7 +721,7 @@
default:
char buf[2];
- buf[0] = (char)ppToken.token;
+ buf[0] = token;
buf[1] = 0;
parseContext.error(loc, "unexpected token", buf, "");
break;
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index e50b12f..9038a7f 100644
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -868,7 +868,7 @@
// This is a list of tokens that do not require a space before or after.
static const std::string unNeededSpaceTokens = ";()[]";
static const std::string noSpaceBeforeTokens = ",";
- glslang::TPpToken token;
+ glslang::TPpToken ppToken;
parseContext.setScanner(&input);
ppContext.setInput(input, versionWillBeError);
@@ -931,29 +931,33 @@
});
int lastToken = EndOfInput; // lastToken records the last token processed.
- while (const char* tok = ppContext.tokenize(&token)) {
+ do {
+ int token = ppContext.tokenize(ppToken);
+ if (token == EndOfInput)
+ break;
+
bool isNewString = lineSync.syncToMostRecentString();
- bool isNewLine = lineSync.syncToLine(token.loc.line);
+ bool isNewLine = lineSync.syncToLine(ppToken.loc.line);
if (isNewLine) {
// Don't emit whitespace onto empty lines.
// Copy any whitespace characters at the start of a line
// from the input to the output.
- outputStream << std::string(token.loc.column - 1, ' ');
+ outputStream << std::string(ppToken.loc.column - 1, ' ');
}
// Output a space in between tokens, but not at the start of a line,
// and also not around special tokens. This helps with readability
// and consistency.
if (!isNewString && !isNewLine && lastToken != EndOfInput &&
- (unNeededSpaceTokens.find((char)token.token) == std::string::npos) &&
+ (unNeededSpaceTokens.find((char)token) == std::string::npos) &&
(unNeededSpaceTokens.find((char)lastToken) == std::string::npos) &&
- (noSpaceBeforeTokens.find((char)token.token) == std::string::npos)) {
+ (noSpaceBeforeTokens.find((char)token) == std::string::npos)) {
outputStream << " ";
}
- lastToken = token.token;
- outputStream << tok;
- }
+ lastToken = token;
+ outputStream << ppToken.name;
+ } while (true);
outputStream << std::endl;
*outputString = outputStream.str();
diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp
index 8a29cb3..afedb4f 100644
--- a/glslang/MachineIndependent/Versions.cpp
+++ b/glslang/MachineIndependent/Versions.cpp
@@ -195,6 +195,11 @@
extensionBehavior[E_GL_AMD_gpu_shader_half_float] = EBhDisable;
#endif
+#ifdef NV_EXTENSIONS
+ extensionBehavior[E_GL_NV_sample_mask_override_coverage] = EBhDisable;
+ extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable;
+#endif
+
// AEP
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable;
extensionBehavior[E_GL_KHR_blend_equation_advanced] = EBhDisable;
@@ -302,6 +307,11 @@
"#define GL_AMD_gcn_shader 1\n"
"#define GL_AMD_gpu_shader_half_float 1\n"
#endif
+
+#ifdef NV_EXTENSIONS
+ "#define GL_NV_sample_mask_override_coverage 1\n"
+ "#define GL_NV_geometry_shader_passthrough 1\n"
+#endif
;
}
diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h
index 17baf3b..fe9764f 100644
--- a/glslang/MachineIndependent/Versions.h
+++ b/glslang/MachineIndependent/Versions.h
@@ -142,6 +142,10 @@
const char* const E_GL_AMD_gcn_shader = "GL_AMD_gcn_shader";
const char* const E_GL_AMD_gpu_shader_half_float = "GL_AMD_gpu_shader_half_float";
#endif
+#ifdef NV_EXTENSIONS
+const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
+const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough";
+#endif
// AEP
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp
index 3834fde..b8ce6d7 100644
--- a/glslang/MachineIndependent/linkValidate.cpp
+++ b/glslang/MachineIndependent/linkValidate.cpp
@@ -469,9 +469,17 @@
case EShLangGeometry:
if (inputPrimitive == ElgNone)
error(infoSink, "At least one shader must specify an input layout primitive");
- if (outputPrimitive == ElgNone)
+ if (outputPrimitive == ElgNone
+#ifdef NV_EXTENSIONS
+ && !getGeoPassthroughEXT()
+#endif
+ )
error(infoSink, "At least one shader must specify an output layout primitive");
- if (vertices == TQualifier::layoutNotSet)
+ if (vertices == TQualifier::layoutNotSet
+#ifdef NV_EXTENSIONS
+ && !getGeoPassthroughEXT()
+#endif
+ )
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
break;
case EShLangFragment:
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index 6f6db92..34875c2 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -151,6 +151,10 @@
shiftUboBinding(0),
autoMapBindings(false),
flattenUniformArrays(false),
+#ifdef NV_EXTENSIONS
+ layoutOverrideCoverage(false),
+ geoPassthroughEXT(false),
+#endif
useUnknownFormat(false)
{
localSize[0] = 1;
@@ -387,6 +391,13 @@
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
bool promote(TIntermOperator*);
+#ifdef NV_EXTENSIONS
+ void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
+ bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
+ void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
+ bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
+#endif
+
protected:
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
void error(TInfoSink& infoSink, const char*);
@@ -447,6 +458,11 @@
bool xfbMode;
bool multiStream;
+#ifdef NV_EXTENSIONS
+ bool layoutOverrideCoverage;
+ bool geoPassthroughEXT;
+#endif
+
typedef std::list<TCall> TGraph;
TGraph callGraph;
diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp
index 824a69a..595b729 100644
--- a/glslang/MachineIndependent/preprocessor/Pp.cpp
+++ b/glslang/MachineIndependent/preprocessor/Pp.cpp
@@ -75,9 +75,6 @@
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
-//
-// cpp.c
-//
#define _CRT_SECURE_NO_WARNINGS
@@ -91,20 +88,12 @@
namespace glslang {
-int TPpContext::InitCPP()
-{
- pool = mem_CreatePool(0, 0);
-
- return 1;
-}
-
// Handle #define
int TPpContext::CPPdefine(TPpToken* ppToken)
{
MacroSymbol mac;
- Symbol *symb;
- // get macro name
+ // get the macro name
int token = scanToken(ppToken);
if (token != PpAtomIdentifier) {
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#define", "");
@@ -115,38 +104,36 @@
parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#define");
}
- // save the original atom
- const int defAtom = ppToken->atom;
+ // save the macro name
+ const int defAtom = atomStrings.getAddAtom(ppToken->name);
// gather parameters to the macro, between (...)
token = scanToken(ppToken);
if (token == '(' && ! ppToken->space) {
- int argc = 0;
- int args[maxMacroArgs];
+ mac.emptyArgs = 1;
do {
token = scanToken(ppToken);
- if (argc == 0 && token == ')')
+ if (mac.args.size() == 0 && token == ')')
break;
if (token != PpAtomIdentifier) {
parseContext.ppError(ppToken->loc, "bad argument", "#define", "");
return token;
}
+ mac.emptyArgs = 0;
+ const int argAtom = atomStrings.getAddAtom(ppToken->name);
+
// check for duplication of parameter name
bool duplicate = false;
- for (int a = 0; a < argc; ++a) {
- if (args[a] == ppToken->atom) {
+ for (size_t a = 0; a < mac.args.size(); ++a) {
+ if (mac.args[a] == argAtom) {
parseContext.ppError(ppToken->loc, "duplicate macro parameter", "#define", "");
duplicate = true;
break;
}
}
- if (! duplicate) {
- if (argc < maxMacroArgs)
- args[argc++] = ppToken->atom;
- else
- parseContext.ppError(ppToken->loc, "too many macro parameters", "#define", "");
- }
+ if (! duplicate)
+ mac.args.push_back(argAtom);
token = scanToken(ppToken);
} while (token == ',');
if (token != ')') {
@@ -154,15 +141,12 @@
return token;
}
- mac.argc = argc;
- mac.args = (int*)mem_Alloc(pool, argc * sizeof(int));
- memcpy(mac.args, args, argc * sizeof(int));
+
token = scanToken(ppToken);
}
// record the definition of the macro
TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors
- mac.body = new TokenStream;
while (token != '\n' && token != EndOfInput) {
RecordToken(mac.body, token, ppToken);
token = scanToken(ppToken);
@@ -171,40 +155,36 @@
}
// check for duplicate definition
- symb = LookUpSymbol(defAtom);
- if (symb) {
- if (! symb->mac.undef) {
+ MacroSymbol* existing = lookupMacroDef(defAtom);
+ if (existing != nullptr) {
+ if (! existing->undef) {
// 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 (symb->mac.argc != mac.argc)
- parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", GetAtomString(defAtom));
+ if (existing->args.size() != mac.args.size() || existing->emptyArgs != mac.emptyArgs)
+ parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom));
else {
- for (int argc = 0; argc < mac.argc; argc++) {
- if (symb->mac.args[argc] != mac.args[argc])
- parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", GetAtomString(defAtom));
- }
- RewindTokenStream(symb->mac.body);
+ if (existing->args != mac.args)
+ parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom));
+ RewindTokenStream(existing->body);
RewindTokenStream(mac.body);
int newToken;
do {
int oldToken;
TPpToken oldPpToken;
TPpToken newPpToken;
- oldToken = ReadToken(symb->mac.body, &oldPpToken);
+ oldToken = ReadToken(existing->body, &oldPpToken);
newToken = ReadToken(mac.body, &newPpToken);
if (oldToken != newToken || oldPpToken != newPpToken) {
- parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", GetAtomString(defAtom));
+ parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom));
break;
}
} while (newToken > 0);
}
}
+ *existing = mac;
} else
- symb = AddSymbol(defAtom);
-
- delete symb->mac.body;
- symb->mac = mac;
+ addMacroDef(defAtom, mac);
return '\n';
}
@@ -213,7 +193,6 @@
int TPpContext::CPPundef(TPpToken* ppToken)
{
int token = scanToken(ppToken);
- Symbol *symb;
if (token != PpAtomIdentifier) {
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#undef", "");
@@ -222,10 +201,9 @@
parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#undef");
- symb = LookUpSymbol(ppToken->atom);
- if (symb) {
- symb->mac.undef = 1;
- }
+ MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
+ if (macro != nullptr)
+ macro->undef = 1;
token = scanToken(ppToken);
if (token != '\n')
parseContext.ppError(ppToken->loc, "can only be followed by a single macro name", "#undef", "");
@@ -240,7 +218,6 @@
*/
int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
{
- int atom;
int depth = 0;
int token = scanToken(ppToken);
@@ -259,13 +236,13 @@
if ((token = scanToken(ppToken)) != PpAtomIdentifier)
continue;
- atom = ppToken->atom;
- if (atom == PpAtomIf || atom == PpAtomIfdef || atom == PpAtomIfndef) {
+ int nextAtom = atomStrings.getAtom(ppToken->name);
+ if (nextAtom == PpAtomIf || nextAtom == PpAtomIfdef || nextAtom == PpAtomIfndef) {
depth++;
ifdepth++;
elsetracker++;
- } else if (atom == PpAtomEndif) {
- token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
+ } else if (nextAtom == PpAtomEndif) {
+ token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
elseSeen[elsetracker] = false;
--elsetracker;
if (depth == 0) {
@@ -277,12 +254,12 @@
--depth;
--ifdepth;
} else if (matchelse && depth == 0) {
- if (atom == PpAtomElse) {
+ if (nextAtom == PpAtomElse) {
elseSeen[elsetracker] = true;
- token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
+ token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
// found the #else we are looking for
break;
- } else if (atom == PpAtomElif) {
+ } else if (nextAtom == PpAtomElif) {
if (elseSeen[elsetracker])
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
/* we decrement ifdepth here, because CPPif will increment
@@ -295,13 +272,13 @@
return CPPif(ppToken);
}
- } else if (atom == PpAtomElse) {
+ } else if (nextAtom == PpAtomElse) {
if (elseSeen[elsetracker])
parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
else
elseSeen[elsetracker] = true;
- token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
- } else if (atom == PpAtomElif) {
+ token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
+ } else if (nextAtom == PpAtomElif) {
if (elseSeen[elsetracker])
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
}
@@ -311,21 +288,21 @@
}
// Call when there should be no more tokens left on a line.
-int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token)
+int TPpContext::extraTokenCheck(int contextAtom, TPpToken* ppToken, int token)
{
if (token != '\n' && token != EndOfInput) {
static const char* message = "unexpected tokens following directive";
const char* label;
- if (atom == PpAtomElse)
+ if (contextAtom == PpAtomElse)
label = "#else";
- else if (atom == PpAtomElif)
+ else if (contextAtom == PpAtomElif)
label = "#elif";
- else if (atom == PpAtomEndif)
+ else if (contextAtom == PpAtomEndif)
label = "#endif";
- else if (atom == PpAtomIf)
+ else if (contextAtom == PpAtomIf)
label = "#if";
- else if (atom == PpAtomLine)
+ else if (contextAtom == PpAtomLine)
label = "#line";
else
label = "";
@@ -413,7 +390,7 @@
{
TSourceLoc loc = ppToken->loc; // because we sometimes read the newline before reporting the error
if (token == PpAtomIdentifier) {
- if (ppToken->atom == PpAtomDefined) {
+ if (strcmp("defined", ppToken->name) == 0) {
bool needclose = 0;
token = scanToken(ppToken);
if (token == '(') {
@@ -427,8 +404,9 @@
return token;
}
- Symbol* s = LookUpSymbol(ppToken->atom);
- res = s ? ! s->mac.undef : 0;
+
+ MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
+ res = macro != nullptr ? !macro->undef : 0;
token = scanToken(ppToken);
if (needclose) {
if (token != ')') {
@@ -520,8 +498,8 @@
// Expand macros, skipping empty expansions, to get to the first real token in those expansions.
int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken* ppToken)
{
- while (token == PpAtomIdentifier && ppToken->atom != PpAtomDefined) {
- int macroReturn = MacroExpand(ppToken->atom, ppToken, true, false);
+ while (token == PpAtomIdentifier && strcmp("defined", ppToken->name) != 0) {
+ int macroReturn = MacroExpand(ppToken, true, false);
if (macroReturn == 0) {
parseContext.ppError(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
err = true;
@@ -568,7 +546,6 @@
int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
{
int token = scanToken(ppToken);
- int name = ppToken->atom;
if (++ifdepth > maxIfNesting) {
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", "");
return 0;
@@ -580,14 +557,14 @@
else
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", "");
} else {
- Symbol *s = LookUpSymbol(name);
+ MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
token = scanToken(ppToken);
if (token != '\n') {
parseContext.ppError(ppToken->loc, "unexpected tokens following #ifdef directive - expected a newline", "#ifdef", "");
while (token != '\n' && token != EndOfInput)
token = scanToken(ppToken);
}
- if (((s && !s->mac.undef) ? 1 : 0) != defined)
+ if (((macro != nullptr && !macro->undef) ? 1 : 0) != defined)
token = CPPelse(1, ppToken);
}
@@ -674,7 +651,7 @@
// We need to save a copy of the string instead of pointing
// to the name field of the token since the name field
// will likely be overwritten by the next token scan.
- sourceName = GetAtomString(LookUpAddString(ppToken->name));
+ sourceName = atomStrings.getString(atomStrings.getAddAtom(ppToken->name));
parseContext.setCurrentSourceName(sourceName);
hasFile = true;
token = scanToken(ppToken);
@@ -713,7 +690,7 @@
} else if (token == PpAtomIdentifier || token == PpAtomConstString) {
message.append(ppToken->name);
} else {
- message.append(GetAtomString(token));
+ message.append(atomStrings.getString(token));
}
message.append(" ");
token = scanToken(ppToken);
@@ -790,9 +767,10 @@
parseContext.notifyVersion(line, versionNumber, nullptr);
return token;
} else {
- if (ppToken->atom != PpAtomCore &&
- ppToken->atom != PpAtomCompatibility &&
- ppToken->atom != PpAtomEs)
+ int profileAtom = atomStrings.getAtom(ppToken->name);
+ if (profileAtom != PpAtomCore &&
+ profileAtom != PpAtomCompatibility &&
+ profileAtom != PpAtomEs)
parseContext.ppError(ppToken->loc, "bad profile name; use es, core, or compatibility", "#version", "");
parseContext.notifyVersion(line, versionNumber, ppToken->name);
token = scanToken(ppToken);
@@ -853,7 +831,7 @@
int token = scanToken(ppToken);
if (token == PpAtomIdentifier) {
- switch (ppToken->atom) {
+ switch (atomStrings.getAtom(ppToken->name)) {
case PpAtomDefine:
token = CPPdefine(ppToken);
break;
@@ -933,36 +911,42 @@
return token;
}
-TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream* a, TPpToken* ppToken, bool newLineOkay)
+// Macro-expand a macro argument 'arg' to create 'expandedArg'.
+// Does not replace 'arg'.
+// Returns nullptr if no expanded argument is created.
+TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* ppToken, bool newLineOkay)
{
+ // pre-check, to see if anything in the argument needs to be expanded,
+ // to see if we can kick out early
int token;
- TokenStream *n;
- RewindTokenStream(a);
+ RewindTokenStream(arg);
do {
- token = ReadToken(a, ppToken);
- if (token == PpAtomIdentifier && LookUpSymbol(ppToken->atom))
+ token = ReadToken(arg, ppToken);
+ if (token == PpAtomIdentifier && lookupMacroDef(atomStrings.getAtom(ppToken->name)) != nullptr)
break;
} while (token != EndOfInput);
+ // if nothing needs to be expanded, kick out early
if (token == EndOfInput)
- return a;
+ return nullptr;
- n = new TokenStream;
+ // expand the argument
+ TokenStream* expandedArg = new TokenStream;
pushInput(new tMarkerInput(this));
- pushTokenStreamInput(a);
+ pushTokenStreamInput(arg);
while ((token = scanToken(ppToken)) != tMarkerInput::marker) {
- if (token == PpAtomIdentifier && MacroExpand(ppToken->atom, ppToken, false, newLineOkay) != 0)
+ if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0)
continue;
- RecordToken(n, token, ppToken);
+ RecordToken(*expandedArg, token, ppToken);
}
popInput();
- delete a;
- return n;
+ return expandedArg;
}
//
-// Return the next token for a macro expansion, handling macro args.
+// Return the next token for a macro expansion, handling macro arguments,
+// whose semantics are dependent on being adjacent to ##.
//
int TPpContext::tMacroInput::scan(TPpToken* ppToken)
{
@@ -971,14 +955,50 @@
token = pp->ReadToken(mac->body, ppToken);
} while (token == ' '); // handle white space in macro
+ // Hash operators basically turn off a round of macro substitution
+ // (the round done on the argument before the round done on the RHS of the
+ // macro definition):
+ //
+ // "A parameter in the replacement list, unless preceded by a # or ##
+ // preprocessing token or followed by a ## preprocessing token (see below),
+ // is replaced by the corresponding argument after all macros contained
+ // therein have been expanded."
+ //
+ // "If, in the replacement list, a parameter is immediately preceded or
+ // followed by a ## preprocessing token, the parameter is replaced by the
+ // corresponding argument's preprocessing token sequence."
+
+ bool pasting = false;
+ if (postpaste) {
+ // don't expand next token
+ pasting = true;
+ postpaste = false;
+ }
+
+ if (prepaste) {
+ // already know we should be on a ##, verify
+ assert(token == PpAtomPaste);
+ prepaste = false;
+ postpaste = true;
+ }
+
+ // see if are preceding a ##
+ if (peekMacPasting()) {
+ prepaste = true;
+ pasting = true;
+ }
+
// TODO: preprocessor: properly handle whitespace (or lack of it) between tokens when expanding
if (token == PpAtomIdentifier) {
int i;
- for (i = mac->argc - 1; i >= 0; i--)
- if (mac->args[i] == ppToken->atom)
+ for (i = mac->args.size() - 1; i >= 0; i--)
+ if (strcmp(pp->atomStrings.getString(mac->args[i]), ppToken->name) == 0)
break;
if (i >= 0) {
- pp->pushTokenStreamInput(args[i]);
+ TokenStream* arg = expandedArgs[i];
+ if (arg == nullptr || pasting)
+ arg = args[i];
+ pp->pushTokenStreamInput(*arg, prepaste);
return pp->scanToken(ppToken);
}
@@ -990,6 +1010,31 @@
return token;
}
+// See if the next non-white-space token in the macro is ##
+bool TPpContext::tMacroInput::peekMacPasting()
+{
+ // don't return early, have to restore this
+ size_t savePos = mac->body.current;
+
+ // skip white-space
+ int ltoken;
+ do {
+ ltoken = pp->lReadByte(mac->body);
+ } while (ltoken == ' ');
+
+ // check for ##
+ bool pasting = false;
+ if (ltoken == '#') {
+ ltoken = pp->lReadByte(mac->body);
+ if (ltoken == '#')
+ pasting = true;
+ }
+
+ mac->body.current = savePos;
+
+ return pasting;
+}
+
// return a textual zero, for scanning a macro that was never defined
int TPpContext::tZeroInput::scan(TPpToken* ppToken)
{
@@ -1005,17 +1050,18 @@
}
//
-// Check an identifier (atom) to see if it is a macro that should be expanded.
+// Check a token to see if it is a macro that should be expanded.
// If it is, and defined, push a tInput that will produce the appropriate expansion
// and return 1.
// If it is, but undefined, and expandUndef is requested, push a tInput that will
// expand to 0 and return -1.
// Otherwise, return 0 to indicate no expansion, which is not necessarily an error.
//
-int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool newLineOkay)
+int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay)
{
ppToken->space = false;
- switch (atom) {
+ int macroAtom = atomStrings.getAtom(ppToken->name);
+ switch (macroAtom) {
case PpAtomLineMacro:
ppToken->ival = parseContext.getCurrentLoc().line;
snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
@@ -1041,20 +1087,20 @@
break;
}
- Symbol *sym = LookUpSymbol(atom);
+ MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom);
int token;
int depth = 0;
// no recursive expansions
- if (sym && sym->mac.busy)
+ if (macro != nullptr && macro->busy)
return 0;
// not expanding undefined macros
- if ((! sym || sym->mac.undef) && ! expandUndef)
+ if ((macro == nullptr || macro->undef) && ! expandUndef)
return 0;
// 0 is the value of an undefined macro
- if ((! sym || sym->mac.undef) && expandUndef) {
+ if ((macro == nullptr || macro->undef) && expandUndef) {
pushInput(new tZeroInput(this));
return -1;
}
@@ -1062,49 +1108,50 @@
tMacroInput *in = new tMacroInput(this);
TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error
- in->mac = &sym->mac;
- if (sym->mac.args) {
+ in->mac = macro;
+ if (macro->args.size() > 0 || macro->emptyArgs) {
token = scanToken(ppToken);
if (newLineOkay) {
while (token == '\n')
token = scanToken(ppToken);
}
if (token != '(') {
- parseContext.ppError(loc, "expected '(' following", "macro expansion", GetAtomString(atom));
+ parseContext.ppError(loc, "expected '(' following", "macro expansion", atomStrings.getString(macroAtom));
UngetToken(token, ppToken);
- ppToken->atom = atom;
-
delete in;
return 0;
}
- in->args.resize(in->mac->argc);
- for (int i = 0; i < in->mac->argc; i++)
+ in->args.resize(in->mac->args.size());
+ for (size_t i = 0; i < in->mac->args.size(); i++)
in->args[i] = new TokenStream;
- int arg = 0;
+ in->expandedArgs.resize(in->mac->args.size());
+ for (size_t i = 0; i < in->mac->args.size(); i++)
+ in->expandedArgs[i] = nullptr;
+ size_t arg = 0;
bool tokenRecorded = false;
do {
depth = 0;
while (1) {
token = scanToken(ppToken);
if (token == EndOfInput) {
- parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
+ parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
delete in;
return 0;
}
if (token == '\n') {
if (! newLineOkay) {
- parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", GetAtomString(atom));
+ parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", atomStrings.getString(macroAtom));
delete in;
return 0;
}
continue;
}
if (token == '#') {
- parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", GetAtomString(atom));
+ parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", atomStrings.getString(macroAtom));
delete in;
return 0;
}
- if (in->mac->argc == 0 && token != ')')
+ if (in->mac->args.size() == 0 && token != ')')
break;
if (depth == 0 && (token == ',' || token == ')'))
break;
@@ -1112,20 +1159,20 @@
depth++;
if (token == ')')
depth--;
- RecordToken(in->args[arg], token, ppToken);
+ RecordToken(*in->args[arg], token, ppToken);
tokenRecorded = true;
}
if (token == ')') {
- if (in->mac->argc == 1 && tokenRecorded == 0)
+ if (in->mac->args.size() == 1 && tokenRecorded == 0)
break;
arg++;
break;
}
arg++;
- } while (arg < in->mac->argc);
+ } while (arg < in->mac->args.size());
- if (arg < in->mac->argc)
- parseContext.ppError(loc, "Too few args in Macro", "macro expansion", GetAtomString(atom));
+ if (arg < in->mac->args.size())
+ parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom));
else if (token != ')') {
depth=0;
while (token != EndOfInput && (depth > 0 || token != ')')) {
@@ -1137,19 +1184,22 @@
}
if (token == EndOfInput) {
- parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
+ parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
delete in;
return 0;
}
- parseContext.ppError(loc, "Too many args in macro", "macro expansion", GetAtomString(atom));
+ parseContext.ppError(loc, "Too many args in macro", "macro expansion", atomStrings.getString(macroAtom));
}
- for (int i = 0; i < in->mac->argc; i++)
- in->args[i] = PrescanMacroArg(in->args[i], ppToken, newLineOkay);
+
+ // We need both expanded and non-expanded forms of the argument, for whether or
+ // not token pasting is in play.
+ for (size_t i = 0; i < in->mac->args.size(); i++)
+ in->expandedArgs[i] = PrescanMacroArg(*in->args[i], ppToken, newLineOkay);
}
pushInput(in);
- sym->mac.busy = 1;
- RewindTokenStream(sym->mac.body);
+ macro->busy = 1;
+ RewindTokenStream(macro->body);
return 1;
}
diff --git a/glslang/MachineIndependent/preprocessor/PpAtom.cpp b/glslang/MachineIndependent/preprocessor/PpAtom.cpp
index 2b21193..6948aad 100644
--- a/glslang/MachineIndependent/preprocessor/PpAtom.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpAtom.cpp
@@ -76,10 +76,6 @@
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
-//
-// atom.c
-//
-
#define _CRT_SECURE_NO_WARNINGS
#include <cassert>
@@ -98,11 +94,12 @@
const char* str;
} tokens[] = {
- { PpAtomAdd, "+=" },
- { PpAtomSub, "-=" },
- { PpAtomMul, "*=" },
- { PpAtomDiv, "/=" },
- { PpAtomMod, "%=" },
+ { PPAtomAddAssign, "+=" },
+ { PPAtomSubAssign, "-=" },
+ { PPAtomMulAssign, "*=" },
+ { PPAtomDivAssign, "/=" },
+ { PPAtomModAssign, "%=" },
+
{ PpAtomRight, ">>" },
{ PpAtomLeft, "<<" },
{ PpAtomAnd, "&&" },
@@ -124,7 +121,6 @@
{ PpAtomIncrement, "++" },
{ PpAtomDefine, "define" },
- { PpAtomDefined, "defined" },
{ PpAtomUndef, "undef" },
{ PpAtomIf, "if" },
{ PpAtomElif, "elif" },
@@ -154,47 +150,12 @@
namespace glslang {
//
-// Map a new or existing string to an atom, inventing a new atom if necessary.
-//
-int TPpContext::LookUpAddString(const char* s)
-{
- auto it = atomMap.find(s);
- if (it == atomMap.end()) {
- AddAtomFixed(s, nextAtom);
- return nextAtom++;
- } else
- return it->second;
-}
-
-//
-// Map an already created atom to its string.
-//
-const char* TPpContext::GetAtomString(int atom)
-{
- if ((size_t)atom >= stringMap.size())
- return "<bad token>";
-
- const TString* atomString = stringMap[atom];
-
- return atomString ? atomString->c_str() : "<bad token>";
-}
-
-//
-// Add forced mapping of string to atom.
-//
-void TPpContext::AddAtomFixed(const char* s, int atom)
-{
- auto it = atomMap.insert(std::pair<TString, int>(s, atom)).first;
- if (stringMap.size() < (size_t)atom + 1)
- stringMap.resize(atom + 100, 0);
- stringMap[atom] = &it->first;
-}
-
-//
// Initialize the atom table.
//
-void TPpContext::InitAtomTable()
+TStringAtomMap::TStringAtomMap()
{
+ badToken.assign("<bad token>");
+
// Add single character tokens to the atom table:
const char* s = "~!%^&*()-+=|,.<>/?;:[]{}#\\";
char t[2];
@@ -202,13 +163,13 @@
t[1] = '\0';
while (*s) {
t[0] = *s;
- AddAtomFixed(t, s[0]);
+ addAtomFixed(t, s[0]);
s++;
}
// Add multiple character scanner tokens :
for (size_t ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
- AddAtomFixed(tokens[ii].str, tokens[ii].val);
+ addAtomFixed(tokens[ii].str, tokens[ii].val);
nextAtom = PpAtomLast;
}
diff --git a/glslang/MachineIndependent/preprocessor/PpContext.cpp b/glslang/MachineIndependent/preprocessor/PpContext.cpp
index 6791fef..e31127f 100644
--- a/glslang/MachineIndependent/preprocessor/PpContext.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpContext.cpp
@@ -83,13 +83,10 @@
namespace glslang {
TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) :
- preamble(0), strings(0), parseContext(pc), includer(inclr), inComment(false),
+ preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false),
rootFileName(rootFileName),
currentSourceFile(rootFileName)
{
- InitAtomTable();
- InitScanner();
-
ifdepth = 0;
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
elseSeen[elsetracker] = false;
@@ -98,9 +95,6 @@
TPpContext::~TPpContext()
{
- for (TSymbolMap::iterator it = symbols.begin(); it != symbols.end(); ++it)
- delete it->second->mac.body;
- mem_FreePool(pool);
delete [] preamble;
// free up the inputStack
diff --git a/glslang/MachineIndependent/preprocessor/PpContext.h b/glslang/MachineIndependent/preprocessor/PpContext.h
index 013c90e..64f99ef 100644
--- a/glslang/MachineIndependent/preprocessor/PpContext.h
+++ b/glslang/MachineIndependent/preprocessor/PpContext.h
@@ -92,30 +92,85 @@
class TPpToken {
public:
- TPpToken() : token(0), space(false), ival(0), dval(0.0), atom(0)
+ TPpToken() : space(false), ival(0), dval(0.0), i64val(0)
{
loc.init();
name[0] = 0;
}
+ // This is used for comparing macro definitions, so checks what is relevant for that.
bool operator==(const TPpToken& right)
{
- return token == right.token && atom == right.atom &&
- ival == right.ival && dval == right.dval &&
- strcmp(name, right.name) == 0;
+ return space == right.space &&
+ ival == right.ival && dval == right.dval && i64val == right.i64val &&
+ strncmp(name, right.name, MaxTokenLength) == 0;
}
bool operator!=(const TPpToken& right) { return ! operator==(right); }
TSourceLoc loc;
- int token;
bool space; // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned
int ival;
double dval;
long long i64val;
- int atom;
char name[MaxTokenLength + 1];
};
+class TStringAtomMap {
+//
+// Implementation is in PpAtom.cpp
+//
+// Maintain a bi-directional mapping between relevant preprocessor strings and
+// "atoms" which a unique integers (small, contiguous, not hash-like) per string.
+//
+public:
+ TStringAtomMap();
+
+ // Map string -> atom.
+ // Return 0 if no existing string.
+ int getAtom(const char* s) const
+ {
+ auto it = atomMap.find(s);
+ return it == atomMap.end() ? 0 : it->second;
+ }
+
+ // Map a new or existing string -> atom, inventing a new atom if necessary.
+ int getAddAtom(const char* s)
+ {
+ int atom = getAtom(s);
+ if (atom == 0) {
+ atom = nextAtom++;
+ addAtomFixed(s, atom);
+ }
+ return atom;
+ }
+
+ // Map atom -> string.
+ const char* getString(int atom) const { return stringMap[atom]->c_str(); }
+
+protected:
+ TStringAtomMap(TStringAtomMap&);
+ TStringAtomMap& operator=(TStringAtomMap&);
+
+ TUnorderedMap<TString, int> atomMap;
+ TVector<const TString*> stringMap; // these point into the TString in atomMap
+ int nextAtom;
+
+ // Bad source characters can lead to bad atoms, so gracefully handle those by
+ // pre-filling the table with them (to avoid if tests later).
+ TString badToken;
+
+ // Add bi-directional mappings:
+ // - string -> atom
+ // - atom -> string
+ void addAtomFixed(const char* s, int atom)
+ {
+ auto it = atomMap.insert(std::pair<TString, int>(s, atom)).first;
+ if (stringMap.size() < (size_t)atom + 1)
+ stringMap.resize(atom + 100, &badToken);
+ stringMap[atom] = &it->first;
+ }
+};
+
class TInputScanner;
// This class is the result of turning a huge pile of C code communicating through globals
@@ -128,7 +183,8 @@
void setPreamble(const char* preamble, size_t length);
- const char* tokenize(TPpToken* ppToken);
+ int tokenize(TPpToken& ppToken);
+ int tokenPaste(int token, TPpToken&);
class tInput {
public:
@@ -138,6 +194,8 @@
virtual int scan(TPpToken*) = 0;
virtual int getch() = 0;
virtual void ungetch() = 0;
+ virtual bool peekPasting() { return false; } // true when about to see ##
+ virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
// Will be called when we start reading tokens from this instance
virtual void notifyActivated() {}
@@ -168,44 +226,33 @@
size_t current;
};
- struct MemoryPool {
- struct chunk *next;
- uintptr_t free, end;
- size_t chunksize;
- uintptr_t alignmask;
- };
-
//
// From Pp.cpp
//
struct MacroSymbol {
- MacroSymbol() : argc(0), args(0), body(0), busy(0), undef(0) { }
- int argc;
- int *args;
- TokenStream *body;
- unsigned busy:1;
- unsigned undef:1;
+ MacroSymbol() : emptyArgs(0), busy(0), undef(0) { }
+ TVector<int> args;
+ TokenStream body;
+ unsigned emptyArgs : 1;
+ unsigned busy : 1;
+ unsigned undef : 1;
};
- struct Symbol {
- int atom;
- MacroSymbol mac;
- };
-
- struct SymbolList {
- struct SymbolList_Rec *next;
- Symbol *symb;
- };
-
- MemoryPool *pool;
- typedef TMap<int, Symbol*> TSymbolMap;
- TSymbolMap symbols; // this has light use... just defined macros
+ typedef TMap<int, MacroSymbol> TSymbolMap;
+ TSymbolMap macroDefs; // map atoms to macro definitions
+ MacroSymbol* lookupMacroDef(int atom)
+ {
+ auto existingMacroIt = macroDefs.find(atom);
+ return (existingMacroIt == macroDefs.end()) ? nullptr : &(existingMacroIt->second);
+ }
+ void addMacroDef(int atom, MacroSymbol& macroDef) { macroDefs[atom] = macroDef; }
protected:
TPpContext(TPpContext&);
TPpContext& operator=(TPpContext&);
+ TStringAtomMap atomStrings;
char* preamble; // string to parse, all before line 1 of string 0, it is 0 if no preamble
int preambleLength;
char** strings; // official strings of shader, starting a string 0 line 1
@@ -235,8 +282,9 @@
}
int getChar() { return inputStack.back()->getch(); }
void ungetChar() { inputStack.back()->ungetch(); }
+ bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); }
+ bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
- static const int maxMacroArgs = 64;
static const int maxIfNesting = 64;
int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
@@ -245,24 +293,35 @@
class tMacroInput : public tInput {
public:
- tMacroInput(TPpContext* pp) : tInput(pp) { }
+ tMacroInput(TPpContext* pp) : tInput(pp), prepaste(false), postpaste(false) { }
virtual ~tMacroInput()
{
for (size_t i = 0; i < args.size(); ++i)
delete args[i];
+ for (size_t i = 0; i < expandedArgs.size(); ++i)
+ delete expandedArgs[i];
}
- virtual int scan(TPpToken*);
- virtual int getch() { assert(0); return EndOfInput; }
- virtual void ungetch() { assert(0); }
+ virtual int scan(TPpToken*) override;
+ virtual int getch() override { assert(0); return EndOfInput; }
+ virtual void ungetch() override { assert(0); }
+ bool peekPasting() override { return prepaste; }
+ bool endOfReplacementList() override { return mac->body.current >= mac->body.data.size(); }
+
MacroSymbol *mac;
TVector<TokenStream*> args;
+ TVector<TokenStream*> expandedArgs;
+
+ protected:
+ bool peekMacPasting();
+ bool prepaste; // true if we are just before ##
+ bool postpaste; // true if we are right after ##
};
class tMarkerInput : public tInput {
public:
tMarkerInput(TPpContext* pp) : tInput(pp) { }
- virtual int scan(TPpToken*)
+ virtual int scan(TPpToken*) override
{
if (done)
return EndOfInput;
@@ -270,17 +329,17 @@
return marker;
}
- virtual int getch() { assert(0); return EndOfInput; }
- virtual void ungetch() { assert(0); }
+ virtual int getch() override { assert(0); return EndOfInput; }
+ virtual void ungetch() override { assert(0); }
static const int marker = -3;
};
class tZeroInput : public tInput {
public:
tZeroInput(TPpContext* pp) : tInput(pp) { }
- virtual int scan(TPpToken*);
- virtual int getch() { assert(0); return EndOfInput; }
- virtual void ungetch() { assert(0); }
+ virtual int scan(TPpToken*) override;
+ virtual int getch() override { assert(0); return EndOfInput; }
+ virtual void ungetch() override { assert(0); }
};
std::vector<tInput*> inputStack;
@@ -294,7 +353,6 @@
// Used to obtain #include content.
TShader::Includer& includer;
- int InitCPP();
int CPPdefine(TPpToken * ppToken);
int CPPundef(TPpToken * ppToken);
int CPPelse(int matchelse, TPpToken * ppToken);
@@ -310,44 +368,39 @@
int CPPversion(TPpToken * ppToken);
int CPPextension(TPpToken * ppToken);
int readCPPline(TPpToken * ppToken);
- TokenStream* PrescanMacroArg(TokenStream *a, TPpToken * ppToken, bool newLineOkay);
- int MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool newLineOkay);
-
- //
- // from PpSymbols.cpp
- //
- Symbol *NewSymbol(int name);
- Symbol *AddSymbol(int atom);
- Symbol *LookUpSymbol(int atom);
+ TokenStream* PrescanMacroArg(TokenStream&, TPpToken*, bool newLineOkay);
+ int MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay);
//
// From PpTokens.cpp
//
- void lAddByte(TokenStream *fTok, unsigned char fVal);
- int lReadByte(TokenStream *pTok);
- void lUnreadByte(TokenStream *pTok);
- void RecordToken(TokenStream* pTok, int token, TPpToken* ppToken);
- void RewindTokenStream(TokenStream *pTok);
- int ReadToken(TokenStream* pTok, TPpToken* ppToken);
- void pushTokenStreamInput(TokenStream *ts);
- void UngetToken(int token, TPpToken* ppToken);
+ void lAddByte(TokenStream&, unsigned char fVal);
+ int lReadByte(TokenStream&);
+ void lUnreadByte(TokenStream&);
+ void RecordToken(TokenStream&, int token, TPpToken* ppToken);
+ void RewindTokenStream(TokenStream&);
+ int ReadToken(TokenStream&, TPpToken*);
+ void pushTokenStreamInput(TokenStream&, bool pasting = false);
+ void UngetToken(int token, TPpToken*);
class tTokenInput : public tInput {
public:
- tTokenInput(TPpContext* pp, TokenStream* t) : tInput(pp), tokens(t) { }
- virtual int scan(TPpToken *);
- virtual int getch() { assert(0); return EndOfInput; }
- virtual void ungetch() { assert(0); }
+ tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) : tInput(pp), tokens(t), lastTokenPastes(prepasting) { }
+ virtual int scan(TPpToken *) override;
+ virtual int getch() override { assert(0); return EndOfInput; }
+ virtual void ungetch() override { assert(0); }
+ virtual bool peekPasting() override;
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
};
class tUngotTokenInput : public tInput {
public:
tUngotTokenInput(TPpContext* pp, int t, TPpToken* p) : tInput(pp), token(t), lval(*p) { }
- virtual int scan(TPpToken *);
- virtual int getch() { assert(0); return EndOfInput; }
- virtual void ungetch() { assert(0); }
+ virtual int scan(TPpToken *) override;
+ virtual int getch() override { assert(0); return EndOfInput; }
+ virtual void ungetch() override { assert(0); }
protected:
int token;
TPpToken lval;
@@ -359,12 +412,12 @@
class tStringInput : public tInput {
public:
tStringInput(TPpContext* pp, TInputScanner& i) : tInput(pp), input(&i) { }
- virtual int scan(TPpToken*);
+ virtual int scan(TPpToken*) override;
// Scanner used to get source stream characters.
// - Escaped newlines are handled here, invisibly to the caller.
// - All forms of newline are handled, and turned into just a '\n'.
- int getch()
+ int getch() override
{
int ch = input->get();
@@ -402,7 +455,7 @@
// handled here, invisibly to the caller, meaning have to undo exactly
// what getch() above does (e.g., don't leave things in the middle of a
// sequence of escaped newlines).
- void ungetch()
+ void ungetch() override
{
input->unget();
@@ -516,7 +569,6 @@
tStringInput stringInput;
};
- int InitScanner();
int ScanFromString(char* s);
void missingEndifCheck();
int lFloatConst(int len, int ch, TPpToken* ppToken);
@@ -540,31 +592,9 @@
}
bool inComment;
-
- //
- // From PpAtom.cpp
- //
- typedef TUnorderedMap<TString, int> TAtomMap;
- typedef TVector<const TString*> TStringMap;
-
- TAtomMap atomMap;
- TStringMap stringMap;
+ std::string rootFileName;
std::stack<TShader::Includer::IncludeResult*> includeStack;
std::string currentSourceFile;
- std::string rootFileName;
- int nextAtom;
- void InitAtomTable();
- void AddAtomFixed(const char* s, int atom);
- int LookUpAddString(const char* s);
- const char* GetAtomString(int atom);
-
- //
- // From PpMemory.cpp
- //
- MemoryPool *mem_CreatePool(size_t chunksize, unsigned align);
- void mem_FreePool(MemoryPool*);
- void *mem_Alloc(MemoryPool* p, size_t size);
- int mem_AddCleanup(MemoryPool* p, void (*fn)(void *, void*), void* arg1, void* arg2);
};
} // end namespace glslang
diff --git a/glslang/MachineIndependent/preprocessor/PpMemory.cpp b/glslang/MachineIndependent/preprocessor/PpMemory.cpp
index 6158a38..4d0f32a 100644
--- a/glslang/MachineIndependent/preprocessor/PpMemory.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpMemory.cpp
@@ -76,86 +76,6 @@
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
-#include <cstddef>
-#include <cstdlib>
-#include <cstring>
-
-#include "PpContext.h"
-
-// default alignment and chunksize, if called with 0 arguments
-#define CHUNKSIZE (64*1024)
-#define ALIGN 8
-
namespace glslang {
-struct chunk {
- struct chunk *next;
-};
-
-TPpContext::MemoryPool* TPpContext::mem_CreatePool(size_t chunksize, unsigned int align)
-{
- if (align == 0)
- align = ALIGN;
- if (chunksize == 0)
- chunksize = CHUNKSIZE;
- if (align & (align - 1))
- return nullptr;
- if (chunksize < sizeof(MemoryPool))
- return nullptr;
- if (chunksize & (align - 1))
- return nullptr;
-
- MemoryPool *pool = (MemoryPool*)malloc(chunksize);
- if (! pool)
- return nullptr;
-
- pool->next = 0;
- pool->chunksize = chunksize;
- pool->alignmask = (uintptr_t)(align) - 1;
- pool->free = ((uintptr_t)(pool + 1) + pool->alignmask) & ~pool->alignmask;
- pool->end = (uintptr_t)pool + chunksize;
-
- return pool;
-}
-
-void TPpContext::mem_FreePool(MemoryPool *pool)
-{
- struct chunk *p, *next;
-
- for (p = (struct chunk *)pool; p; p = next) {
- next = p->next;
- free(p);
- }
-}
-
-void* TPpContext::mem_Alloc(MemoryPool *pool, size_t size)
-{
- struct chunk *ch;
- void *rv = (void *)pool->free;
- size = (size + pool->alignmask) & ~pool->alignmask;
- if (size <= 0) size = pool->alignmask;
- pool->free += size;
- if (pool->free > pool->end || pool->free < (uintptr_t)rv) {
- size_t minreq = (size + sizeof(struct chunk) + pool->alignmask) & ~pool->alignmask;
- pool->free = (uintptr_t)rv;
- if (minreq >= pool->chunksize) {
- // request size is too big for the chunksize, so allocate it as
- // a single chunk of the right size
- ch = (struct chunk*)malloc(minreq);
- if (! ch)
- return nullptr;
- } else {
- ch = (struct chunk*)malloc(pool->chunksize);
- if (! ch)
- return nullptr;
- pool->free = (uintptr_t)ch + minreq;
- pool->end = (uintptr_t)ch + pool->chunksize;
- }
- ch->next = pool->next;
- pool->next = ch;
- rv = (void *)(((uintptr_t)(ch+1) + pool->alignmask) & ~pool->alignmask);
- }
- return rv;
-}
-
} // end namespace glslang
diff --git a/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/glslang/MachineIndependent/preprocessor/PpScanner.cpp
index 518dbde..4bb7c93 100644
--- a/glslang/MachineIndependent/preprocessor/PpScanner.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpScanner.cpp
@@ -75,9 +75,6 @@
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
-//
-// scanner.c
-//
#define _CRT_SECURE_NO_WARNINGS
@@ -90,17 +87,6 @@
namespace glslang {
-int TPpContext::InitScanner()
-{
- // Add various atoms needed by the CPP line scanner:
- if (!InitCPP())
- return 0;
-
- previous_token = '\n';
-
- return 1;
-}
-
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Floating point constants: /////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -261,7 +247,6 @@
//
int TPpContext::tStringInput::scan(TPpToken* ppToken)
{
- char* tokenText = ppToken->name;
int AlreadyComplained = 0;
int len = 0;
int ch = 0;
@@ -300,7 +285,7 @@
case 'z':
do {
if (len < MaxTokenLength) {
- tokenText[len++] = (char)ch;
+ ppToken->name[len++] = (char)ch;
ch = getch();
} else {
if (! AlreadyComplained) {
@@ -318,9 +303,8 @@
if (len == 0)
continue;
- tokenText[len] = '\0';
+ ppToken->name[len] = '\0';
ungetch();
- ppToken->atom = pp->LookUpAddString(tokenText);
return PpAtomIdentifier;
case '0':
ppToken->name[len++] = (char)ch;
@@ -545,7 +529,7 @@
if (ch == '-') {
return PpAtomDecrement;
} else if (ch == '=') {
- return PpAtomSub;
+ return PPAtomSubAssign;
} else {
ungetch();
return '-';
@@ -555,7 +539,7 @@
if (ch == '+') {
return PpAtomIncrement;
} else if (ch == '=') {
- return PpAtomAdd;
+ return PPAtomAddAssign;
} else {
ungetch();
return '+';
@@ -563,7 +547,7 @@
case '*':
ch = getch();
if (ch == '=') {
- return PpAtomMul;
+ return PPAtomMulAssign;
} else {
ungetch();
return '*';
@@ -571,7 +555,7 @@
case '%':
ch = getch();
if (ch == '=') {
- return PpAtomMod;
+ return PPAtomModAssign;
} else {
ungetch();
return '%';
@@ -697,7 +681,7 @@
// loop again to get the next token...
break;
} else if (ch == '=') {
- return PpAtomDiv;
+ return PPAtomDivAssign;
} else {
ungetch();
return '/';
@@ -707,13 +691,13 @@
ch = getch();
while (ch != '"' && ch != '\n' && ch != EndOfInput) {
if (len < MaxTokenLength) {
- tokenText[len] = (char)ch;
+ ppToken->name[len] = (char)ch;
len++;
ch = getch();
} else
break;
};
- tokenText[len] = '\0';
+ ppToken->name[len] = '\0';
if (ch != '"') {
ungetch();
pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", "");
@@ -729,31 +713,31 @@
// The main functional entry point into the preprocessor, which will
// scan the source strings to figure out and return the next processing token.
//
-// Return string pointer to next token.
-// Return 0 when no more tokens.
+// Return the token, or EndOfInput when no more tokens.
//
-const char* TPpContext::tokenize(TPpToken* ppToken)
+int TPpContext::tokenize(TPpToken& ppToken)
{
- int token = '\n';
-
for(;;) {
- token = scanToken(ppToken);
- ppToken->token = token;
+ int token = scanToken(&ppToken);
+
+ // Handle token-pasting logic
+ token = tokenPaste(token, ppToken);
+
if (token == EndOfInput) {
missingEndifCheck();
- return nullptr;
+ return EndOfInput;
}
if (token == '#') {
if (previous_token == '\n') {
- token = readCPPline(ppToken);
+ token = readCPPline(&ppToken);
if (token == EndOfInput) {
missingEndifCheck();
- return nullptr;
+ return EndOfInput;
}
continue;
} else {
- parseContext.ppError(ppToken->loc, "preprocessor directive cannot be preceded by another token", "#", "");
- return nullptr;
+ parseContext.ppError(ppToken.loc, "preprocessor directive cannot be preceded by another token", "#", "");
+ return EndOfInput;
}
}
previous_token = token;
@@ -762,10 +746,9 @@
continue;
// expand macros
- if (token == PpAtomIdentifier && MacroExpand(ppToken->atom, ppToken, false, true) != 0)
+ if (token == PpAtomIdentifier && MacroExpand(&ppToken, false, true) != 0)
continue;
- const char* tokenString = nullptr;
switch (token) {
case PpAtomIdentifier:
case PpAtomConstInt:
@@ -777,29 +760,110 @@
#ifdef AMD_EXTENSIONS
case PpAtomConstFloat16:
#endif
- tokenString = ppToken->name;
+ if (ppToken.name[0] == '\0')
+ continue;
break;
case PpAtomConstString:
- if (parseContext.intermediate.getSource() == EShSourceHlsl) {
+ if (parseContext.intermediate.getSource() != EShSourceHlsl) {
// HLSL allows string literals.
- tokenString = ppToken->name;
- } else {
- parseContext.ppError(ppToken->loc, "string literals not supported", "\"\"", "");
+ parseContext.ppError(ppToken.loc, "string literals not supported", "\"\"", "");
+ continue;
}
break;
case '\'':
- parseContext.ppError(ppToken->loc, "character literals not supported", "\'", "");
- break;
+ parseContext.ppError(ppToken.loc, "character literals not supported", "\'", "");
+ continue;
default:
- tokenString = GetAtomString(token);
+ strcpy(ppToken.name, atomStrings.getString(token));
break;
}
- if (tokenString)
- return tokenString;
+ return token;
}
}
+//
+// Do all token-pasting related combining of two pasted tokens when getting a
+// stream of tokens from a replacement list. Degenerates to no processing if a
+// replacement list is not the source of the token stream.
+//
+int TPpContext::tokenPaste(int token, TPpToken& ppToken)
+{
+ // starting with ## is illegal, skip to next token
+ if (token == PpAtomPaste) {
+ parseContext.ppError(ppToken.loc, "unexpected location", "##", "");
+ return scanToken(&ppToken);
+ }
+
+ int resultToken = token; // "foo" pasted with "35" is an identifier, not a number
+
+ // ## can be chained, process all in the chain at once
+ while (peekPasting()) {
+ TPpToken pastedPpToken;
+
+ // next token has to be ##
+ token = scanToken(&pastedPpToken);
+ assert(token == PpAtomPaste);
+
+ if (endOfReplacementList()) {
+ parseContext.ppError(ppToken.loc, "unexpected location; end of replacement list", "##", "");
+ break;
+ }
+
+ // get the token after the ##
+ token = scanToken(&pastedPpToken);
+
+ // 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;
+ }
+
+ // 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", "##", "");
+ }
+ }
+
+ return resultToken;
+}
+
// Checks if we've seen balanced #if...#endif
void TPpContext::missingEndifCheck()
{
diff --git a/glslang/MachineIndependent/preprocessor/PpSymbols.cpp b/glslang/MachineIndependent/preprocessor/PpSymbols.cpp
index b7f1df5..585bf2c 100644
--- a/glslang/MachineIndependent/preprocessor/PpSymbols.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpSymbols.cpp
@@ -75,60 +75,3 @@
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
-//
-// symbols.c
-//
-
-#include <cassert>
-#include <cstdlib>
-#include <cstring>
-
-#include "PpContext.h"
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-namespace glslang {
-
-/*
-* Allocate a new symbol node;
-*
-*/
-TPpContext::Symbol* TPpContext::NewSymbol(int atom)
-{
- Symbol* lSymb;
- char* pch;
- size_t ii;
-
- lSymb = (Symbol *) mem_Alloc(pool, sizeof(Symbol));
- lSymb->atom = atom;
-
- // Clear macro
- pch = (char*) &lSymb->mac;
- for (ii = 0; ii < sizeof(lSymb->mac); ii++)
- *pch++ = 0;
-
- return lSymb;
-}
-
-TPpContext::Symbol* TPpContext::AddSymbol(int atom)
-{
- Symbol *lSymb;
-
- lSymb = NewSymbol(atom);
- symbols[lSymb->atom] = lSymb;
-
- return lSymb;
-}
-
-TPpContext::Symbol* TPpContext::LookUpSymbol(int atom)
-{
- TSymbolMap::iterator it = symbols.find(atom);
- if (it == symbols.end())
- return nullptr;
- else
- return it->second;
-}
-
-} // end namespace glslang
diff --git a/glslang/MachineIndependent/preprocessor/PpTokens.cpp b/glslang/MachineIndependent/preprocessor/PpTokens.cpp
index 23b617d..471f26c 100644
--- a/glslang/MachineIndependent/preprocessor/PpTokens.cpp
+++ b/glslang/MachineIndependent/preprocessor/PpTokens.cpp
@@ -95,32 +95,32 @@
namespace glslang {
-void TPpContext::lAddByte(TokenStream *fTok, unsigned char fVal)
+void TPpContext::lAddByte(TokenStream& fTok, unsigned char fVal)
{
- fTok->data.push_back(fVal);
+ fTok.data.push_back(fVal);
}
/*
* Get the next byte from a stream.
*/
-int TPpContext::lReadByte(TokenStream *pTok)
+int TPpContext::lReadByte(TokenStream& pTok)
{
- if (pTok->current < pTok->data.size())
- return pTok->data[pTok->current++];
+ if (pTok.current < pTok.data.size())
+ return pTok.data[pTok.current++];
else
return EndOfInput;
}
-void TPpContext::lUnreadByte(TokenStream *pTok)
+void TPpContext::lUnreadByte(TokenStream& pTok)
{
- if (pTok->current > 0)
- --pTok->current;
+ if (pTok.current > 0)
+ --pTok.current;
}
/*
* Add a token to the end of a list for later playback.
*/
-void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken* ppToken)
+void TPpContext::RecordToken(TokenStream& pTok, int token, TPpToken* ppToken)
{
const char* s;
char* str = NULL;
@@ -160,19 +160,18 @@
}
/*
-* Reset a token stream in preperation for reading.
+* Reset a token stream in preparation for reading.
*/
-void TPpContext::RewindTokenStream(TokenStream *pTok)
+void TPpContext::RewindTokenStream(TokenStream& pTok)
{
- pTok->current = 0;
+ pTok.current = 0;
}
/*
* Read the next token from a token stream (not the source stream, but stream used to hold a tokenized macro).
*/
-int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
+int TPpContext::ReadToken(TokenStream& pTok, TPpToken *ppToken)
{
- char* tokenText = ppToken->name;
int ltoken, len;
int ch;
@@ -183,13 +182,11 @@
switch (ltoken) {
case '#':
// Check for ##, unless the current # is the last character
- if (pTok->current < pTok->data.size()) {
+ if (pTok.current < pTok.data.size()) {
if (lReadByte(pTok) == '#') {
parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
- parseContext.error(ppToken->loc, "token pasting not implemented (internal error)", "##", "");
- //return PpAtomPaste;
- return ReadToken(pTok, ppToken);
+ ltoken = PpAtomPaste;
} else
lUnreadByte(pTok);
}
@@ -209,7 +206,7 @@
ch = lReadByte(pTok);
while (ch != 0 && ch != EndOfInput) {
if (len < MaxTokenLength) {
- tokenText[len] = (char)ch;
+ ppToken->name[len] = (char)ch;
len++;
ch = lReadByte(pTok);
} else {
@@ -217,11 +214,10 @@
break;
}
}
- tokenText[len] = 0;
+ ppToken->name[len] = 0;
switch (ltoken) {
case PpAtomIdentifier:
- ppToken->atom = LookUpAddString(tokenText);
break;
case PpAtomConstString:
break;
@@ -233,8 +229,8 @@
ppToken->dval = atof(ppToken->name);
break;
case PpAtomConstInt:
- if (len > 0 && tokenText[0] == '0') {
- if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
+ if (len > 0 && ppToken->name[0] == '0') {
+ if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->ival = (int)strtol(ppToken->name, 0, 16);
else
ppToken->ival = (int)strtol(ppToken->name, 0, 8);
@@ -242,8 +238,8 @@
ppToken->ival = atoi(ppToken->name);
break;
case PpAtomConstUint:
- if (len > 0 && tokenText[0] == '0') {
- if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
+ if (len > 0 && ppToken->name[0] == '0') {
+ if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->ival = (int)strtoul(ppToken->name, 0, 16);
else
ppToken->ival = (int)strtoul(ppToken->name, 0, 8);
@@ -251,8 +247,8 @@
ppToken->ival = (int)strtoul(ppToken->name, 0, 10);
break;
case PpAtomConstInt64:
- if (len > 0 && tokenText[0] == '0') {
- if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
+ if (len > 0 && ppToken->name[0] == '0') {
+ if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->i64val = strtoll(ppToken->name, nullptr, 16);
else
ppToken->i64val = strtoll(ppToken->name, nullptr, 8);
@@ -260,8 +256,8 @@
ppToken->i64val = atoll(ppToken->name);
break;
case PpAtomConstUint64:
- if (len > 0 && tokenText[0] == '0') {
- if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
+ if (len > 0 && ppToken->name[0] == '0') {
+ if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 16);
else
ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 8);
@@ -276,12 +272,37 @@
int TPpContext::tTokenInput::scan(TPpToken* ppToken)
{
- return pp->ReadToken(tokens, ppToken);
+ return pp->ReadToken(*tokens, ppToken);
}
-void TPpContext::pushTokenStreamInput(TokenStream* ts)
+// We are pasting if the entire macro is preceding a pasting operator
+// (lastTokenPastes) and we are also on the last token.
+bool TPpContext::tTokenInput::peekPasting()
{
- pushInput(new tTokenInput(this, ts));
+ if (! lastTokenPastes)
+ return false;
+ // Getting here means the last token will be pasted.
+
+ // Are we at the last non-whitespace token?
+ size_t savePos = tokens->current;
+ bool moreTokens = false;
+ do {
+ int byte = pp->lReadByte(*tokens);
+ if (byte == EndOfInput)
+ break;
+ if (byte != ' ') {
+ moreTokens = true;
+ break;
+ }
+ } while (true);
+ tokens->current = savePos;
+
+ return !moreTokens;
+}
+
+void TPpContext::pushTokenStreamInput(TokenStream& ts, bool prepasting)
+{
+ pushInput(new tTokenInput(this, &ts, prepasting));
RewindTokenStream(ts);
}
diff --git a/glslang/MachineIndependent/preprocessor/PpTokens.h b/glslang/MachineIndependent/preprocessor/PpTokens.h
index c84431d..20aeb10 100644
--- a/glslang/MachineIndependent/preprocessor/PpTokens.h
+++ b/glslang/MachineIndependent/preprocessor/PpTokens.h
@@ -86,11 +86,11 @@
// Operators
- PpAtomAdd,
- PpAtomSub,
- PpAtomMul,
- PpAtomDiv,
- PpAtomMod,
+ PPAtomAddAssign,
+ PPAtomSubAssign,
+ PPAtomMulAssign,
+ PPAtomDivAssign,
+ PPAtomModAssign,
PpAtomRight,
PpAtomLeft,
@@ -134,7 +134,6 @@
// preprocessor "keywords"
PpAtomDefine,
- PpAtomDefined,
PpAtomUndef,
PpAtomIf,
diff --git a/gtests/AST.FromFile.cpp b/gtests/AST.FromFile.cpp
index a2e961e..7070533 100644
--- a/gtests/AST.FromFile.cpp
+++ b/gtests/AST.FromFile.cpp
@@ -178,6 +178,7 @@
"syntaxError.frag",
"test.frag",
"texture.frag",
+ "tokenPaste.vert",
"types.frag",
"uniformArray.frag",
"variableArrayIndex.frag",
diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp
index 414fa7b..c946ef7 100644
--- a/gtests/Spv.FromFile.cpp
+++ b/gtests/Spv.FromFile.cpp
@@ -216,6 +216,7 @@
"spv.forwardFun.frag",
"spv.functionCall.frag",
"spv.functionSemantics.frag",
+ "spv.GeometryShaderPassthrough.geom",
"spv.interpOps.frag",
"spv.int64.frag",
"spv.layoutNested.vert",
@@ -240,6 +241,7 @@
"spv.precision.frag",
"spv.prepost.frag",
"spv.qualifiers.vert",
+ "spv.sampleMaskOverrideCoverage.frag",
"spv.shaderBallot.comp",
"spv.shaderDrawParams.vert",
"spv.shaderGroupVote.comp",
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index e676e95..b874aa8 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -90,10 +90,11 @@
// as "linear" or "centroid" NOT valid identifiers. This code special cases "sample",
// so e.g, "int sample;" is accepted.
if (peekTokenClass(EHTokSample)) {
- idToken.string = NewPoolTString("sample");
- idToken.tokenClass = EHTokIdentifier;
- idToken.symbol = nullptr;
- idToken.loc = token.loc;
+ token.string = NewPoolTString("sample");
+ token.tokenClass = EHTokIdentifier;
+ token.symbol = nullptr;
+
+ idToken = token;
advanceToken();
return true;
}
@@ -475,8 +476,15 @@
TSourceLoc loc = token.loc;
// type_specifier
- if (! acceptType(type))
+ if (! acceptType(type)) {
+ // If this is not a type, we may have inadvertently gone down a wrong path
+ // py parsing "sample", which can be treated like either an identifier or a
+ // qualifier. Back it out, if we did.
+ if (qualifier.sample)
+ recedeToken();
+
return false;
+ }
if (type.getBasicType() == EbtBlock) {
// the type was a block, which set some parts of the qualifier
parseContext.mergeQualifiers(type.getQualifier(), qualifier);
@@ -2203,7 +2211,7 @@
} else if (acceptIdentifier(idToken)) {
// identifier or function_call name
if (! peekTokenClass(EHTokLeftParen)) {
- node = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
+ node = parseContext.handleVariable(idToken.loc, idToken.symbol, idToken.string);
} else if (acceptFunctionCall(idToken, node)) {
// function_call (nothing else to do yet)
} else {
diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp
index 54cd10f..62dac4b 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -579,8 +579,10 @@
}
// Recovery, if it wasn't found or was not a variable.
- if (! variable)
+ if (! variable) {
+ error(loc, "unknown variable", string->c_str(), "");
variable = new TVariable(string, TType(EbtVoid));
+ }
if (variable->getType().getQualifier().isFrontEndConstant())
node = intermediate.addConstantUnion(variable->getConstArray(), variable->getType(), loc);
@@ -957,13 +959,13 @@
if (flattenData.nextBinding != TQualifier::layoutBindingEnd)
memberVariable->getWritableType().getQualifier().layoutBinding = flattenData.nextBinding++;
- flattenData.offsets.push_back(flattenData.members.size());
+ flattenData.offsets.push_back(static_cast<int>(flattenData.members.size()));
flattenData.members.push_back(memberVariable);
if (track)
trackLinkageDeferred(*memberVariable);
- return flattenData.offsets.size()-1; // location of the member reference
+ return static_cast<int>(flattenData.offsets.size())-1; // location of the member reference
} else {
// Further recursion required
return flatten(loc, variable, type, flattenData, memberName);
@@ -985,7 +987,7 @@
auto members = *type.getStruct();
// Reserve space for this tree level.
- int start = flattenData.offsets.size();
+ int start = static_cast<int>(flattenData.offsets.size());
int pos = start;
flattenData.offsets.resize(int(pos + members.size()), -1);
@@ -1022,7 +1024,7 @@
name = variable.getName();
// Reserve space for this tree level.
- int start = flattenData.offsets.size();
+ int start = static_cast<int>(flattenData.offsets.size());
int pos = start;
flattenData.offsets.resize(int(pos + size), -1);
@@ -2781,7 +2783,7 @@
//
// Add any needed implicit conversions for function-call arguments to input parameters.
//
-void HlslParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const
+void HlslParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments)
{
TIntermAggregate* aggregate = arguments->getAsAggregate();
const auto setArg = [&](int argNum, TIntermNode* arg) {
@@ -2809,9 +2811,13 @@
if (*function[i].type != arg->getType()) {
// In-qualified arguments just need an extra node added above the argument to
// convert to the correct type.
- arg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg);
- arg = intermediate.addShapeConversion(EOpFunctionCall, *function[i].type, arg);
- setArg(i, arg);
+ TIntermTyped* convArg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg);
+ if (convArg != nullptr)
+ convArg = intermediate.addShapeConversion(EOpFunctionCall, *function[i].type, convArg);
+ if (convArg != nullptr)
+ setArg(i, convArg);
+ else
+ error(arg->getLoc(), "cannot convert input argument, argument", "", "%d", i);
} else {
if (wasFlattened(arg)) {
// Will make a two-level subtree.
@@ -4977,7 +4983,7 @@
return addConstructor(loc, initList, arrayType);
} else if (type.isStruct()) {
// lengthen list to be long enough
- lengthenList(loc, initList->getSequence(), type.getStruct()->size());
+ lengthenList(loc, initList->getSequence(), static_cast<int>(type.getStruct()->size()));
if (type.getStruct()->size() != initList->getSequence().size()) {
error(loc, "wrong number of structure members", "initializer list", "");
diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h
index 206df9b..d017a2a 100755
--- a/hlsl/hlslParseHelper.h
+++ b/hlsl/hlslParseHelper.h
@@ -50,18 +50,18 @@
const TString sourceEntryPointName,
bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
virtual ~HlslParseContext();
- void initializeExtensionBehavior();
+ void initializeExtensionBehavior() override;
- void setLimits(const TBuiltInResource&);
- bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false);
- virtual const char* getGlobalUniformBlockName() { return "$Global"; }
+ void setLimits(const TBuiltInResource&) override;
+ bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
+ virtual const char* getGlobalUniformBlockName() override { return "$Global"; }
- void reservedPpErrorCheck(const TSourceLoc&, const char* /*name*/, const char* /*op*/) { }
- bool lineContinuationCheck(const TSourceLoc&, bool /*endOfComment*/) { return true; }
- bool lineDirectiveShouldSetNextLine() const { return true; }
+ void reservedPpErrorCheck(const TSourceLoc&, const char* /*name*/, const char* /*op*/) override { }
+ bool lineContinuationCheck(const TSourceLoc&, bool /*endOfComment*/) override { return true; }
+ bool lineDirectiveShouldSetNextLine() const override { return true; }
bool builtInName(const TString&);
- void handlePragma(const TSourceLoc&, const TVector<TString>&);
+ void handlePragma(const TSourceLoc&, const TVector<TString>&) override;
TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
TIntermTyped* handleBracketOperator(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
@@ -84,7 +84,7 @@
void decomposeSampleMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void decomposeGeometryMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
- void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
+ void addInputArgumentConversions(const TFunction&, TIntermNode*&);
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&);
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
TFunction* handleConstructorCall(const TSourceLoc&, const TType&);
@@ -134,7 +134,7 @@
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
void declareBlock(const TSourceLoc&, TType&, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
- void finalizeGlobalUniformBlockLayout(TVariable& block);
+ void finalizeGlobalUniformBlockLayout(TVariable& block) override;
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
void fixBlockXfbOffsets(TQualifier&, TTypeList&);
void fixBlockUniformOffsets(const TQualifier&, TTypeList&);
diff --git a/hlsl/hlslScanContext.cpp b/hlsl/hlslScanContext.cpp
index 4e355ba..3ae19fc 100755
--- a/hlsl/hlslScanContext.cpp
+++ b/hlsl/hlslScanContext.cpp
@@ -394,13 +394,14 @@
do {
parserToken = &token;
TPpToken ppToken;
- tokenText = ppContext.tokenize(&ppToken);
- if (tokenText == nullptr)
+ int token = ppContext.tokenize(ppToken);
+ if (token == EndOfInput)
return EHTokNone;
+ tokenText = ppToken.name;
loc = ppToken.loc;
parserToken->loc = loc;
- switch (ppToken.token) {
+ switch (token) {
case ';': return EHTokSemicolon;
case ',': return EHTokComma;
case ':': return EHTokColon;
@@ -429,11 +430,11 @@
parseContext.error(loc, "illegal use of escape character", "\\", "");
break;
- case PpAtomAdd: return EHTokAddAssign;
- case PpAtomSub: return EHTokSubAssign;
- case PpAtomMul: return EHTokMulAssign;
- case PpAtomDiv: return EHTokDivAssign;
- case PpAtomMod: return EHTokModAssign;
+ case PPAtomAddAssign: return EHTokAddAssign;
+ case PPAtomSubAssign: return EHTokSubAssign;
+ case PPAtomMulAssign: return EHTokMulAssign;
+ case PPAtomDivAssign: return EHTokDivAssign;
+ case PPAtomModAssign: return EHTokModAssign;
case PpAtomRight: return EHTokRightOp;
case PpAtomLeft: return EHTokLeftOp;
@@ -467,7 +468,7 @@
}
case PpAtomConstString: {
- parserToken->string = NewPoolTString(ppToken.name);
+ parserToken->string = NewPoolTString(tokenText);
return EHTokStringConstant;
}
@@ -475,7 +476,7 @@
default:
char buf[2];
- buf[0] = (char)ppToken.token;
+ buf[0] = (char)token;
buf[1] = 0;
parseContext.error(loc, "unexpected token", buf, "");
break;