Index: llvm/include/llvm/Support/CommandLine.h =================================================================== --- llvm/include/llvm/Support/CommandLine.h +++ llvm/include/llvm/Support/CommandLine.h @@ -1406,7 +1406,7 @@ // Make sure we initialize the value with the default constructor for the // type. - opt_storage() : Value(DataType()), Default(DataType()) {} + opt_storage() : Value(DataType()), Default() {} template void setValue(const T &V, bool initial = false) { Value = V; Index: llvm/unittests/Support/CommandLineTest.cpp =================================================================== --- llvm/unittests/Support/CommandLineTest.cpp +++ llvm/unittests/Support/CommandLineTest.cpp @@ -1789,11 +1789,11 @@ TEST(CommandLineTest, Callback) { cl::ResetCommandLineParser(); - StackOption OptA("a", cl::desc("option a")); - StackOption OptB( + StackOption OptA("a", cl::desc("option a"), cl::init(false)); + StackOption OptB(cl::init(false), "b", cl::desc("option b -- This option turns on option a"), cl::callback([&](const bool &) { OptA = true; })); - StackOption OptC( + StackOption OptC(cl::init(false), "c", cl::desc("option c -- This option turns on options a and b"), cl::callback([&](const bool &) { OptB = true; })); StackOption> List( @@ -1904,7 +1904,7 @@ cl::ResetCommandLineParser(); // -option [sink] input [args] - StackOption Option("option"); + StackOption Option("option", cl::init(false)); StackOption> Sink(cl::Sink); StackOption Input(cl::Positional); StackOption> ExtraArgs(cl::ConsumeAfter); @@ -1930,4 +1930,60 @@ EXPECT_EQ(0, (int)ExtraArgs.size()); } +TEST(CommandLineTest, DefaultValue) { + cl::ResetCommandLineParser(); + + StackOption BoolOption("bool-option"); + StackOption StrOption("str-option"); + StackOption BoolInitOption("bool-init-option", cl::init(true)); + StackOption StrInitOption("str-init-option", + cl::init("str-default-value")); + + const char *Args[] = {"prog"}; // no options + + std::string Errs; + raw_string_ostream OS(Errs); + EXPECT_TRUE(cl::ParseCommandLineOptions(1, Args, StringRef(), &OS)); + EXPECT_TRUE(OS.str().empty()); + + EXPECT_TRUE(!BoolOption); + EXPECT_FALSE(BoolOption.Default.hasValue()); + EXPECT_EQ(0, BoolOption.getNumOccurrences()); + + EXPECT_EQ("", StrOption); + EXPECT_FALSE(StrOption.Default.hasValue()); + EXPECT_EQ(0, StrOption.getNumOccurrences()); + + EXPECT_TRUE(BoolInitOption); + EXPECT_TRUE(BoolInitOption.Default.hasValue()); + EXPECT_EQ(0, BoolInitOption.getNumOccurrences()); + + EXPECT_EQ("str-default-value", StrInitOption); + EXPECT_TRUE(StrInitOption.Default.hasValue()); + EXPECT_EQ(0, StrInitOption.getNumOccurrences()); + + const char *Args2[] = {"prog", "-bool-option", "-str-option=str-value", + "-bool-init-option=0", + "-str-init-option=str-init-value"}; + + EXPECT_TRUE(cl::ParseCommandLineOptions(5, Args2, StringRef(), &OS)); + EXPECT_TRUE(OS.str().empty()); + + EXPECT_TRUE(BoolOption); + EXPECT_FALSE(BoolOption.Default.hasValue()); + EXPECT_EQ(1, BoolOption.getNumOccurrences()); + + EXPECT_EQ("str-value", StrOption); + EXPECT_FALSE(StrOption.Default.hasValue()); + EXPECT_EQ(1, StrOption.getNumOccurrences()); + + EXPECT_FALSE(BoolInitOption); + EXPECT_TRUE(BoolInitOption.Default.hasValue()); + EXPECT_EQ(1, BoolInitOption.getNumOccurrences()); + + EXPECT_EQ("str-init-value", StrInitOption); + EXPECT_TRUE(StrInitOption.Default.hasValue()); + EXPECT_EQ(1, StrInitOption.getNumOccurrences()); +} + } // anonymous namespace