forked from OSchip/llvm-project
[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
This commit is contained in:
parent
e5fa049efa
commit
e9719f9e9e
|
@ -3118,9 +3118,19 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
|
|||
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.
|
||||
}
|
||||
|
|
|
@ -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(ParameterizedTests, ImportFriendFunctionTemplates,
|
|||
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClasses,
|
||||
DefaultTestValuesForRunOptions, );
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionTemplates,
|
||||
DefaultTestValuesForRunOptions, );
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions,
|
||||
DefaultTestValuesForRunOptions, );
|
||||
|
||||
|
|
Loading…
Reference in New Issue