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// Tests for unique type declaration rules validator.
16
17#include <string>
18
19#include "source/text.h"
20#include "source/text_handler.h"
21#include "test/test_fixture.h"
22
23namespace spvtools {
24namespace {
25
26using spvtest::ScopedContext;
27
28// Converts code to binary and then back to text.
29spv_result_t ToBinaryAndBack(
30    const std::string& before, std::string* after,
31    uint32_t text_to_binary_options = SPV_TEXT_TO_BINARY_OPTION_NONE,
32    uint32_t binary_to_text_options = SPV_BINARY_TO_TEXT_OPTION_NONE,
33    spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
34  ScopedContext ctx(env);
35  spv_binary binary;
36  spv_text text;
37
38  spv_result_t result =
39      spvTextToBinaryWithOptions(ctx.context, before.c_str(), before.size(),
40                                 text_to_binary_options, &binary, nullptr);
41  if (result != SPV_SUCCESS) {
42    return result;
43  }
44
45  result = spvBinaryToText(ctx.context, binary->code, binary->wordCount,
46                           binary_to_text_options, &text, nullptr);
47  if (result != SPV_SUCCESS) {
48    return result;
49  }
50
51  *after = std::string(text->str, text->length);
52
53  spvBinaryDestroy(binary);
54  spvTextDestroy(text);
55
56  return SPV_SUCCESS;
57}
58
59TEST(ToBinaryAndBack, DontPreserveNumericIds) {
60  const std::string before =
61      R"(OpCapability Addresses
62OpCapability Kernel
63OpCapability GenericPointer
64OpCapability Linkage
65OpMemoryModel Physical32 OpenCL
66%i32 = OpTypeInt 32 1
67%u32 = OpTypeInt 32 0
68%f32 = OpTypeFloat 32
69%200 = OpTypeVoid
70%300 = OpTypeFunction %200
71%main = OpFunction %200 None %300
72%entry = OpLabel
73%100 = OpConstant %u32 100
74%1 = OpConstant %u32 200
75%2 = OpConstant %u32 300
76OpReturn
77OpFunctionEnd
78)";
79
80  const std::string expected =
81      R"(OpCapability Addresses
82OpCapability Kernel
83OpCapability GenericPointer
84OpCapability Linkage
85OpMemoryModel Physical32 OpenCL
86%1 = OpTypeInt 32 1
87%2 = OpTypeInt 32 0
88%3 = OpTypeFloat 32
89%4 = OpTypeVoid
90%5 = OpTypeFunction %4
91%6 = OpFunction %4 None %5
92%7 = OpLabel
93%8 = OpConstant %2 100
94%9 = OpConstant %2 200
95%10 = OpConstant %2 300
96OpReturn
97OpFunctionEnd
98)";
99
100  std::string after;
101  EXPECT_EQ(SPV_SUCCESS,
102            ToBinaryAndBack(before, &after, SPV_TEXT_TO_BINARY_OPTION_NONE,
103                            SPV_BINARY_TO_TEXT_OPTION_NO_HEADER));
104
105  EXPECT_EQ(expected, after);
106}
107
108TEST(TextHandler, PreserveNumericIds) {
109  const std::string before =
110      R"(OpCapability Addresses
111OpCapability Kernel
112OpCapability GenericPointer
113OpCapability Linkage
114OpMemoryModel Physical32 OpenCL
115%i32 = OpTypeInt 32 1
116%u32 = OpTypeInt 32 0
117%f32 = OpTypeFloat 32
118%200 = OpTypeVoid
119%300 = OpTypeFunction %200
120%main = OpFunction %200 None %300
121%entry = OpLabel
122%100 = OpConstant %u32 100
123%1 = OpConstant %u32 200
124%2 = OpConstant %u32 300
125OpReturn
126OpFunctionEnd
127)";
128
129  const std::string expected =
130      R"(OpCapability Addresses
131OpCapability Kernel
132OpCapability GenericPointer
133OpCapability Linkage
134OpMemoryModel Physical32 OpenCL
135%3 = OpTypeInt 32 1
136%4 = OpTypeInt 32 0
137%5 = OpTypeFloat 32
138%200 = OpTypeVoid
139%300 = OpTypeFunction %200
140%6 = OpFunction %200 None %300
141%7 = OpLabel
142%100 = OpConstant %4 100
143%1 = OpConstant %4 200
144%2 = OpConstant %4 300
145OpReturn
146OpFunctionEnd
147)";
148
149  std::string after;
150  EXPECT_EQ(SPV_SUCCESS,
151            ToBinaryAndBack(before, &after,
152                            SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS,
153                            SPV_BINARY_TO_TEXT_OPTION_NO_HEADER));
154
155  EXPECT_EQ(expected, after);
156}
157
158}  // namespace
159}  // namespace spvtools
160