haiku/src/apps/debugger/model/StackFrameValueInfos.cpp
Ingo Weinhold 6e72ebfce3 * More work on retrieving local variable values. Address and compound types can
now be inspected. Still work in progress -- bit fields and arrays don't work
  correctly yet nor does type lookup beyond the current compilation unit.
* Made most of the debugger output configurable via a config header. By default
  it's much less noisy now.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33217 a95241bf-73f2-0310-859d-f6bbb57e9c96
2009-09-21 04:39:40 +00:00

196 lines
3.3 KiB
C++

/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "StackFrameValueInfos.h"
#include <new>
#include "FunctionID.h"
#include "Type.h"
#include "TypeComponentPath.h"
#include "ValueLocation.h"
struct StackFrameValueInfos::Key {
ObjectID* variable;
TypeComponentPath* path;
Key(ObjectID* variable, TypeComponentPath* path)
:
variable(variable),
path(path)
{
}
uint32 HashValue() const
{
return variable->HashValue() ^ path->HashValue();
}
bool operator==(const Key& other) const
{
return *variable == *other.variable && *path == *other.path;
}
};
struct StackFrameValueInfos::InfoEntry : Key {
Type* type;
ValueLocation* location;
InfoEntry* next;
InfoEntry(ObjectID* variable, TypeComponentPath* path)
:
Key(variable, path),
type(NULL),
location(NULL)
{
variable->AcquireReference();
path->AcquireReference();
}
~InfoEntry()
{
SetInfo(NULL, NULL);
variable->ReleaseReference();
path->ReleaseReference();
}
void SetInfo(Type* type, ValueLocation* location)
{
if (type != NULL)
type->AcquireReference();
if (location != NULL)
location->AcquireReference();
if (this->type != NULL)
this->type->ReleaseReference();
if (this->location != NULL)
this->location->ReleaseReference();
this->type = type;
this->location = location;
}
};
struct StackFrameValueInfos::InfoEntryHashDefinition {
typedef Key KeyType;
typedef InfoEntry ValueType;
size_t HashKey(const Key& key) const
{
return key.HashValue();
}
size_t Hash(const InfoEntry* value) const
{
return value->HashValue();
}
bool Compare(const Key& key, const InfoEntry* value) const
{
return key == *value;
}
InfoEntry*& GetLink(InfoEntry* value) const
{
return value->next;
}
};
StackFrameValueInfos::StackFrameValueInfos()
:
fValues(NULL)
{
}
StackFrameValueInfos::~StackFrameValueInfos()
{
_Cleanup();
}
status_t
StackFrameValueInfos::Init()
{
fValues = new(std::nothrow) ValueTable;
if (fValues == NULL)
return B_NO_MEMORY;
return fValues->Init();
}
bool
StackFrameValueInfos::GetInfo(ObjectID* variable,
const TypeComponentPath* path, Type** _type,
ValueLocation** _location) const
{
InfoEntry* entry = fValues->Lookup(
Key(variable, (TypeComponentPath*)path));
if (entry == NULL)
return false;
if (_type != NULL) {
entry->type->AcquireReference();
*_type = entry->type;
}
if (_location != NULL) {
entry->location->AcquireReference();
*_location = entry->location;
}
return true;
}
bool
StackFrameValueInfos::HasInfo(ObjectID* variable,
const TypeComponentPath* path) const
{
return fValues->Lookup(Key(variable, (TypeComponentPath*)path)) != NULL;
}
status_t
StackFrameValueInfos::SetInfo(ObjectID* variable, TypeComponentPath* path,
Type* type, ValueLocation* location)
{
InfoEntry* entry = fValues->Lookup(Key(variable, path));
if (entry == NULL) {
entry = new(std::nothrow) InfoEntry(variable, path);
if (entry == NULL)
return B_NO_MEMORY;
fValues->Insert(entry);
}
entry->SetInfo(type, location);
return B_OK;
}
void
StackFrameValueInfos::_Cleanup()
{
if (fValues != NULL) {
InfoEntry* entry = fValues->Clear(true);
while (entry != NULL) {
InfoEntry* next = entry->next;
delete entry;
entry = next;
}
delete fValues;
fValues = NULL;
}
}