Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/swift/AST/PlatformConditionKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -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_
4 changes: 4 additions & 0 deletions lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ struct CompilerBuildConfiguration: BuildConfiguration {
staticBuildConfiguration.targetPointerBitWidth
}

func isActiveTargetObjectFormat(name: String) throws -> Bool {
try staticBuildConfiguration.isActiveTargetObjectFormat(name: name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't really matter, but I would expect this never to throw, because it's just querying the static build configuration

}

var targetAtomicBitWidths: [Int] {
staticBuildConfiguration.targetAtomicBitWidths
}
Expand Down
4 changes: 4 additions & 0 deletions lib/ASTGen/Sources/ASTGen/EmbeddedSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
31 changes: 26 additions & 5 deletions lib/Basic/LangOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<SupportedConditionalValue> getSupportedConditionalCompilationValues(const PlatformConditionKind &Kind) {
static ArrayRef<SupportedConditionalValue> getSupportedConditionalCompilationValues(const PlatformConditionKind &Kind) {
switch (Kind) {
case PlatformConditionKind::OS:
return SupportedConditionalCompilationOSs;
Expand All @@ -167,12 +174,14 @@ ArrayRef<SupportedConditionalValue> 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<StringRef> &suggestedValues) {
static PlatformConditionKind suggestedPlatformConditionKind(PlatformConditionKind Kind, const StringRef &V,
std::vector<StringRef> &suggestedValues) {
std::string lower = V.lower();
for (const PlatformConditionKind& candidateKind : AllPublicPlatformConditionKinds) {
if (candidateKind != Kind) {
Expand All @@ -191,8 +200,8 @@ PlatformConditionKind suggestedPlatformConditionKind(PlatformConditionKind Kind,
return Kind;
}

bool isMatching(PlatformConditionKind Kind, const StringRef &V,
PlatformConditionKind &suggestedKind, std::vector<StringRef> &suggestions) {
static bool isMatching(PlatformConditionKind Kind, const StringRef &V,
PlatformConditionKind &suggestedKind, std::vector<StringRef> &suggestions) {
// Compare against known values, ignoring case to avoid penalizing
// characters with incorrect case.
unsigned minDistance = std::numeric_limits<unsigned>::max();
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -649,6 +659,17 @@ std::pair<bool, bool> 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");
Expand Down
1 change: 1 addition & 0 deletions lib/Basic/LangOptionsBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ void BridgedLangOptions_enumerateBuildConfigurationEntries(

case PlatformConditionKind::Endianness:
case PlatformConditionKind::PointerBitWidth:
case PlatformConditionKind::ObjectFileFormat:
case PlatformConditionKind::CanImport:
case PlatformConditionKind::HasAtomicBitWidth:
// Handled separately.
Expand Down
4 changes: 3 additions & 1 deletion lib/Parse/ParseIfConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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");
}
Expand Down
48 changes: 48 additions & 0 deletions test/Parse/ConditionalCompilation/object_file_format.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// 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)
#warning("I'm MachO")
#else
#warning("I'm not MachO")
#endif

#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