1 | //===- unittests/Lex/DependencyDirectivesScannerTest.cpp ------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "clang/Lex/DependencyDirectivesScanner.h" |
10 | #include "llvm/ADT/SmallString.h" |
11 | #include "gtest/gtest.h" |
12 | |
13 | using namespace llvm; |
14 | using namespace clang; |
15 | using namespace clang::dependency_directives_scan; |
16 | |
17 | static bool minimizeSourceToDependencyDirectives( |
18 | StringRef Input, SmallVectorImpl<char> &Out, |
19 | SmallVectorImpl<dependency_directives_scan::Token> &Tokens, |
20 | SmallVectorImpl<Directive> &Directives) { |
21 | Out.clear(); |
22 | Tokens.clear(); |
23 | Directives.clear(); |
24 | if (scanSourceForDependencyDirectives(Input, Tokens, Directives)) |
25 | return true; |
26 | |
27 | raw_svector_ostream OS(Out); |
28 | printDependencyDirectivesAsSource(Source: Input, Directives, OS); |
29 | if (!Out.empty() && Out.back() != '\n') |
30 | Out.push_back(Elt: '\n'); |
31 | Out.push_back(Elt: '\0'); |
32 | Out.pop_back(); |
33 | |
34 | return false; |
35 | } |
36 | |
37 | static bool minimizeSourceToDependencyDirectives(StringRef Input, |
38 | SmallVectorImpl<char> &Out) { |
39 | SmallVector<dependency_directives_scan::Token, 16> Tokens; |
40 | SmallVector<Directive, 32> Directives; |
41 | return minimizeSourceToDependencyDirectives(Input, Out, Tokens, Directives); |
42 | } |
43 | |
44 | namespace { |
45 | |
46 | TEST(MinimizeSourceToDependencyDirectivesTest, Empty) { |
47 | SmallVector<char, 128> Out; |
48 | SmallVector<dependency_directives_scan::Token, 4> Tokens; |
49 | SmallVector<Directive, 4> Directives; |
50 | |
51 | ASSERT_FALSE( |
52 | minimizeSourceToDependencyDirectives("" , Out, Tokens, Directives)); |
53 | EXPECT_TRUE(Out.empty()); |
54 | EXPECT_TRUE(Tokens.empty()); |
55 | ASSERT_EQ(1u, Directives.size()); |
56 | ASSERT_EQ(pp_eof, Directives.back().Kind); |
57 | |
58 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("abc def\nxyz" , Out, Tokens, |
59 | Directives)); |
60 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
61 | EXPECT_TRUE(Tokens.empty()); |
62 | ASSERT_EQ(2u, Directives.size()); |
63 | EXPECT_EQ(tokens_present_before_eof, Directives[0].Kind); |
64 | EXPECT_EQ(pp_eof, Directives[1].Kind); |
65 | } |
66 | |
67 | TEST(MinimizeSourceToDependencyDirectivesTest, AllTokens) { |
68 | SmallVector<char, 128> Out; |
69 | SmallVector<dependency_directives_scan::Token, 4> Tokens; |
70 | SmallVector<Directive, 4> Directives; |
71 | |
72 | ASSERT_FALSE( |
73 | minimizeSourceToDependencyDirectives("#define A\n" |
74 | "#undef A\n" |
75 | "#endif\n" |
76 | "#if A\n" |
77 | "#ifdef A\n" |
78 | "#ifndef A\n" |
79 | "#elifdef A\n" |
80 | "#elifndef A\n" |
81 | "#elif A\n" |
82 | "#else\n" |
83 | "#include <A>\n" |
84 | "#include_next <A>\n" |
85 | "#__include_macros <A>\n" |
86 | "#import <A>\n" |
87 | "@import A;\n" |
88 | "#pragma clang module import A\n" |
89 | "#pragma push_macro(A)\n" |
90 | "#pragma pop_macro(A)\n" |
91 | "#pragma include_alias(<A>, <B>)\n" |
92 | "export module m;\n" |
93 | "import m;\n" |
94 | "#pragma clang system_header\n" , |
95 | Out, Tokens, Directives)); |
96 | EXPECT_EQ(pp_define, Directives[0].Kind); |
97 | EXPECT_EQ(pp_undef, Directives[1].Kind); |
98 | EXPECT_EQ(pp_endif, Directives[2].Kind); |
99 | EXPECT_EQ(pp_if, Directives[3].Kind); |
100 | EXPECT_EQ(pp_ifdef, Directives[4].Kind); |
101 | EXPECT_EQ(pp_ifndef, Directives[5].Kind); |
102 | EXPECT_EQ(pp_elifdef, Directives[6].Kind); |
103 | EXPECT_EQ(pp_elifndef, Directives[7].Kind); |
104 | EXPECT_EQ(pp_elif, Directives[8].Kind); |
105 | EXPECT_EQ(pp_else, Directives[9].Kind); |
106 | EXPECT_EQ(pp_include, Directives[10].Kind); |
107 | EXPECT_EQ(pp_include_next, Directives[11].Kind); |
108 | EXPECT_EQ(pp___include_macros, Directives[12].Kind); |
109 | EXPECT_EQ(pp_import, Directives[13].Kind); |
110 | EXPECT_EQ(decl_at_import, Directives[14].Kind); |
111 | EXPECT_EQ(pp_pragma_import, Directives[15].Kind); |
112 | EXPECT_EQ(pp_pragma_push_macro, Directives[16].Kind); |
113 | EXPECT_EQ(pp_pragma_pop_macro, Directives[17].Kind); |
114 | EXPECT_EQ(pp_pragma_include_alias, Directives[18].Kind); |
115 | EXPECT_EQ(cxx_export_module_decl, Directives[19].Kind); |
116 | EXPECT_EQ(cxx_import_decl, Directives[20].Kind); |
117 | EXPECT_EQ(pp_pragma_system_header, Directives[21].Kind); |
118 | EXPECT_EQ(pp_eof, Directives[22].Kind); |
119 | } |
120 | |
121 | TEST(MinimizeSourceToDependencyDirectivesTest, EmptyHash) { |
122 | SmallVector<char, 128> Out; |
123 | |
124 | ASSERT_FALSE( |
125 | minimizeSourceToDependencyDirectives("#\n#define MACRO a\n" , Out)); |
126 | EXPECT_STREQ("#define MACRO a\n" , Out.data()); |
127 | } |
128 | |
129 | TEST(MinimizeSourceToDependencyDirectivesTest, HashHash) { |
130 | SmallVector<char, 128> Out; |
131 | |
132 | StringRef Source = R"( |
133 | #define S |
134 | #if 0 |
135 | ##pragma cool |
136 | ##include "t.h" |
137 | #endif |
138 | #define E |
139 | )" ; |
140 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
141 | EXPECT_STREQ("#define S\n#if 0\n#endif\n#define E\n" , Out.data()); |
142 | } |
143 | |
144 | TEST(MinimizeSourceToDependencyDirectivesTest, Define) { |
145 | SmallVector<char, 128> Out; |
146 | SmallVector<dependency_directives_scan::Token, 4> Tokens; |
147 | SmallVector<Directive, 4> Directives; |
148 | |
149 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO" , Out, |
150 | Tokens, Directives)); |
151 | EXPECT_STREQ("#define MACRO\n" , Out.data()); |
152 | ASSERT_EQ(4u, Tokens.size()); |
153 | ASSERT_EQ(2u, Directives.size()); |
154 | ASSERT_EQ(pp_define, Directives.front().Kind); |
155 | } |
156 | |
157 | TEST(MinimizeSourceToDependencyDirectivesTest, DefineSpacing) { |
158 | SmallVector<char, 128> Out; |
159 | |
160 | ASSERT_FALSE( |
161 | minimizeSourceToDependencyDirectives("#define MACRO\n\n\n" , Out)); |
162 | EXPECT_STREQ("#define MACRO\n" , Out.data()); |
163 | |
164 | ASSERT_FALSE( |
165 | minimizeSourceToDependencyDirectives("#define MACRO \n\n\n" , Out)); |
166 | EXPECT_STREQ("#define MACRO\n" , Out.data()); |
167 | |
168 | ASSERT_FALSE( |
169 | minimizeSourceToDependencyDirectives("#define MACRO a \n\n\n" , Out)); |
170 | EXPECT_STREQ("#define MACRO a\n" , Out.data()); |
171 | |
172 | ASSERT_FALSE( |
173 | minimizeSourceToDependencyDirectives("#define MACRO\n\n\n" , Out)); |
174 | EXPECT_STREQ("#define MACRO\n" , Out.data()); |
175 | } |
176 | |
177 | TEST(MinimizeSourceToDependencyDirectivesTest, DefineMacroArguments) { |
178 | SmallVector<char, 128> Out; |
179 | |
180 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO()" , Out)); |
181 | EXPECT_STREQ("#define MACRO()\n" , Out.data()); |
182 | |
183 | ASSERT_FALSE( |
184 | minimizeSourceToDependencyDirectives("#define MACRO(a, b...)" , Out)); |
185 | EXPECT_STREQ("#define MACRO(a,b...)\n" , Out.data()); |
186 | |
187 | ASSERT_FALSE( |
188 | minimizeSourceToDependencyDirectives("#define MACRO content" , Out)); |
189 | EXPECT_STREQ("#define MACRO content\n" , Out.data()); |
190 | |
191 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
192 | "#define MACRO con tent " , Out)); |
193 | EXPECT_STREQ("#define MACRO con tent\n" , Out.data()); |
194 | |
195 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
196 | "#define MACRO() con tent " , Out)); |
197 | EXPECT_STREQ("#define MACRO() con tent\n" , Out.data()); |
198 | } |
199 | |
200 | TEST(MinimizeSourceToDependencyDirectivesTest, DefineInvalidMacroArguments) { |
201 | SmallVector<char, 128> Out; |
202 | |
203 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO((a))" , Out)); |
204 | EXPECT_STREQ("#define MACRO((a))\n" , Out.data()); |
205 | |
206 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO(" , Out)); |
207 | EXPECT_STREQ("#define MACRO(\n" , Out.data()); |
208 | |
209 | ASSERT_FALSE( |
210 | minimizeSourceToDependencyDirectives("#define MACRO(a * b)" , Out)); |
211 | EXPECT_STREQ("#define MACRO(a*b)\n" , Out.data()); |
212 | } |
213 | |
214 | TEST(MinimizeSourceToDependencyDirectivesTest, DefineHorizontalWhitespace) { |
215 | SmallVector<char, 128> Out; |
216 | |
217 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
218 | "#define MACRO(\t)\tcon \t tent\t" , Out)); |
219 | EXPECT_STREQ("#define MACRO() con tent\n" , Out.data()); |
220 | |
221 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
222 | "#define MACRO(\f)\fcon \f tent\f" , Out)); |
223 | EXPECT_STREQ("#define MACRO() con tent\n" , Out.data()); |
224 | |
225 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
226 | "#define MACRO(\v)\vcon \v tent\v" , Out)); |
227 | EXPECT_STREQ("#define MACRO() con tent\n" , Out.data()); |
228 | |
229 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
230 | "#define MACRO \t\v\f\v\t con\f\t\vtent\v\f \v" , Out)); |
231 | EXPECT_STREQ("#define MACRO con tent\n" , Out.data()); |
232 | } |
233 | |
234 | TEST(MinimizeSourceToDependencyDirectivesTest, DefineMultilineArgs) { |
235 | SmallVector<char, 128> Out; |
236 | |
237 | ASSERT_FALSE( |
238 | minimizeSourceToDependencyDirectives("#define MACRO(a \\\n" |
239 | " )" , |
240 | Out)); |
241 | EXPECT_STREQ("#define MACRO(a)\n" , Out.data()); |
242 | |
243 | ASSERT_FALSE( |
244 | minimizeSourceToDependencyDirectives("#define MACRO(a, \\\n" |
245 | " b) \\\n" |
246 | " call((a), \\\n" |
247 | " (b))" , |
248 | Out)); |
249 | EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n" , Out.data()); |
250 | } |
251 | |
252 | TEST(MinimizeSourceToDependencyDirectivesTest, |
253 | DefineMultilineArgsCarriageReturn) { |
254 | SmallVector<char, 128> Out; |
255 | |
256 | ASSERT_FALSE( |
257 | minimizeSourceToDependencyDirectives("#define MACRO(a, \\\r" |
258 | " b) \\\r" |
259 | " call((a), \\\r" |
260 | " (b))" , |
261 | Out)); |
262 | EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n" , Out.data()); |
263 | } |
264 | |
265 | TEST(MinimizeSourceToDependencyDirectivesTest, DefineMultilineArgsStringize) { |
266 | SmallVector<char, 128> Out; |
267 | |
268 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO(a,b) \\\n" |
269 | " #a \\\n" |
270 | " #b" , |
271 | Out)); |
272 | EXPECT_STREQ("#define MACRO(a,b) #a #b\n" , Out.data()); |
273 | } |
274 | |
275 | TEST(MinimizeSourceToDependencyDirectivesTest, |
276 | DefineMultilineArgsCarriageReturnNewline) { |
277 | SmallVector<char, 128> Out; |
278 | |
279 | ASSERT_FALSE( |
280 | minimizeSourceToDependencyDirectives("#define MACRO(a, \\\r\n" |
281 | " b) \\\r\n" |
282 | " call((a), \\\r\n" |
283 | " (b))" , |
284 | Out)); |
285 | EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n" , Out.data()); |
286 | } |
287 | |
288 | TEST(MinimizeSourceToDependencyDirectivesTest, |
289 | DefineMultilineArgsNewlineCarriageReturn) { |
290 | SmallVector<char, 128> Out; |
291 | |
292 | ASSERT_FALSE( |
293 | minimizeSourceToDependencyDirectives("#define MACRO(a, \\\n\r" |
294 | " b) \\\n\r" |
295 | " call((a), \\\n\r" |
296 | " (b))" , |
297 | Out)); |
298 | EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n" , Out.data()); |
299 | } |
300 | |
301 | TEST(MinimizeSourceToDependencyDirectivesTest, DefineNumber) { |
302 | SmallVector<char, 128> Out; |
303 | |
304 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define 0\n" , Out)); |
305 | } |
306 | |
307 | TEST(MinimizeSourceToDependencyDirectivesTest, DefineNoName) { |
308 | SmallVector<char, 128> Out; |
309 | |
310 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define &\n" , Out)); |
311 | } |
312 | |
313 | TEST(MinimizeSourceToDependencyDirectivesTest, DefineNoWhitespace) { |
314 | SmallVector<char, 128> Out; |
315 | |
316 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define AND&\n" , Out)); |
317 | EXPECT_STREQ("#define AND&\n" , Out.data()); |
318 | |
319 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define AND\\\n" |
320 | "&\n" , |
321 | Out)); |
322 | EXPECT_STREQ("#define AND\\\n" |
323 | "&\n" , |
324 | Out.data()); |
325 | } |
326 | |
327 | TEST(MinimizeSourceToDependencyDirectivesTest, MultilineComment) { |
328 | SmallVector<char, 128> Out; |
329 | |
330 | ASSERT_FALSE( |
331 | minimizeSourceToDependencyDirectives("#define MACRO a/*\n" |
332 | " /*\n" |
333 | "#define MISSING abc\n" |
334 | " /*\n" |
335 | " /* something */ \n" |
336 | "#include /* \"def\" */ <abc> \n" , |
337 | Out)); |
338 | EXPECT_STREQ("#define MACRO a\n" |
339 | "#include <abc>\n" , |
340 | Out.data()); |
341 | } |
342 | |
343 | TEST(MinimizeSourceToDependencyDirectivesTest, MultilineCommentInStrings) { |
344 | SmallVector<char, 128> Out; |
345 | |
346 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO1 \"/*\"\n" |
347 | "#define MACRO2 \"*/\"\n" , |
348 | Out)); |
349 | EXPECT_STREQ("#define MACRO1 \"/*\"\n" |
350 | "#define MACRO2 \"*/\"\n" , |
351 | Out.data()); |
352 | } |
353 | |
354 | TEST(MinimizeSourceToDependencyDirectivesTest, CommentSlashSlashStar) { |
355 | SmallVector<char, 128> Out; |
356 | |
357 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
358 | "#define MACRO 1 //* blah */\n" , Out)); |
359 | EXPECT_STREQ("#define MACRO 1\n" , Out.data()); |
360 | } |
361 | |
362 | TEST(MinimizeSourceToDependencyDirectivesTest, Ifdef) { |
363 | SmallVector<char, 128> Out; |
364 | |
365 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n" |
366 | "#define B\n" |
367 | "#endif\n" , |
368 | Out)); |
369 | EXPECT_STREQ("#ifdef A\n" |
370 | "#define B\n" |
371 | "#endif\n" , |
372 | Out.data()); |
373 | |
374 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n" |
375 | "#define B\n" |
376 | "#elif B\n" |
377 | "#define C\n" |
378 | "#elif C\n" |
379 | "#define D\n" |
380 | "#else\n" |
381 | "#define E\n" |
382 | "#endif\n" , |
383 | Out)); |
384 | EXPECT_STREQ("#ifdef A\n" |
385 | "#define B\n" |
386 | "#elif B\n" |
387 | "#define C\n" |
388 | "#elif C\n" |
389 | "#define D\n" |
390 | "#else\n" |
391 | "#define E\n" |
392 | "#endif\n" , |
393 | Out.data()); |
394 | } |
395 | |
396 | TEST(MinimizeSourceToDependencyDirectivesTest, Elifdef) { |
397 | SmallVector<char, 128> Out; |
398 | |
399 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n" |
400 | "#define B\n" |
401 | "#elifdef C\n" |
402 | "#define D\n" |
403 | "#endif\n" , |
404 | Out)); |
405 | EXPECT_STREQ("#ifdef A\n" |
406 | "#define B\n" |
407 | "#elifdef C\n" |
408 | "#define D\n" |
409 | "#endif\n" , |
410 | Out.data()); |
411 | |
412 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n" |
413 | "#define B\n" |
414 | "#elifdef B\n" |
415 | "#define C\n" |
416 | "#elifndef C\n" |
417 | "#define D\n" |
418 | "#else\n" |
419 | "#define E\n" |
420 | "#endif\n" , |
421 | Out)); |
422 | EXPECT_STREQ("#ifdef A\n" |
423 | "#define B\n" |
424 | "#elifdef B\n" |
425 | "#define C\n" |
426 | "#elifndef C\n" |
427 | "#define D\n" |
428 | "#else\n" |
429 | "#define E\n" |
430 | "#endif\n" , |
431 | Out.data()); |
432 | } |
433 | |
434 | TEST(MinimizeSourceToDependencyDirectivesTest, EmptyIfdef) { |
435 | SmallVector<char, 128> Out; |
436 | |
437 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n" |
438 | "void skip();\n" |
439 | "#elif B\n" |
440 | "#elif C\n" |
441 | "#else D\n" |
442 | "#endif\n" , |
443 | Out)); |
444 | EXPECT_STREQ("#ifdef A\n" |
445 | "#elif B\n" |
446 | "#elif C\n" |
447 | "#endif\n" , |
448 | Out.data()); |
449 | } |
450 | |
451 | TEST(MinimizeSourceToDependencyDirectivesTest, EmptyElifdef) { |
452 | SmallVector<char, 128> Out; |
453 | |
454 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n" |
455 | "void skip();\n" |
456 | "#elifdef B\n" |
457 | "#elifndef C\n" |
458 | "#else D\n" |
459 | "#endif\n" , |
460 | Out)); |
461 | EXPECT_STREQ("#ifdef A\n" |
462 | "#elifdef B\n" |
463 | "#elifndef C\n" |
464 | "#endif\n" , |
465 | Out.data()); |
466 | } |
467 | |
468 | TEST(MinimizeSourceToDependencyDirectivesTest, Pragma) { |
469 | SmallVector<char, 128> Out; |
470 | |
471 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#pragma A\n" , Out)); |
472 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
473 | |
474 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
475 | "#pragma push_macro(\"MACRO\")\n" , Out)); |
476 | EXPECT_STREQ("#pragma push_macro(\"MACRO\")\n" , Out.data()); |
477 | |
478 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
479 | "#pragma pop_macro(\"MACRO\")\n" , Out)); |
480 | EXPECT_STREQ("#pragma pop_macro(\"MACRO\")\n" , Out.data()); |
481 | |
482 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
483 | "#pragma include_alias(\"A\", \"B\")\n" , Out)); |
484 | EXPECT_STREQ("#pragma include_alias(\"A\", \"B\")\n" , Out.data()); |
485 | |
486 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
487 | "#pragma include_alias(<A>, <B>)\n" , Out)); |
488 | EXPECT_STREQ("#pragma include_alias(<A>, <B>)\n" , Out.data()); |
489 | |
490 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#pragma clang\n" , Out)); |
491 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
492 | |
493 | ASSERT_FALSE( |
494 | minimizeSourceToDependencyDirectives("#pragma clang module\n" , Out)); |
495 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
496 | |
497 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
498 | "#pragma clang module impor\n" , Out)); |
499 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
500 | |
501 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
502 | "#pragma clang module import\n" , Out)); |
503 | EXPECT_STREQ("#pragma clang module import\n" , Out.data()); |
504 | } |
505 | |
506 | TEST(MinimizeSourceToDependencyDirectivesTest, UnderscorePragma) { |
507 | SmallVector<char, 128> Out; |
508 | |
509 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_)" , Out)); |
510 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
511 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma)" , Out)); |
512 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
513 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma()" , Out)); |
514 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
515 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma())" , Out)); |
516 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
517 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma(")" , Out)); |
518 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
519 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(R"(_Pragma("A"))" , Out)); |
520 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
521 | |
522 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
523 | R"x(_Pragma("push_macro(\"MACRO\")"))x" , Out)); |
524 | EXPECT_STREQ(R"x(_Pragma("push_macro(\"MACRO\")"))x" |
525 | "\n" , |
526 | Out.data()); |
527 | |
528 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
529 | R"x(_Pragma("pop_macro(\"MACRO\")"))x" , Out)); |
530 | EXPECT_STREQ(R"x(_Pragma("pop_macro(\"MACRO\")"))x" |
531 | "\n" , |
532 | Out.data()); |
533 | |
534 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
535 | R"x(_Pragma("include_alias(\"A\", \"B\")"))x" , Out)); |
536 | EXPECT_STREQ(R"x(_Pragma("include_alias(\"A\", \"B\")"))x" |
537 | "\n" , |
538 | Out.data()); |
539 | |
540 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
541 | R"x(_Pragma("include_alias(<A>, <B>)"))x" , Out)); |
542 | EXPECT_STREQ(R"x(_Pragma("include_alias(<A>, <B>)"))x" |
543 | "\n" , |
544 | Out.data()); |
545 | |
546 | ASSERT_FALSE( |
547 | minimizeSourceToDependencyDirectives(R"(_Pragma("clang"))" , Out)); |
548 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
549 | |
550 | ASSERT_FALSE( |
551 | minimizeSourceToDependencyDirectives(R"(_Pragma("clang module"))" , Out)); |
552 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
553 | |
554 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
555 | R"(_Pragma("clang module impor"))" , Out)); |
556 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
557 | |
558 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
559 | R"(_Pragma("clang module import"))" , Out)); |
560 | EXPECT_STREQ(R"(_Pragma("clang module import"))" |
561 | "\n" , |
562 | Out.data()); |
563 | |
564 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
565 | R"(_Pragma("clang \ |
566 | module \ |
567 | import"))" , |
568 | Out)); |
569 | EXPECT_STREQ(R"(_Pragma("clang \ |
570 | module \ |
571 | import"))" |
572 | "\n" , |
573 | Out.data()); |
574 | |
575 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
576 | R"(_Pragma(L"clang module import"))" , Out)); |
577 | EXPECT_STREQ(R"(_Pragma(L"clang module import"))" |
578 | "\n" , |
579 | Out.data()); |
580 | |
581 | // FIXME: u"" strings depend on using C11 language mode |
582 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
583 | R"(_Pragma(u"clang module import"))" , Out)); |
584 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
585 | |
586 | // R"()" strings are enabled by default. |
587 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
588 | R"(_Pragma(R"abc(clang module import)abc"))" , Out)); |
589 | EXPECT_STREQ(R"(_Pragma(R"abc(clang module import)abc"))" |
590 | "\n" , |
591 | Out.data()); |
592 | } |
593 | |
594 | TEST(MinimizeSourceToDependencyDirectivesTest, Include) { |
595 | SmallVector<char, 128> Out; |
596 | |
597 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include \"A\"\n" , Out)); |
598 | EXPECT_STREQ("#include \"A\"\n" , Out.data()); |
599 | |
600 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include <A>\n" , Out)); |
601 | EXPECT_STREQ("#include <A>\n" , Out.data()); |
602 | |
603 | ASSERT_FALSE( |
604 | minimizeSourceToDependencyDirectives("#include <A//A.h>\n" , Out)); |
605 | EXPECT_STREQ("#include <A//A.h>\n" , Out.data()); |
606 | |
607 | ASSERT_FALSE( |
608 | minimizeSourceToDependencyDirectives("#include \"A//A.h\"\n" , Out)); |
609 | EXPECT_STREQ("#include \"A//A.h\"\n" , Out.data()); |
610 | |
611 | ASSERT_FALSE( |
612 | minimizeSourceToDependencyDirectives("#include_next <A>\n" , Out)); |
613 | EXPECT_STREQ("#include_next <A>\n" , Out.data()); |
614 | |
615 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#import <A>\n" , Out)); |
616 | EXPECT_STREQ("#import <A>\n" , Out.data()); |
617 | |
618 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#import <A//A.h>\n" , Out)); |
619 | EXPECT_STREQ("#import <A//A.h>\n" , Out.data()); |
620 | |
621 | ASSERT_FALSE( |
622 | minimizeSourceToDependencyDirectives("#import \"A//A.h\"\n" , Out)); |
623 | EXPECT_STREQ("#import \"A//A.h\"\n" , Out.data()); |
624 | |
625 | ASSERT_FALSE( |
626 | minimizeSourceToDependencyDirectives("#__include_macros <A>\n" , Out)); |
627 | EXPECT_STREQ("#__include_macros <A>\n" , Out.data()); |
628 | |
629 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include MACRO\n" , Out)); |
630 | EXPECT_STREQ("#include MACRO\n" , Out.data()); |
631 | } |
632 | |
633 | TEST(MinimizeSourceToDependencyDirectivesTest, AtImport) { |
634 | SmallVector<char, 128> Out; |
635 | |
636 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A;\n" , Out)); |
637 | EXPECT_STREQ("@import A;\n" , Out.data()); |
638 | |
639 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(" @ import A;\n" , Out)); |
640 | EXPECT_STREQ("@import A;\n" , Out.data()); |
641 | |
642 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A\n;" , Out)); |
643 | EXPECT_STREQ("@import A;\n" , Out.data()); |
644 | |
645 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A.B;\n" , Out)); |
646 | EXPECT_STREQ("@import A.B;\n" , Out.data()); |
647 | |
648 | ASSERT_FALSE(minimizeSourceToDependencyDirectives( |
649 | "@import /*x*/ A /*x*/ . /*x*/ B /*x*/ \n /*x*/ ; /*x*/" , Out)); |
650 | EXPECT_STREQ("@import A.B;\n" , Out.data()); |
651 | } |
652 | |
653 | TEST(MinimizeSourceToDependencyDirectivesTest, EmptyIncludesAndImports) { |
654 | SmallVector<char, 128> Out; |
655 | |
656 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#import\n" , Out)); |
657 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
658 | |
659 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include\n" , Out)); |
660 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
661 | |
662 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n" |
663 | "#import \n" |
664 | "#endif\n" , |
665 | Out)); |
666 | // The ifdef block is removed because it's "empty". |
667 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
668 | |
669 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n" |
670 | "#import \n" |
671 | "#define B\n" |
672 | "#endif\n" , |
673 | Out)); |
674 | EXPECT_STREQ("#ifdef A\n" |
675 | "#define B\n" |
676 | "#endif\n" , |
677 | Out.data()); |
678 | } |
679 | |
680 | TEST(MinimizeSourceToDependencyDirectivesTest, ImportFailures) { |
681 | SmallVector<char, 128> Out; |
682 | |
683 | ASSERT_TRUE(minimizeSourceToDependencyDirectives("@import A\n" , Out)); |
684 | ASSERT_FALSE( |
685 | minimizeSourceToDependencyDirectives("@import MACRO(A);\n" , Out)); |
686 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import \" \";\n" , Out)); |
687 | |
688 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("import <Foo.h>\n" |
689 | "@import Foo;" , |
690 | Out)); |
691 | EXPECT_STREQ("@import Foo;\n" , Out.data()); |
692 | |
693 | ASSERT_FALSE( |
694 | minimizeSourceToDependencyDirectives("import <Foo.h>\n" |
695 | "#import <Foo.h>\n" |
696 | "@;\n" |
697 | "#pragma clang module import Foo" , |
698 | Out)); |
699 | EXPECT_STREQ("#import <Foo.h>\n" |
700 | "#pragma clang module import Foo\n" , |
701 | Out.data()); |
702 | } |
703 | |
704 | TEST(MinimizeSourceToDependencyDirectivesTest, RawStringLiteral) { |
705 | SmallVector<char, 128> Out; |
706 | |
707 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifndef GUARD\n" |
708 | "#define GUARD\n" |
709 | "R\"()\"\n" |
710 | "#endif\n" , |
711 | Out)); |
712 | EXPECT_STREQ("#ifndef GUARD\n" |
713 | "#define GUARD\n" |
714 | "#endif\n" , |
715 | Out.data()); |
716 | |
717 | bool RawStringLiteralResult = minimizeSourceToDependencyDirectives( |
718 | Input: "#ifndef GUARD\n" |
719 | "#define GUARD\n" |
720 | R"raw(static constexpr char bytes[] = R"(-?:\,[]{}#&*!|>'"%@`)";)raw" |
721 | "\n" |
722 | "#endif\n" , |
723 | Out); |
724 | ASSERT_FALSE(RawStringLiteralResult); |
725 | EXPECT_STREQ("#ifndef GUARD\n" |
726 | "#define GUARD\n" |
727 | "#endif\n" , |
728 | Out.data()); |
729 | |
730 | bool RawStringLiteralResult2 = minimizeSourceToDependencyDirectives( |
731 | Input: "#ifndef GUARD\n" |
732 | "#define GUARD\n" |
733 | R"raw(static constexpr char bytes[] = R"abc(-?:\,[]{}#&*!|>'"%@`)abc";)raw" |
734 | "\n" |
735 | "#endif\n" , |
736 | Out); |
737 | ASSERT_FALSE(RawStringLiteralResult2); |
738 | EXPECT_STREQ("#ifndef GUARD\n" |
739 | "#define GUARD\n" |
740 | "#endif\n" , |
741 | Out.data()); |
742 | } |
743 | |
744 | TEST(MinimizeSourceToDependencyDirectivesTest, SplitIdentifier) { |
745 | SmallVector<char, 128> Out; |
746 | |
747 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#if\\\n" |
748 | "ndef GUARD\n" |
749 | "#define GUARD\n" |
750 | "#endif\n" , |
751 | Out)); |
752 | EXPECT_STREQ("#if\\\n" |
753 | "ndef GUARD\n" |
754 | "#define GUARD\n" |
755 | "#endif\n" , |
756 | Out.data()); |
757 | |
758 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\n" |
759 | "RD\n" , |
760 | Out)); |
761 | EXPECT_STREQ("#define GUA\\\n" |
762 | "RD\n" , |
763 | Out.data()); |
764 | |
765 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\r" |
766 | "RD\n" , |
767 | Out)); |
768 | EXPECT_STREQ("#define GUA\\\r" |
769 | "RD\n" , |
770 | Out.data()); |
771 | |
772 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\n" |
773 | " RD\n" , |
774 | Out)); |
775 | EXPECT_STREQ("#define GUA RD\n" , Out.data()); |
776 | } |
777 | |
778 | TEST(MinimizeSourceToDependencyDirectivesTest, |
779 | WhitespaceAfterLineContinuationSlash) { |
780 | SmallVector<char, 128> Out; |
781 | |
782 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define A 1 + \\ \n" |
783 | "2 + \\\t\n" |
784 | "3\n" , |
785 | Out)); |
786 | EXPECT_STREQ("#define A 1+\\ \n" |
787 | "2+\\\t\n" |
788 | "3\n" , |
789 | Out.data()); |
790 | } |
791 | |
792 | TEST(MinimizeSourceToDependencyDirectivesTest, PoundWarningAndError) { |
793 | SmallVector<char, 128> Out; |
794 | |
795 | for (auto Source : { |
796 | "#warning '\n#include <t.h>\n" , |
797 | "#warning \"\n#include <t.h>\n" , |
798 | "#warning /*\n#include <t.h>\n" , |
799 | "#warning \\\n#include <t.h>\n#include <t.h>\n" , |
800 | "#error '\n#include <t.h>\n" , |
801 | "#error \"\n#include <t.h>\n" , |
802 | "#error /*\n#include <t.h>\n" , |
803 | "#error \\\n#include <t.h>\n#include <t.h>\n" , |
804 | }) { |
805 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
806 | EXPECT_STREQ("#include <t.h>\n" , Out.data()); |
807 | } |
808 | |
809 | for (auto Source : { |
810 | "#warning \\\n#include <t.h>\n" , |
811 | "#error \\\n#include <t.h>\n" , |
812 | }) { |
813 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
814 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
815 | } |
816 | |
817 | for (auto Source : { |
818 | "#if MACRO\n#warning '\n#endif\n" , |
819 | "#if MACRO\n#warning \"\n#endif\n" , |
820 | "#if MACRO\n#warning /*\n#endif\n" , |
821 | "#if MACRO\n#error '\n#endif\n" , |
822 | "#if MACRO\n#error \"\n#endif\n" , |
823 | "#if MACRO\n#error /*\n#endif\n" , |
824 | }) { |
825 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
826 | EXPECT_STREQ("#if MACRO\n#endif\n" , Out.data()); |
827 | } |
828 | } |
829 | |
830 | TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteral) { |
831 | SmallVector<char, 128> Out; |
832 | |
833 | StringRef Source = R"( |
834 | #include <bob> |
835 | int a = 0'1; |
836 | int b = 0xfa'af'fa; |
837 | int c = 12 ' '; |
838 | #include <foo> |
839 | )" ; |
840 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
841 | EXPECT_STREQ("#include <bob>\n#include <foo>\n" , Out.data()); |
842 | } |
843 | |
844 | TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixL) { |
845 | SmallVector<char, 128> Out; |
846 | |
847 | StringRef Source = R"(L'P' |
848 | #if DEBUG |
849 | // ' |
850 | #endif |
851 | #include <test.h> |
852 | )" ; |
853 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
854 | EXPECT_STREQ("#if DEBUG\n#endif\n#include <test.h>\n" , Out.data()); |
855 | } |
856 | |
857 | TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixU) { |
858 | SmallVector<char, 128> Out; |
859 | |
860 | StringRef Source = R"(int x = U'P'; |
861 | #include <test.h> |
862 | // ' |
863 | )" ; |
864 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
865 | EXPECT_STREQ("#include <test.h>\n" , Out.data()); |
866 | } |
867 | |
868 | TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixu) { |
869 | SmallVector<char, 128> Out; |
870 | |
871 | StringRef Source = R"(int x = u'b'; |
872 | int y = u8'a'; |
873 | int z = 128'78; |
874 | #include <test.h> |
875 | // ' |
876 | )" ; |
877 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
878 | EXPECT_STREQ("#include <test.h>\n" , Out.data()); |
879 | } |
880 | |
881 | TEST(MinimizeSourceToDependencyDirectivesTest, PragmaOnce) { |
882 | SmallVector<char, 128> Out; |
883 | SmallVector<dependency_directives_scan::Token, 4> Tokens; |
884 | SmallVector<Directive, 4> Directives; |
885 | |
886 | StringRef Source = R"(// comment |
887 | #pragma once |
888 | // another comment |
889 | #include <test.h> |
890 | _Pragma("once") |
891 | )" ; |
892 | ASSERT_FALSE( |
893 | minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives)); |
894 | EXPECT_STREQ("#pragma once\n#include <test.h>\n_Pragma(\"once\")\n" , |
895 | Out.data()); |
896 | ASSERT_EQ(Directives.size(), 4u); |
897 | EXPECT_EQ(Directives[0].Kind, dependency_directives_scan::pp_pragma_once); |
898 | EXPECT_EQ(Directives[2].Kind, dependency_directives_scan::pp_pragma_once); |
899 | |
900 | Source = R"(// comment |
901 | #pragma once extra tokens |
902 | // another comment |
903 | #include <test.h> |
904 | _Pragma("once") extra tokens |
905 | )" ; |
906 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
907 | EXPECT_STREQ("#pragma once extra tokens\n#include " |
908 | "<test.h>\n_Pragma(\"once\")<TokBeforeEOF>\n" , |
909 | Out.data()); |
910 | } |
911 | |
912 | TEST(MinimizeSourceToDependencyDirectivesTest, |
913 | SkipLineStringCharLiteralsUntilNewline) { |
914 | SmallVector<char, 128> Out; |
915 | |
916 | StringRef Source = R"(#if NEVER_ENABLED |
917 | #define why(fmt, ...) #error don't try me |
918 | #endif |
919 | |
920 | void foo(); |
921 | )" ; |
922 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
923 | EXPECT_STREQ( |
924 | "#if NEVER_ENABLED\n#define why(fmt,...) #error don't try me\n#endif\n" |
925 | "<TokBeforeEOF>\n" , |
926 | Out.data()); |
927 | |
928 | Source = R"(#if NEVER_ENABLED |
929 | #define why(fmt, ...) "quote dropped |
930 | #endif |
931 | |
932 | void foo(); |
933 | )" ; |
934 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
935 | EXPECT_STREQ( |
936 | "#if NEVER_ENABLED\n#define why(fmt,...) \"quote dropped\n#endif\n" |
937 | "<TokBeforeEOF>\n" , |
938 | Out.data()); |
939 | } |
940 | |
941 | TEST(MinimizeSourceToDependencyDirectivesTest, |
942 | SupportWhitespaceBeforeLineContinuation) { |
943 | SmallVector<char, 128> Out; |
944 | |
945 | ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define FOO(BAR) \\\n" |
946 | " #BAR\\\n" |
947 | " baz\n" , |
948 | Out)); |
949 | EXPECT_STREQ("#define FOO(BAR) #BAR baz\n" , Out.data()); |
950 | } |
951 | |
952 | TEST(MinimizeSourceToDependencyDirectivesTest, |
953 | SupportWhitespaceBeforeLineContinuationInStringSkipping) { |
954 | SmallVector<char, 128> Out; |
955 | |
956 | StringRef Source = "#define X '\\ \t\nx'\nvoid foo() {}" ; |
957 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
958 | EXPECT_STREQ("#define X '\\ \t\nx'\n<TokBeforeEOF>\n" , Out.data()); |
959 | |
960 | Source = "#define X \"\\ \r\nx\"\nvoid foo() {}" ; |
961 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
962 | EXPECT_STREQ("#define X \"\\ \r\nx\"\n<TokBeforeEOF>\n" , Out.data()); |
963 | |
964 | Source = "#define X \"\\ \r\nx\n#include <x>\n" ; |
965 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
966 | EXPECT_STREQ("#define X\"\\ \r\nx\n#include <x>\n" , Out.data()); |
967 | } |
968 | |
969 | TEST(MinimizeSourceToDependencyDirectivesTest, CxxModules) { |
970 | SmallVector<char, 128> Out; |
971 | SmallVector<dependency_directives_scan::Token, 4> Tokens; |
972 | SmallVector<Directive, 4> Directives; |
973 | |
974 | StringRef Source = R"( |
975 | module; |
976 | #include "textual-header.h" |
977 | |
978 | export module m; |
979 | exp\ |
980 | ort \ |
981 | import \ |
982 | :l [[rename]]; |
983 | |
984 | export void f(); |
985 | |
986 | void h() { |
987 | import.a = 3; |
988 | import = 3; |
989 | import <<= 3; |
990 | import->a = 3; |
991 | import(); |
992 | import . a(); |
993 | |
994 | import a b d e d e f e; |
995 | import foo [[no_unique_address]]; |
996 | import foo(); |
997 | import f(:sefse); |
998 | import f(->a = 3); |
999 | } |
1000 | )" ; |
1001 | ASSERT_FALSE( |
1002 | minimizeSourceToDependencyDirectives(Source, Out, Tokens, Directives)); |
1003 | EXPECT_STREQ("#include \"textual-header.h\"\nexport module m;" |
1004 | "exp\\\nort import:l[[rename]];" |
1005 | "import<<=3;import a b d e d e f e;" |
1006 | "import foo[[no_unique_address]];import foo();" |
1007 | "import f(:sefse);import f(->a=3);" |
1008 | "<TokBeforeEOF>\n" , |
1009 | Out.data()); |
1010 | ASSERT_EQ(Directives.size(), 11u); |
1011 | EXPECT_EQ(Directives[0].Kind, pp_include); |
1012 | EXPECT_EQ(Directives[1].Kind, cxx_export_module_decl); |
1013 | } |
1014 | |
1015 | TEST(MinimizeSourceToDependencyDirectivesTest, ObjCMethodArgs) { |
1016 | SmallVector<char, 128> Out; |
1017 | |
1018 | StringRef Source = R"( |
1019 | @interface SomeObjcClass |
1020 | - (void)func:(int)otherData |
1021 | module:(int)module |
1022 | import:(int)import; |
1023 | @end |
1024 | )" ; |
1025 | |
1026 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
1027 | // `module :` and `import :` not followed by an identifier are not treated as |
1028 | // directive lines because they can be method argument decls. |
1029 | EXPECT_STREQ("<TokBeforeEOF>\n" , Out.data()); |
1030 | } |
1031 | |
1032 | TEST(MinimizeSourceToDependencyDirectivesTest, TokensBeforeEOF) { |
1033 | SmallString<128> Out; |
1034 | |
1035 | StringRef Source = R"( |
1036 | #define A |
1037 | #ifdef B |
1038 | int x; |
1039 | #endif |
1040 | )" ; |
1041 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
1042 | EXPECT_STREQ("#define A\n<TokBeforeEOF>\n" , Out.data()); |
1043 | |
1044 | Source = R"( |
1045 | #ifndef A |
1046 | #define A |
1047 | #endif // some comment |
1048 | |
1049 | // other comment |
1050 | )" ; |
1051 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
1052 | EXPECT_STREQ("#ifndef A\n#define A\n#endif\n" , Out.data()); |
1053 | |
1054 | Source = R"( |
1055 | #ifndef A |
1056 | #define A |
1057 | #endif /* some comment |
1058 | |
1059 | */ |
1060 | )" ; |
1061 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
1062 | EXPECT_STREQ("#ifndef A\n#define A\n#endif\n" , Out.data()); |
1063 | |
1064 | Source = R"( |
1065 | #ifndef A |
1066 | #define A |
1067 | #endif /* some comment |
1068 | |
1069 | */ |
1070 | int x; |
1071 | )" ; |
1072 | ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out)); |
1073 | EXPECT_STREQ("#ifndef A\n#define A\n#endif\n<TokBeforeEOF>\n" , Out.data()); |
1074 | } |
1075 | |
1076 | } // end anonymous namespace |
1077 | |