Skip to content

Commit 8779074

Browse files
committed
Add support for _hasAtomicBitWidth to evaluation
1 parent aa97fbd commit 8779074

File tree

5 files changed

+37
-10
lines changed

5 files changed

+37
-10
lines changed

Sources/SwiftIfConfig/BuildConfiguration.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,17 +213,30 @@ public protocol BuildConfiguration {
213213

214214
/// The bit width of a data pointer for the target architecture.
215215
///
216-
/// The target's pointer bit with (which also corresponds to the number of
216+
/// The target's pointer bit width (which also corresponds to the number of
217217
/// bits in `Int`/`UInt`) can only be queried with the experimental syntax
218218
/// `_pointerBitWidth(_<bitwidth>)`, e.g.,
219219
///
220220
/// ```swift
221-
/// #if _pointerBitWidth(32)
221+
/// #if _pointerBitWidth(_32)
222222
/// // 32-bit system
223223
/// #endif
224224
/// ```
225225
var targetPointerBitWidth: Int { get }
226226

227+
/// The atomic bit widths that are natively supported by the target
228+
/// architecture.
229+
///
230+
/// This lists all of the bit widths for which the target provides support
231+
/// for atomic operations. It can be queried with
232+
/// `_hasAtomicBitWidth(_<bitwidth>)`, e.g.
233+
///
234+
/// ```swift
235+
/// #if _hasAtomicBitWidth(_64)
236+
/// // 64-bit atomics are available
237+
/// #endif
238+
var targetAtomicBitWidths: [Int] { get }
239+
227240
/// The endianness of the target architecture.
228241
///
229242
/// The target's endianness can onyl be queried with the experimental syntax

Sources/SwiftIfConfig/IfConfigEvaluation.swift

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -269,28 +269,34 @@ func evaluateIfConfig(
269269
versioned: fn.isVersioned
270270
)
271271

272-
case ._pointerBitWidth:
272+
case ._pointerBitWidth, ._hasAtomicBitWidth:
273273
// Ensure that we have a single argument that is a simple identifier, which
274274
// is an underscore followed by an integer.
275275
guard let argExpr = call.arguments.singleUnlabeledExpression,
276276
let arg = argExpr.simpleIdentifierExpr,
277277
let argFirst = arg.first,
278278
argFirst == "_",
279-
let expectedPointerBitWidth = Int(arg.dropFirst())
279+
let expectedBitWidth = Int(arg.dropFirst())
280280
else {
281281
throw recordedError(
282282
.requiresUnlabeledArgument(
283283
name: fnName,
284-
role: "pointer bit with ('_' followed by an integer)",
284+
role: "bit width ('_' followed by an integer)",
285285
syntax: ExprSyntax(call)
286286
)
287287
)
288288
}
289289

290-
return (
291-
active: configuration.targetPointerBitWidth == expectedPointerBitWidth,
292-
versioned: fn.isVersioned
293-
)
290+
let active: Bool
291+
if fn == ._pointerBitWidth {
292+
active = configuration.targetPointerBitWidth == expectedBitWidth
293+
} else if fn == ._hasAtomicBitWidth {
294+
active = configuration.targetAtomicBitWidths.contains(expectedBitWidth)
295+
} else {
296+
fatalError("extraneous case above not handled")
297+
}
298+
299+
return (active: active, versioned: fn.isVersioned)
294300

295301
case .swift:
296302
return try doVersionComparisonCheck(configuration.languageVersion)

Sources/SwiftIfConfig/IfConfigFunctions.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ enum IfConfigFunctions: String {
3636
/// A check for the target environment (e.g., simulator) via `targetEnvironment(<environment>)`.
3737
case targetEnvironment
3838

39+
/// A check to determine whether the platform supports atomic operations
40+
/// with the given bitwidth, e.g., `_hasAtomicBitWidth(_64)`.
41+
case _hasAtomicBitWidth
42+
3943
/// A historical check against a specific compiler build version via `_compiler_version("<version>")`.
4044
case _compiler_version
4145

@@ -61,7 +65,7 @@ enum IfConfigFunctions: String {
6165
return true
6266

6367
case .hasAttribute, .hasFeature, .canImport, .os, .arch, .targetEnvironment,
64-
._endian, ._pointerBitWidth, ._runtime, ._ptrauth:
68+
._hasAtomicBitWidth, ._endian, ._pointerBitWidth, ._runtime, ._ptrauth:
6569
return false
6670
}
6771
}

Tests/SwiftIfConfigTest/EvaluateTests.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ public class EvaluateTests: XCTestCase {
165165
assertIfConfig("_ptrauth(none)", .inactive)
166166
assertIfConfig("_pointerBitWidth(_64)", .active)
167167
assertIfConfig("_pointerBitWidth(_32)", .inactive)
168+
assertIfConfig("_hasAtomicBitWidth(_64)", .active)
169+
assertIfConfig("_hasAtomicBitWidth(_128)", .inactive)
168170
}
169171

170172
func testVersions() throws {

Tests/SwiftIfConfigTest/TestingBuildConfiguration.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ struct TestingBuildConfiguration: BuildConfiguration {
9393

9494
var targetPointerBitWidth: Int { 64 }
9595

96+
var targetAtomicBitWidths: [Int] { [32, 64] }
97+
9698
var endianness: SwiftIfConfig.Endianness { .little }
9799

98100
var languageVersion: VersionTuple { VersionTuple(5, 5) }

0 commit comments

Comments
 (0)