Skip to content

Commit 0ea6536

Browse files
committed
[Name shadowing] Extend Objective-C initializer shadowing to imported inits.
There are multiple ways in which the Clang importer can produce an initializer, and we have existing name shadowing rules to decide on the best. Extend those rules to cover the case where a Clang-importer-synthesized initializer collides with a C function imported as an initializer. There's technically no reason to do the latter because the former already exists, but some frameworks currently depend on this. Prior to this, the constraint solver was preferring the synthesized initializer already (which is the right thing to do), for the wrong reasons.
1 parent 76c7b63 commit 0ea6536

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

lib/AST/NameLookup.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ static void recordShadowedDeclsAfterSignatureMatch(
334334
/// Look through the given set of declarations (that all have the same name),
335335
/// recording those that are shadowed by another declaration in the
336336
/// \c shadowed set.
337-
static void recordShadowDeclsAfterObjCInitMatch(
337+
static void recordShadowedDeclsForImportedInits(
338338
ArrayRef<ConstructorDecl *> ctors,
339339
llvm::SmallPtrSetImpl<ValueDecl *> &shadowed) {
340340
assert(ctors.size() > 1 && "No collisions");
@@ -372,18 +372,21 @@ static void recordShadowedDecls(ArrayRef<ValueDecl *> decls,
372372
llvm::SmallDenseMap<CanType, llvm::TinyPtrVector<ValueDecl *>> collisions;
373373
llvm::SmallVector<CanType, 2> collisionTypes;
374374
llvm::SmallDenseMap<NominalTypeDecl *, llvm::TinyPtrVector<ConstructorDecl *>>
375-
objCInitializerCollisions;
376-
llvm::TinyPtrVector<NominalTypeDecl *> objCInitializerCollisionNominals;
375+
importedInitializerCollisions;
376+
llvm::TinyPtrVector<NominalTypeDecl *> importedInitializerCollectionTypes;
377377

378378
for (auto decl : decls) {
379-
// Specifically keep track of Objective-C initializers, which can come from
380-
// either init methods or factory methods.
381-
if (decl->hasClangNode()) {
379+
// Specifically keep track of imported initializers, which can come from
380+
// Objective-C init methods, Objective-C factory methods, renamed C
381+
// functions, or be synthesized by the importer.
382+
if (decl->hasClangNode() ||
383+
(isa<NominalTypeDecl>(decl->getDeclContext()) &&
384+
cast<NominalTypeDecl>(decl->getDeclContext())->hasClangNode())) {
382385
if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
383386
auto nominal = ctor->getDeclContext()->getSelfNominalTypeDecl();
384-
auto &knownInits = objCInitializerCollisions[nominal];
387+
auto &knownInits = importedInitializerCollisions[nominal];
385388
if (knownInits.size() == 1) {
386-
objCInitializerCollisionNominals.push_back(nominal);
389+
importedInitializerCollectionTypes.push_back(nominal);
387390
}
388391
knownInits.push_back(ctor);
389392
}
@@ -431,9 +434,9 @@ static void recordShadowedDecls(ArrayRef<ValueDecl *> decls,
431434
shadowed);
432435
}
433436

434-
// Check whether we have shadowing for Objective-C initializer collisions.
435-
for (auto nominal : objCInitializerCollisionNominals) {
436-
recordShadowDeclsAfterObjCInitMatch(objCInitializerCollisions[nominal],
437+
// Check whether we have shadowing for imported initializer collisions.
438+
for (auto nominal : importedInitializerCollectionTypes) {
439+
recordShadowedDeclsForImportedInits(importedInitializerCollisions[nominal],
437440
shadowed);
438441
}
439442
}

test/ClangImporter/Inputs/custom-modules/ImportAsMember.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ extern struct IAMStruct1 IAMStruct1CreateSimple(double value)
1414
extern struct IAMStruct1 IAMStruct1CreateSpecialLabel(void)
1515
__attribute__((swift_name("Struct1.init(specialLabel:)")));
1616

17+
extern struct IAMStruct1 IAMStruct1CreateFull(double x, double y, double z)
18+
__attribute__((swift_name("Struct1.init(x:y:z:)")));
19+
1720
extern struct IAMStruct1 IAMStruct1Invert(struct IAMStruct1 s)
1821
__attribute__((swift_name("Struct1.inverted(self:)")));
1922

test/ClangImporter/import-as-member.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ import ImportAsMemberSubmodules
55

66
let _: IAMSOuter.Inner?
77
let _: IAMMultipleNested.Inner? // expected-error {{ambiguous type name 'Inner' in 'IAMMultipleNested'}}
8+
9+
func testCreateShadowing(d: Double) -> Struct1 {
10+
return Struct1(x: d, y: d, z: d)
11+
}

0 commit comments

Comments
 (0)