Skip to content

Commit 220bc64

Browse files
committed
ClangImporter: Directly track constructors imported into a nominal type
This avoids a re-entrant lookup while doing lazy member loading, and eliminates a usage of LookupDirectFlags::IgnoreNewExtensions, and the last usage of NominalTypeDecl::makeMemberVisible().
1 parent 4668def commit 220bc64

File tree

4 files changed

+13
-35
lines changed

4 files changed

+13
-35
lines changed

include/swift/AST/Decl.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3381,16 +3381,6 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
33813381
/// Retrieve the set of extensions of this type.
33823382
ExtensionRange getExtensions();
33833383

3384-
/// Make a member of this nominal type, or one of its extensions,
3385-
/// immediately visible in the lookup table.
3386-
///
3387-
/// A member of a nominal type or extension thereof will become
3388-
/// visible to name lookup as soon as it is added. However, if the
3389-
/// addition of a member is delayed---for example, because it's
3390-
/// being introduced in response to name lookup---this method can be
3391-
/// called to make it immediately visible.
3392-
void makeMemberVisible(ValueDecl *member);
3393-
33943384
/// Special-behaviour flags passed to lookupDirect()
33953385
enum class LookupDirectFlags {
33963386
/// Whether to avoid loading any new extension.

lib/AST/NameLookup.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,16 +1128,6 @@ void NominalTypeDecl::prepareLookupTable(bool ignoreNewExtensions) {
11281128
}
11291129
}
11301130

1131-
void NominalTypeDecl::makeMemberVisible(ValueDecl *member) {
1132-
if (!LookupTable.getPointer()) {
1133-
auto &ctx = getASTContext();
1134-
LookupTable.setPointer(new (ctx) MemberLookupTable(ctx));
1135-
}
1136-
1137-
LookupTable.getPointer()->addMember(member);
1138-
}
1139-
1140-
11411131
static TinyPtrVector<ValueDecl *>
11421132
maybeFilterOutAttrImplements(TinyPtrVector<ValueDecl *> decls,
11431133
DeclName name,

lib/ClangImporter/ImportDecl.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6258,21 +6258,17 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(
62586258
SmallVector<AnyFunctionType::Param, 4> allocParams;
62596259
bodyParams->getParams(allocParams);
62606260

6261-
auto flags = OptionSet<NominalTypeDecl::LookupDirectFlags>();
6262-
if (isa<ClassDecl>(dc))
6263-
flags |= NominalTypeDecl::LookupDirectFlags::IgnoreNewExtensions;
6264-
for (auto other : ownerNominal->lookupDirect(importedName.getDeclName(),
6265-
flags)) {
6266-
auto ctor = dyn_cast<ConstructorDecl>(other);
6267-
if (!ctor || ctor->isInvalid() ||
6261+
TinyPtrVector<ConstructorDecl *> ctors;
6262+
auto found = Impl.ConstructorsForNominal.find(ownerNominal);
6263+
if (found != Impl.ConstructorsForNominal.end())
6264+
ctors = found->second;
6265+
6266+
for (auto ctor : ctors) {
6267+
if (ctor->isInvalid() ||
62686268
ctor->getAttrs().isUnavailable(Impl.SwiftContext) ||
62696269
!ctor->getClangDecl())
62706270
continue;
62716271

6272-
// Resolve the type of the constructor.
6273-
if (!ctor->hasInterfaceType())
6274-
Impl.SwiftContext.getLazyResolver()->resolveDeclSignature(ctor);
6275-
62766272
// If the types don't match, this is a different constructor with
62776273
// the same selector. This can happen when an overlay overloads an
62786274
// existing selector with a Swift-only signature.
@@ -6343,10 +6339,6 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(
63436339
/*ThrowsLoc=*/SourceLoc(), bodyParams,
63446340
/*GenericParams=*/nullptr, dc);
63456341

6346-
// Make the constructor declaration immediately visible in its
6347-
// class or protocol type.
6348-
ownerNominal->makeMemberVisible(result);
6349-
63506342
addObjCAttribute(result, selector);
63516343

63526344
// Calculate the function type of the result.
@@ -6409,6 +6401,7 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(
64096401

64106402
// Record the constructor for future re-use.
64116403
Impl.Constructors[std::make_tuple(objcMethod, dc, getVersion())] = result;
6404+
Impl.ConstructorsForNominal[ownerNominal].push_back(result);
64126405

64136406
// If this constructor overrides another constructor, mark it as such.
64146407
recordObjCOverride(result);

lib/ClangImporter/ImporterImpl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,11 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
493493
std::tuple<const clang::ObjCMethodDecl *, DeclContext *, Version>,
494494
ConstructorDecl *> Constructors;
495495

496+
/// Keep track of all initializers that have been imported into a
497+
/// nominal type.
498+
llvm::DenseMap<const NominalTypeDecl *, TinyPtrVector<ConstructorDecl *>>
499+
ConstructorsForNominal;
500+
496501
/// Retrieve the alternative declaration for the given imported
497502
/// Swift declaration.
498503
ArrayRef<ValueDecl *> getAlternateDecls(Decl *decl) {

0 commit comments

Comments
 (0)