ASTImporterVisibilityTest.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. //===- unittest/AST/ASTImporterTest.cpp - AST node import test ------------===//
  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. // Type-parameterized tests for the correct import of Decls with different
  10. // visibility.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. // Define this to have ::testing::Combine available.
  14. // FIXME: Better solution for this?
  15. #define GTEST_HAS_COMBINE 1
  16. #include "ASTImporterFixtures.h"
  17. namespace clang {
  18. namespace ast_matchers {
  19. using internal::BindableMatcher;
  20. // Type parameters for type-parameterized test fixtures.
  21. struct GetFunPattern {
  22. using DeclTy = FunctionDecl;
  23. BindableMatcher<Decl> operator()() { return functionDecl(hasName("f")); }
  24. };
  25. struct GetVarPattern {
  26. using DeclTy = VarDecl;
  27. BindableMatcher<Decl> operator()() { return varDecl(hasName("v")); }
  28. };
  29. struct GetClassPattern {
  30. using DeclTy = CXXRecordDecl;
  31. BindableMatcher<Decl> operator()() { return cxxRecordDecl(hasName("X")); }
  32. };
  33. struct GetEnumPattern {
  34. using DeclTy = EnumDecl;
  35. BindableMatcher<Decl> operator()() { return enumDecl(hasName("E")); }
  36. };
  37. struct GetTypedefNamePattern {
  38. using DeclTy = TypedefNameDecl;
  39. BindableMatcher<Decl> operator()() { return typedefNameDecl(hasName("T")); }
  40. };
  41. struct GetFunTemplPattern {
  42. using DeclTy = FunctionTemplateDecl;
  43. BindableMatcher<Decl> operator()() {
  44. return functionTemplateDecl(hasName("f"));
  45. }
  46. };
  47. // Values for the value-parameterized test fixtures.
  48. // FunctionDecl:
  49. const auto *ExternF = "void f();";
  50. const auto *StaticF = "static void f();";
  51. const auto *AnonF = "namespace { void f(); }";
  52. // VarDecl:
  53. const auto *ExternV = "extern int v;";
  54. const auto *StaticV = "static int v;";
  55. const auto *AnonV = "namespace { extern int v; }";
  56. // CXXRecordDecl:
  57. const auto *ExternC = "class X;";
  58. const auto *AnonC = "namespace { class X; }";
  59. // EnumDecl:
  60. const auto *ExternE = "enum E {};";
  61. const auto *AnonE = "namespace { enum E {}; }";
  62. // TypedefNameDecl:
  63. const auto *ExternTypedef = "typedef int T;";
  64. const auto *AnonTypedef = "namespace { typedef int T; }";
  65. const auto *ExternUsing = "using T = int;";
  66. const auto *AnonUsing = "namespace { using T = int; }";
  67. // FunctionTemplateDecl:
  68. const auto *ExternFT = "template <class> void f();";
  69. const auto *StaticFT = "template <class> static void f();";
  70. const auto *AnonFT = "namespace { template <class> void f(); }";
  71. // First value in tuple: Compile options.
  72. // Second value in tuple: Source code to be used in the test.
  73. using ImportVisibilityChainParams =
  74. ::testing::WithParamInterface<std::tuple<ArgVector, const char *>>;
  75. // Fixture to test the redecl chain of Decls with the same visibility. Gtest
  76. // makes it possible to have either value-parameterized or type-parameterized
  77. // fixtures. However, we cannot have both value- and type-parameterized test
  78. // fixtures. This is a value-parameterized test fixture in the gtest sense. We
  79. // intend to mimic gtest's type-parameters via the PatternFactory template
  80. // parameter. We manually instantiate the different tests with the each types.
  81. template <typename PatternFactory>
  82. class ImportVisibilityChain
  83. : public ASTImporterTestBase, public ImportVisibilityChainParams {
  84. protected:
  85. using DeclTy = typename PatternFactory::DeclTy;
  86. ArgVector getExtraArgs() const override { return std::get<0>(GetParam()); }
  87. std::string getCode() const { return std::get<1>(GetParam()); }
  88. BindableMatcher<Decl> getPattern() const { return PatternFactory()(); }
  89. // Type-parameterized test.
  90. void TypedTest_ImportChain() {
  91. std::string Code = getCode() + getCode();
  92. auto Pattern = getPattern();
  93. TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_CXX14, "input0.cc");
  94. auto *FromD0 = FirstDeclMatcher<DeclTy>().match(FromTu, Pattern);
  95. auto *FromD1 = LastDeclMatcher<DeclTy>().match(FromTu, Pattern);
  96. auto *ToD0 = Import(FromD0, Lang_CXX14);
  97. auto *ToD1 = Import(FromD1, Lang_CXX14);
  98. EXPECT_TRUE(ToD0);
  99. ASSERT_TRUE(ToD1);
  100. EXPECT_NE(ToD0, ToD1);
  101. EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
  102. }
  103. };
  104. // Manual instantiation of the fixture with each type.
  105. using ImportFunctionsVisibilityChain = ImportVisibilityChain<GetFunPattern>;
  106. using ImportVariablesVisibilityChain = ImportVisibilityChain<GetVarPattern>;
  107. using ImportClassesVisibilityChain = ImportVisibilityChain<GetClassPattern>;
  108. using ImportFunctionTemplatesVisibilityChain =
  109. ImportVisibilityChain<GetFunTemplPattern>;
  110. // Value-parameterized test for functions.
  111. TEST_P(ImportFunctionsVisibilityChain, ImportChain) {
  112. TypedTest_ImportChain();
  113. }
  114. // Value-parameterized test for variables.
  115. TEST_P(ImportVariablesVisibilityChain, ImportChain) {
  116. TypedTest_ImportChain();
  117. }
  118. // Value-parameterized test for classes.
  119. TEST_P(ImportClassesVisibilityChain, ImportChain) {
  120. TypedTest_ImportChain();
  121. }
  122. // Value-parameterized test for function templates.
  123. TEST_P(ImportFunctionTemplatesVisibilityChain, ImportChain) {
  124. TypedTest_ImportChain();
  125. }
  126. // Automatic instantiation of the value-parameterized tests.
  127. INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionsVisibilityChain,
  128. ::testing::Combine(
  129. DefaultTestValuesForRunOptions,
  130. ::testing::Values(ExternF, StaticF, AnonF)), );
  131. INSTANTIATE_TEST_CASE_P(
  132. ParameterizedTests, ImportVariablesVisibilityChain,
  133. ::testing::Combine(
  134. DefaultTestValuesForRunOptions,
  135. // There is no point to instantiate with StaticV, because in C++ we can
  136. // forward declare a variable only with the 'extern' keyword.
  137. // Consequently, each fwd declared variable has external linkage. This
  138. // is different in the C language where any declaration without an
  139. // initializer is a tentative definition, subsequent definitions may be
  140. // provided but they must have the same linkage. See also the test
  141. // ImportVariableChainInC which test for this special C Lang case.
  142. ::testing::Values(ExternV, AnonV)), );
  143. INSTANTIATE_TEST_CASE_P(
  144. ParameterizedTests, ImportClassesVisibilityChain,
  145. ::testing::Combine(
  146. DefaultTestValuesForRunOptions,
  147. ::testing::Values(ExternC, AnonC)), );
  148. INSTANTIATE_TEST_CASE_P(ParameterizedTests,
  149. ImportFunctionTemplatesVisibilityChain,
  150. ::testing::Combine(DefaultTestValuesForRunOptions,
  151. ::testing::Values(ExternFT, StaticFT,
  152. AnonFT)), );
  153. // First value in tuple: Compile options.
  154. // Second value in tuple: Tuple with informations for the test.
  155. // Code for first import (or initial code), code to import, whether the `f`
  156. // functions are expected to be linked in a declaration chain.
  157. // One value of this tuple is combined with every value of compile options.
  158. // The test can have a single tuple as parameter only.
  159. using ImportVisibilityParams = ::testing::WithParamInterface<
  160. std::tuple<ArgVector, std::tuple<const char *, const char *, bool>>>;
  161. template <typename PatternFactory>
  162. class ImportVisibility
  163. : public ASTImporterTestBase,
  164. public ImportVisibilityParams {
  165. protected:
  166. using DeclTy = typename PatternFactory::DeclTy;
  167. ArgVector getExtraArgs() const override { return std::get<0>(GetParam()); }
  168. std::string getCode0() const { return std::get<0>(std::get<1>(GetParam())); }
  169. std::string getCode1() const { return std::get<1>(std::get<1>(GetParam())); }
  170. bool shouldBeLinked() const { return std::get<2>(std::get<1>(GetParam())); }
  171. BindableMatcher<Decl> getPattern() const { return PatternFactory()(); }
  172. void TypedTest_ImportAfter() {
  173. TranslationUnitDecl *ToTu = getToTuDecl(getCode0(), Lang_CXX14);
  174. TranslationUnitDecl *FromTu =
  175. getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
  176. auto *ToD0 = FirstDeclMatcher<DeclTy>().match(ToTu, getPattern());
  177. auto *FromD1 = FirstDeclMatcher<DeclTy>().match(FromTu, getPattern());
  178. auto *ToD1 = Import(FromD1, Lang_CXX14);
  179. ASSERT_TRUE(ToD0);
  180. ASSERT_TRUE(ToD1);
  181. EXPECT_NE(ToD0, ToD1);
  182. if (shouldBeLinked())
  183. EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
  184. else
  185. EXPECT_FALSE(ToD1->getPreviousDecl());
  186. }
  187. void TypedTest_ImportAfterImport() {
  188. TranslationUnitDecl *FromTu0 =
  189. getTuDecl(getCode0(), Lang_CXX14, "input0.cc");
  190. TranslationUnitDecl *FromTu1 =
  191. getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
  192. auto *FromD0 = FirstDeclMatcher<DeclTy>().match(FromTu0, getPattern());
  193. auto *FromD1 = FirstDeclMatcher<DeclTy>().match(FromTu1, getPattern());
  194. auto *ToD0 = Import(FromD0, Lang_CXX14);
  195. auto *ToD1 = Import(FromD1, Lang_CXX14);
  196. ASSERT_TRUE(ToD0);
  197. ASSERT_TRUE(ToD1);
  198. EXPECT_NE(ToD0, ToD1);
  199. if (shouldBeLinked())
  200. EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
  201. else
  202. EXPECT_FALSE(ToD1->getPreviousDecl());
  203. }
  204. void TypedTest_ImportAfterWithMerge() {
  205. TranslationUnitDecl *ToTu = getToTuDecl(getCode0(), Lang_CXX14);
  206. TranslationUnitDecl *FromTu =
  207. getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
  208. auto *ToF0 = FirstDeclMatcher<DeclTy>().match(ToTu, getPattern());
  209. auto *FromF1 = FirstDeclMatcher<DeclTy>().match(FromTu, getPattern());
  210. auto *ToF1 = Import(FromF1, Lang_CXX14);
  211. ASSERT_TRUE(ToF0);
  212. ASSERT_TRUE(ToF1);
  213. if (shouldBeLinked())
  214. EXPECT_EQ(ToF0, ToF1);
  215. else
  216. EXPECT_NE(ToF0, ToF1);
  217. // We expect no (ODR) warning during the import.
  218. EXPECT_EQ(0u, ToTu->getASTContext().getDiagnostics().getNumWarnings());
  219. }
  220. void TypedTest_ImportAfterImportWithMerge() {
  221. TranslationUnitDecl *FromTu0 =
  222. getTuDecl(getCode0(), Lang_CXX14, "input0.cc");
  223. TranslationUnitDecl *FromTu1 =
  224. getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
  225. auto *FromF0 = FirstDeclMatcher<DeclTy>().match(FromTu0, getPattern());
  226. auto *FromF1 = FirstDeclMatcher<DeclTy>().match(FromTu1, getPattern());
  227. auto *ToF0 = Import(FromF0, Lang_CXX14);
  228. auto *ToF1 = Import(FromF1, Lang_CXX14);
  229. ASSERT_TRUE(ToF0);
  230. ASSERT_TRUE(ToF1);
  231. if (shouldBeLinked())
  232. EXPECT_EQ(ToF0, ToF1);
  233. else
  234. EXPECT_NE(ToF0, ToF1);
  235. // We expect no (ODR) warning during the import.
  236. EXPECT_EQ(0u, ToF0->getTranslationUnitDecl()
  237. ->getASTContext()
  238. .getDiagnostics()
  239. .getNumWarnings());
  240. }
  241. };
  242. using ImportFunctionsVisibility = ImportVisibility<GetFunPattern>;
  243. using ImportVariablesVisibility = ImportVisibility<GetVarPattern>;
  244. using ImportClassesVisibility = ImportVisibility<GetClassPattern>;
  245. using ImportEnumsVisibility = ImportVisibility<GetEnumPattern>;
  246. using ImportTypedefNameVisibility = ImportVisibility<GetTypedefNamePattern>;
  247. using ImportFunctionTemplatesVisibility = ImportVisibility<GetFunTemplPattern>;
  248. // FunctionDecl.
  249. TEST_P(ImportFunctionsVisibility, ImportAfter) {
  250. TypedTest_ImportAfter();
  251. }
  252. TEST_P(ImportFunctionsVisibility, ImportAfterImport) {
  253. TypedTest_ImportAfterImport();
  254. }
  255. // VarDecl.
  256. TEST_P(ImportVariablesVisibility, ImportAfter) {
  257. TypedTest_ImportAfter();
  258. }
  259. TEST_P(ImportVariablesVisibility, ImportAfterImport) {
  260. TypedTest_ImportAfterImport();
  261. }
  262. // CXXRecordDecl.
  263. TEST_P(ImportClassesVisibility, ImportAfter) {
  264. TypedTest_ImportAfter();
  265. }
  266. TEST_P(ImportClassesVisibility, ImportAfterImport) {
  267. TypedTest_ImportAfterImport();
  268. }
  269. // EnumDecl.
  270. TEST_P(ImportEnumsVisibility, ImportAfter) {
  271. TypedTest_ImportAfterWithMerge();
  272. }
  273. TEST_P(ImportEnumsVisibility, ImportAfterImport) {
  274. TypedTest_ImportAfterImportWithMerge();
  275. }
  276. // TypedefNameDecl.
  277. TEST_P(ImportTypedefNameVisibility, ImportAfter) {
  278. TypedTest_ImportAfterWithMerge();
  279. }
  280. TEST_P(ImportTypedefNameVisibility, ImportAfterImport) {
  281. TypedTest_ImportAfterImportWithMerge();
  282. }
  283. // FunctionTemplateDecl.
  284. TEST_P(ImportFunctionTemplatesVisibility, ImportAfter) {
  285. TypedTest_ImportAfter();
  286. }
  287. TEST_P(ImportFunctionTemplatesVisibility, ImportAfterImport) {
  288. TypedTest_ImportAfterImport();
  289. }
  290. const bool ExpectLinkedDeclChain = true;
  291. const bool ExpectUnlinkedDeclChain = false;
  292. INSTANTIATE_TEST_CASE_P(
  293. ParameterizedTests, ImportFunctionsVisibility,
  294. ::testing::Combine(
  295. DefaultTestValuesForRunOptions,
  296. ::testing::Values(
  297. std::make_tuple(ExternF, ExternF, ExpectLinkedDeclChain),
  298. std::make_tuple(ExternF, StaticF, ExpectUnlinkedDeclChain),
  299. std::make_tuple(ExternF, AnonF, ExpectUnlinkedDeclChain),
  300. std::make_tuple(StaticF, ExternF, ExpectUnlinkedDeclChain),
  301. std::make_tuple(StaticF, StaticF, ExpectUnlinkedDeclChain),
  302. std::make_tuple(StaticF, AnonF, ExpectUnlinkedDeclChain),
  303. std::make_tuple(AnonF, ExternF, ExpectUnlinkedDeclChain),
  304. std::make_tuple(AnonF, StaticF, ExpectUnlinkedDeclChain),
  305. std::make_tuple(AnonF, AnonF, ExpectUnlinkedDeclChain))), );
  306. INSTANTIATE_TEST_CASE_P(
  307. ParameterizedTests, ImportVariablesVisibility,
  308. ::testing::Combine(
  309. DefaultTestValuesForRunOptions,
  310. ::testing::Values(
  311. std::make_tuple(ExternV, ExternV, ExpectLinkedDeclChain),
  312. std::make_tuple(ExternV, StaticV, ExpectUnlinkedDeclChain),
  313. std::make_tuple(ExternV, AnonV, ExpectUnlinkedDeclChain),
  314. std::make_tuple(StaticV, ExternV, ExpectUnlinkedDeclChain),
  315. std::make_tuple(StaticV, StaticV, ExpectUnlinkedDeclChain),
  316. std::make_tuple(StaticV, AnonV, ExpectUnlinkedDeclChain),
  317. std::make_tuple(AnonV, ExternV, ExpectUnlinkedDeclChain),
  318. std::make_tuple(AnonV, StaticV, ExpectUnlinkedDeclChain),
  319. std::make_tuple(AnonV, AnonV, ExpectUnlinkedDeclChain))), );
  320. INSTANTIATE_TEST_CASE_P(
  321. ParameterizedTests, ImportClassesVisibility,
  322. ::testing::Combine(
  323. DefaultTestValuesForRunOptions,
  324. ::testing::Values(
  325. std::make_tuple(ExternC, ExternC, ExpectLinkedDeclChain),
  326. std::make_tuple(ExternC, AnonC, ExpectUnlinkedDeclChain),
  327. std::make_tuple(AnonC, ExternC, ExpectUnlinkedDeclChain),
  328. std::make_tuple(AnonC, AnonC, ExpectUnlinkedDeclChain))), );
  329. INSTANTIATE_TEST_CASE_P(
  330. ParameterizedTests, ImportEnumsVisibility,
  331. ::testing::Combine(
  332. DefaultTestValuesForRunOptions,
  333. ::testing::Values(
  334. std::make_tuple(ExternE, ExternE, ExpectLinkedDeclChain),
  335. std::make_tuple(ExternE, AnonE, ExpectUnlinkedDeclChain),
  336. std::make_tuple(AnonE, ExternE, ExpectUnlinkedDeclChain),
  337. std::make_tuple(AnonE, AnonE, ExpectUnlinkedDeclChain))), );
  338. INSTANTIATE_TEST_CASE_P(
  339. ParameterizedTests, ImportTypedefNameVisibility,
  340. ::testing::Combine(
  341. DefaultTestValuesForRunOptions,
  342. ::testing::Values(
  343. std::make_tuple(ExternTypedef, ExternTypedef,
  344. ExpectLinkedDeclChain),
  345. std::make_tuple(ExternTypedef, AnonTypedef,
  346. ExpectUnlinkedDeclChain),
  347. std::make_tuple(AnonTypedef, ExternTypedef,
  348. ExpectUnlinkedDeclChain),
  349. std::make_tuple(AnonTypedef, AnonTypedef, ExpectUnlinkedDeclChain),
  350. std::make_tuple(ExternUsing, ExternUsing, ExpectLinkedDeclChain),
  351. std::make_tuple(ExternUsing, AnonUsing, ExpectUnlinkedDeclChain),
  352. std::make_tuple(AnonUsing, ExternUsing, ExpectUnlinkedDeclChain),
  353. std::make_tuple(AnonUsing, AnonUsing, ExpectUnlinkedDeclChain),
  354. std::make_tuple(ExternUsing, ExternTypedef, ExpectLinkedDeclChain),
  355. std::make_tuple(ExternUsing, AnonTypedef, ExpectUnlinkedDeclChain),
  356. std::make_tuple(AnonUsing, ExternTypedef, ExpectUnlinkedDeclChain),
  357. std::make_tuple(AnonUsing, AnonTypedef, ExpectUnlinkedDeclChain),
  358. std::make_tuple(ExternTypedef, ExternUsing, ExpectLinkedDeclChain),
  359. std::make_tuple(ExternTypedef, AnonUsing, ExpectUnlinkedDeclChain),
  360. std::make_tuple(AnonTypedef, ExternUsing, ExpectUnlinkedDeclChain),
  361. std::make_tuple(AnonTypedef, AnonUsing,
  362. ExpectUnlinkedDeclChain))), );
  363. INSTANTIATE_TEST_CASE_P(
  364. ParameterizedTests, ImportFunctionTemplatesVisibility,
  365. ::testing::Combine(
  366. DefaultTestValuesForRunOptions,
  367. ::testing::Values(
  368. std::make_tuple(ExternFT, ExternFT, ExpectLinkedDeclChain),
  369. std::make_tuple(ExternFT, StaticFT, ExpectUnlinkedDeclChain),
  370. std::make_tuple(ExternFT, AnonFT, ExpectUnlinkedDeclChain),
  371. std::make_tuple(StaticFT, ExternFT, ExpectUnlinkedDeclChain),
  372. std::make_tuple(StaticFT, StaticFT, ExpectUnlinkedDeclChain),
  373. std::make_tuple(StaticFT, AnonFT, ExpectUnlinkedDeclChain),
  374. std::make_tuple(AnonFT, ExternFT, ExpectUnlinkedDeclChain),
  375. std::make_tuple(AnonFT, StaticFT, ExpectUnlinkedDeclChain),
  376. std::make_tuple(AnonFT, AnonFT, ExpectUnlinkedDeclChain))), );
  377. } // end namespace ast_matchers
  378. } // end namespace clang