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(
56 CompiledInstructions(input),
57 Eq(Concatenate(
58 {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("DebugInfo")),
59 MakeInstruction(SpvOpExtInst, {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(SpvStorageClass##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(
412 {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("DebugInfo")),
413 MakeInstruction(SpvOpExtInst, {2, 3, 1, DebugInfoDebugTypePointer, 4,
414 uint32_t(SpvStorageClassPrivate),
415 DebugInfoFlagIsPublic})})))
416 << input;
417 // Now check the round trip through the disassembler.
418 EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(expected)) << input;
419 }
420
421 INSTANTIATE_TEST_SUITE_P(
422 DebugInfoDebugTypePointer, ExtInstDebugInfoRoundTripTest,
423 ::testing::ValuesIn(std::vector<InstructionCase>({
424
425 //// Use each flag independently.
426 CASE_ISF(TypePointer, Private, "FlagIsProtected",
427 uint32_t(DebugInfoFlagIsProtected)),
428 CASE_ISF(TypePointer, Private, "FlagIsPrivate",
429 uint32_t(DebugInfoFlagIsPrivate)),
430
431 // FlagIsPublic is tested above.
432
433 CASE_ISF(TypePointer, Private, "FlagIsLocal",
434 uint32_t(DebugInfoFlagIsLocal)),
435 CASE_ISF(TypePointer, Private, "FlagIsDefinition",
436 uint32_t(DebugInfoFlagIsDefinition)),
437 CASE_ISF(TypePointer, Private, "FlagFwdDecl",
438 uint32_t(DebugInfoFlagFwdDecl)),
439 CASE_ISF(TypePointer, Private, "FlagArtificial",
440 uint32_t(DebugInfoFlagArtificial)),
441 CASE_ISF(TypePointer, Private, "FlagExplicit",
442 uint32_t(DebugInfoFlagExplicit)),
443 CASE_ISF(TypePointer, Private, "FlagPrototyped",
444 uint32_t(DebugInfoFlagPrototyped)),
445 CASE_ISF(TypePointer, Private, "FlagObjectPointer",
446 uint32_t(DebugInfoFlagObjectPointer)),
447 CASE_ISF(TypePointer, Private, "FlagStaticMember",
448 uint32_t(DebugInfoFlagStaticMember)),
449 CASE_ISF(TypePointer, Private, "FlagIndirectVariable",
450 uint32_t(DebugInfoFlagIndirectVariable)),
451 CASE_ISF(TypePointer, Private, "FlagLValueReference",
452 uint32_t(DebugInfoFlagLValueReference)),
453 CASE_ISF(TypePointer, Private, "FlagIsOptimized",
454 uint32_t(DebugInfoFlagIsOptimized)),
455
456 //// Use flags in combination, and try different storage classes.
457 CASE_ISF(TypePointer, Function, "FlagIsProtected|FlagIsPrivate",
458 uint32_t(DebugInfoFlagIsProtected) |
459 uint32_t(DebugInfoFlagIsPrivate)),
460 CASE_ISF(
461 TypePointer, Workgroup,
462 "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized",
463 uint32_t(DebugInfoFlagIsPrivate) | uint32_t(DebugInfoFlagFwdDecl) |
464 uint32_t(DebugInfoFlagIndirectVariable) |
465 uint32_t(DebugInfoFlagIsOptimized)),
466
467 })));
468
469 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeQualifier,
470 ExtInstDebugInfoRoundTripTest,
471 ::testing::ValuesIn(std::vector<InstructionCase>({
472 CASE_IE(TypeQualifier, ConstType),
473 CASE_IE(TypeQualifier, VolatileType),
474 CASE_IE(TypeQualifier, RestrictType),
475 })));
476
477 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeArray, ExtInstDebugInfoRoundTripTest,
478 ::testing::ValuesIn(std::vector<InstructionCase>({
479 CASE_II(TypeArray),
480 CASE_III(TypeArray),
481 CASE_IIII(TypeArray),
482 CASE_IIIII(TypeArray),
483 })));
484
485 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeVector,
486 ExtInstDebugInfoRoundTripTest,
487 ::testing::ValuesIn(std::vector<InstructionCase>({
488 CASE_IL(TypeVector, 2),
489 CASE_IL(TypeVector, 3),
490 CASE_IL(TypeVector, 4),
491 CASE_IL(TypeVector, 16),
492 })));
493
494 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypedef, ExtInstDebugInfoRoundTripTest,
495 ::testing::ValuesIn(std::vector<InstructionCase>({
496 CASE_IIILLI(Typedef, 12, 13),
497 CASE_IIILLI(Typedef, 14, 99),
498 })));
499
500 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeFunction,
501 ExtInstDebugInfoRoundTripTest,
502 ::testing::ValuesIn(std::vector<InstructionCase>({
503 CASE_I(TypeFunction),
504 CASE_II(TypeFunction),
505 CASE_III(TypeFunction),
506 CASE_IIII(TypeFunction),
507 CASE_IIIII(TypeFunction),
508 })));
509
510 INSTANTIATE_TEST_SUITE_P(
511 DebugInfoDebugTypeEnum, ExtInstDebugInfoRoundTripTest,
512 ::testing::ValuesIn(std::vector<InstructionCase>({
513 CASE_IIILLIIFII(
514 TypeEnum, 12, 13,
515 "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized",
516 uint32_t(DebugInfoFlagIsPrivate) | uint32_t(DebugInfoFlagFwdDecl) |
517 uint32_t(DebugInfoFlagIndirectVariable) |
518 uint32_t(DebugInfoFlagIsOptimized)),
519 CASE_IIILLIIFIIII(TypeEnum, 17, 18, "FlagStaticMember",
520 uint32_t(DebugInfoFlagStaticMember)),
521 CASE_IIILLIIFIIIIII(TypeEnum, 99, 1, "FlagStaticMember",
522 uint32_t(DebugInfoFlagStaticMember)),
523 })));
524
525 INSTANTIATE_TEST_SUITE_P(
526 DebugInfoDebugTypeComposite, ExtInstDebugInfoRoundTripTest,
527 ::testing::ValuesIn(std::vector<InstructionCase>({
528 CASE_IEILLIIF(
529 TypeComposite, Class, 12, 13,
530 "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized",
531 uint32_t(DebugInfoFlagIsPrivate) | uint32_t(DebugInfoFlagFwdDecl) |
532 uint32_t(DebugInfoFlagIndirectVariable) |
533 uint32_t(DebugInfoFlagIsOptimized)),
534 // Cover all tag values: Class, Structure, Union
535 CASE_IEILLIIF(TypeComposite, Class, 12, 13, "FlagIsPrivate",
536 uint32_t(DebugInfoFlagIsPrivate)),
537 CASE_IEILLIIF(TypeComposite, Structure, 12, 13, "FlagIsPrivate",
538 uint32_t(DebugInfoFlagIsPrivate)),
539 CASE_IEILLIIF(TypeComposite, Union, 12, 13, "FlagIsPrivate",
540 uint32_t(DebugInfoFlagIsPrivate)),
541 // Now add members
542 CASE_IEILLIIFI(TypeComposite, Class, 9, 10, "FlagIsPrivate",
543 uint32_t(DebugInfoFlagIsPrivate)),
544 CASE_IEILLIIFII(TypeComposite, Class, 9, 10, "FlagIsPrivate",
545 uint32_t(DebugInfoFlagIsPrivate)),
546 CASE_IEILLIIFIII(TypeComposite, Class, 9, 10, "FlagIsPrivate",
547 uint32_t(DebugInfoFlagIsPrivate)),
548 CASE_IEILLIIFIIII(TypeComposite, Class, 9, 10, "FlagIsPrivate",
549 uint32_t(DebugInfoFlagIsPrivate)),
550 })));
551
552 INSTANTIATE_TEST_SUITE_P(
553 DebugInfoDebugTypeMember, ExtInstDebugInfoRoundTripTest,
554 ::testing::ValuesIn(std::vector<InstructionCase>({
555 CASE_IIILLIIIF(TypeMember, 12, 13, "FlagIsPrivate",
556 uint32_t(DebugInfoFlagIsPrivate)),
557 CASE_IIILLIIIF(TypeMember, 99, 100, "FlagIsPrivate|FlagFwdDecl",
558 uint32_t(DebugInfoFlagIsPrivate) |
559 uint32_t(DebugInfoFlagFwdDecl)),
560 // Add the optional Id argument.
561 CASE_IIILLIIIFI(TypeMember, 12, 13, "FlagIsPrivate",
562 uint32_t(DebugInfoFlagIsPrivate)),
563 })));
564
565 INSTANTIATE_TEST_SUITE_P(
566 DebugInfoDebugTypeInheritance, ExtInstDebugInfoRoundTripTest,
567 ::testing::ValuesIn(std::vector<InstructionCase>({
568 CASE_IIIIF(TypeInheritance, "FlagIsPrivate",
569 uint32_t(DebugInfoFlagIsPrivate)),
570 CASE_IIIIF(TypeInheritance, "FlagIsPrivate|FlagFwdDecl",
571 uint32_t(DebugInfoFlagIsPrivate) |
572 uint32_t(DebugInfoFlagFwdDecl)),
573 })));
574
575 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypePtrToMember,
576 ExtInstDebugInfoRoundTripTest,
577 ::testing::ValuesIn(std::vector<InstructionCase>({
578 CASE_II(TypePtrToMember),
579 })));
580
581 // DebugInfo 4.4 Templates
582
583 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeTemplate,
584 ExtInstDebugInfoRoundTripTest,
585 ::testing::ValuesIn(std::vector<InstructionCase>({
586 CASE_II(TypeTemplate),
587 CASE_III(TypeTemplate),
588 CASE_IIII(TypeTemplate),
589 CASE_IIIII(TypeTemplate),
590 })));
591
592 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeTemplateParameter,
593 ExtInstDebugInfoRoundTripTest,
594 ::testing::ValuesIn(std::vector<InstructionCase>({
595 CASE_IIIILL(TypeTemplateParameter, 1, 2),
596 CASE_IIIILL(TypeTemplateParameter, 99, 102),
597 CASE_IIIILL(TypeTemplateParameter, 10, 7),
598 })));
599
600 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeTemplateTemplateParameter,
601 ExtInstDebugInfoRoundTripTest,
602 ::testing::ValuesIn(std::vector<InstructionCase>({
603 CASE_IIILL(TypeTemplateTemplateParameter, 1, 2),
604 CASE_IIILL(TypeTemplateTemplateParameter, 99, 102),
605 CASE_IIILL(TypeTemplateTemplateParameter, 10, 7),
606 })));
607
608 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugTypeTemplateParameterPack,
609 ExtInstDebugInfoRoundTripTest,
610 ::testing::ValuesIn(std::vector<InstructionCase>({
611 CASE_IILLI(TypeTemplateParameterPack, 1, 2),
612 CASE_IILLII(TypeTemplateParameterPack, 99, 102),
613 CASE_IILLIII(TypeTemplateParameterPack, 10, 7),
614 CASE_IILLIIII(TypeTemplateParameterPack, 10, 7),
615 })));
616
617 // DebugInfo 4.5 Global Variables
618
619 INSTANTIATE_TEST_SUITE_P(
620 DebugInfoDebugGlobalVariable, ExtInstDebugInfoRoundTripTest,
621 ::testing::ValuesIn(std::vector<InstructionCase>({
622 CASE_IIILLIIIF(GlobalVariable, 1, 2, "FlagIsOptimized",
623 uint32_t(DebugInfoFlagIsOptimized)),
624 CASE_IIILLIIIF(GlobalVariable, 42, 43, "FlagIsOptimized",
625 uint32_t(DebugInfoFlagIsOptimized)),
626 CASE_IIILLIIIFI(GlobalVariable, 1, 2, "FlagIsOptimized",
627 uint32_t(DebugInfoFlagIsOptimized)),
628 CASE_IIILLIIIFI(GlobalVariable, 42, 43, "FlagIsOptimized",
629 uint32_t(DebugInfoFlagIsOptimized)),
630 })));
631
632 // DebugInfo 4.6 Functions
633
634 INSTANTIATE_TEST_SUITE_P(
635 DebugInfoDebugFunctionDeclaration, ExtInstDebugInfoRoundTripTest,
636 ::testing::ValuesIn(std::vector<InstructionCase>({
637 CASE_IIILLIIF(FunctionDeclaration, 1, 2, "FlagIsOptimized",
638 uint32_t(DebugInfoFlagIsOptimized)),
639 CASE_IIILLIIF(FunctionDeclaration, 42, 43, "FlagFwdDecl",
640 uint32_t(DebugInfoFlagFwdDecl)),
641 })));
642
643 INSTANTIATE_TEST_SUITE_P(
644 DebugInfoDebugFunction, ExtInstDebugInfoRoundTripTest,
645 ::testing::ValuesIn(std::vector<InstructionCase>({
646 CASE_IIILLIIFLI(Function, 1, 2, "FlagIsOptimized",
647 uint32_t(DebugInfoFlagIsOptimized), 3),
648 CASE_IIILLIIFLI(Function, 42, 43, "FlagFwdDecl",
649 uint32_t(DebugInfoFlagFwdDecl), 44),
650 // Add the optional declaration Id.
651 CASE_IIILLIIFLII(Function, 1, 2, "FlagIsOptimized",
652 uint32_t(DebugInfoFlagIsOptimized), 3),
653 CASE_IIILLIIFLII(Function, 42, 43, "FlagFwdDecl",
654 uint32_t(DebugInfoFlagFwdDecl), 44),
655 })));
656
657 // DebugInfo 4.7 Local Information
658
659 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugLexicalBlock,
660 ExtInstDebugInfoRoundTripTest,
661 ::testing::ValuesIn(std::vector<InstructionCase>({
662 CASE_ILLII(LexicalBlock, 1, 2),
663 CASE_ILLII(LexicalBlock, 42, 43),
664 })));
665
666 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugLexicalBlockDiscriminator,
667 ExtInstDebugInfoRoundTripTest,
668 ::testing::ValuesIn(std::vector<InstructionCase>({
669 CASE_ILI(LexicalBlockDiscriminator, 1),
670 CASE_ILI(LexicalBlockDiscriminator, 42),
671 })));
672
673 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugScope, ExtInstDebugInfoRoundTripTest,
674 ::testing::ValuesIn(std::vector<InstructionCase>({
675 CASE_I(Scope),
676 CASE_II(Scope),
677 })));
678
679 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugNoScope, ExtInstDebugInfoRoundTripTest,
680 ::testing::ValuesIn(std::vector<InstructionCase>({
681 CASE_0(NoScope),
682 })));
683
684 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugInlinedAt, ExtInstDebugInfoRoundTripTest,
685 ::testing::ValuesIn(std::vector<InstructionCase>({
686 CASE_LII(InlinedAt, 1),
687 CASE_LII(InlinedAt, 42),
688 })));
689
690 // DebugInfo 4.8 Local Variables
691
692 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugLocalVariable,
693 ExtInstDebugInfoRoundTripTest,
694 ::testing::ValuesIn(std::vector<InstructionCase>({
695 CASE_IIILLI(LocalVariable, 1, 2),
696 CASE_IIILLI(LocalVariable, 42, 43),
697 CASE_IIILLIL(LocalVariable, 1, 2, 3),
698 CASE_IIILLIL(LocalVariable, 42, 43, 44),
699 })));
700
701 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugInlinedVariable,
702 ExtInstDebugInfoRoundTripTest,
703 ::testing::ValuesIn(std::vector<InstructionCase>({
704 CASE_II(InlinedVariable),
705 })));
706
707 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugDebugDeclare,
708 ExtInstDebugInfoRoundTripTest,
709 ::testing::ValuesIn(std::vector<InstructionCase>({
710 CASE_III(Declare),
711 })));
712
713 INSTANTIATE_TEST_SUITE_P(
714 DebugInfoDebugDebugValue, ExtInstDebugInfoRoundTripTest,
715 ::testing::ValuesIn(std::vector<InstructionCase>({
716 CASE_III(Value),
717 CASE_IIII(Value),
718 CASE_IIIII(Value),
719 CASE_IIIIII(Value),
720 // Test up to 4 id parameters. We can always try more.
721 CASE_IIIIIII(Value),
722 })));
723
724 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugDebugOperation,
725 ExtInstDebugInfoRoundTripTest,
726 ::testing::ValuesIn(std::vector<InstructionCase>({
727 CASE_E(Operation, Deref),
728 CASE_E(Operation, Plus),
729 CASE_E(Operation, Minus),
730 CASE_EL(Operation, PlusUconst, 1),
731 CASE_EL(Operation, PlusUconst, 42),
732 CASE_ELL(Operation, BitPiece, 1, 2),
733 CASE_ELL(Operation, BitPiece, 4, 5),
734 CASE_E(Operation, Swap),
735 CASE_E(Operation, Xderef),
736 CASE_E(Operation, StackValue),
737 CASE_EL(Operation, Constu, 1),
738 CASE_EL(Operation, Constu, 42),
739 })));
740
741 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugDebugExpression,
742 ExtInstDebugInfoRoundTripTest,
743 ::testing::ValuesIn(std::vector<InstructionCase>({
744 CASE_0(Expression),
745 CASE_I(Expression),
746 CASE_II(Expression),
747 CASE_III(Expression),
748 CASE_IIII(Expression),
749 CASE_IIIII(Expression),
750 CASE_IIIIII(Expression),
751 CASE_IIIIIII(Expression),
752 })));
753
754 // DebugInfo 4.9 Macros
755
756 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugMacroDef, ExtInstDebugInfoRoundTripTest,
757 ::testing::ValuesIn(std::vector<InstructionCase>({
758 CASE_ILI(MacroDef, 1),
759 CASE_ILI(MacroDef, 42),
760 CASE_ILII(MacroDef, 1),
761 CASE_ILII(MacroDef, 42),
762 })));
763
764 INSTANTIATE_TEST_SUITE_P(DebugInfoDebugMacroUndef,
765 ExtInstDebugInfoRoundTripTest,
766 ::testing::ValuesIn(std::vector<InstructionCase>({
767 CASE_ILI(MacroUndef, 1),
768 CASE_ILI(MacroUndef, 42),
769 })));
770
771 #undef CASE_0
772 #undef CASE_ILL
773 #undef CASE_IL
774 #undef CASE_I
775 #undef CASE_II
776 #undef CASE_III
777 #undef CASE_IIII
778 #undef CASE_IIIII
779 #undef CASE_IIIIII
780 #undef CASE_IIIIIII
781 #undef CASE_IIILLI
782 #undef CASE_IIILLIL
783 #undef CASE_IE
784 #undef CASE_IIE
785 #undef CASE_ISF
786 #undef CASE_LII
787 #undef CASE_ILI
788 #undef CASE_ILII
789 #undef CASE_ILLII
790 #undef CASE_IIILLIIF
791 #undef CASE_IIILLIIFII
792 #undef CASE_IIILLIIFIIII
793 #undef CASE_IIILLIIFIIIIII
794 #undef CASE_IEILLIIF
795 #undef CASE_IEILLIIFI
796 #undef CASE_IEILLIIFII
797 #undef CASE_IEILLIIFIII
798 #undef CASE_IEILLIIFIIII
799 #undef CASE_IIILLIIIF
800 #undef CASE_IIILLIIIFI
801 #undef CASE_IIIIF
802 #undef CASE_IIILL
803 #undef CASE_IIIILL
804 #undef CASE_IILLI
805 #undef CASE_IILLII
806 #undef CASE_IILLIII
807 #undef CASE_IILLIIII
808 #undef CASE_IIILLIIFLI
809 #undef CASE_IIILLIIFLII
810 #undef CASE_E
811 #undef CASE_EL
812 #undef CASE_ELL
813
814 } // namespace
815 } // namespace spvtools
816