#include "AtomicFile.hpp"
#include "MiniTrace.hpp"
-#include "Sloppiness.hpp"
#include "Util.hpp"
#include "assertions.hpp"
#include "fmtmacros.hpp"
}
}
-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);
}
}
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()) {
#include "NonCopyable.hpp"
#include "Util.hpp"
+#include <core/Sloppiness.hpp>
+
#include "third_party/nonstd/optional.hpp"
#include <cstdint>
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;
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;
return m_secondary_storage;
}
-inline uint32_t
+inline core::Sloppiness
Config::sloppiness() const
{
return m_sloppiness;
#include "File.hpp"
#include "MiniTrace.hpp"
#include "NonCopyable.hpp"
-#include "Sloppiness.hpp"
#ifdef INODE_CACHE_SUPPORTED
# include "InodeCache.hpp"
#include "File.hpp"
#include "Hash.hpp"
#include "Logging.hpp"
-#include "Sloppiness.hpp"
#include "fmtmacros.hpp"
#include "hashutil.hpp"
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;
// Ignore clang -ivfsoverlay <arg> 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");
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");
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
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");
}
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");
// 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;
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;
}
// 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(
}
}
- 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[] = {
#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 <string>
+
+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<Sloppy>(value))
+{
+}
+
+inline void
+Sloppiness::enable(Sloppy value)
+{
+ m_sloppiness = static_cast<Sloppy>(static_cast<uint32_t>(m_sloppiness)
+ | static_cast<uint32_t>(value));
+}
+
+inline bool
+Sloppiness::is_enabled(Sloppy value) const
+{
+ return static_cast<uint32_t>(m_sloppiness) & static_cast<uint32_t>(value);
+}
+
+inline uint32_t
+Sloppiness::to_bitmask() const
+{
+ return static_cast<uint32_t>(m_sloppiness);
+}
+
+} // namespace core
#pragma once
-#include <string>
-
namespace core {
enum class CacheEntryType { result, manifest };
#include "Context.hpp"
#include "Hash.hpp"
#include "Logging.hpp"
-#include "Sloppiness.hpp"
#include "Stat.hpp"
#include "Util.hpp"
#include "Win32Util.hpp"
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;
// 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);
}
// 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"
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);
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<uint32_t>(core::Sloppy::include_file_mtime)
+ | static_cast<uint32_t>(core::Sloppy::include_file_ctime)
+ | static_cast<uint32_t>(core::Sloppy::time_macros)
+ | static_cast<uint32_t>(core::Sloppy::file_stat_matches)
+ | static_cast<uint32_t>(core::Sloppy::file_stat_matches_ctime)
+ | static_cast<uint32_t>(core::Sloppy::system_headers)
+ | static_cast<uint32_t>(core::Sloppy::pch_defines)
+ | static_cast<uint32_t>(core::Sloppy::clang_index_store)
+ | static_cast<uint32_t>(core::Sloppy::ivfsoverlay)));
CHECK_FALSE(config.stats());
CHECK(config.temporary_dir() == FMT("{}_foo", user));
CHECK(config.umask() == 0777u);
{
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<uint32_t>(core::Sloppy::time_macros));
}
SUBCASE("invalid unsigned")
// 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"