Skip to content

Commit 4dcd9c5

Browse files
authored
Merge pull request swiftlang#66319 from DougGregor/cxx-import-field-caching
[Clang importer] Eliminate redundant imports of C++ fields as properties
2 parents 3582691 + b374c09 commit 4dcd9c5

File tree

3 files changed

+25
-9
lines changed

3 files changed

+25
-9
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5006,7 +5006,8 @@ DeclAttributes cloneImportedAttributes(ValueDecl *decl, ASTContext &context) {
50065006
return attrs;
50075007
}
50085008

5009-
ValueDecl *cloneBaseMemberDecl(ValueDecl *decl, DeclContext *newContext) {
5009+
static ValueDecl *
5010+
cloneBaseMemberDecl(ValueDecl *decl, DeclContext *newContext) {
50105011
if (auto fn = dyn_cast<FuncDecl>(decl)) {
50115012
// TODO: function templates are specialized during type checking so to
50125013
// support these we need to tell Swift to type check the synthesized bodies.
@@ -6290,16 +6291,23 @@ Decl *ClangImporter::importDeclDirectly(const clang::NamedDecl *decl) {
62906291
return Impl.importDecl(decl, Impl.CurrentVersion);
62916292
}
62926293

6293-
ValueDecl *ClangImporter::importBaseMemberDecl(ValueDecl *decl,
6294-
DeclContext *newContext) {
6294+
ValueDecl *ClangImporter::Implementation::importBaseMemberDecl(
6295+
ValueDecl *decl, DeclContext *newContext) {
62956296
// Make sure we don't clone the decl again for this class, as that would
62966297
// result in multiple definitions of the same symbol.
62976298
std::pair<ValueDecl *, DeclContext *> key = {decl, newContext};
6298-
if (!Impl.clonedBaseMembers.count(key)) {
6299+
auto known = clonedBaseMembers.find(key);
6300+
if (known == clonedBaseMembers.end()) {
62996301
ValueDecl *cloned = cloneBaseMemberDecl(decl, newContext);
6300-
Impl.clonedBaseMembers[key] = cloned;
6302+
known = clonedBaseMembers.insert({key, cloned}).first;
63016303
}
6302-
return Impl.clonedBaseMembers[key];
6304+
6305+
return known->second;
6306+
}
6307+
6308+
ValueDecl *ClangImporter::importBaseMemberDecl(ValueDecl *decl,
6309+
DeclContext *newContext) {
6310+
return Impl.importBaseMemberDecl(decl, newContext);
63036311
}
63046312

63056313
void ClangImporter::diagnoseTopLevelValue(const DeclName &name) {

lib/ClangImporter/ImportDecl.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3581,6 +3581,12 @@ namespace {
35813581
if (!dc)
35823582
return nullptr;
35833583

3584+
// While importing the DeclContext, we might have imported the decl
3585+
// itself.
3586+
auto known = Impl.importDeclCached(decl, getVersion());
3587+
if (known.has_value())
3588+
return known.value();
3589+
35843590
// TODO: do we want to emit a diagnostic here?
35853591
// Types that are marked as foreign references cannot be stored by value.
35863592
if (auto recordType =
@@ -8761,8 +8767,6 @@ static void loadAllMembersOfSuperclassIfNeeded(ClassDecl *CD) {
87618767
E->loadAllMembers();
87628768
}
87638769

8764-
ValueDecl *cloneBaseMemberDecl(ValueDecl *decl, DeclContext *newContext);
8765-
87668770
void ClangImporter::Implementation::loadAllMembersOfRecordDecl(
87678771
NominalTypeDecl *swiftDecl, const clang::RecordDecl *clangRecord) {
87688772
// Import all of the members.
@@ -8793,7 +8797,7 @@ void ClangImporter::Implementation::loadAllMembersOfRecordDecl(
87938797
// This means we found a member in a C++ record's base class.
87948798
if (swiftDecl->getClangDecl() != clangRecord) {
87958799
// So we need to clone the member into the derived class.
8796-
if (auto newDecl = cloneBaseMemberDecl(cast<ValueDecl>(member), swiftDecl)) {
8800+
if (auto newDecl = importBaseMemberDecl(cast<ValueDecl>(member), swiftDecl)) {
87978801
swiftDecl->addMember(newDecl);
87988802
}
87998803
continue;

lib/ClangImporter/ImporterImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,10 +642,14 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
642642
llvm::MapVector<std::pair<NominalTypeDecl *, Type>,
643643
std::pair<FuncDecl *, FuncDecl *>> cxxSubscripts;
644644

645+
private:
645646
// Keep track of the decls that were already cloned for this specific class.
646647
llvm::DenseMap<std::pair<ValueDecl *, DeclContext *>, ValueDecl *>
647648
clonedBaseMembers;
648649

650+
ValueDecl *importBaseMemberDecl(ValueDecl *decl, DeclContext *newContext);
651+
652+
public:
649653
// Cache for already-specialized function templates and any thunks they may
650654
// have.
651655
llvm::DenseMap<clang::FunctionDecl *, ValueDecl *>

0 commit comments

Comments
 (0)