//===-- 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/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(),
    m_use_dynamic(use_dynamic),
    m_use_synthetic(use_synthetic),
    m_name (name)
    {
        if (in_valobj_sp)
        {
            if ( (m_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(lldb::eNoDynamicValues, false)) )
            {
                if (!m_name.IsEmpty())
                    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, std::unique_lock<std::recursive_mutex> &lock, 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)
            return ValueObjectSP();

        lock = std::unique_lock<std::recursive_mutex>(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",
                             static_cast<void*>(value_sp.get()));
            error.SetErrorString ("process must be stopped.");
            return ValueObjectSP();
        }

        if (m_use_dynamic != eNoDynamicValues)
        {
            ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(m_use_dynamic);
            if (dynamic_sp)
                value_sp = dynamic_sp;
        }

        if (m_use_synthetic)
        {
            ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue(m_use_synthetic);
            if (synthetic_sp)
                value_sp = synthetic_sp;
        }

        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_lock, m_lock_error);
    }

    Error &
    GetError()
    {
        return m_lock_error;
    }
    
private:
    Process::StopLocker m_stop_locker;
    std::unique_lock<std::recursive_mutex> m_lock;
    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;
            case eValueTypeVariableThreadLocal:
                log->Printf("SBValue(%p)::GetValueType () => eValueTypeVariableThreadLocal",
                            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;
}

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;
}

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;
}

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;
}

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->GetCompilerType(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->GetCompilerType(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)
    {
        CompilerType ast_type(type_impl_sp->GetCompilerType(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 sb_type)
{
    lldb::SBValue sb_value;
    lldb::ValueObjectSP new_value_sp;
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    lldb::TypeImplSP type_impl_sp (sb_type.GetSP());
    if (value_sp && type_impl_sp)
    {
        ExecutionContext exe_ctx (value_sp->GetExecutionContextRef());
        new_value_sp = ValueObject::CreateValueObjectFromData(name, **data, exe_ctx, type_impl_sp->GetCompilerType(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;
}

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

void
SBValue::SetSyntheticChildrenGenerated (bool is)
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        return value_sp->SetSyntheticChildrenGenerated(is);
}

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 ()
{
    return GetNumChildren (UINT32_MAX);
}

uint32_t
SBValue::GetNumChildren (uint32_t max)
{
    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(max);

    if (log)
        log->Printf ("SBValue(%p)::GetNumChildren (%u) => %u",
                     static_cast<void*>(value_sp.get()), max, 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;
}

// Deprecated - please use GetType().IsPointerType() instead.
bool
SBValue::TypeIsPointerType ()
{
    return GetType().IsPointerType();
}

void *
SBValue::GetOpaqueType()
{
    ValueLocker locker;
    lldb::ValueObjectSP value_sp(GetSP(locker));
    if (value_sp)
        return value_sp->GetCompilerType().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())
    {
        locker.GetError().SetErrorString("No value");
        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;
        CompilerType type (value_sp->GetCompilerType());
        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;
}
