• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Tint Authors.
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 "gmock/gmock.h"
16 #include "src/reader/spirv/parser_impl_test_helper.h"
17 #include "src/reader/spirv/spirv_tools_helpers_test.h"
18 
19 namespace tint {
20 namespace reader {
21 namespace spirv {
22 namespace {
23 
24 using ::testing::HasSubstr;
25 
TEST_F(SpvParserTest,Impl_Uint32VecEmpty)26 TEST_F(SpvParserTest, Impl_Uint32VecEmpty) {
27   std::vector<uint32_t> data;
28   auto p = parser(data);
29   EXPECT_FALSE(p->Parse());
30   // TODO(dneto): What message?
31 }
32 
TEST_F(SpvParserTest,Impl_InvalidModuleFails)33 TEST_F(SpvParserTest, Impl_InvalidModuleFails) {
34   auto invalid_spv = test::Assemble("%ty = OpTypeInt 3 0");
35   auto p = parser(invalid_spv);
36   EXPECT_FALSE(p->Parse());
37   EXPECT_THAT(
38       p->error(),
39       HasSubstr("TypeInt cannot appear before the memory model instruction"));
40   EXPECT_THAT(p->error(), HasSubstr("OpTypeInt 3 0"));
41 }
42 
TEST_F(SpvParserTest,Impl_GenericVulkanShader_SimpleMemoryModel)43 TEST_F(SpvParserTest, Impl_GenericVulkanShader_SimpleMemoryModel) {
44   auto spv = test::Assemble(R"(
45   OpCapability Shader
46   OpMemoryModel Logical Simple
47   OpEntryPoint GLCompute %main "main"
48   OpExecutionMode %main LocalSize 1 1 1
49   %void = OpTypeVoid
50   %voidfn = OpTypeFunction %void
51   %main = OpFunction %void None %voidfn
52   %entry = OpLabel
53   OpReturn
54   OpFunctionEnd
55 )");
56   auto p = parser(spv);
57   EXPECT_TRUE(p->Parse());
58   EXPECT_TRUE(p->error().empty());
59 }
60 
TEST_F(SpvParserTest,Impl_GenericVulkanShader_GLSL450MemoryModel)61 TEST_F(SpvParserTest, Impl_GenericVulkanShader_GLSL450MemoryModel) {
62   auto spv = test::Assemble(R"(
63   OpCapability Shader
64   OpMemoryModel Logical GLSL450
65   OpEntryPoint GLCompute %main "main"
66   OpExecutionMode %main LocalSize 1 1 1
67   %void = OpTypeVoid
68   %voidfn = OpTypeFunction %void
69   %main = OpFunction %void None %voidfn
70   %entry = OpLabel
71   OpReturn
72   OpFunctionEnd
73 )");
74   auto p = parser(spv);
75   EXPECT_TRUE(p->Parse());
76   EXPECT_TRUE(p->error().empty());
77 }
78 
TEST_F(SpvParserTest,Impl_GenericVulkanShader_VulkanMemoryModel)79 TEST_F(SpvParserTest, Impl_GenericVulkanShader_VulkanMemoryModel) {
80   auto spv = test::Assemble(R"(
81   OpCapability Shader
82   OpCapability VulkanMemoryModelKHR
83   OpExtension "SPV_KHR_vulkan_memory_model"
84   OpMemoryModel Logical VulkanKHR
85   OpEntryPoint GLCompute %main "main"
86   OpExecutionMode %main LocalSize 1 1 1
87   %void = OpTypeVoid
88   %voidfn = OpTypeFunction %void
89   %main = OpFunction %void None %voidfn
90   %entry = OpLabel
91   OpReturn
92   OpFunctionEnd
93 )");
94   auto p = parser(spv);
95   EXPECT_TRUE(p->Parse());
96   EXPECT_TRUE(p->error().empty());
97 }
98 
TEST_F(SpvParserTest,Impl_OpenCLKernel_Fails)99 TEST_F(SpvParserTest, Impl_OpenCLKernel_Fails) {
100   auto spv = test::Assemble(R"(
101   OpCapability Kernel
102   OpCapability Addresses
103   OpMemoryModel Physical32 OpenCL
104   OpEntryPoint Kernel %main "main"
105   %void = OpTypeVoid
106   %voidfn = OpTypeFunction %void
107   %main = OpFunction %void None %voidfn
108   %entry = OpLabel
109   OpReturn
110   OpFunctionEnd
111 )");
112   auto p = parser(spv);
113   EXPECT_FALSE(p->Parse());
114   EXPECT_THAT(p->error(), HasSubstr("Capability Kernel is not allowed"));
115 }
116 
TEST_F(SpvParserTest,Impl_Source_NoOpLine)117 TEST_F(SpvParserTest, Impl_Source_NoOpLine) {
118   auto spv = test::Assemble(R"(
119   OpCapability Shader
120   OpMemoryModel Logical Simple
121   OpEntryPoint GLCompute %main "main"
122   OpExecutionMode %main LocalSize 1 1 1
123   %void = OpTypeVoid
124   %voidfn = OpTypeFunction %void
125   %5 = OpTypeInt 32 0
126   %60 = OpConstantNull %5
127   %main = OpFunction %void None %voidfn
128   %1 = OpLabel
129   OpReturn
130   OpFunctionEnd
131 )");
132   auto p = parser(spv);
133   EXPECT_TRUE(p->Parse());
134   EXPECT_TRUE(p->error().empty());
135   // Use instruction counting.
136   auto s5 = p->GetSourceForResultIdForTest(5);
137   EXPECT_EQ(7u, s5.range.begin.line);
138   EXPECT_EQ(0u, s5.range.begin.column);
139   auto s60 = p->GetSourceForResultIdForTest(60);
140   EXPECT_EQ(8u, s60.range.begin.line);
141   EXPECT_EQ(0u, s60.range.begin.column);
142   auto s1 = p->GetSourceForResultIdForTest(1);
143   EXPECT_EQ(10u, s1.range.begin.line);
144   EXPECT_EQ(0u, s1.range.begin.column);
145 }
146 
TEST_F(SpvParserTest,Impl_Source_WithOpLine_WithOpNoLine)147 TEST_F(SpvParserTest, Impl_Source_WithOpLine_WithOpNoLine) {
148   auto spv = test::Assemble(R"(
149   OpCapability Shader
150   OpMemoryModel Logical Simple
151   OpEntryPoint GLCompute %main "main"
152   OpExecutionMode %main LocalSize 1 1 1
153   %15 = OpString "myfile"
154   %void = OpTypeVoid
155   %voidfn = OpTypeFunction %void
156   OpLine %15 42 53
157   %5 = OpTypeInt 32 0
158   %60 = OpConstantNull %5
159   OpNoLine
160   %main = OpFunction %void None %voidfn
161   %1 = OpLabel
162   OpReturn
163   OpFunctionEnd
164 )");
165   auto p = parser(spv);
166   EXPECT_TRUE(p->Parse());
167   EXPECT_TRUE(p->error().empty());
168   // Use the information from the OpLine that is still in scope.
169   auto s5 = p->GetSourceForResultIdForTest(5);
170   EXPECT_EQ(42u, s5.range.begin.line);
171   EXPECT_EQ(53u, s5.range.begin.column);
172   auto s60 = p->GetSourceForResultIdForTest(60);
173   EXPECT_EQ(42u, s60.range.begin.line);
174   EXPECT_EQ(53u, s60.range.begin.column);
175   // After OpNoLine, revert back to instruction counting.
176   auto s1 = p->GetSourceForResultIdForTest(1);
177   EXPECT_EQ(14u, s1.range.begin.line);
178   EXPECT_EQ(0u, s1.range.begin.column);
179 }
180 
TEST_F(SpvParserTest,Impl_Source_InvalidId)181 TEST_F(SpvParserTest, Impl_Source_InvalidId) {
182   auto spv = test::Assemble(R"(
183   OpCapability Shader
184   OpMemoryModel Logical Simple
185   OpEntryPoint GLCompute %main "main"
186   OpExecutionMode %main LocalSize 1 1 1
187   %15 = OpString "myfile"
188   %void = OpTypeVoid
189   %voidfn = OpTypeFunction %void
190   %main = OpFunction %void None %voidfn
191   %1 = OpLabel
192   OpReturn
193   OpFunctionEnd
194 )");
195   auto p = parser(spv);
196   EXPECT_TRUE(p->Parse());
197   EXPECT_TRUE(p->error().empty());
198   auto s99 = p->GetSourceForResultIdForTest(99);
199   EXPECT_EQ(0u, s99.range.begin.line);
200   EXPECT_EQ(0u, s99.range.begin.column);
201 }
202 
TEST_F(SpvParserTest,Impl_IsValidIdentifier)203 TEST_F(SpvParserTest, Impl_IsValidIdentifier) {
204   EXPECT_FALSE(ParserImpl::IsValidIdentifier(""));  // empty
205   EXPECT_FALSE(
206       ParserImpl::IsValidIdentifier("_"));  // leading underscore, but ok later
207   EXPECT_FALSE(
208       ParserImpl::IsValidIdentifier("9"));  // leading digit, but ok later
209   EXPECT_FALSE(ParserImpl::IsValidIdentifier(" "));    // leading space
210   EXPECT_FALSE(ParserImpl::IsValidIdentifier("a "));   // trailing space
211   EXPECT_FALSE(ParserImpl::IsValidIdentifier("a 1"));  // space in the middle
212   EXPECT_FALSE(ParserImpl::IsValidIdentifier("."));    // weird character
213 
214   // a simple identifier
215   EXPECT_TRUE(ParserImpl::IsValidIdentifier("A"));
216   // each upper case letter
217   EXPECT_TRUE(ParserImpl::IsValidIdentifier("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
218   // each lower case letter
219   EXPECT_TRUE(ParserImpl::IsValidIdentifier("abcdefghijklmnopqrstuvwxyz"));
220   EXPECT_TRUE(ParserImpl::IsValidIdentifier("a0123456789"));  // each digit
221   EXPECT_TRUE(ParserImpl::IsValidIdentifier("x_"));           // has underscore
222 }
223 
224 }  // namespace
225 }  // namespace spirv
226 }  // namespace reader
227 }  // namespace tint
228