diff --git a/Sources/SwiftSyntax/CMakeLists.txt b/Sources/SwiftSyntax/CMakeLists.txt index 23cdd2fbb59..3d117dc1132 100644 --- a/Sources/SwiftSyntax/CMakeLists.txt +++ b/Sources/SwiftSyntax/CMakeLists.txt @@ -81,3 +81,6 @@ add_swift_syntax_library(SwiftSyntax generated/syntaxNodes/SyntaxNodesQRS.swift generated/syntaxNodes/SyntaxNodesTUVWXYZ.swift ) + +target_link_swift_syntax_libraries(SwiftSyntax PRIVATE + _SwiftSyntaxCShims) diff --git a/Sources/SwiftSyntax/SyntaxArena.swift b/Sources/SwiftSyntax/SyntaxArena.swift index d9f57930b24..56e57327810 100644 --- a/Sources/SwiftSyntax/SyntaxArena.swift +++ b/Sources/SwiftSyntax/SyntaxArena.swift @@ -10,21 +10,10 @@ // //===----------------------------------------------------------------------===// -#if SWIFT_SYNTAX_BUILD_USING_CMAKE -// The CMake bulid of swift-syntax does not build the _AtomicBool module because swift-syntax's CMake build is -// Swift-only. Fake an `AtomicBool` type that is not actually atomic. This should be acceptable for the following -// reasons: -// - `AtomicBool` is only used for the `hasParent` assertion, so release compilers don't rely on it -// - The compiler is single-threaded so it it is safe from race conditions on `AtomicBool`. -fileprivate struct AtomicBool { - var value: Bool - - init(initialValue: Bool) { - self.value = initialValue - } -} +#if swift(>=6.0) +private import _SwiftSyntaxCShims #else -import _SwiftSyntaxCShims +@_implementationOnly import _SwiftSyntaxCShims #endif /// A syntax arena owns the memory for all syntax nodes within it. @@ -69,7 +58,7 @@ public class SyntaxArena { /// /// - Important: This is only intended to be used for assertions to catch /// retain cycles in syntax arenas. - fileprivate var hasParent: AtomicBool + fileprivate let hasParent: UnsafeMutablePointer #endif /// Construct a new ``SyntaxArena`` in which syntax nodes can be allocated. @@ -81,7 +70,7 @@ public class SyntaxArena { self.allocator = BumpPtrAllocator(initialSlabSize: slabSize) self.childRefs = [] #if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS - self.hasParent = AtomicBool(initialValue: false) + self.hasParent = swiftsyntax_atomic_bool_create(false) #endif } @@ -89,6 +78,9 @@ public class SyntaxArena { for child in childRefs { child.release() } + #if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS + swiftsyntax_atomic_bool_destroy(self.hasParent) + #endif } /// Allocates a buffer of `RawSyntax?` with the given count, then returns the @@ -158,7 +150,7 @@ public class SyntaxArena { #if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS precondition( - !self.hasParent.value, + !swiftsyntax_atomic_bool_get(self.hasParent), "an arena can't have a new child once it's owned by other arenas" ) #endif @@ -300,14 +292,14 @@ struct SyntaxArenaRef: Hashable, @unchecked Sendable { } #if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS - /// Accessor for ther underlying's `SyntaxArena.hasParent` + /// Accessor for the underlying's `SyntaxArena.hasParent` var hasParent: Bool { - value.hasParent.value + swiftsyntax_atomic_bool_get(value.hasParent) } /// Sets the `SyntaxArena.hasParent` on the referenced arena. func setHasParent(_ newValue: Bool) { - value.hasParent.value = newValue + swiftsyntax_atomic_bool_set(value.hasParent, newValue) } #endif diff --git a/Sources/_SwiftSyntaxCShims/include/AtomicBool.h b/Sources/_SwiftSyntaxCShims/include/AtomicBool.h index 68990e87aec..1d456ad4943 100644 --- a/Sources/_SwiftSyntaxCShims/include/AtomicBool.h +++ b/Sources/_SwiftSyntaxCShims/include/AtomicBool.h @@ -14,26 +14,28 @@ #define SWIFTSYNTAX_ATOMICBOOL_H #include +#include typedef struct { _Atomic(bool) value; } AtomicBool; -__attribute__((swift_name("AtomicBool.init(initialValue:)"))) -static inline AtomicBool atomic_bool_create(bool initialValue) { - AtomicBool atomic; - atomic.value = initialValue; +static inline AtomicBool *_Nonnull swiftsyntax_atomic_bool_create(bool initialValue) { + AtomicBool *atomic = malloc(sizeof(AtomicBool)); + atomic->value = initialValue; return atomic; } -__attribute__((swift_name("getter:AtomicBool.value(self:)"))) -static inline bool atomic_bool_get(AtomicBool *atomic) { +static inline bool swiftsyntax_atomic_bool_get(AtomicBool *_Nonnull atomic) { return atomic->value; } -__attribute__((swift_name("setter:AtomicBool.value(self:_:)"))) -static inline void atomic_bool_set(AtomicBool *atomic, bool newValue) { +static inline void swiftsyntax_atomic_bool_set(AtomicBool *_Nonnull atomic, bool newValue) { atomic->value = newValue; } +static inline void swiftsyntax_atomic_bool_destroy(AtomicBool *_Nonnull atomic) { + free(atomic); +} + #endif // SWIFTSYNTAX_ATOMICBOOL_H