/* * Copyright 2015, Rene Gollent, rene@gollent.com. * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #include "CompoundValueNode.h" #include #include "Architecture.h" #include "IntegerValue.h" #include "Tracing.h" #include "Type.h" #include "ValueLoader.h" #include "ValueLocation.h" #include "ValueNodeContainer.h" // #pragma mark - Child class CompoundValueNode::Child : public ValueNodeChild { public: Child(CompoundValueNode* parent, const BString& name) : fParent(parent), fName(name) { } virtual const BString& Name() const { return fName; } virtual ValueNode* Parent() const { return fParent; } protected: CompoundValueNode* fParent; BString fName; }; // #pragma mark - BaseTypeChild class CompoundValueNode::BaseTypeChild : public Child { public: BaseTypeChild(CompoundValueNode* parent, BaseType* baseType) : Child(parent, baseType->GetType()->Name()), fBaseType(baseType) { fBaseType->AcquireReference(); } virtual ~BaseTypeChild() { fBaseType->ReleaseReference(); } virtual Type* GetType() const { return fBaseType->GetType(); } virtual status_t ResolveLocation(ValueLoader* valueLoader, ValueLocation*& _location) { // The parent's location refers to the location of the complete // object. We want to extract the location of a member. ValueLocation* parentLocation = fParent->Location(); if (parentLocation == NULL) return B_BAD_VALUE; ValueLocation* location; status_t error = fParent->fType->ResolveBaseTypeLocation(fBaseType, *parentLocation, location); if (error != B_OK) { TRACE_LOCALS("CompoundValueNode::BaseTypeChild::ResolveLocation(): " "ResolveBaseTypeLocation() failed: %s\n", strerror(error)); return error; } _location = location; return B_OK; } private: BaseType* fBaseType; }; // #pragma mark - MemberChild class CompoundValueNode::MemberChild : public Child { public: MemberChild(CompoundValueNode* parent, DataMember* member) : Child(parent, member->Name()), fMember(member) { fMember->AcquireReference(); } virtual ~MemberChild() { fMember->ReleaseReference(); } virtual Type* GetType() const { return fMember->GetType(); } virtual status_t ResolveLocation(ValueLoader* valueLoader, ValueLocation*& _location) { // The parent's location refers to the location of the complete // object. We want to extract the location of a member. ValueLocation* parentLocation = fParent->Location(); if (parentLocation == NULL) return B_BAD_VALUE; ValueLocation* location; status_t error = fParent->fType->ResolveDataMemberLocation(fMember, *parentLocation, location); if (error != B_OK) { TRACE_LOCALS("CompoundValueNode::MemberChild::ResolveLocation(): " "ResolveDataMemberLocation() failed: %s\n", strerror(error)); return error; } _location = location; return B_OK; } private: DataMember* fMember; }; // #pragma mark - CompoundValueNode CompoundValueNode::CompoundValueNode(ValueNodeChild* nodeChild, CompoundType* type) : ValueNode(nodeChild), fType(type) { fType->AcquireReference(); } CompoundValueNode::~CompoundValueNode() { fType->ReleaseReference(); for (int32 i = 0; Child* child = fChildren.ItemAt(i); i++) child->ReleaseReference(); } Type* CompoundValueNode::GetType() const { return fType; } status_t CompoundValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader, ValueLocation*& _location, Value*& _value) { // get the location ValueLocation* location = NodeChild()->Location(); if (location == NULL) return B_BAD_VALUE; location->AcquireReference(); _location = location; _value = NULL; return B_OK; } status_t CompoundValueNode::CreateChildren(TeamTypeInformation* info) { if (!fChildren.IsEmpty()) return B_OK; // base types for (int32 i = 0; BaseType* baseType = fType->BaseTypeAt(i); i++) { TRACE_LOCALS(" base %" B_PRId32 "\n", i); BaseTypeChild* child = new(std::nothrow) BaseTypeChild(this, baseType); if (child == NULL || !fChildren.AddItem(child)) { delete child; return B_NO_MEMORY; } child->SetContainer(fContainer); } // members for (int32 i = 0; DataMember* member = fType->DataMemberAt(i); i++) { TRACE_LOCALS(" member %" B_PRId32 ": \"%s\"\n", i, member->Name()); MemberChild* child = new(std::nothrow) MemberChild(this, member); if (child == NULL || !fChildren.AddItem(child)) { delete child; return B_NO_MEMORY; } child->SetContainer(fContainer); } if (fContainer != NULL) fContainer->NotifyValueNodeChildrenCreated(this); return B_OK; } int32 CompoundValueNode::CountChildren() const { return fChildren.CountItems(); } ValueNodeChild* CompoundValueNode::ChildAt(int32 index) const { return fChildren.ItemAt(index); }