Skip to content

Commit d76c127

Browse files
committed
ClangImporter: Lazily load constructor members of classes
This just requires a small refactoring so that we can build inherited constructors from the lazy loader path.
1 parent 246c45c commit d76c127

File tree

7 files changed

+50
-24
lines changed

7 files changed

+50
-24
lines changed

lib/AST/NameLookup.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,13 +1168,6 @@ TinyPtrVector<ValueDecl *> NominalTypeDecl::lookupDirect(
11681168
bool includeAttrImplements =
11691169
flags.contains(LookupDirectFlags::IncludeAttrImplements);
11701170

1171-
// FIXME: At present, lazy member is not able to find inherited constructors
1172-
// in imported classes, because SwiftDeclConverter::importInheritedConstructors()
1173-
// is only called via ClangImporter::Implementation::loadAllMembers().
1174-
if (hasClangNode() &&
1175-
name.getBaseName() == DeclBaseName::createConstructor())
1176-
useNamedLazyMemberLoading = false;
1177-
11781171
LLVM_DEBUG(llvm::dbgs() << getNameStr() << ".lookupDirect("
11791172
<< name << ", " << ignoreNewExtensions << ")"
11801173
<< ", isLookupTablePopulated()=" << isLookupTablePopulated()

lib/ClangImporter/ClangImporter.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3655,16 +3655,13 @@ ClangImporter::Implementation::loadNamedMembers(
36553655
auto table = findLookupTable(*CMO);
36563656
assert(table && "clang module without lookup table");
36573657

3658-
clang::ASTContext &clangCtx = getClangASTContext();
3659-
36603658
assert(isa<clang::ObjCContainerDecl>(CD) || isa<clang::NamespaceDecl>(CD));
36613659

36623660
TinyPtrVector<ValueDecl *> Members;
36633661
for (auto entry : table->lookup(SerializedSwiftName(N),
36643662
effectiveClangContext)) {
36653663
if (!entry.is<clang::NamedDecl *>()) continue;
36663664
auto member = entry.get<clang::NamedDecl *>();
3667-
if (!isVisibleClangEntry(clangCtx, member)) continue;
36683665

36693666
// Skip Decls from different clang::DeclContexts
36703667
if (member->getDeclContext() != CDC) continue;
@@ -3680,6 +3677,16 @@ ClangImporter::Implementation::loadNamedMembers(
36803677
}
36813678
}
36823679
}
3680+
3681+
if (N == DeclBaseName::createConstructor()) {
3682+
if (auto *classDecl = dyn_cast<ClassDecl>(D)) {
3683+
SmallVector<Decl *, 4> ctors;
3684+
importInheritedConstructors(const_cast<ClassDecl *>(classDecl), ctors);
3685+
for (auto ctor : ctors)
3686+
Members.push_back(cast<ValueDecl>(ctor));
3687+
}
3688+
}
3689+
36833690
return Members;
36843691
}
36853692

lib/ClangImporter/ImportDecl.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7197,6 +7197,17 @@ void SwiftDeclConverter::importNonOverriddenMirroredMethods(DeclContext *dc,
71977197
}
71987198
}
71997199

7200+
void ClangImporter::Implementation::importInheritedConstructors(
7201+
ClassDecl *classDecl, SmallVectorImpl<Decl *> &newMembers) {
7202+
auto curObjCClass = cast<clang::ObjCInterfaceDecl>(classDecl->getClangDecl());
7203+
7204+
// Imported inherited initializers.
7205+
if (curObjCClass->getName() != "Protocol") {
7206+
SwiftDeclConverter converter(*this, CurrentVersion);
7207+
converter.importInheritedConstructors(classDecl, newMembers);
7208+
}
7209+
}
7210+
72007211
void SwiftDeclConverter::importInheritedConstructors(
72017212
ClassDecl *classDecl, SmallVectorImpl<Decl *> &newMembers) {
72027213
if (!classDecl->hasSuperclass())
@@ -8685,26 +8696,20 @@ void ClangImporter::Implementation::collectMembersToAdd(
86858696
insertMembersAndAlternates(nd, members);
86868697
}
86878698

8688-
SwiftDeclConverter converter(*this, CurrentVersion);
8689-
86908699
SmallVector<ProtocolDecl *, 4> protos = takeImportedProtocols(D);
86918700
if (auto clangClass = dyn_cast<clang::ObjCInterfaceDecl>(objcContainer)) {
8692-
auto swiftClass = cast<ClassDecl>(D);
8693-
objcContainer = clangClass = clangClass->getDefinition();
8694-
8695-
// Imported inherited initializers.
8696-
if (clangClass->getName() != "Protocol") {
8697-
converter.importInheritedConstructors(const_cast<ClassDecl *>(swiftClass),
8698-
members);
8699-
}
8701+
importInheritedConstructors(cast<ClassDecl>(D), members);
87008702

8703+
objcContainer = clangClass->getDefinition();
87018704
} else if (auto clangProto
87028705
= dyn_cast<clang::ObjCProtocolDecl>(objcContainer)) {
87038706
objcContainer = clangProto->getDefinition();
87048707
}
8708+
87058709
// Import mirrored declarations for protocols to which this category
87068710
// or extension conforms.
87078711
// FIXME: This is supposed to be a short-term hack.
8712+
SwiftDeclConverter converter(*this, CurrentVersion);
87088713
converter.importMirroredProtocolMembers(objcContainer, DC,
87098714
protos, members, SwiftContext);
87108715
}

lib/ClangImporter/ImporterImpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,9 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
802802
Decl *importMirroredDecl(const clang::NamedDecl *decl, DeclContext *dc,
803803
Version version, ProtocolDecl *proto);
804804

805+
void importInheritedConstructors(ClassDecl *classDecl,
806+
SmallVectorImpl<Decl *> &newMembers);
807+
805808
/// Utility function for building simple generic signatures.
806809
GenericSignature *buildGenericSignature(GenericParamList *genericParams,
807810
DeclContext *dc);

test/ClangImporter/attr-swift_name.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -I %S/Inputs/custom-modules -Xcc -w -typecheck %s 2>&1 | %FileCheck %s
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -I %S/Inputs/custom-modules -Xcc -w -typecheck %s -disable-named-lazy-member-loading 2>&1 | %FileCheck %s
22

33
// REQUIRES: objc_interop
44

test/NameBinding/Inputs/NamedLazyMembers/NamedLazyMembers.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
// Don't conform to the protocol; that loads all protocol members.
2727
@interface SimpleDoer
2828

29+
- (instancetype)initWithValue: (int)value;
30+
2931
// These are names we're hoping don't interfere with Doer, above.
3032
+ (SimpleDoer*)Doer;
3133
+ (SimpleDoer*)DoerOfNoWork;
@@ -107,4 +109,14 @@
107109
@interface SimpleDoerSubclass : SimpleDoer
108110
- (void)simplyDoSomeWorkWithSpeed:(int)s thoroughness:(int)t
109111
NS_SWIFT_NAME(simplyDoVeryImportantWork(speed:thoroughness:));
112+
113+
- (void)exuberantlyGoForWalk;
114+
- (void)exuberantlyTakeNap;
115+
- (void)exuberantlyEatMeal;
116+
- (void)exuberantlyTidyHome;
117+
- (void)exuberantlyCallFamily;
118+
- (void)exuberantlySingSong;
119+
- (void)exuberantlyReadBook;
120+
- (void)exuberantlyAttendLecture;
121+
- (void)exuberantlyWriteLetter;
110122
@end

test/NameBinding/named_lazy_member_loading_objc_interface.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,19 @@
1212

1313
import NamedLazyMembers
1414

15-
public func bar(d: SimpleDoerSubclass) {
16-
let _ = d.simplyDoVeryImportantWork(speed: 10, motivation: 42)
15+
public func bar() {
16+
let d = SimpleDoerSubclass(value: 123)!
17+
let _ = d.simplyDoVeryImportantWork(speed: 10, motivation: 42)
1718
}
1819

19-
public func foo(d: SimpleDoer) {
20+
public func foo() {
21+
let d = SimpleDoer(value: 123)!
2022
let _ = d.simplyDoSomeWork()
2123
let _ = d.simplyDoSomeWork(withSpeed:10)
2224
let _ = d.simplyDoVeryImportantWork(speed:10, thoroughness:12)
2325
let _ = d.simplyDoSomeWorkWithSpeed(speed:10, levelOfAlacrity:12)
2426
}
27+
28+
// Make sure that simply subclassing an imported subclass doesn't page in all
29+
// members.
30+
class MostDoerSubclass : SimpleDoerSubclass {}

0 commit comments

Comments
 (0)