Skip to content

Commit eabc7ad

Browse files
committed
[clang][ASTImporter] Remove extra FunctionTemplateDecl introduced by templated friend
An extranous FunctionTemplateDecl is introduced in the following testcase: template <typename T> struct A { template <typename U> friend void f(); }; "To" Context: ClassTemplateDecl 0x55dae7116618 <input.cc:1:1, col:73> col:30 A |-TemplateTypeParmDecl 0x55dae7116490 <col:11, col:20> col:20 typename depth 0 index 0 T `-CXXRecordDecl 0x55dae7116550 <col:23, col:73> col:30 struct A definition |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param | |-MoveConstructor exists simple trivial needs_implicit | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param | |-MoveAssignment exists simple trivial needs_implicit | `-Destructor simple irrelevant trivial needs_implicit |-FunctionTemplateDecl 0x55dae7116a38 parent 0x55dae6fa2b68 <col:35, col:71> col:69 f // extranous node | |-TemplateTypeParmDecl 0x55dae7116860 <col:45, col:54> col:54 typename depth 1 index 0 U | `-FunctionDecl 0x55dae7116968 parent 0x55dae6fa2b68 <col:57, col:71> col:69 f 'void ()' |-FriendDecl 0x55dae7116aa0 <col:35, col:71> col:69 | `-FunctionTemplateDecl 0x55dae7116a38 parent 0x55dae6fa2b68 <col:35, col:71> col:69 f | |-TemplateTypeParmDecl 0x55dae7116860 <col:45, col:54> col:54 typename depth 1 index 0 U | `-FunctionDecl 0x55dae7116968 parent 0x55dae6fa2b68 <col:57, col:71> col:69 f 'void ()' `-CXXRecordDecl 0x55dae7116ae0 <col:23, col:30> col:30 implicit struct A Reviewed By: balazske Differential Revision: https://reviews.llvm.org/D157691
1 parent 3b0eeb6 commit eabc7ad

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

clang/lib/AST/ASTImporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6459,7 +6459,7 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
64596459

64606460
ToFunc->setAccess(D->getAccess());
64616461
ToFunc->setLexicalDeclContext(LexicalDC);
6462-
LexicalDC->addDeclInternal(ToFunc);
6462+
addDeclToContexts(D, ToFunc);
64636463

64646464
ASTImporterLookupTable *LT = Importer.SharedState->getLookupTable();
64656465
if (LT && !OldParamDC.empty()) {

clang/unittests/AST/ASTImporterTest.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5634,6 +5634,43 @@ TEST_P(ImportFriendFunctionTemplates, LookupShouldFindPreviousFriend) {
56345634
EXPECT_EQ(Imported->getPreviousDecl(), Friend);
56355635
}
56365636

5637+
TEST_P(ImportFriendFunctionTemplates, ImportFriendFunctionInsideClassTemplate) {
5638+
Decl *From, *To;
5639+
std::tie(From, To) = getImportedDecl(
5640+
R"(
5641+
template <typename T> struct X {
5642+
template <typename U> friend void f();
5643+
};
5644+
)",
5645+
Lang_CXX03, "", Lang_CXX03, "X");
5646+
5647+
auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(From, friendDecl());
5648+
auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(To, friendDecl());
5649+
5650+
EXPECT_TRUE(FromFriend ==
5651+
LastDeclMatcher<FriendDecl>().match(From, friendDecl()));
5652+
EXPECT_TRUE(ToFriend ==
5653+
LastDeclMatcher<FriendDecl>().match(To, friendDecl()));
5654+
5655+
auto *FromDecl = FromFriend->getFriendDecl();
5656+
auto *FromDC = FromFriend->getDeclContext();
5657+
auto *FromLexicalDC = FromFriend->getLexicalDeclContext();
5658+
5659+
EXPECT_TRUE(FromDC->containsDecl(FromFriend));
5660+
EXPECT_FALSE(FromDC->containsDecl(FromDecl));
5661+
EXPECT_TRUE(FromLexicalDC->containsDecl(FromFriend));
5662+
EXPECT_FALSE(FromLexicalDC->containsDecl(FromDecl));
5663+
5664+
auto *ToDecl = ToFriend->getFriendDecl();
5665+
auto *ToDC = ToFriend->getDeclContext();
5666+
auto *ToLexicalDC = ToFriend->getLexicalDeclContext();
5667+
5668+
EXPECT_TRUE(ToDC->containsDecl(ToFriend));
5669+
EXPECT_FALSE(ToDC->containsDecl(ToDecl));
5670+
EXPECT_TRUE(ToLexicalDC->containsDecl(ToFriend));
5671+
EXPECT_FALSE(ToLexicalDC->containsDecl(ToDecl));
5672+
}
5673+
56375674
struct ASTImporterWithFakeErrors : ASTImporter {
56385675
using ASTImporter::ASTImporter;
56395676
bool returnWithErrorInTest() override { return true; }

0 commit comments

Comments
 (0)