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