struct ImportFunctions : ASTImporterOptionSpecificTestBase {};
-TEST_P(ImportFunctions,
- DefinitionShouldBeImportedAsDefintionWhenThereIsAPrototype) {
- Decl *FromTU = getTuDecl("void f(); void f() {}", Lang_CXX);
- auto Pattern = functionDecl(hasName("f"));
- FunctionDecl *FromD = // Definition
- LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
-
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- EXPECT_TRUE(cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
-}
-
-TEST_P(ImportFunctions, DefinitionShouldBeImportedAsADefinition) {
- Decl *FromTU = getTuDecl("void f() {}", Lang_CXX);
- auto Pattern = functionDecl(hasName("f"));
- FunctionDecl *FromD =
- FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
-
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
- EXPECT_TRUE(cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
-}
-
TEST_P(ImportFunctions, ImportPrototypeOfRecursiveFunction) {
Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX);
auto Pattern = functionDecl(hasName("f"));
EXPECT_EQ(To1->getPreviousDecl(), To0);
}
-TEST_P(ImportFunctions, ImportPrototypes) {
- auto Pattern = functionDecl(hasName("f"));
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
-
- ImportedD = Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input1.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
- EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportFunctions, ImportDefinitions) {
- auto Pattern = functionDecl(hasName("f"));
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl("void f(){}", Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl("void f(){};", Lang_CXX, "input1.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
-}
-
-TEST_P(ImportFunctions, ImportDefinitionThenPrototype) {
- auto Pattern = functionDecl(hasName("f"));
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl("void f(){}", Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input1.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
- EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportFunctions, ImportPrototypeThenDefinition) {
- auto Pattern = functionDecl(hasName("f"));
-
- {
- Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input0.cc");
- FunctionDecl *FromD =
- FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
-
- Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl("void f(){}", Lang_CXX, "input1.cc");
- FunctionDecl *FromD =
- FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
- ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- FunctionDecl *ProtoD = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_FALSE(ProtoD->doesThisDeclarationHaveABody());
- FunctionDecl *DefinitionD =
- LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(DefinitionD->doesThisDeclarationHaveABody());
- EXPECT_EQ(DefinitionD->getPreviousDecl(), ProtoD);
-}
-
-TEST_P(ImportFunctions, ImportPrototypeThenProtoAndDefinition) {
- auto Pattern = functionDecl(hasName("f"));
-
- {
- Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl("void f(); void f(){}", Lang_CXX, "input1.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
-
- ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 3u);
- FunctionDecl *ProtoD = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_FALSE(ProtoD->doesThisDeclarationHaveABody());
-
- FunctionDecl *DefinitionD =
- LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(DefinitionD->doesThisDeclarationHaveABody());
-
- EXPECT_TRUE(DefinitionD->getPreviousDecl());
- EXPECT_FALSE(DefinitionD->getPreviousDecl()->doesThisDeclarationHaveABody());
- EXPECT_EQ(DefinitionD->getPreviousDecl()->getPreviousDecl(), ProtoD);
-}
-
TEST_P(ImportFunctions, OverriddenMethodsShouldBeImported) {
auto Code =
R"(
struct ImportClasses : ASTImporterOptionSpecificTestBase {};
-TEST_P(ImportClasses,
- PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition) {
- Decl *FromTU = getTuDecl("class X;", Lang_CXX);
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto FromD = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
-
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 1u);
- auto ToD = LastDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == ToD);
- EXPECT_FALSE(ToD->isThisDeclarationADefinition());
-}
-
-TEST_P(ImportClasses, ImportPrototypeAfterImportedPrototype) {
- Decl *FromTU = getTuDecl("class X; class X;", Lang_CXX);
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
- auto From1 = LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 2u);
- auto To0 = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- auto To1 = LastDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- EXPECT_TRUE(Imported1 == To1);
- EXPECT_FALSE(To0->isThisDeclarationADefinition());
- EXPECT_FALSE(To1->isThisDeclarationADefinition());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportClasses, DefinitionShouldBeImportedAsADefinition) {
- Decl *FromTU = getTuDecl("class X {};", Lang_CXX);
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
-
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 1u);
- EXPECT_TRUE(cast<CXXRecordDecl>(ImportedD)->isThisDeclarationADefinition());
-}
-
-TEST_P(ImportClasses, ImportPrototypeFromDifferentTUAfterImportedPrototype) {
- Decl *FromTU0 = getTuDecl("class X;", Lang_CXX, "input0.cc");
- Decl *FromTU1 = getTuDecl("class X;", Lang_CXX, "input1.cc");
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<CXXRecordDecl>().match(FromTU0, Pattern);
- auto From1 = FirstDeclMatcher<CXXRecordDecl>().match(FromTU1, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 2u);
- auto To0 = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- auto To1 = LastDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- EXPECT_TRUE(Imported1 == To1);
- EXPECT_FALSE(To0->isThisDeclarationADefinition());
- EXPECT_FALSE(To1->isThisDeclarationADefinition());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportClasses, ImportDefinitions) {
- Decl *FromTU0 = getTuDecl("class X {};", Lang_CXX, "input0.cc");
- Decl *FromTU1 = getTuDecl("class X {};", Lang_CXX, "input1.cc");
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<CXXRecordDecl>().match(FromTU0, Pattern);
- auto From1 = FirstDeclMatcher<CXXRecordDecl>().match(FromTU1, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(Imported0, Imported1);
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 1u);
- auto To0 = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- EXPECT_TRUE(To0->isThisDeclarationADefinition());
-}
-
-TEST_P(ImportClasses, ImportDefinitionThenPrototype) {
- Decl *FromTU0 = getTuDecl("class X {};", Lang_CXX, "input0.cc");
- Decl *FromTU1 = getTuDecl("class X;", Lang_CXX, "input1.cc");
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto FromDef = FirstDeclMatcher<CXXRecordDecl>().match(FromTU0, Pattern);
- auto FromProto = FirstDeclMatcher<CXXRecordDecl>().match(FromTU1, Pattern);
-
- Decl *ImportedDef = Import(FromDef, Lang_CXX);
- Decl *ImportedProto = Import(FromProto, Lang_CXX);
- Decl *ToTU = ImportedDef->getTranslationUnitDecl();
-
- EXPECT_NE(ImportedDef, ImportedProto);
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 2u);
- auto ToDef = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- auto ToProto = LastDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedDef == ToDef);
- EXPECT_TRUE(ImportedProto == ToProto);
- EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
- EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToProto->getPreviousDecl(), ToDef);
-}
-
-TEST_P(ImportClasses, ImportPrototypeThenDefinition) {
- Decl *FromTU0 = getTuDecl("class X;", Lang_CXX, "input0.cc");
- Decl *FromTU1 = getTuDecl("class X {};", Lang_CXX, "input1.cc");
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto FromProto = FirstDeclMatcher<CXXRecordDecl>().match(FromTU0, Pattern);
- auto FromDef = FirstDeclMatcher<CXXRecordDecl>().match(FromTU1, Pattern);
-
- Decl *ImportedProto = Import(FromProto, Lang_CXX);
- Decl *ImportedDef = Import(FromDef, Lang_CXX);
- Decl *ToTU = ImportedDef->getTranslationUnitDecl();
-
- EXPECT_NE(ImportedDef, ImportedProto);
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 2u);
- auto ToProto = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- auto ToDef = LastDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedDef == ToDef);
- EXPECT_TRUE(ImportedProto == ToProto);
- EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
- EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
-}
-
-TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInToContext) {
- Decl *ToTU = getToTuDecl("struct X;", Lang_C);
- Decl *FromTU1 = getTuDecl("struct X {};", Lang_C, "input1.cc");
- auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
- auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
- auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
-
- Decl *ImportedDef = Import(FromDef, Lang_C);
-
- EXPECT_NE(ImportedDef, ToProto);
- EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
- auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedDef == ToDef);
- EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
- EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
-}
-
TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContext) {
Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_C);
Decl *FromTU1 = getTuDecl("struct X {};", Lang_C, "input1.cc");
EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
}
-struct ImportClassTemplates : ASTImporterOptionSpecificTestBase {};
+// FIXME put these structs and the tests rely on them into their own separate
+// test file!
+struct Function {
+ using DeclTy = FunctionDecl;
+ static constexpr auto *Prototype = "void X();";
+ static constexpr auto *Definition = "void X() {}";
+ BindableMatcher<Decl> getPattern() {
+ return functionDecl(hasName("X"), unless(isImplicit()));
+ }
+};
-TEST_P(ImportClassTemplates,
- PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition) {
- Decl *FromTU = getTuDecl("template <class T> class X;", Lang_CXX);
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto FromD = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, Pattern);
+struct Class {
+ using DeclTy = CXXRecordDecl;
+ static constexpr auto *Prototype = "class X;";
+ static constexpr auto *Definition = "class X {};";
+ BindableMatcher<Decl> getPattern() {
+ return cxxRecordDecl(hasName("X"), unless(isImplicit()));
+ }
+};
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
+struct Variable {
+ using DeclTy = VarDecl;
+ static constexpr auto *Prototype = "extern int X;";
+ static constexpr auto *Definition = "int X;";
+ BindableMatcher<Decl> getPattern() {
+ return varDecl(hasName("X"));
+ }
+};
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 1u);
- auto ToD = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == ToD);
- ASSERT_TRUE(ToD->getTemplatedDecl());
- EXPECT_FALSE(ToD->isThisDeclarationADefinition());
-}
+struct FunctionTemplate {
+ using DeclTy = FunctionTemplateDecl;
+ static constexpr auto *Prototype = "template <class T> void X();";
+ static constexpr auto *Definition =
+ R"(
+ template <class T> void X() {};
+ // Explicit instantiation is a must because of -fdelayed-template-parsing:
+ template void X<int>();
+ )";
+ BindableMatcher<Decl> getPattern() {
+ return functionTemplateDecl(hasName("X"), unless(isImplicit()));
+ }
+};
-TEST_P(ImportClassTemplates, ImportPrototypeAfterImportedPrototype) {
- Decl *FromTU = getTuDecl(
- "template <class T> class X; template <class T> class X;", Lang_CXX);
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, Pattern);
- auto From1 = LastDeclMatcher<ClassTemplateDecl>().match(FromTU, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 2u);
- auto To0 = FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- auto To1 = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- EXPECT_TRUE(Imported1 == To1);
- ASSERT_TRUE(To0->getTemplatedDecl());
- ASSERT_TRUE(To1->getTemplatedDecl());
- EXPECT_FALSE(To0->isThisDeclarationADefinition());
- EXPECT_FALSE(To1->isThisDeclarationADefinition());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
- EXPECT_EQ(To1->getTemplatedDecl()->getPreviousDecl(),
- To0->getTemplatedDecl());
-}
+struct ClassTemplate {
+ using DeclTy = ClassTemplateDecl;
+ static constexpr auto *Prototype = "template <class T> class X;";
+ static constexpr auto *Definition = "template <class T> class X {};";
+ BindableMatcher<Decl> getPattern() {
+ return classTemplateDecl(hasName("X"), unless(isImplicit()));
+ }
+};
-TEST_P(ImportClassTemplates, DefinitionShouldBeImportedAsADefinition) {
- Decl *FromTU = getTuDecl("template <class T> class X {};", Lang_CXX);
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, Pattern);
+struct FunctionTemplateSpec {
+ using DeclTy = FunctionDecl;
+ static constexpr auto *Prototype =
+ R"(
+ // Proto of the primary template.
+ template <class T>
+ void X();
+ // Proto of the specialization.
+ template <>
+ void X<int>();
+ )";
+ static constexpr auto *Definition =
+ R"(
+ // Proto of the primary template.
+ template <class T>
+ void X();
+ // Specialization and definition.
+ template <>
+ void X<int>() {}
+ )";
+ BindableMatcher<Decl> getPattern() {
+ return functionDecl(hasName("X"), isExplicitTemplateSpecialization());
+ }
+};
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
+template <typename TypeParam>
+struct RedeclChain : ASTImporterOptionSpecificTestBase {
+
+ using DeclTy = typename TypeParam::DeclTy;
+ std::string getPrototype() { return TypeParam::Prototype; }
+ std::string getDefinition() { return TypeParam::Definition; }
+ BindableMatcher<Decl> getPattern() const { return TypeParam().getPattern(); }
+
+ void
+ TypedTest_PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition() {
+ Decl *FromTU = getTuDecl(getPrototype(), Lang_CXX);
+ auto *FromD = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_FALSE(FromD->isThisDeclarationADefinition());
+
+ Decl *ImportedD = Import(FromD, Lang_CXX);
+ Decl *ToTU = ImportedD->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 1u);
+ auto *ToD = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ImportedD == ToD);
+ EXPECT_FALSE(ToD->isThisDeclarationADefinition());
+ if (auto *ToT = dyn_cast<TemplateDecl>(ToD))
+ EXPECT_TRUE(ToT->getTemplatedDecl());
+ }
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 1u);
- auto ToD = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- ASSERT_TRUE(ToD->getTemplatedDecl());
- EXPECT_TRUE(ToD->isThisDeclarationADefinition());
-}
-
-TEST_P(ImportClassTemplates,
- ImportPrototypeFromDifferentTUAfterImportedPrototype) {
- Decl *FromTU0 =
- getTuDecl("template <class T> class X;", Lang_CXX, "input0.cc");
- Decl *FromTU1 =
- getTuDecl("template <class T> class X;", Lang_CXX, "input1.cc");
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU0, Pattern);
- auto From1 = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU1, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 2u);
- auto To0 = FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- auto To1 = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- EXPECT_TRUE(Imported1 == To1);
- ASSERT_TRUE(To0->getTemplatedDecl());
- ASSERT_TRUE(To1->getTemplatedDecl());
- EXPECT_FALSE(To0->isThisDeclarationADefinition());
- EXPECT_FALSE(To1->isThisDeclarationADefinition());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
- EXPECT_EQ(To1->getTemplatedDecl()->getPreviousDecl(),
- To0->getTemplatedDecl());
-}
-
-TEST_P(ImportClassTemplates, ImportDefinitions) {
- Decl *FromTU0 =
- getTuDecl("template <class T> class X {};", Lang_CXX, "input0.cc");
- Decl *FromTU1 =
- getTuDecl("template <class T> class X {};", Lang_CXX, "input1.cc");
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU0, Pattern);
- auto From1 = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU1, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(Imported0, Imported1);
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 1u);
- auto To0 = FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- ASSERT_TRUE(To0->getTemplatedDecl());
- EXPECT_TRUE(To0->isThisDeclarationADefinition());
-}
-
-TEST_P(ImportClassTemplates, ImportDefinitionThenPrototype) {
- Decl *FromTU0 =
- getTuDecl("template <class T> class X {};", Lang_CXX, "input0.cc");
- Decl *FromTU1 =
- getTuDecl("template <class T> class X;", Lang_CXX, "input1.cc");
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto FromDef = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU0, Pattern);
- auto FromProto =
- FirstDeclMatcher<ClassTemplateDecl>().match(FromTU1, Pattern);
+ void TypedTest_DefinitionShouldBeImportedAsADefinition() {
+ Decl *FromTU = getTuDecl(getDefinition(), Lang_CXX);
+ auto *FromD = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_TRUE(FromD->isThisDeclarationADefinition());
- Decl *ImportedDef = Import(FromDef, Lang_CXX);
- Decl *ImportedProto = Import(FromProto, Lang_CXX);
- Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+ Decl *ImportedD = Import(FromD, Lang_CXX);
+ Decl *ToTU = ImportedD->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 1u);
+ auto *ToD = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ToD->isThisDeclarationADefinition());
+ if (auto *ToT = dyn_cast<TemplateDecl>(ToD))
+ EXPECT_TRUE(ToT->getTemplatedDecl());
+ }
+
+ void TypedTest_ImportPrototypeAfterImportedPrototype() {
+ Decl *FromTU = getTuDecl(
+ getPrototype() + getPrototype(), Lang_CXX);
+ auto *From0 =
+ FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ auto *From1 = LastDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_FALSE(From0->isThisDeclarationADefinition());
+ ASSERT_FALSE(From1->isThisDeclarationADefinition());
+
+ Decl *Imported0 = Import(From0, Lang_CXX);
+ Decl *Imported1 = Import(From1, Lang_CXX);
+ Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *To0 = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *To1 = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(Imported0 == To0);
+ EXPECT_TRUE(Imported1 == To1);
+ EXPECT_FALSE(To0->isThisDeclarationADefinition());
+ EXPECT_FALSE(To1->isThisDeclarationADefinition());
+ EXPECT_EQ(To1->getPreviousDecl(), To0);
+ if (auto *ToT0 = dyn_cast<TemplateDecl>(To0)) {
+ auto *ToT1 = cast<TemplateDecl>(To1);
+ ASSERT_TRUE(ToT0->getTemplatedDecl());
+ ASSERT_TRUE(ToT1->getTemplatedDecl());
+ EXPECT_EQ(ToT1->getTemplatedDecl()->getPreviousDecl(),
+ ToT0->getTemplatedDecl());
+ }
+ }
+
+ void TypedTest_ImportDefinitionAfterImportedPrototype() {
+ Decl *FromTU = getTuDecl(
+ getPrototype() + getDefinition(), Lang_CXX);
+ auto *FromProto = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ auto *FromDef = LastDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_FALSE(FromProto->isThisDeclarationADefinition());
+ ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
+
+ Decl *ImportedProto = Import(FromProto, Lang_CXX);
+ Decl *ImportedDef = Import(FromDef, Lang_CXX);
+ Decl *ToTU = ImportedProto->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *ToProto = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *ToDef = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ImportedProto == ToProto);
+ EXPECT_TRUE(ImportedDef == ToDef);
+ EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+ EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+ EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
+ if (auto *ToProtoT = dyn_cast<TemplateDecl>(ToProto)) {
+ auto *ToDefT = cast<TemplateDecl>(ToDef);
+ ASSERT_TRUE(ToProtoT->getTemplatedDecl());
+ ASSERT_TRUE(ToDefT->getTemplatedDecl());
+ EXPECT_EQ(ToDefT->getTemplatedDecl()->getPreviousDecl(),
+ ToProtoT->getTemplatedDecl());
+ }
+ }
+
+ void TypedTest_ImportPrototypeAfterImportedDefinition() {
+ Decl *FromTU = getTuDecl(
+ getDefinition() + getPrototype(), Lang_CXX);
+ auto *FromDef = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ auto *FromProto = LastDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
+ ASSERT_FALSE(FromProto->isThisDeclarationADefinition());
+
+ Decl *ImportedDef = Import(FromDef, Lang_CXX);
+ Decl *ImportedProto = Import(FromProto, Lang_CXX);
+ Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *ToDef = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *ToProto = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ImportedDef == ToDef);
+ EXPECT_TRUE(ImportedProto == ToProto);
+ EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+ EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+ EXPECT_EQ(ToProto->getPreviousDecl(), ToDef);
+ if (auto *ToDefT = dyn_cast<TemplateDecl>(ToDef)) {
+ auto *ToProtoT = cast<TemplateDecl>(ToProto);
+ ASSERT_TRUE(ToDefT->getTemplatedDecl());
+ ASSERT_TRUE(ToProtoT->getTemplatedDecl());
+ EXPECT_EQ(ToProtoT->getTemplatedDecl()->getPreviousDecl(),
+ ToDefT->getTemplatedDecl());
+ }
+ }
+
+ void TypedTest_ImportPrototypes() {
+ Decl *FromTU0 = getTuDecl(getPrototype(), Lang_CXX, "input0.cc");
+ Decl *FromTU1 = getTuDecl(getPrototype(), Lang_CXX, "input1.cc");
+ auto *From0 = FirstDeclMatcher<DeclTy>().match(FromTU0, getPattern());
+ auto *From1 = FirstDeclMatcher<DeclTy>().match(FromTU1, getPattern());
+ ASSERT_FALSE(From0->isThisDeclarationADefinition());
+ ASSERT_FALSE(From1->isThisDeclarationADefinition());
+
+ Decl *Imported0 = Import(From0, Lang_CXX);
+ Decl *Imported1 = Import(From1, Lang_CXX);
+ Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *To0 = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *To1 = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(Imported0 == To0);
+ EXPECT_TRUE(Imported1 == To1);
+ EXPECT_FALSE(To0->isThisDeclarationADefinition());
+ EXPECT_FALSE(To1->isThisDeclarationADefinition());
+ EXPECT_EQ(To1->getPreviousDecl(), To0);
+ if (auto *ToT0 = dyn_cast<TemplateDecl>(To0)) {
+ auto *ToT1 = cast<TemplateDecl>(To1);
+ ASSERT_TRUE(ToT0->getTemplatedDecl());
+ ASSERT_TRUE(ToT1->getTemplatedDecl());
+ EXPECT_EQ(ToT1->getTemplatedDecl()->getPreviousDecl(),
+ ToT0->getTemplatedDecl());
+ }
+ // Extra check for specializations.
+ // FIXME Add this check to other tests too (possibly factor out into a
+ // function), when they start to pass.
+ if (auto *From0F = dyn_cast<FunctionDecl>(From0)) {
+ auto *To0F = cast<FunctionDecl>(To0);
+ if (From0F->getTemplatedKind() ==
+ FunctionDecl::TK_FunctionTemplateSpecialization) {
+ auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
+ ToTU, functionTemplateDecl());
+ auto *FirstSpecD = *(TemplateD->spec_begin());
+ EXPECT_EQ(FirstSpecD->getCanonicalDecl(), To0F->getCanonicalDecl());
+ }
+ }
+ }
+
+ void TypedTest_ImportDefinitions() {
+ Decl *FromTU0 = getTuDecl(getDefinition(), Lang_CXX, "input0.cc");
+ Decl *FromTU1 = getTuDecl(getDefinition(), Lang_CXX, "input1.cc");
+ auto *From0 = FirstDeclMatcher<DeclTy>().match(FromTU0, getPattern());
+ auto *From1 = FirstDeclMatcher<DeclTy>().match(FromTU1, getPattern());
+ ASSERT_TRUE(From0->isThisDeclarationADefinition());
+ ASSERT_TRUE(From1->isThisDeclarationADefinition());
+
+ Decl *Imported0 = Import(From0, Lang_CXX);
+ Decl *Imported1 = Import(From1, Lang_CXX);
+ Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+ EXPECT_EQ(Imported0, Imported1);
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 1u);
+ auto *To0 = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(Imported0 == To0);
+ EXPECT_TRUE(To0->isThisDeclarationADefinition());
+ if (auto *ToT0 = dyn_cast<TemplateDecl>(To0))
+ EXPECT_TRUE(ToT0->getTemplatedDecl());
+ }
+
+ void TypedTest_ImportDefinitionThenPrototype() {
+ Decl *FromTUDef = getTuDecl(getDefinition(), Lang_CXX, "input0.cc");
+ Decl *FromTUProto = getTuDecl(getPrototype(), Lang_CXX, "input1.cc");
+ auto *FromDef = FirstDeclMatcher<DeclTy>().match(FromTUDef, getPattern());
+ auto *FromProto =
+ FirstDeclMatcher<DeclTy>().match(FromTUProto, getPattern());
+ ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
+ ASSERT_FALSE(FromProto->isThisDeclarationADefinition());
+
+ Decl *ImportedDef = Import(FromDef, Lang_CXX);
+ Decl *ImportedProto = Import(FromProto, Lang_CXX);
+ Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+
+ EXPECT_NE(ImportedDef, ImportedProto);
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *ToDef = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *ToProto = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ImportedDef == ToDef);
+ EXPECT_TRUE(ImportedProto == ToProto);
+ EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+ EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+ EXPECT_EQ(ToProto->getPreviousDecl(), ToDef);
+ if (auto *ToDefT = dyn_cast<TemplateDecl>(ToDef)) {
+ auto *ToProtoT = cast<TemplateDecl>(ToProto);
+ ASSERT_TRUE(ToDefT->getTemplatedDecl());
+ ASSERT_TRUE(ToProtoT->getTemplatedDecl());
+ EXPECT_EQ(ToProtoT->getTemplatedDecl()->getPreviousDecl(),
+ ToDefT->getTemplatedDecl());
+ }
+ }
+
+ void TypedTest_ImportPrototypeThenDefinition() {
+ Decl *FromTUProto = getTuDecl(getPrototype(), Lang_CXX, "input0.cc");
+ Decl *FromTUDef = getTuDecl(getDefinition(), Lang_CXX, "input1.cc");
+ auto *FromProto =
+ FirstDeclMatcher<DeclTy>().match(FromTUProto, getPattern());
+ auto *FromDef = FirstDeclMatcher<DeclTy>().match(FromTUDef, getPattern());
+ ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
+ ASSERT_FALSE(FromProto->isThisDeclarationADefinition());
+
+ Decl *ImportedProto = Import(FromProto, Lang_CXX);
+ Decl *ImportedDef = Import(FromDef, Lang_CXX);
+ Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+
+ EXPECT_NE(ImportedDef, ImportedProto);
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *ToProto = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *ToDef = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ImportedDef == ToDef);
+ EXPECT_TRUE(ImportedProto == ToProto);
+ EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+ EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+ EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
+ if (auto *ToDefT = dyn_cast<TemplateDecl>(ToDef)) {
+ auto *ToProtoT = cast<TemplateDecl>(ToProto);
+ ASSERT_TRUE(ToDefT->getTemplatedDecl());
+ ASSERT_TRUE(ToProtoT->getTemplatedDecl());
+ EXPECT_EQ(ToDefT->getTemplatedDecl()->getPreviousDecl(),
+ ToProtoT->getTemplatedDecl());
+ }
+ }
+
+ void TypedTest_WholeRedeclChainIsImportedAtOnce() {
+ Decl *FromTU = getTuDecl(getPrototype() + getDefinition(), Lang_CXX);
+ auto *FromD = // Definition
+ LastDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_TRUE(FromD->isThisDeclarationADefinition());
+
+ Decl *ImportedD = Import(FromD, Lang_CXX);
+ Decl *ToTU = ImportedD->getTranslationUnitDecl();
+
+ // The whole redecl chain is imported at once.
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ EXPECT_TRUE(cast<DeclTy>(ImportedD)->isThisDeclarationADefinition());
+ }
+
+ void TypedTest_ImportPrototypeThenProtoAndDefinition() {
+ {
+ Decl *FromTU = getTuDecl(getPrototype(), Lang_CXX, "input0.cc");
+ auto *FromD = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ Import(FromD, Lang_CXX);
+ }
+ {
+ Decl *FromTU =
+ getTuDecl(getPrototype() + getDefinition(), Lang_CXX, "input1.cc");
+ auto *FromD = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ Import(FromD, Lang_CXX);
+ }
+
+ Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+
+ ASSERT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 3u);
+ DeclTy *ProtoD = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_FALSE(ProtoD->isThisDeclarationADefinition());
+
+ DeclTy *DefinitionD = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(DefinitionD->isThisDeclarationADefinition());
+
+ EXPECT_TRUE(DefinitionD->getPreviousDecl());
+ EXPECT_FALSE(
+ DefinitionD->getPreviousDecl()->isThisDeclarationADefinition());
+ EXPECT_EQ(DefinitionD->getPreviousDecl()->getPreviousDecl(), ProtoD);
+ }
+};
+
+#define ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(BaseTemplate, TypeParam, \
+ NamePrefix, TestCase) \
+ using BaseTemplate##TypeParam = BaseTemplate<TypeParam>; \
+ TEST_P(BaseTemplate##TypeParam, NamePrefix##TestCase) { \
+ TypedTest_##TestCase(); \
+ }
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Function, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Class, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Variable, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+// FIXME Enable this test, once we import function templates chains correctly.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, FunctionTemplate, DISABLED_,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, ClassTemplate, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, FunctionTemplateSpec, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Function, , DefinitionShouldBeImportedAsADefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Class, , DefinitionShouldBeImportedAsADefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Variable, , DefinitionShouldBeImportedAsADefinition);
+// FIXME Enable this test, once we import function templates chains correctly.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, FunctionTemplate, DISABLED_,
+ DefinitionShouldBeImportedAsADefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, ClassTemplate, , DefinitionShouldBeImportedAsADefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, FunctionTemplateSpec, ,
+ DefinitionShouldBeImportedAsADefinition);
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportPrototypeAfterImportedPrototype);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
+ ImportPrototypeAfterImportedPrototype);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportPrototypeAfterImportedPrototype);
+// FIXME Enable this test, once we import function templates chains correctly.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
+ DISABLED_,
+ ImportPrototypeAfterImportedPrototype);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportPrototypeAfterImportedPrototype);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportPrototypeAfterImportedPrototype);
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportDefinitionAfterImportedPrototype);
+// FIXME This does not pass, possible error with Class import.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, DISABLED_,
+ ImportDefinitionAfterImportedPrototype);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportDefinitionAfterImportedPrototype);
+// FIXME Enable this test, once we import function templates chains correctly.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
+ DISABLED_,
+ ImportDefinitionAfterImportedPrototype);
+// FIXME This does not pass, possible error with ClassTemplate import.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, DISABLED_,
+ ImportDefinitionAfterImportedPrototype);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportDefinitionAfterImportedPrototype);
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportPrototypeAfterImportedDefinition);
+// FIXME This does not pass, possible error with Class import.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, DISABLED_,
+ ImportPrototypeAfterImportedDefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportPrototypeAfterImportedDefinition);
+// FIXME Enable this test, once we import function templates chains correctly.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
+ DISABLED_,
+ ImportPrototypeAfterImportedDefinition);
+// FIXME This does not pass, possible error with ClassTemplate import.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, DISABLED_,
+ ImportPrototypeAfterImportedDefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportPrototypeAfterImportedDefinition);
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportPrototypes);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, , ImportPrototypes);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportPrototypes);
+// FIXME Enable this test, once we import function templates chains correctly.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
+ DISABLED_, ImportPrototypes);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportPrototypes);
+// FIXME This does not pass, possible error with Spec import.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec,
+ DISABLED_, ImportPrototypes);
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportDefinitions);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
+ ImportDefinitions);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportDefinitions);
+// FIXME Enable this test, once we import function templates chains correctly.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
+ DISABLED_, ImportDefinitions);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportDefinitions);
+// FIXME This does not pass, possible error with Spec import.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec,
+ DISABLED_, ImportDefinitions);
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportDefinitionThenPrototype);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
+ ImportDefinitionThenPrototype);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportDefinitionThenPrototype);
+// FIXME Enable this test, once we import function templates chains correctly.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
+ DISABLED_,
+ ImportDefinitionThenPrototype);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportDefinitionThenPrototype);
+// FIXME This does not pass, possible error with Spec import.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec,
+ DISABLED_,
+ ImportDefinitionThenPrototype);
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportPrototypeThenDefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
+ ImportPrototypeThenDefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportPrototypeThenDefinition);
+// FIXME Enable this test, once we import function templates chains correctly.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
+ DISABLED_,
+ ImportPrototypeThenDefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportPrototypeThenDefinition);
+// FIXME This does not pass, possible error with Spec import.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec,
+ DISABLED_,
+ ImportPrototypeThenDefinition);
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ WholeRedeclChainIsImportedAtOnce);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ WholeRedeclChainIsImportedAtOnce);
+// FIXME Enable this test, once we import function templates chains correctly.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
+ DISABLED_,
+ WholeRedeclChainIsImportedAtOnce);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ WholeRedeclChainIsImportedAtOnce);
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportPrototypeThenProtoAndDefinition);
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportPrototypeThenProtoAndDefinition);
+// FIXME Enable this test, once we import function templates chains correctly.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
+ DISABLED_,
+ ImportPrototypeThenProtoAndDefinition);
+// FIXME This does not pass, possible error with Spec import.
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec,
+ DISABLED_,
+ ImportPrototypeThenProtoAndDefinition);
+
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainFunction,
+ DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainClass,
+ DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainVariable,
+ DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainFunctionTemplate,
+ DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainClassTemplate,
+ DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainFunctionTemplateSpec,
+ DefaultTestValuesForRunOptions, );
- EXPECT_NE(ImportedDef, ImportedProto);
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 2u);
- auto ToDef = FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- auto ToProto = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedDef == ToDef);
- EXPECT_TRUE(ImportedProto == ToProto);
- ASSERT_TRUE(ToDef->getTemplatedDecl());
- ASSERT_TRUE(ToProto->getTemplatedDecl());
- EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
- EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToProto->getPreviousDecl(), ToDef);
- EXPECT_EQ(ToProto->getTemplatedDecl()->getPreviousDecl(),
- ToDef->getTemplatedDecl());
-}
-
-TEST_P(ImportClassTemplates, ImportPrototypeThenDefinition) {
- Decl *FromTU0 =
- getTuDecl("template <class T> class X;", Lang_CXX, "input0.cc");
- Decl *FromTU1 =
- getTuDecl("template <class T> class X {};", Lang_CXX, "input1.cc");
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto FromProto =
- FirstDeclMatcher<ClassTemplateDecl>().match(FromTU0, Pattern);
- auto FromDef = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU1, Pattern);
-
- Decl *ImportedProto = Import(FromProto, Lang_CXX);
- Decl *ImportedDef = Import(FromDef, Lang_CXX);
- Decl *ToTU = ImportedDef->getTranslationUnitDecl();
- EXPECT_NE(ImportedDef, ImportedProto);
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 2u);
- auto ToProto = FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- auto ToDef = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedDef == ToDef);
- EXPECT_TRUE(ImportedProto == ToProto);
- ASSERT_TRUE(ToProto->getTemplatedDecl());
- ASSERT_TRUE(ToDef->getTemplatedDecl());
- EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
- EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
- EXPECT_EQ(ToDef->getTemplatedDecl()->getPreviousDecl(),
- ToProto->getTemplatedDecl());
-}
struct ImportFriendClasses : ASTImporterOptionSpecificTestBase {};
DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))));
}
-TEST_P(ImportFunctionTemplateSpecializations,
- ImportPrototypes) {
- auto Pattern = functionDecl(hasName("f"), isExplicitTemplateSpecialization());
- auto Code =
- R"(
- // Proto of the primary template.
- template <class T>
- void f();
- // Proto of the specialization.
- template <>
- void f<int>();
- )";
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
- auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
-
- ImportedD = Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input1.cc");
- auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(ImportedD != To1);
- EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
- EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
- // Check that they are part of the same redecl chain.
- EXPECT_EQ(To1->getCanonicalDecl(), To0->getCanonicalDecl());
-}
-
-TEST_P(ImportFunctionTemplateSpecializations, ImportDefinitions) {
- auto Pattern = functionDecl(hasName("f"), isExplicitTemplateSpecialization());
- auto Code =
- R"(
- // Proto of the primary template.
- template <class T>
- void f();
- // Specialization and definition.
- template <>
- void f<int>() {}
- )";
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input1.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
-
- auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
- ToTU, functionTemplateDecl());
- auto *FirstSpecD = *(TemplateD->spec_begin());
- EXPECT_EQ(FirstSpecD->getCanonicalDecl(), To0->getCanonicalDecl());
-}
-
-TEST_P(ImportFunctionTemplateSpecializations, PrototypeThenPrototype) {
- auto Pattern = functionDecl(hasName("f"), isExplicitTemplateSpecialization());
- auto Code =
- R"(
- // Proto of the primary template.
- template <class T>
- void f();
- // Specialization proto.
- template <>
- void f<int>();
- // Specialization proto.
- template <>
- void f<int>();
- )";
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(ImportedD != To1);
- EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
- EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportFunctionTemplateSpecializations, PrototypeThenDefinition) {
- auto Pattern = functionDecl(hasName("f"), isExplicitTemplateSpecialization());
- auto Code =
- R"(
- // Proto of the primary template.
- template <class T>
- void f();
- // Specialization proto.
- template <>
- void f<int>();
- // Specialization definition.
- template <>
- void f<int>() {}
- )";
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(ImportedD != To1);
- EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
- EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportFunctionTemplateSpecializations, DefinitionThenPrototype) {
- auto Pattern = functionDecl(hasName("f"), isExplicitTemplateSpecialization());
- auto Code =
- R"(
- // Proto of the primary template.
- template <class T>
- void f();
- // Specialization definition.
- template <>
- void f<int>() {}
- // Specialization proto.
- template <>
- void f<int>();
- )";
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(ImportedD != To1);
- EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
- EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
TEST_P(ASTImporterOptionSpecificTestBase,
ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined) {
{
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions,
DefaultTestValuesForRunOptions, );
-INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClassTemplates,
- DefaultTestValuesForRunOptions, );
-
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendClasses,
DefaultTestValuesForRunOptions, );