Skip to content

Commit 60a195e

Browse files
authored
Merge pull request #38439 from egorzhdan/cxx-string-npos
C++ Interop: improve skipping already imported struct members
2 parents 535a1b5 + fc2dc6a commit 60a195e

File tree

4 files changed

+61
-6
lines changed

4 files changed

+61
-6
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3502,6 +3502,10 @@ namespace {
35023502
SmallVector<ConstructorDecl *, 4> ctors;
35033503
SmallVector<TypeDecl *, 4> nestedTypes;
35043504

3505+
// Store the already imported members in a set to avoid importing the same
3506+
// decls multiple times.
3507+
SmallPtrSet<clang::Decl *, 16> importedMembers;
3508+
35053509
// FIXME: Import anonymous union fields and support field access when
35063510
// it is nested in a struct.
35073511

@@ -3520,6 +3524,12 @@ namespace {
35203524
}
35213525
}
35223526

3527+
// If we've already imported this decl & added it to the resulting
3528+
// struct, skip it so we don't add the same member twice.
3529+
if (!importedMembers.insert(m->getCanonicalDecl()).second) {
3530+
continue;
3531+
}
3532+
35233533
auto nd = dyn_cast<clang::NamedDecl>(m);
35243534
if (!nd) {
35253535
// We couldn't import the member, so we can't reference it in Swift.
@@ -3548,12 +3558,6 @@ namespace {
35483558
}
35493559
}
35503560

3551-
// If we've already imported this decl, skip it so we don't add the same
3552-
// member twice.
3553-
if (Impl.ImportedDecls.find({nd->getCanonicalDecl(), getVersion()}) !=
3554-
Impl.ImportedDecls.end())
3555-
continue;
3556-
35573561
// If we encounter an IndirectFieldDecl, ensure that its parent is
35583562
// importable before attempting to import it because they are dependent
35593563
// when it comes to getter/setter generation.

test/Interop/Cxx/namespace/Inputs/module.modulemap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,8 @@ module TemplatesSecondHeader {
3232
header "templates-second-header.h"
3333
requires cplusplus
3434
}
35+
36+
module TemplatesWithForwardDecl {
37+
header "templates-with-forward-decl.h"
38+
requires cplusplus
39+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef TEST_INTEROP_CXX_NAMESPACE_INPUTS_TEMPLATES_WITH_FORWARD_DECL_H
2+
#define TEST_INTEROP_CXX_NAMESPACE_INPUTS_TEMPLATES_WITH_FORWARD_DECL_H
3+
4+
namespace NS1 {
5+
6+
template <typename T>
7+
struct Decl;
8+
9+
typedef Decl<int> di;
10+
11+
} // namespace NS1
12+
13+
namespace NS1 {
14+
15+
template <typename T>
16+
struct ForwardDeclared;
17+
18+
template <typename T>
19+
struct Decl {
20+
typedef T MyInt;
21+
ForwardDeclared<T> fwd;
22+
const static MyInt intValue = -1;
23+
};
24+
25+
template <typename T>
26+
const typename Decl<T>::MyInt Decl<T>::intValue;
27+
28+
} // namespace NS1
29+
30+
namespace NS1 {
31+
32+
template <typename T>
33+
struct ForwardDeclared {};
34+
35+
} // namespace NS1
36+
37+
#endif // TEST_INTEROP_CXX_NAMESPACE_INPUTS_TEMPLATES_WITH_FORWARD_DECL_H
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-swift-ide-test -print-module -module-to-print=TemplatesWithForwardDecl -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s
2+
3+
// CHECK: extension NS1 {
4+
// CHECK: struct __CxxTemplateInstN3NS14DeclIiEE {
5+
// CHECK: typealias MyInt = Int32
6+
// CHECK: var fwd: NS1.__CxxTemplateInstN3NS115ForwardDeclaredIiEE
7+
// CHECK: static let intValue: NS1.__CxxTemplateInstN3NS14DeclIiEE.MyInt
8+
// CHECK: }
9+
// CHECK: }

0 commit comments

Comments
 (0)