Move several GetByteSize() calls over to the brave new world of taking an ExecutionCo...
authorEnrico Granata <egranata@apple.com>
Wed, 28 Jan 2015 01:09:45 +0000 (01:09 +0000)
committerEnrico Granata <egranata@apple.com>
Wed, 28 Jan 2015 01:09:45 +0000 (01:09 +0000)
And since enough of these are doing the right thing, add a test case to verify we are doing the right thing with freeze drying ObjC object types

Fixes rdar://18092770

llvm-svn: 227282

lldb/source/Core/ValueObject.cpp
lldb/source/Core/ValueObjectConstResult.cpp
lldb/source/Core/ValueObjectDynamicValue.cpp
lldb/source/Core/ValueObjectVariable.cpp
lldb/source/Symbol/ClangASTType.cpp
lldb/test/expression_command/persist_objc_pointeetype/Makefile [new file with mode: 0644]
lldb/test/expression_command/persist_objc_pointeetype/TestPersistObjCPointeeType.py [new file with mode: 0644]
lldb/test/expression_command/persist_objc_pointeetype/main.m [new file with mode: 0644]

index 99b38dd..b72e5c3 100644 (file)
@@ -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,
index cbeb2ab..e8b477a 100644 (file)
@@ -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;
 }
 
index 1b8ec80..89b98a1 100644 (file)
@@ -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();
 }
index e4fd212..ed2aeb3 100644 (file)
@@ -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
index 4ffeadf..e7103fb 100644 (file)
@@ -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 (file)
index 0000000..8066198
--- /dev/null
@@ -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 (file)
index 0000000..eb771f8
--- /dev/null
@@ -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 (file)
index 0000000..a2b6b70
--- /dev/null
@@ -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;
+}