1//===-- OptionGroupWatchpoint.cpp -----------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Interpreter/OptionGroupWatchpoint.h"
10
11#include "lldb/Host/OptionParser.h"
12#include "lldb/Interpreter/OptionArgParser.h"
13#include "lldb/Target/Language.h"
14#include "lldb/lldb-enumerations.h"
15
16using namespace lldb;
17using namespace lldb_private;
18
19static constexpr OptionEnumValueElement g_watch_type[] = {
20    {
21        OptionGroupWatchpoint::eWatchRead,
22        "read",
23        "Watch for read",
24    },
25    {
26        OptionGroupWatchpoint::eWatchWrite,
27        "write",
28        "Watch for write",
29    },
30    {
31        OptionGroupWatchpoint::eWatchModify,
32        "modify",
33        "Watch for modifications",
34    },
35    {
36        OptionGroupWatchpoint::eWatchReadWrite,
37        "read_write",
38        "Watch for read/write",
39    },
40};
41
42static constexpr OptionDefinition g_option_table[] = {
43    {LLDB_OPT_SET_1, false, "watch", 'w', OptionParser::eRequiredArgument,
44     nullptr, OptionEnumValues(g_watch_type), 0, eArgTypeWatchType,
45     "Specify the type of watching to perform."},
46    {LLDB_OPT_SET_1, false, "size", 's', OptionParser::eRequiredArgument,
47     nullptr, {}, 0, eArgTypeByteSize,
48     "Number of bytes to use to watch a region."},
49    {LLDB_OPT_SET_2,
50     false,
51     "language",
52     'l',
53     OptionParser::eRequiredArgument,
54     nullptr,
55     {},
56     0,
57     eArgTypeLanguage,
58     "Language of expression to run"}};
59
60Status
61OptionGroupWatchpoint::SetOptionValue(uint32_t option_idx,
62                                      llvm::StringRef option_arg,
63                                      ExecutionContext *execution_context) {
64  Status error;
65  const int short_option = g_option_table[option_idx].short_option;
66  switch (short_option) {
67  case 'l': {
68    language_type = Language::GetLanguageTypeFromString(option_arg);
69    if (language_type == eLanguageTypeUnknown) {
70      StreamString sstr;
71      sstr.Printf("Unknown language type: '%s' for expression. List of "
72                  "supported languages:\n",
73                  option_arg.str().c_str());
74      Language::PrintSupportedLanguagesForExpressions(sstr, " ", "\n");
75      error.SetErrorString(sstr.GetString());
76    }
77    break;
78  }
79  case 'w': {
80    WatchType tmp_watch_type;
81    tmp_watch_type = (WatchType)OptionArgParser::ToOptionEnum(
82        option_arg, g_option_table[option_idx].enum_values, 0, error);
83    if (error.Success()) {
84      watch_type = tmp_watch_type;
85      watch_type_specified = true;
86    }
87    break;
88  }
89  case 's':
90    error = watch_size.SetValueFromString(option_arg);
91    if (watch_size.GetCurrentValue() == 0)
92      error.SetErrorStringWithFormat("invalid --size option value '%s'",
93                                     option_arg.str().c_str());
94    break;
95
96  default:
97    llvm_unreachable("Unimplemented option");
98  }
99
100  return error;
101}
102
103void OptionGroupWatchpoint::OptionParsingStarting(
104    ExecutionContext *execution_context) {
105  watch_type_specified = false;
106  watch_type = eWatchInvalid;
107  watch_size.Clear();
108  language_type = eLanguageTypeUnknown;
109}
110
111llvm::ArrayRef<OptionDefinition> OptionGroupWatchpoint::GetDefinitions() {
112  return llvm::ArrayRef(g_option_table);
113}
114