Index: cmake/LLDBDependencies.cmake =================================================================== --- cmake/LLDBDependencies.cmake +++ cmake/LLDBDependencies.cmake @@ -27,6 +27,7 @@ lldbPluginJavaLanguage lldbPluginObjCLanguage lldbPluginObjCPlusPlusLanguage + lldbPluginOCamlLanguage lldbPluginObjectFileELF lldbPluginObjectFileJIT Index: include/lldb/Symbol/OCamlASTContext.h =================================================================== --- /dev/null +++ include/lldb/Symbol/OCamlASTContext.h @@ -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 +#include +#include +#include +#include + +// 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> 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 &languages_for_types, + std::set &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 &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 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_ Index: include/lldb/Symbol/TypeSystem.h =================================================================== --- include/lldb/Symbol/TypeSystem.h +++ include/lldb/Symbol/TypeSystem.h @@ -75,6 +75,7 @@ eKindSwift, eKindGo, eKindJava, + eKindOCaml, kNumKinds }; Index: source/API/SystemInitializerFull.cpp =================================================================== --- source/API/SystemInitializerFull.cpp +++ source/API/SystemInitializerFull.cpp @@ -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" @@ -55,6 +56,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" @@ -313,6 +315,7 @@ ClangASTContext::Initialize(); GoASTContext::Initialize(); JavaASTContext::Initialize(); + OCamlASTContext::Initialize(); ABIMacOSX_i386::Initialize(); ABIMacOSX_arm::Initialize(); @@ -359,6 +362,7 @@ JavaLanguage::Initialize(); ObjCLanguage::Initialize(); ObjCPlusPlusLanguage::Initialize(); + OCamlLanguage::Initialize(); #if defined(_MSC_VER) ProcessWindowsLive::Initialize(); @@ -442,6 +446,7 @@ ClangASTContext::Terminate(); GoASTContext::Terminate(); JavaASTContext::Terminate(); + OCamlASTContext::Terminate(); ABIMacOSX_i386::Terminate(); ABIMacOSX_arm::Terminate(); @@ -486,6 +491,7 @@ JavaLanguage::Terminate(); ObjCLanguage::Terminate(); ObjCPlusPlusLanguage::Terminate(); + OCamlLanguage::Terminate(); #if defined(__APPLE__) DynamicLoaderDarwinKernel::Terminate(); Index: source/Plugins/Language/CMakeLists.txt =================================================================== --- source/Plugins/Language/CMakeLists.txt +++ source/Plugins/Language/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(Java) add_subdirectory(ObjC) add_subdirectory(ObjCPlusPlus) +add_subdirectory(OCaml) Index: source/Plugins/Language/OCaml/CMakeLists.txt =================================================================== --- /dev/null +++ source/Plugins/Language/OCaml/CMakeLists.txt @@ -0,0 +1,4 @@ +add_lldb_library(lldbPluginOCamlLanguage + OCamlLanguage.cpp +) + Index: source/Plugins/Language/OCaml/OCamlLanguage.h =================================================================== --- /dev/null +++ source/Plugins/Language/OCaml/OCamlLanguage.h @@ -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 + +// 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_ Index: source/Plugins/Language/OCaml/OCamlLanguage.cpp =================================================================== --- /dev/null +++ source/Plugins/Language/OCaml/OCamlLanguage.cpp @@ -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 +// C++ Includes +#include +#include + +// 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; +} + Index: source/Plugins/SymbolFile/DWARF/CMakeLists.txt =================================================================== --- source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -4,6 +4,7 @@ DWARFASTParserClang.cpp DWARFASTParserGo.cpp DWARFASTParserJava.cpp + DWARFASTParserOCaml.cpp DWARFAttribute.cpp DWARFCompileUnit.cpp DWARFDataExtractor.cpp Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h @@ -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 + GetDIEForDeclContext (lldb_private::CompilerDeclContext decl_context) override { return {}; } + +protected: + + lldb_private::OCamlASTContext &m_ast; +}; + +#endif // SymbolFileDWARF_DWARFASTParserOCaml_h_ Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp @@ -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(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 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(); +} Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -74,6 +74,7 @@ friend class DWARFASTParserClang; friend class DWARFASTParserGo; friend class DWARFASTParserJava; + friend class DWARFASTParserOCaml; //------------------------------------------------------------------ // Static Functions Index: source/Symbol/CMakeLists.txt =================================================================== --- source/Symbol/CMakeLists.txt +++ source/Symbol/CMakeLists.txt @@ -21,6 +21,7 @@ LineEntry.cpp LineTable.cpp ObjectFile.cpp + OCamlASTContext.cpp Symbol.cpp SymbolContext.cpp SymbolFile.cpp Index: source/Symbol/OCamlASTContext.cpp =================================================================== --- /dev/null +++ source/Symbol/OCamlASTContext.cpp @@ -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 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(new OCamlASTContext); + + if (log) { + log->Printf ("((Module*)%p) [%s]->GetOCamlASTContext() = %p", + (void *)module, + module->GetFileSpec().GetFilename().AsCString(""), + (void *)ocaml_ast_sp.get()); + } + + } else if (target) { + arch = target->GetArchitecture(); + ocaml_ast_sp = std::shared_ptr(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 &languages_for_types, + std::set &languages_for_expressions) +{ + static std::vector s_supported_languages_for_types({lldb::eLanguageTypeOCaml}); + static std::vector 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(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(static_cast(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(static_cast(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(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(static_cast(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(static_cast(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(static_cast(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 &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(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(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(type)).first; + } + + return CompilerType(this, it->second.get()); +} +