From: Joel Rosdahl Date: Wed, 21 Jul 2021 08:45:01 +0000 (+0200) Subject: Convert Sloppiness enum to type-safe class X-Git-Tag: v4.4~102 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c1735710741967dbc5a23c0fae8259a68a9e7160;p=thirdparty%2Fccache.git Convert Sloppiness enum to type-safe class --- diff --git a/src/Config.cpp b/src/Config.cpp index 48c05808b..6bf54c667 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -20,7 +20,6 @@ #include "AtomicFile.hpp" #include "MiniTrace.hpp" -#include "Sloppiness.hpp" #include "Util.hpp" #include "assertions.hpp" #include "fmtmacros.hpp" @@ -269,38 +268,38 @@ parse_compiler_type(const std::string& value) } } -uint32_t +core::Sloppiness parse_sloppiness(const std::string& value) { size_t start = 0; size_t end = 0; - uint32_t result = 0; + core::Sloppiness result; while (end != std::string::npos) { end = value.find_first_of(", ", start); std::string token = util::strip_whitespace(value.substr(start, end - start)); if (token == "file_stat_matches") { - result |= SLOPPY_FILE_STAT_MATCHES; + result.enable(core::Sloppy::file_stat_matches); } else if (token == "file_stat_matches_ctime") { - result |= SLOPPY_FILE_STAT_MATCHES_CTIME; + result.enable(core::Sloppy::file_stat_matches_ctime); } else if (token == "include_file_ctime") { - result |= SLOPPY_INCLUDE_FILE_CTIME; + result.enable(core::Sloppy::include_file_ctime); } else if (token == "include_file_mtime") { - result |= SLOPPY_INCLUDE_FILE_MTIME; + result.enable(core::Sloppy::include_file_mtime); } else if (token == "system_headers" || token == "no_system_headers") { - result |= SLOPPY_SYSTEM_HEADERS; + result.enable(core::Sloppy::system_headers); } else if (token == "pch_defines") { - result |= SLOPPY_PCH_DEFINES; + result.enable(core::Sloppy::pch_defines); } else if (token == "time_macros") { - result |= SLOPPY_TIME_MACROS; + result.enable(core::Sloppy::time_macros); } else if (token == "clang_index_store") { - result |= SLOPPY_CLANG_INDEX_STORE; + result.enable(core::Sloppy::clang_index_store); } else if (token == "locale") { - result |= SLOPPY_LOCALE; + result.enable(core::Sloppy::locale); } else if (token == "modules") { - result |= SLOPPY_MODULES; + result.enable(core::Sloppy::modules); } else if (token == "ivfsoverlay") { - result |= SLOPPY_IVFSOVERLAY; + result.enable(core::Sloppy::ivfsoverlay); } // else: ignore unknown value for forward compatibility start = value.find_first_not_of(", ", end); } @@ -308,40 +307,40 @@ parse_sloppiness(const std::string& value) } std::string -format_sloppiness(uint32_t sloppiness) +format_sloppiness(core::Sloppiness sloppiness) { std::string result; - if (sloppiness & SLOPPY_INCLUDE_FILE_MTIME) { + if (sloppiness.is_enabled(core::Sloppy::include_file_mtime)) { result += "include_file_mtime, "; } - if (sloppiness & SLOPPY_INCLUDE_FILE_CTIME) { + if (sloppiness.is_enabled(core::Sloppy::include_file_ctime)) { result += "include_file_ctime, "; } - if (sloppiness & SLOPPY_TIME_MACROS) { + if (sloppiness.is_enabled(core::Sloppy::time_macros)) { result += "time_macros, "; } - if (sloppiness & SLOPPY_PCH_DEFINES) { + if (sloppiness.is_enabled(core::Sloppy::pch_defines)) { result += "pch_defines, "; } - if (sloppiness & SLOPPY_FILE_STAT_MATCHES) { + if (sloppiness.is_enabled(core::Sloppy::file_stat_matches)) { result += "file_stat_matches, "; } - if (sloppiness & SLOPPY_FILE_STAT_MATCHES_CTIME) { + if (sloppiness.is_enabled(core::Sloppy::file_stat_matches_ctime)) { result += "file_stat_matches_ctime, "; } - if (sloppiness & SLOPPY_SYSTEM_HEADERS) { + if (sloppiness.is_enabled(core::Sloppy::system_headers)) { result += "system_headers, "; } - if (sloppiness & SLOPPY_CLANG_INDEX_STORE) { + if (sloppiness.is_enabled(core::Sloppy::clang_index_store)) { result += "clang_index_store, "; } - if (sloppiness & SLOPPY_LOCALE) { + if (sloppiness.is_enabled(core::Sloppy::locale)) { result += "locale, "; } - if (sloppiness & SLOPPY_MODULES) { + if (sloppiness.is_enabled(core::Sloppy::modules)) { result += "modules, "; } - if (sloppiness & SLOPPY_IVFSOVERLAY) { + if (sloppiness.is_enabled(core::Sloppy::ivfsoverlay)) { result += "ivfsoverlay, "; } if (!result.empty()) { diff --git a/src/Config.hpp b/src/Config.hpp index acc4638ef..053ee7547 100644 --- a/src/Config.hpp +++ b/src/Config.hpp @@ -21,6 +21,8 @@ #include "NonCopyable.hpp" #include "Util.hpp" +#include + #include "third_party/nonstd/optional.hpp" #include @@ -75,7 +77,7 @@ public: bool recache() const; bool run_second_cpp() const; const std::string& secondary_storage() const; - uint32_t sloppiness() const; + core::Sloppiness sloppiness() const; bool stats() const; const std::string& stats_log() const; const std::string& temporary_dir() const; @@ -169,7 +171,7 @@ private: bool m_recache = false; bool m_run_second_cpp = true; std::string m_secondary_storage; - uint32_t m_sloppiness = 0; + core::Sloppiness m_sloppiness; bool m_stats = true; std::string m_stats_log; std::string m_temporary_dir; @@ -398,7 +400,7 @@ Config::secondary_storage() const return m_secondary_storage; } -inline uint32_t +inline core::Sloppiness Config::sloppiness() const { return m_sloppiness; diff --git a/src/Context.hpp b/src/Context.hpp index d0a7e8f45..96cf134c9 100644 --- a/src/Context.hpp +++ b/src/Context.hpp @@ -26,7 +26,6 @@ #include "File.hpp" #include "MiniTrace.hpp" #include "NonCopyable.hpp" -#include "Sloppiness.hpp" #ifdef INODE_CACHE_SUPPORTED # include "InodeCache.hpp" diff --git a/src/Manifest.cpp b/src/Manifest.cpp index c27416d35..d5e8a3b55 100644 --- a/src/Manifest.cpp +++ b/src/Manifest.cpp @@ -28,7 +28,6 @@ #include "File.hpp" #include "Hash.hpp" #include "Logging.hpp" -#include "Sloppiness.hpp" #include "fmtmacros.hpp" #include "hashutil.hpp" @@ -453,8 +452,9 @@ verify_result(const Context& ctx, return false; } - if (ctx.config.sloppiness() & SLOPPY_FILE_STAT_MATCHES) { - if (!(ctx.config.sloppiness() & SLOPPY_FILE_STAT_MATCHES_CTIME)) { + if (ctx.config.sloppiness().is_enabled(core::Sloppy::file_stat_matches)) { + if (!(ctx.config.sloppiness().is_enabled( + core::Sloppy::file_stat_matches_ctime))) { if (fi.mtime == fs.mtime && fi.ctime == fs.ctime) { LOG("mtime/ctime hit for {}", path); continue; diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index 9fcdb041a..a52a4f6a1 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -242,7 +242,7 @@ process_arg(Context& ctx, // Ignore clang -ivfsoverlay to not detect multiple input files. if (args[i] == "-ivfsoverlay" - && !(config.sloppiness() & SLOPPY_IVFSOVERLAY)) { + && !(config.sloppiness().is_enabled(core::Sloppy::ivfsoverlay))) { LOG_RAW( "You have to specify \"ivfsoverlay\" sloppiness when using" " -ivfsoverlay to get hits"); @@ -387,7 +387,7 @@ process_arg(Context& ctx, LOG("Compiler option {} is unsupported without direct depend mode", args[i]); return Statistic::could_not_use_modules; - } else if (!(config.sloppiness() & SLOPPY_MODULES)) { + } else if (!(config.sloppiness().is_enabled(core::Sloppy::modules))) { LOG_RAW( "You have to specify \"modules\" sloppiness when using" " -fmodules to get hits"); @@ -788,7 +788,7 @@ process_arg(Context& ctx, return nullopt; } - if (config.sloppiness() & SLOPPY_CLANG_INDEX_STORE + if (config.sloppiness().is_enabled(core::Sloppy::clang_index_store) && args[i] == "-index-store-path") { // Xcode 9 or later calls Clang with this option. The given path includes a // UUID that might lead to cache misses, especially when cache is shared @@ -1059,7 +1059,7 @@ process_args(Context& ctx) if (state.found_pch || state.found_fpch_preprocess) { args_info.using_precompiled_header = true; - if (!(config.sloppiness() & SLOPPY_TIME_MACROS)) { + if (!(config.sloppiness().is_enabled(core::Sloppy::time_macros))) { LOG_RAW( "You have to specify \"time_macros\" sloppiness when using" " precompiled headers to get direct hits"); @@ -1095,7 +1095,7 @@ process_args(Context& ctx) } if (args_info.output_is_precompiled_header - && !(config.sloppiness() & SLOPPY_PCH_DEFINES)) { + && !(config.sloppiness().is_enabled(core::Sloppy::pch_defines))) { LOG_RAW( "You have to specify \"pch_defines,time_macros\" sloppiness when" " creating precompiled headers"); diff --git a/src/ccache.cpp b/src/ccache.cpp index 2aba2e292..e1803916a 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -320,14 +320,14 @@ include_file_too_new(const Context& ctx, // The comparison using >= is intentional, due to a possible race between // starting compilation and writing the include file. See also the notes under // "Performance" in doc/MANUAL.adoc. - if (!(ctx.config.sloppiness() & SLOPPY_INCLUDE_FILE_MTIME) + if (!(ctx.config.sloppiness().is_enabled(core::Sloppy::include_file_mtime)) && path_stat.mtime() >= ctx.time_of_compilation) { LOG("Include file {} too new", path); return true; } // The same >= logic as above applies to the change time of the file. - if (!(ctx.config.sloppiness() & SLOPPY_INCLUDE_FILE_CTIME) + if (!(ctx.config.sloppiness().is_enabled(core::Sloppy::include_file_ctime)) && path_stat.ctime() >= ctx.time_of_compilation) { LOG("Include file {} ctime too new", path); return true; @@ -356,7 +356,8 @@ do_remember_include_file(Context& ctx, return true; } - if (system && (ctx.config.sloppiness() & SLOPPY_SYSTEM_HEADERS)) { + if (system + && (ctx.config.sloppiness().is_enabled(core::Sloppy::system_headers))) { // Don't remember this system header. return true; } @@ -801,7 +802,7 @@ update_manifest_file(Context& ctx, // See comment in get_file_hash_index for why saving of timestamps is forced // for precompiled headers. const bool save_timestamp = - (ctx.config.sloppiness() & SLOPPY_FILE_STAT_MATCHES) + (ctx.config.sloppiness().is_enabled(core::Sloppy::file_stat_matches)) || ctx.args_info.output_is_precompiled_header; ctx.storage.put( @@ -1296,7 +1297,7 @@ hash_common_info(const Context& ctx, } } - if (!(ctx.config.sloppiness() & SLOPPY_LOCALE)) { + if (!(ctx.config.sloppiness().is_enabled(core::Sloppy::locale))) { // Hash environment variables that may affect localization of compiler // warning messages. const char* envvars[] = { diff --git a/src/Sloppiness.hpp b/src/core/Sloppiness.hpp similarity index 52% rename from src/Sloppiness.hpp rename to src/core/Sloppiness.hpp index 62c0508a8..a1aa9564d 100644 --- a/src/Sloppiness.hpp +++ b/src/core/Sloppiness.hpp @@ -18,26 +18,78 @@ #pragma once -enum Sloppiness { - SLOPPY_INCLUDE_FILE_MTIME = 1 << 0, - SLOPPY_INCLUDE_FILE_CTIME = 1 << 1, - SLOPPY_TIME_MACROS = 1 << 2, - SLOPPY_PCH_DEFINES = 1 << 3, +#include + +namespace core { + +enum class Sloppy : uint32_t { + none = 0u, + + include_file_mtime = 1u << 0, + include_file_ctime = 1u << 1, + time_macros = 1u << 2, + pch_defines = 1u << 3, // Allow us to match files based on their stats (size, mtime, ctime), without // looking at their contents. - SLOPPY_FILE_STAT_MATCHES = 1 << 4, + file_stat_matches = 1u << 4, // Allow us to not include any system headers in the manifest include files, // similar to -MM versus -M for dependencies. - SLOPPY_SYSTEM_HEADERS = 1 << 5, + system_headers = 1u << 5, // Allow us to ignore ctimes when comparing file stats, so we can fake mtimes // if we want to (it is much harder to fake ctimes, requires changing clock) - SLOPPY_FILE_STAT_MATCHES_CTIME = 1 << 6, + file_stat_matches_ctime = 1u << 6, // Allow us to not include the -index-store-path option in the manifest hash. - SLOPPY_CLANG_INDEX_STORE = 1 << 7, + clang_index_store = 1u << 7, // Ignore locale settings. - SLOPPY_LOCALE = 1 << 8, + locale = 1u << 8, // Allow caching even if -fmodules is used. - SLOPPY_MODULES = 1 << 9, + modules = 1u << 9, // Ignore virtual file system (VFS) overlay file. - SLOPPY_IVFSOVERLAY = 1 << 10, + ivfsoverlay = 1u << 10, +}; + +class Sloppiness +{ +public: + Sloppiness(Sloppy value = Sloppy::none); + explicit Sloppiness(uint32_t value); + + void enable(Sloppy value); + bool is_enabled(Sloppy value) const; + uint32_t to_bitmask() const; + +private: + Sloppy m_sloppiness = Sloppy::none; }; + +// --- Inline implementations --- + +inline Sloppiness::Sloppiness(Sloppy value) : m_sloppiness(value) +{ +} + +inline Sloppiness::Sloppiness(uint32_t value) + : m_sloppiness(static_cast(value)) +{ +} + +inline void +Sloppiness::enable(Sloppy value) +{ + m_sloppiness = static_cast(static_cast(m_sloppiness) + | static_cast(value)); +} + +inline bool +Sloppiness::is_enabled(Sloppy value) const +{ + return static_cast(m_sloppiness) & static_cast(value); +} + +inline uint32_t +Sloppiness::to_bitmask() const +{ + return static_cast(m_sloppiness); +} + +} // namespace core diff --git a/src/core/types.hpp b/src/core/types.hpp index 7cd53da0a..d4fbf6659 100644 --- a/src/core/types.hpp +++ b/src/core/types.hpp @@ -18,8 +18,6 @@ #pragma once -#include - namespace core { enum class CacheEntryType { result, manifest }; diff --git a/src/hashutil.cpp b/src/hashutil.cpp index 03d2e748e..9e30cd019 100644 --- a/src/hashutil.cpp +++ b/src/hashutil.cpp @@ -23,7 +23,6 @@ #include "Context.hpp" #include "Hash.hpp" #include "Logging.hpp" -#include "Sloppiness.hpp" #include "Stat.hpp" #include "Util.hpp" #include "Win32Util.hpp" @@ -205,7 +204,7 @@ get_content_type(const Config& config, const std::string& path) if (Util::is_precompiled_header(path)) { return InodeCache::ContentType::precompiled_header; } - if (config.sloppiness() & SLOPPY_TIME_MACROS) { + if (config.sloppiness().is_enabled(core::Sloppy::time_macros)) { return InodeCache::ContentType::code_with_sloppy_time_macros; } return InodeCache::ContentType::code; @@ -235,7 +234,7 @@ hash_source_code_string(const Context& ctx, // Check for __DATE__, __TIME__ and __TIMESTAMP__if the sloppiness // configuration tells us we should. - if (!(ctx.config.sloppiness() & SLOPPY_TIME_MACROS)) { + if (!(ctx.config.sloppiness().is_enabled(core::Sloppy::time_macros))) { result |= check_for_temporal_macros(str); } diff --git a/unittest/test_Config.cpp b/unittest/test_Config.cpp index 010f22565..ab1ed2003 100644 --- a/unittest/test_Config.cpp +++ b/unittest/test_Config.cpp @@ -17,7 +17,6 @@ // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "../src/Config.hpp" -#include "../src/Sloppiness.hpp" #include "../src/Util.hpp" #include "../src/fmtmacros.hpp" #include "TestUtil.hpp" @@ -72,7 +71,7 @@ TEST_CASE("Config: default values") CHECK_FALSE(config.read_only_direct()); CHECK_FALSE(config.recache()); CHECK(config.run_second_cpp()); - CHECK(config.sloppiness() == 0); + CHECK(config.sloppiness().to_bitmask() == 0); CHECK(config.stats()); CHECK(config.temporary_dir().empty()); // Set later CHECK(config.umask() == nonstd::nullopt); @@ -166,12 +165,16 @@ TEST_CASE("Config::update_from_file") CHECK(config.read_only_direct()); CHECK(config.recache()); CHECK_FALSE(config.run_second_cpp()); - CHECK(config.sloppiness() - == (SLOPPY_INCLUDE_FILE_MTIME | SLOPPY_INCLUDE_FILE_CTIME - | SLOPPY_TIME_MACROS | SLOPPY_FILE_STAT_MATCHES - | SLOPPY_FILE_STAT_MATCHES_CTIME | SLOPPY_SYSTEM_HEADERS - | SLOPPY_PCH_DEFINES | SLOPPY_CLANG_INDEX_STORE - | SLOPPY_IVFSOVERLAY)); + CHECK(config.sloppiness().to_bitmask() + == (static_cast(core::Sloppy::include_file_mtime) + | static_cast(core::Sloppy::include_file_ctime) + | static_cast(core::Sloppy::time_macros) + | static_cast(core::Sloppy::file_stat_matches) + | static_cast(core::Sloppy::file_stat_matches_ctime) + | static_cast(core::Sloppy::system_headers) + | static_cast(core::Sloppy::pch_defines) + | static_cast(core::Sloppy::clang_index_store) + | static_cast(core::Sloppy::ivfsoverlay))); CHECK_FALSE(config.stats()); CHECK(config.temporary_dir() == FMT("{}_foo", user)); CHECK(config.umask() == 0777u); @@ -235,7 +238,8 @@ TEST_CASE("Config::update_from_file, error handling") { Util::write_file("ccache.conf", "sloppiness = time_macros, foo"); CHECK(config.update_from_file("ccache.conf")); - CHECK(config.sloppiness() == SLOPPY_TIME_MACROS); + CHECK(config.sloppiness().to_bitmask() + == static_cast(core::Sloppy::time_macros)); } SUBCASE("invalid unsigned") diff --git a/unittest/test_ccache.cpp b/unittest/test_ccache.cpp index a09a316e7..e465a97c5 100644 --- a/unittest/test_ccache.cpp +++ b/unittest/test_ccache.cpp @@ -17,7 +17,6 @@ // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "../src/Context.hpp" -#include "../src/Sloppiness.hpp" #include "../src/ccache.hpp" #include "../src/fmtmacros.hpp" #include "TestUtil.hpp"