[ASTGen] Enable C++ interop

This commit is contained in:
Hamish Knight
2023-10-30 23:49:52 +00:00
parent 26bfe10456
commit e5442fea50
7 changed files with 89 additions and 14 deletions

View File

@@ -405,9 +405,10 @@ set(SWIFT_STDLIB_MSVC_RUNTIME_LIBRARY
if(BRIDGING_MODE STREQUAL "DEFAULT" OR NOT BRIDGING_MODE)
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows" OR (CMAKE_Swift_COMPILER AND CMAKE_Swift_COMPILER_VERSION VERSION_LESS 5.8))
# In debug builds, to workaround a problem with LLDB's `po` command (rdar://115770255).
# On windows to workaround a build problem.
# If the host Swift version is less than 5.8, use pure mode to workaround a C++ interop compiler crash.
set(BRIDGING_MODE "PURE")
else()
set(BRIDGING_MODE "INLINE")

View File

@@ -37,6 +37,11 @@ function(_add_host_swift_compile_options name)
target_link_options(${name} PRIVATE ${_cov_flags})
endif()
if("${BRIDGING_MODE}" STREQUAL "PURE")
target_compile_options(${name} PRIVATE
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xcc -DPURE_BRIDGING_MODE>")
endif()
# The compat56 library is not available in current toolchains. The stage-0
# compiler will build fine since the builder compiler is not aware of the 56
# compat library, but the stage-1 and subsequent stage compilers will fail as

View File

@@ -38,3 +38,39 @@ add_pure_swift_host_library(swiftASTGen STATIC
SwiftSyntaxMacroExpansion
swiftLLVMJSON
)
set(c_include_paths
# LLVM modules and headers.
"${LLVM_MAIN_INCLUDE_DIR}"
# Generated LLVM headers.
"${LLVM_INCLUDE_DIR}"
# Clang modules and headers.
${CLANG_INCLUDE_DIRS}
# Bridging modules and headers.
"${SWIFT_MAIN_INCLUDE_DIR}"
# Generated C headers.
"${CMAKE_CURRENT_BINARY_DIR}/../../include")
set(c_include_paths_args)
foreach(c_include_path ${c_include_paths})
list(APPEND c_include_paths_args "SHELL: -Xcc -I -Xcc ${c_include_path}")
endforeach()
# Prior to 5.9, we have to use the experimental flag for C++ interop.
if (CMAKE_Swift_COMPILER_VERSION VERSION_LESS 5.9)
set(cxx_interop_flag "-enable-experimental-cxx-interop")
else()
set(cxx_interop_flag "-cxx-interoperability-mode=default")
endif()
set(compile_options
${c_include_paths_args}
"SHELL: ${cxx_interop_flag}"
"SHELL: -Xcc -std=c++17 -Xcc -DCOMPILED_WITH_SWIFT"
# Necessary to avoid treating IBOutlet and IBAction as keywords
"SHELL:-Xcc -UIBOutlet -Xcc -UIBAction -Xcc -UIBInspectable"
)
foreach(target swiftASTGen swiftLLVMJSON)
target_compile_options(${target} PRIVATE ${compile_options})
endforeach()

View File

@@ -1,4 +1,4 @@
// swift-tools-version: 5.6
// swift-tools-version: 5.9
// The CMake build system is the only one that's able to produce a working
// compiler. This Package.swift makes it easier to build and work with the
@@ -7,19 +7,37 @@
// the new Swift parser are better implemented/tested within or on top of the
// swift-syntax package.
// To successfully build, you'll need to create a couple of symlinks to an
// existing Ninja build:
//
// ln -s <project-root>/build/<Ninja-Build>/llvm-<os+arch> <project-root>/build/Default/llvm
// ln -s <project-root>/build/<Ninja-Build>/swift-<os+arch> <project-root>/build/Default/swift
//
// where <project-root> is the parent directory of the swift repository.
//
// FIXME: We may want to consider generating Package.swift as a part of the
// build.
import PackageDescription
let swiftSetttings: [SwiftSetting] = [
.interoperabilityMode(.Cxx),
.unsafeFlags([
"-I", "../../include/swift/",
"-I", "../../include",
])
"-Xcc", "-DCOMPILED_WITH_SWIFT",
"-Xcc", "-UIBOutlet", "-Xcc", "-UIBAction", "-Xcc", "-UIBInspectable",
"-Xcc", "-I../../include",
"-Xcc", "-I../../../llvm-project/llvm/include",
"-Xcc", "-I../../../llvm-project/clang/include",
"-Xcc", "-I../../../build/Default/swift/include",
"-Xcc", "-I../../../build/Default/llvm/include",
"-Xcc", "-I../../../build/Default/llvm/tools/clang/include",
]),
]
let package = Package(
name: "swiftSwiftCompiler",
platforms: [
.macOS(.v10_15)
.macOS(.v13)
],
products: [
.library(name: "swiftASTGen", targets: ["swiftASTGen"]),
@@ -53,5 +71,6 @@ let package = Package(
path: "Sources/LLVMJSON",
swiftSettings: swiftSetttings
),
]
],
cxxLanguageStandard: .cxx17
)

View File

@@ -380,7 +380,9 @@ extension ASTGenVisitor {
@inline(__always)
func generate(_ node: InheritedTypeListSyntax?) -> BridgedArrayRef {
guard let node else {
return .init()
// NOTE: You cannot do '.init()' here as that will produce garbage
// (rdar://116825963).
return .init(data: nil, numElements: 0)
}
return self.generate(node)
@@ -389,7 +391,9 @@ extension ASTGenVisitor {
@inline(__always)
func generate(_ node: PrecedenceGroupNameListSyntax?) -> BridgedArrayRef {
guard let node else {
return .init()
// NOTE: You cannot do '.init()' here as that will produce garbage
// (rdar://116825963).
return .init(data: nil, numElements: 0)
}
return self.generate(node)
@@ -403,7 +407,9 @@ extension Collection {
/// on a ``LazyFilterSequence`` due to the `count` access.
func compactMap<T>(in astgen: ASTGenVisitor, _ transform: (Element) -> T?) -> BridgedArrayRef {
if self.isEmpty {
return .init()
// NOTE: You cannot do '.init()' here as that will produce garbage
// (rdar://116825963).
return .init(data: nil, numElements: 0)
}
let baseAddress = astgen.allocator.allocate(T.self, count: self.count).baseAddress!
@@ -429,7 +435,9 @@ extension LazyCollectionProtocol {
/// Returns a copy of the collection's elements as a `BridgedArrayRef` with a lifetime tied to that of `astgen`.
func bridgedArray(in astgen: ASTGenVisitor) -> BridgedArrayRef {
if self.isEmpty {
return .init()
// NOTE: You cannot do '.init()' here as that will produce garbage
// (rdar://116825963).
return .init(data: nil, numElements: 0)
}
let buffer = astgen.allocator.allocate(Element.self, count: self.count)
@@ -455,7 +463,9 @@ extension Optional where Wrapped: LazyCollectionProtocol {
@inline(__always)
func bridgedArray(in astgen: ASTGenVisitor) -> BridgedArrayRef {
guard let self else {
return .init()
// NOTE: You cannot do '.init()' here as that will produce garbage
// (rdar://116825963).
return .init(data: nil, numElements: 0)
}
return self.bridgedArray(in: astgen)

View File

@@ -400,7 +400,9 @@ func makeExpansionOutputResult(
outputPointer: UnsafeMutablePointer<BridgedString>
) -> Int {
guard var expandedSource = expandedSource else {
outputPointer.pointee = BridgedString()
// NOTE: You cannot use 'init()' here as that will produce garbage
// (rdar://116825963).
outputPointer.pointee = BridgedString(data: nil, length: 0)
return -1
}
outputPointer.pointee = allocateBridgedString(expandedSource)

View File

@@ -127,7 +127,9 @@ struct CompilerPlugin {
}
private func waitForNextMessage() throws -> PluginToHostMessage {
var result: BridgedData = BridgedData()
// NOTE: You cannot use 'init()' here as that will produce garbage
// (rdar://116825963).
var result = BridgedData(baseAddress: nil, size: 0)
let hadError = Plugin_waitForNextMessage(opaqueHandle, &result)
defer { BridgedData_free(result) }
guard !hadError else {