xref: /haiku/src/kits/debugger/value/value_nodes/CompoundValueNode.cpp (revision fce4895d1884da5ae6fb299d23c735c598e690b1)
1*fce4895dSRene Gollent /*
2*fce4895dSRene Gollent  * Copyright 2015, Rene Gollent, rene@gollent.com.
3*fce4895dSRene Gollent  * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
4*fce4895dSRene Gollent  * Distributed under the terms of the MIT License.
5*fce4895dSRene Gollent  */
6*fce4895dSRene Gollent 
7*fce4895dSRene Gollent 
8*fce4895dSRene Gollent #include "CompoundValueNode.h"
9*fce4895dSRene Gollent 
10*fce4895dSRene Gollent #include <new>
11*fce4895dSRene Gollent 
12*fce4895dSRene Gollent #include "Architecture.h"
13*fce4895dSRene Gollent #include "IntegerValue.h"
14*fce4895dSRene Gollent #include "Tracing.h"
15*fce4895dSRene Gollent #include "Type.h"
16*fce4895dSRene Gollent #include "ValueLoader.h"
17*fce4895dSRene Gollent #include "ValueLocation.h"
18*fce4895dSRene Gollent #include "ValueNodeContainer.h"
19*fce4895dSRene Gollent 
20*fce4895dSRene Gollent 
21*fce4895dSRene Gollent // #pragma mark - Child
22*fce4895dSRene Gollent 
23*fce4895dSRene Gollent 
24*fce4895dSRene Gollent class CompoundValueNode::Child : public ValueNodeChild {
25*fce4895dSRene Gollent public:
Child(CompoundValueNode * parent,const BString & name)26*fce4895dSRene Gollent 	Child(CompoundValueNode* parent, const BString& name)
27*fce4895dSRene Gollent 		:
28*fce4895dSRene Gollent 		fParent(parent),
29*fce4895dSRene Gollent 		fName(name)
30*fce4895dSRene Gollent 	{
31*fce4895dSRene Gollent 	}
32*fce4895dSRene Gollent 
Name() const33*fce4895dSRene Gollent 	virtual const BString& Name() const
34*fce4895dSRene Gollent 	{
35*fce4895dSRene Gollent 		return fName;
36*fce4895dSRene Gollent 	}
37*fce4895dSRene Gollent 
Parent() const38*fce4895dSRene Gollent 	virtual ValueNode* Parent() const
39*fce4895dSRene Gollent 	{
40*fce4895dSRene Gollent 		return fParent;
41*fce4895dSRene Gollent 	}
42*fce4895dSRene Gollent 
43*fce4895dSRene Gollent protected:
44*fce4895dSRene Gollent 	CompoundValueNode*	fParent;
45*fce4895dSRene Gollent 	BString				fName;
46*fce4895dSRene Gollent };
47*fce4895dSRene Gollent 
48*fce4895dSRene Gollent 
49*fce4895dSRene Gollent // #pragma mark - BaseTypeChild
50*fce4895dSRene Gollent 
51*fce4895dSRene Gollent 
52*fce4895dSRene Gollent class CompoundValueNode::BaseTypeChild : public Child {
53*fce4895dSRene Gollent public:
BaseTypeChild(CompoundValueNode * parent,BaseType * baseType)54*fce4895dSRene Gollent 	BaseTypeChild(CompoundValueNode* parent, BaseType* baseType)
55*fce4895dSRene Gollent 		:
56*fce4895dSRene Gollent 		Child(parent, baseType->GetType()->Name()),
57*fce4895dSRene Gollent 		fBaseType(baseType)
58*fce4895dSRene Gollent 	{
59*fce4895dSRene Gollent 		fBaseType->AcquireReference();
60*fce4895dSRene Gollent 	}
61*fce4895dSRene Gollent 
~BaseTypeChild()62*fce4895dSRene Gollent 	virtual ~BaseTypeChild()
63*fce4895dSRene Gollent 	{
64*fce4895dSRene Gollent 		fBaseType->ReleaseReference();
65*fce4895dSRene Gollent 	}
66*fce4895dSRene Gollent 
GetType() const67*fce4895dSRene Gollent 	virtual Type* GetType() const
68*fce4895dSRene Gollent 	{
69*fce4895dSRene Gollent 		return fBaseType->GetType();
70*fce4895dSRene Gollent 	}
71*fce4895dSRene Gollent 
ResolveLocation(ValueLoader * valueLoader,ValueLocation * & _location)72*fce4895dSRene Gollent 	virtual status_t ResolveLocation(ValueLoader* valueLoader,
73*fce4895dSRene Gollent 		ValueLocation*& _location)
74*fce4895dSRene Gollent 	{
75*fce4895dSRene Gollent 		// The parent's location refers to the location of the complete
76*fce4895dSRene Gollent 		// object. We want to extract the location of a member.
77*fce4895dSRene Gollent 		ValueLocation* parentLocation = fParent->Location();
78*fce4895dSRene Gollent 		if (parentLocation == NULL)
79*fce4895dSRene Gollent 			return B_BAD_VALUE;
80*fce4895dSRene Gollent 
81*fce4895dSRene Gollent 		ValueLocation* location;
82*fce4895dSRene Gollent 		status_t error = fParent->fType->ResolveBaseTypeLocation(fBaseType,
83*fce4895dSRene Gollent 			*parentLocation, location);
84*fce4895dSRene Gollent 		if (error != B_OK) {
85*fce4895dSRene Gollent 			TRACE_LOCALS("CompoundValueNode::BaseTypeChild::ResolveLocation(): "
86*fce4895dSRene Gollent 				"ResolveBaseTypeLocation() failed: %s\n", strerror(error));
87*fce4895dSRene Gollent 			return error;
88*fce4895dSRene Gollent 		}
89*fce4895dSRene Gollent 
90*fce4895dSRene Gollent 		_location = location;
91*fce4895dSRene Gollent 		return B_OK;
92*fce4895dSRene Gollent 	}
93*fce4895dSRene Gollent 
94*fce4895dSRene Gollent private:
95*fce4895dSRene Gollent 	BaseType*	fBaseType;
96*fce4895dSRene Gollent };
97*fce4895dSRene Gollent 
98*fce4895dSRene Gollent 
99*fce4895dSRene Gollent // #pragma mark - MemberChild
100*fce4895dSRene Gollent 
101*fce4895dSRene Gollent 
102*fce4895dSRene Gollent class CompoundValueNode::MemberChild : public Child {
103*fce4895dSRene Gollent public:
MemberChild(CompoundValueNode * parent,DataMember * member)104*fce4895dSRene Gollent 	MemberChild(CompoundValueNode* parent, DataMember* member)
105*fce4895dSRene Gollent 		:
106*fce4895dSRene Gollent 		Child(parent, member->Name()),
107*fce4895dSRene Gollent 		fMember(member)
108*fce4895dSRene Gollent 	{
109*fce4895dSRene Gollent 		fMember->AcquireReference();
110*fce4895dSRene Gollent 	}
111*fce4895dSRene Gollent 
~MemberChild()112*fce4895dSRene Gollent 	virtual ~MemberChild()
113*fce4895dSRene Gollent 	{
114*fce4895dSRene Gollent 		fMember->ReleaseReference();
115*fce4895dSRene Gollent 	}
116*fce4895dSRene Gollent 
GetType() const117*fce4895dSRene Gollent 	virtual Type* GetType() const
118*fce4895dSRene Gollent 	{
119*fce4895dSRene Gollent 		return fMember->GetType();
120*fce4895dSRene Gollent 	}
121*fce4895dSRene Gollent 
ResolveLocation(ValueLoader * valueLoader,ValueLocation * & _location)122*fce4895dSRene Gollent 	virtual status_t ResolveLocation(ValueLoader* valueLoader,
123*fce4895dSRene Gollent 		ValueLocation*& _location)
124*fce4895dSRene Gollent 	{
125*fce4895dSRene Gollent 		// The parent's location refers to the location of the complete
126*fce4895dSRene Gollent 		// object. We want to extract the location of a member.
127*fce4895dSRene Gollent 		ValueLocation* parentLocation = fParent->Location();
128*fce4895dSRene Gollent 		if (parentLocation == NULL)
129*fce4895dSRene Gollent 			return B_BAD_VALUE;
130*fce4895dSRene Gollent 
131*fce4895dSRene Gollent 		ValueLocation* location;
132*fce4895dSRene Gollent 		status_t error = fParent->fType->ResolveDataMemberLocation(fMember,
133*fce4895dSRene Gollent 			*parentLocation, location);
134*fce4895dSRene Gollent 		if (error != B_OK) {
135*fce4895dSRene Gollent 			TRACE_LOCALS("CompoundValueNode::MemberChild::ResolveLocation(): "
136*fce4895dSRene Gollent 				"ResolveDataMemberLocation() failed: %s\n", strerror(error));
137*fce4895dSRene Gollent 			return error;
138*fce4895dSRene Gollent 		}
139*fce4895dSRene Gollent 
140*fce4895dSRene Gollent 		_location = location;
141*fce4895dSRene Gollent 		return B_OK;
142*fce4895dSRene Gollent 	}
143*fce4895dSRene Gollent 
144*fce4895dSRene Gollent private:
145*fce4895dSRene Gollent 	DataMember*	fMember;
146*fce4895dSRene Gollent };
147*fce4895dSRene Gollent 
148*fce4895dSRene Gollent 
149*fce4895dSRene Gollent // #pragma mark - CompoundValueNode
150*fce4895dSRene Gollent 
151*fce4895dSRene Gollent 
CompoundValueNode(ValueNodeChild * nodeChild,CompoundType * type)152*fce4895dSRene Gollent CompoundValueNode::CompoundValueNode(ValueNodeChild* nodeChild,
153*fce4895dSRene Gollent 	CompoundType* type)
154*fce4895dSRene Gollent 	:
155*fce4895dSRene Gollent 	ValueNode(nodeChild),
156*fce4895dSRene Gollent 	fType(type)
157*fce4895dSRene Gollent {
158*fce4895dSRene Gollent 	fType->AcquireReference();
159*fce4895dSRene Gollent }
160*fce4895dSRene Gollent 
161*fce4895dSRene Gollent 
~CompoundValueNode()162*fce4895dSRene Gollent CompoundValueNode::~CompoundValueNode()
163*fce4895dSRene Gollent {
164*fce4895dSRene Gollent 	fType->ReleaseReference();
165*fce4895dSRene Gollent 
166*fce4895dSRene Gollent 	for (int32 i = 0; Child* child = fChildren.ItemAt(i); i++)
167*fce4895dSRene Gollent 		child->ReleaseReference();
168*fce4895dSRene Gollent }
169*fce4895dSRene Gollent 
170*fce4895dSRene Gollent 
171*fce4895dSRene Gollent Type*
GetType() const172*fce4895dSRene Gollent CompoundValueNode::GetType() const
173*fce4895dSRene Gollent {
174*fce4895dSRene Gollent 	return fType;
175*fce4895dSRene Gollent }
176*fce4895dSRene Gollent 
177*fce4895dSRene Gollent 
178*fce4895dSRene Gollent status_t
ResolvedLocationAndValue(ValueLoader * valueLoader,ValueLocation * & _location,Value * & _value)179*fce4895dSRene Gollent CompoundValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
180*fce4895dSRene Gollent 	ValueLocation*& _location, Value*& _value)
181*fce4895dSRene Gollent {
182*fce4895dSRene Gollent 	// get the location
183*fce4895dSRene Gollent 	ValueLocation* location = NodeChild()->Location();
184*fce4895dSRene Gollent 	if (location == NULL)
185*fce4895dSRene Gollent 		return B_BAD_VALUE;
186*fce4895dSRene Gollent 
187*fce4895dSRene Gollent 	location->AcquireReference();
188*fce4895dSRene Gollent 	_location = location;
189*fce4895dSRene Gollent 	_value = NULL;
190*fce4895dSRene Gollent 	return B_OK;
191*fce4895dSRene Gollent }
192*fce4895dSRene Gollent 
193*fce4895dSRene Gollent 
194*fce4895dSRene Gollent status_t
CreateChildren(TeamTypeInformation * info)195*fce4895dSRene Gollent CompoundValueNode::CreateChildren(TeamTypeInformation* info)
196*fce4895dSRene Gollent {
197*fce4895dSRene Gollent 	if (!fChildren.IsEmpty())
198*fce4895dSRene Gollent 		return B_OK;
199*fce4895dSRene Gollent 
200*fce4895dSRene Gollent 	// base types
201*fce4895dSRene Gollent 	for (int32 i = 0; BaseType* baseType = fType->BaseTypeAt(i); i++) {
202*fce4895dSRene Gollent 		TRACE_LOCALS("  base %" B_PRId32 "\n", i);
203*fce4895dSRene Gollent 
204*fce4895dSRene Gollent 		BaseTypeChild* child = new(std::nothrow) BaseTypeChild(this, baseType);
205*fce4895dSRene Gollent 		if (child == NULL || !fChildren.AddItem(child)) {
206*fce4895dSRene Gollent 			delete child;
207*fce4895dSRene Gollent 			return B_NO_MEMORY;
208*fce4895dSRene Gollent 		}
209*fce4895dSRene Gollent 
210*fce4895dSRene Gollent 		child->SetContainer(fContainer);
211*fce4895dSRene Gollent 	}
212*fce4895dSRene Gollent 
213*fce4895dSRene Gollent 	// members
214*fce4895dSRene Gollent 	for (int32 i = 0; DataMember* member = fType->DataMemberAt(i); i++) {
215*fce4895dSRene Gollent 		TRACE_LOCALS("  member %" B_PRId32 ": \"%s\"\n", i, member->Name());
216*fce4895dSRene Gollent 
217*fce4895dSRene Gollent 		MemberChild* child = new(std::nothrow) MemberChild(this, member);
218*fce4895dSRene Gollent 		if (child == NULL || !fChildren.AddItem(child)) {
219*fce4895dSRene Gollent 			delete child;
220*fce4895dSRene Gollent 			return B_NO_MEMORY;
221*fce4895dSRene Gollent 		}
222*fce4895dSRene Gollent 
223*fce4895dSRene Gollent 		child->SetContainer(fContainer);
224*fce4895dSRene Gollent 	}
225*fce4895dSRene Gollent 
226*fce4895dSRene Gollent 	if (fContainer != NULL)
227*fce4895dSRene Gollent 		fContainer->NotifyValueNodeChildrenCreated(this);
228*fce4895dSRene Gollent 
229*fce4895dSRene Gollent 	return B_OK;
230*fce4895dSRene Gollent }
231*fce4895dSRene Gollent 
232*fce4895dSRene Gollent 
233*fce4895dSRene Gollent int32
CountChildren() const234*fce4895dSRene Gollent CompoundValueNode::CountChildren() const
235*fce4895dSRene Gollent {
236*fce4895dSRene Gollent 	return fChildren.CountItems();
237*fce4895dSRene Gollent }
238*fce4895dSRene Gollent 
239*fce4895dSRene Gollent 
240*fce4895dSRene Gollent ValueNodeChild*
ChildAt(int32 index) const241*fce4895dSRene Gollent CompoundValueNode::ChildAt(int32 index) const
242*fce4895dSRene Gollent {
243*fce4895dSRene Gollent 	return fChildren.ItemAt(index);
244*fce4895dSRene Gollent }
245