martong updated this revision to Diff 220104. martong marked an inline comment as done. martong added a comment.
- Initialize the variable template in test - Clean up tests for fun templates and for specializations Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66951/new/ https://reviews.llvm.org/D66951 Files: clang/unittests/AST/ASTImporterODRStrategiesTest.cpp clang/unittests/AST/ASTImporterTest.cpp clang/unittests/AST/CMakeLists.txt
Index: clang/unittests/AST/CMakeLists.txt =================================================================== --- clang/unittests/AST/CMakeLists.txt +++ clang/unittests/AST/CMakeLists.txt @@ -11,6 +11,7 @@ ASTImporterFixtures.cpp ASTImporterTest.cpp ASTImporterGenericRedeclTest.cpp + ASTImporterODRStrategiesTest.cpp ASTImporterVisibilityTest.cpp ASTTraverserTest.cpp ASTTypeTraitsTest.cpp Index: clang/unittests/AST/ASTImporterTest.cpp =================================================================== --- clang/unittests/AST/ASTImporterTest.cpp +++ clang/unittests/AST/ASTImporterTest.cpp @@ -5409,187 +5409,6 @@ EXPECT_EQ(ImportedX->isAggregate(), FromX->isAggregate()); } -struct ConflictingDeclsWithLiberalStrategy : ASTImporterOptionSpecificTestBase { - ConflictingDeclsWithLiberalStrategy() { - this->ODRHandling = ASTImporter::ODRHandlingType::Liberal; - } -}; - -// Check that a Decl has been successfully imported into a standalone redecl -// chain. -template <typename DeclTy, typename PatternTy> -static void CheckImportedAsNew(llvm::Expected<Decl *> &Result, Decl *ToTU, - PatternTy Pattern) { - ASSERT_TRUE(isSuccess(Result)); - Decl *ImportedD = *Result; - ASSERT_TRUE(ImportedD); - auto *ToD = FirstDeclMatcher<DeclTy>().match(ToTU, Pattern); - EXPECT_NE(ImportedD, ToD); - EXPECT_FALSE(ImportedD->getPreviousDecl()); - EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, Pattern), 2u); -} - -TEST_P(ConflictingDeclsWithLiberalStrategy, Typedef) { - Decl *ToTU = getToTuDecl( - R"( - typedef int X; - )", - Lang_CXX11); - Decl *FromTU = getTuDecl( - R"( - typedef double X; - )", - Lang_CXX11); - auto Pattern = typedefNameDecl(hasName("X")); - auto *FromX = FirstDeclMatcher<TypedefNameDecl>().match(FromTU, Pattern); - - Expected<Decl *> Result = importOrError(FromX, Lang_CXX11); - CheckImportedAsNew<TypedefNameDecl>(Result, ToTU, Pattern); -} - -TEST_P(ConflictingDeclsWithLiberalStrategy, TypeAlias) { - Decl *ToTU = getToTuDecl( - R"( - using X = int; - )", - Lang_CXX11); - Decl *FromTU = getTuDecl( - R"( - using X = double; - )", - Lang_CXX11); - auto Pattern = typedefNameDecl(hasName("X")); - auto *FromX = FirstDeclMatcher<TypedefNameDecl>().match(FromTU, Pattern); - Expected<Decl *> Result = importOrError(FromX, Lang_CXX11); - CheckImportedAsNew<TypedefNameDecl>(Result, ToTU, Pattern); -} - -TEST_P(ConflictingDeclsWithLiberalStrategy, EnumDecl) { - Decl *ToTU = getToTuDecl( - R"( - enum X { a, b }; - )", - Lang_CXX11); - Decl *FromTU = getTuDecl( - R"( - enum X { a, b, c }; - )", - Lang_CXX11); - auto Pattern = enumDecl(hasName("X")); - auto *FromX = FirstDeclMatcher<EnumDecl>().match(FromTU, Pattern); - Expected<Decl *> Result = importOrError(FromX, Lang_CXX11); - CheckImportedAsNew<EnumDecl>(Result, ToTU, Pattern); -} - -TEST_P(ConflictingDeclsWithLiberalStrategy, EnumConstantDecl) { - Decl *ToTU = getToTuDecl( - R"( - enum E { X = 0 }; - )", - Lang_CXX11); - Decl *FromTU = getTuDecl( - R"( - enum E { X = 1 }; - )", - Lang_CXX11); - auto Pattern = enumConstantDecl(hasName("X")); - auto *FromX = FirstDeclMatcher<EnumConstantDecl>().match(FromTU, Pattern); - Expected<Decl *> Result = importOrError(FromX, Lang_CXX11); - CheckImportedAsNew<EnumConstantDecl>(Result, ToTU, Pattern); -} - -TEST_P(ConflictingDeclsWithLiberalStrategy, RecordDecl) { - Decl *ToTU = getToTuDecl( - R"( - class X { int a; }; - )", - Lang_CXX11); - Decl *FromTU = getTuDecl( - R"( - class X { int b; }; - )", - Lang_CXX11); - auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit())); - auto *FromX = FirstDeclMatcher<RecordDecl>().match(FromTU, Pattern); - Expected<Decl *> Result = importOrError(FromX, Lang_CXX11); - CheckImportedAsNew<RecordDecl>(Result, ToTU, Pattern); -} - -TEST_P(ConflictingDeclsWithLiberalStrategy, VarDecl) { - Decl *ToTU = getToTuDecl( - R"( - int X; - )", - Lang_CXX11); - Decl *FromTU = getTuDecl( - R"( - double X; - )", - Lang_CXX11); - auto Pattern = varDecl(hasName("X")); - auto *FromX = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern); - Expected<Decl *> Result = importOrError(FromX, Lang_CXX11); - CheckImportedAsNew<VarDecl>(Result, ToTU, Pattern); -} - -TEST_P(ConflictingDeclsWithLiberalStrategy, FunctionDecl) { - Decl *ToTU = getToTuDecl( - R"( - void X(int); - )", - Lang_C); // C, no overloading! - Decl *FromTU = getTuDecl( - R"( - void X(double); - )", - Lang_C); - auto Pattern = functionDecl(hasName("X")); - auto *FromX = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); - Expected<Decl *> Result = importOrError(FromX, Lang_CXX11); - CheckImportedAsNew<FunctionDecl>(Result, ToTU, Pattern); -} - -TEST_P(ConflictingDeclsWithLiberalStrategy, ClassTemplateDecl) { - Decl *ToTU = getToTuDecl( - R"( - template <class> - struct X; - )", - Lang_CXX11); - Decl *FromTU = getTuDecl( - R"( - template <int> - struct X; - )", - Lang_CXX11); - auto Pattern = classTemplateDecl(hasName("X")); - auto *FromX = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, Pattern); - Expected<Decl *> Result = importOrError(FromX, Lang_CXX11); - CheckImportedAsNew<ClassTemplateDecl>(Result, ToTU, Pattern); -} - -TEST_P(ConflictingDeclsWithLiberalStrategy, DISABLED_VarTemplateDecl) { - const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateDecl> - varTemplateDecl; - Decl *ToTU = getToTuDecl( - R"( - template <class T> - constexpr T X; - )", - Lang_CXX14); - Decl *FromTU = getTuDecl( - R"( - template <int> - constexpr int X = 0; - )", - Lang_CXX14); - auto Pattern = varTemplateDecl(hasName("X")); - auto *FromX = FirstDeclMatcher<VarTemplateDecl>().match( - FromTU, varTemplateDecl(hasName("X"))); - Expected<Decl *> Result = importOrError(FromX, Lang_CXX11); - CheckImportedAsNew<VarTemplateDecl>(Result, ToTU, Pattern); -} - INSTANTIATE_TEST_CASE_P(ParameterizedTests, SVEBuiltins, ::testing::Values(ArgVector{"-target", "aarch64-linux-gnu"}), ); @@ -5655,8 +5474,5 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTests, LLDBLookupTest, DefaultTestValuesForRunOptions, ); -INSTANTIATE_TEST_CASE_P(ParameterizedTests, ConflictingDeclsWithLiberalStrategy, - DefaultTestValuesForRunOptions, ); - } // end namespace ast_matchers } // end namespace clang Index: clang/unittests/AST/ASTImporterODRStrategiesTest.cpp =================================================================== --- /dev/null +++ clang/unittests/AST/ASTImporterODRStrategiesTest.cpp @@ -0,0 +1,609 @@ +//===- unittest/AST/ASTImporterODRStrategiesTest.cpp -----------------------===// +// +// 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 to verify the import behaviour in case of ODR +// violation. +// +//===----------------------------------------------------------------------===// + +#include "ASTImporterFixtures.h" + +namespace clang { +namespace ast_matchers { + +using internal::BindableMatcher; + +// DeclTy: Type of the Decl to check. +// Prototype: "Prototype" (forward declaration) of the Decl. +// Definition: A definition for the Prototype. +// ConflictingPrototype: A prototype with the same name but different +// declaration. +// ConflictingDefinition: A different definition for Prototype. +// ConflictingProtoDef: A definition for ConflictingPrototype. +// getPattern: Return a matcher that matches any of Prototype, Definition, +// ConflictingPrototype, ConflictingDefinition, ConflictingProtoDef. + +struct Function { + using DeclTy = FunctionDecl; + static constexpr auto *Prototype = "void X(int);"; + static constexpr auto *ConflictingPrototype = "void X(double);"; + static constexpr auto *Definition = "void X(int a) {}"; + static constexpr auto *ConflictingDefinition = "void X(double a) {}"; + BindableMatcher<Decl> getPattern() { + return functionDecl(hasName("X"), unless(isImplicit())); + } + Language getLang() { return Lang_C; } +}; + +struct Typedef { + using DeclTy = TypedefNameDecl; + static constexpr auto *Definition = "typedef int X;"; + static constexpr auto *ConflictingDefinition = "typedef double X;"; + BindableMatcher<Decl> getPattern() { return typedefNameDecl(hasName("X")); } + Language getLang() { return Lang_CXX; } +}; + +struct TypedefAlias { + using DeclTy = TypedefNameDecl; + static constexpr auto *Definition = "using X = int;"; + static constexpr auto *ConflictingDefinition = "using X = double;"; + BindableMatcher<Decl> getPattern() { return typedefNameDecl(hasName("X")); } + Language getLang() { return Lang_CXX11; } +}; + +struct Enum { + using DeclTy = EnumDecl; + static constexpr auto *Definition = "enum X { a, b };"; + static constexpr auto *ConflictingDefinition = "enum X { a, b, c };"; + BindableMatcher<Decl> getPattern() { return enumDecl(hasName("X")); } + Language getLang() { return Lang_CXX; } +}; + +struct EnumConstant { + using DeclTy = EnumConstantDecl; + static constexpr auto *Definition = "enum E { X = 0 };"; + static constexpr auto *ConflictingDefinition = "enum E { X = 1 };"; + BindableMatcher<Decl> getPattern() { return enumConstantDecl(hasName("X")); } + Language getLang() { return Lang_CXX; } +}; + +struct Class { + using DeclTy = CXXRecordDecl; + static constexpr auto *Prototype = "class X;"; + static constexpr auto *Definition = "class X {};"; + static constexpr auto *ConflictingDefinition = "class X { int A; };"; + BindableMatcher<Decl> getPattern() { + return cxxRecordDecl(hasName("X"), unless(isImplicit())); + } + Language getLang() { return Lang_CXX; } +}; + +struct Variable { + using DeclTy = VarDecl; + static constexpr auto *Prototype = "extern int X;"; + static constexpr auto *ConflictingPrototype = "extern float X;"; + static constexpr auto *Definition = "int X;"; + static constexpr auto *ConflictingDefinition = "float X;"; + BindableMatcher<Decl> getPattern() { return varDecl(hasName("X")); } + Language getLang() { return Lang_CXX; } +}; + +struct ClassTemplate { + using DeclTy = ClassTemplateDecl; + static constexpr auto *Prototype = "template <class> class X;"; + static constexpr auto *ConflictingPrototype = "template <int> class X;"; + static constexpr auto *Definition = "template <class> class X {};"; + static constexpr auto *ConflictingDefinition = + "template <class> class X { int A; };"; + static constexpr auto *ConflictingProtoDef = "template <int> class X { };"; + BindableMatcher<Decl> getPattern() { + return classTemplateDecl(hasName("X"), unless(isImplicit())); + } + Language getLang() { return Lang_CXX; } +}; + +struct FunctionTemplate { + using DeclTy = FunctionTemplateDecl; + static constexpr auto *Prototype = + R"( + template <class T> + void X(T a); + )"; + static constexpr auto *ConflictingPrototype = + R"( + template <class T> + void X(T* a); + )"; + BindableMatcher<Decl> getPattern() { + return functionTemplateDecl(hasName("X"), unless(isImplicit())); + } + Language getLang() { return Lang_CXX; } +}; + +static const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateDecl> + varTemplateDecl; + +struct VarTemplate { + using DeclTy = VarTemplateDecl; + static constexpr auto *Definition = + R"( + template <class T> + constexpr T X = 0; + )"; + static constexpr auto *ConflictingDefinition = + R"( + template <int> + constexpr int X = 0; + )"; + BindableMatcher<Decl> getPattern() { return varTemplateDecl(hasName("X")); } + Language getLang() { return Lang_CXX14; } +}; + +struct ClassTemplateSpec { + using DeclTy = ClassTemplateSpecializationDecl; + static constexpr auto *Prototype = + R"( + template <class T> class X; + template <> class X<int>; + )"; + static constexpr auto *Definition = + R"( + template <class T> class X; + template <> class X<int> {}; + )"; + static constexpr auto *ConflictingDefinition = + R"( + template <class T> class X; + template <> class X<int> { int A; }; + )"; + BindableMatcher<Decl> getPattern() { + return classTemplateSpecializationDecl(hasName("X"), unless(isImplicit())); + } + Language getLang() { return Lang_CXX; } +}; + +// Function template specializations are all "full" specializations. +// Structural equivalency does not check the body of functions, so we cannot +// create conflicting function template specializations. +struct FunctionTemplateSpec { + using DeclTy = FunctionDecl; + + static constexpr auto *Prototype = + R"( + template <class T> + void X(T a); + template <> void X(int a); + )"; + + // This is the same full specialization. + // And not a conflicting prototype! + // Thus, during the import we would use the existing specialization and would + // not create a new node. + static constexpr auto *Prototype2 = + R"( + template <class T> + void X(T a); + template <> void X(int a); + )"; + + // This is another full specialization. + // And not a conflicting prototype! + // Thus, during the import we would create a new specialization with a + // different type argument. + static constexpr auto *Prototype3 = + R"( + template <class T> + void X(T a); + template <> void X(double a); + )"; + + BindableMatcher<Decl> getPattern() { + return functionDecl(hasName("X"), isExplicitTemplateSpecialization(), + unless(isImplicit())); + } + Language getLang() { return Lang_CXX; } +}; + +static const internal::VariadicDynCastAllOfMatcher< + Decl, VarTemplateSpecializationDecl> + varTemplateSpecializationDecl; + +struct VarTemplateSpec { + using DeclTy = VarTemplateSpecializationDecl; + static constexpr auto *Definition = + R"( + template <class T> T X = 0; + template <> int X<int> = 0; + )"; + static constexpr auto *ConflictingDefinition = + R"( + template <class T> T X = 0; + template <> float X<int> = 1.0; + )"; + BindableMatcher<Decl> getPattern() { + return varTemplateSpecializationDecl(hasName("X"), unless(isImplicit())); + } + Language getLang() { return Lang_CXX14; } +}; + +template <typename TypeParam, ASTImporter::ODRHandlingType ODRHandlingParam> +struct ODRViolation : ASTImporterOptionSpecificTestBase { + + using DeclTy = typename TypeParam::DeclTy; + + ODRViolation() { ODRHandling = ODRHandlingParam; } + + static std::string getPrototype() { return TypeParam::Prototype; } + static std::string getConflictingPrototype() { + return TypeParam::ConflictingPrototype; + } + static std::string getDefinition() { return TypeParam::Definition; } + static std::string getConflictingDefinition() { + return TypeParam::ConflictingDefinition; + } + static std::string getConflictingProtoDef() { + return TypeParam::ConflictingProtoDef; + } + static BindableMatcher<Decl> getPattern() { return TypeParam().getPattern(); } + static Language getLang() { return TypeParam().getLang(); } + + template <std::string (*ToTUContent)(), std::string (*FromTUContent)(), + void (*ResultChecker)(llvm::Expected<Decl *> &, Decl *, Decl *)> + void TypedTest_ImportAfter() { + Decl *ToTU = getToTuDecl(ToTUContent(), getLang()); + auto *ToD = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern()); + + Decl *FromTU = getTuDecl(FromTUContent(), getLang()); + auto *FromD = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern()); + + auto Result = importOrError(FromD, getLang()); + + ResultChecker(Result, ToTU, ToD); + } + + // Check that a Decl has been successfully imported into a standalone redecl + // chain. + static void CheckImportedAsNew(llvm::Expected<Decl *> &Result, Decl *ToTU, + Decl *ToD) { + ASSERT_TRUE(isSuccess(Result)); + Decl *ImportedD = *Result; + ASSERT_TRUE(ImportedD); + EXPECT_NE(ImportedD, ToD); + EXPECT_FALSE(ImportedD->getPreviousDecl()); + EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u); + } + + // Check that a Decl was not imported because of NameConflict. + static void CheckImportNameConflict(llvm::Expected<Decl *> &Result, + Decl *ToTU, Decl *ToD) { + EXPECT_TRUE(isImportError(Result, ImportError::NameConflict)); + EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 1u); + } + + void TypedTest_ImportConflictingDefAfterDef() { + TypedTest_ImportAfter<getDefinition, getConflictingDefinition, + CheckImportedAsNew>(); + } + void TypedTest_ImportConflictingProtoAfterProto() { + TypedTest_ImportAfter<getPrototype, getConflictingPrototype, + CheckImportedAsNew>(); + } + void TypedTest_ImportConflictingProtoAfterDef() { + TypedTest_ImportAfter<getDefinition, getConflictingPrototype, + CheckImportedAsNew>(); + } + void TypedTest_ImportConflictingDefAfterProto() { + TypedTest_ImportAfter<getConflictingPrototype, getDefinition, + CheckImportedAsNew>(); + } + void TypedTest_ImportConflictingProtoDefAfterProto() { + TypedTest_ImportAfter<getPrototype, getConflictingProtoDef, + CheckImportedAsNew>(); + } + void TypedTest_ImportConflictingProtoAfterProtoDef() { + TypedTest_ImportAfter<getConflictingProtoDef, getPrototype, + CheckImportedAsNew>(); + } + void TypedTest_ImportConflictingProtoDefAfterDef() { + TypedTest_ImportAfter<getDefinition, getConflictingProtoDef, + CheckImportedAsNew>(); + } + void TypedTest_ImportConflictingDefAfterProtoDef() { + TypedTest_ImportAfter<getConflictingProtoDef, getDefinition, + CheckImportedAsNew>(); + } + + void TypedTest_DontImportConflictingProtoAfterProto() { + TypedTest_ImportAfter<getPrototype, getConflictingPrototype, + CheckImportNameConflict>(); + } + void TypedTest_DontImportConflictingDefAfterDef() { + TypedTest_ImportAfter<getDefinition, getConflictingDefinition, + CheckImportNameConflict>(); + } + void TypedTest_DontImportConflictingProtoAfterDef() { + TypedTest_ImportAfter<getDefinition, getConflictingPrototype, + CheckImportNameConflict>(); + } + void TypedTest_DontImportConflictingDefAfterProto() { + TypedTest_ImportAfter<getConflictingPrototype, getDefinition, + CheckImportNameConflict>(); + } + void TypedTest_DontImportConflictingProtoDefAfterProto() { + TypedTest_ImportAfter<getPrototype, getConflictingProtoDef, + CheckImportNameConflict>(); + } + void TypedTest_DontImportConflictingProtoAfterProtoDef() { + TypedTest_ImportAfter<getConflictingProtoDef, getPrototype, + CheckImportNameConflict>(); + } + void TypedTest_DontImportConflictingProtoDefAfterDef() { + TypedTest_ImportAfter<getDefinition, getConflictingProtoDef, + CheckImportNameConflict>(); + } + void TypedTest_DontImportConflictingDefAfterProtoDef() { + TypedTest_ImportAfter<getConflictingProtoDef, getDefinition, + CheckImportNameConflict>(); + } +}; + +// ============================== +// Define the parametrized tests. +// ============================== + +#define ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( \ + TypeParam, ODRHandlingParam, NamePrefix, TestCase) \ + using TypeParam##ODRHandlingParam = \ + ODRViolation<TypeParam, ASTImporter::ODRHandlingType::ODRHandlingParam>; \ + TEST_P(TypeParam##ODRHandlingParam, NamePrefix##TestCase) { \ + TypedTest_##TestCase(); \ + } + +// clang-format off + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Function, Liberal, , + ImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Typedef, Liberal, , + ImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + TypedefAlias, Liberal, , + ImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Enum, Liberal, , + ImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + EnumConstant, Liberal, , + ImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Class, Liberal, , + ImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Variable, Liberal, , + ImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Liberal, , + ImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + VarTemplate, Liberal, , + ImportConflictingDefAfterDef) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Function, Conservative, , + DontImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Typedef, Conservative, , + DontImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + TypedefAlias, Conservative, , + DontImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Enum, Conservative, , + DontImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + EnumConstant, Conservative, , + DontImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Class, Conservative, , + DontImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Variable, Conservative, , + DontImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Conservative, , + DontImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + VarTemplate, Conservative, , + DontImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplateSpec, Conservative, , + DontImportConflictingDefAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + VarTemplateSpec, Conservative, , + DontImportConflictingDefAfterDef) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Function, Liberal, , + ImportConflictingProtoAfterProto) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Variable, Liberal, , + ImportConflictingProtoAfterProto) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Liberal, , + ImportConflictingProtoAfterProto) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + FunctionTemplate, Liberal, , + ImportConflictingProtoAfterProto) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Function, Conservative, , + DontImportConflictingProtoAfterProto) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Variable, Conservative, , + DontImportConflictingProtoAfterProto) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Conservative, , + DontImportConflictingProtoAfterProto) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Variable, Liberal, , + ImportConflictingProtoAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Liberal, , + ImportConflictingProtoAfterDef) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Variable, Conservative, , + DontImportConflictingProtoAfterDef) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Conservative, , + DontImportConflictingProtoAfterDef) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Function, Liberal, , + ImportConflictingDefAfterProto) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Variable, Liberal, , + ImportConflictingDefAfterProto) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Liberal, , + ImportConflictingDefAfterProto) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Function, Conservative, , + DontImportConflictingDefAfterProto) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + Variable, Conservative, , + DontImportConflictingDefAfterProto) +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Conservative, , + DontImportConflictingDefAfterProto) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Liberal, , + ImportConflictingProtoDefAfterProto) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Conservative, , + DontImportConflictingProtoDefAfterProto) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Liberal, , + ImportConflictingProtoAfterProtoDef) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Conservative, , + DontImportConflictingProtoAfterProtoDef) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Liberal, , + ImportConflictingProtoDefAfterDef) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Conservative, , + DontImportConflictingProtoDefAfterDef) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Liberal, , + ImportConflictingDefAfterProtoDef) + +ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE( + ClassTemplate, Conservative, , + DontImportConflictingDefAfterProtoDef) + +// ====================== +// Instantiate the tests. +// ====================== + +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, FunctionConservative, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, TypedefConservative, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, TypedefAliasConservative, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, EnumConservative, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, EnumConstantConservative, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, ClassConservative, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, VariableConservative, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, ClassTemplateConservative, + DefaultTestValuesForRunOptions, ); +// FIXME: Make VarTemplate tests work. +//INSTANTIATE_TEST_CASE_P( + //ODRViolationTests, VarTemplateConservative, + //DefaultTestValuesForRunOptions, ); +// +// Class and variable template specializations/instantiatons are always +// imported conservatively, because the AST holds the specializations in a set, +// and the key within the set is a hash calculated from the arguments of the +// specialization. +// +// Function template specializations are different. They are all "full" +// specializations. Structural equivalency does not check the body of +// functions, so we cannot create conflicting function template specializations. +// Thus, ODR handling strategies has nothing to do with function template +// specializations. +// +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, ClassTemplateSpecConservative, + DefaultTestValuesForRunOptions, ); +// FIXME: Make VarTemplateSpec tests work. +//INSTANTIATE_TEST_CASE_P( + //ODRViolationTests, VarTemplateSpecConservative, + //DefaultTestValuesForRunOptions, ); + +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, FunctionLiberal, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, TypedefLiberal, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, TypedefAliasLiberal, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, EnumLiberal, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, EnumConstantLiberal, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, ClassLiberal, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, VariableLiberal, + DefaultTestValuesForRunOptions, ); +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, ClassTemplateLiberal, + DefaultTestValuesForRunOptions, ); +// FunctionTemplate decls overload with each other. Thus, they are imported +// always "liberally". +INSTANTIATE_TEST_CASE_P( + ODRViolationTests, FunctionTemplateLiberal, + DefaultTestValuesForRunOptions, ); +// FIXME: Make VarTemplate tests work. +// INSTANTIATE_TEST_CASE_P( +// ODRViolationTests, VarTemplateLiberal, +// DefaultTestValuesForRunOptions, ); + +// clang-format on + +} // end namespace ast_matchers +} // end namespace clang
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits