From 2ced972b9fcf344e339c9ac9dc3217ad7ee90174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Sun, 18 Feb 2018 14:26:52 +0100 Subject: [PATCH] Add missing missing file check --- src/libclang/preprocessor.cpp | 34 +++++++++++++++++++++++++++------- test/preprocessor.cpp | 13 ++++++++++--- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/libclang/preprocessor.cpp b/src/libclang/preprocessor.cpp index 797d0b7..9effa6f 100644 --- a/src/libclang/preprocessor.cpp +++ b/src/libclang/preprocessor.cpp @@ -393,13 +393,15 @@ namespace }; clang_preprocess_result clang_preprocess_impl(const libclang_compile_config& c, + const diagnostic_logger& logger, const std::string& full_path, const char* macro_path) { clang_preprocess_result result; std::string diagnostic; - auto diagnostic_handler = [&](const char* str, std::size_t n) { + auto expect_bad_exit_code = false; + auto diagnostic_handler = [&](const char* str, std::size_t n) { diagnostic.reserve(diagnostic.size() + n); for (auto end = str + n; str != end; ++str) if (*str == '\r') @@ -407,10 +409,19 @@ namespace else if (*str == '\n') { // handle current diagnostic - auto file = parse_missing_file(full_path, diagnostic); - if (file) - // save for clang without -dI flag - result.included_files.push_back(file.value()); + if (macro_path) + { + // hide diagnostics + + auto file = parse_missing_file(full_path, diagnostic); + if (file) + // save for clang without -dI flag + result.included_files.push_back(file.value()); + + expect_bad_exit_code = true; + } + else + log_diagnostic(logger, diagnostic); diagnostic.clear(); } @@ -430,7 +441,12 @@ namespace }, diagnostic_handler); // wait for process end - process.get_exit_status(); + auto exit_code = process.get_exit_status(); + DEBUG_ASSERT(diagnostic.empty(), detail::assert_handler{}); + if (exit_code != 0 && !expect_bad_exit_code) + throw libclang_error("preprocessor: command '" + cmd + + "' exited with non-zero exit code (" + std::to_string(exit_code) + + ")"); return result; } @@ -438,6 +454,10 @@ namespace clang_preprocess_result clang_preprocess(const libclang_compile_config& c, const char* full_path, const diagnostic_logger& logger) { + if (!std::ifstream(full_path)) + throw libclang_error("preprocessor: file '" + std::string(full_path) + + "' doesn't exist"); + // if we're fast preprocessing we only preprocess the main file, not includes // this is done by disabling all include search paths when doing the preprocessing // to allow macros a separate preprocessing with the -dM flag is done that extracts all macros @@ -449,7 +469,7 @@ namespace clang_preprocess_result result; try { - result = clang_preprocess_impl(c, full_path, + result = clang_preprocess_impl(c, logger, full_path, fast_preprocessing ? macro_file.c_str() : nullptr); } catch (...) diff --git a/test/preprocessor.cpp b/test/preprocessor.cpp index 7886878..5860644 100644 --- a/test/preprocessor.cpp +++ b/test/preprocessor.cpp @@ -77,9 +77,16 @@ struct foo {}; config.set_flags(cpp_standard::cpp_latest); config.fast_preprocessing(true); - auto result = detail::preprocess(config, file_name, default_logger().get()); - REQUIRE(result.macros.size() == 1u); - REQUIRE(result.macros[0].macro->name() == "INCLUDE_GUARD"); + try + { + auto result = detail::preprocess(config, file_name, default_logger().get()); + REQUIRE(result.macros.size() == 1u); + REQUIRE(result.macros[0].macro->name() == "INCLUDE_GUARD"); + } + catch (libclang_error& ex) + { + FAIL(ex.what()); + } } TEST_CASE("preprocessor line numbers")