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