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: 26 Child(CompoundValueNode* parent, const BString& name) 27 : 28 fParent(parent), 29 fName(name) 30 { 31 } 32 33 virtual const BString& Name() const 34 { 35 return fName; 36 } 37 38 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: 54 BaseTypeChild(CompoundValueNode* parent, BaseType* baseType) 55 : 56 Child(parent, baseType->GetType()->Name()), 57 fBaseType(baseType) 58 { 59 fBaseType->AcquireReference(); 60 } 61 62 virtual ~BaseTypeChild() 63 { 64 fBaseType->ReleaseReference(); 65 } 66 67 virtual Type* GetType() const 68 { 69 return fBaseType->GetType(); 70 } 71 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: 104 MemberChild(CompoundValueNode* parent, DataMember* member) 105 : 106 Child(parent, member->Name()), 107 fMember(member) 108 { 109 fMember->AcquireReference(); 110 } 111 112 virtual ~MemberChild() 113 { 114 fMember->ReleaseReference(); 115 } 116 117 virtual Type* GetType() const 118 { 119 return fMember->GetType(); 120 } 121 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 152 CompoundValueNode::CompoundValueNode(ValueNodeChild* nodeChild, 153 CompoundType* type) 154 : 155 ValueNode(nodeChild), 156 fType(type) 157 { 158 fType->AcquireReference(); 159 } 160 161 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* 172 CompoundValueNode::GetType() const 173 { 174 return fType; 175 } 176 177 178 status_t 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 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 234 CompoundValueNode::CountChildren() const 235 { 236 return fChildren.CountItems(); 237 } 238 239 240 ValueNodeChild* 241 CompoundValueNode::ChildAt(int32 index) const 242 { 243 return fChildren.ItemAt(index); 244 } 245