1 //
2 // Copyright 2012 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "PreprocessorTest.h"
8 #include "compiler/preprocessor/Token.h"
9
10 namespace angle
11 {
12
13 class VersionTest : public SimplePreprocessorTest
14 {};
15
TEST_F(VersionTest,NoDirectives)16 TEST_F(VersionTest, NoDirectives)
17 {
18 const char *str = "foo\n";
19 const char *expected = "foo\n";
20
21 using testing::_;
22 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 100, SH_GLES2_SPEC, _));
23 // No error or warning.
24 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
25
26 preprocess(str, expected);
27 }
28
TEST_F(VersionTest,NoVersion)29 TEST_F(VersionTest, NoVersion)
30 {
31 const char *str = "#define foo\n";
32 const char *expected = "\n";
33
34 using testing::_;
35 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 100, SH_GLES2_SPEC, _));
36 // No error or warning.
37 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
38
39 preprocess(str, expected);
40 }
41
TEST_F(VersionTest,Valid)42 TEST_F(VersionTest, Valid)
43 {
44 const char *str = "#version 200\n";
45 const char *expected = "\n";
46
47 using testing::_;
48 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200, SH_GLES2_SPEC, _));
49 // No error or warning.
50 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
51
52 preprocess(str, expected);
53 }
54
TEST_F(VersionTest,CommentsIgnored)55 TEST_F(VersionTest, CommentsIgnored)
56 {
57 const char *str =
58 "/*foo*/"
59 "#"
60 "/*foo*/"
61 "version"
62 "/*foo*/"
63 "200"
64 "/*foo*/"
65 "//foo"
66 "\n";
67 const char *expected = "\n";
68
69 using testing::_;
70 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200, SH_GLES2_SPEC, _));
71 // No error or warning.
72 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
73
74 preprocess(str, expected);
75 }
76
TEST_F(VersionTest,MissingNewline)77 TEST_F(VersionTest, MissingNewline)
78 {
79 const char *str = "#version 200";
80 const char *expected = "";
81
82 using testing::_;
83 // Directive successfully parsed.
84 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200, SH_GLES2_SPEC, _));
85 // Error reported about EOF.
86 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_EOF_IN_DIRECTIVE, _, _));
87
88 preprocess(str, expected);
89 }
90
TEST_F(VersionTest,AfterComments)91 TEST_F(VersionTest, AfterComments)
92 {
93 const char *str =
94 "/* block comment acceptable */\n"
95 "// line comment acceptable\n"
96 "#version 200\n";
97 const char *expected = "\n\n\n";
98
99 using testing::_;
100 // Directive successfully parsed.
101 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 3), 200, SH_GLES2_SPEC, _));
102 // No error or warning.
103 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
104
105 preprocess(str, expected);
106 }
107
TEST_F(VersionTest,AfterWhitespace)108 TEST_F(VersionTest, AfterWhitespace)
109 {
110 const char *str =
111 "\n"
112 "\n"
113 "#version 200\n";
114 const char *expected = "\n\n\n";
115
116 using testing::_;
117 // Directive successfully parsed.
118 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 3), 200, SH_GLES2_SPEC, _));
119 // No error or warning.
120 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
121
122 preprocess(str, expected);
123 }
124
TEST_F(VersionTest,AfterValidToken)125 TEST_F(VersionTest, AfterValidToken)
126 {
127 const char *str =
128 "foo\n"
129 "#version 200\n";
130
131 using testing::_;
132 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT,
133 pp::SourceLocation(0, 2), _));
134
135 preprocess(str);
136 }
137
TEST_F(VersionTest,AfterInvalidToken)138 TEST_F(VersionTest, AfterInvalidToken)
139 {
140 const char *str =
141 "$\n"
142 "#version 200\n";
143
144 using testing::_;
145 EXPECT_CALL(mDiagnostics,
146 print(pp::Diagnostics::PP_INVALID_CHARACTER, pp::SourceLocation(0, 1), "$"));
147 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT,
148 pp::SourceLocation(0, 2), _));
149
150 preprocess(str);
151 }
152
TEST_F(VersionTest,AfterValidDirective)153 TEST_F(VersionTest, AfterValidDirective)
154 {
155 const char *str =
156 "#\n"
157 "#version 200\n";
158
159 using testing::_;
160 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT,
161 pp::SourceLocation(0, 2), _));
162
163 preprocess(str);
164 }
165
TEST_F(VersionTest,AfterInvalidDirective)166 TEST_F(VersionTest, AfterInvalidDirective)
167 {
168 const char *str =
169 "#foo\n"
170 "#version 200\n";
171
172 using testing::_;
173 EXPECT_CALL(mDiagnostics,
174 print(pp::Diagnostics::PP_DIRECTIVE_INVALID_NAME, pp::SourceLocation(0, 1), "foo"));
175 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT,
176 pp::SourceLocation(0, 2), _));
177
178 preprocess(str);
179 }
180
TEST_F(VersionTest,AfterExcludedBlock)181 TEST_F(VersionTest, AfterExcludedBlock)
182 {
183 const char *str =
184 "#if 0\n"
185 "foo\n"
186 "#endif\n"
187 "#version 200\n";
188
189 using testing::_;
190 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT,
191 pp::SourceLocation(0, 4), _));
192
193 preprocess(str);
194 }
195
196 struct VersionTestParam
197 {
198 const char *str;
199 pp::Diagnostics::ID id;
200 };
201
202 class InvalidVersionTest : public VersionTest, public testing::WithParamInterface<VersionTestParam>
203 {};
204
TEST_P(InvalidVersionTest,Identified)205 TEST_P(InvalidVersionTest, Identified)
206 {
207 VersionTestParam param = GetParam();
208 const char *expected = "\n";
209
210 using testing::_;
211 // No handleVersion call.
212 EXPECT_CALL(mDirectiveHandler, handleVersion(_, _, _, _)).Times(0);
213 // Invalid version directive call.
214 EXPECT_CALL(mDiagnostics, print(param.id, pp::SourceLocation(0, 1), _));
215
216 preprocess(param.str, expected);
217 }
218
219 static const VersionTestParam kParams[] = {
220 {"#version\n", pp::Diagnostics::PP_INVALID_VERSION_DIRECTIVE},
221 {"#version foo\n", pp::Diagnostics::PP_INVALID_VERSION_NUMBER},
222 {"#version 100 foo\n", pp::Diagnostics::PP_UNEXPECTED_TOKEN},
223 {"#version 0xffffffff\n", pp::Diagnostics::PP_INTEGER_OVERFLOW}};
224
225 INSTANTIATE_TEST_SUITE_P(All, InvalidVersionTest, testing::ValuesIn(kParams));
226
227 } // namespace angle
228