697 lines
25 KiB
C++
697 lines
25 KiB
C++
|
//===- 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()));
|
||
|
}
|
||
|
TestLanguage getLang() { return Lang_C99; }
|
||
|
};
|
||
|
|
||
|
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")); }
|
||
|
TestLanguage getLang() { return Lang_CXX03; }
|
||
|
};
|
||
|
|
||
|
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")); }
|
||
|
TestLanguage 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")); }
|
||
|
TestLanguage getLang() { return Lang_CXX03; }
|
||
|
};
|
||
|
|
||
|
struct EnumClass {
|
||
|
using DeclTy = EnumDecl;
|
||
|
static constexpr auto *Definition = "enum class X { a, b };";
|
||
|
static constexpr auto *ConflictingDefinition = "enum class X { a, b, c };";
|
||
|
BindableMatcher<Decl> getPattern() { return enumDecl(hasName("X")); }
|
||
|
TestLanguage getLang() { return Lang_CXX11; }
|
||
|
};
|
||
|
|
||
|
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")); }
|
||
|
TestLanguage getLang() { return Lang_CXX03; }
|
||
|
};
|
||
|
|
||
|
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()));
|
||
|
}
|
||
|
TestLanguage getLang() { return Lang_CXX03; }
|
||
|
};
|
||
|
|
||
|
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")); }
|
||
|
TestLanguage getLang() { return Lang_CXX03; }
|
||
|
};
|
||
|
|
||
|
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()));
|
||
|
}
|
||
|
TestLanguage getLang() { return Lang_CXX03; }
|
||
|
};
|
||
|
|
||
|
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; }
|
||
|
TestLanguage getLang() { return Lang_CXX03; }
|
||
|
};
|
||
|
|
||
|
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")); }
|
||
|
TestLanguage 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()));
|
||
|
}
|
||
|
TestLanguage getLang() { return Lang_CXX03; }
|
||
|
};
|
||
|
|
||
|
// 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; }
|
||
|
TestLanguage getLang() { return Lang_CXX03; }
|
||
|
};
|
||
|
|
||
|
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()));
|
||
|
}
|
||
|
TestLanguage 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 TestLanguage 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(
|
||
|
EnumClass, 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(
|
||
|
EnumClass, 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.
|
||
|
// ======================
|
||
|
|
||
|
// FIXME: These fail on Windows.
|
||
|
#if !defined(_WIN32)
|
||
|
INSTANTIATE_TEST_CASE_P(
|
||
|
ODRViolationTests, FunctionConservative,
|
||
|
DefaultTestValuesForRunOptions, );
|
||
|
#endif
|
||
|
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, EnumClassConservative,
|
||
|
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, );
|
||
|
|
||
|
// FIXME: These fail on Windows.
|
||
|
#if !defined(_WIN32)
|
||
|
INSTANTIATE_TEST_CASE_P(
|
||
|
ODRViolationTests, FunctionLiberal,
|
||
|
DefaultTestValuesForRunOptions, );
|
||
|
#endif
|
||
|
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, EnumClassLiberal,
|
||
|
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
|