• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2015-2016 The Khronos Group Inc.
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 // Assembler tests for instructions in the "Annotation" section of the
16 // SPIR-V spec.
17 
18 #include <sstream>
19 #include <string>
20 #include <tuple>
21 #include <vector>
22 
23 #include "gmock/gmock.h"
24 #include "test/test_fixture.h"
25 #include "test/unit_spirv.h"
26 
27 namespace spvtools {
28 namespace {
29 
30 using spvtest::EnumCase;
31 using spvtest::MakeInstruction;
32 using spvtest::MakeVector;
33 using spvtest::TextToBinaryTest;
34 using ::testing::Combine;
35 using ::testing::Eq;
36 using ::testing::Values;
37 using ::testing::ValuesIn;
38 
39 // Test OpDecorate
40 
41 using OpDecorateSimpleTest =
42     spvtest::TextToBinaryTestBase<::testing::TestWithParam<
43         std::tuple<spv_target_env, EnumCase<SpvDecoration>>>>;
44 
TEST_P(OpDecorateSimpleTest,AnySimpleDecoration)45 TEST_P(OpDecorateSimpleTest, AnySimpleDecoration) {
46   // This string should assemble, but should not validate.
47   std::stringstream input;
48   input << "OpDecorate %1 " << std::get<1>(GetParam()).name();
49   for (auto operand : std::get<1>(GetParam()).operands())
50     input << " " << operand;
51   input << std::endl;
52   EXPECT_THAT(CompiledInstructions(input.str(), std::get<0>(GetParam())),
53               Eq(MakeInstruction(SpvOpDecorate,
54                                  {1, uint32_t(std::get<1>(GetParam()).value())},
55                                  std::get<1>(GetParam()).operands())));
56   // Also check disassembly.
57   EXPECT_THAT(
58       EncodeAndDecodeSuccessfully(input.str(), SPV_BINARY_TO_TEXT_OPTION_NONE,
59                                   std::get<0>(GetParam())),
60       Eq(input.str()));
61 }
62 
63 #define CASE(NAME) SpvDecoration##NAME, #NAME
64 INSTANTIATE_TEST_CASE_P(
65     TextToBinaryDecorateSimple, OpDecorateSimpleTest,
66     Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
67             ValuesIn(std::vector<EnumCase<SpvDecoration>>{
68                 // The operand literal values are arbitrarily chosen,
69                 // but there are the right number of them.
70                 {CASE(RelaxedPrecision), {}},
71                 {CASE(SpecId), {100}},
72                 {CASE(Block), {}},
73                 {CASE(BufferBlock), {}},
74                 {CASE(RowMajor), {}},
75                 {CASE(ColMajor), {}},
76                 {CASE(ArrayStride), {4}},
77                 {CASE(MatrixStride), {16}},
78                 {CASE(GLSLShared), {}},
79                 {CASE(GLSLPacked), {}},
80                 {CASE(CPacked), {}},
81                 // Placeholder line for enum value 12
82                 {CASE(NoPerspective), {}},
83                 {CASE(Flat), {}},
84                 {CASE(Patch), {}},
85                 {CASE(Centroid), {}},
86                 {CASE(Sample), {}},
87                 {CASE(Invariant), {}},
88                 {CASE(Restrict), {}},
89                 {CASE(Aliased), {}},
90                 {CASE(Volatile), {}},
91                 {CASE(Constant), {}},
92                 {CASE(Coherent), {}},
93                 {CASE(NonWritable), {}},
94                 {CASE(NonReadable), {}},
95                 {CASE(Uniform), {}},
96                 {CASE(SaturatedConversion), {}},
97                 {CASE(Stream), {2}},
98                 {CASE(Location), {6}},
99                 {CASE(Component), {3}},
100                 {CASE(Index), {14}},
101                 {CASE(Binding), {19}},
102                 {CASE(DescriptorSet), {7}},
103                 {CASE(Offset), {12}},
104                 {CASE(XfbBuffer), {1}},
105                 {CASE(XfbStride), {8}},
106                 {CASE(NoContraction), {}},
107                 {CASE(InputAttachmentIndex), {102}},
108                 {CASE(Alignment), {16}},
109             })), );
110 
111 INSTANTIATE_TEST_CASE_P(TextToBinaryDecorateSimpleV11, OpDecorateSimpleTest,
112                         Combine(Values(SPV_ENV_UNIVERSAL_1_1),
113                                 Values(EnumCase<SpvDecoration>{
114                                     CASE(MaxByteOffset), {128}})), );
115 #undef CASE
116 
TEST_F(OpDecorateSimpleTest,WrongDecoration)117 TEST_F(OpDecorateSimpleTest, WrongDecoration) {
118   EXPECT_THAT(CompileFailure("OpDecorate %1 xxyyzz"),
119               Eq("Invalid decoration 'xxyyzz'."));
120 }
121 
TEST_F(OpDecorateSimpleTest,ExtraOperandsOnDecorationExpectingNone)122 TEST_F(OpDecorateSimpleTest, ExtraOperandsOnDecorationExpectingNone) {
123   EXPECT_THAT(CompileFailure("OpDecorate %1 RelaxedPrecision 99"),
124               Eq("Expected <opcode> or <result-id> at the beginning of an "
125                  "instruction, found '99'."));
126 }
127 
TEST_F(OpDecorateSimpleTest,ExtraOperandsOnDecorationExpectingOne)128 TEST_F(OpDecorateSimpleTest, ExtraOperandsOnDecorationExpectingOne) {
129   EXPECT_THAT(CompileFailure("OpDecorate %1 SpecId 99 100"),
130               Eq("Expected <opcode> or <result-id> at the beginning of an "
131                  "instruction, found '100'."));
132 }
133 
TEST_F(OpDecorateSimpleTest,ExtraOperandsOnDecorationExpectingTwo)134 TEST_F(OpDecorateSimpleTest, ExtraOperandsOnDecorationExpectingTwo) {
135   EXPECT_THAT(
136       CompileFailure("OpDecorate %1 LinkageAttributes \"abc\" Import 42"),
137       Eq("Expected <opcode> or <result-id> at the beginning of an "
138          "instruction, found '42'."));
139 }
140 
141 // A single test case for an enum decoration.
142 struct DecorateEnumCase {
143   // Place the enum value first, so it's easier to read the binary dumps when
144   // the test fails.
145   uint32_t value;  // The value within the enum, e.g. Position
146   std::string name;
147   uint32_t enum_value;  // Which enum, e.g. BuiltIn
148   std::string enum_name;
149 };
150 
151 using OpDecorateEnumTest =
152     spvtest::TextToBinaryTestBase<::testing::TestWithParam<DecorateEnumCase>>;
153 
TEST_P(OpDecorateEnumTest,AnyEnumDecoration)154 TEST_P(OpDecorateEnumTest, AnyEnumDecoration) {
155   // This string should assemble, but should not validate.
156   const std::string input =
157       "OpDecorate %1 " + GetParam().enum_name + " " + GetParam().name;
158   EXPECT_THAT(CompiledInstructions(input),
159               Eq(MakeInstruction(SpvOpDecorate, {1, GetParam().enum_value,
160                                                  GetParam().value})));
161 }
162 
163 // Test OpDecorate BuiltIn.
164 // clang-format off
165 #define CASE(NAME) \
166   { SpvBuiltIn##NAME, #NAME, SpvDecorationBuiltIn, "BuiltIn" }
167 INSTANTIATE_TEST_CASE_P(TextToBinaryDecorateBuiltIn, OpDecorateEnumTest,
168                         ::testing::ValuesIn(std::vector<DecorateEnumCase>{
169                             CASE(Position),
170                             CASE(PointSize),
171                             CASE(ClipDistance),
172                             CASE(CullDistance),
173                             CASE(VertexId),
174                             CASE(InstanceId),
175                             CASE(PrimitiveId),
176                             CASE(InvocationId),
177                             CASE(Layer),
178                             CASE(ViewportIndex),
179                             CASE(TessLevelOuter),
180                             CASE(TessLevelInner),
181                             CASE(TessCoord),
182                             CASE(PatchVertices),
183                             CASE(FragCoord),
184                             CASE(PointCoord),
185                             CASE(FrontFacing),
186                             CASE(SampleId),
187                             CASE(SamplePosition),
188                             CASE(SampleMask),
189                             // Value 21 intentionally missing.
190                             CASE(FragDepth),
191                             CASE(HelperInvocation),
192                             CASE(NumWorkgroups),
193                             CASE(WorkgroupSize),
194                             CASE(WorkgroupId),
195                             CASE(LocalInvocationId),
196                             CASE(GlobalInvocationId),
197                             CASE(LocalInvocationIndex),
198                             CASE(WorkDim),
199                             CASE(GlobalSize),
200                             CASE(EnqueuedWorkgroupSize),
201                             CASE(GlobalOffset),
202                             CASE(GlobalLinearId),
203                             // Value 35 intentionally missing.
204                             CASE(SubgroupSize),
205                             CASE(SubgroupMaxSize),
206                             CASE(NumSubgroups),
207                             CASE(NumEnqueuedSubgroups),
208                             CASE(SubgroupId),
209                             CASE(SubgroupLocalInvocationId),
210                             CASE(VertexIndex),
211                             CASE(InstanceIndex),
212                         }),);
213 #undef CASE
214 // clang-format on
215 
TEST_F(OpDecorateEnumTest,WrongBuiltIn)216 TEST_F(OpDecorateEnumTest, WrongBuiltIn) {
217   EXPECT_THAT(CompileFailure("OpDecorate %1 BuiltIn xxyyzz"),
218               Eq("Invalid built-in 'xxyyzz'."));
219 }
220 
221 // Test OpDecorate FuncParamAttr
222 // clang-format off
223 #define CASE(NAME) \
224   { SpvFunctionParameterAttribute##NAME, #NAME, SpvDecorationFuncParamAttr, "FuncParamAttr" }
225 INSTANTIATE_TEST_CASE_P(TextToBinaryDecorateFuncParamAttr, OpDecorateEnumTest,
226                         ::testing::ValuesIn(std::vector<DecorateEnumCase>{
227                             CASE(Zext),
228                             CASE(Sext),
229                             CASE(ByVal),
230                             CASE(Sret),
231                             CASE(NoAlias),
232                             CASE(NoCapture),
233                             CASE(NoWrite),
234                             CASE(NoReadWrite),
235                       }),);
236 #undef CASE
237 // clang-format on
238 
TEST_F(OpDecorateEnumTest,WrongFuncParamAttr)239 TEST_F(OpDecorateEnumTest, WrongFuncParamAttr) {
240   EXPECT_THAT(CompileFailure("OpDecorate %1 FuncParamAttr xxyyzz"),
241               Eq("Invalid function parameter attribute 'xxyyzz'."));
242 }
243 
244 // Test OpDecorate FPRoundingMode
245 // clang-format off
246 #define CASE(NAME) \
247   { SpvFPRoundingMode##NAME, #NAME, SpvDecorationFPRoundingMode, "FPRoundingMode" }
248 INSTANTIATE_TEST_CASE_P(TextToBinaryDecorateFPRoundingMode, OpDecorateEnumTest,
249                         ::testing::ValuesIn(std::vector<DecorateEnumCase>{
250                             CASE(RTE),
251                             CASE(RTZ),
252                             CASE(RTP),
253                             CASE(RTN),
254                       }),);
255 #undef CASE
256 // clang-format on
257 
TEST_F(OpDecorateEnumTest,WrongFPRoundingMode)258 TEST_F(OpDecorateEnumTest, WrongFPRoundingMode) {
259   EXPECT_THAT(CompileFailure("OpDecorate %1 FPRoundingMode xxyyzz"),
260               Eq("Invalid floating-point rounding mode 'xxyyzz'."));
261 }
262 
263 // Test OpDecorate FPFastMathMode.
264 // These can by named enums for the single-bit masks.  However, we don't support
265 // symbolic combinations of the masks.  Rather, they can use !<immediate>
266 // syntax, e.g. !0x3
267 
268 // clang-format off
269 #define CASE(ENUM,NAME) \
270   { SpvFPFastMathMode##ENUM, #NAME, SpvDecorationFPFastMathMode, "FPFastMathMode" }
271 INSTANTIATE_TEST_CASE_P(TextToBinaryDecorateFPFastMathMode, OpDecorateEnumTest,
272                         ::testing::ValuesIn(std::vector<DecorateEnumCase>{
273                             CASE(MaskNone, None),
274                             CASE(NotNaNMask, NotNaN),
275                             CASE(NotInfMask, NotInf),
276                             CASE(NSZMask, NSZ),
277                             CASE(AllowRecipMask, AllowRecip),
278                             CASE(FastMask, Fast),
279                       }),);
280 #undef CASE
281 // clang-format on
282 
TEST_F(OpDecorateEnumTest,CombinedFPFastMathMask)283 TEST_F(OpDecorateEnumTest, CombinedFPFastMathMask) {
284   // Sample a single combination.  This ensures we've integrated
285   // the instruction parsing logic with spvTextParseMask.
286   const std::string input = "OpDecorate %1 FPFastMathMode NotNaN|NotInf|NSZ";
287   const uint32_t expected_enum = SpvDecorationFPFastMathMode;
288   const uint32_t expected_mask = SpvFPFastMathModeNotNaNMask |
289                                  SpvFPFastMathModeNotInfMask |
290                                  SpvFPFastMathModeNSZMask;
291   EXPECT_THAT(
292       CompiledInstructions(input),
293       Eq(MakeInstruction(SpvOpDecorate, {1, expected_enum, expected_mask})));
294 }
295 
TEST_F(OpDecorateEnumTest,WrongFPFastMathMode)296 TEST_F(OpDecorateEnumTest, WrongFPFastMathMode) {
297   EXPECT_THAT(
298       CompileFailure("OpDecorate %1 FPFastMathMode NotNaN|xxyyzz"),
299       Eq("Invalid floating-point fast math mode operand 'NotNaN|xxyyzz'."));
300 }
301 
302 // Test OpDecorate Linkage
303 
304 // A single test case for a linkage
305 struct DecorateLinkageCase {
306   uint32_t linkage_type_value;
307   std::string linkage_type_name;
308   std::string external_name;
309 };
310 
311 using OpDecorateLinkageTest = spvtest::TextToBinaryTestBase<
312     ::testing::TestWithParam<DecorateLinkageCase>>;
313 
TEST_P(OpDecorateLinkageTest,AnyLinkageDecoration)314 TEST_P(OpDecorateLinkageTest, AnyLinkageDecoration) {
315   // This string should assemble, but should not validate.
316   const std::string input = "OpDecorate %1 LinkageAttributes \"" +
317                             GetParam().external_name + "\" " +
318                             GetParam().linkage_type_name;
319   std::vector<uint32_t> expected_operands{1, SpvDecorationLinkageAttributes};
320   std::vector<uint32_t> encoded_external_name =
321       MakeVector(GetParam().external_name);
322   expected_operands.insert(expected_operands.end(),
323                            encoded_external_name.begin(),
324                            encoded_external_name.end());
325   expected_operands.push_back(GetParam().linkage_type_value);
326   EXPECT_THAT(CompiledInstructions(input),
327               Eq(MakeInstruction(SpvOpDecorate, expected_operands)));
328 }
329 
330 // clang-format off
331 #define CASE(ENUM) SpvLinkageType##ENUM, #ENUM
332 INSTANTIATE_TEST_CASE_P(TextToBinaryDecorateLinkage, OpDecorateLinkageTest,
333                         ::testing::ValuesIn(std::vector<DecorateLinkageCase>{
334                             { CASE(Import), "a" },
335                             { CASE(Export), "foo" },
336                             { CASE(Import), "some kind of long name with spaces etc." },
337                             // TODO(dneto): utf-8, escaping, quoting cases.
338                       }),);
339 #undef CASE
340 // clang-format on
341 
TEST_F(OpDecorateLinkageTest,WrongType)342 TEST_F(OpDecorateLinkageTest, WrongType) {
343   EXPECT_THAT(CompileFailure("OpDecorate %1 LinkageAttributes \"foo\" xxyyzz"),
344               Eq("Invalid linkage type 'xxyyzz'."));
345 }
346 
347 // Test OpGroupMemberDecorate
348 
TEST_F(TextToBinaryTest,GroupMemberDecorateGoodOneTarget)349 TEST_F(TextToBinaryTest, GroupMemberDecorateGoodOneTarget) {
350   EXPECT_THAT(CompiledInstructions("OpGroupMemberDecorate %group %id0 42"),
351               Eq(MakeInstruction(SpvOpGroupMemberDecorate, {1, 2, 42})));
352 }
353 
TEST_F(TextToBinaryTest,GroupMemberDecorateGoodTwoTargets)354 TEST_F(TextToBinaryTest, GroupMemberDecorateGoodTwoTargets) {
355   EXPECT_THAT(
356       CompiledInstructions("OpGroupMemberDecorate %group %id0 96 %id1 42"),
357       Eq(MakeInstruction(SpvOpGroupMemberDecorate, {1, 2, 96, 3, 42})));
358 }
359 
TEST_F(TextToBinaryTest,GroupMemberDecorateMissingGroupId)360 TEST_F(TextToBinaryTest, GroupMemberDecorateMissingGroupId) {
361   EXPECT_THAT(CompileFailure("OpGroupMemberDecorate"),
362               Eq("Expected operand, found end of stream."));
363 }
364 
TEST_F(TextToBinaryTest,GroupMemberDecorateInvalidGroupId)365 TEST_F(TextToBinaryTest, GroupMemberDecorateInvalidGroupId) {
366   EXPECT_THAT(CompileFailure("OpGroupMemberDecorate 16"),
367               Eq("Expected id to start with %."));
368 }
369 
TEST_F(TextToBinaryTest,GroupMemberDecorateInvalidTargetId)370 TEST_F(TextToBinaryTest, GroupMemberDecorateInvalidTargetId) {
371   EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group 12"),
372               Eq("Expected id to start with %."));
373 }
374 
TEST_F(TextToBinaryTest,GroupMemberDecorateMissingTargetMemberNumber)375 TEST_F(TextToBinaryTest, GroupMemberDecorateMissingTargetMemberNumber) {
376   EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group %id0"),
377               Eq("Expected operand, found end of stream."));
378 }
379 
TEST_F(TextToBinaryTest,GroupMemberDecorateInvalidTargetMemberNumber)380 TEST_F(TextToBinaryTest, GroupMemberDecorateInvalidTargetMemberNumber) {
381   EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group %id0 %id1"),
382               Eq("Invalid unsigned integer literal: %id1"));
383 }
384 
TEST_F(TextToBinaryTest,GroupMemberDecorateInvalidSecondTargetId)385 TEST_F(TextToBinaryTest, GroupMemberDecorateInvalidSecondTargetId) {
386   EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group %id1 42 12"),
387               Eq("Expected id to start with %."));
388 }
389 
TEST_F(TextToBinaryTest,GroupMemberDecorateMissingSecondTargetMemberNumber)390 TEST_F(TextToBinaryTest, GroupMemberDecorateMissingSecondTargetMemberNumber) {
391   EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group %id0 42 %id1"),
392               Eq("Expected operand, found end of stream."));
393 }
394 
TEST_F(TextToBinaryTest,GroupMemberDecorateInvalidSecondTargetMemberNumber)395 TEST_F(TextToBinaryTest, GroupMemberDecorateInvalidSecondTargetMemberNumber) {
396   EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group %id0 42 %id1 %id2"),
397               Eq("Invalid unsigned integer literal: %id2"));
398 }
399 
400 // Test OpMemberDecorate
401 
402 using OpMemberDecorateSimpleTest =
403     spvtest::TextToBinaryTestBase<::testing::TestWithParam<
404         std::tuple<spv_target_env, EnumCase<SpvDecoration>>>>;
405 
TEST_P(OpMemberDecorateSimpleTest,AnySimpleDecoration)406 TEST_P(OpMemberDecorateSimpleTest, AnySimpleDecoration) {
407   // This string should assemble, but should not validate.
408   std::stringstream input;
409   input << "OpMemberDecorate %1 42 " << std::get<1>(GetParam()).name();
410   for (auto operand : std::get<1>(GetParam()).operands())
411     input << " " << operand;
412   input << std::endl;
413   EXPECT_THAT(
414       CompiledInstructions(input.str(), std::get<0>(GetParam())),
415       Eq(MakeInstruction(SpvOpMemberDecorate,
416                          {1, 42, uint32_t(std::get<1>(GetParam()).value())},
417                          std::get<1>(GetParam()).operands())));
418   // Also check disassembly.
419   EXPECT_THAT(
420       EncodeAndDecodeSuccessfully(input.str(), SPV_BINARY_TO_TEXT_OPTION_NONE,
421                                   std::get<0>(GetParam())),
422       Eq(input.str()));
423 }
424 
425 #define CASE(NAME) SpvDecoration##NAME, #NAME
426 INSTANTIATE_TEST_CASE_P(
427     TextToBinaryDecorateSimple, OpMemberDecorateSimpleTest,
428     Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
429             ValuesIn(std::vector<EnumCase<SpvDecoration>>{
430                 // The operand literal values are arbitrarily chosen,
431                 // but there are the right number of them.
432                 {CASE(RelaxedPrecision), {}},
433                 {CASE(SpecId), {100}},
434                 {CASE(Block), {}},
435                 {CASE(BufferBlock), {}},
436                 {CASE(RowMajor), {}},
437                 {CASE(ColMajor), {}},
438                 {CASE(ArrayStride), {4}},
439                 {CASE(MatrixStride), {16}},
440                 {CASE(GLSLShared), {}},
441                 {CASE(GLSLPacked), {}},
442                 {CASE(CPacked), {}},
443                 // Placeholder line for enum value 12
444                 {CASE(NoPerspective), {}},
445                 {CASE(Flat), {}},
446                 {CASE(Patch), {}},
447                 {CASE(Centroid), {}},
448                 {CASE(Sample), {}},
449                 {CASE(Invariant), {}},
450                 {CASE(Restrict), {}},
451                 {CASE(Aliased), {}},
452                 {CASE(Volatile), {}},
453                 {CASE(Constant), {}},
454                 {CASE(Coherent), {}},
455                 {CASE(NonWritable), {}},
456                 {CASE(NonReadable), {}},
457                 {CASE(Uniform), {}},
458                 {CASE(SaturatedConversion), {}},
459                 {CASE(Stream), {2}},
460                 {CASE(Location), {6}},
461                 {CASE(Component), {3}},
462                 {CASE(Index), {14}},
463                 {CASE(Binding), {19}},
464                 {CASE(DescriptorSet), {7}},
465                 {CASE(Offset), {12}},
466                 {CASE(XfbBuffer), {1}},
467                 {CASE(XfbStride), {8}},
468                 {CASE(NoContraction), {}},
469                 {CASE(InputAttachmentIndex), {102}},
470                 {CASE(Alignment), {16}},
471             })), );
472 
473 INSTANTIATE_TEST_CASE_P(
474     TextToBinaryDecorateSimpleV11, OpMemberDecorateSimpleTest,
475     Combine(Values(SPV_ENV_UNIVERSAL_1_1),
476             Values(EnumCase<SpvDecoration>{CASE(MaxByteOffset), {128}})), );
477 #undef CASE
478 
TEST_F(OpMemberDecorateSimpleTest,WrongDecoration)479 TEST_F(OpMemberDecorateSimpleTest, WrongDecoration) {
480   EXPECT_THAT(CompileFailure("OpMemberDecorate %1 9 xxyyzz"),
481               Eq("Invalid decoration 'xxyyzz'."));
482 }
483 
TEST_F(OpMemberDecorateSimpleTest,ExtraOperandsOnDecorationExpectingNone)484 TEST_F(OpMemberDecorateSimpleTest, ExtraOperandsOnDecorationExpectingNone) {
485   EXPECT_THAT(CompileFailure("OpMemberDecorate %1 12 RelaxedPrecision 99"),
486               Eq("Expected <opcode> or <result-id> at the beginning of an "
487                  "instruction, found '99'."));
488 }
489 
TEST_F(OpMemberDecorateSimpleTest,ExtraOperandsOnDecorationExpectingOne)490 TEST_F(OpMemberDecorateSimpleTest, ExtraOperandsOnDecorationExpectingOne) {
491   EXPECT_THAT(CompileFailure("OpMemberDecorate %1 0 SpecId 99 100"),
492               Eq("Expected <opcode> or <result-id> at the beginning of an "
493                  "instruction, found '100'."));
494 }
495 
TEST_F(OpMemberDecorateSimpleTest,ExtraOperandsOnDecorationExpectingTwo)496 TEST_F(OpMemberDecorateSimpleTest, ExtraOperandsOnDecorationExpectingTwo) {
497   EXPECT_THAT(CompileFailure(
498                   "OpMemberDecorate %1 1 LinkageAttributes \"abc\" Import 42"),
499               Eq("Expected <opcode> or <result-id> at the beginning of an "
500                  "instruction, found '42'."));
501 }
502 
503 // TODO(dneto): OpMemberDecorate cases for decorations with parameters which
504 // are: not just lists of literal numbers.
505 
506 // TODO(dneto): OpDecorationGroup
507 // TODO(dneto): OpGroupDecorate
508 
509 }  // namespace
510 }  // namespace spvtools
511