mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Add support for an assert_configuration builtin function
This patch adds support for a builtin function assert_configuration that is
replaced by constant progpagation by an appropriate value dependent on a compile
time setting. This replacement can also be disabled when serializing sil for a
library.
Using this mechanism we implement assertions that can be disabled (or whose
behavior changes) depending on compile time build settings (Debug, Release,
DisableReplacement).
In the standard library we can now write one assert function that uses this
builtin function to provide different compile time selectable runtime behavior.
Example
Assert.swift:
@transparent
func assert<T : LogicValue>(
condition: @auto_closure () -> T, message: StaticString = StaticString(),
// Do not supply these parameters explicitly; they will be filled in
// by the compiler and aren't even present when asserts are disabled
file: StaticString = __FILE__, line: UWord = __LINE__
) {
// Only in debug mode.
if _isDebug() {
assert(condition().getLogicValue(), message, file, line)
}
}
AssertCommon.swift:
@transparent
func _isDebug() -> Bool {
return Int32(Builtin.assert_configuration()) == 0;
}
rdar://16458612
Swift SVN r16472
This commit is contained in:
@@ -640,6 +640,7 @@ static void PrintArg(raw_ostream &OS, const char *Arg, bool Quote) {
|
||||
}
|
||||
|
||||
static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
|
||||
IRGenOptions &IRGenOpts,
|
||||
DiagnosticEngine &Diags) {
|
||||
using namespace options;
|
||||
|
||||
@@ -675,7 +676,54 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
|
||||
llvm_unreachable("Unknown SIL linking option!");
|
||||
}
|
||||
|
||||
Opts.RemoveRuntimeAsserts = Args.hasArg(OPT_remove_runtime_asserts);
|
||||
// Parse the optimization level.
|
||||
if (const Arg *A = Args.getLastArg(OPT_O_Group)) {
|
||||
// The maximum optimization level we currently support.
|
||||
unsigned MaxLevel = 3;
|
||||
|
||||
if (A->getOption().matches(OPT_O0)) {
|
||||
IRGenOpts.OptLevel = 0;
|
||||
} else {
|
||||
unsigned OptLevel;
|
||||
if (StringRef(A->getValue()).getAsInteger(10, OptLevel) ||
|
||||
OptLevel > MaxLevel) {
|
||||
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
|
||||
A->getAsString(Args), A->getValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
IRGenOpts.OptLevel = OptLevel;
|
||||
}
|
||||
} else {
|
||||
IRGenOpts.OptLevel = 0;
|
||||
}
|
||||
|
||||
// Parse the build configuration identifier.
|
||||
if (const Arg *A = Args.getLastArg(OPT_AssertConfig_Group)) {
|
||||
// We currently understand build configuration up to 3 of which we only use
|
||||
// 0 and 1 in the standard library.
|
||||
unsigned MaxId = 3;
|
||||
StringRef Configuration = A->getValue();
|
||||
if (Configuration == "DisableReplacement") {
|
||||
Opts.AssertConfig = SILOptions::DisableReplacement;
|
||||
} else if (Configuration == "Debug") {
|
||||
Opts.AssertConfig = SILOptions::Debug;
|
||||
} else if (Configuration == "Release") {
|
||||
Opts.AssertConfig = SILOptions::Release;
|
||||
} else {
|
||||
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
|
||||
A->getAsString(Args), A->getValue());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Set the assert configuration according to the optimization level.
|
||||
Opts.AssertConfig =
|
||||
IRGenOpts.OptLevel > 0 ? SILOptions::Release : SILOptions::Debug;
|
||||
}
|
||||
|
||||
// OFast might also set removal of runtime asserts (cond_fail).
|
||||
Opts.RemoveRuntimeAsserts |= Args.hasArg(OPT_remove_runtime_asserts);
|
||||
|
||||
Opts.EnableARCOptimizations = !Args.hasArg(OPT_disable_arc_opts);
|
||||
Opts.VerifyAll = Args.hasArg(OPT_sil_verify_all);
|
||||
Opts.PrintAll = Args.hasArg(OPT_sil_print_all);
|
||||
@@ -746,24 +794,6 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
|
||||
Opts.LinkLibraries.push_back(LinkLibrary(A->getValue(), Kind));
|
||||
}
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_O_Group)) {
|
||||
if (A->getOption().matches(OPT_O0)) {
|
||||
Opts.OptLevel = 0;
|
||||
}
|
||||
else {
|
||||
unsigned OptLevel;
|
||||
if (StringRef(A->getValue()).getAsInteger(10, OptLevel) || OptLevel > 3) {
|
||||
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
|
||||
A->getAsString(Args), A->getValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
Opts.OptLevel = OptLevel;
|
||||
}
|
||||
} else {
|
||||
Opts.OptLevel = 0;
|
||||
}
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_target_cpu)) {
|
||||
Opts.TargetCPU = A->getValue();
|
||||
}
|
||||
@@ -849,7 +879,7 @@ bool CompilerInvocation::parseArgs(ArrayRef<const char *> Args,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ParseSILArgs(SILOpts, *ParsedArgs, Diags)) {
|
||||
if (ParseSILArgs(SILOpts, *ParsedArgs, IRGenOpts, Diags)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user