]> granicus.if.org Git - llvm/commitdiff
[Support][CommandLine] Add cl::Option::setDefault()
authorEvgeny Mankov <evgeny.mankov@gmail.com>
Mon, 28 Aug 2017 13:39:43 +0000 (13:39 +0000)
committerEvgeny Mankov <evgeny.mankov@gmail.com>
Mon, 28 Aug 2017 13:39:43 +0000 (13:39 +0000)
Add abstract virtual method setDefault() to class Option and implement it in its inheritors in order to be able to set all the options to its default values in user's code without actually knowing all these options. For instance:

for (auto &OM : cl::getRegisteredOptions(*cl::TopLevelSubCommand)) {
  cl::Option *O = OM.second;
  O->setDefault();
}

Reviewed by: rampitec, Eugene.Zelenko, kasaurov

Differential Revision: http://reviews.llvm.org/D36877

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311887 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/CommandLine.h
unittests/Support/CommandLineTest.cpp

index 771b0a8c26a988697b9924d204f393a5c0a482a3..22d18194dd84cda1573163e11304d99ef6fd7fc8 100644 (file)
@@ -349,6 +349,8 @@ public:
 
   virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0;
 
+  virtual void setDefault() = 0;
+
   static void printHelpStr(StringRef HelpStr, size_t Indent,
                            size_t FirstLineIndentedBy);
 
@@ -1318,6 +1320,20 @@ class opt : public Option,
     }
   }
 
+  template <class T, class = typename std::enable_if<
+            std::is_assignable<T&, T>::value>::type>
+  void setDefaultImpl() {
+    const OptionValue<DataType> &V = this->getDefault();
+    if (V.hasValue())
+      this->setValue(V.getValue());
+  }
+
+  template <class T, class = typename std::enable_if<
+            !std::is_assignable<T&, T>::value>::type>
+  void setDefaultImpl(...) {}
+
+  void setDefault() override { setDefaultImpl<DataType>(); }
+
   void done() {
     addArgument();
     Parser.initialize();
@@ -1493,6 +1509,8 @@ class list : public Option, public list_storage<DataType, StorageClass> {
   void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override {
   }
 
+  void setDefault() override {}
+
   void done() {
     addArgument();
     Parser.initialize();
@@ -1634,6 +1652,8 @@ class bits : public Option, public bits_storage<DataType, Storage> {
   void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override {
   }
 
+  void setDefault() override {}
+
   void done() {
     addArgument();
     Parser.initialize();
@@ -1684,6 +1704,8 @@ class alias : public Option {
   void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const override {
   }
 
+  void setDefault() override { AliasFor->setDefault(); }
+
   ValueExpected getValueExpectedFlagDefault() const override {
     return AliasFor->getValueExpectedFlag();
   }
index 660df11446acb76b2a8e4d488d38de4ada7d6925..1fb0213b4d18fb2ff3d1decee3febfc85b64d9b3 100644 (file)
@@ -613,4 +613,39 @@ TEST(CommandLineTest, ResponseFiles) {
   llvm::sys::fs::remove(TestDir);
 }
 
+TEST(CommandLineTest, SetDefautValue) {
+  cl::ResetCommandLineParser();
+
+  StackOption<std::string> Opt1("opt1", cl::init("true"));
+  StackOption<bool> Opt2("opt2", cl::init(true));
+  cl::alias Alias("alias", llvm::cl::aliasopt(Opt2));
+  StackOption<int> Opt3("opt3", cl::init(3));
+
+  const char *args[] = {"prog", "-opt1=false", "-opt2", "-opt3"};
+
+  EXPECT_TRUE(
+    cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls()));
+
+  EXPECT_TRUE(Opt1 == "false");
+  EXPECT_TRUE(Opt2);
+  EXPECT_TRUE(Opt3 == 3);
+
+  Opt2 = false;
+  Opt3 = 1;
+
+  cl::ResetAllOptionOccurrences();
+
+  for (auto &OM : cl::getRegisteredOptions(*cl::TopLevelSubCommand)) {
+    cl::Option *O = OM.second;
+    if (O->ArgStr == "opt2") {
+      continue;
+    }
+    O->setDefault();
+  }
+
+  EXPECT_TRUE(Opt1 == "true");
+  EXPECT_TRUE(Opt2);
+  EXPECT_TRUE(Opt3 == 3);
+}
+
 }  // anonymous namespace