From c3f865be4ab4a7d179f1a82a39c33986a38f72d3 Mon Sep 17 00:00:00 2001 From: Kuba Mracek Date: Thu, 16 Oct 2025 15:15:27 -0700 Subject: [PATCH 1/2] Add #objectFormat compilation conditional (SE-0492) --- include/swift/AST/PlatformConditionKinds.def | 3 ++ .../ASTGen/CompilerBuildConfiguration.swift | 4 +++ .../Sources/ASTGen/EmbeddedSupport.swift | 4 +++ lib/Basic/LangOptions.cpp | 31 ++++++++++++++++--- lib/Basic/LangOptionsBridging.cpp | 1 + lib/Parse/ParseIfConfig.cpp | 4 ++- .../object_file_format.swift | 11 +++++++ 7 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 test/Parse/ConditionalCompilation/object_file_format.swift diff --git a/include/swift/AST/PlatformConditionKinds.def b/include/swift/AST/PlatformConditionKinds.def index bc980fd13f98b..9c461f1bf13da 100644 --- a/include/swift/AST/PlatformConditionKinds.def +++ b/include/swift/AST/PlatformConditionKinds.def @@ -49,5 +49,8 @@ PLATFORM_CONDITION_(PtrAuth, "ptrauth") /// The active arch target's max atomic bit width. PLATFORM_CONDITION_(HasAtomicBitWidth, "hasAtomicBitWidth") +/// The active target's file format (Mach-O, ELF, COFF, WASM) +PLATFORM_CONDITION_(ObjectFileFormat, "objectFormat") + #undef PLATFORM_CONDITION #undef PLATFORM_CONDITION_ diff --git a/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift b/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift index 3dbc62d4d760a..62340fbfebbba 100644 --- a/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift +++ b/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift @@ -120,6 +120,10 @@ struct CompilerBuildConfiguration: BuildConfiguration { staticBuildConfiguration.targetPointerBitWidth } + func isActiveTargetObjectFormat(name: String) throws -> Bool { + try staticBuildConfiguration.isActiveTargetObjectFormat(name: name) + } + var targetAtomicBitWidths: [Int] { staticBuildConfiguration.targetAtomicBitWidths } diff --git a/lib/ASTGen/Sources/ASTGen/EmbeddedSupport.swift b/lib/ASTGen/Sources/ASTGen/EmbeddedSupport.swift index 0dfc9fa768fbe..324cbffa3e2f8 100644 --- a/lib/ASTGen/Sources/ASTGen/EmbeddedSupport.swift +++ b/lib/ASTGen/Sources/ASTGen/EmbeddedSupport.swift @@ -124,6 +124,10 @@ struct EmbeddedBuildConfiguration: BuildConfiguration { return configuration.targetPointerBitWidth } + func isActiveTargetObjectFormat(name: String) throws -> Bool { + return try configuration.isActiveTargetObjectFormat(name: name) + } + var targetAtomicBitWidths: [Int] { return configuration.targetAtomicBitWidths } diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp index 114b81a20ae53..3b5b13f65535a 100644 --- a/lib/Basic/LangOptions.cpp +++ b/lib/Basic/LangOptions.cpp @@ -141,13 +141,20 @@ static const SupportedConditionalValue SupportedConditionalCompilationHasAtomicB "_128" }; +static const SupportedConditionalValue SupportedConditionalCompilationObjectFileFormats[] = { + "MachO", + "ELF", + "COFF", + "Wasm", +}; + static const PlatformConditionKind AllPublicPlatformConditionKinds[] = { #define PLATFORM_CONDITION(LABEL, IDENTIFIER) PlatformConditionKind::LABEL, #define PLATFORM_CONDITION_(LABEL, IDENTIFIER) #include "swift/AST/PlatformConditionKinds.def" }; -ArrayRef getSupportedConditionalCompilationValues(const PlatformConditionKind &Kind) { +static ArrayRef getSupportedConditionalCompilationValues(const PlatformConditionKind &Kind) { switch (Kind) { case PlatformConditionKind::OS: return SupportedConditionalCompilationOSs; @@ -167,12 +174,14 @@ ArrayRef getSupportedConditionalCompilationValues(con return SupportedConditionalCompilationPtrAuthSchemes; case PlatformConditionKind::HasAtomicBitWidth: return SupportedConditionalCompilationHasAtomicBitWidths; + case PlatformConditionKind::ObjectFileFormat: + return SupportedConditionalCompilationObjectFileFormats; } llvm_unreachable("Unhandled PlatformConditionKind in switch"); } -PlatformConditionKind suggestedPlatformConditionKind(PlatformConditionKind Kind, const StringRef &V, - std::vector &suggestedValues) { +static PlatformConditionKind suggestedPlatformConditionKind(PlatformConditionKind Kind, const StringRef &V, + std::vector &suggestedValues) { std::string lower = V.lower(); for (const PlatformConditionKind& candidateKind : AllPublicPlatformConditionKinds) { if (candidateKind != Kind) { @@ -191,8 +200,8 @@ PlatformConditionKind suggestedPlatformConditionKind(PlatformConditionKind Kind, return Kind; } -bool isMatching(PlatformConditionKind Kind, const StringRef &V, - PlatformConditionKind &suggestedKind, std::vector &suggestions) { +static bool isMatching(PlatformConditionKind Kind, const StringRef &V, + PlatformConditionKind &suggestedKind, std::vector &suggestions) { // Compare against known values, ignoring case to avoid penalizing // characters with incorrect case. unsigned minDistance = std::numeric_limits::max(); @@ -231,6 +240,7 @@ checkPlatformConditionSupported(PlatformConditionKind Kind, StringRef Value, case PlatformConditionKind::TargetEnvironment: case PlatformConditionKind::PtrAuth: case PlatformConditionKind::HasAtomicBitWidth: + case PlatformConditionKind::ObjectFileFormat: return isMatching(Kind, Value, suggestedKind, suggestedValues); case PlatformConditionKind::CanImport: // All importable names are valid. @@ -649,6 +659,17 @@ std::pair LangOptions::setTarget(llvm::Triple triple) { addPlatformConditionValue(PlatformConditionKind::PointerBitWidth, "_64"); } + // Set the "objectFormat" platform condition. + if (Target.isOSBinFormatMachO()) { + addPlatformConditionValue(PlatformConditionKind::ObjectFileFormat, "MachO"); + } else if (Target.isOSBinFormatELF()) { + addPlatformConditionValue(PlatformConditionKind::ObjectFileFormat, "ELF"); + } else if (Target.isOSBinFormatCOFF()) { + addPlatformConditionValue(PlatformConditionKind::ObjectFileFormat, "COFF"); + } else if (Target.isOSBinFormatWasm()) { + addPlatformConditionValue(PlatformConditionKind::ObjectFileFormat, "Wasm"); + } + // Set the "runtime" platform condition. addPlatformConditionValue(PlatformConditionKind::Runtime, EnableObjCInterop ? "_ObjC" : "_Native"); diff --git a/lib/Basic/LangOptionsBridging.cpp b/lib/Basic/LangOptionsBridging.cpp index 5ccc2a8ea1df0..2eacc3f5bd957 100644 --- a/lib/Basic/LangOptionsBridging.cpp +++ b/lib/Basic/LangOptionsBridging.cpp @@ -228,6 +228,7 @@ void BridgedLangOptions_enumerateBuildConfigurationEntries( case PlatformConditionKind::Endianness: case PlatformConditionKind::PointerBitWidth: + case PlatformConditionKind::ObjectFileFormat: case PlatformConditionKind::CanImport: case PlatformConditionKind::HasAtomicBitWidth: // Handled separately. diff --git a/lib/Parse/ParseIfConfig.cpp b/lib/Parse/ParseIfConfig.cpp index 4e05e078aee60..9dc2e7b6b5726 100644 --- a/lib/Parse/ParseIfConfig.cpp +++ b/lib/Parse/ParseIfConfig.cpp @@ -385,7 +385,7 @@ class ValidateIfConfigCondition : return E; } - // ( 'os' | 'arch' | '_endian' | '_pointerBitWidth' | '_runtime' | '_hasAtomicBitWidth' ) '(' identifier ')'' + // ( 'os' | 'arch' | '_endian' | '_pointerBitWidth' | '_runtime' | '_hasAtomicBitWidth' | 'objectFormat' ) '(' identifier ')'' auto Kind = getPlatformConditionKind(*KindName); if (!Kind.has_value()) { D.diagnose(E->getLoc(), diag::unsupported_platform_condition_expression); @@ -429,6 +429,8 @@ class ValidateIfConfigCondition : DiagName = "pointer authentication scheme"; break; case PlatformConditionKind::HasAtomicBitWidth: DiagName = "has atomic bit width"; break; + case PlatformConditionKind::ObjectFileFormat: + DiagName = "object file format"; break; case PlatformConditionKind::Runtime: llvm_unreachable("handled above"); } diff --git a/test/Parse/ConditionalCompilation/object_file_format.swift b/test/Parse/ConditionalCompilation/object_file_format.swift new file mode 100644 index 0000000000000..3383107270582 --- /dev/null +++ b/test/Parse/ConditionalCompilation/object_file_format.swift @@ -0,0 +1,11 @@ +// RUN: %swift -typecheck %s -verify -target arm64-apple-none-macho -parse-stdlib +// RUN: %swift -typecheck %s -verify -target arm64-apple-none-elf -parse-stdlib +// RUN: %swift -typecheck %s -verify -target wasm32-unknown-wasi -parse-stdlib +// RUN: %swift -typecheck %s -verify -target x86_64-unknown-windows-msvc -parse-stdlib +// RUN: %swift-ide-test -test-input-complete -source-filename=%s -target arm64-apple-macos + +#if objectFormat(MachO) || objectFormat(ELF) || objectFormat(Wasm) || objectFormat(COFF) +class C {} +var x = C() +#endif +var y = x From 4923db8761b5528d6130888d421428bba2319784 Mon Sep 17 00:00:00 2001 From: Kuba Mracek Date: Wed, 22 Oct 2025 10:38:52 -0700 Subject: [PATCH 2/2] Adjust PlatformConditionKinds.def + target #objectFormat test more precisely --- include/swift/AST/PlatformConditionKinds.def | 2 +- .../object_file_format.swift | 55 ++++++++++++++++--- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/include/swift/AST/PlatformConditionKinds.def b/include/swift/AST/PlatformConditionKinds.def index 9c461f1bf13da..a5a95af283c9e 100644 --- a/include/swift/AST/PlatformConditionKinds.def +++ b/include/swift/AST/PlatformConditionKinds.def @@ -50,7 +50,7 @@ PLATFORM_CONDITION_(PtrAuth, "ptrauth") PLATFORM_CONDITION_(HasAtomicBitWidth, "hasAtomicBitWidth") /// The active target's file format (Mach-O, ELF, COFF, WASM) -PLATFORM_CONDITION_(ObjectFileFormat, "objectFormat") +PLATFORM_CONDITION(ObjectFileFormat, "objectFormat") #undef PLATFORM_CONDITION #undef PLATFORM_CONDITION_ diff --git a/test/Parse/ConditionalCompilation/object_file_format.swift b/test/Parse/ConditionalCompilation/object_file_format.swift index 3383107270582..997e41f17e83a 100644 --- a/test/Parse/ConditionalCompilation/object_file_format.swift +++ b/test/Parse/ConditionalCompilation/object_file_format.swift @@ -1,11 +1,48 @@ -// RUN: %swift -typecheck %s -verify -target arm64-apple-none-macho -parse-stdlib -// RUN: %swift -typecheck %s -verify -target arm64-apple-none-elf -parse-stdlib -// RUN: %swift -typecheck %s -verify -target wasm32-unknown-wasi -parse-stdlib -// RUN: %swift -typecheck %s -verify -target x86_64-unknown-windows-msvc -parse-stdlib -// RUN: %swift-ide-test -test-input-complete -source-filename=%s -target arm64-apple-macos +// RUN: %swift -typecheck %s -target arm64-apple-none-macho -parse-stdlib 2>&1 | %FileCheck -check-prefix CHECK-MACHO %s +// RUN: %swift -typecheck %s -target arm64-apple-none-elf -parse-stdlib 2>&1 | %FileCheck -check-prefix CHECK-ELF %s +// RUN: %swift -typecheck %s -target wasm32-unknown-wasi -parse-stdlib 2>&1 | %FileCheck -check-prefix CHECK-WASM %s +// RUN: %swift -typecheck %s -target x86_64-unknown-windows-msvc -parse-stdlib 2>&1 | %FileCheck -check-prefix CHECK-COFF %s -#if objectFormat(MachO) || objectFormat(ELF) || objectFormat(Wasm) || objectFormat(COFF) -class C {} -var x = C() +#if objectFormat(MachO) +#warning("I'm MachO") +#else +#warning("I'm not MachO") #endif -var y = x + +#if objectFormat(ELF) +#warning("I'm ELF") +#else +#warning("I'm not ELF") +#endif + +#if objectFormat(Wasm) +#warning("I'm Wasm") +#else +#warning("I'm not Wasm") +#endif + +#if objectFormat(COFF) +#warning("I'm COFF") +#else +#warning("I'm not COFF") +#endif + +// CHECK-MACHO: I'm MachO +// CHECK-MACHO: I'm not ELF +// CHECK-MACHO: I'm not Wasm +// CHECK-MACHO: I'm not COFF + +// CHECK-ELF: I'm not MachO +// CHECK-ELF: I'm ELF +// CHECK-ELF: I'm not Wasm +// CHECK-ELF: I'm not COFF + +// CHECK-WASM: I'm not MachO +// CHECK-WASM: I'm not ELF +// CHECK-WASM: I'm Wasm +// CHECK-WASM: I'm not COFF + +// CHECK-COFF: I'm not MachO +// CHECK-COFF: I'm not ELF +// CHECK-COFF: I'm not Wasm +// CHECK-COFF: I'm COFF