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
30namespace spvtools {
31namespace {
32
33using spvtest::Concatenate;
34using spvtest::MakeInstruction;
35using utils::MakeVector;
36using testing::Eq;
37
38struct InstructionCase {
39  uint32_t opcode;
40  std::string name;
41  std::string operands;
42  std::vector<uint32_t> expected_operands;
43};
44
45using ExtInstDebugInfoRoundTripTest =
46    spvtest::TextToBinaryTestBase<::testing::TestWithParam<InstructionCase>>;
47using ExtInstDebugInfoRoundTripTestExplicit = spvtest::TextToBinaryTest;
48
49TEST_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
372INSTANTIATE_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
378INSTANTIATE_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
385INSTANTIATE_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.
402TEST_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
422INSTANTIATE_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
470INSTANTIATE_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
478INSTANTIATE_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
486INSTANTIATE_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
495INSTANTIATE_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
501INSTANTIATE_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
511INSTANTIATE_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
526INSTANTIATE_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
553INSTANTIATE_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
566INSTANTIATE_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
576INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypePtrToMember,
577                         ExtInstDebugInfoRoundTripTest,
578                         ::testing::ValuesIn(std::vector<InstructionCase>({
579                             CASE_II(TypePtrToMember),
580                         })));
581
582// DebugInfo 4.4 Templates
583
584INSTANTIATE_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
593INSTANTIATE_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
601INSTANTIATE_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
609INSTANTIATE_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
620INSTANTIATE_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
635INSTANTIATE_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
644INSTANTIATE_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
660INSTANTIATE_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
667INSTANTIATE_TEST_SUITE_P(DebugInfoDebugLexicalBlockDiscriminator,
668                         ExtInstDebugInfoRoundTripTest,
669                         ::testing::ValuesIn(std::vector<InstructionCase>({
670                             CASE_ILI(LexicalBlockDiscriminator, 1),
671                             CASE_ILI(LexicalBlockDiscriminator, 42),
672                         })));
673
674INSTANTIATE_TEST_SUITE_P(DebugInfoDebugScope, ExtInstDebugInfoRoundTripTest,
675                         ::testing::ValuesIn(std::vector<InstructionCase>({
676                             CASE_I(Scope),
677                             CASE_II(Scope),
678                         })));
679
680INSTANTIATE_TEST_SUITE_P(DebugInfoDebugNoScope, ExtInstDebugInfoRoundTripTest,
681                         ::testing::ValuesIn(std::vector<InstructionCase>({
682                             CASE_0(NoScope),
683                         })));
684
685INSTANTIATE_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
693INSTANTIATE_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
702INSTANTIATE_TEST_SUITE_P(DebugInfoDebugInlinedVariable,
703                         ExtInstDebugInfoRoundTripTest,
704                         ::testing::ValuesIn(std::vector<InstructionCase>({
705                             CASE_II(InlinedVariable),
706                         })));
707
708INSTANTIATE_TEST_SUITE_P(DebugInfoDebugDebugDeclare,
709                         ExtInstDebugInfoRoundTripTest,
710                         ::testing::ValuesIn(std::vector<InstructionCase>({
711                             CASE_III(Declare),
712                         })));
713
714INSTANTIATE_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
725INSTANTIATE_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
742INSTANTIATE_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
757INSTANTIATE_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
765INSTANTIATE_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