//===-- 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, Mutex::Locker &api_locker, Error &error)
    {
        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
        if (!m_valobj_sp)
        {
            error.SetErrorString("invalid value object");
            return m_valobj_sp;
        }

        lldb::ValueObjectSP value_sp = m_valobj_sp;

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

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

        if (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_api_locker, m_lock_error);
    }
    
    Error &
    GetError()
    {
        return m_lock_error;
    }
    
private:
    Process::StopLocker m_stop_locker;
    Mutex::Locker m_api_locker;
    Error m_lock_error;
    
};

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

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

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

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

SBValue::~SBValue()
{
}

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

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

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

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

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

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

    return name;
}

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

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

    return name;
}

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

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

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

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

    return result;
}

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

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

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

    return result;
}

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

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

    return cstr;
}

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

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

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

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

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

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

    return result;
}

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

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