r368163 - [ASTImporter] Do not import FunctionTemplateDecl in record twice.
Balazs Keri via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 7 05:40:17 PDT 2019
Author: balazske
Date: Wed Aug 7 05:40:17 2019
New Revision: 368163
URL: http://llvm.org/viewvc/llvm-project?rev=368163&view=rev
Log:
[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
Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp
Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=368163&r1=368162&r2=368163&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Aug 7 05:40:17 2019
@@ -3118,9 +3118,19 @@ ExpectedDecl ASTNodeImporter::VisitFunct
if (FoundByLookup) {
if (isa<CXXMethodDecl>(FoundByLookup)) {
if (D->getLexicalDeclContext() == D->getDeclContext()) {
- if (!D->doesThisDeclarationHaveABody())
+ if (!D->doesThisDeclarationHaveABody()) {
+ if (FunctionTemplateDecl *DescribedD =
+ D->getDescribedFunctionTemplate()) {
+ // Handle a "templated" function together with its described
+ // template. This avoids need for a similar check at import of the
+ // described template.
+ assert(FoundByLookup->getDescribedFunctionTemplate() &&
+ "Templated function mapped to non-templated?");
+ Importer.MapImported(DescribedD,
+ FoundByLookup->getDescribedFunctionTemplate());
+ }
return Importer.MapImported(D, FoundByLookup);
- else {
+ } else {
// Let's continue and build up the redecl chain in this case.
// FIXME Merge the functions into one decl.
}
Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=368163&r1=368162&r2=368163&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Wed Aug 7 05:40:17 2019
@@ -2389,6 +2389,49 @@ TEST_P(ImportFunctions,
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(ParameterizedTes
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClasses,
DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionTemplates,
+ DefaultTestValuesForRunOptions, );
+
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions,
DefaultTestValuesForRunOptions, );
More information about the cfe-commits
mailing list