1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

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
This commit is contained in:
Mehdi Amini 2021-07-15 23:52:44 +00:00
parent 79801693ba
commit a9a8a9a361
32 changed files with 519 additions and 282 deletions

View File

@ -661,7 +661,7 @@ declared, the command line option ``-help-list`` becomes visible which will
print the command line options as uncategorized list. print the command line options as uncategorized list.
Note that Options that are not explicitly categorized will be placed in the Note that Options that are not explicitly categorized will be placed in the
``cl::GeneralCategory`` category. ``cl::getGeneralCategory()`` category.
.. _Reference Guide: .. _Reference Guide:

View File

@ -71,9 +71,9 @@ class ARMAttributeParser : public ELFAttributeParser {
public: public:
ARMAttributeParser(ScopedPrinter *sw) ARMAttributeParser(ScopedPrinter *sw)
: ELFAttributeParser(sw, ARMBuildAttrs::ARMAttributeTags, "aeabi") {} : ELFAttributeParser(sw, ARMBuildAttrs::getARMAttributeTags(), "aeabi") {}
ARMAttributeParser() ARMAttributeParser()
: ELFAttributeParser(ARMBuildAttrs::ARMAttributeTags, "aeabi") {} : ELFAttributeParser(ARMBuildAttrs::getARMAttributeTags(), "aeabi") {}
}; };
} }

View File

@ -23,7 +23,7 @@
namespace llvm { namespace llvm {
namespace ARMBuildAttrs { namespace ARMBuildAttrs {
extern const TagNameMap ARMAttributeTags; const TagNameMap &getARMAttributeTags();
enum SpecialAttr { enum SpecialAttr {
// This is for the .cpu asm attr. It translates into one or more // This is for the .cpu asm attr. It translates into one or more

View File

@ -202,7 +202,7 @@ public:
}; };
// The general Option Category (used as default category). // The general Option Category (used as default category).
extern OptionCategory GeneralCategory; OptionCategory &getGeneralCategory();
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// SubCommand class // SubCommand class
@ -342,7 +342,7 @@ protected:
: NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0), : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0),
HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0), HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0),
FullyInitialized(false), Position(0), AdditionalVals(0) { FullyInitialized(false), Position(0), AdditionalVals(0) {
Categories.push_back(&GeneralCategory); Categories.push_back(&getGeneralCategory());
} }
inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; } inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; }

View File

@ -27,9 +27,9 @@ class RISCVAttributeParser : public ELFAttributeParser {
public: public:
RISCVAttributeParser(ScopedPrinter *sw) RISCVAttributeParser(ScopedPrinter *sw)
: ELFAttributeParser(sw, RISCVAttrs::RISCVAttributeTags, "riscv") {} : ELFAttributeParser(sw, RISCVAttrs::getRISCVAttributeTags(), "riscv") {}
RISCVAttributeParser() RISCVAttributeParser()
: ELFAttributeParser(RISCVAttrs::RISCVAttributeTags, "riscv") {} : ELFAttributeParser(RISCVAttrs::getRISCVAttributeTags(), "riscv") {}
}; };
} // namespace llvm } // namespace llvm

View File

@ -22,7 +22,7 @@
namespace llvm { namespace llvm {
namespace RISCVAttrs { namespace RISCVAttrs {
extern const TagNameMap RISCVAttributeTags; const TagNameMap &getRISCVAttributeTags();
enum AttrType : unsigned { enum AttrType : unsigned {
// Attribute types in ELF/.riscv.attributes. // Attribute types in ELF/.riscv.attributes.

View File

@ -32,8 +32,9 @@ template <typename T> struct EnumEntry {
// "Advanced Micro Devices X86-64" on GNU style // "Advanced Micro Devices X86-64" on GNU style
StringRef AltName; StringRef AltName;
T Value; T Value;
EnumEntry(StringRef N, StringRef A, T V) : Name(N), AltName(A), Value(V) {} constexpr EnumEntry(StringRef N, StringRef A, T V)
EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {} : Name(N), AltName(A), Value(V) {}
constexpr EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {}
}; };
struct HexNumber { struct HexNumber {

View File

@ -20,7 +20,7 @@ namespace cl {
class OptionCategory; class OptionCategory;
} }
extern cl::OptionCategory ColorCategory; extern cl::OptionCategory &getColorCategory();
// Symbolic names for various syntax elements. // Symbolic names for various syntax elements.
enum class HighlightColor { enum class HighlightColor {

View File

@ -63,6 +63,7 @@ static const TagNameItem tagData[] = {
{ARMBuildAttrs::ABI_align_preserved, "Tag_ABI_align8_preserved"}, {ARMBuildAttrs::ABI_align_preserved, "Tag_ABI_align8_preserved"},
}; };
const TagNameMap llvm::ARMBuildAttrs::ARMAttributeTags(tagData, constexpr TagNameMap ARMAttributeTags{tagData};
sizeof(tagData) / const TagNameMap &llvm::ARMBuildAttrs::getARMAttributeTags() {
sizeof(TagNameItem)); return ARMAttributeTags;
}

View File

@ -16,6 +16,9 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "DebugOptions.h"
#include "llvm-c/Support.h" #include "llvm-c/Support.h"
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h" #include "llvm/ADT/Optional.h"
@ -462,7 +465,7 @@ void Option::addCategory(OptionCategory &C) {
// Maintain backward compatibility by replacing the default GeneralCategory // Maintain backward compatibility by replacing the default GeneralCategory
// if it's still set. Otherwise, just add the new one. The 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. // 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; Categories[0] = &C;
else if (!is_contained(Categories, &C)) else if (!is_contained(Categories, &C))
Categories.push_back(&C); Categories.push_back(&C);
@ -475,9 +478,6 @@ void Option::reset() {
removeArgument(); removeArgument();
} }
// Initialise the general option category.
OptionCategory llvm::cl::GeneralCategory("General options");
void OptionCategory::registerCategory() { void OptionCategory::registerCategory() {
GlobalParser->registerCategory(this); GlobalParser->registerCategory(this);
} }
@ -1293,10 +1293,12 @@ bool cl::readConfigFile(StringRef CfgFile, StringSaver &Saver,
/*MarkEOLs=*/false, /*RelativeNames=*/true); /*MarkEOLs=*/false, /*RelativeNames=*/true);
} }
static void initCommonOptions();
bool cl::ParseCommandLineOptions(int argc, const char *const *argv, bool cl::ParseCommandLineOptions(int argc, const char *const *argv,
StringRef Overview, raw_ostream *Errs, StringRef Overview, raw_ostream *Errs,
const char *EnvVar, const char *EnvVar,
bool LongOptionsUseDoubleDash) { bool LongOptionsUseDoubleDash) {
initCommonOptions();
SmallVector<const char *, 20> NewArgv; SmallVector<const char *, 20> NewArgv;
BumpPtrAllocator A; BumpPtrAllocator A;
StringSaver Saver(A); StringSaver Saver(A);
@ -1937,7 +1939,9 @@ unsigned generic_parser_base::findOption(StringRef Name) {
static StringRef EqValue = "=<value>"; static StringRef EqValue = "=<value>";
static StringRef EmptyOption = "<empty>"; static StringRef EmptyOption = "<empty>";
static StringRef OptionPrefix = " ="; 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, static bool shouldPrintOption(StringRef Name, StringRef Description,
const Option &O) { const Option &O) {
@ -1955,7 +1959,7 @@ size_t generic_parser_base::getOptionWidth(const Option &O) const {
if (!shouldPrintOption(Name, getDescription(i), O)) if (!shouldPrintOption(Name, getDescription(i), O))
continue; continue;
size_t NameSize = Name.empty() ? EmptyOption.size() : Name.size(); size_t NameSize = Name.empty() ? EmptyOption.size() : Name.size();
Size = std::max(Size, NameSize + OptionPrefixesSize); Size = std::max(Size, NameSize + getOptionPrefixesSize());
} }
return Size; return Size;
} else { } else {
@ -1994,7 +1998,7 @@ void generic_parser_base::printOptionInfo(const Option &O,
StringRef Description = getDescription(i); StringRef Description = getDescription(i);
if (!shouldPrintOption(OptionName, Description, O)) if (!shouldPrintOption(OptionName, Description, O))
continue; continue;
size_t FirstLineIndent = OptionName.size() + OptionPrefixesSize; size_t FirstLineIndent = OptionName.size() + getOptionPrefixesSize();
outs() << OptionPrefix << OptionName; outs() << OptionPrefix << OptionName;
if (OptionName.empty()) { if (OptionName.empty()) {
outs() << EmptyOption; outs() << EmptyOption;
@ -2374,105 +2378,6 @@ public:
} // End anonymous namespace } // 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__) #if defined(__GNUC__)
// GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are // GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are
// enabled. // enabled.
@ -2528,59 +2433,203 @@ public:
#endif #endif
OS << '\n'; OS << '\n';
} }
void operator=(bool OptionWasSpecified) { void operator=(bool OptionWasSpecified);
if (!OptionWasSpecified) };
return;
if (OverrideVersionPrinter != nullptr) { struct CommandLineCommonOptions {
OverrideVersionPrinter(outs()); // Declare the four HelpPrinter instances that are used to print out help, or
exit(0); // help-hidden as an uncategorized list or in categories.
} HelpPrinter UncategorizedNormalPrinter{false};
print(); 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"};
// Iterate over any registered extra printers and call them to add further // Define uncategorized help printers.
// information. // --help-list is hidden by default because if Option categories are being
if (ExtraVersionPrinters != nullptr) { // used then --help behaves the same as --help-list.
outs() << '\n'; cl::opt<HelpPrinter, true, parser<bool>> HLOp{
for (const auto &I : *ExtraVersionPrinters) "help-list",
I(outs()); 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)};
exit(0); 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 } // End anonymous namespace
// Define the --version option that prints out the LLVM version for the tool // Lazy-initialized global instance of options controlling the command-line
static VersionPrinter VersionPrinterInstance; // parser and general handling.
static ManagedStatic<CommandLineCommonOptions> CommonOptions;
static cl::opt<VersionPrinter, true, parser<bool>> static void initCommonOptions() {
VersOp("version", cl::desc("Display the version of this program"), *CommonOptions;
cl::location(VersionPrinterInstance), cl::ValueDisallowed, initDebugCounterOptions();
cl::cat(GenericCategory)); 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);
}
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);
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;
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. // Utility function for printing the help message.
void cl::PrintHelpMessage(bool Hidden, bool Categorized) { void cl::PrintHelpMessage(bool Hidden, bool Categorized) {
if (!Hidden && !Categorized) if (!Hidden && !Categorized)
UncategorizedNormalPrinter.printHelp(); CommonOptions->UncategorizedNormalPrinter.printHelp();
else if (!Hidden && Categorized) else if (!Hidden && Categorized)
CategorizedNormalPrinter.printHelp(); CommonOptions->CategorizedNormalPrinter.printHelp();
else if (Hidden && !Categorized) else if (Hidden && !Categorized)
UncategorizedHiddenPrinter.printHelp(); CommonOptions->UncategorizedHiddenPrinter.printHelp();
else else
CategorizedHiddenPrinter.printHelp(); CommonOptions->CategorizedHiddenPrinter.printHelp();
} }
/// Utility function for printing version number. /// 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) { void cl::AddExtraVersionPrinter(VersionPrinterTy func) {
if (!ExtraVersionPrinters) CommonOptions->ExtraVersionPrinters.push_back(func);
ExtraVersionPrinters = new std::vector<VersionPrinterTy>;
ExtraVersionPrinters->push_back(func);
} }
StringMap<Option *> &cl::getRegisteredOptions(SubCommand &Sub) { StringMap<Option *> &cl::getRegisteredOptions(SubCommand &Sub) {
@ -2596,10 +2645,10 @@ cl::getRegisteredSubcommands() {
} }
void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) { void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) {
initCommonOptions();
for (auto &I : Sub.OptionsMap) { for (auto &I : Sub.OptionsMap) {
for (auto &Cat : I.second->Categories) { for (auto &Cat : I.second->Categories) {
if (Cat != &Category && if (Cat != &Category && Cat != &CommonOptions->GenericCategory)
Cat != &GenericCategory)
I.second->setHiddenFlag(cl::ReallyHidden); 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, void cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories,
SubCommand &Sub) { SubCommand &Sub) {
initCommonOptions();
for (auto &I : Sub.OptionsMap) { for (auto &I : Sub.OptionsMap) {
for (auto &Cat : I.second->Categories) { 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); I.second->setHiddenFlag(cl::ReallyHidden);
} }
} }

View File

@ -30,6 +30,8 @@
#include "llvm/Support/circular_raw_ostream.h" #include "llvm/Support/circular_raw_ostream.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "DebugOptions.h"
#undef isCurrentDebugType #undef isCurrentDebugType
#undef setCurrentDebugType #undef setCurrentDebugType
#undef setCurrentDebugTypes #undef setCurrentDebugTypes
@ -79,21 +81,32 @@ void setCurrentDebugTypes(const char **Types, unsigned Count) {
// All Debug.h functionality is a no-op in NDEBUG mode. // All Debug.h functionality is a no-op in NDEBUG mode.
#ifndef NDEBUG #ifndef NDEBUG
// -debug - Command line option to enable the DEBUG statements in the passes. namespace {
// This flag may only be enabled in debug builds. struct CreateDebug {
static cl::opt<bool, true> static void *call() {
Debug("debug", cl::desc("Enable debug output"), cl::Hidden, return new cl::opt<bool, true>("debug", cl::desc("Enable debug output"),
cl::location(DebugFlag)); cl::Hidden, cl::location(DebugFlag));
}
};
// -debug-buffer-size - Buffer the last N characters of debug output // -debug-buffer-size - Buffer the last N characters of debug output
//until program termination. //until program termination.
static cl::opt<unsigned> struct CreateDebugBufferSize {
DebugBufferSize("debug-buffer-size", static void *call() {
cl::desc("Buffer the last N characters of debug output " return new cl::opt<unsigned>(
"until program termination. " "debug-buffer-size",
"[default 0 -- immediate print-out]"), cl::desc("Buffer the last N characters of debug output "
cl::Hidden, "until program termination. "
cl::init(0)); "[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 { namespace {
@ -108,15 +121,33 @@ struct DebugOnlyOpt {
CurrentDebugType->push_back(std::string(dbgType)); CurrentDebugType->push_back(std::string(dbgType));
} }
}; };
} // namespace } // namespace
static DebugOnlyOpt DebugOnlyOptLoc; static DebugOnlyOpt DebugOnlyOptLoc;
static cl::opt<DebugOnlyOpt, true, cl::parser<std::string> > namespace {
DebugOnly("debug-only", cl::desc("Enable a specific type of debug output (comma separated list of types)"), struct CreateDebugOnly {
cl::Hidden, cl::ZeroOrMore, cl::value_desc("debug string"), static void *call() {
cl::location(DebugOnlyOptLoc), cl::ValueRequired); 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. // Signal handlers - dump debug output on termination.
static void debug_user_sig_handler(void *Cookie) { static void debug_user_sig_handler(void *Cookie) {
// This is a bit sneaky. Since this is under #ifndef NDEBUG, we // This is a bit sneaky. Since this is under #ifndef NDEBUG, we
@ -134,10 +165,10 @@ raw_ostream &llvm::dbgs() {
static struct dbgstream { static struct dbgstream {
circular_raw_ostream strm; circular_raw_ostream strm;
dbgstream() : dbgstream()
strm(errs(), "*** Debug Log Output ***\n", : strm(errs(), "*** Debug Log Output ***\n",
(!EnableDebugBuffering || !DebugFlag) ? 0 : DebugBufferSize) { (!EnableDebugBuffering || !DebugFlag) ? 0 : *DebugBufferSize) {
if (EnableDebugBuffering && DebugFlag && DebugBufferSize != 0) if (EnableDebugBuffering && DebugFlag && *DebugBufferSize != 0)
// TODO: Add a handler for SIGUSER1-type signals so the user can // TODO: Add a handler for SIGUSER1-type signals so the user can
// force a debug dump. // force a debug dump.
sys::AddSignalHandler(&debug_user_sig_handler, nullptr); sys::AddSignalHandler(&debug_user_sig_handler, nullptr);

View File

@ -1,4 +1,7 @@
#include "llvm/Support/DebugCounter.h" #include "llvm/Support/DebugCounter.h"
#include "DebugOptions.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Format.h" #include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/ManagedStatic.h"
@ -40,17 +43,29 @@ private:
} }
} }
}; };
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 } // namespace
// Create our command line option. static ManagedStatic<DebugCounterList, CreateDebugCounterOption>
static DebugCounterList DebugCounterOption( DebugCounterOption;
"debug-counter", cl::Hidden, static bool PrintDebugCounter;
cl::desc("Comma separated list of debug counter skip and count"),
cl::CommaSeparated, cl::ZeroOrMore, cl::location(DebugCounter::instance()));
static cl::opt<bool> PrintDebugCounter( void llvm::initDebugCounterOptions() {
"print-debug-counter", cl::Hidden, cl::init(false), cl::Optional, *DebugCounterOption;
cl::desc("Print out debug counter info after all counters accumulated")); 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; static ManagedStatic<DebugCounter> DC;

View File

@ -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

View File

@ -16,7 +16,7 @@
using namespace llvm; using namespace llvm;
using namespace llvm::ELFAttrs; using namespace llvm::ELFAttrs;
static const EnumEntry<unsigned> tagNames[] = { static constexpr EnumEntry<unsigned> tagNames[] = {
{"Tag_File", ELFAttrs::File}, {"Tag_File", ELFAttrs::File},
{"Tag_Section", ELFAttrs::Section}, {"Tag_Section", ELFAttrs::Section},
{"Tag_Symbol", ELFAttrs::Symbol}, {"Tag_Symbol", ELFAttrs::Symbol},

View File

@ -11,6 +11,9 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Support/GraphWriter.h" #include "llvm/Support/GraphWriter.h"
#include "DebugOptions.h"
#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
@ -29,8 +32,21 @@
using namespace llvm; using namespace llvm;
static cl::opt<bool> ViewBackground("view-background", cl::Hidden, #ifdef __APPLE__
cl::desc("Execute graph viewer in the background. Creates tmp file litter.")); 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 llvm::DOT::EscapeString(const std::string &Label) {
std::string Str(Label); std::string Str(Label);

View File

@ -11,7 +11,7 @@
using namespace llvm; using namespace llvm;
using namespace llvm::RISCVAttrs; using namespace llvm::RISCVAttrs;
static const TagNameItem tagData[] = { static constexpr TagNameItem tagData[] = {
{STACK_ALIGN, "Tag_stack_align"}, {STACK_ALIGN, "Tag_stack_align"},
{ARCH, "Tag_arch"}, {ARCH, "Tag_arch"},
{UNALIGNED_ACCESS, "Tag_unaligned_access"}, {UNALIGNED_ACCESS, "Tag_unaligned_access"},
@ -20,6 +20,7 @@ static const TagNameItem tagData[] = {
{PRIV_SPEC_REVISION, "Tag_priv_spec_revision"}, {PRIV_SPEC_REVISION, "Tag_priv_spec_revision"},
}; };
const TagNameMap llvm::RISCVAttrs::RISCVAttributeTags(tagData, constexpr TagNameMap RISCVAttributeTags{tagData};
sizeof(tagData) / const TagNameMap &llvm::RISCVAttrs::getRISCVAttributeTags() {
sizeof(TagNameItem)); return RISCVAttributeTags;
}

View File

@ -13,6 +13,9 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Support/RandomNumberGenerator.h" #include "llvm/Support/RandomNumberGenerator.h"
#include "DebugOptions.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
@ -25,13 +28,20 @@
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "rng" #define DEBUG_TYPE "rng"
namespace {
static cl::opt<uint64_t> Seed("rng-seed", cl::value_desc("seed"), cl::Hidden, struct CreateSeed {
cl::desc("Seed for the random number generator"), static void *call() {
cl::init(0)); 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) { RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) {
LLVM_DEBUG(if (Seed == 0) dbgs() LLVM_DEBUG(if (*Seed == 0) dbgs()
<< "Warning! Using unseeded random number generator.\n"); << "Warning! Using unseeded random number generator.\n");
// Combine seed and salts using std::seed_seq. // 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. // twister constructor copies these correctly into its initial state.
std::vector<uint32_t> Data; std::vector<uint32_t> Data;
Data.resize(2 + Salt.size()); Data.resize(2 + Salt.size());
Data[0] = Seed; Data[0] = *Seed;
Data[1] = Seed >> 32; Data[1] = *Seed >> 32;
llvm::copy(Salt, Data.begin() + 2); llvm::copy(Salt, Data.begin() + 2);

View File

@ -12,6 +12,9 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Support/Signals.h" #include "llvm/Support/Signals.h"
#include "DebugOptions.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/Config/llvm-config.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. // Use explicit storage to avoid accessing cl::opt in a signal handler.
static bool DisableSymbolicationFlag = false; static bool DisableSymbolicationFlag = false;
static cl::opt<bool, true> static ManagedStatic<std::string> CrashDiagnosticsDirectory;
DisableSymbolication("disable-symbolication", namespace {
cl::desc("Disable symbolizing crash backtraces."), struct CreateDisableSymbolication {
cl::location(DisableSymbolicationFlag), cl::Hidden); static void *call() {
static std::string CrashDiagnosticsDirectory; return new cl::opt<bool, true>(
static cl::opt<std::string, true> "disable-symbolication",
CrashDiagnosticsDir("crash-diagnostics-dir", cl::value_desc("directory"), cl::desc("Disable symbolizing crash backtraces."),
cl::desc("Directory for crash diagnostic files."), cl::location(DisableSymbolicationFlag), cl::Hidden);
cl::location(CrashDiagnosticsDirectory), 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 DisableSymbolizationEnv[] = "LLVM_DISABLE_SYMBOLIZATION";
constexpr char LLVMSymbolizerPathEnv[] = "LLVM_SYMBOLIZER_PATH"; constexpr char LLVMSymbolizerPathEnv[] = "LLVM_SYMBOLIZER_PATH";

View File

@ -21,6 +21,9 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "DebugOptions.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
@ -38,18 +41,22 @@ using namespace llvm;
/// -stats - Command line option to cause transformations to emit stats about /// -stats - Command line option to cause transformations to emit stats about
/// what they did. /// what they did.
/// ///
static cl::opt<bool> EnableStats( static bool EnableStats;
"stats", static bool StatsAsJSON;
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 Enabled; static bool Enabled;
static bool PrintOnExit; 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 { namespace {
/// This class is used in a ManagedStatic so that it is created on demand (when /// 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 /// the first statistic is bumped) and destroyed only when llvm_shutdown is
@ -128,9 +135,7 @@ void llvm::EnableStatistics(bool DoPrintOnExit) {
PrintOnExit = DoPrintOnExit; PrintOnExit = DoPrintOnExit;
} }
bool llvm::AreStatisticsEnabled() { bool llvm::AreStatisticsEnabled() { return Enabled || EnableStats; }
return Enabled || EnableStats;
}
void StatisticInfo::sort() { void StatisticInfo::sort() {
llvm::stable_sort( llvm::stable_sort(

View File

@ -30,7 +30,7 @@ using namespace llvm;
static std::mutex Mu; static std::mutex Mu;
// List of all instances // List of all instances
static std::vector<TimeTraceProfiler *> static ManagedStatic<std::vector<TimeTraceProfiler *>>
ThreadTimeTraceProfilerInstances; // GUARDED_BY(Mu) ThreadTimeTraceProfilerInstances; // GUARDED_BY(Mu)
// Per Thread instance // Per Thread instance
static LLVM_THREAD_LOCAL TimeTraceProfiler *TimeTraceProfilerInstance = nullptr; static LLVM_THREAD_LOCAL TimeTraceProfiler *TimeTraceProfilerInstance = nullptr;
@ -128,7 +128,7 @@ struct llvm::TimeTraceProfiler {
std::lock_guard<std::mutex> Lock(Mu); std::lock_guard<std::mutex> Lock(Mu);
assert(Stack.empty() && assert(Stack.empty() &&
"All profiler sections should be ended when calling write"); "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(); }) && [](const auto &TTP) { return TTP->Stack.empty(); }) &&
"All profiler sections should be ended when calling write"); "All profiler sections should be ended when calling write");
@ -156,7 +156,7 @@ struct llvm::TimeTraceProfiler {
}; };
for (const Entry &E : Entries) for (const Entry &E : Entries)
writeEvent(E, this->Tid); writeEvent(E, this->Tid);
for (const TimeTraceProfiler *TTP : ThreadTimeTraceProfilerInstances) for (const TimeTraceProfiler *TTP : *ThreadTimeTraceProfilerInstances)
for (const Entry &E : TTP->Entries) for (const Entry &E : TTP->Entries)
writeEvent(E, TTP->Tid); writeEvent(E, TTP->Tid);
@ -164,7 +164,7 @@ struct llvm::TimeTraceProfiler {
// longest one. // longest one.
// Find highest used thread id. // Find highest used thread id.
uint64_t MaxTid = this->Tid; uint64_t MaxTid = this->Tid;
for (const TimeTraceProfiler *TTP : ThreadTimeTraceProfilerInstances) for (const TimeTraceProfiler *TTP : *ThreadTimeTraceProfilerInstances)
MaxTid = std::max(MaxTid, TTP->Tid); MaxTid = std::max(MaxTid, TTP->Tid);
// Combine all CountAndTotalPerName from threads into one. // Combine all CountAndTotalPerName from threads into one.
@ -178,7 +178,7 @@ struct llvm::TimeTraceProfiler {
}; };
for (const auto &Stat : CountAndTotalPerName) for (const auto &Stat : CountAndTotalPerName)
combineStat(Stat); combineStat(Stat);
for (const TimeTraceProfiler *TTP : ThreadTimeTraceProfilerInstances) for (const TimeTraceProfiler *TTP : *ThreadTimeTraceProfilerInstances)
for (const auto &Stat : TTP->CountAndTotalPerName) for (const auto &Stat : TTP->CountAndTotalPerName)
combineStat(Stat); combineStat(Stat);
@ -229,7 +229,7 @@ struct llvm::TimeTraceProfiler {
writeMetadataEvent("process_name", Tid, ProcName); writeMetadataEvent("process_name", Tid, ProcName);
writeMetadataEvent("thread_name", Tid, ThreadName); writeMetadataEvent("thread_name", Tid, ThreadName);
for (const TimeTraceProfiler *TTP : ThreadTimeTraceProfilerInstances) for (const TimeTraceProfiler *TTP : *ThreadTimeTraceProfilerInstances)
writeMetadataEvent("thread_name", TTP->Tid, TTP->ThreadName); writeMetadataEvent("thread_name", TTP->Tid, TTP->ThreadName);
J.arrayEnd(); J.arrayEnd();
@ -273,16 +273,16 @@ void llvm::timeTraceProfilerInitialize(unsigned TimeTraceGranularity,
void llvm::timeTraceProfilerCleanup() { void llvm::timeTraceProfilerCleanup() {
delete TimeTraceProfilerInstance; delete TimeTraceProfilerInstance;
std::lock_guard<std::mutex> Lock(Mu); std::lock_guard<std::mutex> Lock(Mu);
for (auto TTP : ThreadTimeTraceProfilerInstances) for (auto TTP : *ThreadTimeTraceProfilerInstances)
delete TTP; delete TTP;
ThreadTimeTraceProfilerInstances.clear(); ThreadTimeTraceProfilerInstances->clear();
} }
// Finish TimeTraceProfilerInstance on a worker thread. // Finish TimeTraceProfilerInstance on a worker thread.
// This doesn't remove the instance, just moves the pointer to global vector. // This doesn't remove the instance, just moves the pointer to global vector.
void llvm::timeTraceProfilerFinishThread() { void llvm::timeTraceProfilerFinishThread() {
std::lock_guard<std::mutex> Lock(Mu); std::lock_guard<std::mutex> Lock(Mu);
ThreadTimeTraceProfilerInstances.push_back(TimeTraceProfilerInstance); ThreadTimeTraceProfilerInstances->push_back(TimeTraceProfilerInstance);
TimeTraceProfilerInstance = nullptr; TimeTraceProfilerInstance = nullptr;
} }

View File

@ -11,6 +11,9 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Support/Timer.h" #include "llvm/Support/Timer.h"
#include "DebugOptions.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#include "llvm/Config/config.h" #include "llvm/Config/config.h"
@ -53,20 +56,41 @@ static ManagedStatic<sys::SmartMutex<true> > TimerLock;
static ManagedStatic<SignpostEmitter> Signposts; static ManagedStatic<SignpostEmitter> Signposts;
namespace { namespace {
static cl::opt<bool> struct CreateTrackSpace {
TrackSpace("track-memory", cl::desc("Enable -time-passes memory " static void *call() {
return new cl::opt<bool>("track-memory",
cl::desc("Enable -time-passes memory "
"tracking (this may be slow)"), "tracking (this may be slow)"),
cl::Hidden); 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<std::string, true> void llvm::initTimerOptions() {
InfoOutputFilename("info-output-file", cl::value_desc("filename"), *TrackSpace;
cl::desc("File to append -stats and -timer output to"), *InfoOutputFilename;
cl::Hidden, cl::location(getLibSupportInfoOutputFilename())); *SortTimers;
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);
} }
std::unique_ptr<raw_fd_ostream> llvm::CreateInfoOutputFile() { std::unique_ptr<raw_fd_ostream> llvm::CreateInfoOutputFile() {
@ -125,7 +149,8 @@ Timer::~Timer() {
} }
static inline size_t getMemUsage() { static inline size_t getMemUsage() {
if (!TrackSpace) return 0; if (!*TrackSpace)
return 0;
return sys::Process::GetMallocUsage(); return sys::Process::GetMallocUsage();
} }
@ -331,7 +356,7 @@ void TimerGroup::addTimer(Timer &T) {
void TimerGroup::PrintQueuedTimers(raw_ostream &OS) { void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
// Perhaps sort the timers in descending order by amount of time taken. // Perhaps sort the timers in descending order by amount of time taken.
if (SortTimers) if (*SortTimers)
llvm::sort(TimersToPrint); llvm::sort(TimersToPrint);
TimeRecord Total; TimeRecord Total;

View File

@ -9,19 +9,35 @@
#include "llvm/Support/TypeSize.h" #include "llvm/Support/TypeSize.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "DebugOptions.h"
using namespace llvm; using namespace llvm;
/// The ScalableErrorAsWarning is a temporary measure to suppress errors from #ifndef STRICT_FIXED_SIZE_VECTORS
/// using the wrong interface on a scalable vector. namespace {
cl::opt<bool> ScalableErrorAsWarning( struct CreateScalableErrorAsWarning {
"treat-scalable-fixed-error-as-warning", cl::Hidden, cl::init(false), /// The ScalableErrorAsWarning is a temporary measure to suppress errors from
cl::desc("Treat issues where a fixed-width property is requested from a " /// using the wrong interface on a scalable vector.
"scalable type as a warning, instead of an error."), static void *call() {
cl::ZeroOrMore); 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) { void llvm::reportInvalidSizeRequest(const char *Msg) {
#ifndef STRICT_FIXED_SIZE_VECTORS #ifndef STRICT_FIXED_SIZE_VECTORS
if (ScalableErrorAsWarning) { if (*ScalableErrorAsWarning) {
WithColor::warning() << "Invalid size request on a scalable vector; " << Msg WithColor::warning() << "Invalid size request on a scalable vector; " << Msg
<< "\n"; << "\n";
return; return;

View File

@ -773,7 +773,7 @@ WriteWindowsDumpFile(PMINIDUMP_EXCEPTION_INFORMATION ExceptionInfo) {
// (GetDumpFolder will return false either if the key is NULL or if there is // (GetDumpFolder will return false either if the key is NULL or if there is
// no valid DumpFolder value at its location). // no valid DumpFolder value at its location).
bool ExplicitDumpDirectorySet = true; bool ExplicitDumpDirectorySet = true;
SmallString<MAX_PATH> DumpDirectory(CrashDiagnosticsDirectory); SmallString<MAX_PATH> DumpDirectory(*CrashDiagnosticsDirectory);
if (DumpDirectory.empty()) if (DumpDirectory.empty())
if (!GetDumpFolder(AppSpecificKey, DumpDirectory)) if (!GetDumpFolder(AppSpecificKey, DumpDirectory))
if (!GetDumpFolder(DefaultLocalDumpsKey, DumpDirectory)) if (!GetDumpFolder(DefaultLocalDumpsKey, DumpDirectory))

View File

@ -7,17 +7,31 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Support/WithColor.h" #include "llvm/Support/WithColor.h"
#include "DebugOptions.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h" #include "llvm/Support/Error.h"
#include "llvm/Support/ManagedStatic.h"
using namespace llvm; using namespace llvm;
cl::OptionCategory llvm::ColorCategory("Color Options"); cl::OptionCategory &llvm::getColorCategory() {
static cl::OptionCategory ColorCategory("Color Options");
static cl::opt<cl::boolOrDefault> return ColorCategory;
UseColor("color", cl::cat(ColorCategory), }
cl::desc("Use colors in output (default=autodetect)"), namespace {
cl::init(cl::BOU_UNSET)); 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) WithColor::WithColor(raw_ostream &OS, HighlightColor Color, ColorMode Mode)
: OS(OS), Mode(Mode) { : OS(OS), Mode(Mode) {
@ -113,8 +127,8 @@ bool WithColor::colorsEnabled() {
case ColorMode::Disable: case ColorMode::Disable:
return false; return false;
case ColorMode::Auto: case ColorMode::Auto:
return UseColor == cl::BOU_UNSET ? OS.has_colors() return *UseColor == cl::BOU_UNSET ? OS.has_colors()
: UseColor == cl::BOU_TRUE; : *UseColor == cl::BOU_TRUE;
} }
llvm_unreachable("All cases handled above."); llvm_unreachable("All cases handled above.");
} }

View File

@ -11325,8 +11325,8 @@ bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
TagLoc = Parser.getTok().getLoc(); TagLoc = Parser.getTok().getLoc();
if (Parser.getTok().is(AsmToken::Identifier)) { if (Parser.getTok().is(AsmToken::Identifier)) {
StringRef Name = Parser.getTok().getIdentifier(); StringRef Name = Parser.getTok().getIdentifier();
Optional<unsigned> Ret = Optional<unsigned> Ret = ELFAttrs::attrTypeFromString(
ELFAttrs::attrTypeFromString(Name, ARMBuildAttrs::ARMAttributeTags); Name, ARMBuildAttrs::getARMAttributeTags());
if (!Ret.hasValue()) { if (!Ret.hasValue()) {
Error(TagLoc, "attribute name not recognised: " + Name); Error(TagLoc, "attribute name not recognised: " + Name);
return false; return false;

View File

@ -176,8 +176,8 @@ void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {}
void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) { void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value); OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
if (IsVerboseAsm) { if (IsVerboseAsm) {
StringRef Name = StringRef Name = ELFAttrs::attrTypeAsString(
ELFAttrs::attrTypeAsString(Attribute, ARMBuildAttrs::ARMAttributeTags); Attribute, ARMBuildAttrs::getARMAttributeTags());
if (!Name.empty()) if (!Name.empty())
OS << "\t@ " << Name; OS << "\t@ " << Name;
} }
@ -194,7 +194,7 @@ void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\""; OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\"";
if (IsVerboseAsm) { if (IsVerboseAsm) {
StringRef Name = ELFAttrs::attrTypeAsString( StringRef Name = ELFAttrs::attrTypeAsString(
Attribute, ARMBuildAttrs::ARMAttributeTags); Attribute, ARMBuildAttrs::getARMAttributeTags());
if (!Name.empty()) if (!Name.empty())
OS << "\t@ " << Name; OS << "\t@ " << Name;
} }
@ -215,7 +215,7 @@ void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
if (IsVerboseAsm) if (IsVerboseAsm)
OS << "\t@ " OS << "\t@ "
<< ELFAttrs::attrTypeAsString(Attribute, << ELFAttrs::attrTypeAsString(Attribute,
ARMBuildAttrs::ARMAttributeTags); ARMBuildAttrs::getARMAttributeTags());
break; break;
} }
OS << "\n"; OS << "\n";

View File

@ -1970,7 +1970,7 @@ bool RISCVAsmParser::parseDirectiveAttribute() {
if (Parser.getTok().is(AsmToken::Identifier)) { if (Parser.getTok().is(AsmToken::Identifier)) {
StringRef Name = Parser.getTok().getIdentifier(); StringRef Name = Parser.getTok().getIdentifier();
Optional<unsigned> Ret = Optional<unsigned> Ret =
ELFAttrs::attrTypeFromString(Name, RISCVAttrs::RISCVAttributeTags); ELFAttrs::attrTypeFromString(Name, RISCVAttrs::getRISCVAttributeTags());
if (!Ret.hasValue()) { if (!Ret.hasValue()) {
Error(TagLoc, "attribute name not recognised: " + Name); Error(TagLoc, "attribute name not recognised: " + Name);
return false; return false;

View File

@ -623,7 +623,8 @@ int main(int argc, char **argv) {
llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargetMCs(); llvm::InitializeAllTargetMCs();
HideUnrelatedOptions({&DwarfDumpCategory, &SectionCategory, &ColorCategory}); HideUnrelatedOptions(
{&DwarfDumpCategory, &SectionCategory, &getColorCategory()});
cl::ParseCommandLineOptions( cl::ParseCommandLineOptions(
argc, argv, argc, argv,
"pretty-print DWARF debug information in object files" "pretty-print DWARF debug information in object files"

View File

@ -571,7 +571,7 @@ static Expected<Config> parseCommandLine(int Argc, char **Argv) {
int main(int Argc, char **Argv) { int main(int Argc, char **Argv) {
InitLLVM X(Argc, Argv); InitLLVM X(Argc, Argv);
cl::HideUnrelatedOptions({&LibtoolCategory, &ColorCategory}); cl::HideUnrelatedOptions({&LibtoolCategory, &getColorCategory()});
Expected<Config> ConfigOrErr = parseCommandLine(Argc, Argv); Expected<Config> ConfigOrErr = parseCommandLine(Argc, Argv);
if (!ConfigOrErr) { if (!ConfigOrErr) {
WithColor::defaultErrorHandler(ConfigOrErr.takeError()); WithColor::defaultErrorHandler(ConfigOrErr.takeError());

View File

@ -48,7 +48,7 @@ void testParseError(ArrayRef<uint8_t> bytes, const char *msg) {
} }
bool testTagString(unsigned Tag, const char *name) { bool testTagString(unsigned Tag, const char *name) {
return ELFAttrs::attrTypeAsString(Tag, ARMBuildAttrs::ARMAttributeTags) return ELFAttrs::attrTypeAsString(Tag, ARMBuildAttrs::getARMAttributeTags())
.str() == name; .str() == name;
} }

View File

@ -110,7 +110,7 @@ TEST(CommandLineTest, ModifyExisitingOption) {
ASSERT_NE(Retrieved->Categories.end(), ASSERT_NE(Retrieved->Categories.end(),
find_if(Retrieved->Categories, find_if(Retrieved->Categories,
[&](const llvm::cl::OptionCategory *Cat) { [&](const llvm::cl::OptionCategory *Cat) {
return Cat == &cl::GeneralCategory; return Cat == &cl::getGeneralCategory();
})) }))
<< "Incorrect default option category."; << "Incorrect default option category.";
@ -152,10 +152,10 @@ TEST(CommandLineTest, UseOptionCategory) {
TEST(CommandLineTest, UseMultipleCategories) { TEST(CommandLineTest, UseMultipleCategories) {
StackOption<int> TestOption2("test-option2", cl::cat(TestCategory), StackOption<int> TestOption2("test-option2", cl::cat(TestCategory),
cl::cat(cl::GeneralCategory), cl::cat(cl::getGeneralCategory()),
cl::cat(cl::GeneralCategory)); 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_EQ(TestOption2.Categories.size(), 2U);
ASSERT_NE(TestOption2.Categories.end(), ASSERT_NE(TestOption2.Categories.end(),
@ -166,9 +166,9 @@ TEST(CommandLineTest, UseMultipleCategories) {
<< "Failed to assign Option Category."; << "Failed to assign Option Category.";
ASSERT_NE(TestOption2.Categories.end(), ASSERT_NE(TestOption2.Categories.end(),
find_if(TestOption2.Categories, find_if(TestOption2.Categories,
[&](const llvm::cl::OptionCategory *Cat) { [&](const llvm::cl::OptionCategory *Cat) {
return Cat == &cl::GeneralCategory; return Cat == &cl::getGeneralCategory();
})) }))
<< "Failed to assign General Category."; << "Failed to assign General Category.";
cl::OptionCategory AnotherCategory("Additional test Options", "Description"); cl::OptionCategory AnotherCategory("Additional test Options", "Description");
@ -176,9 +176,9 @@ TEST(CommandLineTest, UseMultipleCategories) {
cl::cat(AnotherCategory)); cl::cat(AnotherCategory));
ASSERT_EQ(TestOption.Categories.end(), ASSERT_EQ(TestOption.Categories.end(),
find_if(TestOption.Categories, find_if(TestOption.Categories,
[&](const llvm::cl::OptionCategory *Cat) { [&](const llvm::cl::OptionCategory *Cat) {
return Cat == &cl::GeneralCategory; return Cat == &cl::getGeneralCategory();
})) }))
<< "Failed to remove General Category."; << "Failed to remove General Category.";
ASSERT_NE(TestOption.Categories.end(), ASSERT_NE(TestOption.Categories.end(),
find_if(TestOption.Categories, find_if(TestOption.Categories,

View File

@ -49,7 +49,7 @@ static bool testAttribute(unsigned Tag, unsigned Value, unsigned ExpectedTag,
} }
static bool testTagString(unsigned Tag, const char *name) { static bool testTagString(unsigned Tag, const char *name) {
return ELFAttrs::attrTypeAsString(Tag, RISCVAttrs::RISCVAttributeTags) return ELFAttrs::attrTypeAsString(Tag, RISCVAttrs::getRISCVAttributeTags())
.str() == name; .str() == name;
} }