//===-- 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 ()
    {
        return m_valobj_sp.get() != NULL;
    }
    
    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());
        
        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", 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->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\"", value_sp.get(), name);
        else
            log->Printf ("SBValue(%p)::GetName () => NULL", 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\"", value_sp.get(), name);
        else
            log->Printf ("SBValue(%p)::GetTypeName () => NULL", 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, value_sp.get(), (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", 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\"", value_sp.get(), cstr);
        else
            log->Printf ("SBValue(%p)::GetValue() => NULL", 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", value_sp.get()); break;
            case eValueTypeVariableGlobal:  log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", value_sp.get()); break;
            case eValueTypeVariableStatic:  log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", value_sp.get()); break;
            case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", value_sp.get()); break;
            case eValueTypeVariableLocal:   log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", value_sp.get()); break;
            case eValueTypeRegister:        log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", value_sp.get()); break;
            case eValueTypeRegisterSet:     log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", value_sp.get()); break;
            case eValueTypeConstResult:     log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", 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\"", value_sp.get(), cstr);
        else
            log->Printf ("SBValue(%p)::GetObjectDescription() => NULL", 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)", value_sp.get(), type_sp.get());
        else
            log->Printf ("SBValue(%p)::GetType => NULL", 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)
    {
        result = value_sp->GetValueDidChange ();
    }
    if (log)
        log->Printf ("SBValue(%p)::GetValueDidChange() => %i", 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\"", value_sp.get(), cstr);
        else
            log->Printf ("SBValue(%p)::GetSummary() => NULL", 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\"", value_sp.get(), cstr);
        else
            log->Printf ("SBValue(%p)::GetLocation() => NULL", 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", 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\"",
                         value_sp.get(),
                         new_value_sp->GetName().AsCString());
        else
            log->Printf ("SBValue(%p)::CreateChildAtOffset => NULL",
                         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());
        Target* target = exe_ctx.GetTargetPtr();
        if (target)
        {
            options.ref().SetKeepInMemory(true);
            target->EvaluateExpression (expression,
                                        exe_ctx.GetFramePtr(),
                                        new_value_sp,
                                        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)",
                         value_sp.get(),
                         name,
                         expression,
                         new_value_sp.get());
        else
            log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => NULL",
                         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 pointer_ast_type(type_impl_sp->GetClangASTType(false).GetPointerType ());
        if (pointer_ast_type)
        {
            lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
            
            ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
            ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
                                                                               pointer_ast_type,
                                                                               ConstString(name),
                                                                               buffer,
                                                                               exe_ctx.GetByteOrder(),
                                                                               exe_ctx.GetAddressByteSize()));
            
            if (ptr_result_valobj_sp)
            {
                ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
                Error err;
                new_value_sp = ptr_result_valobj_sp->Dereference(err);
                if (new_value_sp)
                    new_value_sp->SetName(ConstString(name));
            }
            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\"", value_sp.get(), new_value_sp->GetName().AsCString());
        else
            log->Printf ("SBValue(%p)::CreateValueFromAddress => NULL", 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 = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
                                                       type.m_opaque_sp->GetClangASTType(false),
                                                       ConstString(name),
                                                       *data.m_opaque_sp,
                                                       LLDB_INVALID_ADDRESS);
        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\"", value_sp.get(), new_value_sp->GetName().AsCString());
        else
            log->Printf ("SBValue(%p)::CreateValueFromData => NULL", 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)
        {
            if (value_sp->IsPointerType())
            {
                child_sp = value_sp->GetSyntheticArrayMemberFromPointer(idx, can_create);
            }
            else if (value_sp->IsArrayType())
            {
                child_sp = value_sp->GetSyntheticArrayMemberFromArray(idx, can_create);
            }
        }
    }
    
    SBValue sb_value;
    sb_value.SetSP (child_sp, use_dynamic, GetPreferSyntheticValue());
    if (log)
        log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", value_sp.get(), idx, 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", value_sp.get(), name);
        else
            log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", 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)", value_sp.get(), name, 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)", value_sp.get(), expr_path, 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", value_sp.get(), has_children);
    return has_children;
}

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", 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)", value_sp.get(), 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", 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", m_opaque_sp.get());
        else
            log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), 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", m_opaque_sp.get());
        else
            log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), 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", m_opaque_sp.get());
        else
            log->Printf ("SBValue(%p)::GetThread () => %p", m_opaque_sp.get(), 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", m_opaque_sp.get());
        else
            log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), 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)", value_sp.get(), 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 ")", 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 ")", 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)",
                     value_sp.get(),
                     item_idx,
                     item_count,
                     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());
        value_sp->GetData(*data_sp);
        if (data_sp->GetByteSize() > 0)
            *sb_data = data_sp;
    }
    if (log)
        log->Printf ("SBValue(%p)::GetData () => SBData(%p)",
                     value_sp.get(),
                     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", 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",
                     value_sp.get(),
                     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", 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", 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;
}
