Files
llvm-project/lldb/source/Expression/Materializer.cpp
Sean Callanan 96d2730a7b Added a Materializer class that contains
information about each variable that needs to
be materialized for an expression to work.  The
next step is to migrate all materialization code
from ClangExpressionDeclMap to Materializer, and
to use it for variable materialization.

llvm-svn: 179245
2013-04-11 00:09:05 +00:00

276 lines
7.5 KiB
C++

//===-- Materializer.cpp ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/Expression/ClangExpressionVariable.h"
#include "lldb/Expression/Materializer.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/ExecutionContext.h"
using namespace lldb_private;
uint32_t
Materializer::AddStructMember (Entity &entity)
{
uint32_t size = entity.GetSize();
uint32_t alignment = entity.GetAlignment();
uint32_t ret;
if (!m_current_offset)
m_struct_alignment = alignment;
if (m_current_offset % alignment)
m_current_offset += (alignment - (m_current_offset % alignment));
ret = m_current_offset;
m_current_offset += size;
return ret;
}
void
Materializer::Entity::SetSizeAndAlignmentFromType (ClangASTType &type)
{
m_size = type.GetTypeByteSize();
uint32_t bit_alignment = type.GetTypeBitAlign();
if (bit_alignment % 8)
{
bit_alignment += 8;
bit_alignment &= ~((uint32_t)0x111u);
}
m_alignment = bit_alignment / 8;
}
class EntityPersistentVariable : public Materializer::Entity
{
public:
EntityPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp) :
Entity(),
m_persistent_variable_sp(persistent_variable_sp)
{
ClangASTType type(m_persistent_variable_sp->GetClangAST(),
m_persistent_variable_sp->GetClangType());
SetSizeAndAlignmentFromType(type);
}
virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
{
}
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
{
}
private:
lldb::ClangExpressionVariableSP m_persistent_variable_sp;
};
uint32_t
Materializer::AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err)
{
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
iter->reset (new EntityPersistentVariable (persistent_variable_sp));
uint32_t ret = AddStructMember(**iter);
(*iter)->SetOffset(ret);
return ret;
}
class EntityVariable : public Materializer::Entity
{
public:
EntityVariable (lldb::VariableSP &variable_sp) :
Entity(),
m_variable_sp(variable_sp)
{
Type *type = variable_sp->GetType();
assert(type);
if (type)
{
ClangASTType clang_type(type->GetClangAST(),
type->GetClangLayoutType());
SetSizeAndAlignmentFromType(clang_type);
}
}
virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
{
}
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
{
}
private:
lldb::VariableSP m_variable_sp;
};
uint32_t
Materializer::AddVariable (lldb::VariableSP &variable_sp, Error &err)
{
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
iter->reset (new EntityVariable (variable_sp));
uint32_t ret = AddStructMember(**iter);
(*iter)->SetOffset(ret);
return ret;
}
class EntityResultVariable : public Materializer::Entity
{
public:
EntityResultVariable (const ClangASTType &type) :
Entity(),
m_type(type)
{
SetSizeAndAlignmentFromType(m_type);
}
virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
{
}
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
{
}
private:
ClangASTType m_type;
};
uint32_t
Materializer::AddResultVariable (const ClangASTType &type, Error &err)
{
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
iter->reset (new EntityResultVariable (type));
uint32_t ret = AddStructMember(**iter);
(*iter)->SetOffset(ret);
return ret;
}
class EntitySymbol : public Materializer::Entity
{
public:
EntitySymbol (const Symbol &symbol) :
Entity(),
m_symbol(symbol)
{
// Hard-coding to maximum size of a symbol
m_size = 8;
m_alignment = 8;
}
virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
{
}
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
{
}
private:
Symbol m_symbol;
};
uint32_t
Materializer::AddSymbol (const Symbol &symbol_sp, Error &err)
{
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
iter->reset (new EntitySymbol (symbol_sp));
uint32_t ret = AddStructMember(**iter);
(*iter)->SetOffset(ret);
return ret;
}
class EntityRegister : public Materializer::Entity
{
public:
EntityRegister (const RegisterInfo &register_info) :
Entity(),
m_register_info(register_info)
{
// Hard-coding alignment conservatively
m_size = m_register_info.byte_size;
m_alignment = m_register_info.byte_size;
}
virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
{
}
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
{
}
private:
RegisterInfo m_register_info;
};
uint32_t
Materializer::AddRegister (const RegisterInfo &register_info, Error &err)
{
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
iter->reset (new EntityRegister (register_info));
uint32_t ret = AddStructMember(**iter);
(*iter)->SetOffset(ret);
return ret;
}
Materializer::Materializer () :
m_needs_dematerialize(Mutex::eMutexTypeNormal),
m_current_offset(0),
m_struct_alignment(8)
{
}
Materializer::Dematerializer
Materializer::Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVariableSP &result_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &error)
{
for (EntityUP &entity_up : m_entities)
{
entity_up->Materialize(frame_sp, map, process_address, error);
if (!error.Success())
return Dematerializer (*this, frame_sp, map, LLDB_INVALID_ADDRESS);
}
m_needs_dematerialize.Lock();
return Dematerializer (*this, frame_sp, map, process_address);
}
void
Materializer::Dematerializer::Dematerialize (Error &error)
{
lldb::StackFrameSP frame_sp = m_frame_wp.lock();
if (!frame_sp)
{
error.SetErrorToGenericError();
error.SetErrorString("Couldn't dematerialize: frame is gone");
}
else
{
for (EntityUP &entity_up : m_materializer.m_entities)
{
entity_up->Dematerialize (frame_sp, m_map, m_process_address, error);
if (!error.Success())
break;
}
}
m_materializer.m_needs_dematerialize.Unlock();
}