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