diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
commit | e81d9d49145e432d917eea3a70d2ae74dcad1d89 (patch) | |
tree | 9ed5e1a91f242e2cb5911577356e487a55c01b78 /source/Plugins/Language/Go | |
parent | 85d8ef8f1f0e0e063a8571944302be2d2026f823 (diff) |
Notes
Diffstat (limited to 'source/Plugins/Language/Go')
-rw-r--r-- | source/Plugins/Language/Go/GoFormatterFunctions.cpp | 173 | ||||
-rw-r--r-- | source/Plugins/Language/Go/GoFormatterFunctions.h | 43 | ||||
-rw-r--r-- | source/Plugins/Language/Go/GoLanguage.cpp | 146 | ||||
-rw-r--r-- | source/Plugins/Language/Go/GoLanguage.h | 66 |
4 files changed, 428 insertions, 0 deletions
diff --git a/source/Plugins/Language/Go/GoFormatterFunctions.cpp b/source/Plugins/Language/Go/GoFormatterFunctions.cpp new file mode 100644 index 0000000000000..1d7cd76b97392 --- /dev/null +++ b/source/Plugins/Language/Go/GoFormatterFunctions.cpp @@ -0,0 +1,173 @@ +//===-- GoFormatterFunctions.cpp---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// C Includes +// C++ Includes +#include <map> + +// Other libraries and framework includes +// Project includes +#include "GoFormatterFunctions.h" +#include "lldb/DataFormatters/FormattersHelpers.h" +#include "lldb/DataFormatters/StringPrinter.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +namespace +{ +class GoSliceSyntheticFrontEnd : public SyntheticChildrenFrontEnd +{ + public: + GoSliceSyntheticFrontEnd(ValueObject &valobj) + : SyntheticChildrenFrontEnd(valobj) + { + Update(); + } + + ~GoSliceSyntheticFrontEnd() override = default; + + size_t + CalculateNumChildren() override + { + return m_len; + } + + lldb::ValueObjectSP + GetChildAtIndex(size_t idx) override + { + if (idx < m_len) + { + ValueObjectSP &cached = m_children[idx]; + if (!cached) + { + StreamString idx_name; + idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); + lldb::addr_t object_at_idx = m_base_data_address; + object_at_idx += idx * m_type.GetByteSize(nullptr); + cached = CreateValueObjectFromAddress(idx_name.GetData(), object_at_idx, + m_backend.GetExecutionContextRef(), m_type); + } + return cached; + } + return ValueObjectSP(); + } + + bool + Update() override + { + size_t old_count = m_len; + + ConstString array_const_str("array"); + ValueObjectSP array_sp = m_backend.GetChildMemberWithName(array_const_str, true); + if (!array_sp) + { + m_children.clear(); + return old_count == 0; + } + m_type = array_sp->GetCompilerType().GetPointeeType(); + m_base_data_address = array_sp->GetPointerValue(); + + ConstString len_const_str("len"); + ValueObjectSP len_sp = m_backend.GetChildMemberWithName(len_const_str, true); + if (len_sp) + { + m_len = len_sp->GetValueAsUnsigned(0); + m_children.clear(); + } + + return old_count == m_len; + } + + bool + MightHaveChildren() override + { + return true; + } + + size_t + GetIndexOfChildWithName(const ConstString &name) override + { + return ExtractIndexFromString(name.AsCString()); + } + + private: + CompilerType m_type; + lldb::addr_t m_base_data_address; + size_t m_len; + std::map<size_t, lldb::ValueObjectSP> m_children; +}; + +} // anonymous namespace + +bool +lldb_private::formatters::GoStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) +{ + ProcessSP process_sp = valobj.GetProcessSP(); + if (!process_sp) + return false; + + if (valobj.IsPointerType()) + { + Error err; + ValueObjectSP deref = valobj.Dereference(err); + if (!err.Success()) + return false; + return GoStringSummaryProvider(*deref, stream, opts); + } + + ConstString str_name("str"); + ConstString len_name("len"); + + ValueObjectSP data_sp = valobj.GetChildMemberWithName(str_name, true); + ValueObjectSP len_sp = valobj.GetChildMemberWithName(len_name, true); + if (!data_sp || !len_sp) + return false; + bool success; + lldb::addr_t valobj_addr = data_sp->GetValueAsUnsigned(0, &success); + + if (!success) + return false; + + uint64_t length = len_sp->GetValueAsUnsigned(0); + if (length == 0) + { + stream.Printf("\"\""); + return true; + } + + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); + options.SetLocation(valobj_addr); + options.SetProcessSP(process_sp); + options.SetStream(&stream); + options.SetSourceSize(length); + options.SetNeedsZeroTermination(false); + options.SetLanguage(eLanguageTypeGo); + + if (!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options)) + { + stream.Printf("Summary Unavailable"); + return true; + } + + return true; +} + +SyntheticChildrenFrontEnd * +lldb_private::formatters::GoSliceSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) +{ + if (!valobj_sp) + return nullptr; + + lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); + if (!process_sp) + return nullptr; + return new GoSliceSyntheticFrontEnd(*valobj_sp); +} diff --git a/source/Plugins/Language/Go/GoFormatterFunctions.h b/source/Plugins/Language/Go/GoFormatterFunctions.h new file mode 100644 index 0000000000000..ae1eda0f0c541 --- /dev/null +++ b/source/Plugins/Language/Go/GoFormatterFunctions.h @@ -0,0 +1,43 @@ +//===-- GoFormatterFunctions.h-----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_GoFormatterFunctions_h_ +#define liblldb_GoFormatterFunctions_h_ + +// C Includes +#include <stdint.h> +#include <time.h> + +// C++ Includes +// Other libraries and framework includes +#include "clang/AST/ASTContext.h" + +// Project includes +#include "lldb/lldb-forward.h" + +#include "lldb/Core/ConstString.h" +#include "lldb/DataFormatters/FormatClasses.h" +#include "lldb/DataFormatters/TypeSynthetic.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ObjCLanguageRuntime.h" +#include "lldb/Target/Target.h" + +namespace lldb_private +{ +namespace formatters +{ + +bool GoStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); + +SyntheticChildrenFrontEnd *GoSliceSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); + +} // namespace formatters +} // namespace lldb_private + +#endif // liblldb_GoFormatterFunctions_h_ diff --git a/source/Plugins/Language/Go/GoLanguage.cpp b/source/Plugins/Language/Go/GoLanguage.cpp new file mode 100644 index 0000000000000..ed010ffa4b2e0 --- /dev/null +++ b/source/Plugins/Language/Go/GoLanguage.cpp @@ -0,0 +1,146 @@ +//===-- GoLanguage.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// C Includes +#include <string.h> +// C++ Includes +#include <functional> +#include <mutex> + +// Other libraries and framework includes +#include "llvm/ADT/StringRef.h" + +// Project includes +#include "GoLanguage.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/DataFormatters/FormattersHelpers.h" +#include "lldb/Symbol/GoASTContext.h" +#include "Plugins/Language/Go/GoFormatterFunctions.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +void +GoLanguage::Initialize() +{ + PluginManager::RegisterPlugin(GetPluginNameStatic(), "Go Language", CreateInstance); +} + +void +GoLanguage::Terminate() +{ + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString +GoLanguage::GetPluginNameStatic() +{ + static ConstString g_name("Go"); + return g_name; +} + +//------------------------------------------------------------------ +// PluginInterface protocol +//------------------------------------------------------------------ +lldb_private::ConstString +GoLanguage::GetPluginName() +{ + return GetPluginNameStatic(); +} + +uint32_t +GoLanguage::GetPluginVersion() +{ + return 1; +} + +//------------------------------------------------------------------ +// Static Functions +//------------------------------------------------------------------ +Language * +GoLanguage::CreateInstance(lldb::LanguageType language) +{ + if (language == eLanguageTypeGo) + return new GoLanguage(); + return nullptr; +} + +HardcodedFormatters::HardcodedSummaryFinder +GoLanguage::GetHardcodedSummaries() +{ + static std::once_flag g_initialize; + static HardcodedFormatters::HardcodedSummaryFinder g_formatters; + + std::call_once(g_initialize, []() -> void + { + g_formatters.push_back( + [](lldb_private::ValueObject &valobj, lldb::DynamicValueType, + FormatManager &) -> TypeSummaryImpl::SharedPointer + { + static CXXFunctionSummaryFormat::SharedPointer formatter_sp(new CXXFunctionSummaryFormat( + TypeSummaryImpl::Flags().SetDontShowChildren(true), + lldb_private::formatters::GoStringSummaryProvider, "Go string summary provider")); + if (GoASTContext::IsGoString(valobj.GetCompilerType())) + { + return formatter_sp; + } + if (GoASTContext::IsGoString(valobj.GetCompilerType().GetPointeeType())) + { + return formatter_sp; + } + return nullptr; + }); + g_formatters.push_back( + [](lldb_private::ValueObject &valobj, lldb::DynamicValueType, + FormatManager &) -> TypeSummaryImpl::SharedPointer + { + static lldb::TypeSummaryImplSP formatter_sp( + new StringSummaryFormat(TypeSummaryImpl::Flags().SetHideItemNames(true), + "(len ${var.len}, cap ${var.cap})")); + if (GoASTContext::IsGoSlice(valobj.GetCompilerType())) + { + return formatter_sp; + } + if (GoASTContext::IsGoSlice(valobj.GetCompilerType().GetPointeeType())) + { + return formatter_sp; + } + return nullptr; + }); + }); + return g_formatters; +} + +HardcodedFormatters::HardcodedSyntheticFinder +GoLanguage::GetHardcodedSynthetics() +{ + static std::once_flag g_initialize; + static HardcodedFormatters::HardcodedSyntheticFinder g_formatters; + + std::call_once(g_initialize, []() -> void + { + g_formatters.push_back( + [](lldb_private::ValueObject &valobj, lldb::DynamicValueType, + FormatManager &fmt_mgr) -> SyntheticChildren::SharedPointer + { + static CXXSyntheticChildren::SharedPointer formatter_sp( + new CXXSyntheticChildren(SyntheticChildren::Flags(), "slice synthetic children", + lldb_private::formatters::GoSliceSyntheticFrontEndCreator)); + if (GoASTContext::IsGoSlice(valobj.GetCompilerType())) + { + return formatter_sp; + } + return nullptr; + }); + }); + + return g_formatters; +} diff --git a/source/Plugins/Language/Go/GoLanguage.h b/source/Plugins/Language/Go/GoLanguage.h new file mode 100644 index 0000000000000..67dd04c2a22ee --- /dev/null +++ b/source/Plugins/Language/Go/GoLanguage.h @@ -0,0 +1,66 @@ +//===-- GoLanguage.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_GoLanguage_h_ +#define liblldb_GoLanguage_h_ + +// C Includes +// C++ Includes +#include <vector> + +// Other libraries and framework includes +#include "llvm/ADT/StringRef.h" + +// Project includes +#include "lldb/lldb-private.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Target/Language.h" + +namespace lldb_private +{ + +class GoLanguage : public Language +{ + public: + GoLanguage() = default; + + ~GoLanguage() override = default; + + lldb::LanguageType + GetLanguageType() const override + { + return lldb::eLanguageTypeGo; + } + + HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries() override; + + HardcodedFormatters::HardcodedSyntheticFinder GetHardcodedSynthetics() override; + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void Initialize(); + + static void Terminate(); + + static lldb_private::Language *CreateInstance(lldb::LanguageType language); + + static lldb_private::ConstString GetPluginNameStatic(); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; +}; + +} // namespace lldb_private + +#endif // liblldb_GoLanguage_h_ |