Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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")
Copy link
Member

Choose a reason for hiding this comment

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

No need for the underscore here?


#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");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add an else clause here that diagnoses the target is unknown? That way if we add a new port, we'll know to update this code.


// 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
11 changes: 11 additions & 0 deletions test/Parse/ConditionalCompilation/object_file_format.swift
Original file line number Diff line number Diff line change
@@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be good to have this check each one separately and somehow have each RUN line check that it selected the right one. This would detect it if someone managed to accidentally make it always be true or always false.

class C {}
var x = C()
#endif
var y = x