Author: Mehdi Amini Date: 2021-07-16T06:54:26Z New Revision: af9321739b20becf170e6bb5060b8d780e1dc8dd
URL: https://github.com/llvm/llvm-project/commit/af9321739b20becf170e6bb5060b8d780e1dc8dd DIFF: https://github.com/llvm/llvm-project/commit/af9321739b20becf170e6bb5060b8d780e1dc8dd.diff LOG: 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 Added: llvm/lib/Support/DebugOptions.h Modified: clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp clang-tools-extra/clangd/indexer/IndexerMain.cpp clang/tools/clang-refactor/ClangRefactor.cpp llvm/docs/CommandLine.rst llvm/include/llvm/Support/ARMAttributeParser.h llvm/include/llvm/Support/ARMBuildAttributes.h llvm/include/llvm/Support/CommandLine.h llvm/include/llvm/Support/RISCVAttributeParser.h llvm/include/llvm/Support/RISCVAttributes.h llvm/include/llvm/Support/ScopedPrinter.h llvm/include/llvm/Support/WithColor.h llvm/lib/Support/ARMBuildAttrs.cpp llvm/lib/Support/CommandLine.cpp llvm/lib/Support/Debug.cpp llvm/lib/Support/DebugCounter.cpp llvm/lib/Support/ELFAttributeParser.cpp llvm/lib/Support/GraphWriter.cpp llvm/lib/Support/RISCVAttributes.cpp llvm/lib/Support/RandomNumberGenerator.cpp llvm/lib/Support/Signals.cpp llvm/lib/Support/Statistic.cpp llvm/lib/Support/TimeProfiler.cpp llvm/lib/Support/Timer.cpp llvm/lib/Support/TypeSize.cpp llvm/lib/Support/Windows/Signals.inc llvm/lib/Support/WithColor.cpp llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp llvm/unittests/Support/ARMAttributeParser.cpp llvm/unittests/Support/CommandLineTest.cpp llvm/unittests/Support/RISCVAttributeParserTest.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp index 49f16e72be92a..581dae7557295 100644 --- a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp +++ b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp @@ -91,7 +91,7 @@ class Command { // By resetting the parser options, we lost the standard -help flag. llvm::cl::opt<bool, false, llvm::cl::parser<bool>> Help{ "help", llvm::cl::desc("Display available options"), - llvm::cl::ValueDisallowed, llvm::cl::cat(llvm::cl::GeneralCategory)}; + llvm::cl::ValueDisallowed, llvm::cl::cat(llvm::cl::getGeneralCategory())}; // FIXME: Allow commands to signal failure. virtual void run() = 0; diff --git a/clang-tools-extra/clangd/indexer/IndexerMain.cpp b/clang-tools-extra/clangd/indexer/IndexerMain.cpp index fd8404be677a2..533334fcc1f28 100644 --- a/clang-tools-extra/clangd/indexer/IndexerMain.cpp +++ b/clang-tools-extra/clangd/indexer/IndexerMain.cpp @@ -124,7 +124,7 @@ int main(int argc, const char **argv) { )"; auto Executor = clang::tooling::createExecutorFromCommandLineArgs( - argc, argv, llvm::cl::GeneralCategory, Overview); + argc, argv, llvm::cl::getGeneralCategory(), Overview); if (!Executor) { llvm::errs() << llvm::toString(Executor.takeError()) << "\n"; diff --git a/clang/tools/clang-refactor/ClangRefactor.cpp b/clang/tools/clang-refactor/ClangRefactor.cpp index 01edad43164fb..eacd00a601dbe 100644 --- a/clang/tools/clang-refactor/ClangRefactor.cpp +++ b/clang/tools/clang-refactor/ClangRefactor.cpp @@ -38,11 +38,11 @@ namespace opts { static cl::OptionCategory CommonRefactorOptions("Refactoring options"); static cl::opt<bool> Verbose("v", cl::desc("Use verbose output"), - cl::cat(cl::GeneralCategory), + cl::cat(cl::getGeneralCategory()), cl::sub(*cl::AllSubCommands)); static cl::opt<bool> Inplace("i", cl::desc("Inplace edit <file>s"), - cl::cat(cl::GeneralCategory), + cl::cat(cl::getGeneralCategory()), cl::sub(*cl::AllSubCommands)); } // end namespace opts @@ -613,7 +613,7 @@ int main(int argc, const char **argv) { ClangRefactorTool RefactorTool; auto ExpectedParser = CommonOptionsParser::create( - argc, argv, cl::GeneralCategory, cl::ZeroOrMore, + argc, argv, cl::getGeneralCategory(), cl::ZeroOrMore, "Clang-based refactoring tool for C, C++ and Objective-C"); if (!ExpectedParser) { llvm::errs() << ExpectedParser.takeError(); diff --git a/llvm/docs/CommandLine.rst b/llvm/docs/CommandLine.rst index e549d49bd90f5..fef7e39ad86d2 100644 --- a/llvm/docs/CommandLine.rst +++ b/llvm/docs/CommandLine.rst @@ -661,7 +661,7 @@ declared, the command line option ``-help-list`` becomes visible which will print the command line options as uncategorized list. Note that Options that are not explicitly categorized will be placed in the -``cl::GeneralCategory`` category. +``cl::getGeneralCategory()`` category. .. _Reference Guide: diff --git a/llvm/include/llvm/Support/ARMAttributeParser.h b/llvm/include/llvm/Support/ARMAttributeParser.h index bf85ea14cfe33..5d12b7e08d580 100644 --- a/llvm/include/llvm/Support/ARMAttributeParser.h +++ b/llvm/include/llvm/Support/ARMAttributeParser.h @@ -71,9 +71,9 @@ class ARMAttributeParser : public ELFAttributeParser { public: ARMAttributeParser(ScopedPrinter *sw) - : ELFAttributeParser(sw, ARMBuildAttrs::ARMAttributeTags, "aeabi") {} + : ELFAttributeParser(sw, ARMBuildAttrs::getARMAttributeTags(), "aeabi") {} ARMAttributeParser() - : ELFAttributeParser(ARMBuildAttrs::ARMAttributeTags, "aeabi") {} + : ELFAttributeParser(ARMBuildAttrs::getARMAttributeTags(), "aeabi") {} }; } diff --git a/llvm/include/llvm/Support/ARMBuildAttributes.h b/llvm/include/llvm/Support/ARMBuildAttributes.h index 5a06fd6ca7be7..37c37522fd266 100644 --- a/llvm/include/llvm/Support/ARMBuildAttributes.h +++ b/llvm/include/llvm/Support/ARMBuildAttributes.h @@ -23,7 +23,7 @@ namespace llvm { namespace ARMBuildAttrs { -extern const TagNameMap ARMAttributeTags; +const TagNameMap &getARMAttributeTags(); enum SpecialAttr { // This is for the .cpu asm attr. It translates into one or more diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h index bcbc4f993d513..14d7e21f78b23 100644 --- a/llvm/include/llvm/Support/CommandLine.h +++ b/llvm/include/llvm/Support/CommandLine.h @@ -202,7 +202,7 @@ class OptionCategory { }; // The general Option Category (used as default category). -extern OptionCategory GeneralCategory; +OptionCategory &getGeneralCategory(); //===----------------------------------------------------------------------===// // SubCommand class @@ -342,7 +342,7 @@ class Option { : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0), HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), FullyInitialized(false), Position(0), AdditionalVals(0) { - Categories.push_back(&GeneralCategory); + Categories.push_back(&getGeneralCategory()); } inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; } diff --git a/llvm/include/llvm/Support/RISCVAttributeParser.h b/llvm/include/llvm/Support/RISCVAttributeParser.h index 3e629419a7e9b..305adffbe851e 100644 --- a/llvm/include/llvm/Support/RISCVAttributeParser.h +++ b/llvm/include/llvm/Support/RISCVAttributeParser.h @@ -27,9 +27,9 @@ class RISCVAttributeParser : public ELFAttributeParser { public: RISCVAttributeParser(ScopedPrinter *sw) - : ELFAttributeParser(sw, RISCVAttrs::RISCVAttributeTags, "riscv") {} + : ELFAttributeParser(sw, RISCVAttrs::getRISCVAttributeTags(), "riscv") {} RISCVAttributeParser() - : ELFAttributeParser(RISCVAttrs::RISCVAttributeTags, "riscv") {} + : ELFAttributeParser(RISCVAttrs::getRISCVAttributeTags(), "riscv") {} }; } // namespace llvm diff --git a/llvm/include/llvm/Support/RISCVAttributes.h b/llvm/include/llvm/Support/RISCVAttributes.h index caded9519b668..a8ce8f4d8daf4 100644 --- a/llvm/include/llvm/Support/RISCVAttributes.h +++ b/llvm/include/llvm/Support/RISCVAttributes.h @@ -22,7 +22,7 @@ namespace llvm { namespace RISCVAttrs { -extern const TagNameMap RISCVAttributeTags; +const TagNameMap &getRISCVAttributeTags(); enum AttrType : unsigned { // Attribute types in ELF/.riscv.attributes. diff --git a/llvm/include/llvm/Support/ScopedPrinter.h b/llvm/include/llvm/Support/ScopedPrinter.h index fe800e3240470..0dfe1245f7d6e 100644 --- a/llvm/include/llvm/Support/ScopedPrinter.h +++ b/llvm/include/llvm/Support/ScopedPrinter.h @@ -32,8 +32,9 @@ template <typename T> struct EnumEntry { // "Advanced Micro Devices X86-64" on GNU style StringRef AltName; T Value; - EnumEntry(StringRef N, StringRef A, T V) : Name(N), AltName(A), Value(V) {} - EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {} + constexpr EnumEntry(StringRef N, StringRef A, T V) + : Name(N), AltName(A), Value(V) {} + constexpr EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {} }; struct HexNumber { diff --git a/llvm/include/llvm/Support/WithColor.h b/llvm/include/llvm/Support/WithColor.h index 1908c6eb8ea32..e772ea667f4f6 100644 --- a/llvm/include/llvm/Support/WithColor.h +++ b/llvm/include/llvm/Support/WithColor.h @@ -20,7 +20,7 @@ namespace cl { class OptionCategory; } -extern cl::OptionCategory ColorCategory; +extern cl::OptionCategory &getColorCategory(); // Symbolic names for various syntax elements. enum class HighlightColor { diff --git a/llvm/lib/Support/ARMBuildAttrs.cpp b/llvm/lib/Support/ARMBuildAttrs.cpp index 5aaf0a4e7c62e..f20521f2a2d47 100644 --- a/llvm/lib/Support/ARMBuildAttrs.cpp +++ b/llvm/lib/Support/ARMBuildAttrs.cpp @@ -63,6 +63,7 @@ static const TagNameItem tagData[] = { {ARMBuildAttrs::ABI_align_preserved, "Tag_ABI_align8_preserved"}, }; -const TagNameMap llvm::ARMBuildAttrs::ARMAttributeTags(tagData, - sizeof(tagData) / - sizeof(TagNameItem)); +constexpr TagNameMap ARMAttributeTags{tagData}; +const TagNameMap &llvm::ARMBuildAttrs::getARMAttributeTags() { + return ARMAttributeTags; +} diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index 8cf7d5b1e57e2..4ae3ad4c24535 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -16,6 +16,9 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/CommandLine.h" + +#include "DebugOptions.h" + #include "llvm-c/Support.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" @@ -462,7 +465,7 @@ void Option::addCategory(OptionCategory &C) { // Maintain backward compatibility by replacing the default GeneralCategory // if it's still set. Otherwise, just add the new one. The GeneralCategory // must be explicitly added if you want multiple categories that include it. - if (&C != &GeneralCategory && Categories[0] == &GeneralCategory) + if (&C != &getGeneralCategory() && Categories[0] == &getGeneralCategory()) Categories[0] = &C; else if (!is_contained(Categories, &C)) Categories.push_back(&C); @@ -475,9 +478,6 @@ void Option::reset() { removeArgument(); } -// Initialise the general option category. -OptionCategory llvm::cl::GeneralCategory("General options"); - void OptionCategory::registerCategory() { GlobalParser->registerCategory(this); } @@ -1293,10 +1293,12 @@ bool cl::readConfigFile(StringRef CfgFile, StringSaver &Saver, /*MarkEOLs=*/false, /*RelativeNames=*/true); } +static void initCommonOptions(); bool cl::ParseCommandLineOptions(int argc, const char *const *argv, StringRef Overview, raw_ostream *Errs, const char *EnvVar, bool LongOptionsUseDoubleDash) { + initCommonOptions(); SmallVector<const char *, 20> NewArgv; BumpPtrAllocator A; StringSaver Saver(A); @@ -1937,7 +1939,9 @@ unsigned generic_parser_base::findOption(StringRef Name) { static StringRef EqValue = "=<value>"; static StringRef EmptyOption = "<empty>"; static StringRef OptionPrefix = " ="; -static size_t OptionPrefixesSize = OptionPrefix.size() + ArgHelpPrefix.size(); +static size_t getOptionPrefixesSize() { + return OptionPrefix.size() + ArgHelpPrefix.size(); +} static bool shouldPrintOption(StringRef Name, StringRef Description, const Option &O) { @@ -1955,7 +1959,7 @@ size_t generic_parser_base::getOptionWidth(const Option &O) const { if (!shouldPrintOption(Name, getDescription(i), O)) continue; size_t NameSize = Name.empty() ? EmptyOption.size() : Name.size(); - Size = std::max(Size, NameSize + OptionPrefixesSize); + Size = std::max(Size, NameSize + getOptionPrefixesSize()); } return Size; } else { @@ -1994,7 +1998,7 @@ void generic_parser_base::printOptionInfo(const Option &O, StringRef Description = getDescription(i); if (!shouldPrintOption(OptionName, Description, O)) continue; - size_t FirstLineIndent = OptionName.size() + OptionPrefixesSize; + size_t FirstLineIndent = OptionName.size() + getOptionPrefixesSize(); outs() << OptionPrefix << OptionName; if (OptionName.empty()) { outs() << EmptyOption; @@ -2374,105 +2378,6 @@ class HelpPrinterWrapper { } // End anonymous namespace -// Declare the four HelpPrinter instances that are used to print out help, or -// help-hidden as an uncategorized list or in categories. -static HelpPrinter UncategorizedNormalPrinter(false); -static HelpPrinter UncategorizedHiddenPrinter(true); -static CategorizedHelpPrinter CategorizedNormalPrinter(false); -static CategorizedHelpPrinter CategorizedHiddenPrinter(true); - -// Declare HelpPrinter wrappers that will decide whether or not to invoke -// a categorizing help printer -static HelpPrinterWrapper WrappedNormalPrinter(UncategorizedNormalPrinter, - CategorizedNormalPrinter); -static HelpPrinterWrapper WrappedHiddenPrinter(UncategorizedHiddenPrinter, - CategorizedHiddenPrinter); - -// Define a category for generic options that all tools should have. -static cl::OptionCategory GenericCategory("Generic Options"); - -// Define uncategorized help printers. -// --help-list is hidden by default because if Option categories are being used -// then --help behaves the same as --help-list. -static cl::opt<HelpPrinter, true, parser<bool>> HLOp( - "help-list", - cl::desc("Display list of available options (--help-list-hidden for more)"), - cl::location(UncategorizedNormalPrinter), cl::Hidden, cl::ValueDisallowed, - cl::cat(GenericCategory), cl::sub(*AllSubCommands)); - -static cl::opt<HelpPrinter, true, parser<bool>> - HLHOp("help-list-hidden", cl::desc("Display list of all available options"), - cl::location(UncategorizedHiddenPrinter), cl::Hidden, - cl::ValueDisallowed, cl::cat(GenericCategory), - cl::sub(*AllSubCommands)); - -// Define uncategorized/categorized help printers. These printers change their -// behaviour at runtime depending on whether one or more Option categories have -// been declared. -static cl::opt<HelpPrinterWrapper, true, parser<bool>> - HOp("help", cl::desc("Display available options (--help-hidden for more)"), - cl::location(WrappedNormalPrinter), cl::ValueDisallowed, - cl::cat(GenericCategory), cl::sub(*AllSubCommands)); - -static cl::alias HOpA("h", cl::desc("Alias for --help"), cl::aliasopt(HOp), - cl::DefaultOption); - -static cl::opt<HelpPrinterWrapper, true, parser<bool>> - HHOp("help-hidden", cl::desc("Display all available options"), - cl::location(WrappedHiddenPrinter), cl::Hidden, cl::ValueDisallowed, - cl::cat(GenericCategory), cl::sub(*AllSubCommands)); - -static cl::opt<bool> PrintOptions( - "print-options", - cl::desc("Print non-default options after command line parsing"), - cl::Hidden, cl::init(false), cl::cat(GenericCategory), - cl::sub(*AllSubCommands)); - -static cl::opt<bool> PrintAllOptions( - "print-all-options", - cl::desc("Print all option values after command line parsing"), cl::Hidden, - cl::init(false), cl::cat(GenericCategory), cl::sub(*AllSubCommands)); - -void HelpPrinterWrapper::operator=(bool Value) { - if (!Value) - return; - - // Decide which printer to invoke. If more than one option category is - // registered then it is useful to show the categorized help instead of - // uncategorized help. - if (GlobalParser->RegisteredOptionCategories.size() > 1) { - // unhide --help-list option so user can have uncategorized output if they - // want it. - HLOp.setHiddenFlag(NotHidden); - - CategorizedPrinter = true; // Invoke categorized printer - } else - UncategorizedPrinter = true; // Invoke uncategorized printer -} - -// Print the value of each option. -void cl::PrintOptionValues() { GlobalParser->printOptionValues(); } - -void CommandLineParser::printOptionValues() { - if (!PrintOptions && !PrintAllOptions) - return; - - SmallVector<std::pair<const char *, Option *>, 128> Opts; - sortOpts(ActiveSubCommand->OptionsMap, Opts, /*ShowHidden*/ true); - - // Compute the maximum argument length... - size_t MaxArgLen = 0; - for (size_t i = 0, e = Opts.size(); i != e; ++i) - MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth()); - - for (size_t i = 0, e = Opts.size(); i != e; ++i) - Opts[i].second->printOptionValue(MaxArgLen, PrintAllOptions); -} - -static VersionPrinterTy OverrideVersionPrinter = nullptr; - -static std::vector<VersionPrinterTy> *ExtraVersionPrinters = nullptr; - #if defined(__GNUC__) // GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are // enabled. @@ -2528,59 +2433,203 @@ class VersionPrinter { #endif OS << '\n'; } - void operator=(bool OptionWasSpecified) { - if (!OptionWasSpecified) - return; + void operator=(bool OptionWasSpecified); +}; - if (OverrideVersionPrinter != nullptr) { - OverrideVersionPrinter(outs()); - exit(0); - } - print(); - - // Iterate over any registered extra printers and call them to add further - // information. - if (ExtraVersionPrinters != nullptr) { - outs() << '\n'; - for (const auto &I : *ExtraVersionPrinters) - I(outs()); - } +struct CommandLineCommonOptions { + // Declare the four HelpPrinter instances that are used to print out help, or + // help-hidden as an uncategorized list or in categories. + HelpPrinter UncategorizedNormalPrinter{false}; + HelpPrinter UncategorizedHiddenPrinter{true}; + CategorizedHelpPrinter CategorizedNormalPrinter{false}; + CategorizedHelpPrinter CategorizedHiddenPrinter{true}; + // Declare HelpPrinter wrappers that will decide whether or not to invoke + // a categorizing help printer + HelpPrinterWrapper WrappedNormalPrinter{UncategorizedNormalPrinter, + CategorizedNormalPrinter}; + HelpPrinterWrapper WrappedHiddenPrinter{UncategorizedHiddenPrinter, + CategorizedHiddenPrinter}; + // Define a category for generic options that all tools should have. + cl::OptionCategory GenericCategory{"Generic Options"}; + + // Define uncategorized help printers. + // --help-list is hidden by default because if Option categories are being + // used then --help behaves the same as --help-list. + cl::opt<HelpPrinter, true, parser<bool>> HLOp{ + "help-list", + cl::desc( + "Display list of available options (--help-list-hidden for more)"), + cl::location(UncategorizedNormalPrinter), + cl::Hidden, + cl::ValueDisallowed, + cl::cat(GenericCategory), + cl::sub(*AllSubCommands)}; + + cl::opt<HelpPrinter, true, parser<bool>> HLHOp{ + "help-list-hidden", + cl::desc("Display list of all available options"), + cl::location(UncategorizedHiddenPrinter), + cl::Hidden, + cl::ValueDisallowed, + cl::cat(GenericCategory), + cl::sub(*AllSubCommands)}; + + // Define uncategorized/categorized help printers. These printers change their + // behaviour at runtime depending on whether one or more Option categories + // have been declared. + cl::opt<HelpPrinterWrapper, true, parser<bool>> HOp{ + "help", + cl::desc("Display available options (--help-hidden for more)"), + cl::location(WrappedNormalPrinter), + cl::ValueDisallowed, + cl::cat(GenericCategory), + cl::sub(*AllSubCommands)}; + + cl::alias HOpA{"h", cl::desc("Alias for --help"), cl::aliasopt(HOp), + cl::DefaultOption}; + + cl::opt<HelpPrinterWrapper, true, parser<bool>> HHOp{ + "help-hidden", + cl::desc("Display all available options"), + cl::location(WrappedHiddenPrinter), + cl::Hidden, + cl::ValueDisallowed, + cl::cat(GenericCategory), + cl::sub(*AllSubCommands)}; + + cl::opt<bool> PrintOptions{ + "print-options", + cl::desc("Print non-default options after command line parsing"), + cl::Hidden, + cl::init(false), + cl::cat(GenericCategory), + cl::sub(*AllSubCommands)}; + + cl::opt<bool> PrintAllOptions{ + "print-all-options", + cl::desc("Print all option values after command line parsing"), + cl::Hidden, + cl::init(false), + cl::cat(GenericCategory), + cl::sub(*AllSubCommands)}; + + VersionPrinterTy OverrideVersionPrinter = nullptr; + + std::vector<VersionPrinterTy> ExtraVersionPrinters; + + // Define the --version option that prints out the LLVM version for the tool + VersionPrinter VersionPrinterInstance; + + cl::opt<VersionPrinter, true, parser<bool>> VersOp{ + "version", cl::desc("Display the version of this program"), + cl::location(VersionPrinterInstance), cl::ValueDisallowed, + cl::cat(GenericCategory)}; +}; +} // End anonymous namespace + +// Lazy-initialized global instance of options controlling the command-line +// parser and general handling. +static ManagedStatic<CommandLineCommonOptions> CommonOptions; +static void initCommonOptions() { + *CommonOptions; + initDebugCounterOptions(); + initGraphWriterOptions(); + initSignalsOptions(); + initStatisticOptions(); + initTimerOptions(); + initTypeSizeOptions(); + initWithColorOptions(); + initDebugOptions(); + initRandomSeedOptions(); +} + +OptionCategory &cl::getGeneralCategory() { + // Initialise the general option category. + static OptionCategory GeneralCategory{"General options"}; + return GeneralCategory; +} + +void VersionPrinter::operator=(bool OptionWasSpecified) { + if (!OptionWasSpecified) + return; + + if (CommonOptions->OverrideVersionPrinter != nullptr) { + CommonOptions->OverrideVersionPrinter(outs()); exit(0); } -}; -} // End anonymous namespace + print(); + + // Iterate over any registered extra printers and call them to add further + // information. + if (!CommonOptions->ExtraVersionPrinters.empty()) { + outs() << '\n'; + for (const auto &I : CommonOptions->ExtraVersionPrinters) + I(outs()); + } + + exit(0); +} + +void HelpPrinterWrapper::operator=(bool Value) { + if (!Value) + return; + + // Decide which printer to invoke. If more than one option category is + // registered then it is useful to show the categorized help instead of + // uncategorized help. + if (GlobalParser->RegisteredOptionCategories.size() > 1) { + // unhide --help-list option so user can have uncategorized output if they + // want it. + CommonOptions->HLOp.setHiddenFlag(NotHidden); -// Define the --version option that prints out the LLVM version for the tool -static VersionPrinter VersionPrinterInstance; + CategorizedPrinter = true; // Invoke categorized printer + } else + UncategorizedPrinter = true; // Invoke uncategorized printer +} + +// Print the value of each option. +void cl::PrintOptionValues() { GlobalParser->printOptionValues(); } + +void CommandLineParser::printOptionValues() { + if (!CommonOptions->PrintOptions && !CommonOptions->PrintAllOptions) + return; -static cl::opt<VersionPrinter, true, parser<bool>> - VersOp("version", cl::desc("Display the version of this program"), - cl::location(VersionPrinterInstance), cl::ValueDisallowed, - cl::cat(GenericCategory)); + SmallVector<std::pair<const char *, Option *>, 128> Opts; + sortOpts(ActiveSubCommand->OptionsMap, Opts, /*ShowHidden*/ true); + + // Compute the maximum argument length... + size_t MaxArgLen = 0; + for (size_t i = 0, e = Opts.size(); i != e; ++i) + MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth()); + + for (size_t i = 0, e = Opts.size(); i != e; ++i) + Opts[i].second->printOptionValue(MaxArgLen, CommonOptions->PrintAllOptions); +} // Utility function for printing the help message. void cl::PrintHelpMessage(bool Hidden, bool Categorized) { if (!Hidden && !Categorized) - UncategorizedNormalPrinter.printHelp(); + CommonOptions->UncategorizedNormalPrinter.printHelp(); else if (!Hidden && Categorized) - CategorizedNormalPrinter.printHelp(); + CommonOptions->CategorizedNormalPrinter.printHelp(); else if (Hidden && !Categorized) - UncategorizedHiddenPrinter.printHelp(); + CommonOptions->UncategorizedHiddenPrinter.printHelp(); else - CategorizedHiddenPrinter.printHelp(); + CommonOptions->CategorizedHiddenPrinter.printHelp(); } /// Utility function for printing version number. -void cl::PrintVersionMessage() { VersionPrinterInstance.print(); } +void cl::PrintVersionMessage() { + CommonOptions->VersionPrinterInstance.print(); +} -void cl::SetVersionPrinter(VersionPrinterTy func) { OverrideVersionPrinter = func; } +void cl::SetVersionPrinter(VersionPrinterTy func) { + CommonOptions->OverrideVersionPrinter = func; +} void cl::AddExtraVersionPrinter(VersionPrinterTy func) { - if (!ExtraVersionPrinters) - ExtraVersionPrinters = new std::vector<VersionPrinterTy>; - - ExtraVersionPrinters->push_back(func); + CommonOptions->ExtraVersionPrinters.push_back(func); } StringMap<Option *> &cl::getRegisteredOptions(SubCommand &Sub) { @@ -2596,10 +2645,10 @@ cl::getRegisteredSubcommands() { } void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) { + initCommonOptions(); for (auto &I : Sub.OptionsMap) { for (auto &Cat : I.second->Categories) { - if (Cat != &Category && - Cat != &GenericCategory) + if (Cat != &Category && Cat != &CommonOptions->GenericCategory) I.second->setHiddenFlag(cl::ReallyHidden); } } @@ -2607,9 +2656,11 @@ void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) { void cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories, SubCommand &Sub) { + initCommonOptions(); for (auto &I : Sub.OptionsMap) { for (auto &Cat : I.second->Categories) { - if (!is_contained(Categories, Cat) && Cat != &GenericCategory) + if (!is_contained(Categories, Cat) && + Cat != &CommonOptions->GenericCategory) I.second->setHiddenFlag(cl::ReallyHidden); } } diff --git a/llvm/lib/Support/Debug.cpp b/llvm/lib/Support/Debug.cpp index 19b40abdf0799..b48045cc04d5c 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<bool, true> -Debug("debug", cl::desc("Enable debug output"), cl::Hidden, - cl::location(DebugFlag)); +namespace { +struct CreateDebug { + static void *call() { + return new cl::opt<bool, true>("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<unsigned> -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<unsigned>( + "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<cl::opt<bool, true>, CreateDebug> Debug; +static ManagedStatic<cl::opt<unsigned>, CreateDebugBufferSize> DebugBufferSize; namespace { @@ -108,15 +121,33 @@ struct DebugOnlyOpt { CurrentDebugType->push_back(std::string(dbgType)); } }; - } // namespace static DebugOnlyOpt DebugOnlyOptLoc; -static cl::opt<DebugOnlyOpt, true, cl::parser<std::string> > -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<DebugOnlyOpt, true, cl::parser<std::string>>( + "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<cl::opt<DebugOnlyOpt, true, cl::parser<std::string>>, + 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); diff --git a/llvm/lib/Support/DebugCounter.cpp b/llvm/lib/Support/DebugCounter.cpp index 7bb231c79239b..f553463be8df2 100644 --- a/llvm/lib/Support/DebugCounter.cpp +++ b/llvm/lib/Support/DebugCounter.cpp @@ -1,4 +1,7 @@ #include "llvm/Support/DebugCounter.h" + +#include "DebugOptions.h" + #include "llvm/Support/CommandLine.h" #include "llvm/Support/Format.h" #include "llvm/Support/ManagedStatic.h" @@ -40,17 +43,29 @@ class DebugCounterList : public cl::list<std::string, DebugCounter> { } } }; + +struct CreateDebugCounterOption { + static void *call() { + return new DebugCounterList( + "debug-counter", cl::Hidden, + cl::desc("Comma separated list of debug counter skip and count"), + cl::CommaSeparated, cl::ZeroOrMore, + cl::location(DebugCounter::instance())); + } +}; } // namespace -// Create our command line option. -static DebugCounterList DebugCounterOption( - "debug-counter", cl::Hidden, - cl::desc("Comma separated list of debug counter skip and count"), - cl::CommaSeparated, cl::ZeroOrMore, cl::location(DebugCounter::instance())); +static ManagedStatic<DebugCounterList, CreateDebugCounterOption> + DebugCounterOption; +static bool PrintDebugCounter; -static cl::opt<bool> PrintDebugCounter( - "print-debug-counter", cl::Hidden, cl::init(false), cl::Optional, - cl::desc("Print out debug counter info after all counters accumulated")); +void llvm::initDebugCounterOptions() { + *DebugCounterOption; + static cl::opt<bool, true> RegisterPrintDebugCounter( + "print-debug-counter", cl::Hidden, cl::location(PrintDebugCounter), + cl::init(false), cl::Optional, + cl::desc("Print out debug counter info after all counters accumulated")); +} static ManagedStatic<DebugCounter> DC; diff --git a/llvm/lib/Support/DebugOptions.h b/llvm/lib/Support/DebugOptions.h new file mode 100644 index 0000000000000..4d5250649f6a2 --- /dev/null +++ b/llvm/lib/Support/DebugOptions.h @@ -0,0 +1,29 @@ +//===-- DebugOptions.h - Global Command line opt for libSupport *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the entry point to initialize the options registered on the +// command line for libSupport, this is internal to libSupport. +// +//===----------------------------------------------------------------------===// + +namespace llvm { + +// These are invoked internally before parsing command line options. +// This enables lazy-initialization of all the globals in libSupport, instead +// of eagerly loading everything on program startup. +void initDebugCounterOptions(); +void initGraphWriterOptions(); +void initSignalsOptions(); +void initStatisticOptions(); +void initTimerOptions(); +void initTypeSizeOptions(); +void initWithColorOptions(); +void initDebugOptions(); +void initRandomSeedOptions(); + +} // namespace llvm \ No newline at end of file diff --git a/llvm/lib/Support/ELFAttributeParser.cpp b/llvm/lib/Support/ELFAttributeParser.cpp index 2a30794bc1e91..1206553343efe 100644 --- a/llvm/lib/Support/ELFAttributeParser.cpp +++ b/llvm/lib/Support/ELFAttributeParser.cpp @@ -16,7 +16,7 @@ using namespace llvm; using namespace llvm::ELFAttrs; -static const EnumEntry<unsigned> tagNames[] = { +static constexpr EnumEntry<unsigned> tagNames[] = { {"Tag_File", ELFAttrs::File}, {"Tag_Section", ELFAttrs::Section}, {"Tag_Symbol", ELFAttrs::Symbol}, diff --git a/llvm/lib/Support/GraphWriter.cpp b/llvm/lib/Support/GraphWriter.cpp index f47a52a853f4e..240f59748d137 100644 --- a/llvm/lib/Support/GraphWriter.cpp +++ b/llvm/lib/Support/GraphWriter.cpp @@ -11,6 +11,9 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/GraphWriter.h" + +#include "DebugOptions.h" + #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -29,8 +32,21 @@ using namespace llvm; -static cl::opt<bool> ViewBackground("view-background", cl::Hidden, - cl::desc("Execute graph viewer in the background. Creates tmp file litter.")); +#ifdef __APPLE__ +namespace { +struct CreateViewBackground { + static void *call() { + return new cl::opt<bool>("view-background", cl::Hidden, + cl::desc("Execute graph viewer in the background. " + "Creates tmp file litter.")); + } +}; +} // namespace +static ManagedStatic<cl::opt<bool>, CreateViewBackground> ViewBackground; +void llvm::initGraphWriterOptions() { *ViewBackground; } +#else +void llvm::initGraphWriterOptions() {} +#endif std::string llvm::DOT::EscapeString(const std::string &Label) { std::string Str(Label); diff --git a/llvm/lib/Support/RISCVAttributes.cpp b/llvm/lib/Support/RISCVAttributes.cpp index 201048e03009b..9e629760d3d84 100644 --- a/llvm/lib/Support/RISCVAttributes.cpp +++ b/llvm/lib/Support/RISCVAttributes.cpp @@ -11,7 +11,7 @@ using namespace llvm; using namespace llvm::RISCVAttrs; -static const TagNameItem tagData[] = { +static constexpr TagNameItem tagData[] = { {STACK_ALIGN, "Tag_stack_align"}, {ARCH, "Tag_arch"}, {UNALIGNED_ACCESS, "Tag_unaligned_access"}, @@ -20,6 +20,7 @@ static const TagNameItem tagData[] = { {PRIV_SPEC_REVISION, "Tag_priv_spec_revision"}, }; -const TagNameMap llvm::RISCVAttrs::RISCVAttributeTags(tagData, - sizeof(tagData) / - sizeof(TagNameItem)); +constexpr TagNameMap RISCVAttributeTags{tagData}; +const TagNameMap &llvm::RISCVAttrs::getRISCVAttributeTags() { + return RISCVAttributeTags; +} diff --git a/llvm/lib/Support/RandomNumberGenerator.cpp b/llvm/lib/Support/RandomNumberGenerator.cpp index f9c41ee5eaaf0..aea0132a93fe2 100644 --- a/llvm/lib/Support/RandomNumberGenerator.cpp +++ b/llvm/lib/Support/RandomNumberGenerator.cpp @@ -13,6 +13,9 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/RandomNumberGenerator.h" + +#include "DebugOptions.h" + #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -25,13 +28,20 @@ using namespace llvm; #define DEBUG_TYPE "rng" - -static cl::opt<uint64_t> Seed("rng-seed", cl::value_desc("seed"), cl::Hidden, - cl::desc("Seed for the random number generator"), - cl::init(0)); +namespace { +struct CreateSeed { + static void *call() { + return new cl::opt<uint64_t>( + "rng-seed", cl::value_desc("seed"), cl::Hidden, + cl::desc("Seed for the random number generator"), cl::init(0)); + } +}; +} // namespace +static ManagedStatic<cl::opt<uint64_t>, CreateSeed> Seed; +void llvm::initRandomSeedOptions() { *Seed; } RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) { - LLVM_DEBUG(if (Seed == 0) dbgs() + LLVM_DEBUG(if (*Seed == 0) dbgs() << "Warning! Using unseeded random number generator.\n"); // Combine seed and salts using std::seed_seq. @@ -41,8 +51,8 @@ RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) { // twister constructor copies these correctly into its initial state. std::vector<uint32_t> 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 index 4e70eed28b862..dd4dded4cd1d8 100644 --- a/llvm/lib/Support/Signals.cpp +++ b/llvm/lib/Support/Signals.cpp @@ -12,6 +12,9 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Signals.h" + +#include "DebugOptions.h" + #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Config/llvm-config.h" @@ -39,15 +42,33 @@ using namespace llvm; // Use explicit storage to avoid accessing cl::opt in a signal handler. static bool DisableSymbolicationFlag = false; -static cl::opt<bool, true> - DisableSymbolication("disable-symbolication", - cl::desc("Disable symbolizing crash backtraces."), - cl::location(DisableSymbolicationFlag), cl::Hidden); -static std::string CrashDiagnosticsDirectory; -static cl::opt<std::string, true> - CrashDiagnosticsDir("crash-diagnostics-dir", cl::value_desc("directory"), - cl::desc("Directory for crash diagnostic files."), - cl::location(CrashDiagnosticsDirectory), cl::Hidden); +static ManagedStatic<std::string> CrashDiagnosticsDirectory; +namespace { +struct CreateDisableSymbolication { + static void *call() { + return new cl::opt<bool, true>( + "disable-symbolication", + cl::desc("Disable symbolizing crash backtraces."), + cl::location(DisableSymbolicationFlag), cl::Hidden); + } +}; +struct CreateCrashDiagnosticsDir { + static void *call() { + return new cl::opt<std::string, true>( + "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<cl::opt<bool, true>, CreateDisableSymbolication> + DisableSymbolication; + static ManagedStatic<cl::opt<std::string, true>, CreateCrashDiagnosticsDir> + CrashDiagnosticsDir; + *DisableSymbolication; + *CrashDiagnosticsDir; +} constexpr char DisableSymbolizationEnv[] = "LLVM_DISABLE_SYMBOLIZATION"; constexpr char LLVMSymbolizerPathEnv[] = "LLVM_SYMBOLIZER_PATH"; diff --git a/llvm/lib/Support/Statistic.cpp b/llvm/lib/Support/Statistic.cpp index e9308ab575abe..d95c8642c16e7 100644 --- a/llvm/lib/Support/Statistic.cpp +++ b/llvm/lib/Support/Statistic.cpp @@ -21,6 +21,9 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/Statistic.h" + +#include "DebugOptions.h" + #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" @@ -38,18 +41,22 @@ using namespace llvm; /// -stats - Command line option to cause transformations to emit stats about /// what they did. /// -static cl::opt<bool> EnableStats( - "stats", - cl::desc("Enable statistics output from program (available with Asserts)"), - cl::Hidden); - -static cl::opt<bool> StatsAsJSON("stats-json", - cl::desc("Display statistics as json data"), - cl::Hidden); - +static bool EnableStats; +static bool StatsAsJSON; static bool Enabled; static bool PrintOnExit; +void llvm::initStatisticOptions() { + static cl::opt<bool, true> registerEnableStats{ + "stats", + cl::desc( + "Enable statistics output from program (available with Asserts)"), + cl::location(EnableStats), cl::Hidden}; + static cl::opt<bool, true> registerStatsAsJson{ + "stats-json", cl::desc("Display statistics as json data"), + cl::location(StatsAsJSON), cl::Hidden}; +} + namespace { /// This class is used in a ManagedStatic so that it is created on demand (when /// the first statistic is bumped) and destroyed only when llvm_shutdown is @@ -128,9 +135,7 @@ void llvm::EnableStatistics(bool DoPrintOnExit) { PrintOnExit = DoPrintOnExit; } -bool llvm::AreStatisticsEnabled() { - return Enabled || EnableStats; -} +bool llvm::AreStatisticsEnabled() { return Enabled || EnableStats; } void StatisticInfo::sort() { llvm::stable_sort( diff --git a/llvm/lib/Support/TimeProfiler.cpp b/llvm/lib/Support/TimeProfiler.cpp index c37c74c61f3ce..8f2544e9e26d1 100644 --- a/llvm/lib/Support/TimeProfiler.cpp +++ b/llvm/lib/Support/TimeProfiler.cpp @@ -30,7 +30,7 @@ using namespace llvm; static std::mutex Mu; // List of all instances -static std::vector<TimeTraceProfiler *> +static ManagedStatic<std::vector<TimeTraceProfiler *>> ThreadTimeTraceProfilerInstances; // GUARDED_BY(Mu) // Per Thread instance static LLVM_THREAD_LOCAL TimeTraceProfiler *TimeTraceProfilerInstance = nullptr; @@ -128,7 +128,7 @@ struct llvm::TimeTraceProfiler { std::lock_guard<std::mutex> Lock(Mu); assert(Stack.empty() && "All profiler sections should be ended when calling write"); - assert(llvm::all_of(ThreadTimeTraceProfilerInstances, + assert(llvm::all_of(*ThreadTimeTraceProfilerInstances, [](const auto &TTP) { return TTP->Stack.empty(); }) && "All profiler sections should be ended when calling write"); @@ -156,7 +156,7 @@ struct llvm::TimeTraceProfiler { }; for (const Entry &E : Entries) writeEvent(E, this->Tid); - for (const TimeTraceProfiler *TTP : ThreadTimeTraceProfilerInstances) + for (const TimeTraceProfiler *TTP : *ThreadTimeTraceProfilerInstances) for (const Entry &E : TTP->Entries) writeEvent(E, TTP->Tid); @@ -164,7 +164,7 @@ struct llvm::TimeTraceProfiler { // longest one. // Find highest used thread id. uint64_t MaxTid = this->Tid; - for (const TimeTraceProfiler *TTP : ThreadTimeTraceProfilerInstances) + for (const TimeTraceProfiler *TTP : *ThreadTimeTraceProfilerInstances) MaxTid = std::max(MaxTid, TTP->Tid); // Combine all CountAndTotalPerName from threads into one. @@ -178,7 +178,7 @@ struct llvm::TimeTraceProfiler { }; for (const auto &Stat : CountAndTotalPerName) combineStat(Stat); - for (const TimeTraceProfiler *TTP : ThreadTimeTraceProfilerInstances) + for (const TimeTraceProfiler *TTP : *ThreadTimeTraceProfilerInstances) for (const auto &Stat : TTP->CountAndTotalPerName) combineStat(Stat); @@ -229,7 +229,7 @@ struct llvm::TimeTraceProfiler { writeMetadataEvent("process_name", Tid, ProcName); writeMetadataEvent("thread_name", Tid, ThreadName); - for (const TimeTraceProfiler *TTP : ThreadTimeTraceProfilerInstances) + for (const TimeTraceProfiler *TTP : *ThreadTimeTraceProfilerInstances) writeMetadataEvent("thread_name", TTP->Tid, TTP->ThreadName); J.arrayEnd(); @@ -273,16 +273,16 @@ void llvm::timeTraceProfilerInitialize(unsigned TimeTraceGranularity, void llvm::timeTraceProfilerCleanup() { delete TimeTraceProfilerInstance; std::lock_guard<std::mutex> Lock(Mu); - for (auto TTP : ThreadTimeTraceProfilerInstances) + for (auto TTP : *ThreadTimeTraceProfilerInstances) delete TTP; - ThreadTimeTraceProfilerInstances.clear(); + ThreadTimeTraceProfilerInstances->clear(); } // Finish TimeTraceProfilerInstance on a worker thread. // This doesn't remove the instance, just moves the pointer to global vector. void llvm::timeTraceProfilerFinishThread() { std::lock_guard<std::mutex> Lock(Mu); - ThreadTimeTraceProfilerInstances.push_back(TimeTraceProfilerInstance); + ThreadTimeTraceProfilerInstances->push_back(TimeTraceProfilerInstance); TimeTraceProfilerInstance = nullptr; } diff --git a/llvm/lib/Support/Timer.cpp b/llvm/lib/Support/Timer.cpp index 8d421db4f7b15..f025ecd3d45c4 100644 --- a/llvm/lib/Support/Timer.cpp +++ b/llvm/lib/Support/Timer.cpp @@ -11,6 +11,9 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Timer.h" + +#include "DebugOptions.h" + #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringMap.h" #include "llvm/Config/config.h" @@ -53,20 +56,41 @@ static ManagedStatic<sys::SmartMutex<true> > TimerLock; static ManagedStatic<SignpostEmitter> Signposts; namespace { - static cl::opt<bool> - TrackSpace("track-memory", cl::desc("Enable -time-passes memory " +struct CreateTrackSpace { + static void *call() { + return new cl::opt<bool>("track-memory", + cl::desc("Enable -time-passes memory " "tracking (this may be slow)"), - cl::Hidden); - - static cl::opt<std::string, true> - InfoOutputFilename("info-output-file", cl::value_desc("filename"), - cl::desc("File to append -stats and -timer output to"), - cl::Hidden, cl::location(getLibSupportInfoOutputFilename())); + cl::Hidden); + } +}; +static ManagedStatic<cl::opt<bool>, CreateTrackSpace> TrackSpace; +struct CreateInfoOutputFilename { + static void *call() { + return new cl::opt<std::string, true>( + "info-output-file", cl::value_desc("filename"), + cl::desc("File to append -stats and -timer output to"), cl::Hidden, + cl::location(getLibSupportInfoOutputFilename())); + } +}; +static ManagedStatic<cl::opt<std::string, true>, CreateInfoOutputFilename> + InfoOutputFilename; +struct CreateSortTimers { + static void *call() { + return new cl::opt<bool>( + "sort-timers", + cl::desc("In the report, sort the timers in each group " + "in wall clock time order"), + cl::init(true), cl::Hidden); + } +}; +ManagedStatic<cl::opt<bool>, CreateSortTimers> SortTimers; +} // namespace - static cl::opt<bool> - SortTimers("sort-timers", cl::desc("In the report, sort the timers in each group " - "in wall clock time order"), - cl::init(true), cl::Hidden); +void llvm::initTimerOptions() { + *TrackSpace; + *InfoOutputFilename; + *SortTimers; } std::unique_ptr<raw_fd_ostream> llvm::CreateInfoOutputFile() { @@ -125,7 +149,8 @@ Timer::~Timer() { } static inline size_t getMemUsage() { - if (!TrackSpace) return 0; + if (!*TrackSpace) + return 0; return sys::Process::GetMallocUsage(); } @@ -331,7 +356,7 @@ void TimerGroup::addTimer(Timer &T) { void TimerGroup::PrintQueuedTimers(raw_ostream &OS) { // Perhaps sort the timers in descending order by amount of time taken. - if (SortTimers) + if (*SortTimers) llvm::sort(TimersToPrint); TimeRecord Total; diff --git a/llvm/lib/Support/TypeSize.cpp b/llvm/lib/Support/TypeSize.cpp index 83d40d9cb0edd..abb81016a0bad 100644 --- a/llvm/lib/Support/TypeSize.cpp +++ b/llvm/lib/Support/TypeSize.cpp @@ -9,19 +9,35 @@ #include "llvm/Support/TypeSize.h" #include "llvm/Support/CommandLine.h" +#include "DebugOptions.h" + using namespace llvm; -/// The ScalableErrorAsWarning is a temporary measure to suppress errors from -/// using the wrong interface on a scalable vector. -cl::opt<bool> ScalableErrorAsWarning( - "treat-scalable-fixed-error-as-warning", cl::Hidden, cl::init(false), - cl::desc("Treat issues where a fixed-width property is requested from a " - "scalable type as a warning, instead of an error."), - cl::ZeroOrMore); +#ifndef STRICT_FIXED_SIZE_VECTORS +namespace { +struct CreateScalableErrorAsWarning { + /// 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<bool>( + "treat-scalable-fixed-error-as-warning", cl::Hidden, cl::init(false), + cl::desc( + "Treat issues where a fixed-width property is requested from a " + "scalable type as a warning, instead of an error."), + cl::ZeroOrMore); + } +}; +} // namespace +static ManagedStatic<cl::opt<bool>, CreateScalableErrorAsWarning> + ScalableErrorAsWarning; +void llvm::initTypeSizeOptions() { *ScalableErrorAsWarning; } +#else +void llvm::initTypeSizeOptions() {} +#endif void llvm::reportInvalidSizeRequest(const char *Msg) { #ifndef STRICT_FIXED_SIZE_VECTORS - if (ScalableErrorAsWarning) { + if (*ScalableErrorAsWarning) { WithColor::warning() << "Invalid size request on a scalable vector; " << Msg << "\n"; return; diff --git a/llvm/lib/Support/Windows/Signals.inc b/llvm/lib/Support/Windows/Signals.inc index df5fcb1b151bc..32186bbe51607 100644 --- a/llvm/lib/Support/Windows/Signals.inc +++ b/llvm/lib/Support/Windows/Signals.inc @@ -773,7 +773,7 @@ WriteWindowsDumpFile(PMINIDUMP_EXCEPTION_INFORMATION ExceptionInfo) { // (GetDumpFolder will return false either if the key is NULL or if there is // no valid DumpFolder value at its location). bool ExplicitDumpDirectorySet = true; - SmallString<MAX_PATH> DumpDirectory(CrashDiagnosticsDirectory); + SmallString<MAX_PATH> DumpDirectory(*CrashDiagnosticsDirectory); if (DumpDirectory.empty()) if (!GetDumpFolder(AppSpecificKey, DumpDirectory)) if (!GetDumpFolder(DefaultLocalDumpsKey, DumpDirectory)) diff --git a/llvm/lib/Support/WithColor.cpp b/llvm/lib/Support/WithColor.cpp index f8d2b01653073..b1aa709862d86 100644 --- a/llvm/lib/Support/WithColor.cpp +++ b/llvm/lib/Support/WithColor.cpp @@ -7,17 +7,31 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/WithColor.h" + +#include "DebugOptions.h" + #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" +#include "llvm/Support/ManagedStatic.h" using namespace llvm; -cl::OptionCategory llvm::ColorCategory("Color Options"); - -static cl::opt<cl::boolOrDefault> - UseColor("color", cl::cat(ColorCategory), - cl::desc("Use colors in output (default=autodetect)"), - cl::init(cl::BOU_UNSET)); +cl::OptionCategory &llvm::getColorCategory() { + static cl::OptionCategory ColorCategory("Color Options"); + return ColorCategory; +} +namespace { +struct CreateUseColor { + static void *call() { + return new cl::opt<cl::boolOrDefault>( + "color", cl::cat(getColorCategory()), + cl::desc("Use colors in output (default=autodetect)"), + cl::init(cl::BOU_UNSET)); + } +}; +} // namespace +static ManagedStatic<cl::opt<cl::boolOrDefault>, CreateUseColor> UseColor; +void llvm::initWithColorOptions() { *UseColor; } WithColor::WithColor(raw_ostream &OS, HighlightColor Color, ColorMode Mode) : OS(OS), Mode(Mode) { @@ -113,8 +127,8 @@ bool WithColor::colorsEnabled() { case ColorMode::Disable: return false; case ColorMode::Auto: - return UseColor == cl::BOU_UNSET ? OS.has_colors() - : UseColor == cl::BOU_TRUE; + return *UseColor == cl::BOU_UNSET ? OS.has_colors() + : *UseColor == cl::BOU_TRUE; } llvm_unreachable("All cases handled above."); } diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index abecc9cc0c8af..1ddbe944ec085 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -11325,8 +11325,8 @@ bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) { TagLoc = Parser.getTok().getLoc(); if (Parser.getTok().is(AsmToken::Identifier)) { StringRef Name = Parser.getTok().getIdentifier(); - Optional<unsigned> Ret = - ELFAttrs::attrTypeFromString(Name, ARMBuildAttrs::ARMAttributeTags); + Optional<unsigned> Ret = ELFAttrs::attrTypeFromString( + Name, ARMBuildAttrs::getARMAttributeTags()); if (!Ret.hasValue()) { Error(TagLoc, "attribute name not recognised: " + Name); return false; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index d6a32b4e967c0..12076b8c49c14 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -176,8 +176,8 @@ void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {} void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) { OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value); if (IsVerboseAsm) { - StringRef Name = - ELFAttrs::attrTypeAsString(Attribute, ARMBuildAttrs::ARMAttributeTags); + StringRef Name = ELFAttrs::attrTypeAsString( + Attribute, ARMBuildAttrs::getARMAttributeTags()); if (!Name.empty()) OS << "\t@ " << Name; } @@ -194,7 +194,7 @@ void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute, OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\""; if (IsVerboseAsm) { StringRef Name = ELFAttrs::attrTypeAsString( - Attribute, ARMBuildAttrs::ARMAttributeTags); + Attribute, ARMBuildAttrs::getARMAttributeTags()); if (!Name.empty()) OS << "\t@ " << Name; } @@ -215,7 +215,7 @@ void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute, if (IsVerboseAsm) OS << "\t@ " << ELFAttrs::attrTypeAsString(Attribute, - ARMBuildAttrs::ARMAttributeTags); + ARMBuildAttrs::getARMAttributeTags()); break; } OS << "\n"; diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 6be4373e5fc58..4127dd786d203 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -1970,7 +1970,7 @@ bool RISCVAsmParser::parseDirectiveAttribute() { if (Parser.getTok().is(AsmToken::Identifier)) { StringRef Name = Parser.getTok().getIdentifier(); Optional<unsigned> Ret = - ELFAttrs::attrTypeFromString(Name, RISCVAttrs::RISCVAttributeTags); + ELFAttrs::attrTypeFromString(Name, RISCVAttrs::getRISCVAttributeTags()); if (!Ret.hasValue()) { Error(TagLoc, "attribute name not recognised: " + Name); return false; diff --git a/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp index ca22cc45d063d..f4851bfb2a9cf 100644 --- a/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ b/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @@ -97,7 +97,7 @@ static Expected<std::unique_ptr<MemoryBuffer>> openBitcodeFile(StringRef Path) { int main(int argc, char **argv) { InitLLVM X(argc, argv); - cl::HideUnrelatedOptions({&BCAnalyzerCategory, &ColorCategory}); + cl::HideUnrelatedOptions({&BCAnalyzerCategory, &getColorCategory()}); cl::ParseCommandLineOptions(argc, argv, "llvm-bcanalyzer file analyzer\n"); ExitOnError ExitOnErr("llvm-bcanalyzer: "); diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index 1180e029f2553..a324ff710af5d 100644 --- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -623,7 +623,8 @@ int main(int argc, char **argv) { llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); - HideUnrelatedOptions({&DwarfDumpCategory, &SectionCategory, &ColorCategory}); + HideUnrelatedOptions( + {&DwarfDumpCategory, &SectionCategory, &getColorCategory()}); cl::ParseCommandLineOptions( argc, argv, "pretty-print DWARF debug information in object files" diff --git a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp index 9b01ff59afd63..ef4aec58d2e67 100644 --- a/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp +++ b/llvm/tools/llvm-libtool-darwin/llvm-libtool-darwin.cpp @@ -571,7 +571,7 @@ static Expected<Config> parseCommandLine(int Argc, char **Argv) { int main(int Argc, char **Argv) { InitLLVM X(Argc, Argv); - cl::HideUnrelatedOptions({&LibtoolCategory, &ColorCategory}); + cl::HideUnrelatedOptions({&LibtoolCategory, &getColorCategory()}); Expected<Config> ConfigOrErr = parseCommandLine(Argc, Argv); if (!ConfigOrErr) { WithColor::defaultErrorHandler(ConfigOrErr.takeError()); diff --git a/llvm/unittests/Support/ARMAttributeParser.cpp b/llvm/unittests/Support/ARMAttributeParser.cpp index 9a823ed1de7ee..61dfd6276e311 100644 --- a/llvm/unittests/Support/ARMAttributeParser.cpp +++ b/llvm/unittests/Support/ARMAttributeParser.cpp @@ -48,7 +48,7 @@ void testParseError(ArrayRef<uint8_t> bytes, const char *msg) { } bool testTagString(unsigned Tag, const char *name) { - return ELFAttrs::attrTypeAsString(Tag, ARMBuildAttrs::ARMAttributeTags) + return ELFAttrs::attrTypeAsString(Tag, ARMBuildAttrs::getARMAttributeTags()) .str() == name; } diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp index 7d880464e2665..a0352bc8a4c5e 100644 --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/unittests/Support/CommandLineTest.cpp @@ -110,7 +110,7 @@ TEST(CommandLineTest, ModifyExisitingOption) { ASSERT_NE(Retrieved->Categories.end(), find_if(Retrieved->Categories, [&](const llvm::cl::OptionCategory *Cat) { - return Cat == &cl::GeneralCategory; + return Cat == &cl::getGeneralCategory(); })) << "Incorrect default option category."; @@ -152,10 +152,10 @@ TEST(CommandLineTest, UseOptionCategory) { TEST(CommandLineTest, UseMultipleCategories) { StackOption<int> TestOption2("test-option2", cl::cat(TestCategory), - cl::cat(cl::GeneralCategory), - cl::cat(cl::GeneralCategory)); + cl::cat(cl::getGeneralCategory()), + cl::cat(cl::getGeneralCategory())); - // Make sure cl::GeneralCategory wasn't added twice. + // Make sure cl::getGeneralCategory() wasn't added twice. ASSERT_EQ(TestOption2.Categories.size(), 2U); ASSERT_NE(TestOption2.Categories.end(), @@ -166,9 +166,9 @@ TEST(CommandLineTest, UseMultipleCategories) { << "Failed to assign Option Category."; ASSERT_NE(TestOption2.Categories.end(), find_if(TestOption2.Categories, - [&](const llvm::cl::OptionCategory *Cat) { - return Cat == &cl::GeneralCategory; - })) + [&](const llvm::cl::OptionCategory *Cat) { + return Cat == &cl::getGeneralCategory(); + })) << "Failed to assign General Category."; cl::OptionCategory AnotherCategory("Additional test Options", "Description"); @@ -176,9 +176,9 @@ TEST(CommandLineTest, UseMultipleCategories) { cl::cat(AnotherCategory)); ASSERT_EQ(TestOption.Categories.end(), find_if(TestOption.Categories, - [&](const llvm::cl::OptionCategory *Cat) { - return Cat == &cl::GeneralCategory; - })) + [&](const llvm::cl::OptionCategory *Cat) { + return Cat == &cl::getGeneralCategory(); + })) << "Failed to remove General Category."; ASSERT_NE(TestOption.Categories.end(), find_if(TestOption.Categories, diff --git a/llvm/unittests/Support/RISCVAttributeParserTest.cpp b/llvm/unittests/Support/RISCVAttributeParserTest.cpp index 1458af604a5c5..02ffb366a8396 100644 --- a/llvm/unittests/Support/RISCVAttributeParserTest.cpp +++ b/llvm/unittests/Support/RISCVAttributeParserTest.cpp @@ -49,7 +49,7 @@ static bool testAttribute(unsigned Tag, unsigned Value, unsigned ExpectedTag, } static bool testTagString(unsigned Tag, const char *name) { - return ELFAttrs::attrTypeAsString(Tag, RISCVAttrs::RISCVAttributeTags) + return ELFAttrs::attrTypeAsString(Tag, RISCVAttrs::getRISCVAttributeTags()) .str() == name; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits