Skip to content

Commit 03df845

Browse files
authored
Merge pull request #9592 from swiftlang/cherrypick-4714215
[lldb] Support true/false in ValueObject::SetValueFromCString (llvm#115780)
2 parents 12081ad + 924ffd8 commit 03df845

File tree

10 files changed

+87
-9
lines changed

10 files changed

+87
-9
lines changed

lldb/include/lldb/Target/Language.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ class Language : public PluginInterface {
247247
// a match. But we wouldn't want this to match AnotherA::my_function. The
248248
// user is specifying a truncated path, not a truncated set of characters.
249249
// This function does a language-aware comparison for those purposes.
250-
virtual bool DemangledNameContainsPath(llvm::StringRef path,
250+
virtual bool DemangledNameContainsPath(llvm::StringRef path,
251251
ConstString demangled) const;
252252

253253
// if a language has a custom format for printing variable declarations that
@@ -374,6 +374,8 @@ class Language : public PluginInterface {
374374
return {};
375375
}
376376

377+
virtual std::optional<bool> GetBooleanFromString(llvm::StringRef str) const;
378+
377379
/// Returns true if this Language supports exception breakpoints on throw via
378380
/// a corresponding LanguageRuntime plugin.
379381
virtual bool SupportsExceptionBreakpointsOnThrow() const { return false; }

lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -1041,3 +1041,11 @@ bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const {
10411041
}
10421042
return false;
10431043
}
1044+
1045+
std::optional<bool>
1046+
ObjCLanguage::GetBooleanFromString(llvm::StringRef str) const {
1047+
return llvm::StringSwitch<std::optional<bool>>(str)
1048+
.Case("YES", {true})
1049+
.Case("NO", {false})
1050+
.Default({});
1051+
}

lldb/source/Plugins/Language/ObjC/ObjCLanguage.h

+3
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ class ObjCLanguage : public Language {
194194

195195
llvm::StringRef GetInstanceVariableName() override { return "self"; }
196196

197+
virtual std::optional<bool>
198+
GetBooleanFromString(llvm::StringRef str) const override;
199+
197200
bool SupportsExceptionBreakpointsOnThrow() const override { return true; }
198201

199202
// PluginInterface protocol

lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,11 @@ Language *ObjCPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
4343
return nullptr;
4444
}
4545
}
46+
47+
std::optional<bool>
48+
ObjCPlusPlusLanguage::GetBooleanFromString(llvm::StringRef str) const {
49+
return llvm::StringSwitch<std::optional<bool>>(str)
50+
.Cases("true", "YES", {true})
51+
.Cases("false", "NO", {false})
52+
.Default({});
53+
}

lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h

+3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class ObjCPlusPlusLanguage : public Language {
4444

4545
llvm::StringRef GetInstanceVariableName() override { return "self"; }
4646

47+
virtual std::optional<bool>
48+
GetBooleanFromString(llvm::StringRef str) const override;
49+
4750
static llvm::StringRef GetPluginNameStatic() { return "objcplusplus"; }
4851

4952
// PluginInterface protocol

lldb/source/Target/Language.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,14 @@ void Language::GetDefaultExceptionResolverDescription(bool catch_on,
528528
s.Printf("Exception breakpoint (catch: %s throw: %s)",
529529
catch_on ? "on" : "off", throw_on ? "on" : "off");
530530
}
531+
532+
std::optional<bool> Language::GetBooleanFromString(llvm::StringRef str) const {
533+
return llvm::StringSwitch<std::optional<bool>>(str)
534+
.Case("true", {true})
535+
.Case("false", {false})
536+
.Default({});
537+
}
538+
531539
// Constructor
532540
Language::Language() = default;
533541

lldb/source/ValueObject/ValueObject.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,18 @@ addr_t ValueObject::GetPointerValue(AddressType *address_type) {
17051705
return address;
17061706
}
17071707

1708+
static const char *ConvertBoolean(lldb::LanguageType language_type,
1709+
const char *value_str) {
1710+
if (Language *language = Language::FindPlugin(language_type))
1711+
if (auto boolean = language->GetBooleanFromString(value_str))
1712+
return *boolean ? "1" : "0";
1713+
1714+
return llvm::StringSwitch<const char *>(value_str)
1715+
.Case("true", "1")
1716+
.Case("false", "0")
1717+
.Default(value_str);
1718+
}
1719+
17081720
bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
17091721
error.Clear();
17101722
// Make sure our value is up to date first so that our location and location
@@ -1725,6 +1737,9 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
17251737
// If the value is already a scalar, then let the scalar change itself:
17261738
m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);
17271739
} else if (byte_size <= 16) {
1740+
if (GetCompilerType().IsBoolean())
1741+
value_str = ConvertBoolean(GetObjectRuntimeLanguage(), value_str);
1742+
17281743
// If the value fits in a scalar, then make a new scalar and again let the
17291744
// scalar code do the conversion, then figure out where to put the new
17301745
// value.

lldb/test/API/functionalities/data-formatter/setvaluefromcstring/main.m

+5
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22

33
int main() {
44
NSDictionary* dic = @{@1 : @2};
5+
BOOL b = NO;
56
NSLog(@"hello world"); //% dic = self.frame().FindVariable("dic")
67
//% dic.SetPreferSyntheticValue(True)
78
//% dic.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
89
//% dic.SetValueFromCString("12")
10+
//% b = self.frame().FindVariable("b")
11+
//% b.SetValueFromCString("YES")
912
return 0; //% dic = self.frame().FindVariable("dic")
1013
//% self.assertTrue(dic.GetValueAsUnsigned() == 0xC, "failed to read what I wrote")
14+
//% b = self.frame().FindVariable("b")
15+
//% self.assertTrue(b.GetValueAsUnsigned() == 0x0, "failed to update b")
1116
}

lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py

+25-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
Test some SBValue APIs.
33
"""
44

5-
65
import lldb
76
from lldbsuite.test.decorators import *
87
from lldbsuite.test.lldbtest import *
@@ -111,6 +110,30 @@ def test_change_value(self):
111110
actual_value, 98765, "Got the right changed value from ptr->second_val"
112111
)
113112

113+
ptr_fourth_value = ptr_value.GetChildMemberWithName("fourth_val")
114+
self.assertTrue(ptr_fourth_value.IsValid(), "Got fourth_val from ptr")
115+
fourth_actual_value = ptr_fourth_value.GetValueAsUnsigned(error, 1)
116+
self.assertTrue(error.Success(), "Got an unsigned value for ptr->fourth_val")
117+
self.assertEqual(fourth_actual_value, 0)
118+
119+
result = ptr_fourth_value.SetValueFromCString("true")
120+
self.assertTrue(result, "Success setting ptr->fourth_val.")
121+
fourth_actual_value = ptr_fourth_value.GetValueAsSigned(error, 0)
122+
self.assertTrue(error.Success(), "Got a changed value from ptr->fourth_val")
123+
self.assertEqual(
124+
fourth_actual_value, 1, "Got the right changed value from ptr->fourth_val"
125+
)
126+
127+
result = ptr_fourth_value.SetValueFromCString("NO")
128+
self.assertFalse(result, "Failed setting ptr->fourth_val.")
129+
fourth_actual_value = ptr_fourth_value.GetValueAsSigned(error, 0)
130+
self.assertTrue(error.Success(), "Got the original value from ptr->fourth_val")
131+
self.assertEqual(
132+
fourth_actual_value,
133+
1,
134+
"Got the original changed value from ptr->fourth_val",
135+
)
136+
114137
# gcc may set multiple locations for breakpoint
115138
breakpoint.SetEnabled(False)
116139

@@ -125,7 +148,7 @@ def test_change_value(self):
125148
)
126149

127150
expected_value = (
128-
"Val - 12345 Mine - 55, 98765, 55555555. Ptr - 66, 98765, 66666666"
151+
"Val - 12345 Mine - 55, 98765, 55555555, 0. Ptr - 66, 98765, 66666666, 1"
129152
)
130153
stdout = process.GetSTDOUT(1000)
131154
self.assertIn(expected_value, stdout, "STDOUT showed changed values.")

lldb/test/API/python_api/value/change_values/main.c

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
1-
#include <stdio.h>
1+
#include <stdbool.h>
22
#include <stdint.h>
3+
#include <stdio.h>
34
#include <stdlib.h>
45

56
struct foo
67
{
78
uint8_t first_val;
89
uint32_t second_val;
910
uint64_t third_val;
11+
bool fourth_val;
1012
};
11-
13+
1214
int main ()
1315
{
1416
int val = 100;
15-
struct foo mine = {55, 5555, 55555555};
17+
struct foo mine = {55, 5555, 55555555, false};
1618
struct foo *ptr = (struct foo *) malloc (sizeof (struct foo));
1719
ptr->first_val = 66;
1820
ptr->second_val = 6666;
1921
ptr->third_val = 66666666;
22+
ptr->fourth_val = false;
2023

2124
// Stop here and set values
22-
printf ("Val - %d Mine - %d, %d, %llu. Ptr - %d, %d, %llu\n", val,
23-
mine.first_val, mine.second_val, mine.third_val,
24-
ptr->first_val, ptr->second_val, ptr->third_val);
25+
printf("Val - %d Mine - %d, %d, %llu, %d. Ptr - %d, %d, %llu, %d\n", val,
26+
mine.first_val, mine.second_val, mine.third_val, mine.fourth_val,
27+
ptr->first_val, ptr->second_val, ptr->third_val, ptr->fourth_val);
2528

2629
// Stop here and check values
2730
printf ("This is just another call which we won't make it over %d.", val);

0 commit comments

Comments
 (0)