1 // Copyright (c) 2017 Google 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 #include <string>
16 #include <vector>
17 
18 #include "DebugInfo.h"
19 #include "gmock/gmock.h"
20 #include "source/util/string_utils.h"
21 #include "test/test_fixture.h"
22 #include "test/unit_spirv.h"
23 
24 // This file tests the correctness of encoding and decoding of instructions
25 // involving the DebugInfo extended instruction set.
26 // Semantic correctness should be the responsibility of validator.
27 //
28 // See https://www.khronos.org/registry/spir-v/specs/1.0/DebugInfo.html
29 
30 namespace spvtools {
31 namespace {
32 
33 using spvtest::Concatenate;
34 using spvtest::MakeInstruction;
35 using utils::MakeVector;
36 using testing::Eq;
37 
38 struct InstructionCase {
39   uint32_t opcode;
40   std::string name;
41   std::string operands;
42   std::vector<uint32_t> expected_operands;
43 };
44 
45 using ExtInstDebugInfoRoundTripTest =
46     spvtest::TextToBinaryTestBase<::testing::TestWithParam<InstructionCase>>;
47 using ExtInstDebugInfoRoundTripTestExplicit = spvtest::TextToBinaryTest;
48 
TEST_P(ExtInstDebugInfoRoundTripTest,ParameterizedExtInst)49 TEST_P(ExtInstDebugInfoRoundTripTest, ParameterizedExtInst) {
50   const std::string input =
51       "%1 = OpExtInstImport \"DebugInfo\"\n"
52       "%3 = OpExtInst %2 %1 " +
53       GetParam().name + GetParam().operands + "\n";
54   // First make sure it assembles correctly.
55   EXPECT_THAT(CompiledInstructions(input),
56               Eq(Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1},
57                                               MakeVector("DebugInfo")),
58                               MakeInstruction(spv::Op::OpExtInst,
59                                               {2, 3, 1, GetParam().opcode},
60                                               GetParam().expected_operands)})))
61       << input;
62   // Now check the round trip through the disassembler.
63   EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input) << input;
64 }
65 
66 #define CASE_0(Enum)                                      \
67   {                                                       \
68     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, "", {} \
69   }
70 
71 #define CASE_ILL(Enum, L0, L1)                                           \
72   {                                                                      \
73     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 " #L0 " " #L1, { \
74       4, L0, L1                                                          \
75     }                                                                    \
76   }
77 
78 #define CASE_IL(Enum, L0)                                                \
79   {                                                                      \
80     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 " #L0, { 4, L0 } \
81   }
82 
83 #define CASE_I(Enum)                                            \
84   {                                                             \
85     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4", { 4 } \
86   }
87 
88 #define CASE_II(Enum)                                                 \
89   {                                                                   \
90     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 %5", { 4, 5 } \
91   }
92 
93 #define CASE_III(Enum)                                                      \
94   {                                                                         \
95     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 %5 %6", { 4, 5, 6 } \
96   }
97 
98 #define CASE_IIII(Enum)                                              \
99   {                                                                  \
100     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 %5 %6 %7", { \
101       4, 5, 6, 7                                                     \
102     }                                                                \
103   }
104 
105 #define CASE_IIIII(Enum)                                                \
106   {                                                                     \
107     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 %5 %6 %7 %8", { \
108       4, 5, 6, 7, 8                                                     \
109     }                                                                   \
110   }
111 
112 #define CASE_IIIIII(Enum)                                                  \
113   {                                                                        \
114     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 %5 %6 %7 %8 %9", { \
115       4, 5, 6, 7, 8, 9                                                     \
116     }                                                                      \
117   }
118 
119 #define CASE_IIIIIII(Enum)                                                     \
120   {                                                                            \
121     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 %5 %6 %7 %8 %9 %10", { \
122       4, 5, 6, 7, 8, 9, 10                                                     \
123     }                                                                          \
124   }
125 
126 #define CASE_IIILLI(Enum, L0, L1)                  \
127   {                                                \
128     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, \
129         " %4 %5 %6 " #L0 " " #L1 " %7", {          \
130       4, 5, 6, L0, L1, 7                           \
131     }                                              \
132   }
133 
134 #define CASE_IIILLIL(Enum, L0, L1, L2)             \
135   {                                                \
136     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, \
137         " %4 %5 %6 " #L0 " " #L1 " %7 " #L2, {     \
138       4, 5, 6, L0, L1, 7, L2                       \
139     }                                              \
140   }
141 
142 #define CASE_IE(Enum, E0)                                        \
143   {                                                              \
144     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 " #E0, { \
145       4, uint32_t(DebugInfo##E0)                                 \
146     }                                                            \
147   }
148 
149 #define CASE_IIE(Enum, E0)                                          \
150   {                                                                 \
151     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 %5 " #E0, { \
152       4, 5, uint32_t(DebugInfo##E0)                                 \
153     }                                                               \
154   }
155 
156 #define CASE_ISF(Enum, S0, Fstr, Fnum)                                    \
157   {                                                                       \
158     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 " #S0 " " Fstr, { \
159       4, uint32_t(spv::StorageClass::S0), Fnum                            \
160     }                                                                     \
161   }
162 
163 #define CASE_LII(Enum, L0)                                             \
164   {                                                                    \
165     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " " #L0 " %4 %5", { \
166       L0, 4, 5                                                         \
167     }                                                                  \
168   }
169 
170 #define CASE_ILI(Enum, L0)                                             \
171   {                                                                    \
172     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 " #L0 " %5", { \
173       4, L0, 5                                                         \
174     }                                                                  \
175   }
176 
177 #define CASE_ILII(Enum, L0)                                               \
178   {                                                                       \
179     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 " #L0 " %5 %6", { \
180       4, L0, 5, 6                                                         \
181     }                                                                     \
182   }
183 
184 #define CASE_ILLII(Enum, L0, L1)                   \
185   {                                                \
186     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, \
187         " %4 " #L0 " " #L1 " %5 %6", {             \
188       4, L0, L1, 5, 6                              \
189     }                                              \
190   }
191 
192 #define CASE_IIILLIIF(Enum, L0, L1, Fstr, Fnum)    \
193   {                                                \
194     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, \
195         " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr, { \
196       4, 5, 6, L0, L1, 7, 8, Fnum                  \
197     }                                              \
198   }
199 
200 #define CASE_IIILLIIFII(Enum, L0, L1, Fstr, Fnum)            \
201   {                                                          \
202     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,           \
203         " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " %9 %10", { \
204       4, 5, 6, L0, L1, 7, 8, Fnum, 9, 10                     \
205     }                                                        \
206   }
207 
208 #define CASE_IIILLIIFIIII(Enum, L0, L1, Fstr, Fnum)                  \
209   {                                                                  \
210     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,                   \
211         " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " %9 %10 %11 %12", { \
212       4, 5, 6, L0, L1, 7, 8, Fnum, 9, 10, 11, 12                     \
213     }                                                                \
214   }
215 
216 #define CASE_IIILLIIFIIIIII(Enum, L0, L1, Fstr, Fnum)                        \
217   {                                                                          \
218     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,                           \
219         " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " %9 %10 %11 %12 %13 %14", { \
220       4, 5, 6, L0, L1, 7, 8, Fnum, 9, 10, 11, 12, 13, 14                     \
221     }                                                                        \
222   }
223 
224 #define CASE_IEILLIIF(Enum, E0, L0, L1, Fstr, Fnum)     \
225   {                                                     \
226     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,      \
227         " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 " Fstr, { \
228       4, uint32_t(DebugInfo##E0), 5, L0, L1, 6, 7, Fnum \
229     }                                                   \
230   }
231 
232 #define CASE_IEILLIIFI(Enum, E0, L0, L1, Fstr, Fnum)          \
233   {                                                           \
234     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,            \
235         " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 " Fstr " %8", { \
236       4, uint32_t(DebugInfo##E0), 5, L0, L1, 6, 7, Fnum, 8    \
237     }                                                         \
238   }
239 
240 #define CASE_IEILLIIFII(Enum, E0, L0, L1, Fstr, Fnum)            \
241   {                                                              \
242     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,               \
243         " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 " Fstr " %8 %9", { \
244       4, uint32_t(DebugInfo##E0), 5, L0, L1, 6, 7, Fnum, 8, 9    \
245     }                                                            \
246   }
247 
248 #define CASE_IEILLIIFIII(Enum, E0, L0, L1, Fstr, Fnum)               \
249   {                                                                  \
250     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,                   \
251         " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 " Fstr " %8 %9 %10", { \
252       4, uint32_t(DebugInfo##E0), 5, L0, L1, 6, 7, Fnum, 8, 9, 10    \
253     }                                                                \
254   }
255 
256 #define CASE_IEILLIIFIIII(Enum, E0, L0, L1, Fstr, Fnum)                  \
257   {                                                                      \
258     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,                       \
259         " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 " Fstr " %8 %9 %10 %11", { \
260       4, uint32_t(DebugInfo##E0), 5, L0, L1, 6, 7, Fnum, 8, 9, 10, 11    \
261     }                                                                    \
262   }
263 
264 #define CASE_IIILLIIIF(Enum, L0, L1, Fstr, Fnum)      \
265   {                                                   \
266     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,    \
267         " %4 %5 %6 " #L0 " " #L1 " %7 %8 %9 " Fstr, { \
268       4, 5, 6, L0, L1, 7, 8, 9, Fnum                  \
269     }                                                 \
270   }
271 
272 #define CASE_IIILLIIIFI(Enum, L0, L1, Fstr, Fnum)            \
273   {                                                          \
274     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,           \
275         " %4 %5 %6 " #L0 " " #L1 " %7 %8 %9 " Fstr " %10", { \
276       4, 5, 6, L0, L1, 7, 8, 9, Fnum, 10                     \
277     }                                                        \
278   }
279 
280 #define CASE_IIIIF(Enum, Fstr, Fnum)                                       \
281   {                                                                        \
282     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 %5 %6 %7 " Fstr, { \
283       4, 5, 6, 7, Fnum                                                     \
284     }                                                                      \
285   }
286 
287 #define CASE_IIILL(Enum, L0, L1)                                               \
288   {                                                                            \
289     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " %4 %5 %6 " #L0 " " #L1, { \
290       4, 5, 6, L0, L1                                                          \
291     }                                                                          \
292   }
293 
294 #define CASE_IIIILL(Enum, L0, L1)                  \
295   {                                                \
296     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, \
297         " %4 %5 %6 %7 " #L0 " " #L1, {             \
298       4, 5, 6, 7, L0, L1                           \
299     }                                              \
300   }
301 
302 #define CASE_IILLI(Enum, L0, L1)                   \
303   {                                                \
304     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, \
305         " %4 %5 " #L0 " " #L1 " %6", {             \
306       4, 5, L0, L1, 6                              \
307     }                                              \
308   }
309 
310 #define CASE_IILLII(Enum, L0, L1)                  \
311   {                                                \
312     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, \
313         " %4 %5 " #L0 " " #L1 " %6 %7", {          \
314       4, 5, L0, L1, 6, 7                           \
315     }                                              \
316   }
317 
318 #define CASE_IILLIII(Enum, L0, L1)                 \
319   {                                                \
320     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, \
321         " %4 %5 " #L0 " " #L1 " %6 %7 %8", {       \
322       4, 5, L0, L1, 6, 7, 8                        \
323     }                                              \
324   }
325 
326 #define CASE_IILLIIII(Enum, L0, L1)                \
327   {                                                \
328     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, \
329         " %4 %5 " #L0 " " #L1 " %6 %7 %8 %9", {    \
330       4, 5, L0, L1, 6, 7, 8, 9                     \
331     }                                              \
332   }
333 
334 #define CASE_IIILLIIFLI(Enum, L0, L1, Fstr, Fnum, L2)            \
335   {                                                              \
336     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,               \
337         " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " " #L2 " %9", { \
338       4, 5, 6, L0, L1, 7, 8, Fnum, L2, 9                         \
339     }                                                            \
340   }
341 
342 #define CASE_IIILLIIFLII(Enum, L0, L1, Fstr, Fnum, L2)               \
343   {                                                                  \
344     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum,                   \
345         " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " " #L2 " %9 %10", { \
346       4, 5, 6, L0, L1, 7, 8, Fnum, L2, 9, 10                         \
347     }                                                                \
348   }
349 
350 #define CASE_E(Enum, E0)                                      \
351   {                                                           \
352     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " " #E0, { \
353       uint32_t(DebugInfo##E0)                                 \
354     }                                                         \
355   }
356 
357 #define CASE_EL(Enum, E0, L0)                                         \
358   {                                                                   \
359     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " " #E0 " " #L0, { \
360       uint32_t(DebugInfo##E0), L0                                     \
361     }                                                                 \
362   }
363 
364 #define CASE_ELL(Enum, E0, L0, L1)                                            \
365   {                                                                           \
366     uint32_t(DebugInfoDebug##Enum), "Debug" #Enum, " " #E0 " " #L0 " " #L1, { \
367       uint32_t(DebugInfo##E0), L0, L1                                         \
368     }                                                                         \
369   }
370 
371 // DebugInfo 4.1 Absent Debugging Information
372 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugInfoNone, ExtInstDebugInfoRoundTripTest,
373                          ::testing::ValuesIn(std::vector<InstructionCase>({
374                              CASE_0(InfoNone),  // enum value 0
375                          })));
376 
377 // DebugInfo 4.2 Compilation Unit
378 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugCompilationUnit,
379                          ExtInstDebugInfoRoundTripTest,
380                          ::testing::ValuesIn(std::vector<InstructionCase>({
381                              CASE_ILL(CompilationUnit, 100, 42),
382                          })));
383 
384 // DebugInfo 4.3 Type instructions
385 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeBasic, ExtInstDebugInfoRoundTripTest,
386                          ::testing::ValuesIn(std::vector<InstructionCase>({
387                              CASE_IIE(TypeBasic, Unspecified),
388                              CASE_IIE(TypeBasic, Address),
389                              CASE_IIE(TypeBasic, Boolean),
390                              CASE_IIE(TypeBasic, Float),
391                              CASE_IIE(TypeBasic, Signed),
392                              CASE_IIE(TypeBasic, SignedChar),
393                              CASE_IIE(TypeBasic, Unsigned),
394                              CASE_IIE(TypeBasic, UnsignedChar),
395                          })));
396 
397 // The FlagIsPublic is value is (1 << 0) | (1 << 2) which is the same
398 // as the bitwise-OR of FlagIsProtected and FlagIsPrivate.
399 // The disassembler will emit the compound expression instead.
400 // There is no simple fix for this.  This enum is not really a mask
401 // for the bottom two bits.
TEST_F(ExtInstDebugInfoRoundTripTestExplicit,FlagIsPublic)402 TEST_F(ExtInstDebugInfoRoundTripTestExplicit, FlagIsPublic) {
403   const std::string prefix =
404       "%1 = OpExtInstImport \"DebugInfo\"\n"
405       "%3 = OpExtInst %2 %1 DebugTypePointer %4 Private ";
406   const std::string input = prefix + "FlagIsPublic\n";
407   const std::string expected = prefix + "FlagIsProtected|FlagIsPrivate\n";
408   // First make sure it assembles correctly.
409   EXPECT_THAT(
410       CompiledInstructions(input),
411       Eq(Concatenate({MakeInstruction(spv::Op::OpExtInstImport, {1},
412                                       MakeVector("DebugInfo")),
413                       MakeInstruction(spv::Op::OpExtInst,
414                                       {2, 3, 1, DebugInfoDebugTypePointer, 4,
415                                        uint32_t(spv::StorageClass::Private),
416                                        DebugInfoFlagIsPublic})})))
417       << input;
418   // Now check the round trip through the disassembler.
419   EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(expected)) << input;
420 }
421 
422 INSTANTIATE_TEST_SUITE_P(
423     DebugInfoDebugTypePointer, ExtInstDebugInfoRoundTripTest,
424     ::testing::ValuesIn(std::vector<InstructionCase>({
425 
426         //// Use each flag independently.
427         CASE_ISF(TypePointer, Private, "FlagIsProtected",
428                  uint32_t(DebugInfoFlagIsProtected)),
429         CASE_ISF(TypePointer, Private, "FlagIsPrivate",
430                  uint32_t(DebugInfoFlagIsPrivate)),
431 
432         // FlagIsPublic is tested above.
433 
434         CASE_ISF(TypePointer, Private, "FlagIsLocal",
435                  uint32_t(DebugInfoFlagIsLocal)),
436         CASE_ISF(TypePointer, Private, "FlagIsDefinition",
437                  uint32_t(DebugInfoFlagIsDefinition)),
438         CASE_ISF(TypePointer, Private, "FlagFwdDecl",
439                  uint32_t(DebugInfoFlagFwdDecl)),
440         CASE_ISF(TypePointer, Private, "FlagArtificial",
441                  uint32_t(DebugInfoFlagArtificial)),
442         CASE_ISF(TypePointer, Private, "FlagExplicit",
443                  uint32_t(DebugInfoFlagExplicit)),
444         CASE_ISF(TypePointer, Private, "FlagPrototyped",
445                  uint32_t(DebugInfoFlagPrototyped)),
446         CASE_ISF(TypePointer, Private, "FlagObjectPointer",
447                  uint32_t(DebugInfoFlagObjectPointer)),
448         CASE_ISF(TypePointer, Private, "FlagStaticMember",
449                  uint32_t(DebugInfoFlagStaticMember)),
450         CASE_ISF(TypePointer, Private, "FlagIndirectVariable",
451                  uint32_t(DebugInfoFlagIndirectVariable)),
452         CASE_ISF(TypePointer, Private, "FlagLValueReference",
453                  uint32_t(DebugInfoFlagLValueReference)),
454         CASE_ISF(TypePointer, Private, "FlagIsOptimized",
455                  uint32_t(DebugInfoFlagIsOptimized)),
456 
457         //// Use flags in combination, and try different storage classes.
458         CASE_ISF(TypePointer, Function, "FlagIsProtected|FlagIsPrivate",
459                  uint32_t(DebugInfoFlagIsProtected) |
460                      uint32_t(DebugInfoFlagIsPrivate)),
461         CASE_ISF(
462             TypePointer, Workgroup,
463             "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized",
464             uint32_t(DebugInfoFlagIsPrivate) | uint32_t(DebugInfoFlagFwdDecl) |
465                 uint32_t(DebugInfoFlagIndirectVariable) |
466                 uint32_t(DebugInfoFlagIsOptimized)),
467 
468     })));
469 
470 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeQualifier,
471                          ExtInstDebugInfoRoundTripTest,
472                          ::testing::ValuesIn(std::vector<InstructionCase>({
473                              CASE_IE(TypeQualifier, ConstType),
474                              CASE_IE(TypeQualifier, VolatileType),
475                              CASE_IE(TypeQualifier, RestrictType),
476                          })));
477 
478 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeArray, ExtInstDebugInfoRoundTripTest,
479                          ::testing::ValuesIn(std::vector<InstructionCase>({
480                              CASE_II(TypeArray),
481                              CASE_III(TypeArray),
482                              CASE_IIII(TypeArray),
483                              CASE_IIIII(TypeArray),
484                          })));
485 
486 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeVector,
487                          ExtInstDebugInfoRoundTripTest,
488                          ::testing::ValuesIn(std::vector<InstructionCase>({
489                              CASE_IL(TypeVector, 2),
490                              CASE_IL(TypeVector, 3),
491                              CASE_IL(TypeVector, 4),
492                              CASE_IL(TypeVector, 16),
493                          })));
494 
495 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypedef, ExtInstDebugInfoRoundTripTest,
496                          ::testing::ValuesIn(std::vector<InstructionCase>({
497                              CASE_IIILLI(Typedef, 12, 13),
498                              CASE_IIILLI(Typedef, 14, 99),
499                          })));
500 
501 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeFunction,
502                          ExtInstDebugInfoRoundTripTest,
503                          ::testing::ValuesIn(std::vector<InstructionCase>({
504                              CASE_I(TypeFunction),
505                              CASE_II(TypeFunction),
506                              CASE_III(TypeFunction),
507                              CASE_IIII(TypeFunction),
508                              CASE_IIIII(TypeFunction),
509                          })));
510 
511 INSTANTIATE_TEST_SUITE_P(
512     DebugInfoDebugTypeEnum, ExtInstDebugInfoRoundTripTest,
513     ::testing::ValuesIn(std::vector<InstructionCase>({
514         CASE_IIILLIIFII(
515             TypeEnum, 12, 13,
516             "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized",
517             uint32_t(DebugInfoFlagIsPrivate) | uint32_t(DebugInfoFlagFwdDecl) |
518                 uint32_t(DebugInfoFlagIndirectVariable) |
519                 uint32_t(DebugInfoFlagIsOptimized)),
520         CASE_IIILLIIFIIII(TypeEnum, 17, 18, "FlagStaticMember",
521                           uint32_t(DebugInfoFlagStaticMember)),
522         CASE_IIILLIIFIIIIII(TypeEnum, 99, 1, "FlagStaticMember",
523                             uint32_t(DebugInfoFlagStaticMember)),
524     })));
525 
526 INSTANTIATE_TEST_SUITE_P(
527     DebugInfoDebugTypeComposite, ExtInstDebugInfoRoundTripTest,
528     ::testing::ValuesIn(std::vector<InstructionCase>({
529         CASE_IEILLIIF(
530             TypeComposite, Class, 12, 13,
531             "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized",
532             uint32_t(DebugInfoFlagIsPrivate) | uint32_t(DebugInfoFlagFwdDecl) |
533                 uint32_t(DebugInfoFlagIndirectVariable) |
534                 uint32_t(DebugInfoFlagIsOptimized)),
535         // Cover all tag values: Class, Structure, Union
536         CASE_IEILLIIF(TypeComposite, Class, 12, 13, "FlagIsPrivate",
537                       uint32_t(DebugInfoFlagIsPrivate)),
538         CASE_IEILLIIF(TypeComposite, Structure, 12, 13, "FlagIsPrivate",
539                       uint32_t(DebugInfoFlagIsPrivate)),
540         CASE_IEILLIIF(TypeComposite, Union, 12, 13, "FlagIsPrivate",
541                       uint32_t(DebugInfoFlagIsPrivate)),
542         // Now add members
543         CASE_IEILLIIFI(TypeComposite, Class, 9, 10, "FlagIsPrivate",
544                        uint32_t(DebugInfoFlagIsPrivate)),
545         CASE_IEILLIIFII(TypeComposite, Class, 9, 10, "FlagIsPrivate",
546                         uint32_t(DebugInfoFlagIsPrivate)),
547         CASE_IEILLIIFIII(TypeComposite, Class, 9, 10, "FlagIsPrivate",
548                          uint32_t(DebugInfoFlagIsPrivate)),
549         CASE_IEILLIIFIIII(TypeComposite, Class, 9, 10, "FlagIsPrivate",
550                           uint32_t(DebugInfoFlagIsPrivate)),
551     })));
552 
553 INSTANTIATE_TEST_SUITE_P(
554     DebugInfoDebugTypeMember, ExtInstDebugInfoRoundTripTest,
555     ::testing::ValuesIn(std::vector<InstructionCase>({
556         CASE_IIILLIIIF(TypeMember, 12, 13, "FlagIsPrivate",
557                        uint32_t(DebugInfoFlagIsPrivate)),
558         CASE_IIILLIIIF(TypeMember, 99, 100, "FlagIsPrivate|FlagFwdDecl",
559                        uint32_t(DebugInfoFlagIsPrivate) |
560                            uint32_t(DebugInfoFlagFwdDecl)),
561         // Add the optional Id argument.
562         CASE_IIILLIIIFI(TypeMember, 12, 13, "FlagIsPrivate",
563                         uint32_t(DebugInfoFlagIsPrivate)),
564     })));
565 
566 INSTANTIATE_TEST_SUITE_P(
567     DebugInfoDebugTypeInheritance, ExtInstDebugInfoRoundTripTest,
568     ::testing::ValuesIn(std::vector<InstructionCase>({
569         CASE_IIIIF(TypeInheritance, "FlagIsPrivate",
570                    uint32_t(DebugInfoFlagIsPrivate)),
571         CASE_IIIIF(TypeInheritance, "FlagIsPrivate|FlagFwdDecl",
572                    uint32_t(DebugInfoFlagIsPrivate) |
573                        uint32_t(DebugInfoFlagFwdDecl)),
574     })));
575 
576 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypePtrToMember,
577                          ExtInstDebugInfoRoundTripTest,
578                          ::testing::ValuesIn(std::vector<InstructionCase>({
579                              CASE_II(TypePtrToMember),
580                          })));
581 
582 // DebugInfo 4.4 Templates
583 
584 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeTemplate,
585                          ExtInstDebugInfoRoundTripTest,
586                          ::testing::ValuesIn(std::vector<InstructionCase>({
587                              CASE_II(TypeTemplate),
588                              CASE_III(TypeTemplate),
589                              CASE_IIII(TypeTemplate),
590                              CASE_IIIII(TypeTemplate),
591                          })));
592 
593 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeTemplateParameter,
594                          ExtInstDebugInfoRoundTripTest,
595                          ::testing::ValuesIn(std::vector<InstructionCase>({
596                              CASE_IIIILL(TypeTemplateParameter, 1, 2),
597                              CASE_IIIILL(TypeTemplateParameter, 99, 102),
598                              CASE_IIIILL(TypeTemplateParameter, 10, 7),
599                          })));
600 
601 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeTemplateTemplateParameter,
602                          ExtInstDebugInfoRoundTripTest,
603                          ::testing::ValuesIn(std::vector<InstructionCase>({
604                              CASE_IIILL(TypeTemplateTemplateParameter, 1, 2),
605                              CASE_IIILL(TypeTemplateTemplateParameter, 99, 102),
606                              CASE_IIILL(TypeTemplateTemplateParameter, 10, 7),
607                          })));
608 
609 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeTemplateParameterPack,
610                          ExtInstDebugInfoRoundTripTest,
611                          ::testing::ValuesIn(std::vector<InstructionCase>({
612                              CASE_IILLI(TypeTemplateParameterPack, 1, 2),
613                              CASE_IILLII(TypeTemplateParameterPack, 99, 102),
614                              CASE_IILLIII(TypeTemplateParameterPack, 10, 7),
615                              CASE_IILLIIII(TypeTemplateParameterPack, 10, 7),
616                          })));
617 
618 // DebugInfo 4.5 Global Variables
619 
620 INSTANTIATE_TEST_SUITE_P(
621     DebugInfoDebugGlobalVariable, ExtInstDebugInfoRoundTripTest,
622     ::testing::ValuesIn(std::vector<InstructionCase>({
623         CASE_IIILLIIIF(GlobalVariable, 1, 2, "FlagIsOptimized",
624                        uint32_t(DebugInfoFlagIsOptimized)),
625         CASE_IIILLIIIF(GlobalVariable, 42, 43, "FlagIsOptimized",
626                        uint32_t(DebugInfoFlagIsOptimized)),
627         CASE_IIILLIIIFI(GlobalVariable, 1, 2, "FlagIsOptimized",
628                         uint32_t(DebugInfoFlagIsOptimized)),
629         CASE_IIILLIIIFI(GlobalVariable, 42, 43, "FlagIsOptimized",
630                         uint32_t(DebugInfoFlagIsOptimized)),
631     })));
632 
633 // DebugInfo 4.6 Functions
634 
635 INSTANTIATE_TEST_SUITE_P(
636     DebugInfoDebugFunctionDeclaration, ExtInstDebugInfoRoundTripTest,
637     ::testing::ValuesIn(std::vector<InstructionCase>({
638         CASE_IIILLIIF(FunctionDeclaration, 1, 2, "FlagIsOptimized",
639                       uint32_t(DebugInfoFlagIsOptimized)),
640         CASE_IIILLIIF(FunctionDeclaration, 42, 43, "FlagFwdDecl",
641                       uint32_t(DebugInfoFlagFwdDecl)),
642     })));
643 
644 INSTANTIATE_TEST_SUITE_P(
645     DebugInfoDebugFunction, ExtInstDebugInfoRoundTripTest,
646     ::testing::ValuesIn(std::vector<InstructionCase>({
647         CASE_IIILLIIFLI(Function, 1, 2, "FlagIsOptimized",
648                         uint32_t(DebugInfoFlagIsOptimized), 3),
649         CASE_IIILLIIFLI(Function, 42, 43, "FlagFwdDecl",
650                         uint32_t(DebugInfoFlagFwdDecl), 44),
651         // Add the optional declaration Id.
652         CASE_IIILLIIFLII(Function, 1, 2, "FlagIsOptimized",
653                          uint32_t(DebugInfoFlagIsOptimized), 3),
654         CASE_IIILLIIFLII(Function, 42, 43, "FlagFwdDecl",
655                          uint32_t(DebugInfoFlagFwdDecl), 44),
656     })));
657 
658 // DebugInfo 4.7 Local Information
659 
660 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugLexicalBlock,
661                          ExtInstDebugInfoRoundTripTest,
662                          ::testing::ValuesIn(std::vector<InstructionCase>({
663                              CASE_ILLII(LexicalBlock, 1, 2),
664                              CASE_ILLII(LexicalBlock, 42, 43),
665                          })));
666 
667 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugLexicalBlockDiscriminator,
668                          ExtInstDebugInfoRoundTripTest,
669                          ::testing::ValuesIn(std::vector<InstructionCase>({
670                              CASE_ILI(LexicalBlockDiscriminator, 1),
671                              CASE_ILI(LexicalBlockDiscriminator, 42),
672                          })));
673 
674 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugScope, ExtInstDebugInfoRoundTripTest,
675                          ::testing::ValuesIn(std::vector<InstructionCase>({
676                              CASE_I(Scope),
677                              CASE_II(Scope),
678                          })));
679 
680 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugNoScope, ExtInstDebugInfoRoundTripTest,
681                          ::testing::ValuesIn(std::vector<InstructionCase>({
682                              CASE_0(NoScope),
683                          })));
684 
685 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugInlinedAt, ExtInstDebugInfoRoundTripTest,
686                          ::testing::ValuesIn(std::vector<InstructionCase>({
687                              CASE_LII(InlinedAt, 1),
688                              CASE_LII(InlinedAt, 42),
689                          })));
690 
691 // DebugInfo 4.8 Local Variables
692 
693 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugLocalVariable,
694                          ExtInstDebugInfoRoundTripTest,
695                          ::testing::ValuesIn(std::vector<InstructionCase>({
696                              CASE_IIILLI(LocalVariable, 1, 2),
697                              CASE_IIILLI(LocalVariable, 42, 43),
698                              CASE_IIILLIL(LocalVariable, 1, 2, 3),
699                              CASE_IIILLIL(LocalVariable, 42, 43, 44),
700                          })));
701 
702 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugInlinedVariable,
703                          ExtInstDebugInfoRoundTripTest,
704                          ::testing::ValuesIn(std::vector<InstructionCase>({
705                              CASE_II(InlinedVariable),
706                          })));
707 
708 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugDebugDeclare,
709                          ExtInstDebugInfoRoundTripTest,
710                          ::testing::ValuesIn(std::vector<InstructionCase>({
711                              CASE_III(Declare),
712                          })));
713 
714 INSTANTIATE_TEST_SUITE_P(
715     DebugInfoDebugDebugValue, ExtInstDebugInfoRoundTripTest,
716     ::testing::ValuesIn(std::vector<InstructionCase>({
717         CASE_III(Value),
718         CASE_IIII(Value),
719         CASE_IIIII(Value),
720         CASE_IIIIII(Value),
721         // Test up to 4 id parameters. We can always try more.
722         CASE_IIIIIII(Value),
723     })));
724 
725 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugDebugOperation,
726                          ExtInstDebugInfoRoundTripTest,
727                          ::testing::ValuesIn(std::vector<InstructionCase>({
728                              CASE_E(Operation, Deref),
729                              CASE_E(Operation, Plus),
730                              CASE_E(Operation, Minus),
731                              CASE_EL(Operation, PlusUconst, 1),
732                              CASE_EL(Operation, PlusUconst, 42),
733                              CASE_ELL(Operation, BitPiece, 1, 2),
734                              CASE_ELL(Operation, BitPiece, 4, 5),
735                              CASE_E(Operation, Swap),
736                              CASE_E(Operation, Xderef),
737                              CASE_E(Operation, StackValue),
738                              CASE_EL(Operation, Constu, 1),
739                              CASE_EL(Operation, Constu, 42),
740                          })));
741 
742 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugDebugExpression,
743                          ExtInstDebugInfoRoundTripTest,
744                          ::testing::ValuesIn(std::vector<InstructionCase>({
745                              CASE_0(Expression),
746                              CASE_I(Expression),
747                              CASE_II(Expression),
748                              CASE_III(Expression),
749                              CASE_IIII(Expression),
750                              CASE_IIIII(Expression),
751                              CASE_IIIIII(Expression),
752                              CASE_IIIIIII(Expression),
753                          })));
754 
755 // DebugInfo 4.9 Macros
756 
757 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugMacroDef, ExtInstDebugInfoRoundTripTest,
758                          ::testing::ValuesIn(std::vector<InstructionCase>({
759                              CASE_ILI(MacroDef, 1),
760                              CASE_ILI(MacroDef, 42),
761                              CASE_ILII(MacroDef, 1),
762                              CASE_ILII(MacroDef, 42),
763                          })));
764 
765 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugMacroUndef,
766                          ExtInstDebugInfoRoundTripTest,
767                          ::testing::ValuesIn(std::vector<InstructionCase>({
768                              CASE_ILI(MacroUndef, 1),
769                              CASE_ILI(MacroUndef, 42),
770                          })));
771 
772 #undef CASE_0
773 #undef CASE_ILL
774 #undef CASE_IL
775 #undef CASE_I
776 #undef CASE_II
777 #undef CASE_III
778 #undef CASE_IIII
779 #undef CASE_IIIII
780 #undef CASE_IIIIII
781 #undef CASE_IIIIIII
782 #undef CASE_IIILLI
783 #undef CASE_IIILLIL
784 #undef CASE_IE
785 #undef CASE_IIE
786 #undef CASE_ISF
787 #undef CASE_LII
788 #undef CASE_ILI
789 #undef CASE_ILII
790 #undef CASE_ILLII
791 #undef CASE_IIILLIIF
792 #undef CASE_IIILLIIFII
793 #undef CASE_IIILLIIFIIII
794 #undef CASE_IIILLIIFIIIIII
795 #undef CASE_IEILLIIF
796 #undef CASE_IEILLIIFI
797 #undef CASE_IEILLIIFII
798 #undef CASE_IEILLIIFIII
799 #undef CASE_IEILLIIFIIII
800 #undef CASE_IIILLIIIF
801 #undef CASE_IIILLIIIFI
802 #undef CASE_IIIIF
803 #undef CASE_IIILL
804 #undef CASE_IIIILL
805 #undef CASE_IILLI
806 #undef CASE_IILLII
807 #undef CASE_IILLIII
808 #undef CASE_IILLIIII
809 #undef CASE_IIILLIIFLI
810 #undef CASE_IIILLIIFLII
811 #undef CASE_E
812 #undef CASE_EL
813 #undef CASE_ELL
814 
815 }  // namespace
816 }  // namespace spvtools
817