PP/HLSL: Fix #1424: support comma in nested curly braces for macro arg

This commit is contained in:
John Kessenich 2018-07-02 10:40:32 -06:00
parent 0b964b3c35
commit 9cc81de096
5 changed files with 61 additions and 10 deletions

View File

@ -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.

View File

@ -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()
{
}

17
Test/hlsl.pp.expand.frag Executable file
View File

@ -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()
{
}

View File

@ -215,6 +215,13 @@ $EXE -H -e main -D -Od -fhlsl_functionality1 hlsl.noSemantic.functionality1.comp
$TARGETDIR/hlsl.noSemantic.functionality1.comp.out $TARGETDIR/hlsl.noSemantic.functionality1.comp.out
diff -b $BASEDIR/hlsl.noSemantic.functionality1.comp.out $TARGETDIR/hlsl.noSemantic.functionality1.comp.out || HASERROR=1 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 # Final checking
# #

26
glslang/MachineIndependent/preprocessor/Pp.cpp Normal file → Executable file
View File

@ -1153,7 +1153,6 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka
} }
MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom); MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom);
int depth = 0;
// no recursive expansions // no recursive expansions
if (macro != nullptr && macro->busy) if (macro != nullptr && macro->busy)
@ -1193,8 +1192,8 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka
size_t arg = 0; size_t arg = 0;
bool tokenRecorded = false; bool tokenRecorded = false;
do { do {
depth = 0; TVector<char> nestStack;
while (1) { while (true) {
token = scanToken(ppToken); token = scanToken(ppToken);
if (token == EndOfInput || token == tMarkerInput::marker) { if (token == EndOfInput || token == tMarkerInput::marker) {
parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom)); 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 != ')') if (in->mac->args.size() == 0 && token != ')')
break; break;
if (depth == 0 && (token == ',' || token == ')')) if (nestStack.size() == 0 && (token == ',' || token == ')'))
break; break;
if (token == '(') if (token == '(')
depth++; nestStack.push_back(')');
if (token == ')') else if (token == '{' && parseContext.isReadingHLSL())
depth--; nestStack.push_back('}');
else if (nestStack.size() > 0 && token == nestStack.back())
nestStack.pop_back();
in->args[arg]->putToken(token, ppToken); in->args[arg]->putToken(token, ppToken);
tokenRecorded = true; tokenRecorded = true;
} }
// end of single argument scan
if (token == ')') { if (token == ')') {
// closing paren of call
if (in->mac->args.size() == 1 && tokenRecorded == 0) if (in->mac->args.size() == 1 && tokenRecorded == 0)
break; break;
arg++; arg++;
@ -1233,16 +1237,18 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka
} }
arg++; arg++;
} while (arg < in->mac->args.size()); } while (arg < in->mac->args.size());
// end of all arguments scan
if (arg < in->mac->args.size()) if (arg < in->mac->args.size())
parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom)); parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom));
else if (token != ')') { else if (token != ')') {
depth=0; // Error recover code; find end of call, if possible
int depth = 0;
while (token != EndOfInput && (depth > 0 || token != ')')) { while (token != EndOfInput && (depth > 0 || token != ')')) {
if (token == ')') if (token == ')' || token == '}')
depth--; depth--;
token = scanToken(ppToken); token = scanToken(ppToken);
if (token == '(') if (token == '(' || token == '{')
depth++; depth++;
} }