diff options
| author | Lang Hames <lhames@gmail.com> | 2016-03-17 21:28:49 +0000 |
|---|---|---|
| committer | Lang Hames <lhames@gmail.com> | 2016-03-17 21:28:49 +0000 |
| commit | 6935c2d3227661bda111bdecae976a091b8307d8 (patch) | |
| tree | 936675c00ce2c608a996488e45ba4bda358108f2 /llvm/unittests/Support/ErrorTest.cpp | |
| parent | 016b2d0ddc4855a2e07161abd9ba6cdcebadd0c4 (diff) | |
| download | llvm-6935c2d3227661bda111bdecae976a091b8307d8.zip llvm-6935c2d3227661bda111bdecae976a091b8307d8.tar.gz llvm-6935c2d3227661bda111bdecae976a091b8307d8.tar.bz2 | |
[Support] Add ExitOnError utility to support tools that use the exit-on-error
idiom.
Most LLVM tool code exits immediately when an error is encountered and prints an
error message to stderr. The ExitOnError class supports this by providing two
call operators - one for Errors, and one for Expected<T>s. Calls to code that
can return Errors (or Expected<T>s) can use these calls to bail out on error,
and otherwise continue as if the operation had succeeded. E.g.
Error foo();
Expected<int> bar();
int main(int argc, char *argv[]) {
ExitOnError ExitOnErr;
ExitOnErr.setBanner(std::string("Error in ") + argv[0] + ":");
// Exit if foo returns an error. No need to manually check error return.
ExitOnErr(foo());
// Exit if bar returns an error, otherwise unwrap the contained int and
// continue.
int X = ExitOnErr(bar());
// ...
return 0;
}
llvm-svn: 263749
Diffstat (limited to 'llvm/unittests/Support/ErrorTest.cpp')
| -rw-r--r-- | llvm/unittests/Support/ErrorTest.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/unittests/Support/ErrorTest.cpp b/llvm/unittests/Support/ErrorTest.cpp index d5af2ca..343a2d2 100644 --- a/llvm/unittests/Support/ErrorTest.cpp +++ b/llvm/unittests/Support/ErrorTest.cpp @@ -38,6 +38,7 @@ namespace { // - consume_error to consume a "safe" error without any output. // - handleAllUnhandledErrors to assert that all errors are handled. // - logAllUnhandledErrors to log errors to a stream. +// - ExitOnError tests. // // Expected tests: // - Expected<T> with T. @@ -50,6 +51,7 @@ namespace { // - std::error_code to Error (ECError) in failure mode. // - Error to std::error_code in success mode. // - Error (ECError) to std::error_code in failure mode. +// // Custom error class with a default base class and some random 'info' attached. class CustomError : public ErrorInfo<CustomError> { @@ -376,6 +378,32 @@ TEST(Error, CheckErrorUtilities) { EXPECT_EQ(ErrorInfo, 7) << "Failed to handle Error returned from handleErrors."; } + + // Test ExitOnError + { + ExitOnError ExitOnErr; + ExitOnErr.setBanner("Error in tool:"); + ExitOnErr.setExitCodeMapper( + [](const Error &E) { + if (E.isA<CustomSubError>()) + return 2; + return 1; + }); + + // Make sure we don't bail on success. + ExitOnErr(Error::success()); + EXPECT_EQ(ExitOnErr(Expected<int>(7)), 7) + << "exitOnError returned an invalid value for Expected"; + + // Exit tests. + EXPECT_EXIT(ExitOnErr(make_error<CustomError>(7)), + ::testing::ExitedWithCode(1), "Error in tool:") + << "exitOnError returned an unexpected error result"; + + EXPECT_EXIT(ExitOnErr(Expected<int>(make_error<CustomSubError>(0, 0))), + ::testing::ExitedWithCode(2), "Error in tool:") + << "exitOnError returned an unexpected error result"; + } } // Test Expected behavior. |
