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 
16 using namespace lldb;
17 using namespace lldb_private;
18 
19 static 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::eWatchReadWrite,
32         "read_write",
33         "Watch for read/write",
34     },
35 };
36 
37 static constexpr OptionEnumValueElement g_watch_size[] = {
38     {
39         1,
40         "1",
41         "Watch for byte size of 1",
42     },
43     {
44         2,
45         "2",
46         "Watch for byte size of 2",
47     },
48     {
49         4,
50         "4",
51         "Watch for byte size of 4",
52     },
53     {
54         8,
55         "8",
56         "Watch for byte size of 8",
57     },
58 };
59 
60 static constexpr OptionDefinition g_option_table[] = {
61     {LLDB_OPT_SET_1, false, "watch", 'w', OptionParser::eRequiredArgument,
62      nullptr, OptionEnumValues(g_watch_type), 0, eArgTypeWatchType,
63      "Specify the type of watching to perform."},
64     {LLDB_OPT_SET_1, false, "size", 's', OptionParser::eRequiredArgument,
65      nullptr, OptionEnumValues(g_watch_size), 0, eArgTypeByteSize,
66      "Number of bytes to use to watch a region."},
67     {LLDB_OPT_SET_2,
68      false,
69      "language",
70      'l',
71      OptionParser::eRequiredArgument,
72      nullptr,
73      {},
74      0,
75      eArgTypeLanguage,
76      "Language of expression to run"}};
77 
78 bool OptionGroupWatchpoint::IsWatchSizeSupported(uint32_t watch_size) {
79   for (const auto& size : g_watch_size) {
80     if (0  == size.value)
81       break;
82     if (watch_size == size.value)
83       return true;
84   }
85   return false;
86 }
87 
88 Status
89 OptionGroupWatchpoint::SetOptionValue(uint32_t option_idx,
90                                       llvm::StringRef option_arg,
91                                       ExecutionContext *execution_context) {
92   Status error;
93   const int short_option = g_option_table[option_idx].short_option;
94   switch (short_option) {
95   case 'l': {
96     language_type = Language::GetLanguageTypeFromString(option_arg);
97     if (language_type == eLanguageTypeUnknown) {
98       StreamString sstr;
99       sstr.Printf("Unknown language type: '%s' for expression. List of "
100                   "supported languages:\n",
101                   option_arg.str().c_str());
102       Language::PrintSupportedLanguagesForExpressions(sstr, " ", "\n");
103       error.SetErrorString(sstr.GetString());
104     }
105     break;
106   }
107   case 'w': {
108     WatchType tmp_watch_type;
109     tmp_watch_type = (WatchType)OptionArgParser::ToOptionEnum(
110         option_arg, g_option_table[option_idx].enum_values, 0, error);
111     if (error.Success()) {
112       watch_type = tmp_watch_type;
113       watch_type_specified = true;
114     }
115     break;
116   }
117   case 's':
118     watch_size = (uint32_t)OptionArgParser::ToOptionEnum(
119         option_arg, g_option_table[option_idx].enum_values, 0, error);
120     break;
121 
122   default:
123     llvm_unreachable("Unimplemented option");
124   }
125 
126   return error;
127 }
128 
129 void OptionGroupWatchpoint::OptionParsingStarting(
130     ExecutionContext *execution_context) {
131   watch_type_specified = false;
132   watch_type = eWatchInvalid;
133   watch_size = 0;
134   language_type = eLanguageTypeUnknown;
135 }
136 
137 llvm::ArrayRef<OptionDefinition> OptionGroupWatchpoint::GetDefinitions() {
138   return llvm::ArrayRef(g_option_table);
139 }
140