diff --git a/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h b/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h --- a/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h +++ b/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h @@ -43,6 +43,7 @@ WatchType watch_type; uint32_t watch_size; bool watch_type_specified; + lldb::LanguageType language_type; private: OptionGroupWatchpoint(const OptionGroupWatchpoint &) = delete; diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp --- a/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -835,8 +835,7 @@ m_arguments.push_back(arg); // Absorb the '-w' and '-s' options into our option group. - m_option_group.Append(&m_option_watchpoint, LLDB_OPT_SET_ALL, - LLDB_OPT_SET_1); + m_option_group.Append(&m_option_watchpoint, LLDB_OPT_SET_1, LLDB_OPT_SET_1); m_option_group.Finalize(); } @@ -990,6 +989,7 @@ : CommandObjectRaw( interpreter, "watchpoint set expression", "Set a watchpoint on an address by supplying an expression. " + "Use the '-l' option to specify the language of the expression. " "Use the '-w' option to specify the type of watchpoint and " "the '-s' option to specify the byte size to watch for. " "If no '-w' option is specified, it defaults to write. " @@ -1083,6 +1083,8 @@ options.SetKeepInMemory(false); options.SetTryAllThreads(true); options.SetTimeout(std::nullopt); + if (m_option_watchpoint.language_type != eLanguageTypeUnknown) + options.SetLanguage(m_option_watchpoint.language_type); ExpressionResults expr_result = target->EvaluateExpression(expr, frame, valobj_sp, options); diff --git a/lldb/source/Interpreter/OptionGroupWatchpoint.cpp b/lldb/source/Interpreter/OptionGroupWatchpoint.cpp --- a/lldb/source/Interpreter/OptionGroupWatchpoint.cpp +++ b/lldb/source/Interpreter/OptionGroupWatchpoint.cpp @@ -10,6 +10,7 @@ #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Target/Language.h" #include "lldb/lldb-enumerations.h" using namespace lldb; @@ -62,7 +63,17 @@ "Specify the type of watching to perform."}, {LLDB_OPT_SET_1, false, "size", 's', OptionParser::eRequiredArgument, nullptr, OptionEnumValues(g_watch_size), 0, eArgTypeByteSize, - "Number of bytes to use to watch a region."}}; + "Number of bytes to use to watch a region."}, + {LLDB_OPT_SET_2, + false, + "language", + 'l', + OptionParser::eRequiredArgument, + nullptr, + {}, + 0, + eArgTypeLanguage, + "Language of expression to run"}}; bool OptionGroupWatchpoint::IsWatchSizeSupported(uint32_t watch_size) { for (const auto& size : g_watch_size) { @@ -81,6 +92,18 @@ Status error; const int short_option = g_option_table[option_idx].short_option; switch (short_option) { + case 'l': { + language_type = Language::GetLanguageTypeFromString(option_arg); + if (language_type == eLanguageTypeUnknown) { + StreamString sstr; + sstr.Printf("Unknown language type: '%s' for expression. List of " + "supported languages:\n", + option_arg.str().c_str()); + Language::PrintSupportedLanguagesForExpressions(sstr, " ", "\n"); + error.SetErrorString(sstr.GetString()); + } + break; + } case 'w': { WatchType tmp_watch_type; tmp_watch_type = (WatchType)OptionArgParser::ToOptionEnum( @@ -108,6 +131,7 @@ watch_type_specified = false; watch_type = eWatchInvalid; watch_size = 0; + language_type = eLanguageTypeUnknown; } llvm::ArrayRef OptionGroupWatchpoint::GetDefinitions() { diff --git a/lldb/test/Shell/Watchpoint/ExpressionLanguage.test b/lldb/test/Shell/Watchpoint/ExpressionLanguage.test new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/Watchpoint/ExpressionLanguage.test @@ -0,0 +1,19 @@ +# RUN: %clangxx_host %p/Inputs/languages.cpp -g -o %t.out +# RUN: %lldb -b -o 'settings set interpreter.stop-command-source-on-error false' -s %s %t.out 2>&1 | FileCheck %s + +settings show interpreter.stop-command-source-on-error +# CHECK: interpreter.stop-command-source-on-error (boolean) = false + +b main +run +# CHECK: stopped +# CHECK-NEXT: stop reason = breakpoint + +watchpoint set expression -- &g_foo +# CHECK: Watchpoint created: + +watchpoint set expression -l c++ -- &g_bar +# CHECK: Watchpoint created: + +watchpoint set expression -l fake -- &g_baz +# CHECK: Unknown language type: 'fake' for expression. List of supported languages: diff --git a/lldb/test/Shell/Watchpoint/Inputs/languages.cpp b/lldb/test/Shell/Watchpoint/Inputs/languages.cpp new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/Watchpoint/Inputs/languages.cpp @@ -0,0 +1,12 @@ +#include +#include + +uint64_t g_foo = 5; +uint64_t g_bar = 6; +uint64_t g_baz = 7; + +int main() { + int val = 8; + printf("Hello world! %d\n", val); + return 0; +}