Merge pull request #12702 from fjricci/objc_interop
Objc interop
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index cb9ec1d..4a973b2 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -430,49 +430,54 @@
getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
ASTContext &ctx,
const ClangImporterOptions &importerOpts) {
- const llvm::Triple &triple = ctx.LangOpts.Target;
+ const auto &LangOpts = ctx.LangOpts;
+ const llvm::Triple &triple = LangOpts.Target;
SearchPathOptions &searchPathOpts = ctx.SearchPathOpts;
auto languageVersion = ctx.LangOpts.EffectiveLanguageVersion;
- if (llvm::sys::path::extension(importerOpts.BridgingHeader).endswith(
- PCH_EXTENSION)) {
- invocationArgStrs.insert(
- invocationArgStrs.end(),
- { "-include-pch", importerOpts.BridgingHeader }
- );
+ if (llvm::sys::path::extension(importerOpts.BridgingHeader)
+ .endswith(PCH_EXTENSION)) {
+ invocationArgStrs.insert(invocationArgStrs.end(), {
+ "-include-pch", importerOpts.BridgingHeader
+ });
}
// Construct the invocation arguments for the current target.
// Add target-independent options first.
- invocationArgStrs.insert(
- invocationArgStrs.end(),
- {
+ invocationArgStrs.insert(invocationArgStrs.end(), {
+ // Enable modules
+ "-fmodules",
+ "-Werror=non-modular-include-in-framework-module",
+ "-Xclang", "-fmodule-feature", "-Xclang", "swift",
- // Enable modules
- "-fmodules",
- "-Werror=non-modular-include-in-framework-module",
- "-Xclang", "-fmodule-feature", "-Xclang", "swift",
+ // Don't emit LLVM IR.
+ "-fsyntax-only",
- // Don't emit LLVM IR.
- "-fsyntax-only",
+ // Enable block support.
+ "-fblocks",
- // Enable block support.
- "-fblocks",
+ languageVersion.preprocessorDefinition("__swift__", {10000, 100, 1}),
- languageVersion.preprocessorDefinition("__swift__", {10000, 100, 1}),
+ "-fretain-comments-from-system-headers",
- "-fretain-comments-from-system-headers",
+ SHIMS_INCLUDE_FLAG, searchPathOpts.RuntimeResourcePath,
+ });
- SHIMS_INCLUDE_FLAG, searchPathOpts.RuntimeResourcePath,
- });
+ if (LangOpts.EnableObjCInterop) {
+ invocationArgStrs.insert(invocationArgStrs.end(),
+ {"-x", "objective-c", "-std=gnu11", "-fobjc-arc"});
+ // TODO: Investigate whether 7.0 is a suitable default version.
+ if (!triple.isOSDarwin())
+ invocationArgStrs.insert(invocationArgStrs.end(),
+ {"-fobjc-runtime=ios-7.0"});
+ } else {
+ invocationArgStrs.insert(invocationArgStrs.end(), {"-x", "c", "-std=gnu11"});
+ }
// Set C language options.
if (triple.isOSDarwin()) {
invocationArgStrs.insert(invocationArgStrs.end(), {
- // Darwin uses Objective-C ARC.
- "-x", "objective-c", "-std=gnu11", "-fobjc-arc",
-
// Define macros that Swift bridging headers use.
"-DSWIFT_CLASS_EXTRA=__attribute__((annotate(\""
SWIFT_NATIVE_ANNOTATION_STRING "\")))",
@@ -518,24 +523,16 @@
"-DSWIFT_SDK_OVERLAY_UIKIT_EPOCH=2",
});
- // Get the version of this compiler and pass it to
- // C/Objective-C declarations.
+ // Get the version of this compiler and pass it to C/Objective-C
+ // declarations.
auto V = version::Version::getCurrentCompilerVersion();
if (!V.empty()) {
invocationArgStrs.insert(invocationArgStrs.end(), {
V.preprocessorDefinition("__SWIFT_COMPILER_VERSION",
- {1000000000, /*ignored*/0, 1000000, 1000, 1}),
+ {1000000000, /*ignored*/ 0, 1000000, 1000, 1}),
});
}
} else {
- invocationArgStrs.insert(invocationArgStrs.end(), {
- // Non-Darwin platforms don't use the Objective-C runtime, so they can
- // not import Objective-C modules.
- //
- // Just use the most feature-rich C language mode.
- "-x", "c", "-std=gnu11",
- });
-
// The module map used for Glibc depends on the target we're compiling for,
// and is not included in the resource directory with the other implicit
// module maps. It's at {freebsd|linux}/{arch}/glibc.modulemap.
diff --git a/test/IDE/complete_from_clang_framework.swift b/test/IDE/complete_from_clang_framework.swift
index 3fa669e..6cd1101 100644
--- a/test/IDE/complete_from_clang_framework.swift
+++ b/test/IDE/complete_from_clang_framework.swift
@@ -1,6 +1,6 @@
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=SWIFT_COMPLETIONS | %FileCheck %s -check-prefix=SWIFT_COMPLETIONS
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -enable-objc-interop -code-completion-token=SWIFT_COMPLETIONS | %FileCheck %s -check-prefix=SWIFT_COMPLETIONS
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=FW_UNQUAL_1 > %t.compl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -enable-objc-interop -code-completion-token=FW_UNQUAL_1 > %t.compl.txt
// RUN: %FileCheck %s -check-prefix=CLANG_FOO < %t.compl.txt
// RUN: %FileCheck %s -check-prefix=CLANG_FOO_SUB < %t.compl.txt
// RUN: %FileCheck %s -check-prefix=CLANG_FOO_HELPER < %t.compl.txt
@@ -8,27 +8,25 @@
// RUN: %FileCheck %s -check-prefix=CLANG_BAR < %t.compl.txt
// RUN: %FileCheck %s -check-prefix=CLANG_BOTH_FOO_BAR < %t.compl.txt
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_QUAL_FOO_1 > %t.compl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -enable-objc-interop -code-completion-token=CLANG_QUAL_FOO_1 > %t.compl.txt
// RUN: %FileCheck %s -check-prefix=CLANG_FOO < %t.compl.txt
// RUN: %FileCheck %s -check-prefix=CLANG_FOO_SUB < %t.compl.txt
// RUN: %FileCheck %s -check-prefix=CLANG_QUAL_FOO_NEGATIVE < %t.compl.txt
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_QUAL_BAR_1 > %t.compl.txt
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -enable-objc-interop -code-completion-token=CLANG_QUAL_BAR_1 > %t.compl.txt
// RUN: %FileCheck %s -check-prefix=CLANG_QUAL_BAR_1 < %t.compl.txt
// RUN: %FileCheck %s -check-prefix=CLANG_BAR < %t.compl.txt
// RUN: %FileCheck %s -check-prefix=CLANG_QUAL_BAR_NEGATIVE < %t.compl.txt
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_QUAL_FOO_2 | %FileCheck %s -check-prefix=CLANG_QUAL_FOO_2
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -enable-objc-interop -code-completion-token=CLANG_QUAL_FOO_2 | %FileCheck %s -check-prefix=CLANG_QUAL_FOO_2
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=FUNCTION_CALL_1 | %FileCheck %s -check-prefix=FUNCTION_CALL_1
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=FUNCTION_CALL_2 | %FileCheck %s -check-prefix=FUNCTION_CALL_2
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -enable-objc-interop -code-completion-token=FUNCTION_CALL_1 | %FileCheck %s -check-prefix=FUNCTION_CALL_1
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -enable-objc-interop -code-completion-token=FUNCTION_CALL_2 | %FileCheck %s -check-prefix=FUNCTION_CALL_2
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_STRUCT_MEMBERS_1 | %FileCheck %s -check-prefix=CLANG_STRUCT_MEMBERS_1
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_CLASS_MEMBERS_1 | %FileCheck %s -check-prefix=CLANG_CLASS_MEMBERS_1
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_CLASS_MEMBERS_2 | %FileCheck %s -check-prefix=CLANG_CLASS_MEMBERS_2
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_INSTANCE_MEMBERS_1 | %FileCheck %s -check-prefix=CLANG_INSTANCE_MEMBERS_1
-
-// XFAIL: linux
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -enable-objc-interop -code-completion-token=CLANG_STRUCT_MEMBERS_1 | %FileCheck %s -check-prefix=CLANG_STRUCT_MEMBERS_1
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -enable-objc-interop -code-completion-token=CLANG_CLASS_MEMBERS_1 | %FileCheck %s -check-prefix=CLANG_CLASS_MEMBERS_1
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -enable-objc-interop -code-completion-token=CLANG_CLASS_MEMBERS_2 | %FileCheck %s -check-prefix=CLANG_CLASS_MEMBERS_2
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -enable-objc-interop -code-completion-token=CLANG_INSTANCE_MEMBERS_1 | %FileCheck %s -check-prefix=CLANG_INSTANCE_MEMBERS_1
import Foo
// Don't import FooHelper directly in this test!
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index 93fce76..2b18f5c 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -636,6 +636,16 @@
static llvm::cl::opt<bool>
IncludeLocals("include-locals", llvm::cl::desc("Index local symbols too."),
llvm::cl::cat(Category), llvm::cl::init(false));
+
+static llvm::cl::opt<bool>
+ EnableObjCInterop("enable-objc-interop",
+ llvm::cl::desc("Enable ObjC interop."),
+ llvm::cl::cat(Category), llvm::cl::init(false));
+
+static llvm::cl::opt<bool>
+ DisableObjCInterop("disable-objc-interop",
+ llvm::cl::desc("Disable ObjC interop."),
+ llvm::cl::cat(Category), llvm::cl::init(false));
} // namespace options
static std::unique_ptr<llvm::MemoryBuffer>
@@ -3006,6 +3016,14 @@
InitInvok.getLangOptions().EffectiveLanguageVersion = actual.getValue();
}
}
+ if (options::DisableObjCInterop) {
+ InitInvok.getLangOptions().EnableObjCInterop = false;
+ } else if (options::EnableObjCInterop) {
+ InitInvok.getLangOptions().EnableObjCInterop = true;
+ } else {
+ InitInvok.getLangOptions().EnableObjCInterop =
+ llvm::Triple(InitInvok.getTargetTriple()).isOSDarwin();
+ }
InitInvok.getClangImporterOptions().ModuleCachePath =
options::ModuleCachePath;
InitInvok.getClangImporterOptions().PrecompiledHeaderOutputDir =