//===-- SBValue.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/lldb-python.h"

#include "lldb/API/SBValue.h"

#include "lldb/API/SBDeclaration.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBTypeFilter.h"
#include "lldb/API/SBTypeFormat.h"
#include "lldb/API/SBTypeSummary.h"
#include "lldb/API/SBTypeSynthetic.h"

#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Declaration.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBExpressionOptions.h"
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"

using namespace lldb;
using namespace lldb_private;

class ValueImpl
{
public:
    ValueImpl ()
    {
    }

    ValueImpl (lldb::ValueObjectSP in_valobj_sp,
               lldb::DynamicValueType use_dynamic,
               bool use_synthetic,
               const char *name = NULL) :
    m_valobj_sp(in_valobj_sp),
    m_use_dynamic(use_dynamic),
    m_use_synthetic(use_synthetic),
    m_name (name)
    {
        if (!m_name.IsEmpty() && m_valobj_sp)
            m_valobj_sp->SetName(m_name);
    }

    ValueImpl (const ValueImpl& rhs) :
    m_valobj_sp(rhs.m_valobj_sp),
    m_use_dynamic(rhs.m_use_dynamic),
    m_use_synthetic(rhs.m_use_synthetic),
    m_name (rhs.m_name)
    {
    }

    ValueImpl &
    operator = (const ValueImpl &rhs)
    {
        if (this != &rhs)
        {
            m_valobj_sp = rhs.m_valobj_sp;
            m_use_dynamic = rhs.m_use_dynamic;
            m_use_synthetic = rhs.m_use_synthetic;
            m_name = rhs.m_name;
        }
        return *this;
    }

    bool
    IsValid ()
    {
        if (m_valobj_sp.get() == NULL)
            return false;
        else
        {
            // FIXME: This check is necessary but not sufficient.  We for sure don't want to touch SBValues whose owning
            // targets have gone away.  This check is a little weak in that it enforces that restriction when you call
            // IsValid, but since IsValid doesn't lock the target, you have no guarantee that the SBValue won't go
            // invalid after you call this...
            // Also, an SBValue could depend on data from one of the modules in the target, and those could go away
            // independently of the target, for instance if a module is unloaded.  But right now, neither SBValues
            // nor ValueObjects know which modules they depend on.  So I have no good way to make that check without
            // tracking that in all the ValueObject subclasses.
            TargetSP target_sp = m_valobj_sp->GetTargetSP();
            if (target_sp && target_sp->IsValid())
                return true;
            else
                return false;
        }
    }

    lldb::ValueObjectSP
    GetRootSP ()
    {
        return m_valobj_sp;
    }

    lldb::ValueObjectSP
    GetSP (Process::StopLocker &stop_locker, Mutex::Locker &api_locker, Error &error)
    {
        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
        if (!m_valobj_sp)
        {
            error.SetErrorString("invalid value object");
            return m_valobj_sp;
        }

        lldb::ValueObjectSP value_sp = m_valobj_sp;

        Target *target = value_sp->GetTargetSP().get();
        if (target)
            api_locker.Lock(target->GetAPIMutex());
        else
            return ValueObjectSP();

        ProcessSP process_sp(value_sp->GetProcessSP());
        if (process_sp && !stop_locker.TryLock (&process_sp->GetRunLock()))
        {
            // We don't allow people to play around with ValueObject if the process is running.
            // If you want to look at values, pause the process, then look.
            if (log)
                log->Printf ("SBValue(%p)::GetSP() => error: process is running",
                             static_cast<void*>(value_sp.get()));
            error.SetErrorString ("process must be stopped.");
            return ValueObjectSP();
        }

        if (value_sp->GetDynamicValue(m_use_dynamic))
            value_sp = value_sp->GetDynamicValue(m_use_dynamic);
        if (value_sp->GetSyntheticValue(m_use_synthetic))
            value_sp = value_sp->GetSyntheticValue(m_use_synthetic);
        if (!value_sp)
            error.SetErrorString("invalid value object");
        if (!m_name.IsEmpty())
            value_sp->SetName(m_name);

        return value_sp;
    }

    void
    SetUseDynamic (lldb::DynamicValueType use_dynamic)
    {
        m_use_dynamic = use_dynamic;
    }

    void
    SetUseSynthetic (bool use_synthetic)
    {
        m_use_synthetic = use_synthetic;
    }

    lldb::DynamicValueType
    GetUseDynamic ()
    {
        return m_use_dynamic;
    }

    bool
    GetUseSynthetic ()
    {
        return m_use_synthetic;
    }

    // All the derived values that we would make from the m_valobj_sp will share
    // the ExecutionContext with m_valobj_sp, so we don't need to do the calculations
    // in GetSP to return the Target, Process, Thread or Frame.  It is convenient to
    // provide simple accessors for these, which I do here.
    TargetSP
    GetTargetSP ()
    {
        if (m_valobj_sp)
            return m_valobj_sp->GetTargetSP();
        else
            return TargetSP();
    }

    ProcessSP
    GetProcessSP ()
    {
        if (m_valobj_sp)
            return m_valobj_sp->GetProcessSP();
        else
            return ProcessSP();
    }

    ThreadSP
    GetThreadSP ()
    {
        if (m_valobj_sp)
            return m_valobj_sp->GetThreadSP();
        else
            return ThreadSP();
    }

    StackFrameSP
    GetFrameSP ()
    {
        if (m_valobj_sp)
            return m_valobj_sp->GetFrameSP();
        else
            return StackFrameSP();
    }

private:
    lldb::ValueObjectSP m_valobj_sp;
    lldb::DynamicValueType m_use_dynamic;
    bool m_use_synthetic;
    ConstString m_name;
};

class ValueLocker
{
public:
    ValueLocker ()
    {
    }
    
    ValueObjectSP
    GetLockedSP(ValueImpl &in_value)
    {
        return in_value.GetSP(m_stop_locker, m_api_locker, m_lock_error);
    }
    
    Error &
    GetError()
    {
        return m_lock_error;
    }
    
private:
    Process::StopLocker m_stop_locker;
    Mutex::Locker m_api_locker;
    Error m_lock_error;
    
};

SBValue::SBValue () :
m_opaque_sp ()
{
}

SBValue::SBValue (const lldb::ValueObjectSP &value_sp)
{
    SetSP(value_sp);
}

SBValue::SBValue(const SBValue &rhs)
{
    SetSP(rhs.m_opaque_sp);
}

SBValue &
SBValue::operator = (const SBValue &rhs)
{
    if (this != &rhs)
    {
        SetSP(rhs.m_opaque_sp);
    }
    return *this;
}

SBValue::~SBValue()
{
}

bool
SBValue::IsValid ()
{
    // If this function ever changes to anything that does more than just
    // check if the opaque shared pointer is non NULL, then we need to update
    // all "if (m_opaque_sp)" code in this file.
    return m_opaque_sp.get() != NULL && m_opaque_sp->IsValid() && m_opaque_sp->GetRootSP().get() != NULL;
}

void
SBValue::Clear()
{
    m_opaque_sp.reset();
}

SBError
SBValue::GetError()
{
    SBError sb_error;
    
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        sb_error.SetError(value_sp->GetError());
    else
        sb_error.SetErrorStringWithFormat ("error: %s", locker.GetError().AsCString());
    
    return sb_error;
}

user_id_t
SBValue::GetID()
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        return value_sp->GetID();
    return LLDB_INVALID_UID;
}

const char *
SBValue::GetName()
{
    const char *name = NULL;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        name = value_sp->GetName().GetCString();

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (name)
            log->Printf ("SBValue(%p)::GetName () => \"%s\"",
                         static_cast<void*>(value_sp.get()), name);
        else
            log->Printf ("SBValue(%p)::GetName () => NULL",
                         static_cast<void*>(value_sp.get()));
    }

    return name;
}

const char *
SBValue::GetTypeName ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    const char *name = NULL;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        name = value_sp->GetQualifiedTypeName().GetCString();
    }

    if (log)
    {
        if (name)
            log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"",
                         static_cast<void*>(value_sp.get()), name);
        else
            log->Printf ("SBValue(%p)::GetTypeName () => NULL",
                         static_cast<void*>(value_sp.get()));
    }

    return name;
}

const char *
SBValue::GetDisplayTypeName ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    const char *name = NULL;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        name = value_sp->GetDisplayTypeName().GetCString();
    }
    
    if (log)
    {
        if (name)
            log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"",
                         static_cast<void*>(value_sp.get()), name);
        else
            log->Printf ("SBValue(%p)::GetTypeName () => NULL",
                         static_cast<void*>(value_sp.get()));
    }
    
    return name;
}

size_t
SBValue::GetByteSize ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    size_t result = 0;

    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        result = value_sp->GetByteSize();
    }

    if (log)
        log->Printf ("SBValue(%p)::GetByteSize () => %" PRIu64,
                     static_cast<void*>(value_sp.get()),
                     static_cast<uint64_t>(result));

    return result;
}

bool
SBValue::IsInScope ()
{
    bool result = false;

    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        result = value_sp->IsInScope ();
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBValue(%p)::IsInScope () => %i",
                     static_cast<void*>(value_sp.get()), result);

    return result;
}

const char *
SBValue::GetValue ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    const char *cstr = NULL;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        cstr = value_sp->GetValueAsCString ();
    }
    if (log)
    {
        if (cstr)
            log->Printf ("SBValue(%p)::GetValue() => \"%s\"",
                         static_cast<void*>(value_sp.get()), cstr);
        else
            log->Printf ("SBValue(%p)::GetValue() => NULL",
                         static_cast<void*>(value_sp.get()));
    }

    return cstr;
}

ValueType
SBValue::GetValueType ()
{
    ValueType result = eValueTypeInvalid;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        result = value_sp->GetValueType();

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        switch (result)
        {
            case eValueTypeInvalid:
                log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid",
                             static_cast<void*>(value_sp.get()));
                break;
            case eValueTypeVariableGlobal:
                log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal",
                             static_cast<void*>(value_sp.get()));
                break;
            case eValueTypeVariableStatic:
                log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic",
                             static_cast<void*>(value_sp.get()));
                break;
            case eValueTypeVariableArgument:
                log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument",
                             static_cast<void*>(value_sp.get()));
                break;
            case eValueTypeVariableLocal:
                log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal",
                             static_cast<void*>(value_sp.get()));
                break;
            case eValueTypeRegister:
                log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister",
                             static_cast<void*>(value_sp.get()));
                break;
            case eValueTypeRegisterSet:
                log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet",
                             static_cast<void*>(value_sp.get()));
                break;
            case eValueTypeConstResult:
                log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult",
                             static_cast<void*>(value_sp.get()));
                break;
        }
    }
    return result;
}

const char *
SBValue::GetObjectDescription ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    const char *cstr = NULL;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        cstr = value_sp->GetObjectDescription ();
    }
    if (log)
    {
        if (cstr)
            log->Printf ("SBValue(%p)::GetObjectDescription() => \"%s\"",
                         static_cast<void*>(value_sp.get()), cstr);
        else
            log->Printf ("SBValue(%p)::GetObjectDescription() => NULL",
                         static_cast<void*>(value_sp.get()));
    }
    return cstr;
}

const char *
SBValue::GetTypeValidatorResult ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    const char *cstr = NULL;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        const auto& validation(value_sp->GetValidationStatus());
        if (TypeValidatorResult::Failure == validation.first)
        {
            if (validation.second.empty())
                cstr = "unknown error";
            else
                cstr = validation.second.c_str();
        }
    }
    if (log)
    {
        if (cstr)
            log->Printf ("SBValue(%p)::GetTypeValidatorResult() => \"%s\"",
                         static_cast<void*>(value_sp.get()), cstr);
        else
            log->Printf ("SBValue(%p)::GetTypeValidatorResult() => NULL",
                         static_cast<void*>(value_sp.get()));
    }
    return cstr;
}

SBType
SBValue::GetType()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    SBType sb_type;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    TypeImplSP type_sp;
    if (value_sp)
    {
        type_sp.reset (new TypeImpl(value_sp->GetTypeImpl()));
        sb_type.SetSP(type_sp);
    }
    if (log)
    {
        if (type_sp)
            log->Printf ("SBValue(%p)::GetType => SBType(%p)",
                         static_cast<void*>(value_sp.get()),
                         static_cast<void*>(type_sp.get()));
        else
            log->Printf ("SBValue(%p)::GetType => NULL",
                         static_cast<void*>(value_sp.get()));
    }
    return sb_type;
}

bool
SBValue::GetValueDidChange ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    bool result = false;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        if (value_sp->UpdateValueIfNeeded(false))
            result = value_sp->GetValueDidChange ();
    }
    if (log)
        log->Printf ("SBValue(%p)::GetValueDidChange() => %i",
                     static_cast<void*>(value_sp.get()), result);

    return result;
}

#ifndef LLDB_DISABLE_PYTHON
const char *
SBValue::GetSummary ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    const char *cstr = NULL;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        cstr = value_sp->GetSummaryAsCString();
    }
    if (log)
    {
        if (cstr)
            log->Printf ("SBValue(%p)::GetSummary() => \"%s\"",
                         static_cast<void*>(value_sp.get()), cstr);
        else
            log->Printf ("SBValue(%p)::GetSummary() => NULL",
                         static_cast<void*>(value_sp.get()));
    }
    return cstr;
}

const char *
SBValue::GetSummary (lldb::SBStream& stream,
                     lldb::SBTypeSummaryOptions& options)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        std::string buffer;
        if (value_sp->GetSummaryAsCString(buffer,options.ref()) && !buffer.empty())
            stream.Printf("%s",buffer.c_str());
    }
    const char* cstr = stream.GetData();
    if (log)
    {
        if (cstr)
            log->Printf ("SBValue(%p)::GetSummary() => \"%s\"",
                         static_cast<void*>(value_sp.get()), cstr);
        else
            log->Printf ("SBValue(%p)::GetSummary() => NULL",
                         static_cast<void*>(value_sp.get()));
    }
    return cstr;
}
#endif // LLDB_DISABLE_PYTHON

const char *
SBValue::GetLocation ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    const char *cstr = NULL;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        cstr = value_sp->GetLocationAsCString();
    }
    if (log)
    {
        if (cstr)
            log->Printf ("SBValue(%p)::GetLocation() => \"%s\"",
                         static_cast<void*>(value_sp.get()), cstr);
        else
            log->Printf ("SBValue(%p)::GetLocation() => NULL",
                         static_cast<void*>(value_sp.get()));
    }
    return cstr;
}

// Deprecated - use the one that takes an lldb::SBError
bool
SBValue::SetValueFromCString (const char *value_str)
{
    lldb::SBError dummy;
    return SetValueFromCString(value_str,dummy);
}

bool
SBValue::SetValueFromCString (const char *value_str, lldb::SBError& error)
{
    bool success = false;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (value_sp)
    {
        success = value_sp->SetValueFromCString (value_str,error.ref());
    }
    else
        error.SetErrorStringWithFormat ("Could not get value: %s", locker.GetError().AsCString());

    if (log)
        log->Printf ("SBValue(%p)::SetValueFromCString(\"%s\") => %i",
                     static_cast<void*>(value_sp.get()), value_str, success);

    return success;
}

lldb::SBTypeFormat
SBValue::GetTypeFormat ()
{
    lldb::SBTypeFormat format;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        if (value_sp->UpdateValueIfNeeded(true))
        {
            lldb::TypeFormatImplSP format_sp = value_sp->GetValueFormat();
            if (format_sp)
                format.SetSP(format_sp);
        }
    }
    return format;
}

#ifndef LLDB_DISABLE_PYTHON
lldb::SBTypeSummary
SBValue::GetTypeSummary ()
{
    lldb::SBTypeSummary summary;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        if (value_sp->UpdateValueIfNeeded(true))
        {
            lldb::TypeSummaryImplSP summary_sp = value_sp->GetSummaryFormat();
            if (summary_sp)
                summary.SetSP(summary_sp);
        }
    }
    return summary;
}
#endif // LLDB_DISABLE_PYTHON

lldb::SBTypeFilter
SBValue::GetTypeFilter ()
{
    lldb::SBTypeFilter filter;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        if (value_sp->UpdateValueIfNeeded(true))
        {
            lldb::SyntheticChildrenSP synthetic_sp = value_sp->GetSyntheticChildren();
            
            if (synthetic_sp && !synthetic_sp->IsScripted())
            {
                TypeFilterImplSP filter_sp = std::static_pointer_cast<TypeFilterImpl>(synthetic_sp);
                filter.SetSP(filter_sp);
            }
        }
    }
    return filter;
}

#ifndef LLDB_DISABLE_PYTHON
lldb::SBTypeSynthetic
SBValue::GetTypeSynthetic ()
{
    lldb::SBTypeSynthetic synthetic;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        if (value_sp->UpdateValueIfNeeded(true))
        {
            lldb::SyntheticChildrenSP children_sp = value_sp->GetSyntheticChildren();
            
            if (children_sp && children_sp->IsScripted())
            {
                ScriptedSyntheticChildrenSP synth_sp = std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);
                synthetic.SetSP(synth_sp);
            }
        }
    }
    return synthetic;
}
#endif

lldb::SBValue
SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type)
{
    lldb::SBValue sb_value;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    lldb::ValueObjectSP new_value_sp;
    if (value_sp)
    {
        TypeImplSP type_sp (type.GetSP());
        if (type.IsValid())
        {
            sb_value.SetSP(value_sp->GetSyntheticChildAtOffset(offset, type_sp->GetClangASTType(false), true),GetPreferDynamicValue(),GetPreferSyntheticValue(), name);
        }
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (new_value_sp)
            log->Printf ("SBValue(%p)::CreateChildAtOffset => \"%s\"",
                         static_cast<void*>(value_sp.get()),
                         new_value_sp->GetName().AsCString());
        else
            log->Printf ("SBValue(%p)::CreateChildAtOffset => NULL",
                         static_cast<void*>(value_sp.get()));
    }
    return sb_value;
}

lldb::SBValue
SBValue::Cast (SBType type)
{
    lldb::SBValue sb_value;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    TypeImplSP type_sp (type.GetSP());
    if (value_sp && type_sp)
        sb_value.SetSP(value_sp->Cast(type_sp->GetClangASTType(false)),GetPreferDynamicValue(),GetPreferSyntheticValue());
    return sb_value;
}

lldb::SBValue
SBValue::CreateValueFromExpression (const char *name, const char* expression)
{
    SBExpressionOptions options;
    options.ref().SetKeepInMemory(true);
    return CreateValueFromExpression (name, expression, options);
}

lldb::SBValue
SBValue::CreateValueFromExpression (const char *name, const char *expression, SBExpressionOptions &options)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    lldb::SBValue sb_value;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    lldb::ValueObjectSP new_value_sp;
    if (value_sp)
    {
        ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
        new_value_sp = ValueObject::CreateValueObjectFromExpression(name, expression, exe_ctx, options.ref());
        if (new_value_sp)
            new_value_sp->SetName(ConstString(name));
    }
    sb_value.SetSP(new_value_sp);
    if (log)
    {
        if (new_value_sp)
            log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => SBValue (%p)",
                         static_cast<void*>(value_sp.get()), name, expression,
                         static_cast<void*>(new_value_sp.get()));
        else
            log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => NULL",
                         static_cast<void*>(value_sp.get()), name, expression);
    }
    return sb_value;
}

lldb::SBValue
SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType sb_type)
{
    lldb::SBValue sb_value;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    lldb::ValueObjectSP new_value_sp;
    lldb::TypeImplSP type_impl_sp (sb_type.GetSP());
    if (value_sp && type_impl_sp)
    {
        ClangASTType ast_type(type_impl_sp->GetClangASTType(true));
        ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
        new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address, exe_ctx, ast_type);
    }
    sb_value.SetSP(new_value_sp);
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (new_value_sp)
            log->Printf ("SBValue(%p)::CreateValueFromAddress => \"%s\"",
                         static_cast<void*>(value_sp.get()),
                         new_value_sp->GetName().AsCString());
        else
            log->Printf ("SBValue(%p)::CreateValueFromAddress => NULL",
                         static_cast<void*>(value_sp.get()));
    }
    return sb_value;
}

lldb::SBValue
SBValue::CreateValueFromData (const char* name, SBData data, SBType type)
{
    lldb::SBValue sb_value;
    lldb::ValueObjectSP new_value_sp;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
        new_value_sp = ValueObject::CreateValueObjectFromData(name, **data, exe_ctx, type.GetSP()->GetClangASTType(true));
        new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
    }
    sb_value.SetSP(new_value_sp);
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (new_value_sp)
            log->Printf ("SBValue(%p)::CreateValueFromData => \"%s\"",
                         static_cast<void*>(value_sp.get()),
                         new_value_sp->GetName().AsCString());
        else
            log->Printf ("SBValue(%p)::CreateValueFromData => NULL",
                         static_cast<void*>(value_sp.get()));
    }
    return sb_value;
}

SBValue
SBValue::GetChildAtIndex (uint32_t idx)
{
    const bool can_create_synthetic = false;
    lldb::DynamicValueType use_dynamic = eNoDynamicValues;
    TargetSP target_sp;
    if (m_opaque_sp)
        target_sp = m_opaque_sp->GetTargetSP();
    
    if (target_sp)
        use_dynamic = target_sp->GetPreferDynamicValue();
    
    return GetChildAtIndex (idx, use_dynamic, can_create_synthetic);
}

SBValue
SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic)
{
    lldb::ValueObjectSP child_sp;
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        const bool can_create = true;
        child_sp = value_sp->GetChildAtIndex (idx, can_create);
        if (can_create_synthetic && !child_sp)
        {
            child_sp = value_sp->GetSyntheticArrayMember(idx, can_create);
        }
    }

    SBValue sb_value;
    sb_value.SetSP (child_sp, use_dynamic, GetPreferSyntheticValue());
    if (log)
        log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)",
                     static_cast<void*>(value_sp.get()), idx,
                     static_cast<void*>(value_sp.get()));

    return sb_value;
}

uint32_t
SBValue::GetIndexOfChildWithName (const char *name)
{
    uint32_t idx = UINT32_MAX;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        idx = value_sp->GetIndexOfChildWithName (ConstString(name));
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (idx == UINT32_MAX)
            log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND",
                         static_cast<void*>(value_sp.get()), name);
        else
            log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u",
                         static_cast<void*>(value_sp.get()), name, idx);
    }
    return idx;
}

SBValue
SBValue::GetChildMemberWithName (const char *name)
{
    lldb::DynamicValueType use_dynamic_value = eNoDynamicValues;
    TargetSP target_sp;
    if (m_opaque_sp)
        target_sp = m_opaque_sp->GetTargetSP();

    if (target_sp)
        use_dynamic_value = target_sp->GetPreferDynamicValue();
    return GetChildMemberWithName (name, use_dynamic_value);
}

SBValue
SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value)
{
    lldb::ValueObjectSP child_sp;
    const ConstString str_name (name);

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        child_sp = value_sp->GetChildMemberWithName (str_name, true);
    }

    SBValue sb_value;
    sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue());

    if (log)
        log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)",
                     static_cast<void*>(value_sp.get()), name,
                     static_cast<void*>(value_sp.get()));

    return sb_value;
}

lldb::SBValue
SBValue::GetDynamicValue (lldb::DynamicValueType use_dynamic)
{
    SBValue value_sb;
    if (IsValid())
    {
        ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),use_dynamic,m_opaque_sp->GetUseSynthetic()));
        value_sb.SetSP(proxy_sp);
    }
    return value_sb;
}

lldb::SBValue
SBValue::GetStaticValue ()
{
    SBValue value_sb;
    if (IsValid())
    {
        ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),eNoDynamicValues,m_opaque_sp->GetUseSynthetic()));
        value_sb.SetSP(proxy_sp);
    }
    return value_sb;
}

lldb::SBValue
SBValue::GetNonSyntheticValue ()
{
    SBValue value_sb;
    if (IsValid())
    {
        ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),m_opaque_sp->GetUseDynamic(),false));
        value_sb.SetSP(proxy_sp);
    }
    return value_sb;
}

lldb::DynamicValueType
SBValue::GetPreferDynamicValue ()
{
    if (!IsValid())
        return eNoDynamicValues;
    return m_opaque_sp->GetUseDynamic();
}

void
SBValue::SetPreferDynamicValue (lldb::DynamicValueType use_dynamic)
{
    if (IsValid())
        return m_opaque_sp->SetUseDynamic (use_dynamic);
}

bool
SBValue::GetPreferSyntheticValue ()
{
    if (!IsValid())
        return false;
    return m_opaque_sp->GetUseSynthetic();
}

void
SBValue::SetPreferSyntheticValue (bool use_synthetic)
{
    if (IsValid())
        return m_opaque_sp->SetUseSynthetic (use_synthetic);
}

bool
SBValue::IsDynamic()
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        return value_sp->IsDynamic();
    return false;
}

bool
SBValue::IsSynthetic ()
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        return value_sp->IsSynthetic();
    return false;
}

lldb::SBValue
SBValue::GetValueForExpressionPath(const char* expr_path)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    lldb::ValueObjectSP child_sp;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        // using default values for all the fancy options, just do it if you can
        child_sp = value_sp->GetValueForExpressionPath(expr_path);
    }

    SBValue sb_value;
    sb_value.SetSP(child_sp,GetPreferDynamicValue(),GetPreferSyntheticValue());

    if (log)
        log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)",
                     static_cast<void*>(value_sp.get()), expr_path,
                     static_cast<void*>(value_sp.get()));

    return sb_value;
}

int64_t
SBValue::GetValueAsSigned(SBError& error, int64_t fail_value)
{
    error.Clear();
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        bool success = true;
        uint64_t ret_val = fail_value;
        ret_val = value_sp->GetValueAsSigned(fail_value, &success);
        if (!success)
            error.SetErrorString("could not resolve value");
        return ret_val;
    }
    else
        error.SetErrorStringWithFormat ("could not get SBValue: %s", locker.GetError().AsCString());
    
    return fail_value;
}

uint64_t
SBValue::GetValueAsUnsigned(SBError& error, uint64_t fail_value)
{
    error.Clear();
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        bool success = true;
        uint64_t ret_val = fail_value;
        ret_val = value_sp->GetValueAsUnsigned(fail_value, &success);
        if (!success)
            error.SetErrorString("could not resolve value");
        return ret_val;
    }
    else
        error.SetErrorStringWithFormat ("could not get SBValue: %s", locker.GetError().AsCString());
    
    return fail_value;
}

int64_t
SBValue::GetValueAsSigned(int64_t fail_value)
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        return value_sp->GetValueAsSigned(fail_value);
    }
    return fail_value;
}

uint64_t
SBValue::GetValueAsUnsigned(uint64_t fail_value)
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        return value_sp->GetValueAsUnsigned(fail_value);
    }
    return fail_value;
}

bool
SBValue::MightHaveChildren ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    bool has_children = false;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        has_children = value_sp->MightHaveChildren();

    if (log)
        log->Printf ("SBValue(%p)::MightHaveChildren() => %i",
                     static_cast<void*>(value_sp.get()), has_children);
    return has_children;
}

bool
SBValue::IsRuntimeSupportValue ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    bool is_support = false;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        is_support = value_sp->IsRuntimeSupportValue();
    
    if (log)
        log->Printf ("SBValue(%p)::IsRuntimeSupportValue() => %i",
                     static_cast<void*>(value_sp.get()), is_support);
    return is_support;
}

uint32_t
SBValue::GetNumChildren ()
{
    uint32_t num_children = 0;

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        num_children = value_sp->GetNumChildren();

    if (log)
        log->Printf ("SBValue(%p)::GetNumChildren () => %u",
                     static_cast<void*>(value_sp.get()), num_children);

    return num_children;
}


SBValue
SBValue::Dereference ()
{
    SBValue sb_value;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        Error error;
        sb_value = value_sp->Dereference (error);
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)",
                     static_cast<void*>(value_sp.get()),
                     static_cast<void*>(value_sp.get()));

    return sb_value;
}

bool
SBValue::TypeIsPointerType ()
{
    bool is_ptr_type = false;

    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        is_ptr_type = value_sp->IsPointerType();

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBValue(%p)::TypeIsPointerType () => %i",
                     static_cast<void*>(value_sp.get()), is_ptr_type);

    return is_ptr_type;
}

void *
SBValue::GetOpaqueType()
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        return value_sp->GetClangType().GetOpaqueQualType();
    return NULL;
}

lldb::SBTarget
SBValue::GetTarget()
{
    SBTarget sb_target;
    TargetSP target_sp;
    if (m_opaque_sp)
    {
        target_sp = m_opaque_sp->GetTargetSP();
        sb_target.SetSP (target_sp);
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (target_sp.get() == NULL)
            log->Printf ("SBValue(%p)::GetTarget () => NULL",
                         static_cast<void*>(m_opaque_sp.get()));
        else
            log->Printf ("SBValue(%p)::GetTarget () => %p",
                         static_cast<void*>(m_opaque_sp.get()),
                         static_cast<void*>(target_sp.get()));
    }
    return sb_target;
}

lldb::SBProcess
SBValue::GetProcess()
{
    SBProcess sb_process;
    ProcessSP process_sp;
    if (m_opaque_sp)
    {
        process_sp = m_opaque_sp->GetProcessSP();
        sb_process.SetSP (process_sp);
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (process_sp.get() == NULL)
            log->Printf ("SBValue(%p)::GetProcess () => NULL",
                         static_cast<void*>(m_opaque_sp.get()));
        else
            log->Printf ("SBValue(%p)::GetProcess () => %p",
                         static_cast<void*>(m_opaque_sp.get()),
                         static_cast<void*>(process_sp.get()));
    }
    return sb_process;
}

lldb::SBThread
SBValue::GetThread()
{
    SBThread sb_thread;
    ThreadSP thread_sp;
    if (m_opaque_sp)
    {
        thread_sp = m_opaque_sp->GetThreadSP();
        sb_thread.SetThread(thread_sp);
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (thread_sp.get() == NULL)
            log->Printf ("SBValue(%p)::GetThread () => NULL",
                         static_cast<void*>(m_opaque_sp.get()));
        else
            log->Printf ("SBValue(%p)::GetThread () => %p",
                         static_cast<void*>(m_opaque_sp.get()),
                         static_cast<void*>(thread_sp.get()));
    }
    return sb_thread;
}

lldb::SBFrame
SBValue::GetFrame()
{
    SBFrame sb_frame;
    StackFrameSP frame_sp;
    if (m_opaque_sp)
    {
        frame_sp = m_opaque_sp->GetFrameSP();
        sb_frame.SetFrameSP (frame_sp);
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        if (frame_sp.get() == NULL)
            log->Printf ("SBValue(%p)::GetFrame () => NULL",
                         static_cast<void*>(m_opaque_sp.get()));
        else
            log->Printf ("SBValue(%p)::GetFrame () => %p",
                         static_cast<void*>(m_opaque_sp.get()),
                         static_cast<void*>(frame_sp.get()));
    }
    return sb_frame;
}


lldb::ValueObjectSP
SBValue::GetSP (ValueLocker &locker) const
{
    if (!m_opaque_sp || !m_opaque_sp->IsValid())
        return ValueObjectSP();
    return locker.GetLockedSP(*m_opaque_sp.get());
}

lldb::ValueObjectSP
SBValue::GetSP () const
{
    ValueLocker locker;
    return GetSP(locker);
}

void
SBValue::SetSP (ValueImplSP impl_sp)
{
    m_opaque_sp = impl_sp;
}

void
SBValue::SetSP (const lldb::ValueObjectSP &sp)
{
    if (sp)
    {
        lldb::TargetSP target_sp(sp->GetTargetSP());
        if (target_sp)
        {
            lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
            bool use_synthetic = target_sp->TargetProperties::GetEnableSyntheticValue();
            m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic));
        }
        else
            m_opaque_sp = ValueImplSP(new ValueImpl(sp,eNoDynamicValues,true));
    }
    else
        m_opaque_sp = ValueImplSP(new ValueImpl(sp,eNoDynamicValues,false));
}

void
SBValue::SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic)
{
    if (sp)
    {
        lldb::TargetSP target_sp(sp->GetTargetSP());
        if (target_sp)
        {
            bool use_synthetic = target_sp->TargetProperties::GetEnableSyntheticValue();
            SetSP (sp, use_dynamic, use_synthetic);
        }
        else
            SetSP (sp, use_dynamic, true);
    }
    else
        SetSP (sp, use_dynamic, false);
}

void
SBValue::SetSP (const lldb::ValueObjectSP &sp, bool use_synthetic)
{
    if (sp)
    {
        lldb::TargetSP target_sp(sp->GetTargetSP());
        if (target_sp)
        {
            lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
            SetSP (sp, use_dynamic, use_synthetic);
        }
        else
            SetSP (sp, eNoDynamicValues, use_synthetic);
    }
    else
        SetSP (sp, eNoDynamicValues, use_synthetic);
}

void
SBValue::SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic, bool use_synthetic)
{
    m_opaque_sp = ValueImplSP(new ValueImpl(sp,use_dynamic,use_synthetic));
}

void
SBValue::SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic, bool use_synthetic, const char *name)
{
    m_opaque_sp = ValueImplSP(new ValueImpl(sp,use_dynamic,use_synthetic, name));
}

bool
SBValue::GetExpressionPath (SBStream &description)
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        value_sp->GetExpressionPath (description.ref(), false);
        return true;
    }
    return false;
}

bool
SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes)
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        value_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes);
        return true;
    }
    return false;
}

bool
SBValue::GetDescription (SBStream &description)
{
    Stream &strm = description.ref();
    
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        value_sp->Dump(strm);
    else
        strm.PutCString ("No value");
    
    return true;
}

lldb::Format
SBValue::GetFormat ()
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        return value_sp->GetFormat();
    return eFormatDefault;
}

void
SBValue::SetFormat (lldb::Format format)
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        value_sp->SetFormat(format);
}

lldb::SBValue
SBValue::AddressOf()
{
    SBValue sb_value;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        Error error;
        sb_value.SetSP(value_sp->AddressOf (error),GetPreferDynamicValue(), GetPreferSyntheticValue());
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBValue(%p)::AddressOf () => SBValue(%p)",
                     static_cast<void*>(value_sp.get()),
                     static_cast<void*>(value_sp.get()));

    return sb_value;
}

lldb::addr_t
SBValue::GetLoadAddress()
{
    lldb::addr_t value = LLDB_INVALID_ADDRESS;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        TargetSP target_sp (value_sp->GetTargetSP());
        if (target_sp)
        {
            const bool scalar_is_load_address = true;
            AddressType addr_type;
            value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
            if (addr_type == eAddressTypeFile)
            {
                ModuleSP module_sp (value_sp->GetModule());
                if (!module_sp)
                    value = LLDB_INVALID_ADDRESS;
                else
                {
                    Address addr;
                    module_sp->ResolveFileAddress(value, addr);
                    value = addr.GetLoadAddress(target_sp.get());
                }
            }
            else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeInvalid)
                value = LLDB_INVALID_ADDRESS;
        }
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBValue(%p)::GetLoadAddress () => (%" PRIu64 ")",
                     static_cast<void*>(value_sp.get()), value);

    return value;
}

lldb::SBAddress
SBValue::GetAddress()
{
    Address addr;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        TargetSP target_sp (value_sp->GetTargetSP());
        if (target_sp)
        {
            lldb::addr_t value = LLDB_INVALID_ADDRESS;
            const bool scalar_is_load_address = true;
            AddressType addr_type;
            value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
            if (addr_type == eAddressTypeFile)
            {
                ModuleSP module_sp (value_sp->GetModule());
                if (module_sp)
                    module_sp->ResolveFileAddress(value, addr);
            }
            else if (addr_type == eAddressTypeLoad)
            {
                // no need to check the return value on this.. if it can actually do the resolve
                // addr will be in the form (section,offset), otherwise it will simply be returned
                // as (NULL, value)
                addr.SetLoadAddress(value, target_sp.get());
            }
        }
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBValue(%p)::GetAddress () => (%s,%" PRIu64 ")",
                     static_cast<void*>(value_sp.get()),
                     (addr.GetSection()
                        ? addr.GetSection()->GetName().GetCString()
                        : "NULL"),
                     addr.GetOffset());
    return SBAddress(new Address(addr));
}

lldb::SBData
SBValue::GetPointeeData (uint32_t item_idx,
                         uint32_t item_count)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    lldb::SBData sb_data;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        TargetSP target_sp (value_sp->GetTargetSP());
        if (target_sp)
        {
            DataExtractorSP data_sp(new DataExtractor());
            value_sp->GetPointeeData(*data_sp, item_idx, item_count);
            if (data_sp->GetByteSize() > 0)
                *sb_data = data_sp;
        }
    }
    if (log)
        log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)",
                     static_cast<void*>(value_sp.get()), item_idx, item_count,
                     static_cast<void*>(sb_data.get()));

    return sb_data;
}

lldb::SBData
SBValue::GetData ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    lldb::SBData sb_data;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
    {
        DataExtractorSP data_sp(new DataExtractor());
        Error error;
        value_sp->GetData(*data_sp, error);
        if (error.Success())
            *sb_data = data_sp;
    }
    if (log)
        log->Printf ("SBValue(%p)::GetData () => SBData(%p)",
                     static_cast<void*>(value_sp.get()),
                     static_cast<void*>(sb_data.get()));

    return sb_data;
}

bool
SBValue::SetData (lldb::SBData &data, SBError &error)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    bool ret = true;

    if (value_sp)
    {
        DataExtractor *data_extractor = data.get();

        if (!data_extractor)
        {
            if (log)
                log->Printf ("SBValue(%p)::SetData() => error: no data to set",
                             static_cast<void*>(value_sp.get()));

            error.SetErrorString("No data to set");
            ret = false;
        }
        else
        {
            Error set_error;

            value_sp->SetData(*data_extractor, set_error);

            if (!set_error.Success())
            {
                error.SetErrorStringWithFormat("Couldn't set data: %s", set_error.AsCString());
                ret = false;
            }
        }
    }
    else
    {
        error.SetErrorStringWithFormat ("Couldn't set data: could not get SBValue: %s", locker.GetError().AsCString());
        ret = false;
    }

    if (log)
        log->Printf ("SBValue(%p)::SetData (%p) => %s",
                     static_cast<void*>(value_sp.get()),
                     static_cast<void*>(data.get()), ret ? "true" : "false");
    return ret;
}

lldb::SBDeclaration
SBValue::GetDeclaration ()
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    SBDeclaration decl_sb;
    if (value_sp)
    {
        Declaration decl;
        if (value_sp->GetDeclaration(decl))
            decl_sb.SetDeclaration(decl);
    }
    return decl_sb;
}

lldb::SBWatchpoint
SBValue::Watch (bool resolve_location, bool read, bool write, SBError &error)
{
    SBWatchpoint sb_watchpoint;

    // If the SBValue is not valid, there's no point in even trying to watch it.
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    TargetSP target_sp (GetTarget().GetSP());
    if (value_sp && target_sp)
    {
        // Read and Write cannot both be false.
        if (!read && !write)
            return sb_watchpoint;

        // If the value is not in scope, don't try and watch and invalid value
        if (!IsInScope())
            return sb_watchpoint;

        addr_t addr = GetLoadAddress();
        if (addr == LLDB_INVALID_ADDRESS)
            return sb_watchpoint;
        size_t byte_size = GetByteSize();
        if (byte_size == 0)
            return sb_watchpoint;

        uint32_t watch_type = 0;
        if (read)
            watch_type |= LLDB_WATCH_TYPE_READ;
        if (write)
            watch_type |= LLDB_WATCH_TYPE_WRITE;

        Error rc;
        ClangASTType type (value_sp->GetClangType());
        WatchpointSP watchpoint_sp = target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc);
        error.SetError(rc);

        if (watchpoint_sp)
        {
            sb_watchpoint.SetSP (watchpoint_sp);
            Declaration decl;
            if (value_sp->GetDeclaration (decl))
            {
                if (decl.GetFile())
                {
                    StreamString ss;
                    // True to show fullpath for declaration file.
                    decl.DumpStopContext(&ss, true);
                    watchpoint_sp->SetDeclInfo(ss.GetString());
                }
            }
        }
    }
    else if (target_sp)
    {
        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
        if (log)
            log->Printf ("SBValue(%p)::Watch() => error getting SBValue: %s",
                         static_cast<void*>(value_sp.get()),
                         locker.GetError().AsCString());

        error.SetErrorStringWithFormat("could not get SBValue: %s", locker.GetError().AsCString());
    }
    else
    {
        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
        if (log)
            log->Printf ("SBValue(%p)::Watch() => error getting SBValue: no target",
                         static_cast<void*>(value_sp.get()));
        error.SetErrorString("could not set watchpoint, a target is required");
    }

    return sb_watchpoint;
}

// FIXME: Remove this method impl (as well as the decl in .h) once it is no longer needed.
// Backward compatibility fix in the interim.
lldb::SBWatchpoint
SBValue::Watch (bool resolve_location, bool read, bool write)
{
    SBError error;
    return Watch(resolve_location, read, write, error);
}

lldb::SBWatchpoint
SBValue::WatchPointee (bool resolve_location, bool read, bool write, SBError &error)
{
    SBWatchpoint sb_watchpoint;
    if (IsInScope() && GetType().IsPointerType())
        sb_watchpoint = Dereference().Watch (resolve_location, read, write, error);
    return sb_watchpoint;
}

lldb::SBValue
SBValue::Persist ()
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    SBValue persisted_sb;
    if (value_sp)
    {
        persisted_sb.SetSP(value_sp->Persist());
    }
    return persisted_sb;
}
