blob: 1f60f1758bec470a719375bff9c5969fe8fdca8e [file] [log] [blame]
Gabor Marton3c72fe12019-05-13 10:06:25 +00001//===- 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
14// Define this to have ::testing::Combine available.
15// FIXME: Better solution for this?
16#define GTEST_HAS_COMBINE 1
17
18#include "ASTImporterFixtures.h"
19
20namespace clang {
21namespace ast_matchers {
22
23using internal::BindableMatcher;
24
25// Type parameters for type-parameterized test fixtures.
26struct GetFunPattern {
27 using DeclTy = FunctionDecl;
28 BindableMatcher<Decl> operator()() { return functionDecl(hasName("f")); }
29};
30struct GetVarPattern {
31 using DeclTy = VarDecl;
32 BindableMatcher<Decl> operator()() { return varDecl(hasName("v")); }
33};
Balazs Keric8272192019-05-27 09:36:00 +000034struct GetClassPattern {
35 using DeclTy = CXXRecordDecl;
36 BindableMatcher<Decl> operator()() { return cxxRecordDecl(hasName("X")); }
37};
Balazs Kerieb79b252019-07-09 11:08:18 +000038struct GetEnumPattern {
39 using DeclTy = EnumDecl;
40 BindableMatcher<Decl> operator()() { return enumDecl(hasName("E")); }
41};
Balazs Keric86d47b2019-09-04 14:12:18 +000042struct GetTypedefNamePattern {
43 using DeclTy = TypedefNameDecl;
44 BindableMatcher<Decl> operator()() { return typedefNameDecl(hasName("T")); }
45};
Gabor Marton3c72fe12019-05-13 10:06:25 +000046
47// Values for the value-parameterized test fixtures.
48// FunctionDecl:
49const auto *ExternF = "void f();";
50const auto *StaticF = "static void f();";
51const auto *AnonF = "namespace { void f(); }";
52// VarDecl:
53const auto *ExternV = "extern int v;";
54const auto *StaticV = "static int v;";
55const auto *AnonV = "namespace { extern int v; }";
Balazs Keric8272192019-05-27 09:36:00 +000056// CXXRecordDecl:
57const auto *ExternC = "class X;";
58const auto *AnonC = "namespace { class X; }";
Balazs Kerieb79b252019-07-09 11:08:18 +000059// EnumDecl:
60const auto *ExternE = "enum E {};";
61const auto *AnonE = "namespace { enum E {}; }";
Balazs Keric86d47b2019-09-04 14:12:18 +000062// TypedefNameDecl:
63const auto *ExternTypedef = "typedef int T;";
64const auto *AnonTypedef = "namespace { typedef int T; }";
65const auto *ExternUsing = "using T = int;";
66const auto *AnonUsing = "namespace { using T = int; }";
Gabor Marton3c72fe12019-05-13 10:06:25 +000067
68// First value in tuple: Compile options.
69// Second value in tuple: Source code to be used in the test.
70using ImportVisibilityChainParams =
71 ::testing::WithParamInterface<std::tuple<ArgVector, const char *>>;
72// Fixture to test the redecl chain of Decls with the same visibility. Gtest
73// makes it possible to have either value-parameterized or type-parameterized
74// fixtures. However, we cannot have both value- and type-parameterized test
75// fixtures. This is a value-parameterized test fixture in the gtest sense. We
76// intend to mimic gtest's type-parameters via the PatternFactory template
77// parameter. We manually instantiate the different tests with the each types.
78template <typename PatternFactory>
79class ImportVisibilityChain
80 : public ASTImporterTestBase, public ImportVisibilityChainParams {
81protected:
82 using DeclTy = typename PatternFactory::DeclTy;
83 ArgVector getExtraArgs() const override { return std::get<0>(GetParam()); }
84 std::string getCode() const { return std::get<1>(GetParam()); }
85 BindableMatcher<Decl> getPattern() const { return PatternFactory()(); }
86
87 // Type-parameterized test.
88 void TypedTest_ImportChain() {
89 std::string Code = getCode() + getCode();
90 auto Pattern = getPattern();
91
Balazs Keri14d115f2019-07-15 12:16:30 +000092 TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_CXX14, "input0.cc");
Gabor Marton3c72fe12019-05-13 10:06:25 +000093
94 auto *FromD0 = FirstDeclMatcher<DeclTy>().match(FromTu, Pattern);
95 auto *FromD1 = LastDeclMatcher<DeclTy>().match(FromTu, Pattern);
96
Balazs Keri14d115f2019-07-15 12:16:30 +000097 auto *ToD0 = Import(FromD0, Lang_CXX14);
98 auto *ToD1 = Import(FromD1, Lang_CXX14);
Gabor Marton3c72fe12019-05-13 10:06:25 +000099
100 EXPECT_TRUE(ToD0);
101 ASSERT_TRUE(ToD1);
102 EXPECT_NE(ToD0, ToD1);
103 EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
104 }
105};
106
107// Manual instantiation of the fixture with each type.
108using ImportFunctionsVisibilityChain = ImportVisibilityChain<GetFunPattern>;
109using ImportVariablesVisibilityChain = ImportVisibilityChain<GetVarPattern>;
Balazs Keric8272192019-05-27 09:36:00 +0000110using ImportClassesVisibilityChain = ImportVisibilityChain<GetClassPattern>;
111// Value-parameterized test for functions.
Gabor Marton3c72fe12019-05-13 10:06:25 +0000112TEST_P(ImportFunctionsVisibilityChain, ImportChain) {
113 TypedTest_ImportChain();
114}
Balazs Keric8272192019-05-27 09:36:00 +0000115// Value-parameterized test for variables.
Gabor Marton3c72fe12019-05-13 10:06:25 +0000116TEST_P(ImportVariablesVisibilityChain, ImportChain) {
117 TypedTest_ImportChain();
118}
Balazs Keric8272192019-05-27 09:36:00 +0000119// Value-parameterized test for classes.
120TEST_P(ImportClassesVisibilityChain, ImportChain) {
121 TypedTest_ImportChain();
122}
Gabor Marton3c72fe12019-05-13 10:06:25 +0000123
124// Automatic instantiation of the value-parameterized tests.
125INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionsVisibilityChain,
126 ::testing::Combine(
127 DefaultTestValuesForRunOptions,
128 ::testing::Values(ExternF, StaticF, AnonF)), );
129INSTANTIATE_TEST_CASE_P(
130 ParameterizedTests, ImportVariablesVisibilityChain,
131 ::testing::Combine(
132 DefaultTestValuesForRunOptions,
133 // There is no point to instantiate with StaticV, because in C++ we can
134 // forward declare a variable only with the 'extern' keyword.
135 // Consequently, each fwd declared variable has external linkage. This
136 // is different in the C language where any declaration without an
137 // initializer is a tentative definition, subsequent definitions may be
138 // provided but they must have the same linkage. See also the test
139 // ImportVariableChainInC which test for this special C Lang case.
140 ::testing::Values(ExternV, AnonV)), );
Balazs Keric8272192019-05-27 09:36:00 +0000141INSTANTIATE_TEST_CASE_P(
142 ParameterizedTests, ImportClassesVisibilityChain,
143 ::testing::Combine(
144 DefaultTestValuesForRunOptions,
145 ::testing::Values(ExternC, AnonC)), );
Gabor Marton3c72fe12019-05-13 10:06:25 +0000146
147// First value in tuple: Compile options.
148// Second value in tuple: Tuple with informations for the test.
149// Code for first import (or initial code), code to import, whether the `f`
150// functions are expected to be linked in a declaration chain.
151// One value of this tuple is combined with every value of compile options.
152// The test can have a single tuple as parameter only.
153using ImportVisibilityParams = ::testing::WithParamInterface<
154 std::tuple<ArgVector, std::tuple<const char *, const char *, bool>>>;
155
156template <typename PatternFactory>
157class ImportVisibility
158 : public ASTImporterTestBase,
159 public ImportVisibilityParams {
160protected:
161 using DeclTy = typename PatternFactory::DeclTy;
162 ArgVector getExtraArgs() const override { return std::get<0>(GetParam()); }
163 std::string getCode0() const { return std::get<0>(std::get<1>(GetParam())); }
164 std::string getCode1() const { return std::get<1>(std::get<1>(GetParam())); }
165 bool shouldBeLinked() const { return std::get<2>(std::get<1>(GetParam())); }
166 BindableMatcher<Decl> getPattern() const { return PatternFactory()(); }
167
168 void TypedTest_ImportAfter() {
Balazs Keri14d115f2019-07-15 12:16:30 +0000169 TranslationUnitDecl *ToTu = getToTuDecl(getCode0(), Lang_CXX14);
170 TranslationUnitDecl *FromTu =
171 getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
Gabor Marton3c72fe12019-05-13 10:06:25 +0000172
173 auto *ToD0 = FirstDeclMatcher<DeclTy>().match(ToTu, getPattern());
174 auto *FromD1 = FirstDeclMatcher<DeclTy>().match(FromTu, getPattern());
175
Balazs Keri14d115f2019-07-15 12:16:30 +0000176 auto *ToD1 = Import(FromD1, Lang_CXX14);
Gabor Marton3c72fe12019-05-13 10:06:25 +0000177
178 ASSERT_TRUE(ToD0);
179 ASSERT_TRUE(ToD1);
180 EXPECT_NE(ToD0, ToD1);
181
182 if (shouldBeLinked())
183 EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
184 else
185 EXPECT_FALSE(ToD1->getPreviousDecl());
186 }
187
188 void TypedTest_ImportAfterImport() {
Balazs Keri14d115f2019-07-15 12:16:30 +0000189 TranslationUnitDecl *FromTu0 =
190 getTuDecl(getCode0(), Lang_CXX14, "input0.cc");
191 TranslationUnitDecl *FromTu1 =
192 getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
Gabor Marton3c72fe12019-05-13 10:06:25 +0000193 auto *FromD0 = FirstDeclMatcher<DeclTy>().match(FromTu0, getPattern());
194 auto *FromD1 = FirstDeclMatcher<DeclTy>().match(FromTu1, getPattern());
Balazs Keri14d115f2019-07-15 12:16:30 +0000195 auto *ToD0 = Import(FromD0, Lang_CXX14);
196 auto *ToD1 = Import(FromD1, Lang_CXX14);
Gabor Marton3c72fe12019-05-13 10:06:25 +0000197 ASSERT_TRUE(ToD0);
198 ASSERT_TRUE(ToD1);
199 EXPECT_NE(ToD0, ToD1);
200 if (shouldBeLinked())
201 EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
202 else
203 EXPECT_FALSE(ToD1->getPreviousDecl());
204 }
Balazs Kerieb79b252019-07-09 11:08:18 +0000205
206 void TypedTest_ImportAfterWithMerge() {
Balazs Keri14d115f2019-07-15 12:16:30 +0000207 TranslationUnitDecl *ToTu = getToTuDecl(getCode0(), Lang_CXX14);
208 TranslationUnitDecl *FromTu =
209 getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
Balazs Kerieb79b252019-07-09 11:08:18 +0000210
211 auto *ToF0 = FirstDeclMatcher<DeclTy>().match(ToTu, getPattern());
212 auto *FromF1 = FirstDeclMatcher<DeclTy>().match(FromTu, getPattern());
213
Balazs Keri14d115f2019-07-15 12:16:30 +0000214 auto *ToF1 = Import(FromF1, Lang_CXX14);
Balazs Kerieb79b252019-07-09 11:08:18 +0000215
216 ASSERT_TRUE(ToF0);
217 ASSERT_TRUE(ToF1);
218
219 if (shouldBeLinked())
220 EXPECT_EQ(ToF0, ToF1);
221 else
222 EXPECT_NE(ToF0, ToF1);
223
224 // We expect no (ODR) warning during the import.
225 EXPECT_EQ(0u, ToTu->getASTContext().getDiagnostics().getNumWarnings());
226 }
227
228 void TypedTest_ImportAfterImportWithMerge() {
Balazs Keri14d115f2019-07-15 12:16:30 +0000229 TranslationUnitDecl *FromTu0 =
230 getTuDecl(getCode0(), Lang_CXX14, "input0.cc");
231 TranslationUnitDecl *FromTu1 =
232 getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
Balazs Kerieb79b252019-07-09 11:08:18 +0000233 auto *FromF0 = FirstDeclMatcher<DeclTy>().match(FromTu0, getPattern());
234 auto *FromF1 = FirstDeclMatcher<DeclTy>().match(FromTu1, getPattern());
Balazs Keri14d115f2019-07-15 12:16:30 +0000235 auto *ToF0 = Import(FromF0, Lang_CXX14);
236 auto *ToF1 = Import(FromF1, Lang_CXX14);
Balazs Kerieb79b252019-07-09 11:08:18 +0000237 ASSERT_TRUE(ToF0);
238 ASSERT_TRUE(ToF1);
239 if (shouldBeLinked())
240 EXPECT_EQ(ToF0, ToF1);
241 else
242 EXPECT_NE(ToF0, ToF1);
243
244 // We expect no (ODR) warning during the import.
245 EXPECT_EQ(0u, ToF0->getTranslationUnitDecl()
246 ->getASTContext()
247 .getDiagnostics()
248 .getNumWarnings());
249 }
Gabor Marton3c72fe12019-05-13 10:06:25 +0000250};
251using ImportFunctionsVisibility = ImportVisibility<GetFunPattern>;
252using ImportVariablesVisibility = ImportVisibility<GetVarPattern>;
Balazs Keric8272192019-05-27 09:36:00 +0000253using ImportClassesVisibility = ImportVisibility<GetClassPattern>;
Balazs Kerieb79b252019-07-09 11:08:18 +0000254using ImportEnumsVisibility = ImportVisibility<GetEnumPattern>;
Balazs Keric86d47b2019-09-04 14:12:18 +0000255using ImportTypedefNameVisibility = ImportVisibility<GetTypedefNamePattern>;
Gabor Marton3c72fe12019-05-13 10:06:25 +0000256
257// FunctionDecl.
258TEST_P(ImportFunctionsVisibility, ImportAfter) {
259 TypedTest_ImportAfter();
260}
261TEST_P(ImportFunctionsVisibility, ImportAfterImport) {
262 TypedTest_ImportAfterImport();
263}
264// VarDecl.
265TEST_P(ImportVariablesVisibility, ImportAfter) {
266 TypedTest_ImportAfter();
267}
268TEST_P(ImportVariablesVisibility, ImportAfterImport) {
269 TypedTest_ImportAfterImport();
270}
Balazs Keric8272192019-05-27 09:36:00 +0000271// CXXRecordDecl.
272TEST_P(ImportClassesVisibility, ImportAfter) {
273 TypedTest_ImportAfter();
274}
275TEST_P(ImportClassesVisibility, ImportAfterImport) {
276 TypedTest_ImportAfterImport();
277}
Balazs Kerieb79b252019-07-09 11:08:18 +0000278// EnumDecl.
279TEST_P(ImportEnumsVisibility, ImportAfter) {
280 TypedTest_ImportAfterWithMerge();
281}
282TEST_P(ImportEnumsVisibility, ImportAfterImport) {
283 TypedTest_ImportAfterImportWithMerge();
284}
Balazs Keric86d47b2019-09-04 14:12:18 +0000285// TypedefNameDecl.
286TEST_P(ImportTypedefNameVisibility, ImportAfter) {
287 TypedTest_ImportAfterWithMerge();
288}
289TEST_P(ImportTypedefNameVisibility, ImportAfterImport) {
290 TypedTest_ImportAfterImportWithMerge();
291}
Gabor Marton3c72fe12019-05-13 10:06:25 +0000292
Balazs Kericaa42792019-09-05 07:59:45 +0000293const bool ExpectLinkedDeclChain = true;
294const bool ExpectUnlinkedDeclChain = false;
Gabor Marton3c72fe12019-05-13 10:06:25 +0000295
296INSTANTIATE_TEST_CASE_P(
297 ParameterizedTests, ImportFunctionsVisibility,
298 ::testing::Combine(
299 DefaultTestValuesForRunOptions,
Balazs Kericaa42792019-09-05 07:59:45 +0000300 ::testing::Values(
301 std::make_tuple(ExternF, ExternF, ExpectLinkedDeclChain),
302 std::make_tuple(ExternF, StaticF, ExpectUnlinkedDeclChain),
303 std::make_tuple(ExternF, AnonF, ExpectUnlinkedDeclChain),
304 std::make_tuple(StaticF, ExternF, ExpectUnlinkedDeclChain),
305 std::make_tuple(StaticF, StaticF, ExpectUnlinkedDeclChain),
306 std::make_tuple(StaticF, AnonF, ExpectUnlinkedDeclChain),
307 std::make_tuple(AnonF, ExternF, ExpectUnlinkedDeclChain),
308 std::make_tuple(AnonF, StaticF, ExpectUnlinkedDeclChain),
309 std::make_tuple(AnonF, AnonF, ExpectUnlinkedDeclChain))), );
Gabor Marton3c72fe12019-05-13 10:06:25 +0000310INSTANTIATE_TEST_CASE_P(
311 ParameterizedTests, ImportVariablesVisibility,
312 ::testing::Combine(
313 DefaultTestValuesForRunOptions,
Balazs Kericaa42792019-09-05 07:59:45 +0000314 ::testing::Values(
315 std::make_tuple(ExternV, ExternV, ExpectLinkedDeclChain),
316 std::make_tuple(ExternV, StaticV, ExpectUnlinkedDeclChain),
317 std::make_tuple(ExternV, AnonV, ExpectUnlinkedDeclChain),
318 std::make_tuple(StaticV, ExternV, ExpectUnlinkedDeclChain),
319 std::make_tuple(StaticV, StaticV, ExpectUnlinkedDeclChain),
320 std::make_tuple(StaticV, AnonV, ExpectUnlinkedDeclChain),
321 std::make_tuple(AnonV, ExternV, ExpectUnlinkedDeclChain),
322 std::make_tuple(AnonV, StaticV, ExpectUnlinkedDeclChain),
323 std::make_tuple(AnonV, AnonV, ExpectUnlinkedDeclChain))), );
Balazs Keric8272192019-05-27 09:36:00 +0000324INSTANTIATE_TEST_CASE_P(
325 ParameterizedTests, ImportClassesVisibility,
326 ::testing::Combine(
327 DefaultTestValuesForRunOptions,
Balazs Kericaa42792019-09-05 07:59:45 +0000328 ::testing::Values(
329 std::make_tuple(ExternC, ExternC, ExpectLinkedDeclChain),
330 std::make_tuple(ExternC, AnonC, ExpectUnlinkedDeclChain),
331 std::make_tuple(AnonC, ExternC, ExpectUnlinkedDeclChain),
332 std::make_tuple(AnonC, AnonC, ExpectUnlinkedDeclChain))), );
Balazs Kerieb79b252019-07-09 11:08:18 +0000333INSTANTIATE_TEST_CASE_P(
334 ParameterizedTests, ImportEnumsVisibility,
335 ::testing::Combine(
336 DefaultTestValuesForRunOptions,
Balazs Kericaa42792019-09-05 07:59:45 +0000337 ::testing::Values(
338 std::make_tuple(ExternE, ExternE, ExpectLinkedDeclChain),
339 std::make_tuple(ExternE, AnonE, ExpectUnlinkedDeclChain),
340 std::make_tuple(AnonE, ExternE, ExpectUnlinkedDeclChain),
341 std::make_tuple(AnonE, AnonE, ExpectUnlinkedDeclChain))), );
Balazs Keric86d47b2019-09-04 14:12:18 +0000342INSTANTIATE_TEST_CASE_P(
343 ParameterizedTests, ImportTypedefNameVisibility,
344 ::testing::Combine(
345 DefaultTestValuesForRunOptions,
346 ::testing::Values(
Balazs Kericaa42792019-09-05 07:59:45 +0000347 std::make_tuple(ExternTypedef, ExternTypedef,
348 ExpectLinkedDeclChain),
349 std::make_tuple(ExternTypedef, AnonTypedef,
350 ExpectUnlinkedDeclChain),
351 std::make_tuple(AnonTypedef, ExternTypedef,
352 ExpectUnlinkedDeclChain),
353 std::make_tuple(AnonTypedef, AnonTypedef, ExpectUnlinkedDeclChain),
Balazs Keric86d47b2019-09-04 14:12:18 +0000354
Balazs Kericaa42792019-09-05 07:59:45 +0000355 std::make_tuple(ExternUsing, ExternUsing, ExpectLinkedDeclChain),
356 std::make_tuple(ExternUsing, AnonUsing, ExpectUnlinkedDeclChain),
357 std::make_tuple(AnonUsing, ExternUsing, ExpectUnlinkedDeclChain),
358 std::make_tuple(AnonUsing, AnonUsing, ExpectUnlinkedDeclChain),
Balazs Keric86d47b2019-09-04 14:12:18 +0000359
Balazs Kericaa42792019-09-05 07:59:45 +0000360 std::make_tuple(ExternUsing, ExternTypedef, ExpectLinkedDeclChain),
361 std::make_tuple(ExternUsing, AnonTypedef, ExpectUnlinkedDeclChain),
362 std::make_tuple(AnonUsing, ExternTypedef, ExpectUnlinkedDeclChain),
363 std::make_tuple(AnonUsing, AnonTypedef, ExpectUnlinkedDeclChain),
Balazs Keric86d47b2019-09-04 14:12:18 +0000364
Balazs Kericaa42792019-09-05 07:59:45 +0000365 std::make_tuple(ExternTypedef, ExternUsing, ExpectLinkedDeclChain),
366 std::make_tuple(ExternTypedef, AnonUsing, ExpectUnlinkedDeclChain),
367 std::make_tuple(AnonTypedef, ExternUsing, ExpectUnlinkedDeclChain),
368 std::make_tuple(AnonTypedef, AnonUsing,
369 ExpectUnlinkedDeclChain))), );
Gabor Marton3c72fe12019-05-13 10:06:25 +0000370
371} // end namespace ast_matchers
372} // end namespace clang