aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Kessenich <cepheus@frii.com>2016-11-27 17:39:07 -0700
committerJohn Kessenich <cepheus@frii.com>2016-11-27 17:39:07 -0700
commit98ad48532157bbaa1cffc0625cbf0b514aa3ad74 (patch)
tree56ecf66d51a9752d317d9fa6dc57f916f3963788
parent1c98904014a258e446b5dc0edd26607a7085c17b (diff)
downloadglslang-98ad48532157bbaa1cffc0625cbf0b514aa3ad74.tar.gz
HLSL: Support {...} initializer lists that are too short.
-rwxr-xr-xTest/baseResults/hlsl.partialInit.frag.out310
-rwxr-xr-xTest/hlsl.partialInit.frag22
-rw-r--r--glslang/Include/revision.h2
-rw-r--r--glslang/MachineIndependent/Intermediate.cpp12
-rw-r--r--glslang/MachineIndependent/localintermediate.h1
-rw-r--r--gtests/Hlsl.FromFile.cpp1
-rwxr-xr-xhlsl/hlslGrammar.cpp12
-rwxr-xr-xhlsl/hlslParseHelper.cpp45
-rwxr-xr-xhlsl/hlslParseHelper.h1
9 files changed, 397 insertions, 9 deletions
diff --git a/Test/baseResults/hlsl.partialInit.frag.out b/Test/baseResults/hlsl.partialInit.frag.out
new file mode 100755
index 00000000..bac92378
--- /dev/null
+++ b/Test/baseResults/hlsl.partialInit.frag.out
@@ -0,0 +1,310 @@
+hlsl.partialInit.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:8 Sequence
+0:8 move second child to first child (temp 4-component vector of float)
+0:8 'gv' (global 4-component vector of float)
+0:8 Constant:
+0:8 0.000000
+0:8 0.000000
+0:8 1.000000
+0:8 0.000000
+0:9 Sequence
+0:9 move second child to first child (temp 3-element array of float)
+0:9 'gfa' (global 3-element array of float)
+0:9 Constant:
+0:9 0.000000
+0:9 0.000000
+0:9 0.000000
+0:12 Function Definition: PixelShaderFunction(vf4; (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:12 Function Parameters:
+0:12 'input' (layout(location=0 ) in 4-component vector of float)
+0:? Sequence
+0:13 Sequence
+0:13 move second child to first child (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:13 'o2' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:13 Constant:
+0:13 3 (const int)
+0:13 0.000000
+0:13 false (const bool)
+0:13 0.000000
+0:13 0.000000
+0:13 0.000000
+0:13 0.000000
+0:15 move second child to first child (temp 4-component vector of float)
+0:15 v: direct index for structure (temp 4-component vector of float)
+0:15 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:15 Constant:
+0:15 3 (const int)
+0:15 vector-scale (temp 4-component vector of float)
+0:15 'gv' (global 4-component vector of float)
+0:15 direct index (temp float)
+0:15 'gfa' (global 3-element array of float)
+0:15 Constant:
+0:15 2 (const int)
+0:16 Sequence
+0:16 move second child to first child (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:16 'o1' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:16 Constant:
+0:16 0 (const int)
+0:16 0.000000
+0:16 false (const bool)
+0:16 0.000000
+0:16 0.000000
+0:16 0.000000
+0:16 0.000000
+0:19 move second child to first child (temp bool)
+0:19 c: direct index for structure (temp bool)
+0:19 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:19 Constant:
+0:19 2 (const int)
+0:19 c: direct index for structure (temp bool)
+0:19 'o1' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:19 Constant:
+0:19 2 (const int)
+0:21 Sequence
+0:21 Sequence
+0:21 move second child to first child (temp int)
+0:? 'a' (layout(location=0 ) out int)
+0:21 a: direct index for structure (temp int)
+0:21 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:21 Constant:
+0:21 0 (const int)
+0:21 move second child to first child (temp float)
+0:? 'b' (layout(location=1 ) out float)
+0:21 b: direct index for structure (temp float)
+0:21 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:21 Constant:
+0:21 1 (const int)
+0:21 move second child to first child (temp bool)
+0:? 'c' (layout(location=2 ) out bool)
+0:21 c: direct index for structure (temp bool)
+0:21 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:21 Constant:
+0:21 2 (const int)
+0:21 move second child to first child (temp 4-component vector of float)
+0:? 'v' (layout(location=3 ) out 4-component vector of float)
+0:21 v: direct index for structure (temp 4-component vector of float)
+0:21 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:21 Constant:
+0:21 3 (const int)
+0:21 Branch: Return
+0:? Linker Objects
+0:? 'a' (layout(location=0 ) out int)
+0:? 'b' (layout(location=1 ) out float)
+0:? 'c' (layout(location=2 ) out bool)
+0:? 'v' (layout(location=3 ) out 4-component vector of float)
+0:? 'input' (layout(location=0 ) in 4-component vector of float)
+0:? 'gv' (global 4-component vector of float)
+0:? 'gfa' (global 3-element array of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:8 Sequence
+0:8 move second child to first child (temp 4-component vector of float)
+0:8 'gv' (global 4-component vector of float)
+0:8 Constant:
+0:8 0.000000
+0:8 0.000000
+0:8 1.000000
+0:8 0.000000
+0:9 Sequence
+0:9 move second child to first child (temp 3-element array of float)
+0:9 'gfa' (global 3-element array of float)
+0:9 Constant:
+0:9 0.000000
+0:9 0.000000
+0:9 0.000000
+0:12 Function Definition: PixelShaderFunction(vf4; (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:12 Function Parameters:
+0:12 'input' (layout(location=0 ) in 4-component vector of float)
+0:? Sequence
+0:13 Sequence
+0:13 move second child to first child (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:13 'o2' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:13 Constant:
+0:13 3 (const int)
+0:13 0.000000
+0:13 false (const bool)
+0:13 0.000000
+0:13 0.000000
+0:13 0.000000
+0:13 0.000000
+0:15 move second child to first child (temp 4-component vector of float)
+0:15 v: direct index for structure (temp 4-component vector of float)
+0:15 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:15 Constant:
+0:15 3 (const int)
+0:15 vector-scale (temp 4-component vector of float)
+0:15 'gv' (global 4-component vector of float)
+0:15 direct index (temp float)
+0:15 'gfa' (global 3-element array of float)
+0:15 Constant:
+0:15 2 (const int)
+0:16 Sequence
+0:16 move second child to first child (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:16 'o1' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:16 Constant:
+0:16 0 (const int)
+0:16 0.000000
+0:16 false (const bool)
+0:16 0.000000
+0:16 0.000000
+0:16 0.000000
+0:16 0.000000
+0:19 move second child to first child (temp bool)
+0:19 c: direct index for structure (temp bool)
+0:19 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:19 Constant:
+0:19 2 (const int)
+0:19 c: direct index for structure (temp bool)
+0:19 'o1' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:19 Constant:
+0:19 2 (const int)
+0:21 Sequence
+0:21 Sequence
+0:21 move second child to first child (temp int)
+0:? 'a' (layout(location=0 ) out int)
+0:21 a: direct index for structure (temp int)
+0:21 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:21 Constant:
+0:21 0 (const int)
+0:21 move second child to first child (temp float)
+0:? 'b' (layout(location=1 ) out float)
+0:21 b: direct index for structure (temp float)
+0:21 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:21 Constant:
+0:21 1 (const int)
+0:21 move second child to first child (temp bool)
+0:? 'c' (layout(location=2 ) out bool)
+0:21 c: direct index for structure (temp bool)
+0:21 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:21 Constant:
+0:21 2 (const int)
+0:21 move second child to first child (temp 4-component vector of float)
+0:? 'v' (layout(location=3 ) out 4-component vector of float)
+0:21 v: direct index for structure (temp 4-component vector of float)
+0:21 'o4' (temp structure{temp int a, temp float b, temp bool c, temp 4-component vector of float v})
+0:21 Constant:
+0:21 3 (const int)
+0:21 Branch: Return
+0:? Linker Objects
+0:? 'a' (layout(location=0 ) out int)
+0:? 'b' (layout(location=1 ) out float)
+0:? 'c' (layout(location=2 ) out bool)
+0:? 'v' (layout(location=3 ) out 4-component vector of float)
+0:? 'input' (layout(location=0 ) in 4-component vector of float)
+0:? 'gv' (global 4-component vector of float)
+0:? 'gfa' (global 3-element array of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 66
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "PixelShaderFunction" 45 50 56 60 65
+ ExecutionMode 4 OriginUpperLeft
+ Name 4 "PixelShaderFunction"
+ Name 9 "gv"
+ Name 17 "gfa"
+ Name 21 "outs"
+ MemberName 21(outs) 0 "a"
+ MemberName 21(outs) 1 "b"
+ MemberName 21(outs) 2 "c"
+ MemberName 21(outs) 3 "v"
+ Name 23 "o2"
+ Name 28 "o4"
+ Name 37 "o1"
+ Name 45 "a"
+ Name 50 "b"
+ Name 56 "c"
+ Name 60 "v"
+ Name 65 "input"
+ Decorate 45(a) Location 0
+ Decorate 50(b) Location 1
+ Decorate 56(c) Location 2
+ Decorate 60(v) Location 3
+ Decorate 65(input) Location 0
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeFloat 32
+ 7: TypeVector 6(float) 4
+ 8: TypePointer Private 7(fvec4)
+ 9(gv): 8(ptr) Variable Private
+ 10: 6(float) Constant 0
+ 11: 6(float) Constant 1065353216
+ 12: 7(fvec4) ConstantComposite 10 10 11 10
+ 13: TypeInt 32 0
+ 14: 13(int) Constant 3
+ 15: TypeArray 6(float) 14
+ 16: TypePointer Private 15
+ 17(gfa): 16(ptr) Variable Private
+ 18: 15 ConstantComposite 10 10 10
+ 19: TypeInt 32 1
+ 20: TypeBool
+ 21(outs): TypeStruct 19(int) 6(float) 20(bool) 7(fvec4)
+ 22: TypePointer Function 21(outs)
+ 24: 19(int) Constant 3
+ 25: 20(bool) ConstantFalse
+ 26: 7(fvec4) ConstantComposite 10 10 10 10
+ 27: 21(outs) ConstantComposite 24 10 25 26
+ 30: 19(int) Constant 2
+ 31: TypePointer Private 6(float)
+ 35: TypePointer Function 7(fvec4)
+ 38: 19(int) Constant 0
+ 39: 21(outs) ConstantComposite 38 10 25 26
+ 40: TypePointer Function 20(bool)
+ 44: TypePointer Output 19(int)
+ 45(a): 44(ptr) Variable Output
+ 46: TypePointer Function 19(int)
+ 49: TypePointer Output 6(float)
+ 50(b): 49(ptr) Variable Output
+ 51: 19(int) Constant 1
+ 52: TypePointer Function 6(float)
+ 55: TypePointer Output 20(bool)
+ 56(c): 55(ptr) Variable Output
+ 59: TypePointer Output 7(fvec4)
+ 60(v): 59(ptr) Variable Output
+ 64: TypePointer Input 7(fvec4)
+ 65(input): 64(ptr) Variable Input
+4(PixelShaderFunction): 2 Function None 3
+ 5: Label
+ 23(o2): 22(ptr) Variable Function
+ 28(o4): 22(ptr) Variable Function
+ 37(o1): 22(ptr) Variable Function
+ Store 9(gv) 12
+ Store 17(gfa) 18
+ Store 23(o2) 27
+ 29: 7(fvec4) Load 9(gv)
+ 32: 31(ptr) AccessChain 17(gfa) 30
+ 33: 6(float) Load 32
+ 34: 7(fvec4) VectorTimesScalar 29 33
+ 36: 35(ptr) AccessChain 28(o4) 24
+ Store 36 34
+ Store 37(o1) 39
+ 41: 40(ptr) AccessChain 37(o1) 30
+ 42: 20(bool) Load 41
+ 43: 40(ptr) AccessChain 28(o4) 30
+ Store 43 42
+ 47: 46(ptr) AccessChain 28(o4) 38
+ 48: 19(int) Load 47
+ Store 45(a) 48
+ 53: 52(ptr) AccessChain 28(o4) 51
+ 54: 6(float) Load 53
+ Store 50(b) 54
+ 57: 40(ptr) AccessChain 28(o4) 30
+ 58: 20(bool) Load 57
+ Store 56(c) 58
+ 61: 35(ptr) AccessChain 28(o4) 24
+ 62: 7(fvec4) Load 61
+ Store 60(v) 62
+ Return
+ FunctionEnd
diff --git a/Test/hlsl.partialInit.frag b/Test/hlsl.partialInit.frag
new file mode 100755
index 00000000..b5b0a580
--- /dev/null
+++ b/Test/hlsl.partialInit.frag
@@ -0,0 +1,22 @@
+struct outs {
+ int a;
+ float b;
+ bool c;
+ float4 v;
+};
+
+static float4 gv = {0,0,1};
+static float gfa[3] = {0,0};
+
+outs PixelShaderFunction(float4 input) : COLOR0
+{
+ outs o2 = { 3 };
+ outs o4;
+ o4.v = gv * gfa[2];
+ outs o1 = { };
+// outs o3 = (outs)0;
+// o4 = (outs)0;
+ o4.c = o1.c;
+
+ return o4;
+} \ No newline at end of file
diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h
index 66fec1a3..4d1ea9df 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.1664"
+#define GLSLANG_REVISION "Overload400-PrecQual.1665"
#define GLSLANG_DATE "27-Nov-2016"
diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp
index 303c0ad2..71b4b71a 100644
--- a/glslang/MachineIndependent/Intermediate.cpp
+++ b/glslang/MachineIndependent/Intermediate.cpp
@@ -858,6 +858,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EOpLogicalAnd:
case EOpLogicalOr:
case EOpLogicalXor:
+ case EOpConstructStruct:
return true;
default:
break;
@@ -1185,6 +1186,17 @@ TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceL
}
//
+// Make an aggregate with an empty sequence.
+//
+TIntermAggregate* TIntermediate::makeAggregate(const TSourceLoc& loc)
+{
+ TIntermAggregate* aggNode = new TIntermAggregate;
+ aggNode->setLoc(loc);
+
+ return aggNode;
+}
+
+//
// For "if" test nodes. There are three children; a condition,
// a true path, and a false path. The two paths are in the
// nodePair.
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index e8608240..9ad50c74 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -221,6 +221,7 @@ public:
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
TIntermAggregate* makeAggregate(TIntermNode* node);
TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
+ TIntermAggregate* makeAggregate(const TSourceLoc&);
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
bool areAllChildConst(TIntermAggregate* aggrNode);
TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp
index 8c611f20..429f445f 100644
--- a/gtests/Hlsl.FromFile.cpp
+++ b/gtests/Hlsl.FromFile.cpp
@@ -157,6 +157,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.numericsuffixes.frag", "main"},
{"hlsl.numthreads.comp", "main_aux1"},
{"hlsl.overload.frag", "PixelShaderFunction"},
+ {"hlsl.partialInit.frag", "PixelShaderFunction"},
{"hlsl.pp.line.frag", "main"},
{"hlsl.precise.frag", "main"},
{"hlsl.promote.binary.frag", "main"},
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index b202dca6..10dfcc83 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -1896,7 +1896,8 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
}
// initializer
-// : LEFT_BRACE initializer_list RIGHT_BRACE
+// : LEFT_BRACE RIGHT_BRACE
+// | LEFT_BRACE initializer_list RIGHT_BRACE
//
// initializer_list
// : assignment_expression COMMA assignment_expression COMMA ...
@@ -1907,8 +1908,15 @@ bool HlslGrammar::acceptInitializer(TIntermTyped*& node)
if (! acceptTokenClass(EHTokLeftBrace))
return false;
- // initializer_list
+ // RIGHT_BRACE
TSourceLoc loc = token.loc;
+ if (acceptTokenClass(EHTokRightBrace)) {
+ // a zero-length initializer list
+ node = intermediate.makeAggregate(loc);
+ return true;
+ }
+
+ // initializer_list
node = nullptr;
do {
// assignment_expression
diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp
index 3f73a6fb..0ed259a1 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -4594,7 +4594,8 @@ TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TInterm
// constructor-style subtree, allowing the rest of the code to operate
// identically for both kinds of initializers.
//
- initializer = convertInitializerList(loc, variable->getType(), initializer);
+ if (initializer->getAsAggregate() && initializer->getAsAggregate()->getOp() == EOpNull)
+ initializer = convertInitializerList(loc, variable->getType(), initializer);
if (! initializer) {
// error recovery; don't leave const without constant values
if (qualifier == EvqConst)
@@ -4679,8 +4680,15 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
// see if we have bottomed out in the tree within the initializer-list part
TIntermAggregate* initList = initializer->getAsAggregate();
- if (! initList || initList->getOp() != EOpNull)
- return initializer;
+ if (! initList || initList->getOp() != EOpNull) {
+ // We don't have a list, but if it's a scalar and the 'type' is a
+ // composite, we need to lengthen below to make it useful.
+ // Otherwise, this is an already formed object to initialize with.
+ if (type.isScalar() || !initializer->getType().isScalar())
+ return initializer;
+ else
+ initList = intermediate.makeAggregate(initializer);
+ }
// Of the initializer-list set of nodes, need to process bottom up,
// so recurse deep, then process on the way up.
@@ -4694,7 +4702,8 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
arrayType.newArraySizes(*type.getArraySizes()); // but get a fresh copy of the array information, to edit below
// edit array sizes to fill in unsized dimensions
- arrayType.changeOuterArraySize((int)initList->getSequence().size());
+ if (type.isImplicitlySizedArray())
+ arrayType.changeOuterArraySize((int)initList->getSequence().size());
TIntermTyped* firstInit = initList->getSequence()[0]->getAsTyped();
if (arrayType.isArrayOfArrays() && firstInit->getType().isArray() &&
arrayType.getArraySizes().getNumDims() == firstInit->getType().getArraySizes()->getNumDims() + 1) {
@@ -4704,8 +4713,12 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
}
}
+ // lengthen list to be long enough
+ lengthenList(loc, initList->getSequence(), arrayType.getOuterArraySize());
+
+ // recursively process each element
TType elementType(arrayType, 0); // dereferenced type
- for (size_t i = 0; i < initList->getSequence().size(); ++i) {
+ for (int i = 0; i < arrayType.getOuterArraySize(); ++i) {
initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
if (initList->getSequence()[i] == nullptr)
return nullptr;
@@ -4713,6 +4726,9 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
return addConstructor(loc, initList, arrayType);
} else if (type.isStruct()) {
+ // lengthen list to be long enough
+ lengthenList(loc, initList->getSequence(), type.getStruct()->size());
+
if (type.getStruct()->size() != initList->getSequence().size()) {
error(loc, "wrong number of structure members", "initializer list", "");
return nullptr;
@@ -4728,6 +4744,9 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
// a series of rows and columns. We can just use the list directly as
// a constructor; no further processing needed.
} else {
+ // lengthen list to be long enough
+ lengthenList(loc, initList->getSequence(), type.getMatrixCols());
+
if (type.getMatrixCols() != (int)initList->getSequence().size()) {
error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str());
return nullptr;
@@ -4740,6 +4759,10 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
}
}
} else if (type.isVector()) {
+ // lengthen list to be long enough
+ lengthenList(loc, initList->getSequence(), type.getVectorSize());
+
+ // error check; we're at bottom, so work is finished below
if (type.getVectorSize() != (int)initList->getSequence().size()) {
error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str());
return nullptr;
@@ -4749,7 +4772,7 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
error(loc, "scalar expected one element:", "initializer list", type.getCompleteString().c_str());
return nullptr;
}
- } else {
+ } else {
error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str());
return nullptr;
}
@@ -4761,9 +4784,19 @@ TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, co
emulatedConstructorArguments = initList->getSequence()[0];
else
emulatedConstructorArguments = initList;
+
return addConstructor(loc, emulatedConstructorArguments, type);
}
+// Lengthen list to be long enough to cover any gap from the current list size
+// to 'size'. If the list is longer, do nothing.
+// The value to lengthen with is the default for short lists.
+void HlslParseContext::lengthenList(const TSourceLoc& loc, TIntermSequence& list, int size)
+{
+ for (int c = (int)list.size(); c < size; ++c)
+ list.push_back(intermediate.addConstantUnion(0, loc));
+}
+
//
// Test for the correctness of the parameters passed to various constructor functions
// and also convert them to the right data type, if allowed and required.
diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h
index 554243b6..ca937678 100755
--- a/hlsl/hlslParseHelper.h
+++ b/hlsl/hlslParseHelper.h
@@ -128,6 +128,7 @@ public:
const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
void declareTypedef(const TSourceLoc&, TString& identifier, const TType&, TArraySizes* typeArray = 0);
TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, TType&, TIntermTyped* initializer = 0);
+ void lengthenList(const TSourceLoc&, TIntermSequence& list, int size);
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);