#endif
str->append("<no_string_conversion>)");
}
-}
+} // namespace detail
template <bool IsInHeaderFile>
class XlogCategoryInfo;
AppendType) noexcept;
/**
- * LogStreamProcessor constructors for use with XLOG() macros with no extra
- * arguments.
+ * LogStreamProcessor constructor for use with a LOG() macro with arguments
+ * to be concatenated with folly::to<std::string>()
*
- * These are defined separately from the above constructor so that the work
- * of initializing the XLOG LogCategory data is done in a separate function
- * body defined in LogStreamProcessor.cpp. We intentionally want to avoid
- * inlining this work at every XLOG() statement, to reduce the emitted code
- * size.
+ * Note that the filename argument is not copied. The caller should ensure
+ * that it points to storage that will remain valid for the lifetime of the
+ * LogStreamProcessor. (This is always the case for the __FILE__
+ * preprocessor macro.)
*/
+ template <typename... Args>
LogStreamProcessor(
- XlogCategoryInfo<true>* categoryInfo,
- LogLevel level,
- folly::StringPiece categoryName,
- bool isCategoryNameOverridden,
- folly::StringPiece filename,
- unsigned int lineNumber,
- AppendType) noexcept;
- LogStreamProcessor(
- XlogFileScopeInfo* fileScopeInfo,
- LogLevel level,
- folly::StringPiece filename,
- unsigned int lineNumber,
- AppendType) noexcept;
- LogStreamProcessor(
- XlogFileScopeInfo* fileScopeInfo,
+ const LogCategory* category,
LogLevel level,
- folly::StringPiece /* categoryName */,
- bool /* isCategoryNameOverridden */,
folly::StringPiece filename,
unsigned int lineNumber,
- AppendType) noexcept
- : LogStreamProcessor(fileScopeInfo, level, filename, lineNumber, APPEND) {
- }
+ AppendType,
+ Args&&... args) noexcept
+ : LogStreamProcessor(
+ category,
+ level,
+ filename,
+ lineNumber,
+ INTERNAL,
+ createLogString(std::forward<Args>(args)...)) {}
/**
* LogStreamProcessor constructor for use with a LOG() macro with arguments
LogLevel level,
folly::StringPiece filename,
unsigned int lineNumber,
- AppendType,
+ FormatType,
+ folly::StringPiece fmt,
Args&&... args) noexcept
: LogStreamProcessor(
category,
filename,
lineNumber,
INTERNAL,
- createLogString(std::forward<Args>(args)...)) {}
+ formatLogString(fmt, std::forward<Args>(args)...)) {}
- /**
- * Versions of the above constructor for use in XLOG() statements.
+ /*
+ * Versions of the above constructors for use in XLOG() statements.
+ *
+ * These are defined separately from the above constructor so that the work
+ * of initializing the XLOG LogCategory data is done in a separate function
+ * body defined in LogStreamProcessor.cpp. We intentionally want to avoid
+ * inlining this work at every XLOG() statement, to reduce the emitted code
+ * size.
*/
+ LogStreamProcessor(
+ XlogCategoryInfo<true>* categoryInfo,
+ LogLevel level,
+ folly::StringPiece categoryName,
+ bool isCategoryNameOverridden,
+ folly::StringPiece filename,
+ unsigned int lineNumber,
+ AppendType) noexcept;
template <typename... Args>
LogStreamProcessor(
XlogCategoryInfo<true>* categoryInfo,
createLogString(std::forward<Args>(args)...)) {}
template <typename... Args>
LogStreamProcessor(
- XlogFileScopeInfo* fileScopeInfo,
+ XlogCategoryInfo<true>* categoryInfo,
LogLevel level,
- folly::StringPiece /* categoryName */,
- bool /* isCategoryNameOverridden */,
+ folly::StringPiece categoryName,
+ bool isCategoryNameOverridden,
folly::StringPiece filename,
unsigned int lineNumber,
- AppendType,
+ FormatType,
+ folly::StringPiece fmt,
Args&&... args) noexcept
: LogStreamProcessor(
- fileScopeInfo,
+ categoryInfo,
level,
+ categoryName,
+ isCategoryNameOverridden,
filename,
lineNumber,
INTERNAL,
- createLogString(std::forward<Args>(args)...)) {}
+ formatLogString(fmt, std::forward<Args>(args)...)) {}
- /**
- * LogStreamProcessor constructor for use with a LOG() macro with arguments
- * to be concatenated with folly::to<std::string>()
+#ifdef __INCLUDE_LEVEL__
+ /*
+ * Versions of the above constructors to use in XLOG() macros that appear in
+ * .cpp files. These are only used if the compiler supports the
+ * __INCLUDE_LEVEL__ macro, which we need to determine that the XLOG()
+ * statement is not in a header file.
*
- * Note that the filename argument is not copied. The caller should ensure
- * that it points to storage that will remain valid for the lifetime of the
- * LogStreamProcessor. (This is always the case for the __FILE__
- * preprocessor macro.)
+ * These behave identically to the XlogCategoryInfo<true> versions of the
+ * APIs, but slightly more optimized, and allow the XLOG() code to avoid
+ * storing category information at each XLOG() call site.
*/
- template <typename... Args>
LogStreamProcessor(
- const LogCategory* category,
+ XlogFileScopeInfo* fileScopeInfo,
LogLevel level,
folly::StringPiece filename,
unsigned int lineNumber,
- FormatType,
- folly::StringPiece fmt,
- Args&&... args) noexcept
- : LogStreamProcessor(
- category,
- level,
- filename,
- lineNumber,
- INTERNAL,
- formatLogString(fmt, std::forward<Args>(args)...)) {}
-
- /**
- * Versions of the above constructor for use in XLOG() statements.
- */
+ AppendType) noexcept;
+ LogStreamProcessor(
+ XlogFileScopeInfo* fileScopeInfo,
+ LogLevel level,
+ folly::StringPiece /* categoryName */,
+ bool /* isCategoryNameOverridden */,
+ folly::StringPiece filename,
+ unsigned int lineNumber,
+ AppendType) noexcept
+ : LogStreamProcessor(fileScopeInfo, level, filename, lineNumber, APPEND) {
+ }
template <typename... Args>
LogStreamProcessor(
- XlogCategoryInfo<true>* categoryInfo,
+ XlogFileScopeInfo* fileScopeInfo,
LogLevel level,
- folly::StringPiece categoryName,
- bool isCategoryNameOverridden,
+ folly::StringPiece /* categoryName */,
+ bool /* isCategoryNameOverridden */,
folly::StringPiece filename,
unsigned int lineNumber,
- FormatType,
- folly::StringPiece fmt,
+ AppendType,
Args&&... args) noexcept
: LogStreamProcessor(
- categoryInfo,
+ fileScopeInfo,
level,
- categoryName,
- isCategoryNameOverridden,
filename,
lineNumber,
INTERNAL,
- formatLogString(fmt, std::forward<Args>(args)...)) {}
-
+ createLogString(std::forward<Args>(args)...)) {}
template <typename... Args>
LogStreamProcessor(
XlogFileScopeInfo* fileScopeInfo,
lineNumber,
INTERNAL,
formatLogString(fmt, std::forward<Args>(args)...)) {}
+#endif
~LogStreamProcessor() noexcept;
*/
[[noreturn]] void operator&(std::ostream&);
};
-}
+
+/**
+ * logDisabledHelper() is invoked in FB_LOG() and XLOG() statements if the log
+ * admittance check fails.
+ *
+ * This function exists solely to ensure that both sides of the log check are
+ * marked [[noreturn]] for fatal log messages. This allows the compiler to
+ * recognize that the full statement is noreturn, preventing warnings about
+ * missing return statements after fatal log messages.
+ *
+ * Unfortunately it does not appear possible to get the compiler to recognize
+ * that the disabled side of the log statement should never be reached for
+ * fatal messages. Even if we make the check something like
+ * `(isLogLevelFatal(level) || realCheck)`, where isLogLevelFatal() is
+ * constexpr, this is not sufficient for gcc or clang to recognize that the
+ * full expression is noreturn.
+ *
+ * Ideally this would just be a template function specialized on a boolean
+ * IsFatal parameter. Unfortunately this triggers a bug in clang, which does
+ * not like differing noreturn behavior for different template instantiations.
+ * Therefore we overload on integral_constant instead.
+ *
+ * clang-format also doesn't do a good job understanding this code and figuring
+ * out how to format it.
+ */
+// clang-format off
+inline void logDisabledHelper(std::integral_constant<bool, false>) noexcept {}
+[[noreturn]] void logDisabledHelper(
+ std::integral_constant<bool, true>) noexcept;
+// clang-format on
+} // namespace folly