123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416 |
- //===- unittest/AST/ASTImporterTest.cpp - AST node import test ------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // Type-parameterized tests for the correct import of Decls with different
- // visibility.
- //
- //===----------------------------------------------------------------------===//
- // Define this to have ::testing::Combine available.
- // FIXME: Better solution for this?
- #define GTEST_HAS_COMBINE 1
- #include "ASTImporterFixtures.h"
- namespace clang {
- namespace ast_matchers {
- using internal::BindableMatcher;
- // Type parameters for type-parameterized test fixtures.
- struct GetFunPattern {
- using DeclTy = FunctionDecl;
- BindableMatcher<Decl> operator()() { return functionDecl(hasName("f")); }
- };
- struct GetVarPattern {
- using DeclTy = VarDecl;
- BindableMatcher<Decl> operator()() { return varDecl(hasName("v")); }
- };
- struct GetClassPattern {
- using DeclTy = CXXRecordDecl;
- BindableMatcher<Decl> operator()() { return cxxRecordDecl(hasName("X")); }
- };
- struct GetEnumPattern {
- using DeclTy = EnumDecl;
- BindableMatcher<Decl> operator()() { return enumDecl(hasName("E")); }
- };
- struct GetTypedefNamePattern {
- using DeclTy = TypedefNameDecl;
- BindableMatcher<Decl> operator()() { return typedefNameDecl(hasName("T")); }
- };
- struct GetFunTemplPattern {
- using DeclTy = FunctionTemplateDecl;
- BindableMatcher<Decl> operator()() {
- return functionTemplateDecl(hasName("f"));
- }
- };
- // Values for the value-parameterized test fixtures.
- // FunctionDecl:
- const auto *ExternF = "void f();";
- const auto *StaticF = "static void f();";
- const auto *AnonF = "namespace { void f(); }";
- // VarDecl:
- const auto *ExternV = "extern int v;";
- const auto *StaticV = "static int v;";
- const auto *AnonV = "namespace { extern int v; }";
- // CXXRecordDecl:
- const auto *ExternC = "class X;";
- const auto *AnonC = "namespace { class X; }";
- // EnumDecl:
- const auto *ExternE = "enum E {};";
- const auto *AnonE = "namespace { enum E {}; }";
- // TypedefNameDecl:
- const auto *ExternTypedef = "typedef int T;";
- const auto *AnonTypedef = "namespace { typedef int T; }";
- const auto *ExternUsing = "using T = int;";
- const auto *AnonUsing = "namespace { using T = int; }";
- // FunctionTemplateDecl:
- const auto *ExternFT = "template <class> void f();";
- const auto *StaticFT = "template <class> static void f();";
- const auto *AnonFT = "namespace { template <class> void f(); }";
- // First value in tuple: Compile options.
- // Second value in tuple: Source code to be used in the test.
- using ImportVisibilityChainParams =
- ::testing::WithParamInterface<std::tuple<ArgVector, const char *>>;
- // Fixture to test the redecl chain of Decls with the same visibility. Gtest
- // makes it possible to have either value-parameterized or type-parameterized
- // fixtures. However, we cannot have both value- and type-parameterized test
- // fixtures. This is a value-parameterized test fixture in the gtest sense. We
- // intend to mimic gtest's type-parameters via the PatternFactory template
- // parameter. We manually instantiate the different tests with the each types.
- template <typename PatternFactory>
- class ImportVisibilityChain
- : public ASTImporterTestBase, public ImportVisibilityChainParams {
- protected:
- using DeclTy = typename PatternFactory::DeclTy;
- ArgVector getExtraArgs() const override { return std::get<0>(GetParam()); }
- std::string getCode() const { return std::get<1>(GetParam()); }
- BindableMatcher<Decl> getPattern() const { return PatternFactory()(); }
- // Type-parameterized test.
- void TypedTest_ImportChain() {
- std::string Code = getCode() + getCode();
- auto Pattern = getPattern();
- TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_CXX14, "input0.cc");
- auto *FromD0 = FirstDeclMatcher<DeclTy>().match(FromTu, Pattern);
- auto *FromD1 = LastDeclMatcher<DeclTy>().match(FromTu, Pattern);
- auto *ToD0 = Import(FromD0, Lang_CXX14);
- auto *ToD1 = Import(FromD1, Lang_CXX14);
- EXPECT_TRUE(ToD0);
- ASSERT_TRUE(ToD1);
- EXPECT_NE(ToD0, ToD1);
- EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
- }
- };
- // Manual instantiation of the fixture with each type.
- using ImportFunctionsVisibilityChain = ImportVisibilityChain<GetFunPattern>;
- using ImportVariablesVisibilityChain = ImportVisibilityChain<GetVarPattern>;
- using ImportClassesVisibilityChain = ImportVisibilityChain<GetClassPattern>;
- using ImportFunctionTemplatesVisibilityChain =
- ImportVisibilityChain<GetFunTemplPattern>;
- // Value-parameterized test for functions.
- TEST_P(ImportFunctionsVisibilityChain, ImportChain) {
- TypedTest_ImportChain();
- }
- // Value-parameterized test for variables.
- TEST_P(ImportVariablesVisibilityChain, ImportChain) {
- TypedTest_ImportChain();
- }
- // Value-parameterized test for classes.
- TEST_P(ImportClassesVisibilityChain, ImportChain) {
- TypedTest_ImportChain();
- }
- // Value-parameterized test for function templates.
- TEST_P(ImportFunctionTemplatesVisibilityChain, ImportChain) {
- TypedTest_ImportChain();
- }
- // Automatic instantiation of the value-parameterized tests.
- INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionsVisibilityChain,
- ::testing::Combine(
- DefaultTestValuesForRunOptions,
- ::testing::Values(ExternF, StaticF, AnonF)), );
- INSTANTIATE_TEST_CASE_P(
- ParameterizedTests, ImportVariablesVisibilityChain,
- ::testing::Combine(
- DefaultTestValuesForRunOptions,
- // There is no point to instantiate with StaticV, because in C++ we can
- // forward declare a variable only with the 'extern' keyword.
- // Consequently, each fwd declared variable has external linkage. This
- // is different in the C language where any declaration without an
- // initializer is a tentative definition, subsequent definitions may be
- // provided but they must have the same linkage. See also the test
- // ImportVariableChainInC which test for this special C Lang case.
- ::testing::Values(ExternV, AnonV)), );
- INSTANTIATE_TEST_CASE_P(
- ParameterizedTests, ImportClassesVisibilityChain,
- ::testing::Combine(
- DefaultTestValuesForRunOptions,
- ::testing::Values(ExternC, AnonC)), );
- INSTANTIATE_TEST_CASE_P(ParameterizedTests,
- ImportFunctionTemplatesVisibilityChain,
- ::testing::Combine(DefaultTestValuesForRunOptions,
- ::testing::Values(ExternFT, StaticFT,
- AnonFT)), );
- // First value in tuple: Compile options.
- // Second value in tuple: Tuple with informations for the test.
- // Code for first import (or initial code), code to import, whether the `f`
- // functions are expected to be linked in a declaration chain.
- // One value of this tuple is combined with every value of compile options.
- // The test can have a single tuple as parameter only.
- using ImportVisibilityParams = ::testing::WithParamInterface<
- std::tuple<ArgVector, std::tuple<const char *, const char *, bool>>>;
- template <typename PatternFactory>
- class ImportVisibility
- : public ASTImporterTestBase,
- public ImportVisibilityParams {
- protected:
- using DeclTy = typename PatternFactory::DeclTy;
- ArgVector getExtraArgs() const override { return std::get<0>(GetParam()); }
- std::string getCode0() const { return std::get<0>(std::get<1>(GetParam())); }
- std::string getCode1() const { return std::get<1>(std::get<1>(GetParam())); }
- bool shouldBeLinked() const { return std::get<2>(std::get<1>(GetParam())); }
- BindableMatcher<Decl> getPattern() const { return PatternFactory()(); }
- void TypedTest_ImportAfter() {
- TranslationUnitDecl *ToTu = getToTuDecl(getCode0(), Lang_CXX14);
- TranslationUnitDecl *FromTu =
- getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
- auto *ToD0 = FirstDeclMatcher<DeclTy>().match(ToTu, getPattern());
- auto *FromD1 = FirstDeclMatcher<DeclTy>().match(FromTu, getPattern());
- auto *ToD1 = Import(FromD1, Lang_CXX14);
- ASSERT_TRUE(ToD0);
- ASSERT_TRUE(ToD1);
- EXPECT_NE(ToD0, ToD1);
- if (shouldBeLinked())
- EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
- else
- EXPECT_FALSE(ToD1->getPreviousDecl());
- }
- void TypedTest_ImportAfterImport() {
- TranslationUnitDecl *FromTu0 =
- getTuDecl(getCode0(), Lang_CXX14, "input0.cc");
- TranslationUnitDecl *FromTu1 =
- getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
- auto *FromD0 = FirstDeclMatcher<DeclTy>().match(FromTu0, getPattern());
- auto *FromD1 = FirstDeclMatcher<DeclTy>().match(FromTu1, getPattern());
- auto *ToD0 = Import(FromD0, Lang_CXX14);
- auto *ToD1 = Import(FromD1, Lang_CXX14);
- ASSERT_TRUE(ToD0);
- ASSERT_TRUE(ToD1);
- EXPECT_NE(ToD0, ToD1);
- if (shouldBeLinked())
- EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
- else
- EXPECT_FALSE(ToD1->getPreviousDecl());
- }
- void TypedTest_ImportAfterWithMerge() {
- TranslationUnitDecl *ToTu = getToTuDecl(getCode0(), Lang_CXX14);
- TranslationUnitDecl *FromTu =
- getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
- auto *ToF0 = FirstDeclMatcher<DeclTy>().match(ToTu, getPattern());
- auto *FromF1 = FirstDeclMatcher<DeclTy>().match(FromTu, getPattern());
- auto *ToF1 = Import(FromF1, Lang_CXX14);
- ASSERT_TRUE(ToF0);
- ASSERT_TRUE(ToF1);
- if (shouldBeLinked())
- EXPECT_EQ(ToF0, ToF1);
- else
- EXPECT_NE(ToF0, ToF1);
- // We expect no (ODR) warning during the import.
- EXPECT_EQ(0u, ToTu->getASTContext().getDiagnostics().getNumWarnings());
- }
- void TypedTest_ImportAfterImportWithMerge() {
- TranslationUnitDecl *FromTu0 =
- getTuDecl(getCode0(), Lang_CXX14, "input0.cc");
- TranslationUnitDecl *FromTu1 =
- getTuDecl(getCode1(), Lang_CXX14, "input1.cc");
- auto *FromF0 = FirstDeclMatcher<DeclTy>().match(FromTu0, getPattern());
- auto *FromF1 = FirstDeclMatcher<DeclTy>().match(FromTu1, getPattern());
- auto *ToF0 = Import(FromF0, Lang_CXX14);
- auto *ToF1 = Import(FromF1, Lang_CXX14);
- ASSERT_TRUE(ToF0);
- ASSERT_TRUE(ToF1);
- if (shouldBeLinked())
- EXPECT_EQ(ToF0, ToF1);
- else
- EXPECT_NE(ToF0, ToF1);
- // We expect no (ODR) warning during the import.
- EXPECT_EQ(0u, ToF0->getTranslationUnitDecl()
- ->getASTContext()
- .getDiagnostics()
- .getNumWarnings());
- }
- };
- using ImportFunctionsVisibility = ImportVisibility<GetFunPattern>;
- using ImportVariablesVisibility = ImportVisibility<GetVarPattern>;
- using ImportClassesVisibility = ImportVisibility<GetClassPattern>;
- using ImportEnumsVisibility = ImportVisibility<GetEnumPattern>;
- using ImportTypedefNameVisibility = ImportVisibility<GetTypedefNamePattern>;
- using ImportFunctionTemplatesVisibility = ImportVisibility<GetFunTemplPattern>;
- // FunctionDecl.
- TEST_P(ImportFunctionsVisibility, ImportAfter) {
- TypedTest_ImportAfter();
- }
- TEST_P(ImportFunctionsVisibility, ImportAfterImport) {
- TypedTest_ImportAfterImport();
- }
- // VarDecl.
- TEST_P(ImportVariablesVisibility, ImportAfter) {
- TypedTest_ImportAfter();
- }
- TEST_P(ImportVariablesVisibility, ImportAfterImport) {
- TypedTest_ImportAfterImport();
- }
- // CXXRecordDecl.
- TEST_P(ImportClassesVisibility, ImportAfter) {
- TypedTest_ImportAfter();
- }
- TEST_P(ImportClassesVisibility, ImportAfterImport) {
- TypedTest_ImportAfterImport();
- }
- // EnumDecl.
- TEST_P(ImportEnumsVisibility, ImportAfter) {
- TypedTest_ImportAfterWithMerge();
- }
- TEST_P(ImportEnumsVisibility, ImportAfterImport) {
- TypedTest_ImportAfterImportWithMerge();
- }
- // TypedefNameDecl.
- TEST_P(ImportTypedefNameVisibility, ImportAfter) {
- TypedTest_ImportAfterWithMerge();
- }
- TEST_P(ImportTypedefNameVisibility, ImportAfterImport) {
- TypedTest_ImportAfterImportWithMerge();
- }
- // FunctionTemplateDecl.
- TEST_P(ImportFunctionTemplatesVisibility, ImportAfter) {
- TypedTest_ImportAfter();
- }
- TEST_P(ImportFunctionTemplatesVisibility, ImportAfterImport) {
- TypedTest_ImportAfterImport();
- }
- const bool ExpectLinkedDeclChain = true;
- const bool ExpectUnlinkedDeclChain = false;
- INSTANTIATE_TEST_CASE_P(
- ParameterizedTests, ImportFunctionsVisibility,
- ::testing::Combine(
- DefaultTestValuesForRunOptions,
- ::testing::Values(
- std::make_tuple(ExternF, ExternF, ExpectLinkedDeclChain),
- std::make_tuple(ExternF, StaticF, ExpectUnlinkedDeclChain),
- std::make_tuple(ExternF, AnonF, ExpectUnlinkedDeclChain),
- std::make_tuple(StaticF, ExternF, ExpectUnlinkedDeclChain),
- std::make_tuple(StaticF, StaticF, ExpectUnlinkedDeclChain),
- std::make_tuple(StaticF, AnonF, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonF, ExternF, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonF, StaticF, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonF, AnonF, ExpectUnlinkedDeclChain))), );
- INSTANTIATE_TEST_CASE_P(
- ParameterizedTests, ImportVariablesVisibility,
- ::testing::Combine(
- DefaultTestValuesForRunOptions,
- ::testing::Values(
- std::make_tuple(ExternV, ExternV, ExpectLinkedDeclChain),
- std::make_tuple(ExternV, StaticV, ExpectUnlinkedDeclChain),
- std::make_tuple(ExternV, AnonV, ExpectUnlinkedDeclChain),
- std::make_tuple(StaticV, ExternV, ExpectUnlinkedDeclChain),
- std::make_tuple(StaticV, StaticV, ExpectUnlinkedDeclChain),
- std::make_tuple(StaticV, AnonV, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonV, ExternV, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonV, StaticV, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonV, AnonV, ExpectUnlinkedDeclChain))), );
- INSTANTIATE_TEST_CASE_P(
- ParameterizedTests, ImportClassesVisibility,
- ::testing::Combine(
- DefaultTestValuesForRunOptions,
- ::testing::Values(
- std::make_tuple(ExternC, ExternC, ExpectLinkedDeclChain),
- std::make_tuple(ExternC, AnonC, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonC, ExternC, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonC, AnonC, ExpectUnlinkedDeclChain))), );
- INSTANTIATE_TEST_CASE_P(
- ParameterizedTests, ImportEnumsVisibility,
- ::testing::Combine(
- DefaultTestValuesForRunOptions,
- ::testing::Values(
- std::make_tuple(ExternE, ExternE, ExpectLinkedDeclChain),
- std::make_tuple(ExternE, AnonE, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonE, ExternE, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonE, AnonE, ExpectUnlinkedDeclChain))), );
- INSTANTIATE_TEST_CASE_P(
- ParameterizedTests, ImportTypedefNameVisibility,
- ::testing::Combine(
- DefaultTestValuesForRunOptions,
- ::testing::Values(
- std::make_tuple(ExternTypedef, ExternTypedef,
- ExpectLinkedDeclChain),
- std::make_tuple(ExternTypedef, AnonTypedef,
- ExpectUnlinkedDeclChain),
- std::make_tuple(AnonTypedef, ExternTypedef,
- ExpectUnlinkedDeclChain),
- std::make_tuple(AnonTypedef, AnonTypedef, ExpectUnlinkedDeclChain),
- std::make_tuple(ExternUsing, ExternUsing, ExpectLinkedDeclChain),
- std::make_tuple(ExternUsing, AnonUsing, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonUsing, ExternUsing, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonUsing, AnonUsing, ExpectUnlinkedDeclChain),
- std::make_tuple(ExternUsing, ExternTypedef, ExpectLinkedDeclChain),
- std::make_tuple(ExternUsing, AnonTypedef, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonUsing, ExternTypedef, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonUsing, AnonTypedef, ExpectUnlinkedDeclChain),
- std::make_tuple(ExternTypedef, ExternUsing, ExpectLinkedDeclChain),
- std::make_tuple(ExternTypedef, AnonUsing, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonTypedef, ExternUsing, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonTypedef, AnonUsing,
- ExpectUnlinkedDeclChain))), );
- INSTANTIATE_TEST_CASE_P(
- ParameterizedTests, ImportFunctionTemplatesVisibility,
- ::testing::Combine(
- DefaultTestValuesForRunOptions,
- ::testing::Values(
- std::make_tuple(ExternFT, ExternFT, ExpectLinkedDeclChain),
- std::make_tuple(ExternFT, StaticFT, ExpectUnlinkedDeclChain),
- std::make_tuple(ExternFT, AnonFT, ExpectUnlinkedDeclChain),
- std::make_tuple(StaticFT, ExternFT, ExpectUnlinkedDeclChain),
- std::make_tuple(StaticFT, StaticFT, ExpectUnlinkedDeclChain),
- std::make_tuple(StaticFT, AnonFT, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonFT, ExternFT, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonFT, StaticFT, ExpectUnlinkedDeclChain),
- std::make_tuple(AnonFT, AnonFT, ExpectUnlinkedDeclChain))), );
- } // end namespace ast_matchers
- } // end namespace clang
|