6 changes: 6 additions & 0 deletions lldb/source/API/SystemInitializerFull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -314,6 +316,7 @@ SystemInitializerFull::Initialize()
ClangASTContext::Initialize();
GoASTContext::Initialize();
JavaASTContext::Initialize();
OCamlASTContext::Initialize();

ABIMacOSX_i386::Initialize();
ABIMacOSX_arm::Initialize();
Expand Down Expand Up @@ -360,6 +363,7 @@ SystemInitializerFull::Initialize()
JavaLanguage::Initialize();
ObjCLanguage::Initialize();
ObjCPlusPlusLanguage::Initialize();
OCamlLanguage::Initialize();

#if defined(_MSC_VER)
ProcessWindowsLive::Initialize();
Expand Down Expand Up @@ -444,6 +448,7 @@ SystemInitializerFull::Terminate()
ClangASTContext::Terminate();
GoASTContext::Terminate();
JavaASTContext::Terminate();
OCamlASTContext::Terminate();

ABIMacOSX_i386::Terminate();
ABIMacOSX_arm::Terminate();
Expand Down Expand Up @@ -488,6 +493,7 @@ SystemInitializerFull::Terminate()
JavaLanguage::Terminate();
ObjCLanguage::Terminate();
ObjCPlusPlusLanguage::Terminate();
OCamlLanguage::Terminate();

#if defined(__APPLE__)
DynamicLoaderDarwinKernel::Terminate();
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/Language/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ add_subdirectory(Go)
add_subdirectory(Java)
add_subdirectory(ObjC)
add_subdirectory(ObjCPlusPlus)
add_subdirectory(OCaml)
4 changes: 4 additions & 0 deletions lldb/source/Plugins/Language/OCaml/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
add_lldb_library(lldbPluginOCamlLanguage
OCamlLanguage.cpp
)

78 changes: 78 additions & 0 deletions lldb/source/Plugins/Language/OCaml/OCamlLanguage.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 61 additions & 0 deletions lldb/source/Plugins/Language/OCaml/OCamlLanguage.h
Original file line number Diff line number Diff line change
@@ -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_
1 change: 1 addition & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF
DWARFASTParserClang.cpp
DWARFASTParserGo.cpp
DWARFASTParserJava.cpp
DWARFASTParserOCaml.cpp
DWARFAttribute.cpp
DWARFCompileUnit.cpp
DWARFDataExtractor.cpp
Expand Down
232 changes: 232 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 60 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
Original file line number Diff line number Diff line change
@@ -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_
1 change: 1 addition & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class SymbolFileDWARF : public lldb_private::SymbolFile, public lldb_private::Us
friend class DWARFASTParserClang;
friend class DWARFASTParserGo;
friend class DWARFASTParserJava;
friend class DWARFASTParserOCaml;

//------------------------------------------------------------------
// Static Functions
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Symbol/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ add_lldb_library(lldbSymbol
LineEntry.cpp
LineTable.cpp
ObjectFile.cpp
OCamlASTContext.cpp
Symbol.cpp
SymbolContext.cpp
SymbolFile.cpp
Expand Down
798 changes: 798 additions & 0 deletions lldb/source/Symbol/OCamlASTContext.cpp

Large diffs are not rendered by default.