diff --git a/llvm/lib/Support/Debug.cpp b/llvm/lib/Support/Debug.cpp --- a/llvm/lib/Support/Debug.cpp +++ b/llvm/lib/Support/Debug.cpp @@ -25,7 +25,6 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Signals.h" #include "llvm/Support/circular_raw_ostream.h" #include "llvm/Support/raw_ostream.h" @@ -44,17 +43,20 @@ /// Exported boolean set by the -debug option. bool DebugFlag = false; -static ManagedStatic> CurrentDebugType; +static std::vector &getCurrentDebugType() { + static std::vector CurrentDebugType; + return CurrentDebugType; +} /// Return true if the specified string is the debug type /// specified on the command line, or if none was specified on the command line /// with the -debug-only=X option. bool isCurrentDebugType(const char *DebugType) { - if (CurrentDebugType->empty()) + if (getCurrentDebugType().empty()) return true; // See if DebugType is in list. Note: do not use find() as that forces us to // unnecessarily create an std::string instance. - for (auto &d : *CurrentDebugType) { + for (auto &d : getCurrentDebugType()) { if (d == DebugType) return true; } @@ -72,9 +74,9 @@ } void setCurrentDebugTypes(const char **Types, unsigned Count) { - CurrentDebugType->clear(); + getCurrentDebugType().clear(); for (size_t T = 0; T < Count; ++T) - CurrentDebugType->push_back(Types[T]); + getCurrentDebugType().push_back(Types[T]); } } // namespace llvm @@ -82,34 +84,6 @@ #ifndef NDEBUG 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. -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 { - struct DebugOnlyOpt { void operator=(const std::string &Val) const { if (Val.empty()) @@ -118,36 +92,41 @@ SmallVector dbgTypes; StringRef(Val).split(dbgTypes, ',', -1, false); for (auto dbgType : dbgTypes) - CurrentDebugType->push_back(std::string(dbgType)); + getCurrentDebugType().push_back(std::string(dbgType)); } }; -} // namespace - -static DebugOnlyOpt DebugOnlyOptLoc; -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::value_desc("debug string"), - cl::location(DebugOnlyOptLoc), cl::ValueRequired); - } +struct DebugOptions { + // -debug - Command line option to enable the DEBUG statements in the passes. + // This flag may only be enabled in debug builds. + cl::opt Debug{"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. + 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)}; + + cl::opt> DebugOnly{ + "debug-only", + cl::desc("Enable a specific type of debug output (comma separated list " + "of types)"), + cl::Hidden, cl::value_desc("debug string"), cl::ValueRequired}; }; -} // namespace - -static ManagedStatic>, - CreateDebugOnly> - DebugOnly; -void llvm::initDebugOptions() { - *Debug; - *DebugBufferSize; - *DebugOnly; +DebugOptions &getDebugOptions() { + static DebugOptions Opts; + return Opts; } +} // namespace + +void llvm::initDebugOptions() { getDebugOptions(); } + // 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 @@ -167,8 +146,11 @@ dbgstream() : strm(errs(), "*** Debug Log Output ***\n", - (!EnableDebugBuffering || !DebugFlag) ? 0 : *DebugBufferSize) { - if (EnableDebugBuffering && DebugFlag && *DebugBufferSize != 0) + (!EnableDebugBuffering || !DebugFlag) + ? 0 + : getDebugOptions().DebugBufferSize) { + if (EnableDebugBuffering && DebugFlag && + getDebugOptions().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); diff --git a/llvm/lib/Support/GraphWriter.cpp b/llvm/lib/Support/GraphWriter.cpp --- a/llvm/lib/Support/GraphWriter.cpp +++ b/llvm/lib/Support/GraphWriter.cpp @@ -36,21 +36,23 @@ using namespace llvm; -#ifdef __APPLE__ namespace { -struct CreateViewBackground { - static void *call() { - return new cl::opt("view-background", cl::Hidden, - cl::desc("Execute graph viewer in the background. " - "Creates tmp file litter.")); - } +struct Options { +#ifdef __APPLE__ + cl::opt ViewBackground{ + "view-background", cl::Hidden, + cl::desc("Execute graph viewer in the background. " + "Creates tmp file litter.")}; +#endif }; + +static Options &getOptions() { + static Options Opt; + return Opt; +} } // namespace -static ManagedStatic, CreateViewBackground> ViewBackground; -void llvm::initGraphWriterOptions() { *ViewBackground; } -#else -void llvm::initGraphWriterOptions() {} -#endif + +void llvm::initGraphWriterOptions() { getOptions(); } std::string llvm::DOT::EscapeString(const std::string &Label) { std::string Str(Label); @@ -195,7 +197,7 @@ GraphSession S; #ifdef __APPLE__ - wait &= !*ViewBackground; + wait &= !getOptions().ViewBackground; if (S.TryFindProgram("open", ViewerPath)) { std::vector args; args.push_back(ViewerPath); diff --git a/llvm/lib/Support/RandomNumberGenerator.cpp b/llvm/lib/Support/RandomNumberGenerator.cpp --- a/llvm/lib/Support/RandomNumberGenerator.cpp +++ b/llvm/lib/Support/RandomNumberGenerator.cpp @@ -29,19 +29,23 @@ #define DEBUG_TYPE "rng" namespace { -struct CreateSeed { - static void *call() { - return new cl::opt( - "rng-seed", cl::value_desc("seed"), cl::Hidden, - cl::desc("Seed for the random number generator"), cl::init(0)); - } +struct Options { + cl::opt Seed{"rng-seed", cl::value_desc("seed"), cl::Hidden, + cl::desc("Seed for the random number generator"), + cl::init(0)}; }; + +static Options &getOptions() { + static Options Opt; + return Opt; +} } // namespace -static ManagedStatic, CreateSeed> Seed; -void llvm::initRandomSeedOptions() { *Seed; } + +void llvm::initRandomSeedOptions() { getOptions(); } RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) { - LLVM_DEBUG(if (*Seed == 0) dbgs() + auto Seed = getOptions().Seed.getValue(); + LLVM_DEBUG(if (Seed == 0) dbgs() << "Warning! Using unseeded random number generator.\n"); // Combine seed and salts using std::seed_seq. @@ -51,8 +55,8 @@ // twister constructor copies these correctly into its initial state. std::vector Data; Data.resize(2 + Salt.size()); - Data[0] = *Seed; - Data[1] = *Seed >> 32; + Data[0] = Seed; + Data[1] = Seed >> 32; llvm::copy(Salt, Data.begin() + 2); diff --git a/llvm/lib/Support/Signals.cpp b/llvm/lib/Support/Signals.cpp --- a/llvm/lib/Support/Signals.cpp +++ b/llvm/lib/Support/Signals.cpp @@ -23,13 +23,13 @@ #include "llvm/Support/FileUtilities.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/raw_ostream.h" #include +#include #include //===----------------------------------------------------------------------===// @@ -41,33 +41,25 @@ // Use explicit storage to avoid accessing cl::opt in a signal handler. static bool DisableSymbolicationFlag = false; -static ManagedStatic CrashDiagnosticsDirectory; +static std::string CrashDiagnosticsDirectory; namespace { -struct CreateDisableSymbolication { - static void *call() { - return new cl::opt( - "disable-symbolication", - cl::desc("Disable symbolizing crash backtraces."), - cl::location(DisableSymbolicationFlag), cl::Hidden); - } -}; -struct CreateCrashDiagnosticsDir { - static void *call() { - return new cl::opt( - "crash-diagnostics-dir", cl::value_desc("directory"), - cl::desc("Directory for crash diagnostic files."), - cl::location(*CrashDiagnosticsDirectory), cl::Hidden); - } +struct Options { + cl::opt DisableSymbolication{ + "disable-symbolication", + cl::desc("Disable symbolizing crash backtraces."), + cl::location(DisableSymbolicationFlag), cl::Hidden}; + cl::opt CrashDiagnosticsDir{ + "crash-diagnostics-dir", cl::value_desc("directory"), + cl::desc("Directory for crash diagnostic files."), + cl::location(CrashDiagnosticsDirectory), cl::Hidden}; }; -} // namespace -void llvm::initSignalsOptions() { - static ManagedStatic, CreateDisableSymbolication> - DisableSymbolication; - static ManagedStatic, CreateCrashDiagnosticsDir> - CrashDiagnosticsDir; - *DisableSymbolication; - *CrashDiagnosticsDir; + +Options &getOptions() { + static Options Opt; + return Opt; } +} // namespace +void llvm::initSignalsOptions() { getOptions(); } constexpr char DisableSymbolizationEnv[] = "LLVM_DISABLE_SYMBOLIZATION"; constexpr char LLVMSymbolizerPathEnv[] = "LLVM_SYMBOLIZER_PATH"; diff --git a/llvm/lib/Support/Timer.cpp b/llvm/lib/Support/Timer.cpp --- a/llvm/lib/Support/Timer.cpp +++ b/llvm/lib/Support/Timer.cpp @@ -20,7 +20,6 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" -#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/Process.h" #include "llvm/Support/Signposts.h" @@ -38,63 +37,43 @@ using namespace llvm; -// This ugly hack is brought to you courtesy of constructor/destructor ordering -// being unspecified by C++. Basically the problem is that a Statistic object -// gets destroyed, which ends up calling 'GetLibSupportInfoOutputFile()' -// (below), which calls this function. LibSupportInfoOutputFilename used to be -// a global variable, but sometimes it would get destroyed before the Statistic, -// causing havoc to ensue. We "fix" this by creating the string the first time -// it is needed and never destroying it. -static ManagedStatic LibSupportInfoOutputFilename; -static std::string &getLibSupportInfoOutputFilename() { - return *LibSupportInfoOutputFilename; +sys::SmartMutex &getTimerLock() { + static sys::SmartMutex TimerLock; + return TimerLock; } -static ManagedStatic > TimerLock; - /// Allows llvm::Timer to emit signposts when supported. -static ManagedStatic Signposts; +SignpostEmitter &getSignposts() { + static SignpostEmitter Signposts; + return Signposts; +} namespace { -struct CreateTrackSpace { - static void *call() { - return new cl::opt("track-memory", - cl::desc("Enable -time-passes memory " - "tracking (this may be slow)"), - cl::Hidden); - } -}; -static ManagedStatic, CreateTrackSpace> TrackSpace; -struct CreateInfoOutputFilename { - static void *call() { - return new cl::opt( - "info-output-file", cl::value_desc("filename"), - cl::desc("File to append -stats and -timer output to"), cl::Hidden, - cl::location(getLibSupportInfoOutputFilename())); - } -}; -static ManagedStatic, CreateInfoOutputFilename> - InfoOutputFilename; -struct CreateSortTimers { - static void *call() { - return new cl::opt( - "sort-timers", - cl::desc("In the report, sort the timers in each group " - "in wall clock time order"), - cl::init(true), cl::Hidden); - } +struct Options { + cl::opt TrackSpace{"track-memory", + cl::desc("Enable -time-passes memory " + "tracking (this may be slow)"), + cl::Hidden}; + cl::opt InfoOutputFilename{ + "info-output-file", cl::value_desc("filename"), + cl::desc("File to append -stats and -timer output to"), cl::Hidden}; + cl::opt SortTimers{ + "sort-timers", + cl::desc("In the report, sort the timers in each group " + "in wall clock time order"), + cl::init(true), cl::Hidden}; }; -ManagedStatic, CreateSortTimers> SortTimers; -} // namespace -void llvm::initTimerOptions() { - *TrackSpace; - *InfoOutputFilename; - *SortTimers; +Options &getOptions() { + static Options Opt; + return Opt; } +} // namespace + +void llvm::initTimerOptions() { (void)getOptions(); } std::unique_ptr llvm::CreateInfoOutputFile() { - const std::string &OutputFilename = getLibSupportInfoOutputFilename(); + const std::string &OutputFilename = getOptions().InfoOutputFilename; if (OutputFilename.empty()) return std::make_unique(2, false); // stderr. if (OutputFilename == "-") @@ -116,14 +95,16 @@ } namespace { -struct CreateDefaultTimerGroup { - static void *call() { - return new TimerGroup("misc", "Miscellaneous Ungrouped Timers"); - } +struct DefaultTimerGroup { + std::unique_ptr Group; + DefaultTimerGroup() + : Group(new TimerGroup("misc", "Miscellaneous Ungrouped Timers")) {} }; } // namespace -static ManagedStatic DefaultTimerGroup; -static TimerGroup *getDefaultTimerGroup() { return &*DefaultTimerGroup; } +static std::unique_ptr &getDefaultTimerGroup() { + static DefaultTimerGroup TheDefaultTimerGroup; + return TheDefaultTimerGroup.Group; +} //===----------------------------------------------------------------------===// // Timer Implementation @@ -149,7 +130,7 @@ } static inline size_t getMemUsage() { - if (!*TrackSpace) + if (!getOptions().TrackSpace) return 0; return sys::Process::GetMallocUsage(); } @@ -190,7 +171,7 @@ void Timer::startTimer() { assert(!Running && "Cannot start a running timer"); Running = Triggered = true; - Signposts->startInterval(this, getName()); + getSignposts().startInterval(this, getName()); StartTime = TimeRecord::getCurrentTime(true); } @@ -199,7 +180,7 @@ Running = false; Time += TimeRecord::getCurrentTime(false); Time -= StartTime; - Signposts->endInterval(this, getName()); + getSignposts().endInterval(this, getName()); } void Timer::clear() { @@ -251,7 +232,7 @@ Timer &get(StringRef Name, StringRef Description, StringRef GroupName, StringRef GroupDescription) { - sys::SmartScopedLock L(*TimerLock); + sys::SmartScopedLock L(getTimerLock()); std::pair &GroupEntry = Map[GroupName]; @@ -265,16 +246,20 @@ } }; +Name2PairMap &getNamedGroupedTimers() { + static Name2PairMap NamedGroupedTimers; + return NamedGroupedTimers; } -static ManagedStatic NamedGroupedTimers; +} // namespace NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef Description, StringRef GroupName, StringRef GroupDescription, bool Enabled) - : TimeRegion(!Enabled ? nullptr - : &NamedGroupedTimers->get(Name, Description, GroupName, - GroupDescription)) {} + : TimeRegion(!Enabled ? nullptr + : &getNamedGroupedTimers().get(Name, Description, + GroupName, + GroupDescription)) {} //===----------------------------------------------------------------------===// // TimerGroup Implementation @@ -288,7 +273,7 @@ : Name(Name.begin(), Name.end()), Description(Description.begin(), Description.end()) { // Add the group to TimerGroupList. - sys::SmartScopedLock L(*TimerLock); + sys::SmartScopedLock L(getTimerLock()); if (TimerGroupList) TimerGroupList->Prev = &Next; Next = TimerGroupList; @@ -313,7 +298,7 @@ removeTimer(*FirstTimer); // Remove the group from the TimerGroupList. - sys::SmartScopedLock L(*TimerLock); + sys::SmartScopedLock L(getTimerLock()); *Prev = Next; if (Next) Next->Prev = Prev; @@ -321,7 +306,7 @@ void TimerGroup::removeTimer(Timer &T) { - sys::SmartScopedLock L(*TimerLock); + sys::SmartScopedLock L(getTimerLock()); // If the timer was started, move its data to TimersToPrint. if (T.hasTriggered()) @@ -344,7 +329,7 @@ } void TimerGroup::addTimer(Timer &T) { - sys::SmartScopedLock L(*TimerLock); + sys::SmartScopedLock L(getTimerLock()); // Add the timer to our list. if (FirstTimer) @@ -356,7 +341,7 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) { // Perhaps sort the timers in descending order by amount of time taken. - if (*SortTimers) + if (getOptions().SortTimers) llvm::sort(TimersToPrint); TimeRecord Total; @@ -374,7 +359,7 @@ // If this is not an collection of ungrouped times, print the total time. // Ungrouped timers don't really make sense to add up. We still print the // TOTAL line to make the percentages make sense. - if (this != getDefaultTimerGroup()) + if (this != getDefaultTimerGroup().get()) OS << format(" Total Execution Time: %5.4f seconds (%5.4f wall clock)\n", Total.getProcessTime(), Total.getWallTime()); OS << '\n'; @@ -426,7 +411,7 @@ void TimerGroup::print(raw_ostream &OS, bool ResetAfterPrint) { { // After preparing the timers we can free the lock - sys::SmartScopedLock L(*TimerLock); + sys::SmartScopedLock L(getTimerLock()); prepareToPrintList(ResetAfterPrint); } @@ -436,20 +421,20 @@ } void TimerGroup::clear() { - sys::SmartScopedLock L(*TimerLock); + sys::SmartScopedLock L(getTimerLock()); for (Timer *T = FirstTimer; T; T = T->Next) T->clear(); } void TimerGroup::printAll(raw_ostream &OS) { - sys::SmartScopedLock L(*TimerLock); + sys::SmartScopedLock L(getTimerLock()); for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next) TG->print(OS); } void TimerGroup::clearAll() { - sys::SmartScopedLock L(*TimerLock); + sys::SmartScopedLock L(getTimerLock()); for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next) TG->clear(); } @@ -466,7 +451,7 @@ } const char *TimerGroup::printJSONValues(raw_ostream &OS, const char *delim) { - sys::SmartScopedLock L(*TimerLock); + sys::SmartScopedLock L(getTimerLock()); prepareToPrintList(false); for (const PrintRecord &R : TimersToPrint) { @@ -493,17 +478,17 @@ } const char *TimerGroup::printAllJSONValues(raw_ostream &OS, const char *delim) { - sys::SmartScopedLock L(*TimerLock); + sys::SmartScopedLock L(getTimerLock()); for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next) delim = TG->printJSONValues(OS, delim); return delim; } void TimerGroup::ConstructForStatistics() { - (void)getLibSupportInfoOutputFilename(); - (void)*NamedGroupedTimers; + (void)getOptions(); + (void)getNamedGroupedTimers(); } std::unique_ptr TimerGroup::aquireDefaultGroup() { - return std::unique_ptr(DefaultTimerGroup.claim()); + return std::move(getDefaultTimerGroup()); } diff --git a/llvm/lib/Support/TypeSize.cpp b/llvm/lib/Support/TypeSize.cpp --- a/llvm/lib/Support/TypeSize.cpp +++ b/llvm/lib/Support/TypeSize.cpp @@ -16,28 +16,28 @@ #ifndef STRICT_FIXED_SIZE_VECTORS namespace { -struct CreateScalableErrorAsWarning { +struct Options { /// The ScalableErrorAsWarning is a temporary measure to suppress errors from /// using the wrong interface on a scalable vector. - static void *call() { - return new cl::opt( - "treat-scalable-fixed-error-as-warning", cl::Hidden, - cl::desc( - "Treat issues where a fixed-width property is requested from a " - "scalable type as a warning, instead of an error")); - } + cl::opt ScalableErrorAsWarning{ + "treat-scalable-fixed-error-as-warning", cl::Hidden, + cl::desc("Treat issues where a fixed-width property is requested from a " + "scalable type as a warning, instead of an error")}; }; + +Options &getOptions() { + static Options Opt; + return Opt; +} } // namespace -static ManagedStatic, CreateScalableErrorAsWarning> - ScalableErrorAsWarning; -void llvm::initTypeSizeOptions() { *ScalableErrorAsWarning; } +void llvm::initTypeSizeOptions() { (void)getOptions(); } #else void llvm::initTypeSizeOptions() {} #endif void llvm::reportInvalidSizeRequest(const char *Msg) { #ifndef STRICT_FIXED_SIZE_VECTORS - if (*ScalableErrorAsWarning) { + if (getOptions().ScalableErrorAsWarning) { WithColor::warning() << "Invalid size request on a scalable vector; " << Msg << "\n"; return; diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -132,8 +132,8 @@ const std::string &Filename) { // Use a lock to avoid concurrent erase: the comparison would access // free'd memory. - static ManagedStatic> Lock; - sys::SmartScopedLock Writer(*Lock); + static sys::SmartMutex Lock; + sys::SmartScopedLock Writer(Lock); for (FileToRemoveList *Current = Head.load(); Current; Current = Current->Next.load()) { @@ -284,8 +284,8 @@ // The mutex prevents other threads from registering handlers while we're // doing it. We also have to protect the handlers and their count because // a signal handler could fire while we're registeting handlers. - static ManagedStatic> SignalHandlerRegistrationMutex; - sys::SmartScopedLock Guard(*SignalHandlerRegistrationMutex); + static sys::SmartMutex SignalHandlerRegistrationMutex; + sys::SmartScopedLock Guard(SignalHandlerRegistrationMutex); // If the handlers are already registered, we're done. if (NumRegisteredSignals.load() != 0) @@ -444,8 +444,7 @@ bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) { // Ensure that cleanup will occur as soon as one file is added. - static ManagedStatic FilesToRemoveCleanup; - *FilesToRemoveCleanup; + static FilesToRemoveCleanup FilesToRemoveCleanup; FileToRemoveList::insert(FilesToRemove, Filename.str()); RegisterHandlers(); return false; diff --git a/llvm/lib/Support/WithColor.cpp b/llvm/lib/Support/WithColor.cpp --- a/llvm/lib/Support/WithColor.cpp +++ b/llvm/lib/Support/WithColor.cpp @@ -12,7 +12,6 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" -#include "llvm/Support/ManagedStatic.h" using namespace llvm; @@ -21,21 +20,23 @@ return ColorCategory; } namespace { -struct CreateUseColor { - static void *call() { - return new cl::opt( - "color", cl::cat(getColorCategory()), - cl::desc("Use colors in output (default=autodetect)"), - cl::init(cl::BOU_UNSET)); - } +struct Options { + cl::opt UseColor{ + "color", cl::cat(getColorCategory()), + cl::desc("Use colors in output (default=autodetect)"), + cl::init(cl::BOU_UNSET)}; }; + +Options &getOptions() { + static Options Opt; + return Opt; +} } // namespace -static ManagedStatic, CreateUseColor> UseColor; -void llvm::initWithColorOptions() { *UseColor; } +void llvm::initWithColorOptions() { (void)getOptions(); } static bool DefaultAutoDetectFunction(const raw_ostream &OS) { - return *UseColor == cl::BOU_UNSET ? OS.has_colors() - : *UseColor == cl::BOU_TRUE; + cl::boolOrDefault UseColor = getOptions().UseColor; + return UseColor == cl::BOU_UNSET ? OS.has_colors() : UseColor == cl::BOU_TRUE; } WithColor::AutoDetectFunctionType WithColor::AutoDetectFunction =