summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2011-04-05 18:54:36 +0000
committerAndrew Trick <atrick@apple.com>2011-04-05 18:54:36 +0000
commitce96902d88d473697f05c0465952dae374be564e (patch)
tree8dc714413e3a45a808e238a9091a6059d4575638 /lib
parent5dc0c503725c56aa74656b7c1221340f238bfa3f (diff)
downloadllvm-ce96902d88d473697f05c0465952dae374be564e.tar.gz
llvm-ce96902d88d473697f05c0465952dae374be564e.tar.bz2
llvm-ce96902d88d473697f05c0465952dae374be564e.tar.xz
Added *hidden* flags -print-options and -print-all-options so
developers can see if their driver changed any cl::Option's. The current implementation isn't perfect but handles most kinds of options. This is nice to have when decomposing the stages of compilation and moving between different drivers. It's also a good sanity check when comparing results produced by different command line invocations that are expected to produce the comparable results. Note: This is not an attempt to prolong the life of cl::Option. On the contrary, it's a placeholder for a feature that must exist when cl::Option is replaced by a more appropriate framework. A new framework needs: a central option registry, dynamic name lookup, non-global containers of option values (e.g. per-module, per-function), *and* the ability to print options values and their defaults at any point during compilation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128910 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Support/CommandLine.cpp176
1 files changed, 150 insertions, 26 deletions
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 7e744993a7..164177f497 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -908,8 +908,6 @@ void alias::printOptionInfo(size_t GlobalWidth) const {
errs().indent(GlobalWidth-L-6) << " - " << HelpStr << "\n";
}
-
-
//===----------------------------------------------------------------------===//
// Parser Implementation code...
//
@@ -939,7 +937,11 @@ void basic_parser_impl::printOptionInfo(const Option &O,
outs().indent(GlobalWidth-getOptionWidth(O)) << " - " << O.HelpStr << '\n';
}
-
+void basic_parser_impl::printOptionName(const Option &O,
+ size_t GlobalWidth) const {
+ outs() << " -" << O.ArgStr;
+ outs().indent(GlobalWidth-std::strlen(O.ArgStr));
+}
// parser<bool> implementation
@@ -1083,6 +1085,89 @@ void generic_parser_base::printOptionInfo(const Option &O,
}
}
+static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff
+
+// printGenericOptionDiff - Print the value of this option and it's default.
+//
+// "Generic" options have each value mapped to a name.
+void generic_parser_base::
+printGenericOptionDiff(const Option &O, const GenericOptionValue &Value,
+ const GenericOptionValue &Default,
+ size_t GlobalWidth) const {
+ outs() << " -" << O.ArgStr;
+ outs().indent(GlobalWidth-std::strlen(O.ArgStr));
+
+ unsigned NumOpts = getNumOptions();
+ for (unsigned i = 0; i != NumOpts; ++i) {
+ if (Value.compare(getOptionValue(i)))
+ continue;
+
+ outs() << "= " << getOption(i);
+ size_t L = std::strlen(getOption(i));
+ size_t NumSpaces = MaxOptWidth > L ? MaxOptWidth - L : 0;
+ outs().indent(NumSpaces) << " (default: ";
+ for (unsigned j = 0; j != NumOpts; ++j) {
+ if (Default.compare(getOptionValue(j)))
+ continue;
+ outs() << getOption(j);
+ break;
+ }
+ outs() << ")\n";
+ return;
+ }
+ outs() << "= *unknown option value*\n";
+}
+
+// printOptionDiff - Specializations for printing basic value types.
+//
+#define PRINT_OPT_DIFF(T) \
+ void parser<T>:: \
+ printOptionDiff(const Option &O, T V, OptionValue<T> D, \
+ size_t GlobalWidth) const { \
+ printOptionName(O, GlobalWidth); \
+ std::string Str; \
+ { \
+ raw_string_ostream SS(Str); \
+ SS << V; \
+ } \
+ outs() << "= " << Str; \
+ size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0;\
+ outs().indent(NumSpaces) << " (default: "; \
+ if (D.hasValue()) \
+ outs() << D.getValue(); \
+ else \
+ outs() << "*no default*"; \
+ outs() << ")\n"; \
+ } \
+
+PRINT_OPT_DIFF(bool);
+PRINT_OPT_DIFF(boolOrDefault);
+PRINT_OPT_DIFF(int);
+PRINT_OPT_DIFF(unsigned);
+PRINT_OPT_DIFF(double);
+PRINT_OPT_DIFF(float);
+PRINT_OPT_DIFF(char);
+
+void parser<std::string>::
+printOptionDiff(const Option &O, StringRef V, OptionValue<std::string> D,
+ size_t GlobalWidth) const {
+ printOptionName(O, GlobalWidth);
+ outs() << "= " << V;
+ size_t NumSpaces = MaxOptWidth > V.size() ? MaxOptWidth - V.size() : 0;
+ outs().indent(NumSpaces) << " (default: ";
+ if (D.hasValue())
+ outs() << D.getValue();
+ else
+ outs() << "*no default*";
+ outs() << ")\n";
+}
+
+// Print a placeholder for options that don't yet support printOptionDiff().
+void basic_parser_impl::
+printOptionNoValue(const Option &O, size_t GlobalWidth) const {
+ printOptionName(O, GlobalWidth);
+ outs() << "= *cannot print option value*\n";
+}
//===----------------------------------------------------------------------===//
// -help and -help-hidden option implementation
@@ -1094,6 +1179,35 @@ static int OptNameCompare(const void *LHS, const void *RHS) {
return strcmp(((pair_ty*)LHS)->first, ((pair_ty*)RHS)->first);
}
+// Copy Options into a vector so we can sort them as we like.
+static void
+sortOpts(StringMap<Option*> &OptMap,
+ SmallVectorImpl< std::pair<const char *, Option*> > &Opts,
+ bool ShowHidden) {
+ SmallPtrSet<Option*, 128> OptionSet; // Duplicate option detection.
+
+ for (StringMap<Option*>::iterator I = OptMap.begin(), E = OptMap.end();
+ I != E; ++I) {
+ // Ignore really-hidden options.
+ if (I->second->getOptionHiddenFlag() == ReallyHidden)
+ continue;
+
+ // Unless showhidden is set, ignore hidden flags.
+ if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden)
+ continue;
+
+ // If we've already seen this option, don't add it to the list again.
+ if (!OptionSet.insert(I->second))
+ continue;
+
+ Opts.push_back(std::pair<const char *, Option*>(I->getKey().data(),
+ I->second));
+ }
+
+ // Sort the options list alphabetically.
+ qsort(Opts.data(), Opts.size(), sizeof(Opts[0]), OptNameCompare);
+}
+
namespace {
class HelpPrinter {
@@ -1115,30 +1229,8 @@ public:
StringMap<Option*> OptMap;
GetOptionInfo(PositionalOpts, SinkOpts, OptMap);
- // Copy Options into a vector so we can sort them as we like.
SmallVector<std::pair<const char *, Option*>, 128> Opts;
- SmallPtrSet<Option*, 128> OptionSet; // Duplicate option detection.
-
- for (StringMap<Option*>::iterator I = OptMap.begin(), E = OptMap.end();
- I != E; ++I) {
- // Ignore really-hidden options.
- if (I->second->getOptionHiddenFlag() == ReallyHidden)
- continue;
-
- // Unless showhidden is set, ignore hidden flags.
- if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden)
- continue;
-
- // If we've already seen this option, don't add it to the list again.
- if (!OptionSet.insert(I->second))
- continue;
-
- Opts.push_back(std::pair<const char *, Option*>(I->getKey().data(),
- I->second));
- }
-
- // Sort the options list alphabetically.
- qsort(Opts.data(), Opts.size(), sizeof(Opts[0]), OptNameCompare);
+ sortOpts(OptMap, Opts, ShowHidden);
if (ProgramOverview)
outs() << "OVERVIEW: " << ProgramOverview << "\n";
@@ -1197,6 +1289,38 @@ static cl::opt<HelpPrinter, true, parser<bool> >
HHOp("help-hidden", cl::desc("Display all available options"),
cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed);
+static cl::opt<bool>
+PrintOptions("print-options",
+ cl::desc("Print non-default options after command line parsing"),
+ cl::Hidden, cl::init(false));
+
+static cl::opt<bool>
+PrintAllOptions("print-all-options",
+ cl::desc("Print all option values after command line parsing"),
+ cl::Hidden, cl::init(false));
+
+// Print the value of each option.
+void cl::PrintOptionValues() {
+ if (!PrintOptions && !PrintAllOptions) return;
+
+ // Get all the options.
+ SmallVector<Option*, 4> PositionalOpts;
+ SmallVector<Option*, 4> SinkOpts;
+ StringMap<Option*> OptMap;
+ GetOptionInfo(PositionalOpts, SinkOpts, OptMap);
+
+ SmallVector<std::pair<const char *, Option*>, 128> Opts;
+ sortOpts(OptMap, 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 void (*OverrideVersionPrinter)() = 0;
static int TargetArraySortFn(const void *LHS, const void *RHS) {