|
12 | 12 |
|
13 | 13 | import ASTBridging
|
14 | 14 | import SwiftDiagnostics
|
15 |
| -import SwiftIfConfig |
| 15 | +@_spi(Compiler) import SwiftIfConfig |
16 | 16 | import SwiftParser
|
17 | 17 | import SwiftSyntax
|
18 | 18 |
|
@@ -109,6 +109,13 @@ struct CompilerBuildConfiguration: BuildConfiguration {
|
109 | 109 |
|
110 | 110 | func isActiveTargetRuntime(name: String) throws -> Bool {
|
111 | 111 | var name = name
|
| 112 | + |
| 113 | + // Complain if the provided runtime isn't one of the known values. |
| 114 | + switch name { |
| 115 | + case "_Native", "_ObjC", "_multithreaded": break |
| 116 | + default: throw IfConfigError.unexpectedRuntimeCondition |
| 117 | + } |
| 118 | + |
112 | 119 | return name.withBridgedString { nameRef in
|
113 | 120 | ctx.langOptsIsActiveTargetRuntime(nameRef)
|
114 | 121 | }
|
@@ -161,6 +168,18 @@ struct CompilerBuildConfiguration: BuildConfiguration {
|
161 | 168 | }
|
162 | 169 | }
|
163 | 170 |
|
| 171 | +enum IfConfigError: Error, CustomStringConvertible { |
| 172 | + case unexpectedRuntimeCondition |
| 173 | + |
| 174 | + var description: String { |
| 175 | + switch self { |
| 176 | + case .unexpectedRuntimeCondition: |
| 177 | + return "unexpected argument for the '_runtime' condition; expected '_Native' or '_ObjC'" |
| 178 | + } |
| 179 | + } |
| 180 | +} |
| 181 | + |
| 182 | + |
164 | 183 | /// Extract the #if clause range information for the given source file.
|
165 | 184 | @_cdecl("swift_ASTGen_configuredRegions")
|
166 | 185 | public func configuredRegions(
|
@@ -301,3 +320,53 @@ public func freeConfiguredRegions(
|
301 | 320 | ) {
|
302 | 321 | UnsafeMutableBufferPointer(start: regions, count: numRegions).deallocate()
|
303 | 322 | }
|
| 323 | + |
| 324 | +/// Evaluate the #if condition at ifClauseLocationPtr. |
| 325 | +@_cdecl("swift_ASTGen_evaluatePoundIfCondition") |
| 326 | +public func evaluatePoundIfCondition( |
| 327 | + astContext: BridgedASTContext, |
| 328 | + diagEnginePtr: UnsafeMutableRawPointer, |
| 329 | + sourceFileBuffer: BridgedStringRef, |
| 330 | + ifConditionText: BridgedStringRef, |
| 331 | + shouldEvaluate: Bool |
| 332 | +) -> Int { |
| 333 | + // Retrieve the #if condition that we're evaluating here. |
| 334 | + // FIXME: Use 'ExportedSourceFile' when C++ parser is replaced. |
| 335 | + let textBuffer = UnsafeBufferPointer<UInt8>(start: ifConditionText.data, count: ifConditionText.count) |
| 336 | + var parser = Parser(textBuffer) |
| 337 | + let conditionExpr = ExprSyntax.parse(from: &parser) |
| 338 | + |
| 339 | + let isActive: Bool |
| 340 | + let syntaxErrorsAllowed: Bool |
| 341 | + let diagnostics: [Diagnostic] |
| 342 | + if shouldEvaluate { |
| 343 | + // Evaluate the condition against the compiler's build configuration. |
| 344 | + let configuration = CompilerBuildConfiguration( |
| 345 | + ctx: astContext, |
| 346 | + sourceBuffer: textBuffer |
| 347 | + ) |
| 348 | + |
| 349 | + let state: IfConfigRegionState |
| 350 | + (state, syntaxErrorsAllowed, diagnostics) = IfConfigRegionState.evaluating(conditionExpr, in: configuration) |
| 351 | + isActive = (state == .active) |
| 352 | + } else { |
| 353 | + // Don't evaluate the condition, because we know it's inactive. Determine |
| 354 | + // whether syntax errors are permitted within this region according to the |
| 355 | + // condition. |
| 356 | + isActive = false |
| 357 | + (syntaxErrorsAllowed, diagnostics) = IfConfigClauseSyntax.syntaxErrorsAllowed(conditionExpr) |
| 358 | + } |
| 359 | + |
| 360 | + // Render the diagnostics. |
| 361 | + for diagnostic in diagnostics { |
| 362 | + emitDiagnostic( |
| 363 | + diagnosticEngine: BridgedDiagnosticEngine(raw: diagEnginePtr), |
| 364 | + sourceFileBuffer: UnsafeBufferPointer(start: sourceFileBuffer.data, count: sourceFileBuffer.count), |
| 365 | + sourceFileBufferOffset: ifConditionText.data! - sourceFileBuffer.data!, |
| 366 | + diagnostic: diagnostic, |
| 367 | + diagnosticSeverity: diagnostic.diagMessage.severity |
| 368 | + ) |
| 369 | + } |
| 370 | + |
| 371 | + return (isActive ? 0x1 : 0) | (syntaxErrorsAllowed ? 0x2 : 0) |
| 372 | +} |
0 commit comments