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