1// Copyright (c) 2017 Pierre Moreau
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
17#include "gmock/gmock.h"
18#include "test/link/linker_fixture.h"
19
20namespace spvtools {
21namespace {
22
23using ::testing::HasSubstr;
24
25class EntryPoints : public spvtest::LinkerTest {};
26
27TEST_F(EntryPoints, SameModelDifferentName) {
28  const std::string body1 = R"(
29OpCapability Shader
30OpMemoryModel Logical GLSL450
31OpEntryPoint GLCompute %3 "foo"
32%1 = OpTypeVoid
33%2 = OpTypeFunction %1
34%3 = OpFunction %1 None %2
35OpFunctionEnd
36)";
37  const std::string body2 = R"(
38OpCapability Shader
39OpMemoryModel Logical GLSL450
40OpEntryPoint GLCompute %3 "bar"
41%1 = OpTypeVoid
42%2 = OpTypeFunction %1
43%3 = OpFunction %1 None %2
44OpFunctionEnd
45)";
46
47  spvtest::Binary linked_binary;
48  ASSERT_EQ(SPV_SUCCESS, AssembleAndLink({body1, body2}, &linked_binary))
49      << GetErrorMessage();
50  EXPECT_THAT(GetErrorMessage(), std::string());
51}
52
53TEST_F(EntryPoints, DifferentModelSameName) {
54  const std::string body1 = R"(
55OpCapability Shader
56OpMemoryModel Logical GLSL450
57OpEntryPoint GLCompute %3 "foo"
58%1 = OpTypeVoid
59%2 = OpTypeFunction %1
60%3 = OpFunction %1 None %2
61OpFunctionEnd
62)";
63  const std::string body2 = R"(
64OpCapability Shader
65OpMemoryModel Logical GLSL450
66OpEntryPoint Vertex %3 "foo"
67%1 = OpTypeVoid
68%2 = OpTypeFunction %1
69%3 = OpFunction %1 None %2
70OpFunctionEnd
71)";
72
73  spvtest::Binary linked_binary;
74  ASSERT_EQ(SPV_SUCCESS, AssembleAndLink({body1, body2}, &linked_binary))
75      << GetErrorMessage();
76  EXPECT_THAT(GetErrorMessage(), std::string());
77}
78
79TEST_F(EntryPoints, SameModelAndName) {
80  const std::string body1 = R"(
81OpCapability Shader
82OpMemoryModel Logical GLSL450
83OpEntryPoint GLCompute %3 "foo"
84%1 = OpTypeVoid
85%2 = OpTypeFunction %1
86%3 = OpFunction %1 None %2
87OpFunctionEnd
88)";
89  const std::string body2 = R"(
90OpCapability Shader
91OpMemoryModel Logical GLSL450
92OpEntryPoint GLCompute %3 "foo"
93%1 = OpTypeVoid
94%2 = OpTypeFunction %1
95%3 = OpFunction %1 None %2
96OpFunctionEnd
97)";
98
99  spvtest::Binary linked_binary;
100  EXPECT_EQ(SPV_ERROR_INTERNAL,
101            AssembleAndLink({body1, body2}, &linked_binary));
102  EXPECT_THAT(GetErrorMessage(),
103              HasSubstr("The entry point \"foo\", with execution model "
104                        "GLCompute, was already defined."));
105}
106
107TEST_F(EntryPoints, LinkedVariables) {
108  const std::string body1 = R"(
109               OpCapability Addresses
110OpCapability Linkage
111OpCapability Kernel
112OpMemoryModel Physical64 OpenCL
113OpDecorate %7 LinkageAttributes "foo" Export
114%1 = OpTypeInt 32 0
115%2 = OpTypeVector %1 3
116%3 = OpTypePointer Input %2
117%4 = OpVariable %3 Input
118%5 = OpTypeVoid
119%6 = OpTypeFunction %5
120%7 = OpFunction %5 None %6
121%8 = OpLabel
122%9 = OpLoad %2 %4 Aligned 32
123OpReturn
124OpFunctionEnd
125)";
126  const std::string body2 = R"(
127OpCapability Linkage
128OpCapability Kernel
129OpMemoryModel Physical64 OpenCL
130OpEntryPoint Kernel %4 "bar"
131OpDecorate %3 LinkageAttributes "foo" Import
132%1 = OpTypeVoid
133%2 = OpTypeFunction %1
134%3 = OpFunction %1 None %2
135OpFunctionEnd
136%4 = OpFunction %1 None %2
137%5 = OpLabel
138%6 = OpFunctionCall %1 %3
139OpReturn
140OpFunctionEnd
141)";
142
143  spvtest::Binary linked_binary;
144  EXPECT_EQ(SPV_SUCCESS, AssembleAndLink({body1, body2}, &linked_binary));
145  EXPECT_THAT(GetErrorMessage(), std::string());
146  EXPECT_TRUE(Validate(linked_binary));
147  EXPECT_THAT(GetErrorMessage(), std::string());
148}
149
150}  // namespace
151}  // namespace spvtools
152