diff options
8 files changed, 172 insertions, 15 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 99b38dd6264..b72e5c3f18c 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -971,7 +971,9 @@ ValueObject::GetPointeeData (DataExtractor& data, if (item_count == 0) return 0; - const uint64_t item_type_size = pointee_or_element_clang_type.GetByteSize(nullptr); + ExecutionContext exe_ctx (GetExecutionContextRef()); + + const uint64_t item_type_size = pointee_or_element_clang_type.GetByteSize(&exe_ctx); const uint64_t bytes = item_count * item_type_size; const uint64_t offset = item_idx * item_type_size; @@ -1047,7 +1049,7 @@ ValueObject::GetPointeeData (DataExtractor& data, break; case eAddressTypeHost: { - const uint64_t max_bytes = GetClangType().GetByteSize(nullptr); + const uint64_t max_bytes = GetClangType().GetByteSize(&exe_ctx); if (max_bytes > offset) { size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes); @@ -2222,10 +2224,12 @@ ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type if (!can_create) return ValueObjectSP(); + ExecutionContext exe_ctx (GetExecutionContextRef()); + ValueObjectChild *synthetic_child = new ValueObjectChild(*this, type, name_const_str, - type.GetByteSize(nullptr), + type.GetByteSize(&exe_ctx), offset, 0, 0, @@ -2263,10 +2267,12 @@ ValueObject::GetSyntheticBase (uint32_t offset, const ClangASTType& type, bool c const bool is_base_class = true; + ExecutionContext exe_ctx (GetExecutionContextRef()); + ValueObjectChild *synthetic_child = new ValueObjectChild(*this, type, name_const_str, - type.GetByteSize(nullptr), + type.GetByteSize(&exe_ctx), offset, 0, 0, diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp index cbeb2ab47b2..e8b477a74a5 100644 --- a/lldb/source/Core/ValueObjectConstResult.cpp +++ b/lldb/source/Core/ValueObjectConstResult.cpp @@ -256,8 +256,10 @@ ValueObjectConstResult::GetValueType() const uint64_t ValueObjectConstResult::GetByteSize() { + ExecutionContext exe_ctx(GetExecutionContextRef()); + if (m_byte_size == 0) - m_byte_size = GetClangType().GetByteSize(nullptr); + SetByteSize(GetClangType().GetByteSize(&exe_ctx)); return m_byte_size; } diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp index 1b8ec8083f8..89b98a1db1b 100644 --- a/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -127,7 +127,7 @@ ValueObjectDynamicValue::GetByteSize() { const bool success = UpdateValueIfNeeded(false); if (success && m_dynamic_type_info.HasType()) - return m_value.GetValueByteSize(NULL); + return m_value.GetValueByteSize(nullptr); else return m_parent->GetByteSize(); } diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp index e4fd212cbfa..ed2aeb3d963 100644 --- a/lldb/source/Core/ValueObjectVariable.cpp +++ b/lldb/source/Core/ValueObjectVariable.cpp @@ -105,12 +105,14 @@ ValueObjectVariable::CalculateNumChildren() uint64_t ValueObjectVariable::GetByteSize() { + ExecutionContext exe_ctx(GetExecutionContextRef()); + ClangASTType type(GetClangType()); if (!type.IsValid()) return 0; - return type.GetByteSize(nullptr); + return type.GetByteSize(&exe_ctx); } lldb::ValueType diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index 4ffeadf3e11..e7103fbb21e 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -3461,7 +3461,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, // alignment (field_type_info.second) from the AST context. ClangASTType field_clang_type (m_ast, field->getType()); assert(field_idx < record_layout.getFieldCount()); - child_byte_size = field_clang_type.GetByteSize(nullptr); + child_byte_size = field_clang_type.GetByteSize(exe_ctx); // Figure out the field offset within the current struct/union/class type bit_offset = record_layout.getFieldOffset (field_idx); @@ -3626,7 +3626,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, // We have a pointer to an simple type if (idx == 0 && pointee_clang_type.GetCompleteType()) { - child_byte_size = pointee_clang_type.GetByteSize(nullptr); + child_byte_size = pointee_clang_type.GetByteSize(exe_ctx); child_byte_offset = 0; return pointee_clang_type; } @@ -3647,7 +3647,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, char element_name[64]; ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); child_name.assign(element_name); - child_byte_size = element_type.GetByteSize(nullptr); + child_byte_size = element_type.GetByteSize(exe_ctx); child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; return element_type; } @@ -3668,7 +3668,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, char element_name[64]; ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); child_name.assign(element_name); - child_byte_size = element_type.GetByteSize(nullptr); + child_byte_size = element_type.GetByteSize(exe_ctx); child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; return element_type; } @@ -3718,7 +3718,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, // We have a pointer to an simple type if (idx == 0) { - child_byte_size = pointee_clang_type.GetByteSize(nullptr); + child_byte_size = pointee_clang_type.GetByteSize(exe_ctx); child_byte_offset = 0; return pointee_clang_type; } @@ -3762,7 +3762,7 @@ ClangASTType::GetChildClangTypeAtIndex (ExecutionContext *exe_ctx, // We have a pointer to an simple type if (idx == 0) { - child_byte_size = pointee_clang_type.GetByteSize(nullptr); + child_byte_size = pointee_clang_type.GetByteSize(exe_ctx); child_byte_offset = 0; return pointee_clang_type; } @@ -6868,7 +6868,7 @@ ClangASTType::ReadFromMemory (lldb_private::ExecutionContext *exe_ctx, if (!GetCompleteType()) return false; - const uint64_t byte_size = GetByteSize(nullptr); + const uint64_t byte_size = GetByteSize(exe_ctx); if (data.GetByteSize() < byte_size) { lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0')); @@ -6918,7 +6918,7 @@ ClangASTType::WriteToMemory (lldb_private::ExecutionContext *exe_ctx, if (!GetCompleteType()) return false; - const uint64_t byte_size = GetByteSize(nullptr); + const uint64_t byte_size = GetByteSize(exe_ctx); if (byte_size > 0) { diff --git a/lldb/test/expression_command/persist_objc_pointeetype/Makefile b/lldb/test/expression_command/persist_objc_pointeetype/Makefile new file mode 100644 index 00000000000..8066198300f --- /dev/null +++ b/lldb/test/expression_command/persist_objc_pointeetype/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../make + +OBJC_SOURCES := main.m + +include $(LEVEL)/Makefile.rules +LDFLAGS += -framework Foundation -framework CloudKit + diff --git a/lldb/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py b/lldb/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py new file mode 100644 index 00000000000..eb771f888f7 --- /dev/null +++ b/lldb/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py @@ -0,0 +1,60 @@ +""" +Test that we can p *objcObject +""" + +import unittest2 +import lldb +import lldbutil +from lldbtest import * + +class PersistObjCPointeeType(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.cpp. + self.line = line_number('main.m','// break here') + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @dsym_test + def test_with_dsym(self): + """Test that we can p *objcObject""" + self.buildDsym() + self.do_my_test() + + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin due to ObjC test case") + @dwarf_test + def test_with_dwarf(self): + """Test that we can p *objcObject""" + self.buildDwarf() + self.do_my_test() + + def do_my_test(self): + def cleanup(): + pass + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + self.expect("p *self", substrs=['_sc_name = nil', + '_sc_name2 = nil', + '_sc_name3 = nil', + '_sc_name4 = nil', + '_sc_name5 = nil', + '_sc_name6 = nil', + '_sc_name7 = nil', + '_sc_name8 = nil']) + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/expression_command/persist_objc_pointeetype/main.m b/lldb/test/expression_command/persist_objc_pointeetype/main.m new file mode 100644 index 00000000000..a2b6b703d6c --- /dev/null +++ b/lldb/test/expression_command/persist_objc_pointeetype/main.m @@ -0,0 +1,80 @@ +/* +clang -g ExtendSuperclass.m -o ExtendSuperclass -framework Foundation -framework ProtectedCloudStorage -F/System/Library/PrivateFrameworks/ -framework CloudKit && ./ExtendSuperclass +*/ +#include <assert.h> +#import <Foundation/Foundation.h> +#import <CloudKit/CloudKit.h> + +#define SuperClass CKDatabase + +@interface SubClass : SuperClass +@end + +// class extension +@interface SuperClass () +@property (nonatomic, strong) NSString *_sc_name; +@property (nonatomic, strong) NSString *_sc_name2; +@property (nonatomic, strong) NSString *_sc_name3; +@property (nonatomic, strong) NSString *_sc_name4; +@property (nonatomic, strong) NSString *_sc_name5; +@property (nonatomic, strong) NSString *_sc_name6; +@property (nonatomic, strong) NSString *_sc_name7; +@property (nonatomic, strong) NSString *_sc_name8; +@end + +@implementation SuperClass (MySuperClass) +- (id)initThatDoesNotAssert +{ + return [super init]; +} +@end + +@implementation SubClass +- (id)initThatDoesNotAssert +{ + assert(_sc_name == nil); + assert(_sc_name2 == nil); + assert(_sc_name3 == nil); + assert(_sc_name4 == nil); + assert(_sc_name5 == nil); + assert(_sc_name6 == nil); + assert(_sc_name7 == nil); + assert(_sc_name8 == nil); // break here + + if ((self = [super _initWithContainer:(CKContainer*)@"foo" scope:0xff])) { + assert(_sc_name == nil); + assert(_sc_name2 == nil); + assert(_sc_name3 == nil); + assert(_sc_name4 == nil); + assert(_sc_name5 == nil); + assert(_sc_name6 == nil); + assert(_sc_name7 == nil); + assert(_sc_name8 == nil); + + _sc_name = @"empty"; + } + return self; +} +@synthesize _sc_name; +@synthesize _sc_name2; +@synthesize _sc_name3; +@synthesize _sc_name4; +@synthesize _sc_name5; +@synthesize _sc_name6; +@synthesize _sc_name7; +@synthesize _sc_name8; +- (void)foo:(NSString*)bar { self._sc_name = bar; } +- (NSString*)description { return [NSString stringWithFormat:@"%p: %@", self, self._sc_name]; } +@end + +int main() +{ + SubClass *sc = [[SubClass alloc] initThatDoesNotAssert]; + NSLog(@"%@", sc); + [sc foo:@"bar"]; + NSLog(@"%@", sc); + sc._sc_name = @"bar2"; + NSLog(@"%@", sc); + NSLog(@"%@", sc._sc_name); + return 0; +} |