From 67fae0356c346d380b98159059b33792b6b3ca24 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 26 Oct 2017 22:44:01 -0700 Subject: [PATCH 1/5] ClangImporter: minor clang-format fixing (NFC) --- lib/ClangImporter/ClangImporter.cpp | 40 +++++++++++++---------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index cb9ec1da147e9..d7c786d0a8fdb 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -435,37 +435,33 @@ getNormalInvocationArguments(std::vector &invocationArgStrs, 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(), - { - - // Enable modules - "-fmodules", - "-Werror=non-modular-include-in-framework-module", - "-Xclang", "-fmodule-feature", "-Xclang", "swift", + invocationArgStrs.insert(invocationArgStrs.end(), { + // 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, + }); // Set C language options. if (triple.isOSDarwin()) { From 4dba0a33c3a91f4efacdbed79757bcc0d3292b4b Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 26 Oct 2017 23:53:42 -0700 Subject: [PATCH 2/5] ClangImporter: allow control over ObjCInterop Select the language for the clang importer based on the `-enable-objc-interop` flag rather than target. This paves the road to enabling ObjC tests on non-Darwin targets as well as building on Darwin without ObjC interop. --- lib/ClangImporter/ClangImporter.cpp | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index d7c786d0a8fdb..af038130e42ac 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -430,7 +430,8 @@ static void getNormalInvocationArguments(std::vector &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; @@ -463,12 +464,15 @@ getNormalInvocationArguments(std::vector &invocationArgStrs, SHIMS_INCLUDE_FLAG, searchPathOpts.RuntimeResourcePath, }); + if (LangOpts.EnableObjCInterop) + invocationArgStrs.insert(invocationArgStrs.end(), + {"-x", "objective-c", "-std=gnu11", "-fobjc-arc"}); + 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 "\")))", @@ -514,24 +518,16 @@ getNormalInvocationArguments(std::vector &invocationArgStrs, "-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. From 3d1889c015ab9007ea186a522edbcb96dea06506 Mon Sep 17 00:00:00 2001 From: Francis Ricci Date: Thu, 2 Nov 2017 07:23:12 -0700 Subject: [PATCH 3/5] ClangImporter: default to ios objc runtime on non-darwin platforms This allows objc interop to be tested on non-darwin platforms. The iOS runtime is used because the abi is the same as the macOS abi, but without fragility concerns. --- lib/ClangImporter/ClangImporter.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index af038130e42ac..4a973b23fd32b 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -464,11 +464,16 @@ getNormalInvocationArguments(std::vector &invocationArgStrs, SHIMS_INCLUDE_FLAG, searchPathOpts.RuntimeResourcePath, }); - if (LangOpts.EnableObjCInterop) + if (LangOpts.EnableObjCInterop) { invocationArgStrs.insert(invocationArgStrs.end(), {"-x", "objective-c", "-std=gnu11", "-fobjc-arc"}); - else + // 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()) { From 3c417d531ef191b124cf63e8ea03b1ed982b4b49 Mon Sep 17 00:00:00 2001 From: Francis Ricci Date: Mon, 6 Nov 2017 09:30:30 -0800 Subject: [PATCH 4/5] swift-ide-test: Allow objc-interop to be configured This adds a -disable-objc-interop flag to allow objc-interop to be disabled, and an -enable-objc-interop flag to allow objc-interop to be enabled. Objc interop will default to enabled on darwin, and disabled on other platforms. --- tools/swift-ide-test/swift-ide-test.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp index a04751bc03e5e..abb6af8af3bbc 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 DebugConstraintSolver("debug-constraints", static llvm::cl::opt IncludeLocals("include-locals", llvm::cl::desc("Index local symbols too."), llvm::cl::cat(Category), llvm::cl::init(false)); + +static llvm::cl::opt + EnableObjCInterop("enable-objc-interop", + llvm::cl::desc("Enable ObjC interop."), + llvm::cl::cat(Category), llvm::cl::init(false)); + +static llvm::cl::opt + DisableObjCInterop("disable-objc-interop", + llvm::cl::desc("Disable ObjC interop."), + llvm::cl::cat(Category), llvm::cl::init(false)); } // namespace options static std::unique_ptr @@ -3005,6 +3015,14 @@ int main(int argc, char *argv[]) { 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 = From 1822c880581d26377e0dda1939c073587d727133 Mon Sep 17 00:00:00 2001 From: Francis Ricci Date: Mon, 6 Nov 2017 09:50:05 -0800 Subject: [PATCH 5/5] test: Test objc-interop on linux --- test/IDE/complete_from_clang_framework.swift | 24 +++++++++----------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/test/IDE/complete_from_clang_framework.swift b/test/IDE/complete_from_clang_framework.swift index 3fa669ebcded0..6cd1101e04268 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!