llvm-project/clang/unittests/AST/ASTImporterODRStrategiesTes...

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

673 lines
24 KiB
C++
Raw Normal View History

//===- 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 *Definition0 =
R"(
template <class T>
void X(T a) {};
)";
// This is actually not a conflicting definition, but another primary template.
static constexpr auto *Definition1 =
R"(
template <class T>
void X(T* a) {};
)";
BindableMatcher<Decl> getPattern() {
return functionTemplateDecl(hasName("X"), unless(isImplicit()));
}
static std::string getDef0() { return Definition0; }
static std::string getDef1() { return Definition1; }
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 *Definition0 =
R"(
template <class T>
void X(T a);
template <> void X(int a) {};
)";
// This is actually not a conflicting definition, but another full
// specialization.
// Thus, during the import we would create a new specialization with a
// different type argument.
static constexpr auto *Definition1 =
R"(
template <class T>
void X(T a);
template <> void X(double a) {};
)";
BindableMatcher<Decl> getPattern() {
return functionDecl(hasName("X"), isExplicitTemplateSpecialization(),
unless(isImplicit()));
}
static std::string getDef0() { return Definition0; }
static std::string getDef1() { return Definition1; }
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_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
// There may be a hidden fwd spec decl before a function spec decl.
if (auto *ImportedF = dyn_cast<FunctionDecl>(ImportedD))
if (ImportedF->getTemplatedKind() ==
FunctionDecl::TK_FunctionTemplateSpecialization)
return;
EXPECT_FALSE(ImportedD->getPreviousDecl());
}
// 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);
}
// Check that a Decl was not imported because lookup found the same decl.
static void CheckImportFoundExisting(llvm::Expected<Decl *> &Result,
Decl *ToTU, Decl *ToD) {
ASSERT_TRUE(isSuccess(Result));
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>();
}
// Used for function templates and function template specializations.
void TypedTest_ImportDifferentDefAfterDef() {
TypedTest_ImportAfter<TypeParam::getDef0, TypeParam::getDef1,
CheckImportedAsNew>();
}
void TypedTest_DontImportSameDefAfterDef() {
TypedTest_ImportAfter<TypeParam::getDef0, TypeParam::getDef0,
CheckImportFoundExisting>();
}
};
// ==============================
// 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)
// 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.
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
ClassTemplateSpec, Liberal, ,
DontImportConflictingDefAfterDef) // Don't import !!!
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
VarTemplateSpec, Liberal, ,
DontImportConflictingDefAfterDef) // Don't import !!!
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(
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)
// FunctionTemplate decls overload with each other. Thus, they are imported
// always as a new node, independently from any ODRHandling strategy.
//
// Function template specializations are "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. Fully specialized
// function templates are imported as new nodes if their template arguments are
// different.
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
FunctionTemplate, Liberal, ,
ImportDifferentDefAfterDef)
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
FunctionTemplateSpec, Liberal, ,
ImportDifferentDefAfterDef)
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
FunctionTemplate, Conservative, ,
ImportDifferentDefAfterDef)
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
FunctionTemplateSpec, Conservative, ,
ImportDifferentDefAfterDef)
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
FunctionTemplate, Liberal, ,
DontImportSameDefAfterDef)
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
FunctionTemplateSpec, Liberal, ,
DontImportSameDefAfterDef)
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
FunctionTemplate, Conservative, ,
DontImportSameDefAfterDef)
ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_CASE(
FunctionTemplateSpec, Conservative, ,
DontImportSameDefAfterDef)
// ======================
// Instantiate the tests.
// ======================
INSTANTIATE_TEST_CASE_P(
ODRViolationTests, FunctionConservative,
// These tests fail on Windows.
::testing::Values(ArgVector{"-target", "x86_64-pc-linux-gnu"}), );
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, );
INSTANTIATE_TEST_CASE_P(
ODRViolationTests, FunctionTemplateConservative,
DefaultTestValuesForRunOptions, );
// FIXME: Make VarTemplate tests work.
//INSTANTIATE_TEST_CASE_P(
//ODRViolationTests, VarTemplateConservative,
//DefaultTestValuesForRunOptions, );
INSTANTIATE_TEST_CASE_P(
ODRViolationTests, FunctionTemplateSpecConservative,
DefaultTestValuesForRunOptions, );
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,
// These tests fail on Windows.
::testing::Values(ArgVector{"-target", "x86_64-pc-linux-gnu"}), );
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, );
INSTANTIATE_TEST_CASE_P(
ODRViolationTests, FunctionTemplateLiberal,
DefaultTestValuesForRunOptions, );
// FIXME: Make VarTemplate tests work.
// INSTANTIATE_TEST_CASE_P(
// ODRViolationTests, VarTemplateLiberal,
// DefaultTestValuesForRunOptions, );
INSTANTIATE_TEST_CASE_P(
ODRViolationTests, ClassTemplateSpecLiberal,
DefaultTestValuesForRunOptions, );
INSTANTIATE_TEST_CASE_P(
ODRViolationTests, FunctionTemplateSpecLiberal,
DefaultTestValuesForRunOptions, );
// FIXME: Make VarTemplateSpec tests work.
//INSTANTIATE_TEST_CASE_P(
//ODRViolationTests, VarTemplateSpecLiberal,
//DefaultTestValuesForRunOptions, );
// clang-format on
} // end namespace ast_matchers
} // end namespace clang