mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-23 17:48:03 +00:00
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 llvm-svn: 277443
This commit is contained in:
parent
adedac68dc
commit
00adc41370
@ -27,6 +27,7 @@ set( LLDB_USED_LIBS
|
||||
lldbPluginJavaLanguage
|
||||
lldbPluginObjCLanguage
|
||||
lldbPluginObjCPlusPlusLanguage
|
||||
lldbPluginOCamlLanguage
|
||||
|
||||
lldbPluginObjectFileELF
|
||||
lldbPluginObjectFileJIT
|
||||
|
355
lldb/include/lldb/Symbol/OCamlASTContext.h
Normal file
355
lldb/include/lldb/Symbol/OCamlASTContext.h
Normal file
@ -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_
|
@ -75,6 +75,7 @@ public:
|
||||
eKindSwift,
|
||||
eKindGo,
|
||||
eKindJava,
|
||||
eKindOCaml,
|
||||
kNumKinds
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
|
@ -3,3 +3,4 @@ add_subdirectory(Go)
|
||||
add_subdirectory(Java)
|
||||
add_subdirectory(ObjC)
|
||||
add_subdirectory(ObjCPlusPlus)
|
||||
add_subdirectory(OCaml)
|
||||
|
4
lldb/source/Plugins/Language/OCaml/CMakeLists.txt
Normal file
4
lldb/source/Plugins/Language/OCaml/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
add_lldb_library(lldbPluginOCamlLanguage
|
||||
OCamlLanguage.cpp
|
||||
)
|
||||
|
78
lldb/source/Plugins/Language/OCaml/OCamlLanguage.cpp
Normal file
78
lldb/source/Plugins/Language/OCaml/OCamlLanguage.cpp
Normal file
@ -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;
|
||||
}
|
||||
|
61
lldb/source/Plugins/Language/OCaml/OCamlLanguage.h
Normal file
61
lldb/source/Plugins/Language/OCaml/OCamlLanguage.h
Normal file
@ -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_
|
@ -4,6 +4,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF
|
||||
DWARFASTParserClang.cpp
|
||||
DWARFASTParserGo.cpp
|
||||
DWARFASTParserJava.cpp
|
||||
DWARFASTParserOCaml.cpp
|
||||
DWARFAttribute.cpp
|
||||
DWARFCompileUnit.cpp
|
||||
DWARFDataExtractor.cpp
|
||||
|
232
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
Normal file
232
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
Normal file
@ -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();
|
||||
}
|
60
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
Normal file
60
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
Normal file
@ -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_
|
@ -74,6 +74,7 @@ public:
|
||||
friend class DWARFASTParserClang;
|
||||
friend class DWARFASTParserGo;
|
||||
friend class DWARFASTParserJava;
|
||||
friend class DWARFASTParserOCaml;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Static Functions
|
||||
|
@ -21,6 +21,7 @@ add_lldb_library(lldbSymbol
|
||||
LineEntry.cpp
|
||||
LineTable.cpp
|
||||
ObjectFile.cpp
|
||||
OCamlASTContext.cpp
|
||||
Symbol.cpp
|
||||
SymbolContext.cpp
|
||||
SymbolFile.cpp
|
||||
|
798
lldb/source/Symbol/OCamlASTContext.cpp
Normal file
798
lldb/source/Symbol/OCamlASTContext.cpp
Normal file
@ -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());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user