DependencyDirectivesSourceMinimizerTest.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. //===- unittests/Lex/DependencyDirectivesSourceMinimizer.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. #include "clang/Lex/DependencyDirectivesSourceMinimizer.h"
  9. #include "llvm/ADT/SmallString.h"
  10. #include "gtest/gtest.h"
  11. using namespace llvm;
  12. using namespace clang;
  13. using namespace clang::minimize_source_to_dependency_directives;
  14. namespace clang {
  15. bool minimizeSourceToDependencyDirectives(StringRef Input,
  16. SmallVectorImpl<char> &Out) {
  17. SmallVector<minimize_source_to_dependency_directives::Token, 32> Tokens;
  18. return minimizeSourceToDependencyDirectives(Input, Out, Tokens);
  19. }
  20. } // end namespace clang
  21. namespace {
  22. TEST(MinimizeSourceToDependencyDirectivesTest, Empty) {
  23. SmallVector<char, 128> Out;
  24. SmallVector<Token, 4> Tokens;
  25. ASSERT_FALSE(minimizeSourceToDependencyDirectives("", Out, Tokens));
  26. EXPECT_TRUE(Out.empty());
  27. ASSERT_EQ(1u, Tokens.size());
  28. ASSERT_EQ(pp_eof, Tokens.back().K);
  29. ASSERT_FALSE(
  30. minimizeSourceToDependencyDirectives("abc def\nxyz", Out, Tokens));
  31. EXPECT_TRUE(Out.empty());
  32. ASSERT_EQ(1u, Tokens.size());
  33. ASSERT_EQ(pp_eof, Tokens.back().K);
  34. }
  35. TEST(MinimizeSourceToDependencyDirectivesTest, AllTokens) {
  36. SmallVector<char, 128> Out;
  37. SmallVector<Token, 4> Tokens;
  38. ASSERT_FALSE(
  39. minimizeSourceToDependencyDirectives("#define A\n"
  40. "#undef A\n"
  41. "#endif\n"
  42. "#if A\n"
  43. "#ifdef A\n"
  44. "#ifndef A\n"
  45. "#elif A\n"
  46. "#else\n"
  47. "#include <A>\n"
  48. "#include_next <A>\n"
  49. "#__include_macros <A>\n"
  50. "#import <A>\n"
  51. "@import A;\n"
  52. "#pragma clang module import A\n"
  53. "export module m;\n"
  54. "import m;\n",
  55. Out, Tokens));
  56. EXPECT_EQ(pp_define, Tokens[0].K);
  57. EXPECT_EQ(pp_undef, Tokens[1].K);
  58. EXPECT_EQ(pp_endif, Tokens[2].K);
  59. EXPECT_EQ(pp_if, Tokens[3].K);
  60. EXPECT_EQ(pp_ifdef, Tokens[4].K);
  61. EXPECT_EQ(pp_ifndef, Tokens[5].K);
  62. EXPECT_EQ(pp_elif, Tokens[6].K);
  63. EXPECT_EQ(pp_else, Tokens[7].K);
  64. EXPECT_EQ(pp_include, Tokens[8].K);
  65. EXPECT_EQ(pp_include_next, Tokens[9].K);
  66. EXPECT_EQ(pp___include_macros, Tokens[10].K);
  67. EXPECT_EQ(pp_import, Tokens[11].K);
  68. EXPECT_EQ(decl_at_import, Tokens[12].K);
  69. EXPECT_EQ(pp_pragma_import, Tokens[13].K);
  70. EXPECT_EQ(cxx_export_decl, Tokens[14].K);
  71. EXPECT_EQ(cxx_module_decl, Tokens[15].K);
  72. EXPECT_EQ(cxx_import_decl, Tokens[16].K);
  73. EXPECT_EQ(pp_eof, Tokens[17].K);
  74. }
  75. TEST(MinimizeSourceToDependencyDirectivesTest, Define) {
  76. SmallVector<char, 128> Out;
  77. SmallVector<Token, 4> Tokens;
  78. ASSERT_FALSE(
  79. minimizeSourceToDependencyDirectives("#define MACRO", Out, Tokens));
  80. EXPECT_STREQ("#define MACRO\n", Out.data());
  81. ASSERT_EQ(2u, Tokens.size());
  82. ASSERT_EQ(pp_define, Tokens.front().K);
  83. }
  84. TEST(MinimizeSourceToDependencyDirectivesTest, DefineSpacing) {
  85. SmallVector<char, 128> Out;
  86. ASSERT_FALSE(
  87. minimizeSourceToDependencyDirectives("#define MACRO\n\n\n", Out));
  88. EXPECT_STREQ("#define MACRO\n", Out.data());
  89. ASSERT_FALSE(
  90. minimizeSourceToDependencyDirectives("#define MACRO \n\n\n", Out));
  91. EXPECT_STREQ("#define MACRO\n", Out.data());
  92. ASSERT_FALSE(
  93. minimizeSourceToDependencyDirectives("#define MACRO a \n\n\n", Out));
  94. EXPECT_STREQ("#define MACRO a\n", Out.data());
  95. ASSERT_FALSE(
  96. minimizeSourceToDependencyDirectives("#define MACRO\n\n\n", Out));
  97. EXPECT_STREQ("#define MACRO\n", Out.data());
  98. }
  99. TEST(MinimizeSourceToDependencyDirectivesTest, DefineMacroArguments) {
  100. SmallVector<char, 128> Out;
  101. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO()", Out));
  102. EXPECT_STREQ("#define MACRO()\n", Out.data());
  103. ASSERT_FALSE(
  104. minimizeSourceToDependencyDirectives("#define MACRO(a, b...)", Out));
  105. EXPECT_STREQ("#define MACRO(a,b...)\n", Out.data());
  106. ASSERT_FALSE(
  107. minimizeSourceToDependencyDirectives("#define MACRO content", Out));
  108. EXPECT_STREQ("#define MACRO content\n", Out.data());
  109. ASSERT_FALSE(minimizeSourceToDependencyDirectives(
  110. "#define MACRO con tent ", Out));
  111. EXPECT_STREQ("#define MACRO con tent\n", Out.data());
  112. ASSERT_FALSE(minimizeSourceToDependencyDirectives(
  113. "#define MACRO() con tent ", Out));
  114. EXPECT_STREQ("#define MACRO() con tent\n", Out.data());
  115. }
  116. TEST(MinimizeSourceToDependencyDirectivesTest, DefineInvalidMacroArguments) {
  117. SmallVector<char, 128> Out;
  118. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO((a))", Out));
  119. EXPECT_STREQ("#define MACRO(/* invalid */\n", Out.data());
  120. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO(", Out));
  121. EXPECT_STREQ("#define MACRO(/* invalid */\n", Out.data());
  122. ASSERT_FALSE(
  123. minimizeSourceToDependencyDirectives("#define MACRO(a * b)", Out));
  124. EXPECT_STREQ("#define MACRO(/* invalid */\n", Out.data());
  125. }
  126. TEST(MinimizeSourceToDependencyDirectivesTest, DefineHorizontalWhitespace) {
  127. SmallVector<char, 128> Out;
  128. ASSERT_FALSE(minimizeSourceToDependencyDirectives(
  129. "#define MACRO(\t)\tcon \t tent\t", Out));
  130. EXPECT_STREQ("#define MACRO() con \t tent\n", Out.data());
  131. ASSERT_FALSE(minimizeSourceToDependencyDirectives(
  132. "#define MACRO(\f)\fcon \f tent\f", Out));
  133. EXPECT_STREQ("#define MACRO() con \f tent\n", Out.data());
  134. ASSERT_FALSE(minimizeSourceToDependencyDirectives(
  135. "#define MACRO(\v)\vcon \v tent\v", Out));
  136. EXPECT_STREQ("#define MACRO() con \v tent\n", Out.data());
  137. ASSERT_FALSE(minimizeSourceToDependencyDirectives(
  138. "#define MACRO \t\v\f\v\t con\f\t\vtent\v\f \v", Out));
  139. EXPECT_STREQ("#define MACRO con\f\t\vtent\n", Out.data());
  140. }
  141. TEST(MinimizeSourceToDependencyDirectivesTest, DefineMultilineArgs) {
  142. SmallVector<char, 128> Out;
  143. ASSERT_FALSE(
  144. minimizeSourceToDependencyDirectives("#define MACRO(a \\\n"
  145. " )",
  146. Out));
  147. EXPECT_STREQ("#define MACRO(a)\n", Out.data());
  148. ASSERT_FALSE(
  149. minimizeSourceToDependencyDirectives("#define MACRO(a, \\\n"
  150. " b) \\\n"
  151. " call((a), \\\n"
  152. " (b))",
  153. Out));
  154. EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
  155. }
  156. TEST(MinimizeSourceToDependencyDirectivesTest,
  157. DefineMultilineArgsCarriageReturn) {
  158. SmallVector<char, 128> Out;
  159. ASSERT_FALSE(
  160. minimizeSourceToDependencyDirectives("#define MACRO(a, \\\r"
  161. " b) \\\r"
  162. " call((a), \\\r"
  163. " (b))",
  164. Out));
  165. EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
  166. }
  167. TEST(MinimizeSourceToDependencyDirectivesTest, DefineMultilineArgsStringize) {
  168. SmallVector<char, 128> Out;
  169. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO(a,b) \\\n"
  170. " #a \\\n"
  171. " #b",
  172. Out));
  173. EXPECT_STREQ("#define MACRO(a,b) #a #b\n", Out.data());
  174. }
  175. TEST(MinimizeSourceToDependencyDirectivesTest,
  176. DefineMultilineArgsCarriageReturnNewline) {
  177. SmallVector<char, 128> Out;
  178. ASSERT_FALSE(
  179. minimizeSourceToDependencyDirectives("#define MACRO(a, \\\r\n"
  180. " b) \\\r\n"
  181. " call((a), \\\r\n"
  182. " (b))",
  183. Out));
  184. EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
  185. }
  186. TEST(MinimizeSourceToDependencyDirectivesTest,
  187. DefineMultilineArgsNewlineCarriageReturn) {
  188. SmallVector<char, 128> Out;
  189. ASSERT_FALSE(
  190. minimizeSourceToDependencyDirectives("#define MACRO(a, \\\n\r"
  191. " b) \\\n\r"
  192. " call((a), \\\n\r"
  193. " (b))",
  194. Out));
  195. EXPECT_STREQ("#define MACRO(a,b) call((a), (b))\n", Out.data());
  196. }
  197. TEST(MinimizeSourceToDependencyDirectivesTest, DefineNumber) {
  198. SmallVector<char, 128> Out;
  199. ASSERT_TRUE(minimizeSourceToDependencyDirectives("#define 0\n", Out));
  200. }
  201. TEST(MinimizeSourceToDependencyDirectivesTest, DefineNoName) {
  202. SmallVector<char, 128> Out;
  203. ASSERT_TRUE(minimizeSourceToDependencyDirectives("#define &\n", Out));
  204. }
  205. TEST(MinimizeSourceToDependencyDirectivesTest, DefineNoWhitespace) {
  206. SmallVector<char, 128> Out;
  207. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define AND&\n", Out));
  208. EXPECT_STREQ("#define AND &\n", Out.data());
  209. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define AND\\\n"
  210. "&\n",
  211. Out));
  212. EXPECT_STREQ("#define AND &\n", Out.data());
  213. }
  214. TEST(MinimizeSourceToDependencyDirectivesTest, MultilineComment) {
  215. SmallVector<char, 128> Out;
  216. ASSERT_FALSE(
  217. minimizeSourceToDependencyDirectives("#define MACRO a/*\n"
  218. " /*\n"
  219. "#define MISSING abc\n"
  220. " /*\n"
  221. " /* something */ \n"
  222. "#include /* \"def\" */ <abc> \n",
  223. Out));
  224. EXPECT_STREQ("#define MACRO a\n"
  225. "#include <abc>\n",
  226. Out.data());
  227. }
  228. TEST(MinimizeSourceToDependencyDirectivesTest, MultilineCommentInStrings) {
  229. SmallVector<char, 128> Out;
  230. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define MACRO1 \"/*\"\n"
  231. "#define MACRO2 \"*/\"\n",
  232. Out));
  233. EXPECT_STREQ("#define MACRO1 \"/*\"\n"
  234. "#define MACRO2 \"*/\"\n",
  235. Out.data());
  236. }
  237. TEST(MinimizeSourceToDependencyDirectivesTest, Ifdef) {
  238. SmallVector<char, 128> Out;
  239. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
  240. "#define B\n"
  241. "#endif\n",
  242. Out));
  243. EXPECT_STREQ("#ifdef A\n"
  244. "#define B\n"
  245. "#endif\n",
  246. Out.data());
  247. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
  248. "#define B\n"
  249. "#elif B\n"
  250. "#define C\n"
  251. "#elif C\n"
  252. "#define D\n"
  253. "#else\n"
  254. "#define E\n"
  255. "#endif\n",
  256. Out));
  257. EXPECT_STREQ("#ifdef A\n"
  258. "#define B\n"
  259. "#elif B\n"
  260. "#define C\n"
  261. "#elif C\n"
  262. "#define D\n"
  263. "#else\n"
  264. "#define E\n"
  265. "#endif\n",
  266. Out.data());
  267. }
  268. TEST(MinimizeSourceToDependencyDirectivesTest, EmptyIfdef) {
  269. SmallVector<char, 128> Out;
  270. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifdef A\n"
  271. "#elif B\n"
  272. "#elif C\n"
  273. "#else D\n"
  274. "#endif\n",
  275. Out));
  276. EXPECT_STREQ("", Out.data());
  277. }
  278. TEST(MinimizeSourceToDependencyDirectivesTest, Pragma) {
  279. SmallVector<char, 128> Out;
  280. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#pragma A\n", Out));
  281. EXPECT_STREQ("", Out.data());
  282. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#pragma clang\n", Out));
  283. EXPECT_STREQ("", Out.data());
  284. ASSERT_FALSE(
  285. minimizeSourceToDependencyDirectives("#pragma clang module\n", Out));
  286. EXPECT_STREQ("", Out.data());
  287. ASSERT_FALSE(minimizeSourceToDependencyDirectives(
  288. "#pragma clang module impor\n", Out));
  289. EXPECT_STREQ("", Out.data());
  290. ASSERT_FALSE(minimizeSourceToDependencyDirectives(
  291. "#pragma clang module import\n", Out));
  292. EXPECT_STREQ("#pragma clang module import\n", Out.data());
  293. }
  294. TEST(MinimizeSourceToDependencyDirectivesTest, Include) {
  295. SmallVector<char, 128> Out;
  296. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include \"A\"\n", Out));
  297. EXPECT_STREQ("#include \"A\"\n", Out.data());
  298. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#include <A>\n", Out));
  299. EXPECT_STREQ("#include <A>\n", Out.data());
  300. ASSERT_FALSE(
  301. minimizeSourceToDependencyDirectives("#include_next <A>\n", Out));
  302. EXPECT_STREQ("#include_next <A>\n", Out.data());
  303. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#import <A>\n", Out));
  304. EXPECT_STREQ("#import <A>\n", Out.data());
  305. ASSERT_FALSE(
  306. minimizeSourceToDependencyDirectives("#__include_macros <A>\n", Out));
  307. EXPECT_STREQ("#__include_macros <A>\n", Out.data());
  308. }
  309. TEST(MinimizeSourceToDependencyDirectivesTest, AtImport) {
  310. SmallVector<char, 128> Out;
  311. ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A;\n", Out));
  312. EXPECT_STREQ("@import A;\n", Out.data());
  313. ASSERT_FALSE(minimizeSourceToDependencyDirectives(" @ import A;\n", Out));
  314. EXPECT_STREQ("@import A;\n", Out.data());
  315. ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A\n;", Out));
  316. EXPECT_STREQ("@import A;\n", Out.data());
  317. ASSERT_FALSE(minimizeSourceToDependencyDirectives("@import A.B;\n", Out));
  318. EXPECT_STREQ("@import A.B;\n", Out.data());
  319. ASSERT_FALSE(minimizeSourceToDependencyDirectives(
  320. "@import /*x*/ A /*x*/ . /*x*/ B /*x*/ \n /*x*/ ; /*x*/", Out));
  321. EXPECT_STREQ("@import A.B;\n", Out.data());
  322. }
  323. TEST(MinimizeSourceToDependencyDirectivesTest, AtImportFailures) {
  324. SmallVector<char, 128> Out;
  325. ASSERT_TRUE(minimizeSourceToDependencyDirectives("@import A\n", Out));
  326. ASSERT_TRUE(minimizeSourceToDependencyDirectives("@import MACRO(A);\n", Out));
  327. ASSERT_TRUE(minimizeSourceToDependencyDirectives("@import \" \";\n", Out));
  328. }
  329. TEST(MinimizeSourceToDependencyDirectivesTest, RawStringLiteral) {
  330. SmallVector<char, 128> Out;
  331. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#ifndef GUARD\n"
  332. "#define GUARD\n"
  333. "R\"()\"\n"
  334. "#endif\n",
  335. Out));
  336. EXPECT_STREQ("#ifndef GUARD\n"
  337. "#define GUARD\n"
  338. "#endif\n",
  339. Out.data());
  340. bool RawStringLiteralResult = minimizeSourceToDependencyDirectives(
  341. "#ifndef GUARD\n"
  342. "#define GUARD\n"
  343. R"raw(static constexpr char bytes[] = R"(-?:\,[]{}#&*!|>'"%@`)";)raw"
  344. "\n"
  345. "#endif\n",
  346. Out);
  347. ASSERT_FALSE(RawStringLiteralResult);
  348. EXPECT_STREQ("#ifndef GUARD\n"
  349. "#define GUARD\n"
  350. "#endif\n",
  351. Out.data());
  352. bool RawStringLiteralResult2 = minimizeSourceToDependencyDirectives(
  353. "#ifndef GUARD\n"
  354. "#define GUARD\n"
  355. R"raw(static constexpr char bytes[] = R"abc(-?:\,[]{}#&*!|>'"%@`)abc";)raw"
  356. "\n"
  357. "#endif\n",
  358. Out);
  359. ASSERT_FALSE(RawStringLiteralResult2);
  360. EXPECT_STREQ("#ifndef GUARD\n"
  361. "#define GUARD\n"
  362. "#endif\n",
  363. Out.data());
  364. }
  365. TEST(MinimizeSourceToDependencyDirectivesTest, SplitIdentifier) {
  366. SmallVector<char, 128> Out;
  367. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#if\\\n"
  368. "ndef GUARD\n"
  369. "#define GUARD\n"
  370. "#endif\n",
  371. Out));
  372. EXPECT_STREQ("#ifndef GUARD\n"
  373. "#define GUARD\n"
  374. "#endif\n",
  375. Out.data());
  376. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\n"
  377. "RD\n",
  378. Out));
  379. EXPECT_STREQ("#define GUARD\n", Out.data());
  380. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\r"
  381. "RD\n",
  382. Out));
  383. EXPECT_STREQ("#define GUARD\n", Out.data());
  384. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define GUA\\\n"
  385. " RD\n",
  386. Out));
  387. EXPECT_STREQ("#define GUA RD\n", Out.data());
  388. }
  389. TEST(MinimizeSourceToDependencyDirectivesTest,
  390. WhitespaceAfterLineContinuationSlash) {
  391. SmallVector<char, 128> Out;
  392. ASSERT_FALSE(minimizeSourceToDependencyDirectives("#define A 1 + \\ \n"
  393. "2 + \\\t\n"
  394. "3\n",
  395. Out));
  396. EXPECT_STREQ("#define A 1 + 2 + 3\n", Out.data());
  397. }
  398. TEST(MinimizeSourceToDependencyDirectivesTest, PoundWarningAndError) {
  399. SmallVector<char, 128> Out;
  400. for (auto Source : {
  401. "#warning '\n#include <t.h>\n",
  402. "#warning \"\n#include <t.h>\n",
  403. "#warning /*\n#include <t.h>\n",
  404. "#warning \\\n#include <t.h>\n#include <t.h>\n",
  405. "#error '\n#include <t.h>\n",
  406. "#error \"\n#include <t.h>\n",
  407. "#error /*\n#include <t.h>\n",
  408. "#error \\\n#include <t.h>\n#include <t.h>\n",
  409. }) {
  410. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  411. EXPECT_STREQ("#include <t.h>\n", Out.data());
  412. }
  413. for (auto Source : {
  414. "#warning \\\n#include <t.h>\n",
  415. "#error \\\n#include <t.h>\n",
  416. "#if MACRO\n#warning '\n#endif\n",
  417. "#if MACRO\n#warning \"\n#endif\n",
  418. "#if MACRO\n#warning /*\n#endif\n",
  419. "#if MACRO\n#error '\n#endif\n",
  420. "#if MACRO\n#error \"\n#endif\n",
  421. "#if MACRO\n#error /*\n#endif\n",
  422. }) {
  423. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  424. EXPECT_STREQ("", Out.data());
  425. }
  426. }
  427. TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteral) {
  428. SmallVector<char, 128> Out;
  429. StringRef Source = R"(
  430. #include <bob>
  431. int a = 0'1;
  432. int b = 0xfa'af'fa;
  433. int c = 12 ' ';
  434. #include <foo>
  435. )";
  436. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  437. EXPECT_STREQ("#include <bob>\n#include <foo>\n", Out.data());
  438. }
  439. TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixL) {
  440. SmallVector<char, 128> Out;
  441. StringRef Source = R"(L'P'
  442. #if DEBUG
  443. // '
  444. #endif
  445. #include <test.h>
  446. )";
  447. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  448. EXPECT_STREQ("#include <test.h>\n", Out.data());
  449. }
  450. TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixU) {
  451. SmallVector<char, 128> Out;
  452. StringRef Source = R"(int x = U'P';
  453. #include <test.h>
  454. // '
  455. )";
  456. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  457. EXPECT_STREQ("#include <test.h>\n", Out.data());
  458. }
  459. TEST(MinimizeSourceToDependencyDirectivesTest, CharacterLiteralPrefixu) {
  460. SmallVector<char, 128> Out;
  461. StringRef Source = R"(int x = u'b';
  462. int y = u8'a';
  463. int z = 128'78;
  464. #include <test.h>
  465. // '
  466. )";
  467. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  468. EXPECT_STREQ("#include <test.h>\n", Out.data());
  469. }
  470. TEST(MinimizeSourceToDependencyDirectivesTest, PragmaOnce) {
  471. SmallVector<char, 128> Out;
  472. SmallVector<Token, 4> Tokens;
  473. StringRef Source = R"(// comment
  474. #pragma once
  475. // another comment
  476. #include <test.h>
  477. )";
  478. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out, Tokens));
  479. EXPECT_STREQ("#pragma once\n#include <test.h>\n", Out.data());
  480. ASSERT_EQ(Tokens.size(), 3u);
  481. EXPECT_EQ(Tokens[0].K,
  482. minimize_source_to_dependency_directives::pp_pragma_once);
  483. Source = R"(// comment
  484. #pragma once extra tokens
  485. // another comment
  486. #include <test.h>
  487. )";
  488. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  489. EXPECT_STREQ("#pragma once\n#include <test.h>\n", Out.data());
  490. }
  491. TEST(MinimizeSourceToDependencyDirectivesTest,
  492. SkipLineStringCharLiteralsUntilNewline) {
  493. SmallVector<char, 128> Out;
  494. StringRef Source = R"(#if NEVER_ENABLED
  495. #define why(fmt, ...) #error don't try me
  496. #endif
  497. void foo();
  498. )";
  499. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  500. EXPECT_STREQ(
  501. "#if NEVER_ENABLED\n#define why(fmt,...) #error don't try me\n#endif\n",
  502. Out.data());
  503. Source = R"(#if NEVER_ENABLED
  504. #define why(fmt, ...) "quote dropped
  505. #endif
  506. void foo();
  507. )";
  508. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  509. EXPECT_STREQ(
  510. "#if NEVER_ENABLED\n#define why(fmt,...) \"quote dropped\n#endif\n",
  511. Out.data());
  512. }
  513. TEST(MinimizeSourceToDependencyDirectivesTest,
  514. SupportWhitespaceBeforeLineContinuationInStringSkipping) {
  515. SmallVector<char, 128> Out;
  516. StringRef Source = "#define X '\\ \t\nx'\nvoid foo() {}";
  517. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  518. EXPECT_STREQ("#define X '\\ \t\nx'\n", Out.data());
  519. Source = "#define X \"\\ \r\nx\"\nvoid foo() {}";
  520. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  521. EXPECT_STREQ("#define X \"\\ \r\nx\"\n", Out.data());
  522. Source = "#define X \"\\ \r\nx\n#include <x>\n";
  523. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out));
  524. EXPECT_STREQ("#define X \"\\ \r\nx\n#include <x>\n", Out.data());
  525. }
  526. TEST(MinimizeSourceToDependencyDirectivesTest, CxxModules) {
  527. SmallVector<char, 128> Out;
  528. SmallVector<Token, 4> Tokens;
  529. StringRef Source = R"(
  530. module;
  531. #include "textual-header.h"
  532. export module m;
  533. exp\
  534. ort \
  535. import \
  536. :l [[rename]];
  537. export void f();
  538. void h() {
  539. import.a = 3;
  540. import = 3;
  541. import <<= 3;
  542. import->a = 3;
  543. import();
  544. import . a();
  545. import a b d e d e f e;
  546. import foo [[no_unique_address]];
  547. import foo();
  548. import f(:sefse);
  549. import f(->a = 3);
  550. }
  551. )";
  552. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out, Tokens));
  553. EXPECT_STREQ("#include \"textual-header.h\"\nexport module m;\n"
  554. "export import :l [[rename]];\n"
  555. "import <<= 3;\nimport a b d e d e f e;\n"
  556. "import foo [[no_unique_address]];\nimport foo();\n"
  557. "import f(:sefse);\nimport f(->a = 3);\n", Out.data());
  558. ASSERT_EQ(Tokens.size(), 12u);
  559. EXPECT_EQ(Tokens[0].K,
  560. minimize_source_to_dependency_directives::pp_include);
  561. EXPECT_EQ(Tokens[2].K,
  562. minimize_source_to_dependency_directives::cxx_module_decl);
  563. }
  564. TEST(MinimizeSourceToDependencyDirectivesTest, SkippedPPRangesBasic) {
  565. SmallString<128> Out;
  566. SmallVector<Token, 32> Toks;
  567. StringRef Source = "#ifndef GUARD\n"
  568. "#define GUARD\n"
  569. "void foo();\n"
  570. "#endif\n";
  571. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out, Toks));
  572. SmallVector<SkippedRange, 4> Ranges;
  573. ASSERT_FALSE(computeSkippedRanges(Toks, Ranges));
  574. EXPECT_EQ(Ranges.size(), 1u);
  575. EXPECT_EQ(Ranges[0].Offset, 0);
  576. EXPECT_EQ(Ranges[0].Length, (int)Out.find("#endif"));
  577. }
  578. TEST(MinimizeSourceToDependencyDirectivesTest, SkippedPPRangesNested) {
  579. SmallString<128> Out;
  580. SmallVector<Token, 32> Toks;
  581. StringRef Source = "#ifndef GUARD\n"
  582. "#define GUARD\n"
  583. "#if FOO\n"
  584. "#include hello\n"
  585. "#elif BAR\n"
  586. "#include bye\n"
  587. "#endif\n"
  588. "#else\n"
  589. "#include nothing\n"
  590. "#endif\n";
  591. ASSERT_FALSE(minimizeSourceToDependencyDirectives(Source, Out, Toks));
  592. SmallVector<SkippedRange, 4> Ranges;
  593. ASSERT_FALSE(computeSkippedRanges(Toks, Ranges));
  594. EXPECT_EQ(Ranges.size(), 4u);
  595. EXPECT_EQ(Ranges[0].Offset, (int)Out.find("#if FOO"));
  596. EXPECT_EQ(Ranges[0].Offset + Ranges[0].Length, (int)Out.find("#elif"));
  597. EXPECT_EQ(Ranges[1].Offset, (int)Out.find("#elif BAR"));
  598. EXPECT_EQ(Ranges[1].Offset + Ranges[1].Length, (int)Out.find("#endif"));
  599. EXPECT_EQ(Ranges[2].Offset, 0);
  600. EXPECT_EQ(Ranges[2].Length, (int)Out.find("#else"));
  601. EXPECT_EQ(Ranges[3].Offset, (int)Out.find("#else"));
  602. EXPECT_EQ(Ranges[3].Offset + Ranges[3].Length, (int)Out.rfind("#endif"));
  603. }
  604. } // end anonymous namespace