blob: 8c91e5fd7c2cc1187f79fd6de02e0b0795b0c32a [file] [log] [blame]
//===-- RustLanguageRuntime.cpp ---------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "RustLanguageRuntime.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/RustASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "llvm/ADT/StringRef.h"
using namespace lldb;
using namespace lldb_private;
RustLanguageRuntime::RustLanguageRuntime(Process *process)
: LanguageRuntime(process)
{
}
LanguageRuntime *
RustLanguageRuntime::CreateInstance(Process *process,
lldb::LanguageType language) {
if (language == eLanguageTypeRust)
return new RustLanguageRuntime(process);
return nullptr;
}
void RustLanguageRuntime::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(), "Rust language runtime",
CreateInstance);
}
void RustLanguageRuntime::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
}
lldb_private::ConstString RustLanguageRuntime::GetPluginNameStatic() {
static ConstString g_name("rust");
return g_name;
}
lldb_private::ConstString RustLanguageRuntime::GetPluginName() {
return GetPluginNameStatic();
}
uint32_t RustLanguageRuntime::GetPluginVersion() {
return 1;
}
bool RustLanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
return in_value.GetCompilerType().IsPossibleDynamicType(nullptr, false, false);
}
bool RustLanguageRuntime::GetDynamicTypeAndAddress(
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &dynamic_address,
Value::ValueType &value_type) {
class_type_or_name.Clear();
value_type = Value::ValueType::eValueTypeScalar;
CompilerType type = in_value.GetCompilerType();
RustASTContext *ast = llvm::dyn_cast_or_null<RustASTContext>(type.GetTypeSystem());
if (!ast) {
return false;
}
uint64_t discr_offset, discr_byte_size;
if (ast->GetEnumDiscriminantLocation(type, discr_offset, discr_byte_size)) {
lldb::addr_t original_ptr = in_value.GetAddressOf(false); // FIXME?
if (original_ptr == LLDB_INVALID_ADDRESS) {
return false;
}
ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
Process *process = exe_ctx.GetProcessPtr();
if (process == nullptr) {
return false;
}
Status error;
uint64_t discriminant =
process->ReadUnsignedIntegerFromMemory(original_ptr + discr_offset, discr_byte_size,
0, error);
if (!error.Success()) {
return false;
}
CompilerType variant_type = ast->FindEnumVariant(type, discriminant);
if (!variant_type) {
return false;
}
class_type_or_name = TypeAndOrName(variant_type);
// The address doesn't change.
dynamic_address.SetLoadAddress(original_ptr, exe_ctx.GetTargetPtr());
value_type = Value::ValueType::eValueTypeLoadAddress;
return true;
}
return false;
}
TypeAndOrName
RustLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name,
ValueObject &static_value) {
return type_and_or_name;
}