diff --git a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp --- a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp +++ b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp @@ -91,7 +91,7 @@ // By resetting the parser options, we lost the standard -help flag. llvm::cl::opt> 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 --- a/clang-tools-extra/clangd/indexer/IndexerMain.cpp +++ b/clang-tools-extra/clangd/indexer/IndexerMain.cpp @@ -124,7 +124,7 @@ )"; 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 --- a/clang/tools/clang-refactor/ClangRefactor.cpp +++ b/clang/tools/clang-refactor/ClangRefactor.cpp @@ -38,11 +38,11 @@ static cl::OptionCategory CommonRefactorOptions("Refactoring options"); static cl::opt Verbose("v", cl::desc("Use verbose output"), - cl::cat(cl::GeneralCategory), + cl::cat(cl::getGeneralCategory()), cl::sub(*cl::AllSubCommands)); static cl::opt Inplace("i", cl::desc("Inplace edit s"), - cl::cat(cl::GeneralCategory), + cl::cat(cl::getGeneralCategory()), cl::sub(*cl::AllSubCommands)); } // end namespace opts @@ -613,7 +613,7 @@ 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 --- a/llvm/docs/CommandLine.rst +++ b/llvm/docs/CommandLine.rst @@ -661,7 +661,7 @@ 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 --- a/llvm/include/llvm/Support/ARMAttributeParser.h +++ b/llvm/include/llvm/Support/ARMAttributeParser.h @@ -71,9 +71,9 @@ 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 --- 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 --- a/llvm/include/llvm/Support/CommandLine.h +++ b/llvm/include/llvm/Support/CommandLine.h @@ -202,7 +202,7 @@ }; // The general Option Category (used as default category). -extern OptionCategory GeneralCategory; +OptionCategory &getGeneralCategory(); //===----------------------------------------------------------------------===// // SubCommand class @@ -342,7 +342,7 @@ : 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 --- a/llvm/include/llvm/Support/RISCVAttributeParser.h +++ b/llvm/include/llvm/Support/RISCVAttributeParser.h @@ -27,9 +27,9 @@ 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 --- 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 --- a/llvm/include/llvm/Support/ScopedPrinter.h +++ b/llvm/include/llvm/Support/ScopedPrinter.h @@ -32,8 +32,9 @@ // "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 --- a/llvm/include/llvm/Support/WithColor.h +++ b/llvm/include/llvm/Support/WithColor.h @@ -20,7 +20,7 @@ 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 --- a/llvm/lib/Support/ARMBuildAttrs.cpp +++ b/llvm/lib/Support/ARMBuildAttrs.cpp @@ -63,6 +63,7 @@ {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 --- 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 @@ // 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 @@ removeArgument(); } -// Initialise the general option category. -OptionCategory llvm::cl::GeneralCategory("General options"); - void OptionCategory::registerCategory() { GlobalParser->registerCategory(this); } @@ -1293,10 +1293,12 @@ /*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 NewArgv; BumpPtrAllocator A; StringSaver Saver(A); @@ -1937,7 +1939,9 @@ static StringRef EqValue = "="; static StringRef EmptyOption = ""; 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 @@ 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 @@ 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 @@ } // 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> 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> - 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> - 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> - 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 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 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, 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 *ExtraVersionPrinters = nullptr; - #if defined(__GNUC__) // GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are // enabled. @@ -2528,59 +2433,203 @@ #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> 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> 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> 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> HHOp{ + "help-hidden", + cl::desc("Display all available options"), + cl::location(WrappedHiddenPrinter), + cl::Hidden, + cl::ValueDisallowed, + cl::cat(GenericCategory), + cl::sub(*AllSubCommands)}; + + cl::opt 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 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 ExtraVersionPrinters; + + // Define the --version option that prints out the LLVM version for the tool + VersionPrinter VersionPrinterInstance; + + cl::opt> 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 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> - VersOp("version", cl::desc("Display the version of this program"), - cl::location(VersionPrinterInstance), cl::ValueDisallowed, - cl::cat(GenericCategory)); + SmallVector, 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; - - ExtraVersionPrinters->push_back(func); + CommonOptions->ExtraVersionPrinters.push_back(func); } StringMap