374 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			374 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- SBBlock.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/SBBlock.h"
 | 
						|
#include "lldb/API/SBAddress.h"
 | 
						|
#include "lldb/API/SBFileSpec.h"
 | 
						|
#include "lldb/API/SBFrame.h"
 | 
						|
#include "lldb/API/SBStream.h"
 | 
						|
#include "lldb/API/SBValue.h"
 | 
						|
#include "lldb/Core/AddressRange.h"
 | 
						|
#include "lldb/Core/Log.h"
 | 
						|
#include "lldb/Core/ValueObjectVariable.h"
 | 
						|
#include "lldb/Symbol/Block.h"
 | 
						|
#include "lldb/Symbol/Function.h"
 | 
						|
#include "lldb/Symbol/SymbolContext.h"
 | 
						|
#include "lldb/Symbol/VariableList.h"
 | 
						|
#include "lldb/Target/StackFrame.h"
 | 
						|
#include "lldb/Target/Target.h"
 | 
						|
 | 
						|
using namespace lldb;
 | 
						|
using namespace lldb_private;
 | 
						|
 | 
						|
 | 
						|
SBBlock::SBBlock () :
 | 
						|
    m_opaque_ptr (NULL)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
SBBlock::SBBlock (lldb_private::Block *lldb_object_ptr) :
 | 
						|
    m_opaque_ptr (lldb_object_ptr)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
SBBlock::SBBlock(const SBBlock &rhs) :
 | 
						|
    m_opaque_ptr (rhs.m_opaque_ptr)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
const SBBlock &
 | 
						|
SBBlock::operator = (const SBBlock &rhs)
 | 
						|
{
 | 
						|
    m_opaque_ptr = rhs.m_opaque_ptr;
 | 
						|
    return *this;
 | 
						|
}
 | 
						|
 | 
						|
SBBlock::~SBBlock ()
 | 
						|
{
 | 
						|
    m_opaque_ptr = NULL;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
SBBlock::IsValid () const
 | 
						|
{
 | 
						|
    return m_opaque_ptr != NULL;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
SBBlock::IsInlined () const
 | 
						|
{
 | 
						|
    if (m_opaque_ptr)
 | 
						|
        return m_opaque_ptr->GetInlinedFunctionInfo () != NULL;
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
const char *
 | 
						|
SBBlock::GetInlinedName () const
 | 
						|
{
 | 
						|
    if (m_opaque_ptr)
 | 
						|
    {
 | 
						|
        const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo ();
 | 
						|
        if (inlined_info)
 | 
						|
            return inlined_info->GetName().AsCString (NULL);
 | 
						|
    }
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
SBFileSpec
 | 
						|
SBBlock::GetInlinedCallSiteFile () const
 | 
						|
{
 | 
						|
    SBFileSpec sb_file;
 | 
						|
    if (m_opaque_ptr)
 | 
						|
    {
 | 
						|
        const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo ();
 | 
						|
        if (inlined_info)
 | 
						|
            sb_file.SetFileSpec (inlined_info->GetCallSite().GetFile());
 | 
						|
    }
 | 
						|
    return sb_file;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t
 | 
						|
SBBlock::GetInlinedCallSiteLine () const
 | 
						|
{
 | 
						|
    if (m_opaque_ptr)
 | 
						|
    {
 | 
						|
        const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo ();
 | 
						|
        if (inlined_info)
 | 
						|
            return inlined_info->GetCallSite().GetLine();
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t
 | 
						|
SBBlock::GetInlinedCallSiteColumn () const
 | 
						|
{
 | 
						|
    if (m_opaque_ptr)
 | 
						|
    {
 | 
						|
        const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo ();
 | 
						|
        if (inlined_info)
 | 
						|
            return inlined_info->GetCallSite().GetColumn();
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
SBBlock::AppendVariables (bool can_create, bool get_parent_variables, lldb_private::VariableList *var_list)
 | 
						|
{
 | 
						|
    if (IsValid())
 | 
						|
    {
 | 
						|
        bool show_inline = true;
 | 
						|
        m_opaque_ptr->AppendVariables (can_create, get_parent_variables, show_inline, var_list);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
SBBlock
 | 
						|
SBBlock::GetParent ()
 | 
						|
{
 | 
						|
    SBBlock sb_block;
 | 
						|
    if (m_opaque_ptr)
 | 
						|
        sb_block.m_opaque_ptr = m_opaque_ptr->GetParent();
 | 
						|
    return sb_block;
 | 
						|
}
 | 
						|
 | 
						|
lldb::SBBlock
 | 
						|
SBBlock::GetContainingInlinedBlock  ()
 | 
						|
{
 | 
						|
    SBBlock sb_block;
 | 
						|
    if (m_opaque_ptr)
 | 
						|
        sb_block.m_opaque_ptr = m_opaque_ptr->GetContainingInlinedBlock ();
 | 
						|
    return sb_block;
 | 
						|
}
 | 
						|
 | 
						|
SBBlock
 | 
						|
SBBlock::GetSibling ()
 | 
						|
{
 | 
						|
    SBBlock sb_block;
 | 
						|
    if (m_opaque_ptr)
 | 
						|
        sb_block.m_opaque_ptr = m_opaque_ptr->GetSibling();
 | 
						|
    return sb_block;
 | 
						|
}
 | 
						|
 | 
						|
SBBlock
 | 
						|
SBBlock::GetFirstChild ()
 | 
						|
{
 | 
						|
    SBBlock sb_block;
 | 
						|
    if (m_opaque_ptr)
 | 
						|
        sb_block.m_opaque_ptr = m_opaque_ptr->GetFirstChild();
 | 
						|
    return sb_block;
 | 
						|
}
 | 
						|
 | 
						|
lldb_private::Block *
 | 
						|
SBBlock::GetPtr ()
 | 
						|
{
 | 
						|
    return m_opaque_ptr;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
SBBlock::SetPtr (lldb_private::Block *block)
 | 
						|
{
 | 
						|
    m_opaque_ptr = block;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
SBBlock::GetDescription (SBStream &description)
 | 
						|
{
 | 
						|
    Stream &strm = description.ref();
 | 
						|
 | 
						|
    if (m_opaque_ptr)
 | 
						|
    {
 | 
						|
        lldb::user_id_t id = m_opaque_ptr->GetID();
 | 
						|
        strm.Printf ("Block: {id: %" PRIu64 "} ", id);
 | 
						|
        if (IsInlined())
 | 
						|
        {
 | 
						|
            strm.Printf (" (inlined, '%s') ", GetInlinedName());
 | 
						|
        }
 | 
						|
        lldb_private::SymbolContext sc;
 | 
						|
        m_opaque_ptr->CalculateSymbolContext (&sc);
 | 
						|
        if (sc.function)
 | 
						|
        {
 | 
						|
            m_opaque_ptr->DumpAddressRanges (&strm,
 | 
						|
                                             sc.function->GetAddressRange().GetBaseAddress().GetFileAddress());
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else
 | 
						|
        strm.PutCString ("No value");
 | 
						|
    
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t
 | 
						|
SBBlock::GetNumRanges ()
 | 
						|
{
 | 
						|
    if (m_opaque_ptr)
 | 
						|
        return m_opaque_ptr->GetNumRanges();
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
lldb::SBAddress
 | 
						|
SBBlock::GetRangeStartAddress (uint32_t idx)
 | 
						|
{
 | 
						|
    lldb::SBAddress sb_addr;
 | 
						|
    if (m_opaque_ptr)
 | 
						|
    {
 | 
						|
        AddressRange range;
 | 
						|
        if (m_opaque_ptr->GetRangeAtIndex(idx, range))
 | 
						|
        {
 | 
						|
            sb_addr.ref() = range.GetBaseAddress();
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return sb_addr;
 | 
						|
}
 | 
						|
 | 
						|
lldb::SBAddress
 | 
						|
SBBlock::GetRangeEndAddress (uint32_t idx)
 | 
						|
{
 | 
						|
    lldb::SBAddress sb_addr;
 | 
						|
    if (m_opaque_ptr)
 | 
						|
    {
 | 
						|
        AddressRange range;
 | 
						|
        if (m_opaque_ptr->GetRangeAtIndex(idx, range))
 | 
						|
        {
 | 
						|
            sb_addr.ref() = range.GetBaseAddress();
 | 
						|
            sb_addr.ref().Slide(range.GetByteSize());
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return sb_addr;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t
 | 
						|
SBBlock::GetRangeIndexForBlockAddress (lldb::SBAddress block_addr)
 | 
						|
{
 | 
						|
    if (m_opaque_ptr && block_addr.IsValid())
 | 
						|
    {
 | 
						|
        return m_opaque_ptr->GetRangeIndexContainingAddress (block_addr.ref());
 | 
						|
    }
 | 
						|
 | 
						|
    return UINT32_MAX;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
lldb::SBValueList
 | 
						|
SBBlock::GetVariables (lldb::SBFrame& frame,
 | 
						|
                       bool arguments,
 | 
						|
                       bool locals,
 | 
						|
                       bool statics,
 | 
						|
                       lldb::DynamicValueType use_dynamic)
 | 
						|
{
 | 
						|
    Block *block = GetPtr();
 | 
						|
    SBValueList value_list;
 | 
						|
    if (block)
 | 
						|
    {
 | 
						|
        StackFrameSP frame_sp(frame.GetFrameSP());
 | 
						|
        VariableListSP variable_list_sp (block->GetBlockVariableList (true));
 | 
						|
 | 
						|
        if (variable_list_sp)
 | 
						|
        {
 | 
						|
            const size_t num_variables = variable_list_sp->GetSize();
 | 
						|
            if (num_variables)
 | 
						|
            {
 | 
						|
                for (size_t i = 0; i < num_variables; ++i)
 | 
						|
                {
 | 
						|
                    VariableSP variable_sp (variable_list_sp->GetVariableAtIndex(i));
 | 
						|
                    if (variable_sp)
 | 
						|
                    {
 | 
						|
                        bool add_variable = false;
 | 
						|
                        switch (variable_sp->GetScope())
 | 
						|
                        {
 | 
						|
                            case eValueTypeVariableGlobal:
 | 
						|
                            case eValueTypeVariableStatic:
 | 
						|
                                add_variable = statics;
 | 
						|
                                break;
 | 
						|
                                
 | 
						|
                            case eValueTypeVariableArgument:
 | 
						|
                                add_variable = arguments;
 | 
						|
                                break;
 | 
						|
                                
 | 
						|
                            case eValueTypeVariableLocal:
 | 
						|
                                add_variable = locals;
 | 
						|
                                break;
 | 
						|
                                
 | 
						|
                            default:
 | 
						|
                                break;
 | 
						|
                        }
 | 
						|
                        if (add_variable)
 | 
						|
                        {
 | 
						|
                            if (frame_sp)
 | 
						|
                            {
 | 
						|
                                lldb::ValueObjectSP valobj_sp(frame_sp->GetValueObjectForFrameVariable (variable_sp,eNoDynamicValues));
 | 
						|
                                SBValue value_sb;
 | 
						|
                                value_sb.SetSP(valobj_sp, use_dynamic);
 | 
						|
                                value_list.Append (value_sb);
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }        
 | 
						|
    }
 | 
						|
    return value_list;
 | 
						|
}
 | 
						|
 | 
						|
lldb::SBValueList
 | 
						|
SBBlock::GetVariables (lldb::SBTarget& target,
 | 
						|
                       bool arguments,
 | 
						|
                       bool locals,
 | 
						|
                       bool statics)
 | 
						|
{
 | 
						|
    Block *block = GetPtr();
 | 
						|
    
 | 
						|
    SBValueList value_list;
 | 
						|
    if (block)
 | 
						|
    {
 | 
						|
        TargetSP target_sp(target.GetSP());
 | 
						|
        
 | 
						|
        VariableListSP variable_list_sp (block->GetBlockVariableList (true));
 | 
						|
        
 | 
						|
        if (variable_list_sp)
 | 
						|
        {
 | 
						|
            const size_t num_variables = variable_list_sp->GetSize();
 | 
						|
            if (num_variables)
 | 
						|
            {
 | 
						|
                for (size_t i = 0; i < num_variables; ++i)
 | 
						|
                {
 | 
						|
                    VariableSP variable_sp (variable_list_sp->GetVariableAtIndex(i));
 | 
						|
                    if (variable_sp)
 | 
						|
                    {
 | 
						|
                        bool add_variable = false;
 | 
						|
                        switch (variable_sp->GetScope())
 | 
						|
                        {
 | 
						|
                            case eValueTypeVariableGlobal:
 | 
						|
                            case eValueTypeVariableStatic:
 | 
						|
                                add_variable = statics;
 | 
						|
                                break;
 | 
						|
                                
 | 
						|
                            case eValueTypeVariableArgument:
 | 
						|
                                add_variable = arguments;
 | 
						|
                                break;
 | 
						|
                                
 | 
						|
                            case eValueTypeVariableLocal:
 | 
						|
                                add_variable = locals;
 | 
						|
                                break;
 | 
						|
                                
 | 
						|
                            default:
 | 
						|
                                break;
 | 
						|
                        }
 | 
						|
                        if (add_variable)
 | 
						|
                        {
 | 
						|
                            if (target_sp)
 | 
						|
                                value_list.Append (ValueObjectVariable::Create (target_sp.get(), variable_sp));
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }        
 | 
						|
    return value_list;
 | 
						|
}
 | 
						|
 |