diff --git a/Test/baseResults/hlsl.pp.expand.frag.err b/Test/baseResults/hlsl.pp.expand.frag.err new file mode 100644 index 00000000..1b5681fe --- /dev/null +++ b/Test/baseResults/hlsl.pp.expand.frag.err @@ -0,0 +1,3 @@ +ERROR: HLSL currently only supported when requesting SPIR-V for Vulkan. +ERROR: HLSL currently only supported when requesting SPIR-V for Vulkan. + diff --git a/Test/baseResults/hlsl.pp.expand.frag.out b/Test/baseResults/hlsl.pp.expand.frag.out new file mode 100644 index 00000000..71978916 --- /dev/null +++ b/Test/baseResults/hlsl.pp.expand.frag.out @@ -0,0 +1,18 @@ + + + + + + +struct A +{ + float4 a; + float4 b; + float4 c = { 1, 2, 3, 4 }; + float4 d = {({ {(({ 1, 2, 3, 4 }))} })}, { { 1, 2, 3, 4 } }; +}; + +void main() +{ +} + diff --git a/Test/hlsl.pp.expand.frag b/Test/hlsl.pp.expand.frag new file mode 100755 index 00000000..765d17e4 --- /dev/null +++ b/Test/hlsl.pp.expand.frag @@ -0,0 +1,17 @@ +#define EMP1(a) +#define EMP2(a, b) + +#define EXP1(a) = a +#define EXP2(a, b) = a, b + +struct A +{ + float4 a EMP1({1,2,3,4}); // No PP arg errors + float4 b EMP2({({{(({1,2,3,4}))}})}, {{1,2,3,4}}); // No PP arg errors + float4 c EXP1({1,2,3,4}); // ERROR: No PP arg errors, but init error + float4 d EXP2({({{(({1,2,3,4}))}})}, {{1,2,3,4}}); // ERROR: No PP arg errors, but init error +}; + +void main() +{ +} diff --git a/Test/runtests b/Test/runtests index a084cb5c..390acfc3 100755 --- a/Test/runtests +++ b/Test/runtests @@ -215,6 +215,13 @@ $EXE -H -e main -D -Od -fhlsl_functionality1 hlsl.noSemantic.functionality1.comp $TARGETDIR/hlsl.noSemantic.functionality1.comp.out diff -b $BASEDIR/hlsl.noSemantic.functionality1.comp.out $TARGETDIR/hlsl.noSemantic.functionality1.comp.out || HASERROR=1 +# +# Testing HLSL-specific PP feature expansion +# +$EXE -D -E hlsl.pp.expand.frag > $TARGETDIR/hlsl.pp.expand.frag.out 2> $TARGETDIR/hlsl.pp.expand.frag.err +diff -b $BASEDIR/hlsl.pp.expand.frag.out $TARGETDIR/hlsl.pp.expand.frag.out || HASERROR=1 +diff -b $BASEDIR/hlsl.pp.expand.frag.err $TARGETDIR/hlsl.pp.expand.frag.err || HASERROR=1 + # # Final checking # diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp old mode 100644 new mode 100755 index 8048fa51..0a151edc --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -1153,7 +1153,6 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka } MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom); - int depth = 0; // no recursive expansions if (macro != nullptr && macro->busy) @@ -1193,8 +1192,8 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka size_t arg = 0; bool tokenRecorded = false; do { - depth = 0; - while (1) { + TVector nestStack; + while (true) { token = scanToken(ppToken); if (token == EndOfInput || token == tMarkerInput::marker) { parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom)); @@ -1216,16 +1215,21 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka } if (in->mac->args.size() == 0 && token != ')') break; - if (depth == 0 && (token == ',' || token == ')')) + if (nestStack.size() == 0 && (token == ',' || token == ')')) break; if (token == '(') - depth++; - if (token == ')') - depth--; + nestStack.push_back(')'); + else if (token == '{' && parseContext.isReadingHLSL()) + nestStack.push_back('}'); + else if (nestStack.size() > 0 && token == nestStack.back()) + nestStack.pop_back(); in->args[arg]->putToken(token, ppToken); tokenRecorded = true; } + // end of single argument scan + if (token == ')') { + // closing paren of call if (in->mac->args.size() == 1 && tokenRecorded == 0) break; arg++; @@ -1233,16 +1237,18 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka } arg++; } while (arg < in->mac->args.size()); + // end of all arguments scan if (arg < in->mac->args.size()) parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom)); else if (token != ')') { - depth=0; + // Error recover code; find end of call, if possible + int depth = 0; while (token != EndOfInput && (depth > 0 || token != ')')) { - if (token == ')') + if (token == ')' || token == '}') depth--; token = scanToken(ppToken); - if (token == '(') + if (token == '(' || token == '{') depth++; }