Skip to content

Commit e5442fe

Browse files
committed
[ASTGen] Enable C++ interop
1 parent 26bfe10 commit e5442fe

File tree

7 files changed

+89
-14
lines changed

7 files changed

+89
-14
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,9 +405,10 @@ set(SWIFT_STDLIB_MSVC_RUNTIME_LIBRARY
405405

406406

407407
if(BRIDGING_MODE STREQUAL "DEFAULT" OR NOT BRIDGING_MODE)
408-
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
408+
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))
409409
# In debug builds, to workaround a problem with LLDB's `po` command (rdar://115770255).
410410
# On windows to workaround a build problem.
411+
# If the host Swift version is less than 5.8, use pure mode to workaround a C++ interop compiler crash.
411412
set(BRIDGING_MODE "PURE")
412413
else()
413414
set(BRIDGING_MODE "INLINE")

cmake/modules/AddPureSwift.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ function(_add_host_swift_compile_options name)
3737
target_link_options(${name} PRIVATE ${_cov_flags})
3838
endif()
3939

40+
if("${BRIDGING_MODE}" STREQUAL "PURE")
41+
target_compile_options(${name} PRIVATE
42+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xcc -DPURE_BRIDGING_MODE>")
43+
endif()
44+
4045
# The compat56 library is not available in current toolchains. The stage-0
4146
# compiler will build fine since the builder compiler is not aware of the 56
4247
# compat library, but the stage-1 and subsequent stage compilers will fail as

lib/ASTGen/CMakeLists.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,39 @@ add_pure_swift_host_library(swiftASTGen STATIC
3838
SwiftSyntaxMacroExpansion
3939
swiftLLVMJSON
4040
)
41+
42+
set(c_include_paths
43+
# LLVM modules and headers.
44+
"${LLVM_MAIN_INCLUDE_DIR}"
45+
# Generated LLVM headers.
46+
"${LLVM_INCLUDE_DIR}"
47+
# Clang modules and headers.
48+
${CLANG_INCLUDE_DIRS}
49+
# Bridging modules and headers.
50+
"${SWIFT_MAIN_INCLUDE_DIR}"
51+
# Generated C headers.
52+
"${CMAKE_CURRENT_BINARY_DIR}/../../include")
53+
set(c_include_paths_args)
54+
foreach(c_include_path ${c_include_paths})
55+
list(APPEND c_include_paths_args "SHELL: -Xcc -I -Xcc ${c_include_path}")
56+
endforeach()
57+
58+
# Prior to 5.9, we have to use the experimental flag for C++ interop.
59+
if (CMAKE_Swift_COMPILER_VERSION VERSION_LESS 5.9)
60+
set(cxx_interop_flag "-enable-experimental-cxx-interop")
61+
else()
62+
set(cxx_interop_flag "-cxx-interoperability-mode=default")
63+
endif()
64+
65+
set(compile_options
66+
${c_include_paths_args}
67+
"SHELL: ${cxx_interop_flag}"
68+
"SHELL: -Xcc -std=c++17 -Xcc -DCOMPILED_WITH_SWIFT"
69+
70+
# Necessary to avoid treating IBOutlet and IBAction as keywords
71+
"SHELL:-Xcc -UIBOutlet -Xcc -UIBAction -Xcc -UIBInspectable"
72+
)
73+
74+
foreach(target swiftASTGen swiftLLVMJSON)
75+
target_compile_options(${target} PRIVATE ${compile_options})
76+
endforeach()

lib/ASTGen/Package.swift

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version: 5.6
1+
// swift-tools-version: 5.9
22

33
// The CMake build system is the only one that's able to produce a working
44
// compiler. This Package.swift makes it easier to build and work with the
@@ -7,19 +7,37 @@
77
// the new Swift parser are better implemented/tested within or on top of the
88
// swift-syntax package.
99

10+
// To successfully build, you'll need to create a couple of symlinks to an
11+
// existing Ninja build:
12+
//
13+
// ln -s <project-root>/build/<Ninja-Build>/llvm-<os+arch> <project-root>/build/Default/llvm
14+
// ln -s <project-root>/build/<Ninja-Build>/swift-<os+arch> <project-root>/build/Default/swift
15+
//
16+
// where <project-root> is the parent directory of the swift repository.
17+
//
18+
// FIXME: We may want to consider generating Package.swift as a part of the
19+
// build.
20+
1021
import PackageDescription
1122

1223
let swiftSetttings: [SwiftSetting] = [
24+
.interoperabilityMode(.Cxx),
1325
.unsafeFlags([
14-
"-I", "../../include/swift/",
15-
"-I", "../../include",
16-
])
26+
"-Xcc", "-DCOMPILED_WITH_SWIFT",
27+
"-Xcc", "-UIBOutlet", "-Xcc", "-UIBAction", "-Xcc", "-UIBInspectable",
28+
"-Xcc", "-I../../include",
29+
"-Xcc", "-I../../../llvm-project/llvm/include",
30+
"-Xcc", "-I../../../llvm-project/clang/include",
31+
"-Xcc", "-I../../../build/Default/swift/include",
32+
"-Xcc", "-I../../../build/Default/llvm/include",
33+
"-Xcc", "-I../../../build/Default/llvm/tools/clang/include",
34+
]),
1735
]
1836

1937
let package = Package(
2038
name: "swiftSwiftCompiler",
2139
platforms: [
22-
.macOS(.v10_15)
40+
.macOS(.v13)
2341
],
2442
products: [
2543
.library(name: "swiftASTGen", targets: ["swiftASTGen"]),
@@ -53,5 +71,6 @@ let package = Package(
5371
path: "Sources/LLVMJSON",
5472
swiftSettings: swiftSetttings
5573
),
56-
]
74+
],
75+
cxxLanguageStandard: .cxx17
5776
)

lib/ASTGen/Sources/ASTGen/ASTGen.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,9 @@ extension ASTGenVisitor {
380380
@inline(__always)
381381
func generate(_ node: InheritedTypeListSyntax?) -> BridgedArrayRef {
382382
guard let node else {
383-
return .init()
383+
// NOTE: You cannot do '.init()' here as that will produce garbage
384+
// (rdar://116825963).
385+
return .init(data: nil, numElements: 0)
384386
}
385387

386388
return self.generate(node)
@@ -389,7 +391,9 @@ extension ASTGenVisitor {
389391
@inline(__always)
390392
func generate(_ node: PrecedenceGroupNameListSyntax?) -> BridgedArrayRef {
391393
guard let node else {
392-
return .init()
394+
// NOTE: You cannot do '.init()' here as that will produce garbage
395+
// (rdar://116825963).
396+
return .init(data: nil, numElements: 0)
393397
}
394398

395399
return self.generate(node)
@@ -403,7 +407,9 @@ extension Collection {
403407
/// on a ``LazyFilterSequence`` due to the `count` access.
404408
func compactMap<T>(in astgen: ASTGenVisitor, _ transform: (Element) -> T?) -> BridgedArrayRef {
405409
if self.isEmpty {
406-
return .init()
410+
// NOTE: You cannot do '.init()' here as that will produce garbage
411+
// (rdar://116825963).
412+
return .init(data: nil, numElements: 0)
407413
}
408414

409415
let baseAddress = astgen.allocator.allocate(T.self, count: self.count).baseAddress!
@@ -429,7 +435,9 @@ extension LazyCollectionProtocol {
429435
/// Returns a copy of the collection's elements as a `BridgedArrayRef` with a lifetime tied to that of `astgen`.
430436
func bridgedArray(in astgen: ASTGenVisitor) -> BridgedArrayRef {
431437
if self.isEmpty {
432-
return .init()
438+
// NOTE: You cannot do '.init()' here as that will produce garbage
439+
// (rdar://116825963).
440+
return .init(data: nil, numElements: 0)
433441
}
434442

435443
let buffer = astgen.allocator.allocate(Element.self, count: self.count)
@@ -455,7 +463,9 @@ extension Optional where Wrapped: LazyCollectionProtocol {
455463
@inline(__always)
456464
func bridgedArray(in astgen: ASTGenVisitor) -> BridgedArrayRef {
457465
guard let self else {
458-
return .init()
466+
// NOTE: You cannot do '.init()' here as that will produce garbage
467+
// (rdar://116825963).
468+
return .init(data: nil, numElements: 0)
459469
}
460470

461471
return self.bridgedArray(in: astgen)

lib/ASTGen/Sources/ASTGen/Macros.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,9 @@ func makeExpansionOutputResult(
400400
outputPointer: UnsafeMutablePointer<BridgedString>
401401
) -> Int {
402402
guard var expandedSource = expandedSource else {
403-
outputPointer.pointee = BridgedString()
403+
// NOTE: You cannot use 'init()' here as that will produce garbage
404+
// (rdar://116825963).
405+
outputPointer.pointee = BridgedString(data: nil, length: 0)
404406
return -1
405407
}
406408
outputPointer.pointee = allocateBridgedString(expandedSource)

lib/ASTGen/Sources/ASTGen/PluginHost.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ struct CompilerPlugin {
127127
}
128128

129129
private func waitForNextMessage() throws -> PluginToHostMessage {
130-
var result: BridgedData = BridgedData()
130+
// NOTE: You cannot use 'init()' here as that will produce garbage
131+
// (rdar://116825963).
132+
var result = BridgedData(baseAddress: nil, size: 0)
131133
let hadError = Plugin_waitForNextMessage(opaqueHandle, &result)
132134
defer { BridgedData_free(result) }
133135
guard !hadError else {

0 commit comments

Comments
 (0)