summaryrefslogtreecommitdiff
path: root/source/Plugins/Language/Go
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-12-30 11:55:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-12-30 11:55:28 +0000
commite81d9d49145e432d917eea3a70d2ae74dcad1d89 (patch)
tree9ed5e1a91f242e2cb5911577356e487a55c01b78 /source/Plugins/Language/Go
parent85d8ef8f1f0e0e063a8571944302be2d2026f823 (diff)
Notes
Diffstat (limited to 'source/Plugins/Language/Go')
-rw-r--r--source/Plugins/Language/Go/GoFormatterFunctions.cpp173
-rw-r--r--source/Plugins/Language/Go/GoFormatterFunctions.h43
-rw-r--r--source/Plugins/Language/Go/GoLanguage.cpp146
-rw-r--r--source/Plugins/Language/Go/GoLanguage.h66
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_