[Lldb-commits] [lldb] r151703 - in /lldb/trunk: examples/summaries/cocoa/ include/lldb/ include/lldb/Core/ include/lldb/Interpreter/ scripts/Python/ source/API/ source/Core/ source/Interpreter/ test/functionalities/data-formatter/data-formatter-objc/

Enrico Granata egranata at apple.com
Tue Feb 28 19:28:50 PST 2012


Author: enrico
Date: Tue Feb 28 21:28:49 2012
New Revision: 151703

URL: http://llvm.org/viewvc/llvm-project?rev=151703&view=rev
Log:
This commit:
 a) adds a Python summary provider for NSDate
 b) changes the initialization for ScriptInterpreter so that we are not passing a bulk of Python-specific function pointers around
 c) provides a new ScriptInterpreterObject class that allows for ref-count safe wrapping of scripting objects on the C++ side
 d) contains much needed performance improvements:
    1) the pointer to the Python function generating a scripted summary is now cached instead of looked up every time
    2) redundant memory reads in the Python ObjC runtime wrapper are eliminated
    3) summaries now use the m_summary_str in ValueObject to store their data instead of passing around ( == copying) an std::string object
 e) contains other minor fixes, such as adding descriptive error messages for some cases of summary generation failure

Added:
    lldb/trunk/examples/summaries/cocoa/NSDate.py
Modified:
    lldb/trunk/examples/summaries/cocoa/CFArray.py
    lldb/trunk/examples/summaries/cocoa/CFBag.py
    lldb/trunk/examples/summaries/cocoa/CFBinaryHeap.py
    lldb/trunk/examples/summaries/cocoa/CFDictionary.py
    lldb/trunk/examples/summaries/cocoa/CFString.py
    lldb/trunk/examples/summaries/cocoa/NSBundle.py
    lldb/trunk/examples/summaries/cocoa/NSData.py
    lldb/trunk/examples/summaries/cocoa/NSException.py
    lldb/trunk/examples/summaries/cocoa/NSMachPort.py
    lldb/trunk/examples/summaries/cocoa/NSNotification.py
    lldb/trunk/examples/summaries/cocoa/NSNumber.py
    lldb/trunk/examples/summaries/cocoa/NSSet.py
    lldb/trunk/examples/summaries/cocoa/NSURL.py
    lldb/trunk/examples/summaries/cocoa/objc_lldb.py
    lldb/trunk/examples/summaries/cocoa/objc_runtime.py
    lldb/trunk/include/lldb/Core/FormatClasses.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
    lldb/trunk/include/lldb/lldb-forward.h
    lldb/trunk/scripts/Python/finish-swig-Python-LLDB.sh
    lldb/trunk/scripts/Python/python-wrapper.swig
    lldb/trunk/source/API/SBCommandInterpreter.cpp
    lldb/trunk/source/Core/FormatClasses.cpp
    lldb/trunk/source/Core/FormatManager.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m

Modified: lldb/trunk/examples/summaries/cocoa/CFArray.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/CFArray.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/CFArray.py (original)
+++ lldb/trunk/examples/summaries/cocoa/CFArray.py Tue Feb 28 21:28:49 2012
@@ -16,7 +16,7 @@
 class NSArrayKVC_SynthProvider:
 
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -51,7 +51,7 @@
 class NSArrayCF_SynthProvider:
 
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 		self.cfruntime_size = self.size_of_cfruntime_base()
@@ -61,7 +61,7 @@
 	# to get its size we add up sizeof(pointer)+4
 	# and then add 4 more bytes if we are on a 64bit system
 	def size_of_cfruntime_base(self):
-		if self.lp64 == True:
+		if self.is_64_bit == True:
 			return 8+4+4;
 		else:
 			return 4+4;
@@ -93,7 +93,7 @@
 class NSArrayI_SynthProvider:
 
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -133,7 +133,7 @@
 class NSArrayM_SynthProvider:
 
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -223,7 +223,7 @@
 class NSArray_SynthProvider:
 
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
@@ -314,7 +314,7 @@
 	        summary = None
 	    if summary == None:
 	        summary = 'no valid array here'
-	    return 'size='+summary
+	    return summary + " objects"
 	return ''
 
 def __lldb_init_module(debugger,dict):

Modified: lldb/trunk/examples/summaries/cocoa/CFBag.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/CFBag.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/CFBag.py (original)
+++ lldb/trunk/examples/summaries/cocoa/CFBag.py Tue Feb 28 21:28:49 2012
@@ -15,7 +15,7 @@
 # obey the interface specification for synthetic children providers
 class CFBagRef_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -26,7 +26,7 @@
 	def update(self):
 		self.adjust_for_architecture();
 		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
-		if self.lp64:
+		if self.is_64_bit:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
 		else:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
@@ -35,7 +35,7 @@
 	# 20 bytes on x64
 	# most probably 2 pointers and 4 bytes of data
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 20
 		else:
 			return 12
@@ -49,7 +49,7 @@
 
 class CFBagUnknown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -120,7 +120,7 @@
 		if summary == None:
 			summary = 'no valid set here'
 		else:
-			if provider.lp64:
+			if provider.is_64_bit:
 				summary = summary & ~0x1fff000000000000
 		if summary == 1:
 			return '1 item'

Modified: lldb/trunk/examples/summaries/cocoa/CFBinaryHeap.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/CFBinaryHeap.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/CFBinaryHeap.py (original)
+++ lldb/trunk/examples/summaries/cocoa/CFBinaryHeap.py Tue Feb 28 21:28:49 2012
@@ -15,7 +15,7 @@
 # obey the interface specification for synthetic children providers
 class CFBinaryHeapRef_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -26,7 +26,7 @@
 	def update(self):
 		self.adjust_for_architecture();
 		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
-		if self.lp64:
+		if self.is_64_bit:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
 		else:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
@@ -35,7 +35,7 @@
 	# 16 bytes on x64
 	# most probably 2 pointers
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 16
 		else:
 			return 8
@@ -49,7 +49,7 @@
 
 class CFBinaryHeapUnknown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -117,7 +117,7 @@
 		if summary == None:
 			summary = 'no valid set here'
 		else:
-			if provider.lp64:
+			if provider.is_64_bit:
 				summary = summary & ~0x1fff000000000000
 		if summary == 1:
 			return '1 item'

Modified: lldb/trunk/examples/summaries/cocoa/CFDictionary.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/CFDictionary.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/CFDictionary.py (original)
+++ lldb/trunk/examples/summaries/cocoa/CFDictionary.py Tue Feb 28 21:28:49 2012
@@ -15,7 +15,7 @@
 # obey the interface specification for synthetic children providers
 class NSCFDictionary_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -26,7 +26,7 @@
 	def update(self):
 		self.adjust_for_architecture();
 		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
-		if self.lp64:
+		if self.is_64_bit:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
 		else:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
@@ -36,7 +36,7 @@
 	# the description of __CFDictionary is not readily available so most
 	# of this is guesswork, plain and simple
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 20
 		else:
 			return 12
@@ -50,7 +50,7 @@
 
 class NSDictionaryI_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -61,14 +61,14 @@
 	def update(self):
 		self.adjust_for_architecture();
 		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
-		if self.lp64:
+		if self.is_64_bit:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
 		else:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
 
 	# we just need to skip the ISA and the count immediately follows
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 8
 		else:
 			return 4
@@ -79,19 +79,18 @@
 							self.NSUInteger)
 		value = num_children_vo.GetValueAsUnsigned(0)
 		if value != None:
-			# the MSB on immutable dictionaries seems to be taken by the LSB of capacity
-			# not sure if it is a bug or some weird sort of feature, but masking it out
-			# gets the count right (unless, of course, someone's dictionaries grow
-			#                       too large - but I have not tested this)
-			if self.lp64:
-				value = value & ~0xFF00000000000000
+			# the MS6bits on immutable dictionaries seem to be taken by the LSB of capacity
+			# not sure if it is a bug or some weird sort of feature, but masking that out
+			# gets the count right
+			if self.is_64_bit:
+				value = value & ~0xFC00000000000000
 			else:
-				value = value & ~0xFF000000
+				value = value & ~0xFC000000
 		return value
 
 class NSDictionaryM_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -102,14 +101,14 @@
 	def update(self):
 		self.adjust_for_architecture();
 		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
-		if self.lp64:
+		if self.is_64_bit:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
 		else:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
 
 	# we just need to skip the ISA and the count immediately follows
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 8
 		else:
 			return 4
@@ -118,12 +117,21 @@
 		num_children_vo = self.valobj.CreateChildAtOffset("count",
 							self.offset(),
 							self.NSUInteger)
-		return num_children_vo.GetValueAsUnsigned(0)
+		value = num_children_vo.GetValueAsUnsigned(0)
+		if value != None:
+			# the MS6bits on mutable dictionaries seem to be taken by flags for
+			# KVO and probably other features. however, masking it out does get
+			# the count right
+			if self.is_64_bit:
+				value = value & ~0xFC00000000000000
+			else:
+				value = value & ~0xFC000000
+		return value
 
 
 class NSDictionaryUnknown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -198,7 +206,7 @@
 		if summary == None:
 			summary = 'no valid dictionary here'
 		# needed on OSX Mountain Lion
-		elif provider.lp64:
+		elif provider.is_64_bit:
 			summary = int(summary) & ~0x0f1f000000000000
 		return str(summary) + " key/value pairs"
 	return ''

Modified: lldb/trunk/examples/summaries/cocoa/CFString.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/CFString.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/CFString.py (original)
+++ lldb/trunk/examples/summaries/cocoa/CFString.py Tue Feb 28 21:28:49 2012
@@ -76,7 +76,7 @@
 	# handle the special case strings
 	# only use the custom code for the tested LP64 case
 	def handle_special(self):
-		if self.lp64 == False:
+		if self.is_64_bit == False:
 			# for 32bit targets, use safe ObjC code
 			return self.handle_unicode_string_safe()
 		offset = 12
@@ -127,7 +127,7 @@
 			"(char*)\"" + pystr.encode('utf-8') + "\"")
 
 	def handle_inline_explicit(self):
-		if self.lp64:
+		if self.is_64_bit:
 			offset = 24
 		else:
 			offset = 12
@@ -136,7 +136,7 @@
 				"(char*)(" + str(offset) + ")")
 
 	def handle_mutable_string(self):
-		if self.lp64:
+		if self.is_64_bit:
 			offset = 16
 		else:
 			offset = 8
@@ -223,7 +223,7 @@
 	# to get its size we add up sizeof(pointer)+4
 	# and then add 4 more bytes if we are on a 64bit system
 	def size_of_cfruntime_base(self):
-		if self.lp64 == True:
+		if self.is_64_bit == True:
 			return 8+4+4;
 		else:
 			return 4+4;
@@ -234,7 +234,7 @@
 	# on big-endian this means going to byte 3, if we are on
 	# little endian (OSX & iOS), this means reading byte 0
 	def offset_of_info_bits(self):
-		if self.lp64 == True:
+		if self.is_64_bit == True:
 			offset = 8;
 		else:
 			offset = 4;
@@ -282,7 +282,7 @@
 	# preparing ourselves to read into memory
 	# by adjusting architecture-specific info
 	def adjust_for_architecture(self):
-		self.lp64 = self.is_64bit();
+		self.is_64_bit = self.is_64bit();
 		self.is_little = self.is_little_endian();
 
 	# reading info bits out of the CFString and computing

Modified: lldb/trunk/examples/summaries/cocoa/NSBundle.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/NSBundle.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/NSBundle.py (original)
+++ lldb/trunk/examples/summaries/cocoa/NSBundle.py Tue Feb 28 21:28:49 2012
@@ -16,7 +16,7 @@
 # obey the interface specification for synthetic children providers
 class NSBundleKnown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -27,7 +27,7 @@
 	def update(self):
 		self.adjust_for_architecture();
 		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
-		if self.lp64:
+		if self.is_64_bit:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
 			self.pointer_size = 8
 		else:
@@ -58,7 +58,7 @@
 
 class NSBundleUnknown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 

Modified: lldb/trunk/examples/summaries/cocoa/NSData.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/NSData.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/NSData.py (original)
+++ lldb/trunk/examples/summaries/cocoa/NSData.py Tue Feb 28 21:28:49 2012
@@ -15,7 +15,7 @@
 # obey the interface specification for synthetic children providers
 class NSConcreteData_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -26,7 +26,7 @@
 	def update(self):
 		self.adjust_for_architecture();
 		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
-		if self.lp64:
+		if self.is_64_bit:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
 		else:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
@@ -37,7 +37,7 @@
 	# machine word long, which means we actually have two pointers
 	# worth of data to skip
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 16
 		else:
 			return 8
@@ -51,7 +51,7 @@
 
 class NSDataUnknown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 

Added: lldb/trunk/examples/summaries/cocoa/NSDate.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/NSDate.py?rev=151703&view=auto
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/NSDate.py (added)
+++ lldb/trunk/examples/summaries/cocoa/NSDate.py Tue Feb 28 21:28:49 2012
@@ -0,0 +1,171 @@
+# summary provider for NSDate
+import lldb
+import ctypes
+import objc_runtime
+import metrics
+import struct
+import time
+import datetime
+
+statistics = metrics.Metrics()
+statistics.add_metric('invalid_isa')
+statistics.add_metric('invalid_pointer')
+statistics.add_metric('unknown_class')
+statistics.add_metric('code_notrun')
+
+# Python promises to start counting time at midnight on Jan 1st on the epoch year
+# hence, all we need to know is the epoch year
+python_epoch = time.gmtime(0).tm_year
+
+osx_epoch = datetime.date(2001,1,1).timetuple()
+
+def mkgmtime(t):
+    return time.mktime(t)-time.timezone
+
+osx_epoch = mkgmtime(osx_epoch)
+
+def osx_to_python_time(osx):
+	if python_epoch <= 2011:
+		return osx + osx_epoch
+	else:
+		return osx - osx_epoch
+
+
+# despite the similary to synthetic children providers, these classes are not
+# trying to provide anything but the port number of an NSDate, so they need not
+# obey the interface specification for synthetic children providers
+class NSTaggedDate_SummaryProvider:
+	def adjust_for_architecture(self):
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
+		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
+
+	def __init__(self, valobj, info_bits, data):
+		self.valobj = valobj;
+		self.update();
+		self.info_bits = info_bits
+		self.data = data
+
+	def update(self):
+		self.adjust_for_architecture();
+		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
+
+		self.char = self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar)
+		self.short = self.valobj.GetType().GetBasicType(lldb.eBasicTypeShort)
+		self.ushort = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedShort)
+		self.int = self.valobj.GetType().GetBasicType(lldb.eBasicTypeInt)
+		self.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong)
+		self.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
+		self.longlong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLongLong)
+		self.ulonglong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLongLong)
+		self.float = self.valobj.GetType().GetBasicType(lldb.eBasicTypeFloat)
+		self.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
+
+	def value(self):
+		# the value of the date-time object is wrapped into the pointer value
+		# unfortunately, it is made as a time-delta after Jan 1 2011 midnight GMT
+		# while all Python knows about is the "epoch", which is a platform-dependent
+		# year (1970 of *nix) whose Jan 1 at midnight is taken as reference
+		return time.ctime(osx_to_python_time(self.data))
+
+
+class NSUntaggedDate_SummaryProvider:
+	def adjust_for_architecture(self):
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
+		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
+
+	def __init__(self, valobj):
+		self.valobj = valobj;
+		self.update()
+
+	def update(self):
+		self.adjust_for_architecture();
+		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
+		self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
+		self.double = self.valobj.GetType().GetBasicType(lldb.eBasicTypeDouble)
+
+	def offset(self):
+		if self.is_64_bit:
+			return 8
+		else:
+			return 4
+
+
+	def value(self):
+		value = self.valobj.CreateChildAtOffset("value",
+							self.offset(),
+							self.double)
+		value_double = struct.unpack('d', struct.pack('Q', value.GetValueAsUnsigned(0)))[0]
+		return time.ctime(osx_to_python_time(value_double))
+
+class NSUnknownDate_SummaryProvider:
+	def adjust_for_architecture(self):
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
+		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
+
+	def __init__(self, valobj):
+		self.valobj = valobj;
+		self.update()
+
+	def update(self):
+		self.adjust_for_architecture();
+		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
+
+	def value(self):
+		stream = lldb.SBStream()
+		self.valobj.GetExpressionPath(stream)
+		expr = "(NSString*)[" + stream.GetData() + " description]"
+		num_children_vo = self.valobj.CreateValueFromExpression("str",expr);
+		return num_children_vo.GetSummary()
+
+def GetSummary_Impl(valobj):
+	global statistics
+	class_data = objc_runtime.ObjCRuntime(valobj)
+	if class_data.is_valid() == False:
+		statistics.metric_hit('invalid_pointer',valobj)
+		wrapper = None
+		return
+	class_data = class_data.read_class_data()
+	if class_data.is_valid() == False:
+		statistics.metric_hit('invalid_isa',valobj)
+		wrapper = None
+		return
+	if class_data.is_kvo():
+		class_data = class_data.get_superclass()
+	if class_data.is_valid() == False:
+		statistics.metric_hit('invalid_isa',valobj)
+		wrapper = None
+		return
+	
+	name_string = class_data.class_name()
+	if name_string == 'NSDate' or name_string == '__NSDate' or name_string == '__NSTaggedDate':
+		if class_data.is_tagged():
+			wrapper = NSTaggedDate_SummaryProvider(valobj,class_data.info_bits(),class_data.value())
+			statistics.metric_hit('code_notrun',valobj)
+		else:
+			wrapper = NSUntaggedDate_SummaryProvider(valobj)
+			statistics.metric_hit('code_notrun',valobj)
+	else:
+		wrapper = NSUnknownDate_SummaryProvider(valobj)
+		statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string)
+	return wrapper;
+
+
+def NSDate_SummaryProvider (valobj,dict):
+	provider = GetSummary_Impl(valobj);
+	if provider != None:
+	    #try:
+	    summary = provider.value();
+	    #except:
+	    #    summary = None
+	    if summary == None:
+	        summary = 'no valid number here'
+	    return str(summary)
+	return ''
+
+
+def __lldb_init_module(debugger,dict):
+	debugger.HandleCommand("type summary add -F NSDate.NSDate_SummaryProvider NSDate")
+

Modified: lldb/trunk/examples/summaries/cocoa/NSException.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/NSException.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/NSException.py (original)
+++ lldb/trunk/examples/summaries/cocoa/NSException.py Tue Feb 28 21:28:49 2012
@@ -12,7 +12,7 @@
 
 class NSKnownException_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -27,7 +27,7 @@
 
 	# skip the ISA and go to the name pointer
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 8
 		else:
 			return 4
@@ -44,7 +44,7 @@
 
 class NSUnknownException_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 

Modified: lldb/trunk/examples/summaries/cocoa/NSMachPort.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/NSMachPort.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/NSMachPort.py (original)
+++ lldb/trunk/examples/summaries/cocoa/NSMachPort.py Tue Feb 28 21:28:49 2012
@@ -15,7 +15,7 @@
 # obey the interface specification for synthetic children providers
 class NSMachPortKnown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -32,7 +32,7 @@
 	# then we have one other internal pointer, plus
 	# 4 bytes worth of flags. hence, these values
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 20
 		else:
 			return 12
@@ -46,7 +46,7 @@
 
 class NSMachPortUnknown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 

Modified: lldb/trunk/examples/summaries/cocoa/NSNotification.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/NSNotification.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/NSNotification.py (original)
+++ lldb/trunk/examples/summaries/cocoa/NSNotification.py Tue Feb 28 21:28:49 2012
@@ -12,7 +12,7 @@
 
 class NSConcreteNotification_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -27,7 +27,7 @@
 
 	# skip the ISA and go to the name pointer
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 8
 		else:
 			return 4
@@ -41,7 +41,7 @@
 
 class NSNotificationUnknown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 

Modified: lldb/trunk/examples/summaries/cocoa/NSNumber.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/NSNumber.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/NSNumber.py (original)
+++ lldb/trunk/examples/summaries/cocoa/NSNumber.py Tue Feb 28 21:28:49 2012
@@ -16,7 +16,7 @@
 # obey the interface specification for synthetic children providers
 class NSTaggedNumber_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -60,7 +60,7 @@
 
 class NSUntaggedNumber_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -114,7 +114,7 @@
 								self.int)
 			statistics.metric_hit('code_notrun',self.valobj)
 			return '(int)' + str(data_vo.GetValueAsUnsigned(0) % (256*256*256*256))
-		# apparently, on lp64 architectures, these are the only values that will ever
+		# apparently, on is_64_bit architectures, these are the only values that will ever
 		# be represented by a non tagged pointers
 		elif data_type == 0B10001 or data_type == 0B0100:
 			data_offset = data_offset + self.pointer_size
@@ -146,7 +146,7 @@
 
 class NSUnknownNumber_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 

Modified: lldb/trunk/examples/summaries/cocoa/NSSet.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/NSSet.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/NSSet.py (original)
+++ lldb/trunk/examples/summaries/cocoa/NSSet.py Tue Feb 28 21:28:49 2012
@@ -15,7 +15,7 @@
 # obey the interface specification for synthetic children providers
 class NSCFSet_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -32,7 +32,7 @@
 	# then we have one other internal pointer, plus
 	# 4 bytes worth of flags. hence, these values
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 20
 		else:
 			return 12
@@ -46,7 +46,7 @@
 
 class NSSetUnknown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -67,7 +67,7 @@
 
 class NSSetI_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -78,14 +78,14 @@
 	def update(self):
 		self.adjust_for_architecture();
 		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
-		if self.lp64:
+		if self.is_64_bit:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
 		else:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
 
 	# we just need to skip the ISA and the count immediately follows
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 8
 		else:
 			return 4
@@ -100,7 +100,7 @@
 			# not sure if it is a bug or some weird sort of feature, but masking it out
 			# gets the count right (unless, of course, someone's dictionaries grow
 			#                       too large - but I have not tested this)
-			if self.lp64:
+			if self.is_64_bit:
 				value = value & ~0xFF00000000000000
 			else:
 				value = value & ~0xFF000000
@@ -108,7 +108,7 @@
 
 class NSSetM_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -119,14 +119,14 @@
 	def update(self):
 		self.adjust_for_architecture();
 		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
-		if self.lp64:
+		if self.is_64_bit:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
 		else:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
 
 	# we just need to skip the ISA and the count immediately follows
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 8
 		else:
 			return 4
@@ -200,7 +200,7 @@
 		if summary == None:
 			summary = 'no valid set here'
 		else:
-			if provider.lp64:
+			if provider.is_64_bit:
 				summary = int(summary) & ~0x1fff000000000000
 		return str(summary) + ' objects'
 	return ''

Modified: lldb/trunk/examples/summaries/cocoa/NSURL.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/NSURL.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/NSURL.py (original)
+++ lldb/trunk/examples/summaries/cocoa/NSURL.py Tue Feb 28 21:28:49 2012
@@ -16,7 +16,7 @@
 # obey the interface specification for synthetic children providers
 class NSURLKnown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 
@@ -27,7 +27,7 @@
 	def update(self):
 		self.adjust_for_architecture();
 		self.id_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeObjCID)
-		if self.lp64:
+		if self.is_64_bit:
 			self.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
 			self.pointer_size = 8
 		else:
@@ -41,7 +41,7 @@
 	# (which are also present on a 32-bit system)
 	# plus another pointer, and then the real data
 	def offset(self):
-		if self.lp64:
+		if self.is_64_bit:
 			return 24
 		else:
 			return 16
@@ -61,7 +61,7 @@
 
 class NSURLUnknown_SummaryProvider:
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 

Modified: lldb/trunk/examples/summaries/cocoa/objc_lldb.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/objc_lldb.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/objc_lldb.py (original)
+++ lldb/trunk/examples/summaries/cocoa/objc_lldb.py Tue Feb 28 21:28:49 2012
@@ -15,7 +15,7 @@
 		self.adjust_for_architecture() 
 
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 		self.addr_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
@@ -112,7 +112,7 @@
 
 		# read ro pointer
 		ro_pointer = data + 12 + self.pointer_size
-		if self.lp64:
+		if self.is_64_bit:
 			ro_pointer += 4
 		ro_object = self.valobj.CreateValueFromAddress("ro",
 			ro_pointer,

Modified: lldb/trunk/examples/summaries/cocoa/objc_runtime.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/summaries/cocoa/objc_runtime.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/examples/summaries/cocoa/objc_runtime.py (original)
+++ lldb/trunk/examples/summaries/cocoa/objc_runtime.py Tue Feb 28 21:28:49 2012
@@ -4,42 +4,25 @@
 
 class Utilities:
 	@staticmethod
-	def read_ascii(process, pointer,max_len=128,when_over_return_none=True):
+	def read_ascii(process, pointer,max_len=128):
 		error = lldb.SBError()
-		pystr = ''
-		count = 0
-		# there is not any length byte to tell us how much to read
-		# however, there are most probably ways to optimize this
-		# in order to avoid doing the read byte-by-byte (caching is
-		# still occurring, but we could just fetch a larger chunk
-		# of memory instead of going one byte at a time)
-		while True:
-			content = process.ReadMemory(pointer, 1, error)
-			new_bytes = bytearray(content)
-			if new_bytes == None or len(new_bytes) == 0:
-				break
-			b0 = new_bytes[0]
-			pointer = pointer + 1
-			if b0 == 0:
-				break
-			count = count + 1
-			if count > max_len:
-				if when_over_return_none:
-					return None
-				else:
-					return pystr
-			pystr = pystr + chr(b0)
-		return pystr
+		content = None
+		try:
+			content = process.ReadCStringFromMemory(pointer,max_len,error)
+		except:
+			pass
+		if content == None or len(content) == 0 or error.fail == True:
+			return None
+		return content
 
 	@staticmethod
-	def is_valid_pointer(pointer, pointer_size, allow_tagged):
+	def is_valid_pointer(pointer, pointer_size, allow_tagged=False, allow_NULL=False):
 		if pointer == None:
 			return False
 		if pointer == 0:
-			return False
-		if allow_tagged:
-			if (pointer % 2) == 1:
-				return True
+			return allow_NULL
+		if allow_tagged and (pointer % 2) == 1:
+			return True
 		return ((pointer % pointer_size) == 0)
 
 	# Objective-C runtime has a rule that pointers in a class_t will only have bits 0 thru 46 set
@@ -48,10 +31,7 @@
 	def is_allowed_pointer(pointer):
 		if pointer == None:
 			return False
-		mask = 0xFFFF800000000000
-		if (pointer & mask) != 0:
-			return False
-		return True
+		return ((pointer & 0xFFFF800000000000) == 0)
 
 	@staticmethod
 	def read_child_of(valobj,offset,type):
@@ -66,32 +46,36 @@
 			return None
 		if len(name) == 0:
 			return None
-		return True
-		# the rules below make perfect sense for compile-time class names, but the runtime is free
-		# to create classes with arbitrary names to implement functionality (e.g -poseAsClass)
-		# hence, we cannot really outlaw anything appearing in an identifier
-		#ok_first = dict.fromkeys("$ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_")
-		#ok_others = dict.fromkeys("$ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_1234567890")
-		#if name[0] not in ok_first:
-		#	return False
-		#return all(c in ok_others for c in name[1:])
+		# technically, the ObjC runtime does not enforce any rules about what name a class can have
+		# in practice, the commonly used byte values for a class name are the letters, digits and some
+		# symbols: $, %, -, _, .
+		# WARNING: this means that you cannot use this runtime implementation if you need to deal
+		# with class names that use anything but what is allowed here
+		ok_values = dict.fromkeys("$%_.-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890")
+		return all(c in ok_values for c in name)
+
+	@staticmethod
+	def check_is_osx_lion(target):
+		# assume the only thing that has a Foundation.framework is a Mac
+		# assume anything < Lion does not even exist
+		mod = target.module['Foundation']
+		if mod == None or mod.IsValid() == False:
+			return None
+		ver = mod.GetVersion()
+		if ver == None or ver == []:
+			return None
+		return (ver[0] < 900)
 
 class RoT_Data:
 	def __init__(self,rot_pointer,params):
 		if (Utilities.is_valid_pointer(rot_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=False)):
 			self.sys_params = params
 			self.valobj = rot_pointer
-			self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t)
+			#self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t)
 			self.instanceStart = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t)
 			self.instanceSize = Utilities.read_child_of(self.valobj,8,self.sys_params.uint32_t)
-			if self.sys_params.lp64:
-				self.reserved = Utilities.read_child_of(self.valobj,12,self.sys_params.uint32_t)
-				offset = 16
-			else:
-				self.reserved = 0
-				offset = 12
-			self.ivarLayoutPtr = Utilities.read_child_of(self.valobj,offset,self.sys_params.addr_ptr_type)
-			offset = offset + self.sys_params.pointer_size
+			offset = 24 if self.sys_params.is_64_bit else 16
+			#self.ivarLayoutPtr = Utilities.read_child_of(self.valobj,offset,self.sys_params.addr_ptr_type)
 			self.namePointer = Utilities.read_child_of(self.valobj,offset,self.sys_params.addr_ptr_type)
 			self.check_valid()
 		else:
@@ -110,11 +94,9 @@
 		#	pass
 
 	def __str__(self):
-		return 'flags = ' + str(self.flags) + "\n" + \
+		return \
 		 "instanceStart = " + hex(self.instanceStart) + "\n" + \
 		 "instanceSize = " + hex(self.instanceSize) + "\n" + \
-		 "reserved = " + hex(self.reserved) + "\n" + \
-		 "ivarLayoutPtr = " + hex(self.ivarLayoutPtr) + "\n" + \
 		 "namePointer = " + hex(self.namePointer) + " --> " + self.name
 
 	def is_valid(self):
@@ -126,8 +108,8 @@
 		if (Utilities.is_valid_pointer(rwt_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=False)):
 			self.sys_params = params
 			self.valobj = rwt_pointer
-			self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t)
-			self.version = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t)
+			#self.flags = Utilities.read_child_of(self.valobj,0,self.sys_params.uint32_t)
+			#self.version = Utilities.read_child_of(self.valobj,4,self.sys_params.uint32_t)
 			self.roPointer = Utilities.read_child_of(self.valobj,8,self.sys_params.addr_ptr_type)
 			self.check_valid()
 		else:
@@ -143,8 +125,7 @@
 			self.valid = False
 
 	def __str__(self):
-		return 'flags = ' + str(self.flags) + "\n" + \
-		 "version = " + hex(self.version) + "\n" + \
+		return \
 		 "roPointer = " + hex(self.roPointer)
 
 	def is_valid(self):
@@ -207,12 +188,15 @@
 			self.valid = False
 			return
 
+	# in general, KVO is implemented by transparently subclassing
+	# however, there could be exceptions where a class does something else
+	# internally to implement the feature - this method will have no clue that a class
+	# has been KVO'ed unless the standard implementation technique is used
 	def is_kvo(self):
 		if self.is_valid():
-			if self.data.data.name.startswith("NSKVONotify"):
+			if self.class_name().startswith("NSKVONotifying_"):
 				return True
-		else:
-			return None
+		return False
 
 	def get_superclass(self):
 		if self.is_valid():
@@ -249,7 +233,7 @@
 			return None
 		if align:
 			unalign = self.instance_size(False)
-			if self.sys_params.lp64:
+			if self.sys_params.is_64_bit:
 				return ((unalign + 7) & ~7) % 0x100000000
 			else:
 				return ((unalign + 3) & ~3) % 0x100000000
@@ -268,13 +252,6 @@
 			self.version = Utilities.read_child_of(self.valobj,3*self.sys_params.pointer_size,self.sys_params.addr_ptr_type)
 			self.info = Utilities.read_child_of(self.valobj,4*self.sys_params.pointer_size,self.sys_params.addr_ptr_type)
 			self.instanceSize = Utilities.read_child_of(self.valobj,5*self.sys_params.pointer_size,self.sys_params.addr_ptr_type)
-			# since we do not introspect ivars, methods, ... these four pointers need not be named in a meaningful way
-			# moreover, we do not care about their values, just that they are correctly aligned
-			self.ptr1 = Utilities.read_child_of(self.valobj,6*self.sys_params.pointer_size,self.sys_params.addr_ptr_type)
-			self.ptr2 = Utilities.read_child_of(self.valobj,7*self.sys_params.pointer_size,self.sys_params.addr_ptr_type)
-			self.ptr3 = Utilities.read_child_of(self.valobj,8*self.sys_params.pointer_size,self.sys_params.addr_ptr_type)
-			self.ptr4 = Utilities.read_child_of(self.valobj,9*self.sys_params.pointer_size,self.sys_params.addr_ptr_type)
-			self.check_valid()
 		else:
 			self.valid = False
 		if self.valid:
@@ -293,16 +270,19 @@
 			if self.superclassIsaPointer != 0:
 				self.valid = False
 				return
-		#if not(Utilities.is_valid_pointer(self.namePointer,self.sys_params.pointer_size,allow_tagged=False)):
-		#	self.valid = False
-		#	return
+		if not(Utilities.is_valid_pointer(self.namePointer,self.sys_params.pointer_size,allow_tagged=False,allow_NULL=True)):
+			self.valid = False
+			return
 
+	# in general, KVO is implemented by transparently subclassing
+	# however, there could be exceptions where a class does something else
+	# internally to implement the feature - this method will have no clue that a class
+	# has been KVO'ed unless the standard implementation technique is used
 	def is_kvo(self):
 		if self.is_valid():
-			if self.name.startswith("NSKVONotify"):
+			if self.class_name().startswith("NSKVONotifying_"):
 				return True
-		else:
-			return None
+		return False
 
 	def get_superclass(self):
 		if self.is_valid():
@@ -338,15 +318,19 @@
 			return None
 		if align:
 			unalign = self.instance_size(False)
-			if self.sys_params.lp64:
+			if self.sys_params.is_64_bit:
 				return ((unalign + 7) & ~7) % 0x100000000
 			else:
 				return ((unalign + 3) & ~3) % 0x100000000
 		else:
 			return self.instanceSize
 
+TaggedClass_Values_Lion = {3 : 'NSNumber', 6: 'NSDate'}; # double check NSDate
+TaggedClass_Values_NMOS = {3 : 'NSNumber', 6: 'NSDate'}; # double check NSNumber
+
 class TaggedClass_Data:
 	def __init__(self,pointer,params):
+		global TaggedClass_Values_Lion, TaggedClass_Values_NMOS
 		self.valid = True
 		self.name = None
 		self.sys_params = params
@@ -354,28 +338,18 @@
 		self.val = (pointer & ~0x0000000000000000FF) >> 8
 		self.class_bits = (pointer & 0xE) >> 1
 		self.i_bits = (pointer & 0xF0) >> 4
-		# ignoring the LSB, NSNumber gets marked
-		# as 3 on Zin and as 1 on Lion - I can either make
-		# a difference or accept false positives
-		# ToT LLDB + some knowledge of framework versioning
-		# would let me do the right thing - for now I just
-		# act dumb and accept false positives
-		if self.class_bits == 0 or \
-		   self.class_bits == 5 or \
-		   self.class_bits == 7 or \
-		   self.class_bits == 9:
-			self.valid = False
-			return
-		elif self.class_bits == 3 or self.class_bits == 1:
-			self.name = 'NSNumber'
-		elif self.class_bits == 11:
-			self.name = 'NSManagedObject'
-		elif self.class_bits == 13:
-			self.name = 'NSDate'
-		elif self.class_bits == 15:
-			self.name = 'NSDateTS' # not sure what this is
+		
+		if self.sys_params.is_lion:
+			if self.class_bits in TaggedClass_Values_Lion:
+				self.name = TaggedClass_Values_Lion[self.class_bits]
+			else:
+				self.valid = False
 		else:
-			self.valid = False
+			if self.class_bits in TaggedClass_Values_NMOS:
+				self.name = TaggedClass_Values_NMOS[self.class_bits]
+			else:
+				self.valid = False
+
 
 	def is_valid(self):
 		return self.valid
@@ -384,7 +358,7 @@
 		if self.is_valid():
 			return self.name
 		else:
-			return None
+			return False
 
 	def value(self):
 		return self.val if self.is_valid() else None
@@ -409,7 +383,7 @@
 	def instance_size(self,align=False):
 		if self.is_valid() == False:
 			return None
-		return 8 if self.sys_params.lp64 else 4
+		return 8 if self.sys_params.is_64_bit else 4
 
 
 class InvalidClass_Data:
@@ -419,6 +393,7 @@
 		return False
 
 runtime_version = cache.Cache()
+os_version = cache.Cache()
 
 class SystemParameters:
 	def __init__(self,valobj):
@@ -426,19 +401,25 @@
 
 	def adjust_for_architecture(self,valobj):
 		self.process = valobj.GetTarget().GetProcess()
-		self.lp64 = (self.process.GetAddressByteSize() == 8)
+		self.is_64_bit = (self.process.GetAddressByteSize() == 8)
 		self.is_little = (self.process.GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.process.GetAddressByteSize()
 		self.addr_type = valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
 		self.addr_ptr_type = self.addr_type.GetPointerType()
 		self.uint32_t = valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
 		global runtime_version
+		global os_version
 		pid = self.process.GetProcessID()
 		if runtime_version.look_for_key(pid):
 			self.runtime_version = runtime_version.get_value(pid)
 		else:
 			self.runtime_version = ObjCRuntime.runtime_version(self.process)
 			runtime_version.add_item(pid,self.runtime_version)
+		if os_version.look_for_key(pid):
+			self.is_lion = os_version.get_value(pid)
+		else:
+			self.is_lion = Utilities.check_is_osx_lion(valobj.GetTarget())
+			os_version.add_item(pid,self.is_lion)
 
 isa_cache = cache.Cache()
 
@@ -476,9 +457,11 @@
 		self.valobj = valobj
 		self.adjust_for_architecture()
 		self.sys_params = SystemParameters(self.valobj)
+		self.unsigned_value = self.valobj.GetValueAsUnsigned()
+		self.isa_value = None
 
 	def adjust_for_architecture(self):
-		self.lp64 = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
+		self.is_64_bit = (self.valobj.GetTarget().GetProcess().GetAddressByteSize() == 8)
 		self.is_little = (self.valobj.GetTarget().GetProcess().GetByteOrder() == lldb.eByteOrderLittle)
 		self.pointer_size = self.valobj.GetTarget().GetProcess().GetAddressByteSize()
 		self.addr_type = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
@@ -488,16 +471,19 @@
 	def is_tagged(self):
 		if self.valobj is None:
 			return False
-		return (Utilities.is_valid_pointer(self.valobj.GetValueAsUnsigned(),self.pointer_size, allow_tagged=True) and not(Utilities.is_valid_pointer(self.valobj.GetValueAsUnsigned(),self.pointer_size, allow_tagged=False)))
+		return (Utilities.is_valid_pointer(self.unsigned_value,self.pointer_size, allow_tagged=True) and \
+		not(Utilities.is_valid_pointer(self.unsigned_value,self.pointer_size, allow_tagged=False)))
 
 	def is_valid(self):
 		if self.valobj is None:
 			return False
 		if self.valobj.IsInScope() == False:
 			return False
-		return Utilities.is_valid_pointer(self.valobj.GetValueAsUnsigned(),self.pointer_size, allow_tagged=True)
+		return Utilities.is_valid_pointer(self.unsigned_value,self.pointer_size, allow_tagged=True)
 
 	def read_isa(self):
+		if self.isa_value != None:
+			return self.isa_value
 		isa_pointer = self.valobj.CreateChildAtOffset("cfisa",
 			0,
 			self.addr_ptr_type)
@@ -505,6 +491,7 @@
 			return None;
 		if isa_pointer.GetValueAsUnsigned(1) == 1:
 			return None;
+		self.isa_value = isa_pointer
 		return isa_pointer
 
 	def read_class_data(self):
@@ -515,7 +502,7 @@
 				# not every odd-valued pointer is actually tagged. most are just plain wrong
 				# we could try and predetect this before even creating a TaggedClass_Data object
 				# but unless performance requires it, this seems a cleaner way to tackle the task
-				tentative_tagged = TaggedClass_Data(self.valobj.GetValueAsUnsigned(0),self.sys_params)
+				tentative_tagged = TaggedClass_Data(self.unsigned_value,self.sys_params)
 				return tentative_tagged if tentative_tagged.is_valid() else InvalidClass_Data()
 			else:
 				return InvalidClass_Data()

Modified: lldb/trunk/include/lldb/Core/FormatClasses.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatClasses.h?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatClasses.h (original)
+++ lldb/trunk/include/lldb/Core/FormatClasses.h Tue Feb 28 21:28:49 2012
@@ -1158,8 +1158,9 @@
     {
     }
     
-    virtual std::string
-    FormatObject (lldb::ValueObjectSP object) = 0;
+    virtual bool
+    FormatObject (lldb::ValueObjectSP object,
+                  std::string& dest) = 0;
     
     virtual std::string
     GetDescription () = 0;
@@ -1211,8 +1212,9 @@
     {
     }
     
-    virtual std::string
-    FormatObject(lldb::ValueObjectSP object);
+    virtual bool
+    FormatObject(lldb::ValueObjectSP object,
+                 std::string& dest);
     
     virtual std::string
     GetDescription();
@@ -1232,6 +1234,7 @@
 {
     std::string m_function_name;
     std::string m_python_script;
+    lldb::ScriptInterpreterObjectSP m_script_function_sp;
     
     ScriptSummaryFormat(const TypeSummaryImpl::Flags& flags,
                         const char *function_name,
@@ -1273,8 +1276,9 @@
     {
     }
     
-    virtual std::string
-    FormatObject(lldb::ValueObjectSP object);
+    virtual bool
+    FormatObject(lldb::ValueObjectSP object,
+                 std::string& dest);
     
     virtual std::string
     GetDescription();

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Tue Feb 28 21:28:49 2012
@@ -20,6 +20,43 @@
 
 namespace lldb_private {
 
+class ScriptInterpreterObject
+{
+public:
+    ScriptInterpreterObject() :
+    m_object(NULL)
+    {}
+    
+    ScriptInterpreterObject(void* obj) :
+    m_object(obj)
+    {}
+    
+    ScriptInterpreterObject(const ScriptInterpreterObject& rhs)
+    : m_object(rhs.m_object)
+    {}
+    
+    virtual void*
+    GetObject()
+    {
+        return m_object;
+    }
+    
+    ScriptInterpreterObject&
+    operator = (const ScriptInterpreterObject& rhs)
+    {
+        if (this != &rhs)
+            m_object = rhs.m_object;
+        return *this;
+    }
+        
+    virtual
+    ~ScriptInterpreterObject()
+    {}
+    
+protected:
+    void* m_object;
+};
+
 class ScriptInterpreter
 {
 public:
@@ -31,9 +68,11 @@
                                                     const lldb::StackFrameSP& frame_sp,
                                                     const lldb::BreakpointLocationSP &bp_loc_sp);
     
-    typedef std::string (*SWIGPythonTypeScriptCallbackFunction) (const char *python_function_name,
-                                                                 const char *session_dictionary_name,
-                                                                 const lldb::ValueObjectSP& valobj_sp);
+    typedef bool (*SWIGPythonTypeScriptCallbackFunction) (const char *python_function_name,
+                                                          void *session_dictionary,
+                                                          const lldb::ValueObjectSP& valobj_sp,
+                                                          void** pyfunct_wrapper,
+                                                          std::string& retval);
     
     typedef void* (*SWIGPythonCreateSyntheticProvider) (const std::string python_class_name,
                                                         const char *session_dictionary_name,
@@ -163,6 +202,15 @@
         return;
     }
     
+    virtual bool
+    GetScriptedSummary (const char *function_name,
+                        lldb::ValueObjectSP valobj,
+                        lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
+                        std::string& retval)
+    {
+        return false;
+    }
+    
     virtual uint32_t
     CalculateNumChildren (void *implementor)
     {
@@ -211,6 +259,12 @@
         return false;
     }
 
+    virtual lldb::ScriptInterpreterObjectSP
+    MakeScriptObject (void* object)
+    {
+        return lldb::ScriptInterpreterObjectSP(new ScriptInterpreterObject(object));
+    }
+    
     const char *
     GetScriptInterpreterPtyName ();
 
@@ -224,17 +278,7 @@
     LanguageToString (lldb::ScriptLanguage language);
     
     static void
-    InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
-                           SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
-                           SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback,
-                           SWIGPythonCreateSyntheticProvider python_swig_synthetic_script,
-                           SWIGPythonCalculateNumChildren python_swig_calc_children,
-                           SWIGPythonGetChildAtIndex python_swig_get_child_index,
-                           SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
-                           SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
-                           SWIGPythonUpdateSynthProviderInstance python_swig_update_provider,
-                           SWIGPythonCallCommand python_swig_call_command,
-                           SWIGPythonCallModuleInit python_swig_call_mod_init);
+    InitializeInterpreter (SWIGInitCallback python_swig_init_callback);
 
     static void
     TerminateInterpreter ();

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Tue Feb 28 21:28:49 2012
@@ -113,9 +113,11 @@
                                 lldb::user_id_t break_id,
                                 lldb::user_id_t break_loc_id);
     
-    static std::string
-    CallPythonScriptFunction (const char *python_function_name,
-                              lldb::ValueObjectSP valobj);
+    virtual bool
+    GetScriptedSummary (const char *function_name,
+                        lldb::ValueObjectSP valobj,
+                        lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
+                        std::string& retval);
     
     virtual std::string
     GetDocumentationForItem (const char* item);
@@ -124,7 +126,10 @@
     LoadScriptingModule (const char* filename,
                          bool can_reload,
                          lldb_private::Error& error);
-
+    
+    virtual lldb::ScriptInterpreterObjectSP
+    MakeScriptObject (void* object);
+    
     void
     CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
                                              CommandReturnObject &result);
@@ -147,17 +152,7 @@
     InitializePrivate ();
 
     static void
-    InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
-                           SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
-                           SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback,
-                           SWIGPythonCreateSyntheticProvider python_swig_synthetic_script,
-                           SWIGPythonCalculateNumChildren python_swig_calc_children,
-                           SWIGPythonGetChildAtIndex python_swig_get_child_index,
-                           SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
-                           SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
-                           SWIGPythonUpdateSynthProviderInstance python_swig_update_provider,
-                           SWIGPythonCallCommand python_swig_call_command,
-                           SWIGPythonCallModuleInit python_swig_call_mod_init);
+    InitializeInterpreter (SWIGInitCallback python_swig_init_callback);
 
 protected:
 
@@ -187,6 +182,29 @@
         ~SynchronicityHandler();
     };
     
+    class ScriptInterpreterPythonObject : public ScriptInterpreterObject
+    {
+    public:
+        ScriptInterpreterPythonObject() :
+        ScriptInterpreterObject()
+        {}
+        
+        ScriptInterpreterPythonObject(void* obj) :
+        ScriptInterpreterObject(obj)
+        {
+            Py_XINCREF(m_object);
+        }
+        
+        virtual
+        ~ScriptInterpreterPythonObject()
+        {
+            Py_XDECREF(m_object);
+            m_object = NULL;
+        }
+        private:
+            DISALLOW_COPY_AND_ASSIGN (ScriptInterpreterPythonObject);
+    };
+    
 	class Locker
 	{
 	public:

Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Tue Feb 28 21:28:49 2012
@@ -136,6 +136,7 @@
 class   RegularExpression;
 class   Scalar;
 class   ScriptInterpreter;
+class   ScriptInterpreterObject;
 #ifndef LLDB_DISABLE_PYTHON
 class   ScriptInterpreterPython;
 struct  ScriptSummaryFormat;
@@ -276,6 +277,7 @@
     typedef std::tr1::shared_ptr<lldb_private::Section> SectionSP;
     typedef std::tr1::weak_ptr<lldb_private::Section> SectionWP;
     typedef std::tr1::shared_ptr<lldb_private::SearchFilter> SearchFilterSP;
+    typedef std::tr1::shared_ptr<lldb_private::ScriptInterpreterObject> ScriptInterpreterObjectSP;
 #ifndef LLDB_DISABLE_PYTHON
     typedef std::tr1::shared_ptr<lldb_private::ScriptSummaryFormat> ScriptSummaryFormatSP;
 #endif // #ifndef LLDB_DISABLE_PYTHON

Modified: lldb/trunk/scripts/Python/finish-swig-Python-LLDB.sh
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/finish-swig-Python-LLDB.sh?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/finish-swig-Python-LLDB.sh (original)
+++ lldb/trunk/scripts/Python/finish-swig-Python-LLDB.sh Tue Feb 28 21:28:49 2012
@@ -382,6 +382,20 @@
     fi
 fi
 
+if [ -f "${SRC_ROOT}/examples/summaries/cocoa/NSDate.py" ]
+then
+    if [ $Debug == 1 ]
+    then
+        echo "Copying NSDate.py to ${framework_python_dir}"
+    fi
+    cp "${SRC_ROOT}/examples/summaries/cocoa/NSDate.py" "${framework_python_dir}"
+else
+    if [ $Debug == 1 ]
+    then
+        echo "Unable to find ${SRC_ROOT}/examples/summaries/cocoa/NSDate.py"
+    fi
+fi
+
 if [ -f "${SRC_ROOT}/examples/summaries/cocoa/cache.py" ]
 then
     if [ $Debug == 1 ]

Modified: lldb/trunk/scripts/Python/python-wrapper.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-wrapper.swig (original)
+++ lldb/trunk/scripts/Python/python-wrapper.swig Tue Feb 28 21:28:49 2012
@@ -31,10 +31,7 @@
 ResolvePythonName(const char* name,
                   PyObject* pmodule = NULL)
 {
-
-    //printf("Resolving %s\n", name);
-
-    if (!name || !name[0])
+    if (!name)
         return pmodule;
 
     PyErr_Cleaner pyerr_cleanup(true);  // show Python errors
@@ -65,40 +62,33 @@
 
     if (!dot_pos)
     {
-        if (PyDict_Check (main_dict))
+        dest_object = NULL;   
+        while (PyDict_Next (main_dict, &pos, &key, &value))
         {
-            dest_object = NULL;   
-            while (PyDict_Next (main_dict, &pos, &key, &value))
+            // We have stolen references to the key and value objects in the dictionary; we need to increment 
+            // them now so that Python's garbage collector doesn't collect them out from under us.
+            Py_INCREF (key);
+            Py_INCREF (value);
+            if (strcmp (PyString_AsString (key), name) == 0)
             {
-                // We have stolen references to the key and value objects in the dictionary; we need to increment 
-                // them now so that Python's garbage collector doesn't collect them out from under us.
-                Py_INCREF (key);
-                Py_INCREF (value);
-                //printf("Comparing %s and %s\n", name, PyString_AsString (key));
-                if (strcmp (PyString_AsString (key), name) == 0)
-                {
-                    dest_object = value;
-                    break;
-                }
+                dest_object = value;
+                break;
             }
-        }
-        
+        }        
         if (!dest_object || dest_object == Py_None)
             return NULL;
         return dest_object;
     }
-    // foo.bar.ba
-    // 0123456789
-    // len = 3 - 0 
-    size_t len = dot_pos - name;
-    std::string piece(name,len);
-    dest_object = ResolvePythonName(piece.c_str(), main_dict);
-    //printf("Resolved %s to %p\n", piece.c_str(), dest_object);
-    if (!dest_object)
-        return NULL;
-    //printf("Now moving to resolve %s\n", dot_pos+1);
-    return ResolvePythonName(dot_pos+1,dest_object); // tail recursion.. should be optimized by the compiler
-
+    else
+    {
+        size_t len = dot_pos - name;
+        std::string piece(name,len);
+        pmodule = ResolvePythonName(piece.c_str(), main_dict);
+        if (!pmodule)
+            return NULL;
+        name = dot_pos+1;
+        return ResolvePythonName(dot_pos+1,pmodule); // tail recursion.. should be optimized by the compiler
+    }
 }
 
 static PyObject*
@@ -186,85 +176,69 @@
     return stop_at_breakpoint;
 }
 
-SWIGEXPORT std::string
+SWIGEXPORT bool
 LLDBSwigPythonCallTypeScript 
 (
     const char *python_function_name,
-    const char *session_dictionary_name,
-    const lldb::ValueObjectSP& valobj_sp
+    const void *session_dictionary,
+    const lldb::ValueObjectSP& valobj_sp,
+    void** pyfunct_wrapper,
+    std::string& retval
 )
 {
     lldb::SBValue sb_value (valobj_sp);
 
-    std::string retval = "";
-
     PyObject *ValObj_PyObj = SWIG_NewPointerObj((void *) &sb_value, SWIGTYPE_p_lldb__SBValue, 0);
     
     if (ValObj_PyObj == NULL)
-        return retval;
+        return false;
         
-    if (!python_function_name || !session_dictionary_name)
-        return retval;
+    if (!python_function_name || !session_dictionary)
+        return false;
 
-    PyObject *session_dict, *pfunc;
-    PyObject *pargs, *pvalue;
+    PyObject *session_dict = (PyObject*)session_dictionary, *pfunc = NULL, *pargs = NULL, *pvalue = NULL;
     
-    session_dict = FindSessionDictionary (session_dictionary_name);
-    if (session_dict != NULL)
+    if (pyfunct_wrapper && *pyfunct_wrapper && PyFunction_Check (*pyfunct_wrapper))
     {
-        pfunc = ResolvePythonName (python_function_name, session_dict);
-        if (pfunc != NULL)
+        pfunc = (PyObject*)(*pyfunct_wrapper);
+        if (pfunc->ob_refcnt == 1)
         {
-            // Set up the arguments and call the function.
-                
-            if (PyCallable_Check (pfunc))
-            {
-                pargs = PyTuple_New (2);
-                if (pargs == NULL)
-                {
-                    if (PyErr_Occurred())
-                        PyErr_Clear();
-                    return retval;
-                }
-                
-                PyTuple_SetItem (pargs, 0, ValObj_PyObj);  // This "steals" a reference to ValObj_PyObj
-                PyTuple_SetItem (pargs, 1, session_dict); // This "steals" a reference to session_dict
-                pvalue = PyObject_CallObject (pfunc, pargs);
-                Py_DECREF (pargs);
-                
-                if (pvalue != NULL)
-                {
-                    if (pvalue != Py_None && PyString_CheckExact(pvalue))
-                        retval = std::string(PyString_AsString(pvalue));
-                    else
-                        retval = "None";
-                    Py_DECREF (pvalue);
-                }
-                else if (PyErr_Occurred ())
-                {
-                    PyErr_Print();
-                    PyErr_Clear();
-                }
-                Py_INCREF (session_dict);
-            }
-            else if (PyErr_Occurred())
-            {
-                PyErr_Print();
-                PyErr_Clear();
-            }
-        }
-        else if (PyErr_Occurred())
-        {
-            PyErr_Print();
-            PyErr_Clear();
+            Py_XDECREF(pfunc);
+            pfunc = NULL;
         }
     }
-    else if (PyErr_Occurred ())
+
+    if (PyDict_Check(session_dict))
     {
-        PyErr_Print();
-        PyErr_Clear ();
+        PyErr_Cleaner pyerr_cleanup(true);  // show Python errors
+        
+        if (!pfunc)
+        {
+            pfunc = ResolvePythonName (python_function_name, session_dict);
+            if (!pfunc || !PyFunction_Check (pfunc))
+                return false;
+            else
+            {
+                if (pyfunct_wrapper)
+                    *pyfunct_wrapper = pfunc;
+            }
+        }
+        /*else
+            printf("caching works!!!!\n");*/
+        
+        pargs = PyTuple_Pack(2, ValObj_PyObj, session_dict);
+        if (pargs == NULL)
+            return false;
+        
+        pvalue = PyObject_CallObject (pfunc, pargs);
+        Py_DECREF (pargs);
+        
+        if (pvalue != NULL && pvalue != Py_None && PyString_Check(pvalue))
+            retval.assign(PyString_AsString(pvalue));
+        Py_XDECREF (pvalue);
+        Py_INCREF (session_dict);
     }
-    return retval;
+    return true;
 }
 
 SWIGEXPORT void*

Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/source/API/SBCommandInterpreter.cpp (original)
+++ lldb/trunk/source/API/SBCommandInterpreter.cpp Tue Feb 28 21:28:49 2012
@@ -312,59 +312,11 @@
 
 
 #ifndef LLDB_DISABLE_PYTHON
-extern "C" bool
-LLDBSwigPythonBreakpointCallbackFunction 
-(
-    const char *python_function_name,
-    const char *session_dictionary_name,
-    const lldb::StackFrameSP& sb_frame, 
-    const lldb::BreakpointLocationSP& sb_bp_loc
-);
-
-extern "C" std::string
-LLDBSwigPythonCallTypeScript 
-(
-    const char *python_function_name,
-    const char *session_dictionary_name,
-    const lldb::ValueObjectSP& valobj_sp
-);
-
-extern "C" void*
-LLDBSwigPythonCreateSyntheticProvider 
-(
-    const std::string python_class_name,
-    const char *session_dictionary_name,
-    const lldb::ValueObjectSP& valobj_sp
-);
-
-
-extern "C" uint32_t       LLDBSwigPython_CalculateNumChildren        (void *implementor);
-extern "C" void*          LLDBSwigPython_GetChildAtIndex             (void *implementor, uint32_t idx);
-extern "C" int            LLDBSwigPython_GetIndexOfChildWithName     (void *implementor, const char* child_name);
-extern "C" void*          LLDBSWIGPython_CastPyObjectToSBValue       (void* data);
-extern "C" void           LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
-
-extern "C" bool           LLDBSwigPythonCallCommand 
-(
-    const char *python_function_name,
-    const char *session_dictionary_name,
-    lldb::DebuggerSP& debugger,
-    const char* args,
-    std::string& err_msg,
-    lldb_private::CommandReturnObject& cmd_retobj
-);
 
 // Defined in the SWIG source file
 extern "C" void 
 init_lldb(void);
 
-extern "C" bool           LLDBSwigPythonCallModuleInit 
-(
-    const std::string python_module_name,
-    const char *session_dictionary_name,
-    lldb::DebuggerSP& debugger
-);
-
 #else
 
 extern "C" void init_lldb(void);
@@ -385,17 +337,7 @@
     {
         g_initialized = true;
 #ifndef LLDB_DISABLE_PYTHON
-        ScriptInterpreter::InitializeInterpreter (init_lldb, 
-                                                  LLDBSwigPythonBreakpointCallbackFunction,
-                                                  LLDBSwigPythonCallTypeScript,
-                                                  LLDBSwigPythonCreateSyntheticProvider,
-                                                  LLDBSwigPython_CalculateNumChildren,
-                                                  LLDBSwigPython_GetChildAtIndex,
-                                                  LLDBSwigPython_GetIndexOfChildWithName,
-                                                  LLDBSWIGPython_CastPyObjectToSBValue,
-                                                  LLDBSwigPython_UpdateSynthProviderInstance,
-                                                  LLDBSwigPythonCallCommand,
-                                                  LLDBSwigPythonCallModuleInit);
+        ScriptInterpreter::InitializeInterpreter (init_lldb);
 #endif
     }
 }

Modified: lldb/trunk/source/Core/FormatClasses.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatClasses.cpp?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatClasses.cpp (original)
+++ lldb/trunk/source/Core/FormatClasses.cpp Tue Feb 28 21:28:49 2012
@@ -35,6 +35,7 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/FormatClasses.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/Core/Timer.h"
 #include "lldb/Core/ValueObjectConstResult.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Symbol/ClangASTType.h"
@@ -78,11 +79,15 @@
     m_format.assign(format_cstr);
 }
 
-std::string
-StringSummaryFormat::FormatObject(lldb::ValueObjectSP object)
+bool
+StringSummaryFormat::FormatObject(lldb::ValueObjectSP object,
+                                  std::string& retval)
 {
     if (!object.get())
-        return "NULL";
+    {
+        retval.assign("NULL sp");
+        return false;
+    }
     
     StreamString s;
     ExecutionContext exe_ctx (object->GetExecutionContextRef());
@@ -117,18 +122,28 @@
             
             s.PutChar(')');
             
-            return s.GetString();
+            retval.assign(s.GetString());
+            return true;
         }
         else
-            return "";
+        {
+            retval.assign("error: oneliner for no children");
+            return false;
+        }
         
     }
     else
     {
         if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, object.get()))
-            return s.GetString();
+        {
+            retval.assign(s.GetString());
+            return true;
+        }
         else
-            return "";
+        {
+            retval.assign("error: summary string parsing error");
+            return false;
+        }
     }
 }
 
@@ -156,7 +171,8 @@
                                          const char * python_script) :
     TypeSummaryImpl(flags),
     m_function_name(),
-    m_python_script()
+    m_python_script(),
+    m_script_function_sp()
 {
    if (function_name)
      m_function_name.assign(function_name);
@@ -164,11 +180,26 @@
      m_python_script.assign(python_script);
 }
 
-std::string
-ScriptSummaryFormat::FormatObject(lldb::ValueObjectSP object)
+bool
+ScriptSummaryFormat::FormatObject(lldb::ValueObjectSP object,
+                                  std::string& retval)
 {
-    return std::string(ScriptInterpreterPython::CallPythonScriptFunction(m_function_name.c_str(),
-                                                                         object).c_str());
+    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+
+    Debugger& dbg = object->GetTargetSP()->GetDebugger();
+    ScriptInterpreter *script_interpreter = dbg.GetCommandInterpreter().GetScriptInterpreter();
+    
+    if (!script_interpreter)
+    {
+        retval.assign("error: no ScriptInterpreter");
+        return false;
+    }
+        
+    return script_interpreter->GetScriptedSummary(m_function_name.c_str(),
+                                                  object,
+                                                  m_script_function_sp,
+                                                  retval);
+
 }
 
 std::string

Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Tue Feb 28 21:28:49 2012
@@ -854,6 +854,8 @@
     AddScriptSummary(appkit_category_sp, "NSURL.NSURL_SummaryProvider", ConstString("NSURL"), appkit_flags);
     AddScriptSummary(appkit_category_sp, "NSURL.NSURL_SummaryProvider", ConstString("CFURLRef"), appkit_flags);
     
+    AddScriptSummary(appkit_category_sp, "NSDate.NSDate_SummaryProvider", ConstString("NSDate"), appkit_flags);
+    
     TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
 
     TypeSummaryImpl::Flags vector_flags;

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Tue Feb 28 21:28:49 2012
@@ -674,7 +674,8 @@
 
             if (summary_format)
             {
-                m_summary_str = summary_format->FormatObject(GetSP());
+                 summary_format->FormatObject(GetSP(),
+                                              m_summary_str);
             }
             else
             {

Modified: lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreter.cpp?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreter.cpp Tue Feb 28 21:28:49 2012
@@ -69,30 +69,10 @@
 }
 
 void
-ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
-                                          SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
-                                          SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback,
-                                          SWIGPythonCreateSyntheticProvider python_swig_synthetic_script,
-                                          SWIGPythonCalculateNumChildren python_swig_calc_children,
-                                          SWIGPythonGetChildAtIndex python_swig_get_child_index,
-                                          SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
-                                          SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
-                                          SWIGPythonUpdateSynthProviderInstance python_swig_update_provider,
-                                          SWIGPythonCallCommand python_swig_call_command,
-                                          SWIGPythonCallModuleInit python_swig_call_mod_init)
+ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_callback)
 {
 #ifndef LLDB_DISABLE_PYTHON
-    ScriptInterpreterPython::InitializeInterpreter (python_swig_init_callback, 
-                                                    python_swig_breakpoint_callback,
-                                                    python_swig_typescript_callback,
-                                                    python_swig_synthetic_script,
-                                                    python_swig_calc_children,
-                                                    python_swig_get_child_index,
-                                                    python_swig_get_index_child,
-                                                    python_swig_cast_to_sbvalue,
-                                                    python_swig_update_provider,
-                                                    python_swig_call_command,
-                                                    python_swig_call_mod_init);
+    ScriptInterpreterPython::InitializeInterpreter (python_swig_init_callback);
 #endif // #ifndef LLDB_DISABLE_PYTHON
 }
 

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Tue Feb 28 21:28:49 2012
@@ -54,6 +54,62 @@
 static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = NULL;
 static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = NULL;
 
+// these are the Pythonic implementations of the required callbacks
+// these are scripting-language specific, which is why they belong here
+// we still need to use function pointers to them instead of relying
+// on linkage-time resolution because the SWIG stuff and this file
+// get built at different times
+extern "C" bool
+LLDBSwigPythonBreakpointCallbackFunction 
+(
+ const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::StackFrameSP& sb_frame, 
+ const lldb::BreakpointLocationSP& sb_bp_loc
+ );
+
+extern "C" bool
+LLDBSwigPythonCallTypeScript 
+(
+ const char *python_function_name,
+ void *session_dictionary,
+ const lldb::ValueObjectSP& valobj_sp,
+ void** pyfunct_wrapper,
+ std::string& retval
+ );
+
+extern "C" void*
+LLDBSwigPythonCreateSyntheticProvider 
+(
+ const std::string python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP& valobj_sp
+ );
+
+
+extern "C" uint32_t       LLDBSwigPython_CalculateNumChildren        (void *implementor);
+extern "C" void*          LLDBSwigPython_GetChildAtIndex             (void *implementor, uint32_t idx);
+extern "C" int            LLDBSwigPython_GetIndexOfChildWithName     (void *implementor, const char* child_name);
+extern "C" void*          LLDBSWIGPython_CastPyObjectToSBValue       (void* data);
+extern "C" void           LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
+
+extern "C" bool           LLDBSwigPythonCallCommand 
+(
+ const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger,
+ const char* args,
+ std::string& err_msg,
+ lldb_private::CommandReturnObject& cmd_retobj
+ );
+
+extern "C" bool           LLDBSwigPythonCallModuleInit 
+(
+ const std::string python_module_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger
+ );
+
 static int
 _check_and_flush (FILE *stream)
 {
@@ -226,7 +282,7 @@
     // WARNING: temporary code that loads Cocoa formatters - this should be done on a per-platform basis rather than loading the whole set
     // and letting the individual formatter classes exploit APIs to check whether they can/cannot do their task
     run_string.Clear();
-    run_string.Printf ("run_one_line (%s, 'import CFString, CFArray, CFDictionary, NSData, NSMachPort, NSSet, NSNotification, NSException, CFBag, CFBinaryHeap, NSURL, NSBundle, NSNumber')", m_dictionary_name.c_str());
+    run_string.Printf ("run_one_line (%s, 'import CFString, CFArray, CFDictionary, NSData, NSMachPort, NSSet, NSNotification, NSException, CFBag, CFBinaryHeap, NSURL, NSBundle, NSNumber, NSDate')", m_dictionary_name.c_str());
     PyRun_SimpleString (run_string.GetData());
 
     int new_count = Debugger::TestDebuggerRefCount();
@@ -1454,44 +1510,88 @@
     return true;
 }
 
-std::string
-ScriptInterpreterPython::CallPythonScriptFunction (const char *python_function_name,
-                                                   lldb::ValueObjectSP valobj)
+static PyObject*
+FindSessionDictionary(const char* dict_name)
 {
+    static std::map<ConstString,PyObject*> g_dict_map;
     
-    if (!python_function_name || !(*python_function_name))
-        return "<no function>";
+    ConstString dict(dict_name);
     
-    if (!valobj.get())
-        return "<no object>";
-        
-    ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
-    Target *target = exe_ctx.GetTargetPtr();
+    std::map<ConstString,PyObject*>::iterator iter = g_dict_map.find(dict);
     
-    if (!target)
-        return "<no target>";
+    if (iter != g_dict_map.end())
+        return iter->second;
     
-    Debugger &debugger = target->GetDebugger();
-    ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
-    ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
+    PyObject *main_mod = PyImport_AddModule ("__main__");
+    if (main_mod != NULL)
+    {
+        PyObject *main_dict = PyModule_GetDict (main_mod);
+        if ((main_dict != NULL)
+            && PyDict_Check (main_dict))
+        {
+            // Go through the main dictionary looking for the correct python script interpreter dictionary
+            PyObject *key, *value;
+            Py_ssize_t pos = 0;
+            
+            while (PyDict_Next (main_dict, &pos, &key, &value))
+            {
+                // We have stolen references to the key and value objects in the dictionary; we need to increment 
+                // them now so that Python's garbage collector doesn't collect them out from under us.
+                Py_INCREF (key);
+                Py_INCREF (value);
+                if (strcmp (PyString_AsString (key), dict_name) == 0)
+                {
+                    g_dict_map[dict] = value;
+                    return value;
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+bool
+ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name,
+                                             lldb::ValueObjectSP valobj,
+                                             lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
+                                             std::string& retval)
+{
     
-    if (!script_interpreter)
-        return "<no python>";
+    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
     
-    std::string ret_val;
+    if (!valobj.get())
+    {
+        retval.assign("<no object>");
+        return false;
+    }
+        
+    void* old_callee = (callee_wrapper_sp ? callee_wrapper_sp->GetObject() : NULL);
+    void* new_callee = old_callee;
     
+    bool ret_val;
     if (python_function_name 
         && *python_function_name)
     {
         {
-            Locker py_lock(python_interpreter);
-            ret_val = g_swig_typescript_callback (python_function_name, 
-                                                  python_interpreter->m_dictionary_name.c_str(),
-                                                  valobj);
+            Locker py_lock(this);
+            {
+            Timer scoped_timer ("g_swig_typescript_callback","g_swig_typescript_callback");
+            ret_val = g_swig_typescript_callback (python_function_name,
+                                                  FindSessionDictionary(m_dictionary_name.c_str()),
+                                                  valobj,
+                                                  &new_callee,
+                                                  retval);
+            }
         }
     }
     else
-        return "<no function name>";
+    {
+        retval.assign("<no function name>");
+        return false;
+    }
+    
+    if (new_callee && old_callee != new_callee)
+        callee_wrapper_sp = MakeScriptObject(new_callee);
     
     return ret_val;
     
@@ -1822,6 +1922,12 @@
     }
 }
 
+lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::MakeScriptObject (void* object)
+{
+    return lldb::ScriptInterpreterObjectSP(new ScriptInterpreterPythonObject(object));
+}
+
 ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler (lldb::DebuggerSP debugger_sp,
                                                                      ScriptedCommandSynchronicity synchro) :
     m_debugger_sp(debugger_sp),
@@ -1914,29 +2020,19 @@
 }
 
 void
-ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_init_callback,
-                                                SWIGBreakpointCallbackFunction python_swig_breakpoint_callback,
-                                                SWIGPythonTypeScriptCallbackFunction python_swig_typescript_callback,
-                                                SWIGPythonCreateSyntheticProvider python_swig_synthetic_script,
-                                                SWIGPythonCalculateNumChildren python_swig_calc_children,
-                                                SWIGPythonGetChildAtIndex python_swig_get_child_index,
-                                                SWIGPythonGetIndexOfChildWithName python_swig_get_index_child,
-                                                SWIGPythonCastPyObjectToSBValue python_swig_cast_to_sbvalue,
-                                                SWIGPythonUpdateSynthProviderInstance python_swig_update_provider,
-                                                SWIGPythonCallCommand python_swig_call_command,
-                                                SWIGPythonCallModuleInit python_swig_call_mod_init)
+ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_init_callback)
 {
     g_swig_init_callback = python_swig_init_callback;
-    g_swig_breakpoint_callback = python_swig_breakpoint_callback;
-    g_swig_typescript_callback = python_swig_typescript_callback;
-    g_swig_synthetic_script = python_swig_synthetic_script;
-    g_swig_calc_children = python_swig_calc_children;
-    g_swig_get_child_index = python_swig_get_child_index;
-    g_swig_get_index_child = python_swig_get_index_child;
-    g_swig_cast_to_sbvalue = python_swig_cast_to_sbvalue;
-    g_swig_update_provider = python_swig_update_provider;
-    g_swig_call_command = python_swig_call_command;
-    g_swig_call_module_init = python_swig_call_mod_init;
+    g_swig_breakpoint_callback = LLDBSwigPythonBreakpointCallbackFunction;
+    g_swig_typescript_callback = LLDBSwigPythonCallTypeScript;
+    g_swig_synthetic_script = LLDBSwigPythonCreateSyntheticProvider;
+    g_swig_calc_children = LLDBSwigPython_CalculateNumChildren;
+    g_swig_get_child_index = LLDBSwigPython_GetChildAtIndex;
+    g_swig_get_index_child = LLDBSwigPython_GetIndexOfChildWithName;
+    g_swig_cast_to_sbvalue = LLDBSWIGPython_CastPyObjectToSBValue;
+    g_swig_update_provider = LLDBSwigPython_UpdateSynthProviderInstance;
+    g_swig_call_command = LLDBSwigPythonCallCommand;
+    g_swig_call_module_init = LLDBSwigPythonCallModuleInit;
 }
 
 void

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py Tue Feb 28 21:28:49 2012
@@ -17,6 +17,7 @@
         self.buildDsym()
         self.plain_data_formatter_commands()
 
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     def test_plain_objc_with_dwarf_and_run_command(self):
         """Test basic ObjC formatting behavior."""
         self.buildDwarf()
@@ -28,6 +29,7 @@
         self.buildDsym()
         self.appkit_data_formatter_commands()
 
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     def test_appkit_with_dwarf_and_run_command(self):
         """Test formatters for AppKit classes."""
         self.buildDwarf()
@@ -39,11 +41,24 @@
         self.buildDsym()
         self.cf_data_formatter_commands()
 
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     def test_coreframeworks_with_dwarf_and_run_command(self):
         """Test formatters for Core OSX frameworks."""
         self.buildDwarf()
         self.cf_data_formatter_commands()
 
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_kvo_with_dsym_and_run_command(self):
+        """Test the behavior of formatters when KVO is in use."""
+        self.buildDsym()
+        self.kvo_data_formatter_commands()
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_kvo_with_dwarf_and_run_command(self):
+        """Test the behavior of formatters when KVO is in use."""
+        self.buildDwarf()
+        self.kvo_data_formatter_commands()
+
     def setUp(self):
         # Call super's setUp().
         TestBase.setUp(self)
@@ -153,7 +168,6 @@
             self.runCmd('type category disable CoreServices', check=False)
             self.runCmd('type category disable AppKit', check=False)
 
-
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
 
@@ -189,13 +203,13 @@
                     '(NSString *) str12 = ',' @"Process Name:  a.out Process Id:'])
 
         self.expect('frame variable newArray newDictionary newMutableDictionary cfdict_ref mutable_dict_ref cfarray_ref mutable_array_ref',
-                    substrs = ['(NSArray *) newArray = ',' size=50',
+                    substrs = ['(NSArray *) newArray = ',' 50 objects',
                     '(NSDictionary *) newDictionary = ',' 12 key/value pairs',
                     '(NSDictionary *) newMutableDictionary = ',' 21 key/value pairs',
                     '(CFDictionaryRef) cfdict_ref = ',' 3 key/value pairs',
                     '(CFMutableDictionaryRef) mutable_dict_ref = ',' 12 key/value pairs',
-                    '(CFArrayRef) cfarray_ref = ',' size=3',
-                    '(CFMutableArrayRef) mutable_array_ref = ',' size=11'])
+                    '(CFArrayRef) cfarray_ref = ',' 3 objects',
+                    '(CFMutableArrayRef) mutable_array_ref = ',' 11 objects'])
 
         self.expect('frame variable attrString mutableAttrString mutableGetConst',
                     substrs = ['(NSAttributedString *) attrString = ',' @"hello world from foo"',
@@ -278,6 +292,7 @@
             self.runCmd('type category disable CoreGraphics', check=False)
             self.runCmd('type category disable CoreServices', check=False)
             self.runCmd('type category disable AppKit', check=False)
+            self.runCmd('log timers disable', check=False)
 
 
         # Execute the cleanup function during test case tear down.
@@ -287,6 +302,8 @@
         self.runCmd('type category enable CoreFoundation')
         self.runCmd('type category enable CoreGraphics')
         self.runCmd('type category enable CoreServices')
+        self.runCmd("type category enable AppKit")
+        self.runCmd("log timers enable")
         self.expect("frame variable",
              substrs = ['(CFGregorianUnits) cf_greg_units = 1 years, 3 months, 5 days, 12 hours, 5 minutes 7 seconds',
              '(CFRange) cf_range = location=4 length=4',
@@ -307,8 +324,59 @@
              '(Point) point = (v=7, h=12)',
              '(Point *) point_ptr = (v=7, h=12)',
              '(HIPoint) hi_point = (x=7, y=12)',
-             '(HIRect) hi_rect = origin=(x=3, y=5) size=(width=4, height=6)'])
+             '(HIRect) hi_rect = origin=(x=3, y=5) size=(width=4, height=6)',
+             '@"TheGuyWhoHasNoName" @"cuz it\'s funny"'])
+        self.runCmd('log timers dump')
+
+
+    def kvo_data_formatter_commands(self):
+        """Test the behavior of formatters when KVO is in use."""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        self.expect("breakpoint set -f main.m -l %d" % self.line,
+                    BREAKPOINT_CREATED,
+            startstr = "Breakpoint created: 1: file ='main.m', line = %d, locations = 1" %
+                        self.line)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['stopped',
+                       'stop reason = breakpoint'])
+
+        # This is the function to remove the custom formats in order to have a
+        # clean slate for the next test case.
+        def cleanup():
+            self.runCmd('type format clear', check=False)
+            self.runCmd('type summary clear', check=False)
+            self.runCmd('type synth clear', check=False)
+            self.runCmd('type category disable CoreFoundation', check=False)
+            self.runCmd('type category disable CoreGraphics', check=False)
+            self.runCmd('type category disable CoreServices', check=False)
+            self.runCmd('type category disable AppKit', check=False)
+
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+
+        # check formatters for common Objective-C types
+        self.runCmd('type category enable AppKit')
+
+        # as long as KVO is implemented by subclassing, this test should succeed
+        # we should be able to dynamically figure out that the KVO implementor class
+        # is a subclass of Molecule, and use the appropriate summary for it
+        self.runCmd("type summary add -s JustAMoleculeHere Molecule")
+        self.expect('frame variable molecule', substrs = ['JustAMoleculeHere'])
+        self.runCmd("next")
+        self.expect("thread list",
+            substrs = ['stopped',
+                       'step over'])
+        self.expect('frame variable molecule', substrs = ['JustAMoleculeHere'])
 
+        self.runCmd("next")
+        # check that NSMutableDictionary's formatter is not confused when dealing with a KVO'd dictionary
+        self.expect('frame variable newMutableDictionary', substrs = ['(NSDictionary *) newMutableDictionary = ',' 21 key/value pairs'])
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m?rev=151703&r1=151702&r2=151703&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m Tue Feb 28 21:28:49 2012
@@ -66,6 +66,70 @@
 
 @end
 
+ at interface Atom : NSObject {
+    float mass;
+}
+-(void)setMass:(float)newMass;
+-(float)mass;
+ at end
+
+ at interface Molecule : NSObject {
+    NSArray *atoms;
+}
+-(void)setAtoms:(NSArray *)newAtoms;
+-(NSArray *)atoms;
+ at end
+
+ at implementation  Atom
+
+-(void)setMass:(float)newMass
+{
+    mass = newMass;
+}
+-(float)mass
+{
+    return mass;
+}
+
+ at end
+
+ at implementation Molecule
+
+-(void)setAtoms:(NSArray *)newAtoms
+{
+    atoms = newAtoms;
+}
+-(NSArray *)atoms
+{
+    return atoms;
+}
+ at end
+
+ at interface My_KVO_Observer : NSObject
+-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change 
+	context:(void *)context;
+- (id) init;
+- (void) dealloc;
+ at end
+
+ at implementation My_KVO_Observer
+-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change 
+                      context:(void *)context {
+	// we do not really care about KVO'ing - do nothing
+	return;
+}
+- (id) init
+{
+    self = [super init]; 
+    return self;
+}
+
+- (void) dealloc
+{
+    [super dealloc];
+}
+ at end
+
 int main (int argc, const char * argv[])
 {
     
@@ -479,7 +543,16 @@
 	HIPoint hi_point = {7,12};
 	HIRect hi_rect = {{3,5},{4,6}};
 
+	Molecule *molecule = [Molecule new];
+
     // Set break point at this line.
+
+    [molecule addObserver:[My_KVO_Observer new] forKeyPath:@"atoms" options:0 context:NULL];
+    [newMutableDictionary addObserver:[My_KVO_Observer new] forKeyPath:@"weirdKeyToKVO" options:NSKeyValueObservingOptionNew context:NULL];
+
+    [molecule setAtoms:nil];
+    [molecule setAtoms:[NSMutableArray new]];
+
     [pool drain];
     return 0;
 }





More information about the lldb-commits mailing list