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