You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This was a bit tricker than I expected, but I think I came up with a
reasonably clever solution.
In HLSL, user-defined data types have aggregate initialization, not
constructors _except_ that some of the builtin types we do model
constructors for. This is actually useful!
In my earlier change I updated DeclCXX so that HLSL non-implicit
classes are always marged as Aggregates. This ends up being not
quite right, because there are some implicit types that should be
aggregates, and others that shouldn't. For example, the implicit
cbuffer-layout types should be aggregates so that we can flatten
them, but resources shouldn't be because we really don't want to
flatten them.
In the update, whether or not an HLSL type is an aggregate is keyed
off having non-implicit "special" members (constructors & operators).
This is more correct.
Aggregate types get flattened out for casting and initialization, while
non-Aggregate types (basically just resources) get left unflattened and
we attempt copy-initialization on them.
Next problem: I was getting some odd conflicting diagnostics when
argument conversion or copy-initialization fails, so I refactored
BuildInitializerList and CastInitializer to return success/failure so
that we can propagate that up and fail if the argument->destination
type fails without then also complaining about the number of
initializers.
Copy file name to clipboardExpand all lines: clang/test/SemaHLSL/Language/InitLists.hlsl
+24Lines changed: 24 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -44,6 +44,16 @@ struct SlicyBits {
44
44
int W : 8;
45
45
};
46
46
47
+
struct ContainsResource { // #ContainsResource
48
+
int X;
49
+
RWBuffer<float4> B;
50
+
};
51
+
52
+
struct ContainsResourceInverted {
53
+
RWBuffer<float4> B;
54
+
int X;
55
+
};
56
+
47
57
voidfn() {
48
58
TwoFloats TF1 = {{{1.0, 2}}};
49
59
TwoFloats TF2 = {1,2};
@@ -87,3 +97,17 @@ void Errs() {
87
97
88
98
int2 Something = {1.xxx}; // expected-error{{too many initializers in list for type 'int2' (aka 'vector<int, 2>') (expected 2 but found 3)}}
89
99
}
100
+
101
+
voidErr2(RWBuffer<float4> B) {
102
+
ContainsResource RS1 = {1, B};
103
+
ContainsResource RS2 = (1.xx); // expected-error{{no viable conversion from 'vector<int, 2>' (vector of 2 'int' values) to 'ContainsResource'}}
104
+
ContainsResource RS3 = {B, 1}; // expected-error{{no viable conversion from 'RWBuffer<float4>' (aka 'RWBuffer<vector<float, 4>>') to 'int'}}
105
+
ContainsResourceInverted IR = {RS1}; // expected-error{{no viable conversion from 'int' to 'hlsl::RWBuffer<vector<float, 4>>'}}
106
+
}
107
+
108
+
// expected-note@#ContainsResource{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'vector<int, 2>' (vector of 2 'int' values) to 'const ContainsResource &' for 1st argument}}
109
+
// expected-note@#ContainsResource{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'vector<int, 2>' (vector of 2 'int' values) to 'ContainsResource &&' for 1st argument}}
110
+
111
+
// These notes refer to the RWBuffer constructors that do not have source locations
112
+
// expected-note@*{{candidate constructor (the implicit copy constructor) not viable}}
113
+
// expected-note@*{{candidate constructor (the implicit move constructor) not viable}}
0 commit comments