diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def index 578322076e2..280fa56087f 100644 --- a/include/swift/AST/Attr.def +++ b/include/swift/AST/Attr.def @@ -373,6 +373,10 @@ SIMPLE_DECL_ATTR(_frozen, Frozen, OnEnum | UserInaccessible, 76) +SIMPLE_DECL_ATTR(_forbidSerializingReference, ForbidSerializingReference, + OnAnyDecl | + LongAttribute | RejectByParser | UserInaccessible | NotSerialized, + 77) #undef TYPE_ATTR #undef DECL_ATTR_ALIAS diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 1b2730b27c9..4f380a39ea1 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -4621,6 +4621,8 @@ namespace { "This Objective-C class has only been forward-declared; " "import its owning module to use it"); result->getAttrs().add(attr); + result->getAttrs().add( + new (Impl.SwiftContext) ForbidSerializingReferenceAttr(true)); return result; } diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 06e3e685566..730945bc3cb 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -80,6 +80,7 @@ public: IGNORED_ATTR(Effects) IGNORED_ATTR(Exported) IGNORED_ATTR(FixedLayout) + IGNORED_ATTR(ForbidSerializingReference) IGNORED_ATTR(Frozen) IGNORED_ATTR(Implements) IGNORED_ATTR(ImplicitlyUnwrappedOptional) @@ -805,6 +806,7 @@ public: IGNORED_ATTR(Dynamic) IGNORED_ATTR(Effects) IGNORED_ATTR(Exported) + IGNORED_ATTR(ForbidSerializingReference) IGNORED_ATTR(GKInspectable) IGNORED_ATTR(IBDesignable) IGNORED_ATTR(IBInspectable) diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index baaccfe87c4..289abad3125 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -5813,6 +5813,7 @@ public: UNINTERESTING_ATTR(DynamicMemberLookup) UNINTERESTING_ATTR(SILGenName) UNINTERESTING_ATTR(Exported) + UNINTERESTING_ATTR(ForbidSerializingReference) UNINTERESTING_ATTR(GKInspectable) UNINTERESTING_ATTR(IBAction) UNINTERESTING_ATTR(IBDesignable) diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 37f74a789fa..77195d0f499 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -1226,6 +1226,10 @@ static void filterValues(Type expectedTy, ModuleDecl *expectedModule, return true; if (value->isStatic() != isStatic) return true; + + if (value->getAttrs().hasAttribute()) + return true; + // FIXME: Should be able to move a value from an extension in a derived // module to the original definition in a base module. if (expectedModule && !value->hasClangNode() && diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index e07e3a0c8eb..a07781525d3 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -603,6 +603,10 @@ DeclID Serializer::addDeclRef(const Decl *D, bool forceSerialization, isa(D)) && "cannot cross-reference this decl"); + assert((!isDeclXRef(D) || + !D->getAttrs().hasAttribute()) && + "cannot cross-reference this decl"); + assert((allowTypeAliasXRef || !isa(D) || D->getModuleContext() == M) && "cannot cross-reference typealiases directly (use the NameAliasType)"); diff --git a/test/ClangImporter/Inputs/custom-modules/ForwardDeclarationsHelper.h b/test/ClangImporter/Inputs/custom-modules/ForwardDeclarationsHelper.h new file mode 100644 index 00000000000..c1f02bf1d2c --- /dev/null +++ b/test/ClangImporter/Inputs/custom-modules/ForwardDeclarationsHelper.h @@ -0,0 +1,4 @@ +@class Confusing; + +@protocol Confusing +@end diff --git a/test/ClangImporter/Inputs/custom-modules/module.map b/test/ClangImporter/Inputs/custom-modules/module.map index 1f4c987202b..93cfbaf44c7 100644 --- a/test/ClangImporter/Inputs/custom-modules/module.map +++ b/test/ClangImporter/Inputs/custom-modules/module.map @@ -216,4 +216,8 @@ module Warnings9 { header "Warnings9.h" } module ConditionallyFoo { header "ConditionallyFoo.h" config_macros [exhaustive] WANT_FOO +} + +module ForwardDeclarationsHelper { + header "ForwardDeclarationsHelper.h" } \ No newline at end of file diff --git a/test/ClangImporter/objc_forward_declarations.swift b/test/ClangImporter/objc_forward_declarations.swift new file mode 100644 index 00000000000..045cfb46c34 --- /dev/null +++ b/test/ClangImporter/objc_forward_declarations.swift @@ -0,0 +1,9 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -emit-module -o %t -I %S/Inputs/custom-modules -enable-objc-interop %s +// RUN: %target-swift-ide-test -print-module -module-to-print objc_forward_declarations -I %t -I %S/Inputs/custom-modules -enable-objc-interop -enable-objc-forward-declarations -source-filename x | %FileCheck %s + +// CHECK: class Innocuous : Confusing { + +import ForwardDeclarationsHelper + +public class Innocuous: Confusing {}