mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +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:
parent
79801693ba
commit
a9a8a9a361
@ -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:
|
||||||
|
|
||||||
|
@ -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") {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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; }
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
};
|
||||||
|
|
||||||
|
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)
|
if (!OptionWasSpecified)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (OverrideVersionPrinter != nullptr) {
|
if (CommonOptions->OverrideVersionPrinter != nullptr) {
|
||||||
OverrideVersionPrinter(outs());
|
CommonOptions->OverrideVersionPrinter(outs());
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
print();
|
print();
|
||||||
|
|
||||||
// Iterate over any registered extra printers and call them to add further
|
// Iterate over any registered extra printers and call them to add further
|
||||||
// information.
|
// information.
|
||||||
if (ExtraVersionPrinters != nullptr) {
|
if (!CommonOptions->ExtraVersionPrinters.empty()) {
|
||||||
outs() << '\n';
|
outs() << '\n';
|
||||||
for (const auto &I : *ExtraVersionPrinters)
|
for (const auto &I : CommonOptions->ExtraVersionPrinters)
|
||||||
I(outs());
|
I(outs());
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
} // End anonymous namespace
|
|
||||||
|
|
||||||
// Define the --version option that prints out the LLVM version for the tool
|
void HelpPrinterWrapper::operator=(bool Value) {
|
||||||
static VersionPrinter VersionPrinterInstance;
|
if (!Value)
|
||||||
|
return;
|
||||||
|
|
||||||
static cl::opt<VersionPrinter, true, parser<bool>>
|
// Decide which printer to invoke. If more than one option category is
|
||||||
VersOp("version", cl::desc("Display the version of this program"),
|
// registered then it is useful to show the categorized help instead of
|
||||||
cl::location(VersionPrinterInstance), cl::ValueDisallowed,
|
// uncategorized help.
|
||||||
cl::cat(GenericCategory));
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
return new cl::opt<unsigned>(
|
||||||
|
"debug-buffer-size",
|
||||||
cl::desc("Buffer the last N characters of debug output "
|
cl::desc("Buffer the last N characters of debug output "
|
||||||
"until program termination. "
|
"until program termination. "
|
||||||
"[default 0 -- immediate print-out]"),
|
"[default 0 -- immediate print-out]"),
|
||||||
cl::Hidden,
|
cl::Hidden, cl::init(0));
|
||||||
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 {
|
||||||
|
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::Hidden, cl::ZeroOrMore, cl::value_desc("debug string"),
|
||||||
cl::location(DebugOnlyOptLoc), cl::ValueRequired);
|
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);
|
||||||
|
@ -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:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// Create our command line option.
|
struct CreateDebugCounterOption {
|
||||||
static DebugCounterList DebugCounterOption(
|
static void *call() {
|
||||||
|
return new DebugCounterList(
|
||||||
"debug-counter", cl::Hidden,
|
"debug-counter", cl::Hidden,
|
||||||
cl::desc("Comma separated list of debug counter skip and count"),
|
cl::desc("Comma separated list of debug counter skip and count"),
|
||||||
cl::CommaSeparated, cl::ZeroOrMore, cl::location(DebugCounter::instance()));
|
cl::CommaSeparated, cl::ZeroOrMore,
|
||||||
|
cl::location(DebugCounter::instance()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
static cl::opt<bool> PrintDebugCounter(
|
static ManagedStatic<DebugCounterList, CreateDebugCounterOption>
|
||||||
"print-debug-counter", cl::Hidden, cl::init(false), cl::Optional,
|
DebugCounterOption;
|
||||||
|
static bool PrintDebugCounter;
|
||||||
|
|
||||||
|
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"));
|
cl::desc("Print out debug counter info after all counters accumulated"));
|
||||||
|
}
|
||||||
|
|
||||||
static ManagedStatic<DebugCounter> DC;
|
static ManagedStatic<DebugCounter> DC;
|
||||||
|
|
||||||
|
29
lib/Support/DebugOptions.h
Normal file
29
lib/Support/DebugOptions.h
Normal 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
|
@ -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},
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
struct CreateDisableSymbolication {
|
||||||
|
static void *call() {
|
||||||
|
return new cl::opt<bool, true>(
|
||||||
|
"disable-symbolication",
|
||||||
cl::desc("Disable symbolizing crash backtraces."),
|
cl::desc("Disable symbolizing crash backtraces."),
|
||||||
cl::location(DisableSymbolicationFlag), cl::Hidden);
|
cl::location(DisableSymbolicationFlag), cl::Hidden);
|
||||||
static std::string CrashDiagnosticsDirectory;
|
}
|
||||||
static cl::opt<std::string, true>
|
};
|
||||||
CrashDiagnosticsDir("crash-diagnostics-dir", cl::value_desc("directory"),
|
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::desc("Directory for crash diagnostic files."),
|
||||||
cl::location(CrashDiagnosticsDirectory), cl::Hidden);
|
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";
|
||||||
|
@ -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(
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 cl::opt<std::string, true>
|
};
|
||||||
InfoOutputFilename("info-output-file", cl::value_desc("filename"),
|
static ManagedStatic<cl::opt<bool>, CreateTrackSpace> TrackSpace;
|
||||||
cl::desc("File to append -stats and -timer output to"),
|
struct CreateInfoOutputFilename {
|
||||||
cl::Hidden, cl::location(getLibSupportInfoOutputFilename()));
|
static void *call() {
|
||||||
|
return new cl::opt<std::string, true>(
|
||||||
static cl::opt<bool>
|
"info-output-file", cl::value_desc("filename"),
|
||||||
SortTimers("sort-timers", cl::desc("In the report, sort the timers in each group "
|
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"),
|
"in wall clock time order"),
|
||||||
cl::init(true), cl::Hidden);
|
cl::init(true), cl::Hidden);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ManagedStatic<cl::opt<bool>, CreateSortTimers> SortTimers;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void llvm::initTimerOptions() {
|
||||||
|
*TrackSpace;
|
||||||
|
*InfoOutputFilename;
|
||||||
|
*SortTimers;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -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 {
|
||||||
|
/// 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),
|
"treat-scalable-fixed-error-as-warning", cl::Hidden, cl::init(false),
|
||||||
cl::desc("Treat issues where a fixed-width property is requested from a "
|
cl::desc(
|
||||||
|
"Treat issues where a fixed-width property is requested from a "
|
||||||
"scalable type as a warning, instead of an error."),
|
"scalable type as a warning, instead of an error."),
|
||||||
cl::ZeroOrMore);
|
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;
|
||||||
|
@ -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))
|
||||||
|
@ -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),
|
}
|
||||||
|
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::desc("Use colors in output (default=autodetect)"),
|
||||||
cl::init(cl::BOU_UNSET));
|
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.");
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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";
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
|
@ -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());
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(),
|
||||||
@ -167,7 +167,7 @@ TEST(CommandLineTest, UseMultipleCategories) {
|
|||||||
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.";
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ TEST(CommandLineTest, UseMultipleCategories) {
|
|||||||
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(),
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user