Skip to content

Commit 41366eb

Browse files
committed
Merge remote-tracking branch 'origin/main' into rebranch
2 parents d9c9ca8 + 4245bd5 commit 41366eb

File tree

5 files changed

+55
-5
lines changed

5 files changed

+55
-5
lines changed

include/swift/AST/ClangModuleLoader.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ class ClangModuleLoader : public ModuleLoader {
184184
/// Imports a clang decl directly, rather than looking up its name.
185185
virtual Decl *importDeclDirectly(const clang::NamedDecl *decl) = 0;
186186

187+
/// Imports a clang decl from a base class, cloning it for \param newContext
188+
/// if it wasn't cloned for this specific context before.
189+
virtual ValueDecl *importBaseMemberDecl(ValueDecl *decl,
190+
DeclContext *newContext) = 0;
191+
187192
/// Emits diagnostics for any declarations named name
188193
/// whose direct declaration context is a TU.
189194
virtual void diagnoseTopLevelValue(const DeclName &name) = 0;

include/swift/ClangImporter/ClangImporter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,9 @@ class ClangImporter final : public ClangModuleLoader {
531531
/// Imports a clang decl directly, rather than looking up it's name.
532532
Decl *importDeclDirectly(const clang::NamedDecl *decl) override;
533533

534+
ValueDecl *importBaseMemberDecl(ValueDecl *decl,
535+
DeclContext *newContext) override;
536+
534537
/// Emits diagnostics for any declarations named name
535538
/// whose direct declaration context is a TU.
536539
void diagnoseTopLevelValue(const DeclName &name) override;

lib/ClangImporter/ClangImporter.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4946,11 +4946,12 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
49464946

49474947
// Find the results that are actually a member of "recordDecl".
49484948
TinyPtrVector<ValueDecl *> result;
4949+
ClangModuleLoader *clangModuleLoader = ctx.getClangModuleLoader();
49494950
for (auto found : allResults) {
49504951
auto named = found.get<clang::NamedDecl *>();
49514952
if (dyn_cast<clang::Decl>(named->getDeclContext()) ==
49524953
recordDecl->getClangDecl()) {
4953-
if (auto import = ctx.getClangModuleLoader()->importDeclDirectly(named))
4954+
if (auto import = clangModuleLoader->importDeclDirectly(named))
49544955
result.push_back(cast<ValueDecl>(import));
49554956
}
49564957
}
@@ -4966,16 +4967,32 @@ TinyPtrVector<ValueDecl *> ClangRecordMemberLookup::evaluate(
49664967
continue;
49674968

49684969
auto *baseRecord = baseType->getAs<clang::RecordType>()->getDecl();
4969-
if (auto import =
4970-
ctx.getClangModuleLoader()->importDeclDirectly(baseRecord)) {
4970+
if (auto import = clangModuleLoader->importDeclDirectly(baseRecord)) {
49714971
// If we are looking up the base class, go no further. We will have
49724972
// already found it during the other lookup.
49734973
if (cast<ValueDecl>(import)->getName() == name)
49744974
continue;
49754975

4976-
auto baseResults = cast<NominalTypeDecl>(import)->lookupDirect(name);
4976+
// Add Clang members that are imported lazily.
4977+
auto baseResults = evaluateOrDefault(
4978+
ctx.evaluator,
4979+
ClangRecordMemberLookup({cast<NominalTypeDecl>(import), name}), {});
4980+
// Add members that are synthesized eagerly, such as subscripts.
4981+
for (auto member :
4982+
cast<NominalTypeDecl>(import)->getCurrentMembersWithoutLoading()) {
4983+
if (auto namedMember = dyn_cast<ValueDecl>(member)) {
4984+
if (namedMember->hasName() &&
4985+
namedMember->getName().getBaseName() == name &&
4986+
// Make sure we don't add duplicate entries, as that would
4987+
// wrongly imply that lookup is ambiguous.
4988+
!llvm::is_contained(baseResults, namedMember)) {
4989+
baseResults.push_back(namedMember);
4990+
}
4991+
}
4992+
}
49774993
for (auto foundInBase : baseResults) {
4978-
if (auto newDecl = cloneBaseMemberDecl(foundInBase, recordDecl)) {
4994+
if (auto newDecl = clangModuleLoader->importBaseMemberDecl(
4995+
foundInBase, recordDecl)) {
49794996
result.push_back(newDecl);
49804997
}
49814998
}
@@ -5772,6 +5789,18 @@ Decl *ClangImporter::importDeclDirectly(const clang::NamedDecl *decl) {
57725789
return Impl.importDecl(decl, Impl.CurrentVersion);
57735790
}
57745791

5792+
ValueDecl *ClangImporter::importBaseMemberDecl(ValueDecl *decl,
5793+
DeclContext *newContext) {
5794+
// Make sure we don't clone the decl again for this class, as that would
5795+
// result in multiple definitions of the same symbol.
5796+
std::pair<ValueDecl *, DeclContext *> key = {decl, newContext};
5797+
if (!Impl.clonedBaseMembers.count(key)) {
5798+
ValueDecl *cloned = cloneBaseMemberDecl(decl, newContext);
5799+
Impl.clonedBaseMembers[key] = cloned;
5800+
}
5801+
return Impl.clonedBaseMembers[key];
5802+
}
5803+
57755804
void ClangImporter::diagnoseTopLevelValue(const DeclName &name) {
57765805
Impl.diagnoseTopLevelValue(name);
57775806
}

lib/ClangImporter/ImporterImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,10 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
621621
llvm::DenseSet<clang::FunctionDecl *>>>>
622622
cxxMethods;
623623

624+
// Keep track of the decls that were already cloned for this specific class.
625+
llvm::DenseMap<std::pair<ValueDecl *, DeclContext *>, ValueDecl *>
626+
clonedBaseMembers;
627+
624628
// Cache for already-specialized function templates and any thunks they may
625629
// have.
626630
llvm::DenseMap<clang::FunctionDecl *, ValueDecl *>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -enable-experimental-cxx-interop
2+
3+
import Functions
4+
5+
extension Base {
6+
public func swiftFunc() {}
7+
}
8+
9+
Derived().swiftFunc() // expected-error {{value of type 'Derived' has no member 'swiftFunc'}}

0 commit comments

Comments
 (0)