Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lldb/include/lldb/Target/Language.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ class Language : public PluginInterface {
// a match. But we wouldn't want this to match AnotherA::my_function. The
// user is specifying a truncated path, not a truncated set of characters.
// This function does a language-aware comparison for those purposes.
virtual bool DemangledNameContainsPath(llvm::StringRef path,
virtual bool DemangledNameContainsPath(llvm::StringRef path,
ConstString demangled) const;

// if a language has a custom format for printing variable declarations that
Expand Down Expand Up @@ -372,6 +372,8 @@ class Language : public PluginInterface {
return {};
}

virtual std::optional<bool> GetBooleanFromString(llvm::StringRef str) const;

/// Returns true if this Language supports exception breakpoints on throw via
/// a corresponding LanguageRuntime plugin.
virtual bool SupportsExceptionBreakpointsOnThrow() const { return false; }
Expand Down
8 changes: 8 additions & 0 deletions lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1040,3 +1040,11 @@ bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const {
}
return false;
}

std::optional<bool>
ObjCLanguage::GetBooleanFromString(llvm::StringRef str) const {
return llvm::StringSwitch<std::optional<bool>>(str)
.Case("YES", {true})
.Case("NO", {false})
.Default({});
}
3 changes: 3 additions & 0 deletions lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ class ObjCLanguage : public Language {

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

virtual std::optional<bool>
GetBooleanFromString(llvm::StringRef str) const override;

bool SupportsExceptionBreakpointsOnThrow() const override { return true; }

// PluginInterface protocol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,11 @@ Language *ObjCPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
return nullptr;
}
}

std::optional<bool>
ObjCPlusPlusLanguage::GetBooleanFromString(llvm::StringRef str) const {
return llvm::StringSwitch<std::optional<bool>>(str)
.Cases("true", "YES", {true})
.Cases("false", "NO", {false})
.Default({});
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ class ObjCPlusPlusLanguage : public Language {

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

virtual std::optional<bool>
GetBooleanFromString(llvm::StringRef str) const override;

static llvm::StringRef GetPluginNameStatic() { return "objcplusplus"; }

// PluginInterface protocol
Expand Down
8 changes: 8 additions & 0 deletions lldb/source/Target/Language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,14 @@ void Language::GetDefaultExceptionResolverDescription(bool catch_on,
s.Printf("Exception breakpoint (catch: %s throw: %s)",
catch_on ? "on" : "off", throw_on ? "on" : "off");
}

std::optional<bool> Language::GetBooleanFromString(llvm::StringRef str) const {
return llvm::StringSwitch<std::optional<bool>>(str)
.Case("true", {true})
.Case("false", {false})
.Default({});
}

// Constructor
Language::Language() = default;

Expand Down
15 changes: 15 additions & 0 deletions lldb/source/ValueObject/ValueObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1639,6 +1639,18 @@ addr_t ValueObject::GetPointerValue(AddressType *address_type) {
return address;
}

static const char *ConvertBoolean(lldb::LanguageType language_type,
const char *value_str) {
if (Language *language = Language::FindPlugin(language_type))
if (auto boolean = language->GetBooleanFromString(value_str))
return *boolean ? "1" : "0";

return llvm::StringSwitch<const char *>(value_str)
.Case("true", "1")
.Case("false", "0")
.Default(value_str);
}

bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
error.Clear();
// Make sure our value is up to date first so that our location and location
Expand All @@ -1659,6 +1671,9 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
// If the value is already a scalar, then let the scalar change itself:
m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);
} else if (byte_size <= 16) {
if (GetCompilerType().IsBoolean())
value_str = ConvertBoolean(GetObjectRuntimeLanguage(), value_str);

// If the value fits in a scalar, then make a new scalar and again let the
// scalar code do the conversion, then figure out where to put the new
// value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

int main() {
NSDictionary* dic = @{@1 : @2};
BOOL b = NO;
NSLog(@"hello world"); //% dic = self.frame().FindVariable("dic")
//% dic.SetPreferSyntheticValue(True)
//% dic.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
//% dic.SetValueFromCString("12")
//% b = self.frame().FindVariable("b")
//% b.SetValueFromCString("YES")
return 0; //% dic = self.frame().FindVariable("dic")
//% self.assertTrue(dic.GetValueAsUnsigned() == 0xC, "failed to read what I wrote")
//% b = self.frame().FindVariable("b")
//% self.assertTrue(b.GetValueAsUnsigned() == 0x0, "failed to update b")
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
Test some SBValue APIs.
"""


import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
Expand Down Expand Up @@ -111,6 +110,20 @@ def test_change_value(self):
actual_value, 98765, "Got the right changed value from ptr->second_val"
)

ptr_fourth_value = ptr_value.GetChildMemberWithName("fourth_val")
self.assertTrue(ptr_fourth_value.IsValid(), "Got fourth_value from ptr")
fourth_actual_value = ptr_fourth_value.GetValueAsUnsigned(error, 1)
self.assertTrue(error.Success(), "Got an unsigned value for ptr->second_val")
self.assertEqual(fourth_actual_value, 0)

result = ptr_fourth_value.SetValueFromCString("true")
self.assertTrue(result, "Success setting ptr->fourth_value.")
fourth_actual_value = ptr_fourth_value.GetValueAsSigned(error, 0)
self.assertTrue(error.Success(), "Got a changed value from ptr->second_val")
self.assertEqual(
fourth_actual_value, 1, "Got the right changed value from ptr->fourth_val"
)

# gcc may set multiple locations for breakpoint
breakpoint.SetEnabled(False)

Expand All @@ -125,7 +138,7 @@ def test_change_value(self):
)

expected_value = (
"Val - 12345 Mine - 55, 98765, 55555555. Ptr - 66, 98765, 66666666"
"Val - 12345 Mine - 55, 98765, 55555555, 0. Ptr - 66, 98765, 66666666, 1"
)
stdout = process.GetSTDOUT(1000)
self.assertIn(expected_value, stdout, "STDOUT showed changed values.")
Expand Down
15 changes: 9 additions & 6 deletions lldb/test/API/python_api/value/change_values/main.c
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

struct foo
{
uint8_t first_val;
uint32_t second_val;
uint64_t third_val;
bool fourth_val;
};

int main ()
{
int val = 100;
struct foo mine = {55, 5555, 55555555};
struct foo mine = {55, 5555, 55555555, false};
struct foo *ptr = (struct foo *) malloc (sizeof (struct foo));
ptr->first_val = 66;
ptr->second_val = 6666;
ptr->third_val = 66666666;
ptr->fourth_val = false;

// Stop here and set values
printf ("Val - %d Mine - %d, %d, %llu. Ptr - %d, %d, %llu\n", val,
mine.first_val, mine.second_val, mine.third_val,
ptr->first_val, ptr->second_val, ptr->third_val);
printf("Val - %d Mine - %d, %d, %llu, %d. Ptr - %d, %d, %llu, %d\n", val,
mine.first_val, mine.second_val, mine.third_val, mine.fourth_val,
ptr->first_val, ptr->second_val, ptr->third_val, ptr->fourth_val);

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