From 42f588f39c5ce6f521e3709b8871d1fdd076292f Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Thu, 15 Jul 2021 23:52:44 +0000 Subject: Use ManagedStatic and lazy initialization of cl::opt in libSupport to make it free of global initializer We can build it with -Werror=global-constructors now. This helps in situation where libSupport is embedded as a shared library, potential with dlopen/dlclose scenario, and when command-line parsing or other facilities may not be involved. Avoiding the implicit construction of these cl::opt can avoid double-registration issues and other kind of behavior. Reviewed By: lattner, jpienaar Differential Revision: https://reviews.llvm.org/D105959 --- llvm/lib/Support/Debug.cpp | 73 +++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 21 deletions(-) (limited to 'llvm/lib/Support/Debug.cpp') diff --git a/llvm/lib/Support/Debug.cpp b/llvm/lib/Support/Debug.cpp index 19b40ab..b48045c 100644 --- a/llvm/lib/Support/Debug.cpp +++ b/llvm/lib/Support/Debug.cpp @@ -30,6 +30,8 @@ #include "llvm/Support/circular_raw_ostream.h" #include "llvm/Support/raw_ostream.h" +#include "DebugOptions.h" + #undef isCurrentDebugType #undef setCurrentDebugType #undef setCurrentDebugTypes @@ -79,21 +81,32 @@ void setCurrentDebugTypes(const char **Types, unsigned Count) { // All Debug.h functionality is a no-op in NDEBUG mode. #ifndef NDEBUG -// -debug - Command line option to enable the DEBUG statements in the passes. -// This flag may only be enabled in debug builds. -static cl::opt -Debug("debug", cl::desc("Enable debug output"), cl::Hidden, - cl::location(DebugFlag)); +namespace { +struct CreateDebug { + static void *call() { + return new cl::opt("debug", cl::desc("Enable debug output"), + cl::Hidden, cl::location(DebugFlag)); + } +}; // -debug-buffer-size - Buffer the last N characters of debug output //until program termination. -static cl::opt -DebugBufferSize("debug-buffer-size", - cl::desc("Buffer the last N characters of debug output " - "until program termination. " - "[default 0 -- immediate print-out]"), - cl::Hidden, - cl::init(0)); +struct CreateDebugBufferSize { + static void *call() { + return new cl::opt( + "debug-buffer-size", + cl::desc("Buffer the last N characters of debug output " + "until program termination. " + "[default 0 -- immediate print-out]"), + cl::Hidden, cl::init(0)); + } +}; +} // namespace + +// -debug - Command line option to enable the DEBUG statements in the passes. +// This flag may only be enabled in debug builds. +static ManagedStatic, CreateDebug> Debug; +static ManagedStatic, CreateDebugBufferSize> DebugBufferSize; namespace { @@ -108,15 +121,33 @@ struct DebugOnlyOpt { CurrentDebugType->push_back(std::string(dbgType)); } }; - } // namespace static DebugOnlyOpt DebugOnlyOptLoc; -static cl::opt > -DebugOnly("debug-only", cl::desc("Enable a specific type of debug output (comma separated list of types)"), - cl::Hidden, cl::ZeroOrMore, cl::value_desc("debug string"), - cl::location(DebugOnlyOptLoc), cl::ValueRequired); +namespace { +struct CreateDebugOnly { + static void *call() { + return new cl::opt>( + "debug-only", + cl::desc("Enable a specific type of debug output (comma separated list " + "of types)"), + cl::Hidden, cl::ZeroOrMore, cl::value_desc("debug string"), + cl::location(DebugOnlyOptLoc), cl::ValueRequired); + } +}; +} // namespace + +static ManagedStatic>, + CreateDebugOnly> + DebugOnly; + +void llvm::initDebugOptions() { + *Debug; + *DebugBufferSize; + *DebugOnly; +} + // Signal handlers - dump debug output on termination. static void debug_user_sig_handler(void *Cookie) { // This is a bit sneaky. Since this is under #ifndef NDEBUG, we @@ -134,10 +165,10 @@ raw_ostream &llvm::dbgs() { static struct dbgstream { circular_raw_ostream strm; - dbgstream() : - strm(errs(), "*** Debug Log Output ***\n", - (!EnableDebugBuffering || !DebugFlag) ? 0 : DebugBufferSize) { - if (EnableDebugBuffering && DebugFlag && DebugBufferSize != 0) + dbgstream() + : strm(errs(), "*** Debug Log Output ***\n", + (!EnableDebugBuffering || !DebugFlag) ? 0 : *DebugBufferSize) { + if (EnableDebugBuffering && DebugFlag && *DebugBufferSize != 0) // TODO: Add a handler for SIGUSER1-type signals so the user can // force a debug dump. sys::AddSignalHandler(&debug_user_sig_handler, nullptr); -- cgit v1.1