1 // Copyright 2020 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/ast/stage_decoration.h"
16 #include "src/ast/workgroup_decoration.h"
17 #include "src/reader/wgsl/parser_impl_test_helper.h"
18
19 namespace tint {
20 namespace reader {
21 namespace wgsl {
22 namespace {
23
TEST_F(ParserImplTest,Decoration_Workgroup)24 TEST_F(ParserImplTest, Decoration_Workgroup) {
25 auto p = parser("workgroup_size(4)");
26 auto deco = p->decoration();
27 EXPECT_TRUE(deco.matched);
28 EXPECT_FALSE(deco.errored);
29 ASSERT_NE(deco.value, nullptr) << p->error();
30 ASSERT_FALSE(p->has_error());
31 auto* func_deco = deco.value->As<ast::Decoration>();
32 ASSERT_NE(func_deco, nullptr);
33 ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
34
35 auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
36
37 ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
38 EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
39
40 EXPECT_EQ(values[1], nullptr);
41 EXPECT_EQ(values[2], nullptr);
42 }
43
TEST_F(ParserImplTest,Decoration_Workgroup_2Param)44 TEST_F(ParserImplTest, Decoration_Workgroup_2Param) {
45 auto p = parser("workgroup_size(4, 5)");
46 auto deco = p->decoration();
47 EXPECT_TRUE(deco.matched);
48 EXPECT_FALSE(deco.errored);
49 ASSERT_NE(deco.value, nullptr) << p->error();
50 ASSERT_FALSE(p->has_error());
51 auto* func_deco = deco.value->As<ast::Decoration>();
52 ASSERT_NE(func_deco, nullptr) << p->error();
53 ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
54
55 auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
56
57 ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
58 EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
59
60 ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
61 EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
62
63 EXPECT_EQ(values[2], nullptr);
64 }
65
TEST_F(ParserImplTest,Decoration_Workgroup_3Param)66 TEST_F(ParserImplTest, Decoration_Workgroup_3Param) {
67 auto p = parser("workgroup_size(4, 5, 6)");
68 auto deco = p->decoration();
69 EXPECT_TRUE(deco.matched);
70 EXPECT_FALSE(deco.errored);
71 ASSERT_NE(deco.value, nullptr) << p->error();
72 ASSERT_FALSE(p->has_error());
73 auto* func_deco = deco.value->As<ast::Decoration>();
74 ASSERT_NE(func_deco, nullptr);
75 ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
76
77 auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
78
79 ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
80 EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
81
82 ASSERT_TRUE(values[1]->Is<ast::IntLiteralExpression>());
83 EXPECT_EQ(values[1]->As<ast::IntLiteralExpression>()->ValueAsU32(), 5u);
84
85 ASSERT_TRUE(values[2]->Is<ast::IntLiteralExpression>());
86 EXPECT_EQ(values[2]->As<ast::IntLiteralExpression>()->ValueAsU32(), 6u);
87 }
88
TEST_F(ParserImplTest,Decoration_Workgroup_WithIdent)89 TEST_F(ParserImplTest, Decoration_Workgroup_WithIdent) {
90 auto p = parser("workgroup_size(4, height)");
91 auto deco = p->decoration();
92 EXPECT_TRUE(deco.matched);
93 EXPECT_FALSE(deco.errored);
94 ASSERT_NE(deco.value, nullptr) << p->error();
95 ASSERT_FALSE(p->has_error());
96 auto* func_deco = deco.value->As<ast::Decoration>();
97 ASSERT_NE(func_deco, nullptr);
98 ASSERT_TRUE(func_deco->Is<ast::WorkgroupDecoration>());
99
100 auto values = func_deco->As<ast::WorkgroupDecoration>()->Values();
101
102 ASSERT_TRUE(values[0]->Is<ast::IntLiteralExpression>());
103 EXPECT_EQ(values[0]->As<ast::IntLiteralExpression>()->ValueAsU32(), 4u);
104
105 ASSERT_NE(values[1], nullptr);
106 auto* y_ident = values[1]->As<ast::IdentifierExpression>();
107 ASSERT_NE(y_ident, nullptr);
108 EXPECT_EQ(p->builder().Symbols().NameFor(y_ident->symbol), "height");
109
110 ASSERT_EQ(values[2], nullptr);
111 }
112
TEST_F(ParserImplTest,Decoration_Workgroup_TooManyValues)113 TEST_F(ParserImplTest, Decoration_Workgroup_TooManyValues) {
114 auto p = parser("workgroup_size(1, 2, 3, 4)");
115 auto deco = p->decoration();
116 EXPECT_FALSE(deco.matched);
117 EXPECT_TRUE(deco.errored);
118 EXPECT_EQ(deco.value, nullptr);
119 EXPECT_TRUE(p->has_error());
120 EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size decoration");
121 }
122
TEST_F(ParserImplTest,Decoration_Workgroup_MissingLeftParam)123 TEST_F(ParserImplTest, Decoration_Workgroup_MissingLeftParam) {
124 auto p = parser("workgroup_size 4, 5, 6)");
125 auto deco = p->decoration();
126 EXPECT_FALSE(deco.matched);
127 EXPECT_TRUE(deco.errored);
128 EXPECT_EQ(deco.value, nullptr);
129 EXPECT_TRUE(p->has_error());
130 EXPECT_EQ(p->error(), "1:16: expected '(' for workgroup_size decoration");
131 }
132
TEST_F(ParserImplTest,Decoration_Workgroup_MissingRightParam)133 TEST_F(ParserImplTest, Decoration_Workgroup_MissingRightParam) {
134 auto p = parser("workgroup_size(4, 5, 6");
135 auto deco = p->decoration();
136 EXPECT_FALSE(deco.matched);
137 EXPECT_TRUE(deco.errored);
138 EXPECT_EQ(deco.value, nullptr);
139 EXPECT_TRUE(p->has_error());
140 EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size decoration");
141 }
142
TEST_F(ParserImplTest,Decoration_Workgroup_MissingValues)143 TEST_F(ParserImplTest, Decoration_Workgroup_MissingValues) {
144 auto p = parser("workgroup_size()");
145 auto deco = p->decoration();
146 EXPECT_FALSE(deco.matched);
147 EXPECT_TRUE(deco.errored);
148 EXPECT_EQ(deco.value, nullptr);
149 EXPECT_TRUE(p->has_error());
150 EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
151 }
152
TEST_F(ParserImplTest,Decoration_Workgroup_Missing_X_Value)153 TEST_F(ParserImplTest, Decoration_Workgroup_Missing_X_Value) {
154 auto p = parser("workgroup_size(, 2, 3)");
155 auto deco = p->decoration();
156 EXPECT_FALSE(deco.matched);
157 EXPECT_TRUE(deco.errored);
158 EXPECT_EQ(deco.value, nullptr);
159 EXPECT_TRUE(p->has_error());
160 EXPECT_EQ(p->error(), "1:16: expected workgroup_size x parameter");
161 }
162
TEST_F(ParserImplTest,Decoration_Workgroup_Missing_Y_Comma)163 TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Y_Comma) {
164 auto p = parser("workgroup_size(1 2, 3)");
165 auto deco = p->decoration();
166 EXPECT_FALSE(deco.matched);
167 EXPECT_TRUE(deco.errored);
168 EXPECT_EQ(deco.value, nullptr);
169 EXPECT_TRUE(p->has_error());
170 EXPECT_EQ(p->error(), "1:18: expected ')' for workgroup_size decoration");
171 }
172
TEST_F(ParserImplTest,Decoration_Workgroup_Missing_Y_Value)173 TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Y_Value) {
174 auto p = parser("workgroup_size(1, , 3)");
175 auto deco = p->decoration();
176 EXPECT_FALSE(deco.matched);
177 EXPECT_TRUE(deco.errored);
178 EXPECT_EQ(deco.value, nullptr);
179 EXPECT_TRUE(p->has_error());
180 EXPECT_EQ(p->error(), "1:19: expected workgroup_size y parameter");
181 }
182
TEST_F(ParserImplTest,Decoration_Workgroup_Missing_Z_Comma)183 TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Z_Comma) {
184 auto p = parser("workgroup_size(1, 2 3)");
185 auto deco = p->decoration();
186 EXPECT_FALSE(deco.matched);
187 EXPECT_TRUE(deco.errored);
188 EXPECT_EQ(deco.value, nullptr);
189 EXPECT_TRUE(p->has_error());
190 EXPECT_EQ(p->error(), "1:21: expected ')' for workgroup_size decoration");
191 }
192
TEST_F(ParserImplTest,Decoration_Workgroup_Missing_Z_Value)193 TEST_F(ParserImplTest, Decoration_Workgroup_Missing_Z_Value) {
194 auto p = parser("workgroup_size(1, 2, )");
195 auto deco = p->decoration();
196 EXPECT_FALSE(deco.matched);
197 EXPECT_TRUE(deco.errored);
198 EXPECT_EQ(deco.value, nullptr);
199 EXPECT_TRUE(p->has_error());
200 EXPECT_EQ(p->error(), "1:22: expected workgroup_size z parameter");
201 }
202
TEST_F(ParserImplTest,Decoration_Stage)203 TEST_F(ParserImplTest, Decoration_Stage) {
204 auto p = parser("stage(compute)");
205 auto deco = p->decoration();
206 EXPECT_TRUE(deco.matched);
207 EXPECT_FALSE(deco.errored);
208 ASSERT_NE(deco.value, nullptr) << p->error();
209 ASSERT_FALSE(p->has_error());
210 auto* func_deco = deco.value->As<ast::Decoration>();
211 ASSERT_NE(func_deco, nullptr);
212 ASSERT_TRUE(func_deco->Is<ast::StageDecoration>());
213 EXPECT_EQ(func_deco->As<ast::StageDecoration>()->stage,
214 ast::PipelineStage::kCompute);
215 }
216
TEST_F(ParserImplTest,Decoration_Stage_MissingValue)217 TEST_F(ParserImplTest, Decoration_Stage_MissingValue) {
218 auto p = parser("stage()");
219 auto deco = p->decoration();
220 EXPECT_FALSE(deco.matched);
221 EXPECT_TRUE(deco.errored);
222 EXPECT_EQ(deco.value, nullptr);
223 EXPECT_TRUE(p->has_error());
224 EXPECT_EQ(p->error(), "1:7: invalid value for stage decoration");
225 }
226
TEST_F(ParserImplTest,Decoration_Stage_MissingInvalid)227 TEST_F(ParserImplTest, Decoration_Stage_MissingInvalid) {
228 auto p = parser("stage(nan)");
229 auto deco = p->decoration();
230 EXPECT_FALSE(deco.matched);
231 EXPECT_TRUE(deco.errored);
232 EXPECT_EQ(deco.value, nullptr);
233 EXPECT_TRUE(p->has_error());
234 EXPECT_EQ(p->error(), "1:7: invalid value for stage decoration");
235 }
236
TEST_F(ParserImplTest,Decoration_Stage_MissingLeftParen)237 TEST_F(ParserImplTest, Decoration_Stage_MissingLeftParen) {
238 auto p = parser("stage compute)");
239 auto deco = p->decoration();
240 EXPECT_FALSE(deco.matched);
241 EXPECT_TRUE(deco.errored);
242 EXPECT_EQ(deco.value, nullptr);
243 EXPECT_TRUE(p->has_error());
244 EXPECT_EQ(p->error(), "1:7: expected '(' for stage decoration");
245 }
246
TEST_F(ParserImplTest,Decoration_Stage_MissingRightParen)247 TEST_F(ParserImplTest, Decoration_Stage_MissingRightParen) {
248 auto p = parser("stage(compute");
249 auto deco = p->decoration();
250 EXPECT_FALSE(deco.matched);
251 EXPECT_TRUE(deco.errored);
252 EXPECT_EQ(deco.value, nullptr);
253 EXPECT_TRUE(p->has_error());
254 EXPECT_EQ(p->error(), "1:14: expected ')' for stage decoration");
255 }
256
257 } // namespace
258 } // namespace wgsl
259 } // namespace reader
260 } // namespace tint
261