[ASTImporter] Do not import FunctionTemplateDecl in record twice.
Summary:
For functions there is a check to not duplicate the declaration if it is in a
record (class). For function templates there was no similar check, if a
template (in the same class) was imported multiple times the
FunctionTemplateDecl was created multiple times with the same templated
FunctionDecl. This can result in problems with the declaration chain.
Reviewers: martong, a.sidorin, shafik, a_sidorin
Reviewed By: a_sidorin
Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D65203
llvm-svn: 368163
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index 07becce..151b279 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -2389,6 +2389,49 @@
functionDecl(hasName("f"), hasDescendant(declRefExpr()))))));
}
+struct ImportFunctionTemplates : ASTImporterOptionSpecificTestBase {};
+
+TEST_P(ImportFunctionTemplates, ImportFunctionTemplateInRecordDeclTwice) {
+ auto Code =
+ R"(
+ class X {
+ template <class T>
+ void f(T t);
+ };
+ )";
+ Decl *FromTU1 = getTuDecl(Code, Lang_CXX, "input1.cc");
+ auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match(
+ FromTU1, functionTemplateDecl(hasName("f")));
+ auto *ToD1 = Import(FromD1, Lang_CXX);
+ Decl *FromTU2 = getTuDecl(Code, Lang_CXX, "input2.cc");
+ auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match(
+ FromTU2, functionTemplateDecl(hasName("f")));
+ auto *ToD2 = Import(FromD2, Lang_CXX);
+ EXPECT_EQ(ToD1, ToD2);
+}
+
+TEST_P(ImportFunctionTemplates,
+ ImportFunctionTemplateWithDefInRecordDeclTwice) {
+ auto Code =
+ R"(
+ class X {
+ template <class T>
+ void f(T t);
+ };
+ template <class T>
+ void X::f(T t) {};
+ )";
+ Decl *FromTU1 = getTuDecl(Code, Lang_CXX, "input1.cc");
+ auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match(
+ FromTU1, functionTemplateDecl(hasName("f")));
+ auto *ToD1 = Import(FromD1, Lang_CXX);
+ Decl *FromTU2 = getTuDecl(Code, Lang_CXX, "input2.cc");
+ auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match(
+ FromTU2, functionTemplateDecl(hasName("f")));
+ auto *ToD2 = Import(FromD2, Lang_CXX);
+ EXPECT_EQ(ToD1, ToD2);
+}
+
struct ImportFriendFunctions : ImportFunctions {};
TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) {
@@ -5223,6 +5266,9 @@
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClasses,
DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionTemplates,
+ DefaultTestValuesForRunOptions, );
+
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions,
DefaultTestValuesForRunOptions, );