//===-- SBFunction.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/API/SBFunction.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

SBFunction::SBFunction () :
    m_opaque_ptr (NULL)
{
}

SBFunction::SBFunction (lldb_private::Function *lldb_object_ptr) :
    m_opaque_ptr (lldb_object_ptr)
{
}

SBFunction::SBFunction (const lldb::SBFunction &rhs) :
    m_opaque_ptr (rhs.m_opaque_ptr)
{
}

const SBFunction &
SBFunction::operator = (const SBFunction &rhs)
{
    m_opaque_ptr = rhs.m_opaque_ptr;
    return *this;
}

SBFunction::~SBFunction ()
{
    m_opaque_ptr = NULL;
}

bool
SBFunction::IsValid () const
{
    return m_opaque_ptr != NULL;
}

const char *
SBFunction::GetName() const
{
    const char *cstr = NULL;
    if (m_opaque_ptr)
        cstr = m_opaque_ptr->GetMangled().GetName().AsCString();

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (cstr)
            log->Printf ("SBFunction(%p)::GetName () => \"%s\"",
                         static_cast<void*>(m_opaque_ptr), cstr);
        else
            log->Printf ("SBFunction(%p)::GetName () => NULL",
                         static_cast<void*>(m_opaque_ptr));
    }
    return cstr;
}

const char *
SBFunction::GetMangledName () const
{
    const char *cstr = NULL;
    if (m_opaque_ptr)
        cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString();
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (cstr)
            log->Printf ("SBFunction(%p)::GetMangledName () => \"%s\"",
                         static_cast<void*>(m_opaque_ptr), cstr);
        else
            log->Printf ("SBFunction(%p)::GetMangledName () => NULL",
                         static_cast<void*>(m_opaque_ptr));
    }
    return cstr;
}

bool
SBFunction::operator == (const SBFunction &rhs) const
{
    return m_opaque_ptr == rhs.m_opaque_ptr;
}

bool
SBFunction::operator != (const SBFunction &rhs) const
{
    return m_opaque_ptr != rhs.m_opaque_ptr;
}

bool
SBFunction::GetDescription (SBStream &s)
{
    if (m_opaque_ptr)
    {
        s.Printf ("SBFunction: id = 0x%8.8" PRIx64 ", name = %s",
                  m_opaque_ptr->GetID(),
                  m_opaque_ptr->GetName().AsCString());
        Type *func_type = m_opaque_ptr->GetType();
        if (func_type)
            s.Printf(", type = %s", func_type->GetName().AsCString());
        return true;
    }
    s.Printf ("No value");
    return false;
}

SBInstructionList
SBFunction::GetInstructions (SBTarget target)
{
    return GetInstructions (target, NULL);
}

SBInstructionList
SBFunction::GetInstructions (SBTarget target, const char *flavor)
{
    SBInstructionList sb_instructions;
    if (m_opaque_ptr)
    {
        Mutex::Locker api_locker;
        ExecutionContext exe_ctx;
        TargetSP target_sp (target.GetSP());
        if (target_sp)
        {
            api_locker.Lock (target_sp->GetAPIMutex());
            target_sp->CalculateExecutionContext (exe_ctx);
            exe_ctx.SetProcessSP(target_sp->GetProcessSP());
        }
        ModuleSP module_sp (m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule());
        if (module_sp)
        {
            const bool prefer_file_cache = false;
            sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture(),
                                                                             NULL,
                                                                             flavor,
                                                                             exe_ctx,
                                                                             m_opaque_ptr->GetAddressRange(),
                                                                             prefer_file_cache));
        }
    }
    return sb_instructions;
}

lldb_private::Function *
SBFunction::get ()
{
    return m_opaque_ptr;
}

void
SBFunction::reset (lldb_private::Function *lldb_object_ptr)
{
    m_opaque_ptr = lldb_object_ptr;
}

SBAddress
SBFunction::GetStartAddress ()
{
    SBAddress addr;
    if (m_opaque_ptr)
        addr.SetAddress (&m_opaque_ptr->GetAddressRange().GetBaseAddress());
    return addr;
}

SBAddress
SBFunction::GetEndAddress ()
{
    SBAddress addr;
    if (m_opaque_ptr)
    {
        addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize();
        if (byte_size > 0)
        {
            addr.SetAddress (&m_opaque_ptr->GetAddressRange().GetBaseAddress());
            addr->Slide (byte_size);
        }
    }
    return addr;
}


uint32_t
SBFunction::GetPrologueByteSize ()
{
    if (m_opaque_ptr)
        return m_opaque_ptr->GetPrologueByteSize();
    return 0;
}

SBType
SBFunction::GetType ()
{
    SBType sb_type;
    if (m_opaque_ptr)
    {
        Type *function_type = m_opaque_ptr->GetType();
        if (function_type)
            sb_type.ref().SetType (function_type->shared_from_this());
    }
    return sb_type;
}

SBBlock
SBFunction::GetBlock ()
{
    SBBlock sb_block;
    if (m_opaque_ptr)
        sb_block.SetPtr (&m_opaque_ptr->GetBlock (true));
    return sb_block;
}

lldb::LanguageType
SBFunction::GetLanguage ()
{
    if (m_opaque_ptr)
    {
        if (m_opaque_ptr->GetCompileUnit())
            return m_opaque_ptr->GetCompileUnit()->GetLanguage();
    }
    return lldb::eLanguageTypeUnknown;
}


