Skip to content

Commit f96ef9a

Browse files
committed
[ClangImporter] Account for synthesized types when filtering by module
We treat redeclarable Clang declarations as present in every module where they're declared, except for struct/enum/union declarations where we only count full definitions. This logic requires going from the imported Swift declaration back to the Clang declaration, something that's not really possible for "synthesized declarations" today. The only top-level synthesized declarations we have right now are the structs we make to wrap error code enums. The 100% correct thing to do would be to account for people defining error code enums consistently across multiple modules. In practice, though, error code enums are used with Objective-C (the importer's treatment of them is tied to NSError), where redefining existing types is very unusual. Therefore, this fix just ignores redeclarations of error code enums, whether they're definitions or not. rdar://problem/45414271
1 parent edb21b2 commit f96ef9a

File tree

5 files changed

+55
-1
lines changed

5 files changed

+55
-1
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2028,7 +2028,26 @@ static bool isVisibleFromModule(const ClangModuleUnit *ModuleFilter,
20282028
return false;
20292029

20302030
auto ClangNode = VD->getClangNode();
2031-
assert(ClangNode);
2031+
if (!ClangNode) {
2032+
// If we synthesized a ValueDecl, it won't have a Clang node. But so far
2033+
// all the situations where we synthesize top-level declarations are
2034+
// situations where we don't have to worry about C redeclarations.
2035+
// We should only consider the declaration visible from its owning module.
2036+
auto *SynthesizedTypeAttr =
2037+
VD->getAttrs().getAttribute<ClangImporterSynthesizedTypeAttr>();
2038+
assert(SynthesizedTypeAttr);
2039+
2040+
// When adding new ClangImporterSynthesizedTypeAttr::Kinds, make sure that
2041+
// the above statement still holds: "we don't want to allow these
2042+
// declarations to be treated as present in multiple modules".
2043+
switch (SynthesizedTypeAttr->getKind()) {
2044+
case ClangImporterSynthesizedTypeAttr::Kind::NSErrorWrapper:
2045+
case ClangImporterSynthesizedTypeAttr::Kind::NSErrorWrapperAnon:
2046+
break;
2047+
}
2048+
2049+
return false;
2050+
}
20322051

20332052
auto &ClangASTContext = ModuleFilter->getClangASTContext();
20342053
auto OwningClangModule = getClangOwningModule(ClangNode, ClangASTContext);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@import Foundation;
2+
3+
extern NSString * const SomeErrorDomain;
4+
// typedef NS_ERROR_ENUM(SomeErrorDomain, SomeErrorCode) { ... }
5+
typedef enum SomeErrorCode : long SomeErrorCode;
6+
enum __attribute__((ns_error_domain(SomeErrorDomain))) SomeErrorCode : long {
7+
SomeErrorX,
8+
SomeErrorY
9+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@import Foundation;
2+
@import Base;
3+
4+
extern NSString * const SomeErrorDomain;
5+
// typedef NS_ERROR_ENUM(SomeErrorDomain, SomeErrorCode);
6+
typedef enum SomeErrorCode : long SomeErrorCode;
7+
enum __attribute__((ns_error_domain(SomeErrorDomain))) SomeErrorCode : long;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module Base {
2+
header "Base.h"
3+
}
4+
5+
module Redeclared {
6+
header "Redeclared.h"
7+
export *
8+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -verify -enable-objc-interop -I %S/Inputs/custom-modules/RedeclaredErrorEnum
2+
3+
import Redeclared
4+
5+
// Referencing this error type (defined in Base, redeclared in Redeclared)
6+
// used to cause a compiler crash (rdar://problem/45414271).
7+
_ = SomeError.self
8+
_ = SomeError.Code.self
9+
10+
_ = Redeclared.SomeError.self
11+
_ = Base.SomeError.self

0 commit comments

Comments
 (0)