[Lldb-commits] [lldb] r277443 - Support for OCaml native debugging

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Tue Aug 2 04:15:56 PDT 2016


Author: tberghammer
Date: Tue Aug  2 06:15:55 2016
New Revision: 277443

URL: http://llvm.org/viewvc/llvm-project?rev=277443&view=rev
Log:
Support for OCaml native debugging

This introduces basic support for debugging OCaml binaries.
Use of the native compiler with DWARF emission support (see
https://github.com/ocaml/ocaml/pull/574) is required.

Available variables are considered as 64 bits unsigned integers,
their interpretation will be left to a OCaml-made debugging layer.

Differential revision: https://reviews.llvm.org/D22132

Added:
    lldb/trunk/include/lldb/Symbol/OCamlASTContext.h
    lldb/trunk/source/Plugins/Language/OCaml/
    lldb/trunk/source/Plugins/Language/OCaml/CMakeLists.txt
    lldb/trunk/source/Plugins/Language/OCaml/OCamlLanguage.cpp
    lldb/trunk/source/Plugins/Language/OCaml/OCamlLanguage.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
    lldb/trunk/source/Symbol/OCamlASTContext.cpp
Modified:
    lldb/trunk/cmake/LLDBDependencies.cmake
    lldb/trunk/include/lldb/Symbol/TypeSystem.h
    lldb/trunk/source/API/SystemInitializerFull.cpp
    lldb/trunk/source/Plugins/Language/CMakeLists.txt
    lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/trunk/source/Symbol/CMakeLists.txt

Modified: lldb/trunk/cmake/LLDBDependencies.cmake
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/cmake/LLDBDependencies.cmake?rev=277443&r1=277442&r2=277443&view=diff
==============================================================================
--- lldb/trunk/cmake/LLDBDependencies.cmake (original)
+++ lldb/trunk/cmake/LLDBDependencies.cmake Tue Aug  2 06:15:55 2016
@@ -27,6 +27,7 @@ set( LLDB_USED_LIBS
   lldbPluginJavaLanguage
   lldbPluginObjCLanguage
   lldbPluginObjCPlusPlusLanguage
+  lldbPluginOCamlLanguage
 
   lldbPluginObjectFileELF
   lldbPluginObjectFileJIT

Added: lldb/trunk/include/lldb/Symbol/OCamlASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/OCamlASTContext.h?rev=277443&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Symbol/OCamlASTContext.h (added)
+++ lldb/trunk/include/lldb/Symbol/OCamlASTContext.h Tue Aug  2 06:15:55 2016
@@ -0,0 +1,355 @@
+//===-- OCamlASTContext.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_OCamlASTContext_h_
+#define liblldb_OCamlASTContext_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/Symbol/TypeSystem.h"
+#include "lldb/Symbol/CompilerType.h"
+
+namespace lldb_private
+{
+
+class OCamlASTContext : public TypeSystem
+{
+  public:
+    class OCamlType;
+    typedef std::map<ConstString, std::unique_ptr<OCamlType>> OCamlTypeMap;
+
+    OCamlASTContext();
+    ~OCamlASTContext() override;
+
+    ConstString
+    GetPluginName() override;
+
+    uint32_t
+    GetPluginVersion() override;
+
+    static ConstString
+    GetPluginNameStatic ();
+
+    static lldb::TypeSystemSP
+    CreateInstance (lldb::LanguageType language, Module *module, Target *target);
+
+    static void
+    EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types,
+                                std::set<lldb::LanguageType> &languages_for_expressions);
+
+    static void
+    Initialize ();
+
+    static void
+    Terminate ();
+
+    DWARFASTParser *GetDWARFParser() override;
+
+    void
+    SetAddressByteSize(int byte_size)
+    {
+        m_pointer_byte_size = byte_size;
+    }
+
+    static bool classof(const TypeSystem *ts)
+    {
+        return ts->getKind() == TypeSystem::eKindOCaml;
+    }
+
+    ConstString
+    DeclGetName (void *opaque_decl) override
+    {
+        return ConstString();
+    }
+
+    bool
+    DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override
+    {
+        return false;
+    }
+
+    ConstString
+    DeclContextGetName(void *opaque_decl_ctx) override
+    {
+        return ConstString();
+    }
+
+    ConstString
+    DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override
+    {
+        return ConstString();
+    }
+
+    bool
+    DeclContextIsClassMethod(void *opaque_decl_ctx, lldb::LanguageType *language_ptr,
+                             bool *is_instance_method_ptr,
+                             ConstString *language_object_name_ptr) override
+    {
+        return false;
+    }
+
+    bool SupportsLanguage (lldb::LanguageType language) override;
+    uint32_t GetPointerByteSize() override;
+
+    bool
+    IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type, 
+                uint64_t *size, bool *is_incomplete) override;
+
+    bool IsAggregateType(lldb::opaque_compiler_type_t type) override;
+
+    bool IsCharType(lldb::opaque_compiler_type_t type) override;
+
+    bool IsCompleteType(lldb::opaque_compiler_type_t type) override;
+
+    bool IsDefined(lldb::opaque_compiler_type_t type) override;
+
+    bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) override;
+
+    bool IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr = nullptr) override;
+
+    size_t GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override;
+
+    CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index) override;
+
+    bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override;
+
+    bool IsBlockPointerType (lldb::opaque_compiler_type_t type, 
+                             CompilerType *function_pointer_type_ptr) override;
+
+    bool 
+    IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed) override;
+
+    bool
+    IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
+                               CompilerType *target_type,
+                               bool check_cplusplus, bool check_objc) override;
+
+    bool IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr) override;
+
+    bool IsScalarType(lldb::opaque_compiler_type_t type) override;
+
+    bool IsVoidType(lldb::opaque_compiler_type_t type) override;
+
+    bool GetCompleteType(lldb::opaque_compiler_type_t type) override;
+
+    ConstString GetTypeName(lldb::opaque_compiler_type_t type) override;
+
+    uint32_t
+    GetTypeInfo(lldb::opaque_compiler_type_t type,
+                CompilerType *pointee_or_element_compiler_type = nullptr) override;
+
+    lldb::LanguageType GetMinimumLanguage(lldb::opaque_compiler_type_t type) override;
+
+    lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override;
+
+    CompilerType
+    GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride = nullptr) override;
+
+    CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override;
+
+    int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override;
+
+    CompilerType
+    GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override;
+
+    CompilerType
+    GetFunctionReturnType(lldb::opaque_compiler_type_t type) override;
+
+    size_t
+    GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override;
+
+    TypeMemberFunctionImpl
+    GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override;
+
+    CompilerType
+    GetPointeeType(lldb::opaque_compiler_type_t type) override;
+
+    CompilerType
+    GetPointerType(lldb::opaque_compiler_type_t type) override;
+
+    uint64_t
+    GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) override;
+
+    lldb::Encoding
+    GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count) override;
+
+    lldb::Format
+    GetFormat(lldb::opaque_compiler_type_t type) override;
+
+    uint32_t
+    GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes) override;
+
+    lldb::BasicType
+    GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override;
+
+    CompilerType
+    GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size) override;
+
+    uint32_t
+    GetNumFields(lldb::opaque_compiler_type_t type) override;
+
+    CompilerType
+    GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, std::string &name, uint64_t *bit_offset_ptr, 
+                    uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) override;
+
+    uint32_t
+    GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override
+    {
+        return 0;
+    }
+
+    uint32_t
+    GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override
+    {
+        return 0;
+    }
+
+    CompilerType
+    GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override
+    {
+        return CompilerType();
+    }
+
+    CompilerType
+    GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override
+    {
+        return CompilerType();
+    }
+
+    CompilerType 
+    GetChildCompilerTypeAtIndex(lldb::opaque_compiler_type_t type,
+                                ExecutionContext *exe_ctx, size_t idx,
+                                bool transparent_pointers, bool omit_empty_base_classes,
+                                bool ignore_array_bounds, std::string &child_name,
+                                uint32_t &child_byte_size, int32_t &child_byte_offset,
+                                uint32_t &child_bitfield_bit_size,
+                                uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
+                                bool &child_is_deref_of_parent, ValueObject *valobj,
+                                uint64_t &language_flags) override;
+
+    uint32_t 
+    GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes) override;
+
+    size_t
+    GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
+                                  const char *name, bool omit_empty_base_classes,
+                                  std::vector<uint32_t> &child_indexes) override;
+
+    size_t
+    GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override
+    {
+        return 0;
+    }
+
+    CompilerType
+    GetTemplateArgument(lldb::opaque_compiler_type_t type,
+                        size_t idx, lldb::TemplateArgumentKind &kind) override
+    {
+        return CompilerType();
+    }
+
+    void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
+                   Stream *s, lldb::Format format, const DataExtractor &data, 
+                   lldb::offset_t data_offset, size_t data_byte_size,
+                   uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
+                   bool show_types, bool show_summary,
+                   bool verbose, uint32_t depth) override;
+
+    bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s,
+                       lldb::Format format, const DataExtractor &data,
+                       lldb::offset_t data_offset, size_t data_byte_size,
+                       uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
+                       ExecutionContextScope *exe_scope) override;
+
+    void
+    DumpTypeDescription(lldb::opaque_compiler_type_t type) override;
+
+    void
+    DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s) override;
+
+    bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override;
+
+    void 
+    DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
+                Stream *s, const DataExtractor &data,
+                lldb::offset_t data_offset, size_t data_byte_size) override;
+
+    size_t 
+    ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s,
+                              uint8_t *dst, size_t dst_size) override;
+
+    bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type,
+                                  CompilerType *pointee_type = nullptr) override;
+
+    unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override;
+
+    bool IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length) override;
+
+    size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override;
+
+    CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override;
+
+    bool IsBeingDefined(lldb::opaque_compiler_type_t type) override;
+
+    bool IsConst(lldb::opaque_compiler_type_t type) override;
+
+    uint32_t
+    IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr) override;
+
+    bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override;
+
+    bool IsTypedefType(lldb::opaque_compiler_type_t type) override;
+
+    CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override;
+
+    bool
+    IsVectorType(lldb::opaque_compiler_type_t type, CompilerType *element_type, 
+                 uint64_t *size) override;
+
+    CompilerType GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override;
+
+    CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override;
+
+    bool
+    IsReferenceType(lldb::opaque_compiler_type_t type, 
+                    CompilerType *pointee_type = nullptr, 
+                    bool *is_rvalue = nullptr) override;
+
+    CompilerType CreateBaseType(const ConstString &name, uint64_t);
+
+  private:
+    int m_pointer_byte_size;
+    int m_int_byte_size;
+    std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap;
+    OCamlTypeMap m_base_type_map;
+
+    OCamlASTContext(const OCamlASTContext &) = delete;
+    const OCamlASTContext &operator=(const OCamlASTContext &) = delete;
+};
+
+class OCamlASTContextForExpr : public OCamlASTContext
+{
+    public:
+        OCamlASTContextForExpr(lldb::TargetSP target) : m_target_wp(target) {}
+
+    private:
+        lldb::TargetWP m_target_wp;
+};
+
+}
+#endif // liblldb_OCamlASTContext_h_

Modified: lldb/trunk/include/lldb/Symbol/TypeSystem.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/TypeSystem.h?rev=277443&r1=277442&r2=277443&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/TypeSystem.h (original)
+++ lldb/trunk/include/lldb/Symbol/TypeSystem.h Tue Aug  2 06:15:55 2016
@@ -75,6 +75,7 @@ public:
         eKindSwift,
         eKindGo,
         eKindJava,
+        eKindOCaml,
         kNumKinds
     };
 

Modified: lldb/trunk/source/API/SystemInitializerFull.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SystemInitializerFull.cpp?rev=277443&r1=277442&r2=277443&view=diff
==============================================================================
--- lldb/trunk/source/API/SystemInitializerFull.cpp (original)
+++ lldb/trunk/source/API/SystemInitializerFull.cpp Tue Aug  2 06:15:55 2016
@@ -27,6 +27,7 @@
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/GoASTContext.h"
 #include "lldb/Symbol/JavaASTContext.h"
+#include "lldb/Symbol/OCamlASTContext.h"
 
 #include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
 #include "Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h"
@@ -56,6 +57,7 @@
 #include "Plugins/Language/Java/JavaLanguage.h"
 #include "Plugins/Language/ObjC/ObjCLanguage.h"
 #include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h"
+#include "Plugins/Language/OCaml/OCamlLanguage.h"
 #include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
 #include "Plugins/LanguageRuntime/Go/GoLanguageRuntime.h"
 #include "Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h"
@@ -314,6 +316,7 @@ SystemInitializerFull::Initialize()
     ClangASTContext::Initialize();
     GoASTContext::Initialize();
     JavaASTContext::Initialize();
+    OCamlASTContext::Initialize();
 
     ABIMacOSX_i386::Initialize();
     ABIMacOSX_arm::Initialize();
@@ -360,6 +363,7 @@ SystemInitializerFull::Initialize()
     JavaLanguage::Initialize();
     ObjCLanguage::Initialize();
     ObjCPlusPlusLanguage::Initialize();
+    OCamlLanguage::Initialize();
 
 #if defined(_MSC_VER)
     ProcessWindowsLive::Initialize();
@@ -444,6 +448,7 @@ SystemInitializerFull::Terminate()
     ClangASTContext::Terminate();
     GoASTContext::Terminate();
     JavaASTContext::Terminate();
+    OCamlASTContext::Terminate();
 
     ABIMacOSX_i386::Terminate();
     ABIMacOSX_arm::Terminate();
@@ -488,6 +493,7 @@ SystemInitializerFull::Terminate()
     JavaLanguage::Terminate();
     ObjCLanguage::Terminate();
     ObjCPlusPlusLanguage::Terminate();
+    OCamlLanguage::Terminate();
 
 #if defined(__APPLE__)
     DynamicLoaderDarwinKernel::Terminate();

Modified: lldb/trunk/source/Plugins/Language/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CMakeLists.txt?rev=277443&r1=277442&r2=277443&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Language/CMakeLists.txt Tue Aug  2 06:15:55 2016
@@ -3,3 +3,4 @@ add_subdirectory(Go)
 add_subdirectory(Java)
 add_subdirectory(ObjC)
 add_subdirectory(ObjCPlusPlus)
+add_subdirectory(OCaml)

Added: lldb/trunk/source/Plugins/Language/OCaml/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/OCaml/CMakeLists.txt?rev=277443&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Language/OCaml/CMakeLists.txt (added)
+++ lldb/trunk/source/Plugins/Language/OCaml/CMakeLists.txt Tue Aug  2 06:15:55 2016
@@ -0,0 +1,4 @@
+add_lldb_library(lldbPluginOCamlLanguage
+  OCamlLanguage.cpp
+)
+

Added: lldb/trunk/source/Plugins/Language/OCaml/OCamlLanguage.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/OCaml/OCamlLanguage.cpp?rev=277443&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Language/OCaml/OCamlLanguage.cpp (added)
+++ lldb/trunk/source/Plugins/Language/OCaml/OCamlLanguage.cpp Tue Aug  2 06:15:55 2016
@@ -0,0 +1,78 @@
+//===-- OCamlLanguage.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 "OCamlLanguage.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Symbol/OCamlASTContext.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+OCamlLanguage::Initialize()
+{
+    PluginManager::RegisterPlugin(GetPluginNameStatic(), "OCaml Language", CreateInstance);
+}
+
+void
+OCamlLanguage::Terminate()
+{
+    PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString
+OCamlLanguage::GetPluginNameStatic()
+{
+    static ConstString g_name("OCaml");
+    return g_name;
+}
+
+lldb_private::ConstString
+OCamlLanguage::GetPluginName()
+{
+    return GetPluginNameStatic();
+}
+
+uint32_t
+OCamlLanguage::GetPluginVersion()
+{
+    return 1;
+}
+
+Language *
+OCamlLanguage::CreateInstance(lldb::LanguageType language)
+{
+    if (language == eLanguageTypeOCaml)
+        return new OCamlLanguage();
+    return nullptr;
+}
+
+bool
+OCamlLanguage::IsNilReference(ValueObject &valobj)
+{
+    if (!valobj.GetCompilerType().IsReferenceType())
+        return false;
+
+    // If we failed to read the value then it is not a nil reference.
+    return valobj.GetValueAsUnsigned(UINT64_MAX) == 0;
+}
+

Added: lldb/trunk/source/Plugins/Language/OCaml/OCamlLanguage.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/OCaml/OCamlLanguage.h?rev=277443&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Language/OCaml/OCamlLanguage.h (added)
+++ lldb/trunk/source/Plugins/Language/OCaml/OCamlLanguage.h Tue Aug  2 06:15:55 2016
@@ -0,0 +1,61 @@
+//===-- OCamlLanguage.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_OCamlLanguage_h_
+#define liblldb_OCamlLanguage_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+#include "llvm/ADT/StringRef.h"
+
+// Project includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/Target/Language.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private
+{
+
+class OCamlLanguage : public Language
+{
+public:
+    lldb::LanguageType
+    GetLanguageType() const override
+    {
+        return lldb::eLanguageTypeOCaml;
+    }
+
+    static void
+    Initialize();
+
+    static void
+    Terminate();
+
+    static lldb_private::Language *
+    CreateInstance(lldb::LanguageType language);
+
+    static lldb_private::ConstString
+    GetPluginNameStatic();
+
+    ConstString
+    GetPluginName() override;
+
+    uint32_t
+    GetPluginVersion() override;
+
+    bool
+    IsNilReference(ValueObject &valobj) override;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_OCamlLanguage_h_

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt?rev=277443&r1=277442&r2=277443&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/CMakeLists.txt Tue Aug  2 06:15:55 2016
@@ -4,6 +4,7 @@ add_lldb_library(lldbPluginSymbolFileDWA
   DWARFASTParserClang.cpp
   DWARFASTParserGo.cpp
   DWARFASTParserJava.cpp
+  DWARFASTParserOCaml.cpp
   DWARFAttribute.cpp
   DWARFCompileUnit.cpp
   DWARFDataExtractor.cpp

Added: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp?rev=277443&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp (added)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp Tue Aug  2 06:15:55 2016
@@ -0,0 +1,232 @@
+//===-- DWARFASTParserOCaml.cpp ---------------------------------*- C++ -*-===//
+
+#include "DWARFASTParserOCaml.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/TypeList.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+DWARFASTParserOCaml::DWARFASTParserOCaml (OCamlASTContext &ast) :
+    m_ast (ast)
+{}
+
+DWARFASTParserOCaml::~DWARFASTParserOCaml () {}
+
+TypeSP
+DWARFASTParserOCaml::ParseBaseTypeFromDIE(const DWARFDIE &die)
+{
+    SymbolFileDWARF *dwarf = die.GetDWARF();
+    dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+    ConstString type_name;
+    uint64_t byte_size = 0;
+
+    DWARFAttributes attributes;
+    const size_t num_attributes = die.GetAttributes(attributes);
+    for (uint32_t i = 0; i < num_attributes; ++i)
+    {
+        DWARFFormValue form_value;
+        dw_attr_t attr = attributes.AttributeAtIndex(i);
+        if (attributes.ExtractFormValueAtIndex(i, form_value))
+        {
+            switch (attr)
+            {
+                case DW_AT_name:
+                    type_name.SetCString(form_value.AsCString());
+                    break;
+                case DW_AT_byte_size:
+                    byte_size = form_value.Unsigned();
+                    break;
+                case DW_AT_encoding:
+                    break;
+                default:
+                    assert(false && "Unsupported attribute for DW_TAG_base_type");
+            }
+        }
+    }
+
+    Declaration decl;
+    CompilerType compiler_type = m_ast.CreateBaseType(type_name, byte_size);
+    return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size, nullptr, LLDB_INVALID_UID,
+            Type::eEncodingIsUID, decl, compiler_type, Type::eResolveStateFull);
+}
+
+lldb::TypeSP
+DWARFASTParserOCaml::ParseTypeFromDWARF (const SymbolContext& sc,
+                                         const DWARFDIE &die,
+                                         Log *log,
+                                         bool *type_is_new_ptr)
+{
+    if (type_is_new_ptr)
+        *type_is_new_ptr = false;
+
+    if (!die)
+        return nullptr;
+
+    SymbolFileDWARF *dwarf = die.GetDWARF();
+
+    Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
+    if (type_ptr == DIE_IS_BEING_PARSED)
+        return nullptr;
+    if (type_ptr != nullptr)
+        return type_ptr->shared_from_this();
+
+    TypeSP type_sp;
+    if (type_is_new_ptr)
+        *type_is_new_ptr = true;
+
+    switch (die.Tag())
+    {
+        case DW_TAG_base_type:
+            {
+                type_sp = ParseBaseTypeFromDIE(die);
+                break;
+            }
+        case DW_TAG_array_type:
+            {
+                break;
+            }
+        case DW_TAG_class_type:
+            {
+                break;
+            }
+        case DW_TAG_reference_type:
+            {
+                break;
+            }
+    }
+
+    if (!type_sp)
+        return nullptr;
+
+    DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
+    dw_tag_t sc_parent_tag = sc_parent_die.Tag();
+
+    SymbolContextScope *symbol_context_scope = nullptr;
+    if (sc_parent_tag == DW_TAG_compile_unit)
+    {
+        symbol_context_scope = sc.comp_unit;
+    }
+    else if (sc.function != nullptr && sc_parent_die)
+    {
+        symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
+        if (symbol_context_scope == nullptr)
+            symbol_context_scope = sc.function;
+    }
+
+    if (symbol_context_scope != nullptr)
+        type_sp->SetSymbolContextScope(symbol_context_scope);
+
+    dwarf->GetTypeList()->Insert(type_sp);
+    dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+
+    return type_sp;
+}
+
+Function *
+DWARFASTParserOCaml::ParseFunctionFromDWARF (const SymbolContext& sc,
+                                             const DWARFDIE &die)
+{
+    DWARFRangeList func_ranges;
+    const char *name = NULL;
+    const char *mangled = NULL;
+    int decl_file = 0;
+    int decl_line = 0;
+    int decl_column = 0;
+    int call_file = 0;
+    int call_line = 0;
+    int call_column = 0;
+    DWARFExpression frame_base(die.GetCU());
+
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_LANGUAGE));
+
+    if (die)
+    {
+        SymbolFileDWARF *dwarf = die.GetDWARF();
+        if (log)
+        {
+            dwarf->GetObjectFile()->GetModule()->LogMessage(
+                log, "DWARFASTParserOCaml::ParseFunctionFromDWARF (die = 0x%8.8x) %s name = '%s')", die.GetOffset(),
+                DW_TAG_value_to_name(die.Tag()), die.GetName());
+        }
+    }
+
+    assert(die.Tag() == DW_TAG_subprogram);
+
+    if (die.Tag() != DW_TAG_subprogram)
+        return NULL;
+
+    if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line,
+                                 call_column, &frame_base))
+    {
+        AddressRange func_range;
+        lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
+        lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
+        if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
+        {
+            ModuleSP module_sp(die.GetModule());
+            func_range.GetBaseAddress().ResolveAddressUsingFileSections(lowest_func_addr, module_sp->GetSectionList());
+            if (func_range.GetBaseAddress().IsValid())
+                func_range.SetByteSize(highest_func_addr - lowest_func_addr);
+        }
+
+        if (func_range.GetBaseAddress().IsValid())
+        {
+            Mangled func_name;
+
+            func_name.SetValue(ConstString(name), true);
+
+            FunctionSP func_sp;
+            std::unique_ptr<Declaration> decl_ap;
+            if (decl_file != 0 || decl_line != 0 || decl_column != 0)
+                decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line,
+                                              decl_column));
+
+            SymbolFileDWARF *dwarf = die.GetDWARF();
+            Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
+
+            assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
+
+            if (dwarf->FixupAddress(func_range.GetBaseAddress()))
+            {
+                const user_id_t func_user_id = die.GetID();
+                func_sp.reset(new Function(sc.comp_unit,
+                                           func_user_id, // UserID is the DIE offset
+                                           func_user_id,
+                                           func_name,
+                                           func_type,
+                                           func_range)); // first address range
+
+                if (func_sp.get() != NULL)
+                {
+                    if (frame_base.IsValid())
+                        func_sp->GetFrameBaseExpression() = frame_base;
+                    sc.comp_unit->AddFunction(func_sp);
+                    return func_sp.get();
+                }
+            }
+        }
+    }
+
+    return NULL;
+}
+
+lldb_private::CompilerDeclContext
+DWARFASTParserOCaml::GetDeclContextForUIDFromDWARF (const DWARFDIE &die)
+{
+    return CompilerDeclContext();
+}
+
+lldb_private::CompilerDeclContext
+DWARFASTParserOCaml::GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die)
+{
+    return CompilerDeclContext();
+}

Added: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h?rev=277443&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h (added)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h Tue Aug  2 06:15:55 2016
@@ -0,0 +1,60 @@
+//===-- DWARFASTParserOCaml.h -----------------------------------*- C++ -*-===//
+
+#ifndef SymbolFileDWARF_DWARFASTParserOCaml_h_
+#define SymbolFileDWARF_DWARFASTParserOCaml_h_
+
+#include "DWARFASTParser.h"
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugInfo.h"
+#include "DWARFDIE.h"
+#include "DWARFDefines.h"
+#include "SymbolFileDWARF.h"
+
+#include "lldb/Symbol/OCamlASTContext.h"
+
+class DWARFDebugInfoEntry;
+class DWARFDIECollection;
+
+class DWARFASTParserOCaml : public DWARFASTParser
+{
+public:
+    DWARFASTParserOCaml (lldb_private::OCamlASTContext &ast);
+
+    virtual ~DWARFASTParserOCaml ();
+
+    lldb::TypeSP
+    ParseBaseTypeFromDIE(const DWARFDIE &die);
+
+    lldb::TypeSP
+    ParseTypeFromDWARF (const lldb_private::SymbolContext& sc,
+                        const DWARFDIE &die,
+                        lldb_private::Log *log,
+                        bool *type_is_new_ptr) override;
+
+    lldb_private::Function *
+    ParseFunctionFromDWARF (const lldb_private::SymbolContext& sc,
+                            const DWARFDIE &die) override;
+
+    bool
+    CompleteTypeFromDWARF (const DWARFDIE &die,
+                           lldb_private::Type *type,
+                           lldb_private::CompilerType &compiler_type) override { return false; }
+
+    lldb_private::CompilerDecl
+    GetDeclForUIDFromDWARF (const DWARFDIE &die) override { return lldb_private::CompilerDecl(); }
+
+    lldb_private::CompilerDeclContext
+    GetDeclContextForUIDFromDWARF (const DWARFDIE &die) override;
+
+    lldb_private::CompilerDeclContext
+    GetDeclContextContainingUIDFromDWARF (const DWARFDIE &die) override;
+
+    std::vector<DWARFDIE>
+    GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) override { return {}; }
+
+protected:
+
+    lldb_private::OCamlASTContext &m_ast;
+};
+
+#endif  // SymbolFileDWARF_DWARFASTParserOCaml_h_

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=277443&r1=277442&r2=277443&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Tue Aug  2 06:15:55 2016
@@ -74,6 +74,7 @@ public:
     friend class DWARFASTParserClang;
     friend class DWARFASTParserGo;
     friend class DWARFASTParserJava;
+    friend class DWARFASTParserOCaml;
 
     //------------------------------------------------------------------
     // Static Functions

Modified: lldb/trunk/source/Symbol/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CMakeLists.txt?rev=277443&r1=277442&r2=277443&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/CMakeLists.txt (original)
+++ lldb/trunk/source/Symbol/CMakeLists.txt Tue Aug  2 06:15:55 2016
@@ -21,6 +21,7 @@ add_lldb_library(lldbSymbol
   LineEntry.cpp
   LineTable.cpp
   ObjectFile.cpp
+  OCamlASTContext.cpp
   Symbol.cpp
   SymbolContext.cpp
   SymbolFile.cpp

Added: lldb/trunk/source/Symbol/OCamlASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/OCamlASTContext.cpp?rev=277443&view=auto
==============================================================================
--- lldb/trunk/source/Symbol/OCamlASTContext.cpp (added)
+++ lldb/trunk/source/Symbol/OCamlASTContext.cpp Tue Aug  2 06:15:55 2016
@@ -0,0 +1,798 @@
+//===-- OCamlASTContext.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/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/OCamlASTContext.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Target.h"
+
+#include "Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace lldb_private
+{
+    class OCamlASTContext::OCamlType
+    {
+        public:
+            enum LLVMCastKind
+            {
+                eKindPrimitive,
+                eKindObject,
+                eKindReference,
+                eKindArray,
+                kNumKinds
+            };
+
+            OCamlType(LLVMCastKind kind) : m_kind(kind) {}
+
+            virtual ~OCamlType() = default;
+
+            virtual ConstString
+                GetName() = 0;
+
+            virtual void
+                Dump(Stream *s) = 0;
+
+            virtual bool
+                IsCompleteType() = 0;
+
+            LLVMCastKind
+                getKind() const
+                {
+                    return m_kind;
+                }
+
+        private:
+            LLVMCastKind m_kind;
+    };
+
+} // end of namespace lldb_private
+
+namespace
+{
+
+    class OCamlPrimitiveType : public OCamlASTContext::OCamlType
+    {
+        public:
+            enum TypeKind
+            {
+                eTypeInt,
+            };
+
+            OCamlPrimitiveType(TypeKind type_kind, uint32_t byte_size) : OCamlType(OCamlType::eKindPrimitive), m_type_kind(type_kind), m_type(ConstString()), m_byte_size(byte_size) {}
+
+            OCamlPrimitiveType(TypeKind type_kind, ConstString s, uint32_t byte_size) : OCamlType(OCamlType::eKindPrimitive), m_type_kind(type_kind), m_type(s), m_byte_size(byte_size) {}
+
+            ConstString
+            GetName() override
+            {
+                switch (m_type_kind)
+                {
+                    case eTypeInt:
+                        return m_type;
+                }
+                return ConstString();
+            }
+
+            TypeKind
+            GetTypeKind()
+            {
+                return m_type_kind;
+            }
+
+            void
+            Dump(Stream *s) override
+            {
+                s->Printf("%s\n", GetName().GetCString());
+            }
+
+            bool
+            IsCompleteType() override
+            {
+                return true;
+            }
+
+            static bool
+            classof(const OCamlType *ot)
+            {
+                return ot->getKind() == OCamlType::eKindPrimitive;
+            }
+
+            uint64_t
+            GetByteSize() const
+            {
+                return m_byte_size;
+            }
+
+        private:
+            const TypeKind m_type_kind;
+            const ConstString m_type;
+            uint64_t m_byte_size;
+    };
+}
+
+OCamlASTContext::OCamlASTContext()
+    : TypeSystem(eKindOCaml),
+      m_pointer_byte_size(0),
+      m_int_byte_size(0)
+{
+}
+
+OCamlASTContext::~OCamlASTContext()
+{
+}
+
+ConstString
+OCamlASTContext::GetPluginNameStatic()
+{
+    return ConstString("ocaml");
+}
+
+ConstString
+OCamlASTContext::GetPluginName()
+{
+    return OCamlASTContext::GetPluginNameStatic();
+}
+
+uint32_t
+OCamlASTContext::GetPluginVersion()
+{
+    return 1;
+}
+
+lldb::TypeSystemSP
+OCamlASTContext::CreateInstance (lldb::LanguageType language, Module *module, Target *target)
+{
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_LANGUAGE));
+
+    if (language == lldb::eLanguageTypeOCaml)
+    {
+        std::shared_ptr<OCamlASTContext> ocaml_ast_sp;
+        ArchSpec arch;
+
+        if (module)
+        {
+            arch = module->GetArchitecture();
+
+            ObjectFile *objfile = module->GetObjectFile();
+            ArchSpec object_arch;
+
+            if (!objfile || !objfile->GetArchitecture(object_arch))
+                return lldb::TypeSystemSP();
+
+            ocaml_ast_sp = std::shared_ptr<OCamlASTContext>(new OCamlASTContext);
+
+            if (log) {
+                log->Printf ("((Module*)%p) [%s]->GetOCamlASTContext() = %p",
+                            (void *)module,
+                            module->GetFileSpec().GetFilename().AsCString("<anonymous>"),
+                            (void *)ocaml_ast_sp.get());
+            }
+
+        } else if (target) {
+            arch = target->GetArchitecture();
+            ocaml_ast_sp = std::shared_ptr<OCamlASTContextForExpr>(new OCamlASTContextForExpr(target->shared_from_this()));
+
+            if (log)
+            {
+                log->Printf ("((Target*)%p)->GetOCamlASTContext() = %p",
+                            (void *)target,
+                            (void *)ocaml_ast_sp.get());
+            }
+        }
+
+        if (arch.IsValid()) {
+            ocaml_ast_sp->SetAddressByteSize(arch.GetAddressByteSize());
+            return ocaml_ast_sp;
+        }
+    }
+
+    return lldb::TypeSystemSP();
+}
+
+void
+OCamlASTContext::EnumerateSupportedLanguages
+(std::set<lldb::LanguageType> &languages_for_types,
+ std::set<lldb::LanguageType> &languages_for_expressions)
+{
+    static std::vector<lldb::LanguageType> s_supported_languages_for_types({lldb::eLanguageTypeOCaml});
+    static std::vector<lldb::LanguageType> s_supported_languages_for_expressions({});
+
+    languages_for_types.insert(s_supported_languages_for_types.begin(), s_supported_languages_for_types.end());
+    languages_for_expressions.insert(s_supported_languages_for_expressions.begin(), s_supported_languages_for_expressions.end());
+}
+
+void
+OCamlASTContext::Initialize()
+{
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   "OCaml AST context plug-in",
+                                   CreateInstance,
+                                   EnumerateSupportedLanguages);
+}
+
+void
+OCamlASTContext::Terminate()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+DWARFASTParser *
+OCamlASTContext::GetDWARFParser()
+{
+    if (!m_dwarf_ast_parser_ap) {
+        m_dwarf_ast_parser_ap.reset(new DWARFASTParserOCaml(*this));
+    }
+
+    return m_dwarf_ast_parser_ap.get();
+}
+
+bool
+OCamlASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
+                             CompilerType *element_type, uint64_t *size,
+                             bool *is_incomplete)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsVectorType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsAggregateType(lldb::opaque_compiler_type_t type)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsCharType(lldb::opaque_compiler_type_t type)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsCompleteType(lldb::opaque_compiler_type_t type)
+{
+    return static_cast<OCamlPrimitiveType *>(type)->IsCompleteType();
+}
+
+bool
+OCamlASTContext::IsConst(lldb::opaque_compiler_type_t type)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsDefined(lldb::opaque_compiler_type_t type)
+{
+    return type != nullptr;
+}
+
+bool
+OCamlASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr)
+{
+    return false;
+}
+
+uint32_t
+OCamlASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr)
+{
+    return false;
+}
+
+size_t
+OCamlASTContext::GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type)
+{
+    return 0;
+}
+
+CompilerType
+OCamlASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index)
+{
+    return CompilerType();
+}
+
+bool
+OCamlASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type)
+{
+    return IsFunctionType(type);
+}
+
+bool
+OCamlASTContext::IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed)
+{
+    if (OCamlPrimitiveType *ptype = llvm::dyn_cast<OCamlPrimitiveType>(static_cast<OCamlType *>(type)))
+    {
+        switch (ptype->GetTypeKind())
+        {
+            case OCamlPrimitiveType::eTypeInt:
+                is_signed = true;
+                return true;
+            default:
+                break;
+        }
+    }
+
+    is_signed = false;
+    return false;
+}
+
+bool
+OCamlASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
+                                    CompilerType *target_type,
+                                    bool check_cplusplus, bool check_objc)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
+{
+    if (pointee_type)
+        pointee_type->Clear();
+    return false;
+}
+
+bool
+OCamlASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type)
+{
+    return IsPointerType(type, pointee_type);
+}
+
+bool
+OCamlASTContext::IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type, bool *is_rvalue)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsScalarType(lldb::opaque_compiler_type_t type)
+{
+    return llvm::isa<OCamlPrimitiveType>(static_cast<OCamlType *>(type));
+}
+
+bool
+OCamlASTContext::IsTypedefType(lldb::opaque_compiler_type_t type)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::IsVoidType(lldb::opaque_compiler_type_t type)
+{
+    return false;
+}
+
+bool
+OCamlASTContext::SupportsLanguage (lldb::LanguageType language)
+{
+    return language == lldb::eLanguageTypeOCaml;
+}
+
+bool
+OCamlASTContext::GetCompleteType(lldb::opaque_compiler_type_t type)
+{
+    if (IsCompleteType(type))
+        return true;
+
+    return false;
+}
+
+uint32_t
+OCamlASTContext::GetPointerByteSize()
+{
+    return m_pointer_byte_size;
+}
+
+ConstString
+OCamlASTContext::GetTypeName(lldb::opaque_compiler_type_t type)
+{
+    if (type)
+        return static_cast<OCamlPrimitiveType *>(type)->GetName();
+
+    return ConstString();
+}
+
+uint32_t
+OCamlASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type)
+{
+    if (pointee_or_element_compiler_type)
+        pointee_or_element_compiler_type->Clear();
+    if (!type)
+        return 0;
+
+    if (OCamlPrimitiveType *ptype = llvm::dyn_cast<OCamlPrimitiveType>(static_cast<OCamlType *>(type)))
+    {
+        switch (ptype->GetTypeKind())
+        {
+            case OCamlPrimitiveType::eTypeInt:
+                return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsInteger | eTypeIsSigned;
+        }
+    }
+
+    return 0;
+}
+
+lldb::TypeClass
+OCamlASTContext::GetTypeClass(lldb::opaque_compiler_type_t type)
+{
+    if (llvm::isa<OCamlPrimitiveType>(static_cast<OCamlType *>(type)))
+        return eTypeClassBuiltin;
+
+    return lldb::eTypeClassInvalid;
+}
+
+lldb::BasicType
+OCamlASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type)
+{
+    return lldb::eBasicTypeInvalid;
+}
+
+lldb::LanguageType
+OCamlASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type)
+{
+    return lldb::eLanguageTypeOCaml;
+}
+
+unsigned
+OCamlASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type)
+{
+    return 0;
+}
+
+//----------------------------------------------------------------------
+// Creating related types
+//----------------------------------------------------------------------
+
+CompilerType
+OCamlASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride)
+{
+    return CompilerType();
+}
+
+CompilerType
+OCamlASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type)
+{
+    return CompilerType(this, type);
+}
+
+CompilerType
+OCamlASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type)
+{
+    return CompilerType(this, type);
+}
+
+int
+OCamlASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type)
+{
+    return GetNumberOfFunctionArguments(type);
+}
+
+CompilerType
+OCamlASTContext::GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx)
+{
+    return GetFunctionArgumentAtIndex(type, idx);
+}
+
+CompilerType
+OCamlASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type)
+{
+    return CompilerType();
+}
+
+size_t
+OCamlASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type)
+{
+    return 0;
+}
+
+TypeMemberFunctionImpl
+OCamlASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx)
+{
+    return TypeMemberFunctionImpl();
+}
+
+CompilerType
+OCamlASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type)
+{
+    return CompilerType(this, type);
+}
+
+CompilerType
+OCamlASTContext::GetPointeeType(lldb::opaque_compiler_type_t type)
+{
+    return CompilerType();
+}
+
+CompilerType
+OCamlASTContext::GetPointerType(lldb::opaque_compiler_type_t type)
+{
+    return CompilerType();
+}
+
+CompilerType
+OCamlASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type)
+{
+    return CompilerType();
+}
+
+CompilerType
+OCamlASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type)
+{
+    return CompilerType();
+}
+
+CompilerType
+OCamlASTContext::GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding,
+                                                      size_t bit_size)
+{
+    return CompilerType();
+}
+
+uint64_t
+OCamlASTContext::GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope)
+{
+    if (OCamlPrimitiveType *ptype = llvm::dyn_cast<OCamlPrimitiveType>(static_cast<OCamlType *>(type)))
+    {
+        switch (ptype->GetTypeKind())
+        {
+            case OCamlPrimitiveType::eTypeInt:
+                return ptype->GetByteSize() * 8;
+        }
+    }
+    return 0;
+}
+
+lldb::Encoding
+OCamlASTContext::GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count)
+{
+    count = 1;
+    bool is_signed;
+    if (IsIntegerType(type, is_signed))
+        return is_signed ? lldb::eEncodingSint : lldb::eEncodingUint;
+    bool is_complex;
+    uint32_t complex_count;
+    if (IsFloatingPointType(type, complex_count, is_complex))
+    {
+        count = complex_count;
+        return lldb::eEncodingIEEE754;
+    }
+    if (IsPointerType(type))
+        return lldb::eEncodingUint;
+    return lldb::eEncodingInvalid;
+}
+
+lldb::Format
+OCamlASTContext::GetFormat(lldb::opaque_compiler_type_t type)
+{
+    if (!type)
+        return lldb::eFormatDefault;
+    return lldb::eFormatBytes;
+}
+
+size_t
+OCamlASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type)
+{
+    return 0;
+}
+
+uint32_t
+OCamlASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes)
+{
+    if (!type || !GetCompleteType(type))
+        return 0;
+
+    return GetNumFields(type);
+}
+
+uint32_t
+OCamlASTContext::GetNumFields(lldb::opaque_compiler_type_t type)
+{
+    if (!type || !GetCompleteType(type))
+        return 0;
+    return 0;
+}
+
+CompilerType
+OCamlASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, 
+                                 std::string &name, uint64_t *bit_offset_ptr,
+                                 uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr)
+{
+    if (bit_offset_ptr)
+        *bit_offset_ptr = 0;
+    if (bitfield_bit_size_ptr)
+        *bitfield_bit_size_ptr = 0;
+    if (is_bitfield_ptr)
+        *is_bitfield_ptr = false;
+
+    if (!type || !GetCompleteType(type))
+        return CompilerType();
+
+    return CompilerType();
+}
+
+CompilerType
+OCamlASTContext::GetChildCompilerTypeAtIndex(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
+                                             bool transparent_pointers, bool omit_empty_base_classes,
+                                             bool ignore_array_bounds, std::string &child_name,
+                                             uint32_t &child_byte_size, int32_t &child_byte_offset,
+                                             uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
+                                             bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj,
+                                             uint64_t &language_flags)
+{
+    child_name.clear();
+    child_byte_size = 0;
+    child_byte_offset = 0;
+    child_bitfield_bit_size = 0;
+    child_bitfield_bit_offset = 0;
+    child_is_base_class = false;
+    child_is_deref_of_parent = false;
+    language_flags = 0;
+
+    if (!type || !GetCompleteType(type))
+        return CompilerType();
+
+    return CompilerType();
+}
+
+uint32_t
+OCamlASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes)
+{
+    if (!type || !GetCompleteType(type))
+        return UINT_MAX;
+
+    return UINT_MAX;
+}
+
+size_t
+OCamlASTContext::GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, const char *name, 
+                                               bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes)
+{
+    uint32_t index = GetIndexOfChildWithName(type, name, omit_empty_base_classes);
+    if (index == UINT_MAX)
+        return 0;
+    child_indexes.push_back(index);
+    return 1;
+}
+
+size_t
+OCamlASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst, size_t dst_size)
+{
+    assert(false);
+    return 0;
+}
+//----------------------------------------------------------------------
+// Dumping types
+//----------------------------------------------------------------------
+
+void
+OCamlASTContext::DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format,
+                           const DataExtractor &data, lldb::offset_t data_byte_offset, size_t data_byte_size,
+                           uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, bool show_summary,
+                           bool verbose, uint32_t depth)
+{
+    if (!type) {
+        s->Printf("no type\n");
+        return;
+    }
+
+    s->Printf("no value\n");
+
+    if (show_summary)
+        DumpSummary (type, exe_ctx, s, data, data_byte_offset, data_byte_size);
+}
+
+bool
+OCamlASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, 
+                               lldb::Format format, const DataExtractor &data,
+                               lldb::offset_t byte_offset, size_t byte_size, uint32_t bitfield_bit_size,
+                               uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope)
+{
+    if (!type) {
+        s->Printf("no type value\n");
+        return false;
+    }
+
+    if (IsScalarType(type))
+    {
+        return 
+        data.Dump(s, byte_offset, format, byte_size, 1, UINT64_MAX,
+                  LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset, exe_scope);
+    }
+
+    return false;
+}
+
+void
+OCamlASTContext::DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s,
+                             const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size)
+{
+    s->Printf("no summary\n");
+}
+
+void
+OCamlASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type)
+{
+    StreamFile s(stdout, false);
+    DumpTypeDescription(type, &s);
+}
+
+void
+OCamlASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s)
+{
+    static_cast<OCamlType *>(type)->Dump(s);
+}
+
+CompilerType
+OCamlASTContext::CreateBaseType(const ConstString &name, uint64_t byte_size)
+{
+    if (m_base_type_map.empty())
+    {
+        OCamlPrimitiveType *type = new OCamlPrimitiveType(OCamlPrimitiveType::eTypeInt, ConstString("ocaml_int"), byte_size);
+        m_base_type_map.emplace(type->GetName(), std::unique_ptr<OCamlASTContext::OCamlType>(type));
+    }
+
+    auto it = m_base_type_map.find(name);
+    if (it == m_base_type_map.end())
+    {
+        OCamlPrimitiveType *type = new OCamlPrimitiveType(OCamlPrimitiveType::eTypeInt, name, byte_size);
+        it = m_base_type_map.emplace(name, std::unique_ptr<OCamlASTContext::OCamlType>(type)).first;
+    }
+
+    return CompilerType(this, it->second.get());
+}
+




More information about the lldb-commits mailing list