mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-08 19:06:05 +00:00
276 lines
7.5 KiB
C++
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 ®ister_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 ®ister_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();
|
||
|
}
|