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 24class CompoundValueNode::Child : public ValueNodeChild { 25public: 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 43protected: 44 CompoundValueNode* fParent; 45 BString fName; 46}; 47 48 49// #pragma mark - BaseTypeChild 50 51 52class CompoundValueNode::BaseTypeChild : public Child { 53public: 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 94private: 95 BaseType* fBaseType; 96}; 97 98 99// #pragma mark - MemberChild 100 101 102class CompoundValueNode::MemberChild : public Child { 103public: 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 144private: 145 DataMember* fMember; 146}; 147 148 149// #pragma mark - CompoundValueNode 150 151 152CompoundValueNode::CompoundValueNode(ValueNodeChild* nodeChild, 153 CompoundType* type) 154 : 155 ValueNode(nodeChild), 156 fType(type) 157{ 158 fType->AcquireReference(); 159} 160 161 162CompoundValueNode::~CompoundValueNode() 163{ 164 fType->ReleaseReference(); 165 166 for (int32 i = 0; Child* child = fChildren.ItemAt(i); i++) 167 child->ReleaseReference(); 168} 169 170 171Type* 172CompoundValueNode::GetType() const 173{ 174 return fType; 175} 176 177 178status_t 179CompoundValueNode::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 194status_t 195CompoundValueNode::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 233int32 234CompoundValueNode::CountChildren() const 235{ 236 return fChildren.CountItems(); 237} 238 239 240ValueNodeChild* 241CompoundValueNode::ChildAt(int32 index) const 242{ 243 return fChildren.ItemAt(index); 244} 245