Logging for data formatters.

llvm-svn: 153878
diff --git a/lldb/examples/summaries/cocoa/objc_runtime.py b/lldb/examples/summaries/cocoa/objc_runtime.py
index 22052d5..33ba1d4 100644
--- a/lldb/examples/summaries/cocoa/objc_runtime.py
+++ b/lldb/examples/summaries/cocoa/objc_runtime.py
@@ -9,10 +9,12 @@
 import cache
 import attrib_fromdict
 import functools
+import Logger
 
 class Utilities:
 	@staticmethod
 	def read_ascii(process, pointer,max_len=128):
+		logger = Logger.Logger()
 		error = lldb.SBError()
 		content = None
 		try:
@@ -25,6 +27,7 @@
 
 	@staticmethod
 	def is_valid_pointer(pointer, pointer_size, allow_tagged=False, allow_NULL=False):
+		logger = Logger.Logger()
 		if pointer == None:
 			return False
 		if pointer == 0:
@@ -37,12 +40,14 @@
 	# so if any pointer has bits 47 thru 63 high we know that this is not a valid isa
 	@staticmethod
 	def is_allowed_pointer(pointer):
+		logger = Logger.Logger()
 		if pointer == None:
 			return False
 		return ((pointer & 0xFFFF800000000000) == 0)
 
 	@staticmethod
 	def read_child_of(valobj,offset,type):
+		logger = Logger.Logger()
 		child = valobj.CreateChildAtOffset("childUNK",offset,type)
 		if child == None or child.IsValid() == False:
 			return None;
@@ -50,6 +55,7 @@
 
 	@staticmethod
 	def is_valid_identifier(name):
+		logger = Logger.Logger()
 		if name is None:
 			return None
 		if len(name) == 0:
@@ -64,6 +70,7 @@
 
 	@staticmethod
 	def check_is_osx_lion(target):
+		logger = Logger.Logger()
 		# assume the only thing that has a Foundation.framework is a Mac
 		# assume anything < Lion does not even exist
 		mod = target.module['Foundation']
@@ -79,6 +86,7 @@
 	# returns a class_data and a wrapper (or None, if the runtime alone can't decide on a wrapper)
 	@staticmethod
 	def prepare_class_detection(valobj,statistics):
+		logger = Logger.Logger()
 		class_data = ObjCRuntime(valobj)
 		if class_data.is_valid() == False:
 			statistics.metric_hit('invalid_pointer',valobj)
@@ -100,6 +108,7 @@
 
 class RoT_Data:
 	def __init__(self,rot_pointer,params):
+		logger = Logger.Logger()
 		if (Utilities.is_valid_pointer(rot_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=False)):
 			self.sys_params = params
 			self.valobj = rot_pointer
@@ -111,10 +120,12 @@
 			self.namePointer = Utilities.read_child_of(self.valobj,offset,self.sys_params.types_cache.addr_ptr_type)
 			self.check_valid()
 		else:
+			logger >> "Marking as invalid - rot is invalid"
 			self.valid = False
 		if self.valid:
 			self.name = Utilities.read_ascii(self.valobj.GetTarget().GetProcess(),self.namePointer)
 			if not(Utilities.is_valid_identifier(self.name)):
+				logger >> "Marking as invalid - name is invalid"
 				self.valid = False
 
 	# perform sanity checks on the contents of this class_ro_t
@@ -126,6 +137,7 @@
 		#	pass
 
 	def __str__(self):
+		logger = Logger.Logger()
 		return \
 		 "instanceSize = " + hex(self.instance_size()) + "\n" + \
 		 "namePointer = " + hex(self.namePointer) + " --> " + self.name
@@ -134,6 +146,7 @@
 		return self.valid
 
 	def instance_size(self,align=False):
+		logger = Logger.Logger()
 		if self.is_valid() == False:
 			return None
 		if self.instanceSize == None:
@@ -149,6 +162,7 @@
 
 class RwT_Data:
 	def __init__(self,rwt_pointer,params):
+		logger = Logger.Logger()
 		if (Utilities.is_valid_pointer(rwt_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=False)):
 			self.sys_params = params
 			self.valobj = rwt_pointer
@@ -157,6 +171,7 @@
 			self.roPointer = Utilities.read_child_of(self.valobj,8,self.sys_params.types_cache.addr_ptr_type)
 			self.check_valid()
 		else:
+			logger >> "Marking as invalid - rwt is invald"
 			self.valid = False
 		if self.valid:
 			self.rot = self.valobj.CreateValueFromAddress("rot",self.roPointer,self.sys_params.types_cache.addr_ptr_type).AddressOf()
@@ -164,26 +179,32 @@
 
 	# perform sanity checks on the contents of this class_rw_t
 	def check_valid(self):
+		logger = Logger.Logger()
 		self.valid = True
 		if not(Utilities.is_valid_pointer(self.roPointer,self.sys_params.pointer_size,allow_tagged=False)):
+			logger >> "Marking as invalid - ropointer is invalid"
 			self.valid = False
 
 	def __str__(self):
+		logger = Logger.Logger()
 		return \
 		 "roPointer = " + hex(self.roPointer)
 
 	def is_valid(self):
+		logger = Logger.Logger()
 		if self.valid:
 			return self.data.is_valid()
 		return False
 
 class Class_Data_V2:
 	def __init__(self,isa_pointer,params):
+		logger = Logger.Logger()
 		if (isa_pointer != None) and (Utilities.is_valid_pointer(isa_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=False)):
 			self.sys_params = params
 			self.valobj = isa_pointer
 			self.check_valid()
 		else:
+			logger >> "Marking as invalid - isa is invalid or None"
 			self.valid = False
 		if self.valid:
 			self.rwt = self.valobj.CreateValueFromAddress("rwt",self.dataPointer,self.sys_params.types_cache.addr_ptr_type).AddressOf()
@@ -193,45 +214,56 @@
 	# this call tries to minimize the amount of data fetched- as soon as we have "proven"
 	# that we have an invalid object, we stop reading
 	def check_valid(self):
+		logger = Logger.Logger()
 		self.valid = True
 		
 		self.isaPointer = Utilities.read_child_of(self.valobj,0,self.sys_params.types_cache.addr_ptr_type)
 		if not(Utilities.is_valid_pointer(self.isaPointer,self.sys_params.pointer_size,allow_tagged=False)):
+			logger >> "Marking as invalid - isaPointer is invalid"
 			self.valid = False
 			return
 		if not(Utilities.is_allowed_pointer(self.isaPointer)):
+			logger >> "Marking as invalid - isaPointer is not allowed"
 			self.valid = False
 			return
 
 		self.cachePointer = Utilities.read_child_of(self.valobj,2*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
 		if not(Utilities.is_valid_pointer(self.cachePointer,self.sys_params.pointer_size,allow_tagged=False)):
+			logger >> "Marking as invalid - cachePointer is invalid"
 			self.valid = False
 			return
 		if not(Utilities.is_allowed_pointer(self.cachePointer)):
+			logger >> "Marking as invalid - cachePointer is not allowed"
 			self.valid = False
 			return
 
 		self.vtablePointer = Utilities.read_child_of(self.valobj,3*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
 		if not(Utilities.is_valid_pointer(self.vtablePointer,self.sys_params.pointer_size,allow_tagged=False)):
+			logger >> "Marking as invalid - vtablePointer is invalid"
 			self.valid = False
 			return
 		if not(Utilities.is_allowed_pointer(self.vtablePointer)):
+			logger >> "Marking as invalid - vtablePointer is not allowed"
 			self.valid = False
 			return
 
 		self.dataPointer = Utilities.read_child_of(self.valobj,4*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
 		if not(Utilities.is_valid_pointer(self.dataPointer,self.sys_params.pointer_size,allow_tagged=False)):
+			logger >> "Marking as invalid - dataPointer is invalid"
 			self.valid = False
 			return
 		if not(Utilities.is_allowed_pointer(self.dataPointer)):
+			logger >> "Marking as invalid - dataPointer is not allowed"
 			self.valid = False
 			return
 
 		self.superclassIsaPointer = Utilities.read_child_of(self.valobj,1*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
 		if not(Utilities.is_valid_pointer(self.superclassIsaPointer,self.sys_params.pointer_size,allow_tagged=False, allow_NULL=True)):
+			logger >> "Marking as invalid - superclassIsa is invalid"
 			self.valid = False
 			return
 		if not(Utilities.is_allowed_pointer(self.superclassIsaPointer)):
+			logger >> "Marking as invalid - superclassIsa is not allowed"
 			self.valid = False
 			return
 
@@ -240,6 +272,7 @@
 	# 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):
+		logger = Logger.Logger()
 		if self.is_valid():
 			if self.class_name().startswith("NSKVONotifying_"):
 				return True
@@ -250,10 +283,12 @@
 	# which is __NSCFType (the versions without __ also exists and we are matching to it
 	#                      just to be on the safe side)
 	def is_cftype(self):
+		logger = Logger.Logger()
 		if self.is_valid():
 			return self.class_name() == '__NSCFType' or self.class_name() == 'NSCFType'
 
 	def get_superclass(self):
+		logger = Logger.Logger()
 		if self.is_valid():
 			parent_isa_pointer = self.valobj.CreateChildAtOffset("parent_isa",
 				self.sys_params.pointer_size,
@@ -263,17 +298,20 @@
 			return None
 
 	def class_name(self):
+		logger = Logger.Logger()
 		if self.is_valid():
 			return self.data.data.name
 		else:
 			return None
 
 	def is_valid(self):
+		logger = Logger.Logger()
 		if self.valid:
 			return self.data.is_valid()
 		return False
 
 	def __str__(self):
+		logger = Logger.Logger()
 		return 'isaPointer = ' + hex(self.isaPointer) + "\n" + \
 		 "superclassIsaPointer = " + hex(self.superclassIsaPointer) + "\n" + \
 		 "cachePointer = " + hex(self.cachePointer) + "\n" + \
@@ -284,6 +322,7 @@
 		return False
 
 	def instance_size(self,align=False):
+		logger = Logger.Logger()
 		if self.is_valid() == False:
 			return None
 		return self.rwt.rot.instance_size(align)
@@ -291,29 +330,35 @@
 # runtime v1 is much less intricate than v2 and stores relevant information directly in the class_t object
 class Class_Data_V1:
 	def __init__(self,isa_pointer,params):
+		logger = Logger.Logger()
 		if (isa_pointer != None) and (Utilities.is_valid_pointer(isa_pointer.GetValueAsUnsigned(),params.pointer_size, allow_tagged=False)):
 			self.valid = True
 			self.sys_params = params
 			self.valobj = isa_pointer
 			self.check_valid()
 		else:
+			logger >> "Marking as invalid - isaPointer is invalid or None"
 			self.valid = False
 		if self.valid:
 			self.name = Utilities.read_ascii(self.valobj.GetTarget().GetProcess(),self.namePointer)
 			if not(Utilities.is_valid_identifier(self.name)):
+				logger >> "Marking as invalid - name is not valid"
 				self.valid = False
 
 	# perform sanity checks on the contents of this class_t
 	def check_valid(self):
+		logger = Logger.Logger()
 		self.valid = True
 
 		self.isaPointer = Utilities.read_child_of(self.valobj,0,self.sys_params.types_cache.addr_ptr_type)
 		if not(Utilities.is_valid_pointer(self.isaPointer,self.sys_params.pointer_size,allow_tagged=False)):
+			logger >> "Marking as invalid - isaPointer is invalid"
 			self.valid = False
 			return
 
 		self.superclassIsaPointer = Utilities.read_child_of(self.valobj,1*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
 		if not(Utilities.is_valid_pointer(self.superclassIsaPointer,self.sys_params.pointer_size,allow_tagged=False,allow_NULL=True)):
+			logger >> "Marking as invalid - superclassIsa is invalid"
 			self.valid = False
 			return
 
@@ -327,6 +372,7 @@
 	# 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):
+		logger = Logger.Logger()
 		if self.is_valid():
 			if self.class_name().startswith("NSKVONotifying_"):
 				return True
@@ -337,10 +383,12 @@
 	# which is __NSCFType (the versions without __ also exists and we are matching to it
 	#                      just to be on the safe side)
 	def is_cftype(self):
+		logger = Logger.Logger()
 		if self.is_valid():
 			return self.class_name() == '__NSCFType' or self.class_name() == 'NSCFType'
 
 	def get_superclass(self):
+		logger = Logger.Logger()
 		if self.is_valid():
 			parent_isa_pointer = self.valobj.CreateChildAtOffset("parent_isa",
 				self.sys_params.pointer_size,
@@ -350,6 +398,7 @@
 			return None
 
 	def class_name(self):
+		logger = Logger.Logger()
 		if self.is_valid():
 			return self.name
 		else:
@@ -359,6 +408,7 @@
 		return self.valid
 
 	def __str__(self):
+		logger = Logger.Logger()
 		return 'isaPointer = ' + hex(self.isaPointer) + "\n" + \
 		 "superclassIsaPointer = " + hex(self.superclassIsaPointer) + "\n" + \
 		 "namePointer = " + hex(self.namePointer) + " --> " + self.name + \
@@ -368,6 +418,7 @@
 		return False
 
 	def instance_size(self,align=False):
+		logger = Logger.Logger()
 		if self.is_valid() == False:
 			return None
 		if self.instanceSize == None:
@@ -397,6 +448,7 @@
 
 class TaggedClass_Data:
 	def __init__(self,pointer,params):
+		logger = Logger.Logger()
 		global TaggedClass_Values_Lion,TaggedClass_Values_NMOS
 		self.valid = True
 		self.name = None
@@ -410,11 +462,13 @@
 			if self.class_bits in TaggedClass_Values_Lion:
 				self.name = TaggedClass_Values_Lion[self.class_bits]
 			else:
+				logger >> "Marking as invalid - not a good tagged pointer for Lion"
 				self.valid = False
 		else:
 			if self.class_bits in TaggedClass_Values_NMOS:
 				self.name = TaggedClass_Values_NMOS[self.class_bits]
 			else:
+				logger >> "Marking as invalid - not a good tagged pointer for NMOS"
 				self.valid = False
 
 
@@ -422,6 +476,7 @@
 		return self.valid
 
 	def class_name(self):
+		logger = Logger.Logger()
 		if self.is_valid():
 			return self.name
 		else:
@@ -451,6 +506,7 @@
 
 	# it seems reasonable to say that a tagged pointer is the size of a pointer
 	def instance_size(self,align=False):
+		logger = Logger.Logger()
 		if self.is_valid() == False:
 			return None
 		return self.sys_params.pointer_size
@@ -508,10 +564,12 @@
 
 class SystemParameters:
 	def __init__(self,valobj):
+		logger = Logger.Logger()
 		self.adjust_for_architecture(valobj)
 		self.adjust_for_process(valobj)
 
 	def adjust_for_process(self, valobj):
+		logger = Logger.Logger()
 		global runtime_version
 		global os_version
 		global types_caches
@@ -570,7 +628,9 @@
 	# of a well-known section only present in v1
 	@staticmethod
 	def runtime_version(process):
+		logger = Logger.Logger()
 		if process.IsValid() == False:
+			logger >> "No process - bailing out"
 			return None
 		target = process.GetTarget()
 		num_modules = target.GetNumModules()
@@ -581,6 +641,7 @@
 				module_objc = module
 				break
 		if module_objc == None or module_objc.IsValid() == False:
+			logger >> "no libobjc - bailing out"
 			return None
 		num_sections = module.GetNumSections()
 		section_objc = None
@@ -590,16 +651,20 @@
 				section_objc = section
 				break
 		if section_objc != None and section_objc.IsValid():
+			logger >> "found __OBJC: v1"
 			return 1
+		logger >> "no __OBJC: v2"
 		return 2
 
 	@staticmethod
 	def runtime_from_isa(isa):
+		logger = Logger.Logger()
 		runtime = ObjCRuntime(isa)
 		runtime.isa = isa
 		return runtime
 
 	def __init__(self,valobj):
+		logger = Logger.Logger()
 		self.valobj = valobj
 		self.adjust_for_architecture()
 		self.sys_params = SystemParameters(self.valobj)
@@ -611,12 +676,14 @@
 
 # an ObjC pointer can either be tagged or must be aligned
 	def is_tagged(self):
+		logger = Logger.Logger()
 		if self.valobj is None:
 			return False
 		return (Utilities.is_valid_pointer(self.unsigned_value,self.sys_params.pointer_size, allow_tagged=True) and \
 		not(Utilities.is_valid_pointer(self.unsigned_value,self.sys_params.pointer_size, allow_tagged=False)))
 
 	def is_valid(self):
+		logger = Logger.Logger()
 		if self.valobj is None:
 			return False
 		if self.valobj.IsInScope() == False:
@@ -627,29 +694,41 @@
 		return self.unsigned_value == 0
 
 	def read_isa(self):
+		logger = Logger.Logger()
 		if self.isa_value != None:
+			logger >> "using cached isa"
 			return self.isa_value
 		isa_pointer = self.valobj.CreateChildAtOffset("cfisa",
 			0,
 			self.sys_params.types_cache.addr_ptr_type)
 		if isa_pointer == None or isa_pointer.IsValid() == False:
+			logger >> "invalid isa - bailing out"
 			return None;
 		if isa_pointer.GetValueAsUnsigned(1) == 1:
+			logger >> "invalid isa value - bailing out"
 			return None;
 		self.isa_value = isa_pointer
 		return isa_pointer
 
 	def read_class_data(self):
+		logger = Logger.Logger()
 		global isa_cache
 		if self.is_tagged():
 			# tagged pointers only exist in ObjC v2
 			if self.sys_params.runtime_version == 2:
+				logger >> "on v2 and tagged - maybe"
 				# 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.unsigned_value,self.sys_params)
-				return tentative_tagged if tentative_tagged.is_valid() else InvalidClass_Data()
+				if tentative_tagged.is_valid():
+					logger >> "truly tagged"
+					return tentative_tagged
+				else:
+					logger >> "not tagged - error"
+					return InvalidClass_Data()
 			else:
+				logger >> "on v1 and tagged - error"
 				return InvalidClass_Data()
 		if self.is_valid() == False:
 			return InvalidClass_Data()