diff options
Diffstat (limited to 'source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp')
-rw-r--r-- | source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp | 310 |
1 files changed, 142 insertions, 168 deletions
diff --git a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp index c752971e7a09..1450835298e6 100644 --- a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp +++ b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp @@ -1,4 +1,5 @@ -//===-- GoLanguageRuntime.cpp --------------------------------------*- C++ -*-===// +//===-- GoLanguageRuntime.cpp --------------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -36,206 +37,179 @@ using namespace lldb; using namespace lldb_private; namespace { -ValueObjectSP GetChild(ValueObject& obj, const char* name, bool dereference = true) { - ConstString name_const_str(name); - ValueObjectSP result = obj.GetChildMemberWithName(name_const_str, true); - if (dereference && result && result->IsPointerType()) { - Error err; - result = result->Dereference(err); - if (err.Fail()) - result.reset(); - } - return result; +ValueObjectSP GetChild(ValueObject &obj, const char *name, + bool dereference = true) { + ConstString name_const_str(name); + ValueObjectSP result = obj.GetChildMemberWithName(name_const_str, true); + if (dereference && result && result->IsPointerType()) { + Error err; + result = result->Dereference(err); + if (err.Fail()) + result.reset(); + } + return result; } -ConstString ReadString(ValueObject& str, Process* process) { - ConstString result; - ValueObjectSP data = GetChild(str, "str", false); - ValueObjectSP len = GetChild(str, "len"); - if (len && data) - { - Error err; - lldb::addr_t addr = data->GetPointerValue(); - if (addr == LLDB_INVALID_ADDRESS) - return result; - uint64_t byte_size = len->GetValueAsUnsigned(0); - char* buf = new char[byte_size + 1]; - buf[byte_size] = 0; - size_t bytes_read = process->ReadMemory (addr, - buf, - byte_size, - err); - if (!(err.Fail() || bytes_read != byte_size)) - result = ConstString(buf, bytes_read); - delete[] buf; - } - return result; +ConstString ReadString(ValueObject &str, Process *process) { + ConstString result; + ValueObjectSP data = GetChild(str, "str", false); + ValueObjectSP len = GetChild(str, "len"); + if (len && data) { + Error err; + lldb::addr_t addr = data->GetPointerValue(); + if (addr == LLDB_INVALID_ADDRESS) + return result; + uint64_t byte_size = len->GetValueAsUnsigned(0); + char *buf = new char[byte_size + 1]; + buf[byte_size] = 0; + size_t bytes_read = process->ReadMemory(addr, buf, byte_size, err); + if (!(err.Fail() || bytes_read != byte_size)) + result = ConstString(buf, bytes_read); + delete[] buf; + } + return result; } -ConstString -ReadTypeName(ValueObjectSP type, Process* process) -{ - if (ValueObjectSP uncommon = GetChild(*type, "x")) - { - ValueObjectSP name = GetChild(*uncommon, "name"); - ValueObjectSP package = GetChild(*uncommon, "pkgpath"); - if (name && name->GetPointerValue() != 0 && package && package->GetPointerValue() != 0) - { - ConstString package_const_str = ReadString(*package, process); - ConstString name_const_str = ReadString(*name, process); - if (package_const_str.GetLength() == 0) - return name_const_str; - return ConstString((package_const_str.GetStringRef() + "." + name_const_str.GetStringRef()).str()); - } +ConstString ReadTypeName(ValueObjectSP type, Process *process) { + if (ValueObjectSP uncommon = GetChild(*type, "x")) { + ValueObjectSP name = GetChild(*uncommon, "name"); + ValueObjectSP package = GetChild(*uncommon, "pkgpath"); + if (name && name->GetPointerValue() != 0 && package && + package->GetPointerValue() != 0) { + ConstString package_const_str = ReadString(*package, process); + ConstString name_const_str = ReadString(*name, process); + if (package_const_str.GetLength() == 0) + return name_const_str; + return ConstString((package_const_str.GetStringRef() + "." + + name_const_str.GetStringRef()) + .str()); } - ValueObjectSP name = GetChild(*type, "_string"); - if (name) - return ReadString(*name, process); - return ConstString(""); + } + ValueObjectSP name = GetChild(*type, "_string"); + if (name) + return ReadString(*name, process); + return ConstString(""); } -CompilerType -LookupRuntimeType(ValueObjectSP type, ExecutionContext* exe_ctx, bool* is_direct) -{ - uint8_t kind = GetChild(*type, "kind")->GetValueAsUnsigned(0); - *is_direct = GoASTContext::IsDirectIface(kind); - if (GoASTContext::IsPointerKind(kind)) - { - CompilerType type_ptr = type->GetCompilerType().GetPointerType(); - Error err; - ValueObjectSP elem = type->CreateValueObjectFromAddress("elem", type->GetAddressOf() + type->GetByteSize(), *exe_ctx, type_ptr)->Dereference(err); - if (err.Fail()) - return CompilerType(); - bool tmp_direct; - return LookupRuntimeType(elem, exe_ctx, &tmp_direct).GetPointerType(); - } - Target *target = exe_ctx->GetTargetPtr(); - Process *process = exe_ctx->GetProcessPtr(); - - ConstString const_typename = ReadTypeName(type, process); - if (const_typename.GetLength() == 0) - return CompilerType(); - - SymbolContext sc; - TypeList type_list; - llvm::DenseSet<SymbolFile *> searched_symbol_files; - uint32_t num_matches = target->GetImages().FindTypes (sc, - const_typename, - false, - 2, - searched_symbol_files, - type_list); - if (num_matches > 0) { - return type_list.GetTypeAtIndex(0)->GetFullCompilerType(); - } +CompilerType LookupRuntimeType(ValueObjectSP type, ExecutionContext *exe_ctx, + bool *is_direct) { + uint8_t kind = GetChild(*type, "kind")->GetValueAsUnsigned(0); + *is_direct = GoASTContext::IsDirectIface(kind); + if (GoASTContext::IsPointerKind(kind)) { + CompilerType type_ptr = type->GetCompilerType().GetPointerType(); + Error err; + ValueObjectSP elem = + type->CreateValueObjectFromAddress("elem", type->GetAddressOf() + + type->GetByteSize(), + *exe_ctx, type_ptr) + ->Dereference(err); + if (err.Fail()) + return CompilerType(); + bool tmp_direct; + return LookupRuntimeType(elem, exe_ctx, &tmp_direct).GetPointerType(); + } + Target *target = exe_ctx->GetTargetPtr(); + Process *process = exe_ctx->GetProcessPtr(); + + ConstString const_typename = ReadTypeName(type, process); + if (const_typename.GetLength() == 0) return CompilerType(); -} + SymbolContext sc; + TypeList type_list; + llvm::DenseSet<SymbolFile *> searched_symbol_files; + uint32_t num_matches = target->GetImages().FindTypes( + sc, const_typename, false, 2, searched_symbol_files, type_list); + if (num_matches > 0) { + return type_list.GetTypeAtIndex(0)->GetFullCompilerType(); + } + return CompilerType(); +} } -bool -GoLanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value) -{ - return GoASTContext::IsGoInterface(in_value.GetCompilerType()); +bool GoLanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) { + return GoASTContext::IsGoInterface(in_value.GetCompilerType()); } -bool -GoLanguageRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, - TypeAndOrName &class_type_or_name, Address &dynamic_address, - Value::ValueType &value_type) -{ - value_type = Value::eValueTypeScalar; - class_type_or_name.Clear(); - if (CouldHaveDynamicValue (in_value)) - { - Error err; - ValueObjectSP iface = in_value.GetStaticValue(); - ValueObjectSP data_sp = GetChild(*iface, "data", false); - if (!data_sp) - return false; - - if (ValueObjectSP tab = GetChild(*iface, "tab")) - iface = tab; - ValueObjectSP type = GetChild(*iface, "_type"); - if (!type) - { - return false; - } - - bool direct; - ExecutionContext exe_ctx (in_value.GetExecutionContextRef()); - CompilerType final_type = LookupRuntimeType(type, &exe_ctx, &direct); - if (!final_type) - return false; - if (direct) - { - class_type_or_name.SetCompilerType(final_type); - } - else - { - // TODO: implement reference types or fix caller to support dynamic types that aren't pointers - // so we don't have to introduce this extra pointer. - class_type_or_name.SetCompilerType(final_type.GetPointerType()); - } - - dynamic_address.SetLoadAddress(data_sp->GetPointerValue(), exe_ctx.GetTargetPtr()); - - return true; +bool GoLanguageRuntime::GetDynamicTypeAndAddress( + ValueObject &in_value, lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, Address &dynamic_address, + Value::ValueType &value_type) { + value_type = Value::eValueTypeScalar; + class_type_or_name.Clear(); + if (CouldHaveDynamicValue(in_value)) { + Error err; + ValueObjectSP iface = in_value.GetStaticValue(); + ValueObjectSP data_sp = GetChild(*iface, "data", false); + if (!data_sp) + return false; + + if (ValueObjectSP tab = GetChild(*iface, "tab")) + iface = tab; + ValueObjectSP type = GetChild(*iface, "_type"); + if (!type) { + return false; } - return false; + + bool direct; + ExecutionContext exe_ctx(in_value.GetExecutionContextRef()); + CompilerType final_type = LookupRuntimeType(type, &exe_ctx, &direct); + if (!final_type) + return false; + if (direct) { + class_type_or_name.SetCompilerType(final_type); + } else { + // TODO: implement reference types or fix caller to support dynamic types + // that aren't pointers + // so we don't have to introduce this extra pointer. + class_type_or_name.SetCompilerType(final_type.GetPointerType()); + } + + dynamic_address.SetLoadAddress(data_sp->GetPointerValue(), + exe_ctx.GetTargetPtr()); + + return true; + } + return false; } TypeAndOrName -GoLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value) -{ - return type_and_or_name; +GoLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, + ValueObject &static_value) { + return type_and_or_name; } //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ LanguageRuntime * -GoLanguageRuntime::CreateInstance (Process *process, lldb::LanguageType language) -{ - if (language == eLanguageTypeGo) - return new GoLanguageRuntime (process); - else - return NULL; +GoLanguageRuntime::CreateInstance(Process *process, + lldb::LanguageType language) { + if (language == eLanguageTypeGo) + return new GoLanguageRuntime(process); + else + return NULL; } -void -GoLanguageRuntime::Initialize() -{ - PluginManager::RegisterPlugin (GetPluginNameStatic(), - "Go Language Runtime", - CreateInstance); +void GoLanguageRuntime::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), "Go Language Runtime", + CreateInstance); } -void -GoLanguageRuntime::Terminate() -{ - PluginManager::UnregisterPlugin (CreateInstance); +void GoLanguageRuntime::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString -GoLanguageRuntime::GetPluginNameStatic() -{ - static ConstString g_name("golang"); - return g_name; +lldb_private::ConstString GoLanguageRuntime::GetPluginNameStatic() { + static ConstString g_name("golang"); + return g_name; } //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ -lldb_private::ConstString -GoLanguageRuntime::GetPluginName() -{ - return GetPluginNameStatic(); -} - -uint32_t -GoLanguageRuntime::GetPluginVersion() -{ - return 1; +lldb_private::ConstString GoLanguageRuntime::GetPluginName() { + return GetPluginNameStatic(); } +uint32_t GoLanguageRuntime::GetPluginVersion() { return 1; } |