[Lldb-commits] [lldb] r152970 - in /lldb/trunk/examples/synthetic/bitfield: ./ example.py program.cpp

Enrico Granata egranata at apple.com
Fri Mar 16 19:02:04 PDT 2012


Author: enrico
Date: Fri Mar 16 21:02:03 2012
New Revision: 152970

URL: http://llvm.org/viewvc/llvm-project?rev=152970&view=rev
Log:
Adding a new example of synthetic children provider

Added:
    lldb/trunk/examples/synthetic/bitfield/
    lldb/trunk/examples/synthetic/bitfield/example.py
    lldb/trunk/examples/synthetic/bitfield/program.cpp

Added: lldb/trunk/examples/synthetic/bitfield/example.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/bitfield/example.py?rev=152970&view=auto
==============================================================================
--- lldb/trunk/examples/synthetic/bitfield/example.py (added)
+++ lldb/trunk/examples/synthetic/bitfield/example.py Fri Mar 16 21:02:03 2012
@@ -0,0 +1,94 @@
+# Synthetic children provider example for class MaskedData
+# to use me:
+# command script import ./example.py --allow-reload
+# type synthetic add MaskedData --python-class example.MaskedData_SyntheticChildrenProvider
+class MaskedData_SyntheticChildrenProvider:
+	def __init__(self, valobj, dict):
+		self.valobj = valobj # remember the SBValue since you will not have another chance to get it :-)
+
+	def num_children(self):
+		# you could perform calculations involving the SBValue and/or its children to determine this value
+		# here, we have an hardcoded value - but since you have stored the SBValue you could use it to
+		# help figure out the correct thing to return here. if you return a number N, you should be prepared to
+		# answer questions about N children
+		return 4
+
+	def get_child_index(self,name): 
+		# given a name, return its index
+		# you can return None if you don't know the answer for a given name
+		if name == "value":
+			return 0
+		# here, we are using a reserved C++ keyword as a child name - we could not do that in the source code
+		# but we are free to use the names we like best in the synthetic children provider class
+		# we are also not respecting the order of declaration in the C++ class itself - as long as
+		# we are consistent, we can do that freely
+		if name == "operator":
+			return 1
+		if name == "mask":
+			return 2
+		# this member does not exist in the original class - we will compute its value and show it to the user
+		# when returning synthetic children, there is no need to only stick to what already exists in memory
+		if name == "apply()":
+			return 3
+		return None # no clue, just say none
+
+	def get_child_at_index(self,index):
+		# precautionary measures
+		if index < 0:
+			return None
+		if index > self.num_children():
+			return None
+		if self.valobj.IsValid() == False:
+			return None
+		if index == 0:
+			return self.valobj.GetChildMemberWithName("value")
+		if index == 1:
+			# fetch the value of the operator
+			op_chosen = self.valobj.GetChildMemberWithName("oper").GetValueAsUnsigned()
+			# if it is a known value, return a descriptive string for it
+			# we are not doing this in the most efficient possible way, but the code is very readable
+			# and easy to maintain - if you change the values on the C++ side, the same changes must be made here
+			if op_chosen == 0:
+				return self.valobj.CreateValueFromExpression("operator",'(const char*)"none"')
+			elif op_chosen == 1:
+				return self.valobj.CreateValueFromExpression("operator",'(const char*)"AND"')
+			elif op_chosen == 2:
+				return self.valobj.CreateValueFromExpression("operator",'(const char*)"OR"')
+			elif op_chosen == 3:
+				return self.valobj.CreateValueFromExpression("operator",'(const char*)"XOR"')
+			elif op_chosen == 4:
+				return self.valobj.CreateValueFromExpression("operator",'(const char*)"NAND"')
+			elif op_chosen == 5:
+				return self.valobj.CreateValueFromExpression("operator",'(const char*)"NOR"')
+			else:
+				return self.valobj.CreateValueFromExpression("operator",'(const char*)"unknown"') # something else
+		if index == 2:
+			return self.valobj.GetChildMemberWithName("mask")
+		if index == 3:
+			# for this, we must fetch all the other elements
+			# in an efficient implementation, we would be caching this data for efficiency
+			value = self.valobj.GetChildMemberWithName("value").GetValueAsUnsigned()
+			operator = self.valobj.GetChildMemberWithName("oper").GetValueAsUnsigned()
+			mask = self.valobj.GetChildMemberWithName("mask").GetValueAsUnsigned()
+			# compute the masked value according to the operator
+			if operator == 1:
+				value = value & mask
+			elif operator == 2:
+				value = value | mask
+			elif operator == 3:
+				value = value ^ mask
+			elif operator == 4:
+				value = ~(value & mask)
+			elif operator == 5:
+				value = ~(value | mask)
+			else:
+				pass
+			value &= 0xFFFFFFFF # make sure Python does not extend our values to 64-bits
+			# return it - again, not the most efficient possible way. we should actually be pushing the computed value
+			# into an SBData, and using the SBData to create an SBValue - this has the advantage of readability
+			return self.valobj.CreateValueFromExpression("apply()",'(uint32_t)(' + str(value) + ')')
+
+	def update(self):
+		# we do not do anything special in update - but this would be the right place to lookup
+		# the data we use in get_child_at_index and cache it
+		pass

Added: lldb/trunk/examples/synthetic/bitfield/program.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/bitfield/program.cpp?rev=152970&view=auto
==============================================================================
--- lldb/trunk/examples/synthetic/bitfield/program.cpp (added)
+++ lldb/trunk/examples/synthetic/bitfield/program.cpp Fri Mar 16 21:02:03 2012
@@ -0,0 +1,74 @@
+typedef unsigned int uint32_t;
+
+enum MaskingOperator
+{
+	eMaskingOperatorDefault = 0,
+	eMaskingOperatorAnd = 1,
+	eMaskingOperatorOr = 2,
+	eMaskingOperatorXor = 3,
+	eMaskingOperatorNand = 4,
+	eMaskingOperatorNor = 5
+};
+
+class MaskedData
+{
+private:
+	uint32_t value;
+	uint32_t mask;
+	MaskingOperator oper;
+public:
+	MaskedData( uint32_t V = 0,
+				uint32_t M = 0,
+				MaskingOperator P = eMaskingOperatorDefault) :
+		value(V),
+		mask(M),
+		oper(P)
+	{
+	}
+		
+	uint32_t apply()
+	{
+		switch(oper)
+		{
+			case eMaskingOperatorAnd:
+				return value & mask;
+			case eMaskingOperatorOr:
+				return value | mask;
+			case eMaskingOperatorXor:
+				return value ^ mask;
+			case eMaskingOperatorNand:
+				return ~(value & mask);
+			case eMaskingOperatorNor:
+				return ~(value | mask);
+			case eMaskingOperatorDefault: // fall through
+			default:
+				return value;
+		}
+	}
+	
+	void setValue(uint32_t V)
+	{
+		value = V;
+	}
+	
+	void setMask (uint32_t M)
+	{
+		mask = M;
+	}
+	
+	void setOperator(MaskingOperator P)
+	{
+		oper = P;
+	}	
+};
+
+int main()
+{
+	MaskedData data_1(0xFF0F,0xA01F,eMaskingOperatorAnd);
+	MaskedData data_2(data_1.apply(),0x1AFC,eMaskingOperatorXor);
+	MaskedData data_3(data_2.apply(),0xFFCF,eMaskingOperatorOr);
+	MaskedData data_4(data_3.apply(),0xAABC,eMaskingOperatorAnd);
+	MaskedData data_5(data_4.apply(),0xFFAC,eMaskingOperatorNor);
+	MaskedData data_6(data_5.apply(),0x0000BEEF,eMaskingOperatorAnd);
+	return data_6.apply(); // <-- what comes out of here?
+}
\ No newline at end of file





More information about the lldb-commits mailing list