lldb-59.
llvm-svn: 132304
This commit is contained in:
@@ -124,8 +124,9 @@ public:
|
|||||||
/// @param[in] length
|
/// @param[in] length
|
||||||
/// The length in bytes of the subset of data.
|
/// The length in bytes of the subset of data.
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
DataExtractor (const DataExtractor& data, uint32_t offset = 0, uint32_t length = UINT32_MAX);
|
DataExtractor (const DataExtractor& data, uint32_t offset, uint32_t length);
|
||||||
|
|
||||||
|
DataExtractor (const DataExtractor& rhs);
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
/// Assignment operator.
|
/// Assignment operator.
|
||||||
///
|
///
|
||||||
@@ -1086,7 +1087,7 @@ public:
|
|||||||
/// The number of bytes that this object now contains.
|
/// The number of bytes that this object now contains.
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
uint32_t
|
uint32_t
|
||||||
SetData (const DataExtractor& data, uint32_t offset = 0, uint32_t length = UINT32_MAX);
|
SetData (const DataExtractor& data, uint32_t offset, uint32_t length);
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
/// Adopt a subset of shared data in \a data_sp.
|
/// Adopt a subset of shared data in \a data_sp.
|
||||||
|
|||||||
@@ -236,6 +236,9 @@ public:
|
|||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
IsPointerOrReferenceType ();
|
IsPointerOrReferenceType ();
|
||||||
|
|
||||||
|
virtual bool
|
||||||
|
IsPossibleCPlusPlusDynamicType ();
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
IsBaseClass ()
|
IsBaseClass ()
|
||||||
|
|||||||
@@ -304,6 +304,13 @@ public:
|
|||||||
void
|
void
|
||||||
SetExpressionDeclMap (ClangExpressionDeclMap *decl_map);
|
SetExpressionDeclMap (ClangExpressionDeclMap *decl_map);
|
||||||
|
|
||||||
|
bool
|
||||||
|
GetExpressionData (DataExtractor &data) const
|
||||||
|
{
|
||||||
|
data = m_data;
|
||||||
|
return data.GetByteSize() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
/// Pretty-prints the location expression to a stream
|
/// Pretty-prints the location expression to a stream
|
||||||
|
|||||||
@@ -612,6 +612,11 @@ public:
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
IsPointerOrReferenceType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type = NULL);
|
IsPointerOrReferenceType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type = NULL);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast,
|
||||||
|
lldb::clang_type_t clang_type,
|
||||||
|
lldb::clang_type_t *target_type = NULL);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
IsCStringType (lldb::clang_type_t clang_type, uint32_t &length);
|
IsCStringType (lldb::clang_type_t clang_type, uint32_t &length);
|
||||||
|
|||||||
@@ -120,6 +120,21 @@ public:
|
|||||||
bool
|
bool
|
||||||
IsInScope (StackFrame *frame);
|
IsInScope (StackFrame *frame);
|
||||||
|
|
||||||
|
bool
|
||||||
|
LocationIsValidForFrame (StackFrame *frame);
|
||||||
|
|
||||||
|
bool
|
||||||
|
GetLocationIsConstantValueData () const
|
||||||
|
{
|
||||||
|
return m_loc_is_const_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SetLocationIsConstantValueData (bool b)
|
||||||
|
{
|
||||||
|
m_loc_is_const_data = b;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ConstString m_name; // The basename of the variable (no namespaces)
|
ConstString m_name; // The basename of the variable (no namespaces)
|
||||||
Mangled m_mangled; // The mangled name of hte variable
|
Mangled m_mangled; // The mangled name of hte variable
|
||||||
@@ -129,7 +144,8 @@ protected:
|
|||||||
Declaration m_declaration; // Declaration location for this item.
|
Declaration m_declaration; // Declaration location for this item.
|
||||||
DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate()
|
DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate()
|
||||||
uint8_t m_external:1, // Visible outside the containing compile unit?
|
uint8_t m_external:1, // Visible outside the containing compile unit?
|
||||||
m_artificial:1; // Non-zero if the variable is not explicitly declared in source
|
m_artificial:1, // Non-zero if the variable is not explicitly declared in source
|
||||||
|
m_loc_is_const_data:1; // The m_location expression contains the constant variable value data, not a DWARF location
|
||||||
private:
|
private:
|
||||||
Variable(const Variable& rhs);
|
Variable(const Variable& rhs);
|
||||||
Variable& operator=(const Variable& rhs);
|
Variable& operator=(const Variable& rhs);
|
||||||
|
|||||||
@@ -3374,10 +3374,10 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 58;
|
CURRENT_PROJECT_VERSION = 59;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 58;
|
DYLIB_CURRENT_VERSION = 59;
|
||||||
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
|
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -3423,11 +3423,11 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 58;
|
CURRENT_PROJECT_VERSION = 59;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 58;
|
DYLIB_CURRENT_VERSION = 59;
|
||||||
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
|
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -3471,8 +3471,8 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 58;
|
CURRENT_PROJECT_VERSION = 59;
|
||||||
DYLIB_CURRENT_VERSION = 58;
|
DYLIB_CURRENT_VERSION = 59;
|
||||||
EXECUTABLE_EXTENSION = a;
|
EXECUTABLE_EXTENSION = a;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -3510,9 +3510,9 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 58;
|
CURRENT_PROJECT_VERSION = 59;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DYLIB_CURRENT_VERSION = 58;
|
DYLIB_CURRENT_VERSION = 59;
|
||||||
EXECUTABLE_EXTENSION = a;
|
EXECUTABLE_EXTENSION = a;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -3550,9 +3550,9 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 58;
|
CURRENT_PROJECT_VERSION = 59;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DYLIB_CURRENT_VERSION = 58;
|
DYLIB_CURRENT_VERSION = 59;
|
||||||
EXECUTABLE_EXTENSION = a;
|
EXECUTABLE_EXTENSION = a;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -3620,7 +3620,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
CURRENT_PROJECT_VERSION = 58;
|
CURRENT_PROJECT_VERSION = 59;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -3651,11 +3651,11 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
CURRENT_PROJECT_VERSION = 58;
|
CURRENT_PROJECT_VERSION = 59;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 58;
|
DYLIB_CURRENT_VERSION = 59;
|
||||||
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
|
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -3777,7 +3777,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 58;
|
CURRENT_PROJECT_VERSION = 59;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -3809,7 +3809,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
CURRENT_PROJECT_VERSION = 58;
|
CURRENT_PROJECT_VERSION = 59;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>58</string>
|
<string>59</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>${EXECUTABLE_NAME}</string>
|
<string>${EXECUTABLE_NAME}</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ CommandObjectExpression::CommandOptions::SetOptionValue (uint32_t option_idx, co
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (result)
|
if (result)
|
||||||
use_dynamic = eLazyBoolYes;
|
use_dynamic = eLazyBoolYes;
|
||||||
else
|
else
|
||||||
use_dynamic = eLazyBoolNo;
|
use_dynamic = eLazyBoolNo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,15 @@ DataExtractor::DataExtractor (const DataExtractor& data, uint32_t offset, uint32
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DataExtractor::DataExtractor (const DataExtractor& rhs) :
|
||||||
|
m_start (rhs.m_start),
|
||||||
|
m_end (rhs.m_end),
|
||||||
|
m_byte_order (rhs.m_byte_order),
|
||||||
|
m_addr_size (rhs.m_addr_size),
|
||||||
|
m_data_sp (rhs.m_data_sp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Assignment operator
|
// Assignment operator
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
@@ -135,11 +144,11 @@ DataExtractor::operator= (const DataExtractor& rhs)
|
|||||||
{
|
{
|
||||||
if (this != &rhs)
|
if (this != &rhs)
|
||||||
{
|
{
|
||||||
m_start = rhs.m_start;
|
m_start = rhs.m_start;
|
||||||
m_end = rhs.m_end;
|
m_end = rhs.m_end;
|
||||||
m_byte_order= rhs.m_byte_order;
|
m_byte_order = rhs.m_byte_order;
|
||||||
m_addr_size = rhs.m_addr_size;
|
m_addr_size = rhs.m_addr_size;
|
||||||
m_data_sp = rhs.m_data_sp;
|
m_data_sp = rhs.m_data_sp;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,7 +302,6 @@ Error::SetErrorString (const char *err_str)
|
|||||||
if (Success())
|
if (Success())
|
||||||
SetErrorToGenericError();
|
SetErrorToGenericError();
|
||||||
m_string = err_str;
|
m_string = err_str;
|
||||||
m_string.append("\n");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_string.clear();
|
m_string.clear();
|
||||||
|
|||||||
@@ -690,7 +690,12 @@ ValueObject::GetValueAsCString ()
|
|||||||
GetBitfieldBitOffset())) // Bitfield bit offset
|
GetBitfieldBitOffset())) // Bitfield bit offset
|
||||||
m_value_str.swap(sstr.GetString());
|
m_value_str.swap(sstr.GetString());
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
|
||||||
|
m_data.GetByteSize(),
|
||||||
|
GetByteSize());
|
||||||
m_value_str.clear();
|
m_value_str.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -953,7 +958,13 @@ ValueObject::IsIntegerType (bool &is_signed)
|
|||||||
bool
|
bool
|
||||||
ValueObject::IsPointerOrReferenceType ()
|
ValueObject::IsPointerOrReferenceType ()
|
||||||
{
|
{
|
||||||
return ClangASTContext::IsPointerOrReferenceType(GetClangType());
|
return ClangASTContext::IsPointerOrReferenceType (GetClangType());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ValueObject::IsPossibleCPlusPlusDynamicType ()
|
||||||
|
{
|
||||||
|
return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueObjectSP
|
ValueObjectSP
|
||||||
@@ -1149,9 +1160,11 @@ ValueObject::DumpValueObject
|
|||||||
bool flat_output
|
bool flat_output
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (valobj && valobj->UpdateValueIfNeeded ())
|
if (valobj)
|
||||||
{
|
{
|
||||||
if (use_dynamic != lldb::eNoDynamicValues)
|
bool update_success = valobj->UpdateValueIfNeeded ();
|
||||||
|
|
||||||
|
if (update_success && use_dynamic != lldb::eNoDynamicValues)
|
||||||
{
|
{
|
||||||
ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
|
ValueObject *dynamic_value = valobj->GetDynamicValue(use_dynamic).get();
|
||||||
if (dynamic_value)
|
if (dynamic_value)
|
||||||
@@ -1196,7 +1209,7 @@ ValueObject::DumpValueObject
|
|||||||
|
|
||||||
if (!scope_already_checked && !valobj->IsInScope())
|
if (!scope_already_checked && !valobj->IsInScope())
|
||||||
{
|
{
|
||||||
err_cstr = "error: out of scope";
|
err_cstr = "out of scope";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1210,7 +1223,7 @@ ValueObject::DumpValueObject
|
|||||||
|
|
||||||
if (err_cstr)
|
if (err_cstr)
|
||||||
{
|
{
|
||||||
s.Printf (" error: %s\n", err_cstr);
|
s.Printf (" <%s>\n", err_cstr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -120,6 +120,9 @@ ValueObjectDynamicValue::UpdateValue ()
|
|||||||
|
|
||||||
if (!m_parent->UpdateValueIfNeeded())
|
if (!m_parent->UpdateValueIfNeeded())
|
||||||
{
|
{
|
||||||
|
// The dynamic value failed to get an error, pass the error along
|
||||||
|
if (m_error.Success() && m_parent->GetError().Fail())
|
||||||
|
m_error = m_parent->GetError();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,10 @@ ValueObjectVariable::GetClangAST ()
|
|||||||
size_t
|
size_t
|
||||||
ValueObjectVariable::GetByteSize()
|
ValueObjectVariable::GetByteSize()
|
||||||
{
|
{
|
||||||
return m_variable_sp->GetType()->GetByteSize();
|
Type *type = m_variable_sp->GetType();
|
||||||
|
if (type)
|
||||||
|
return type->GetByteSize();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lldb::ValueType
|
lldb::ValueType
|
||||||
@@ -107,96 +110,109 @@ ValueObjectVariable::UpdateValue ()
|
|||||||
|
|
||||||
Variable *variable = m_variable_sp.get();
|
Variable *variable = m_variable_sp.get();
|
||||||
DWARFExpression &expr = variable->LocationExpression();
|
DWARFExpression &expr = variable->LocationExpression();
|
||||||
lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
|
|
||||||
ExecutionContext exe_ctx (GetExecutionContextScope());
|
|
||||||
|
|
||||||
if (exe_ctx.target)
|
if (variable->GetLocationIsConstantValueData())
|
||||||
{
|
{
|
||||||
m_data.SetByteOrder(exe_ctx.target->GetArchitecture().GetByteOrder());
|
// expr doesn't contain DWARF bytes, it contains the constant variable
|
||||||
m_data.SetAddressByteSize(exe_ctx.target->GetArchitecture().GetAddressByteSize());
|
// value bytes themselves...
|
||||||
|
if (expr.GetExpressionData(m_data))
|
||||||
|
m_value.SetContext(Value::eContextTypeVariable, variable);
|
||||||
|
else
|
||||||
|
m_error.SetErrorString ("empty constant data");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (expr.IsLocationList())
|
|
||||||
{
|
{
|
||||||
SymbolContext sc;
|
lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
|
||||||
variable->CalculateSymbolContext (&sc);
|
ExecutionContext exe_ctx (GetExecutionContextScope());
|
||||||
if (sc.function)
|
|
||||||
loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
|
if (exe_ctx.target)
|
||||||
}
|
|
||||||
Value old_value(m_value);
|
|
||||||
if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error))
|
|
||||||
{
|
|
||||||
m_value.SetContext(Value::eContextTypeVariable, variable);
|
|
||||||
|
|
||||||
Value::ValueType value_type = m_value.GetValueType();
|
|
||||||
|
|
||||||
switch (value_type)
|
|
||||||
{
|
{
|
||||||
default:
|
m_data.SetByteOrder(exe_ctx.target->GetArchitecture().GetByteOrder());
|
||||||
assert(!"Unhandled expression result value kind...");
|
m_data.SetAddressByteSize(exe_ctx.target->GetArchitecture().GetAddressByteSize());
|
||||||
break;
|
}
|
||||||
|
|
||||||
case Value::eValueTypeScalar:
|
if (expr.IsLocationList())
|
||||||
// The variable value is in the Scalar value inside the m_value.
|
{
|
||||||
// We can point our m_data right to it.
|
SymbolContext sc;
|
||||||
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0);
|
variable->CalculateSymbolContext (&sc);
|
||||||
break;
|
if (sc.function)
|
||||||
|
loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
|
||||||
|
}
|
||||||
|
Value old_value(m_value);
|
||||||
|
if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error))
|
||||||
|
{
|
||||||
|
m_value.SetContext(Value::eContextTypeVariable, variable);
|
||||||
|
|
||||||
case Value::eValueTypeFileAddress:
|
Value::ValueType value_type = m_value.GetValueType();
|
||||||
case Value::eValueTypeLoadAddress:
|
|
||||||
case Value::eValueTypeHostAddress:
|
|
||||||
// The DWARF expression result was an address in the inferior
|
|
||||||
// process. If this variable is an aggregate type, we just need
|
|
||||||
// the address as the main value as all child variable objects
|
|
||||||
// will rely upon this location and add an offset and then read
|
|
||||||
// their own values as needed. If this variable is a simple
|
|
||||||
// type, we read all data for it into m_data.
|
|
||||||
// Make sure this type has a value before we try and read it
|
|
||||||
|
|
||||||
// If we have a file address, convert it to a load address if we can.
|
switch (value_type)
|
||||||
if (value_type == Value::eValueTypeFileAddress && exe_ctx.process)
|
|
||||||
{
|
{
|
||||||
lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
|
default:
|
||||||
if (file_addr != LLDB_INVALID_ADDRESS)
|
assert(!"Unhandled expression result value kind...");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Value::eValueTypeScalar:
|
||||||
|
// The variable value is in the Scalar value inside the m_value.
|
||||||
|
// We can point our m_data right to it.
|
||||||
|
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Value::eValueTypeFileAddress:
|
||||||
|
case Value::eValueTypeLoadAddress:
|
||||||
|
case Value::eValueTypeHostAddress:
|
||||||
|
// The DWARF expression result was an address in the inferior
|
||||||
|
// process. If this variable is an aggregate type, we just need
|
||||||
|
// the address as the main value as all child variable objects
|
||||||
|
// will rely upon this location and add an offset and then read
|
||||||
|
// their own values as needed. If this variable is a simple
|
||||||
|
// type, we read all data for it into m_data.
|
||||||
|
// Make sure this type has a value before we try and read it
|
||||||
|
|
||||||
|
// If we have a file address, convert it to a load address if we can.
|
||||||
|
if (value_type == Value::eValueTypeFileAddress && exe_ctx.process)
|
||||||
{
|
{
|
||||||
SymbolContext var_sc;
|
lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
|
||||||
variable->CalculateSymbolContext(&var_sc);
|
if (file_addr != LLDB_INVALID_ADDRESS)
|
||||||
if (var_sc.module_sp)
|
|
||||||
{
|
{
|
||||||
ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
|
SymbolContext var_sc;
|
||||||
if (objfile)
|
variable->CalculateSymbolContext(&var_sc);
|
||||||
|
if (var_sc.module_sp)
|
||||||
{
|
{
|
||||||
Address so_addr(file_addr, objfile->GetSectionList());
|
ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
|
||||||
lldb::addr_t load_addr = so_addr.GetLoadAddress (exe_ctx.target);
|
if (objfile)
|
||||||
if (load_addr != LLDB_INVALID_ADDRESS)
|
|
||||||
{
|
{
|
||||||
m_value.SetValueType(Value::eValueTypeLoadAddress);
|
Address so_addr(file_addr, objfile->GetSectionList());
|
||||||
m_value.GetScalar() = load_addr;
|
lldb::addr_t load_addr = so_addr.GetLoadAddress (exe_ctx.target);
|
||||||
|
if (load_addr != LLDB_INVALID_ADDRESS)
|
||||||
|
{
|
||||||
|
m_value.SetValueType(Value::eValueTypeLoadAddress);
|
||||||
|
m_value.GetScalar() = load_addr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ClangASTContext::IsAggregateType (GetClangType()))
|
||||||
|
{
|
||||||
|
// this value object represents an aggregate type whose
|
||||||
|
// children have values, but this object does not. So we
|
||||||
|
// say we are changed if our location has changed.
|
||||||
|
SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Copy the Value and set the context to use our Variable
|
||||||
|
// so it can extract read its value into m_data appropriately
|
||||||
|
Value value(m_value);
|
||||||
|
value.SetContext(Value::eContextTypeVariable, variable);
|
||||||
|
m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ClangASTContext::IsAggregateType (GetClangType()))
|
SetValueIsValid (m_error.Success());
|
||||||
{
|
|
||||||
// this value object represents an aggregate type whose
|
|
||||||
// children have values, but this object does not. So we
|
|
||||||
// say we are changed if our location has changed.
|
|
||||||
SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Copy the Value and set the context to use our Variable
|
|
||||||
// so it can extract read its value into m_data appropriately
|
|
||||||
Value value(m_value);
|
|
||||||
value.SetContext(Value::eContextTypeVariable, variable);
|
|
||||||
m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetValueIsValid (m_error.Success());
|
|
||||||
}
|
}
|
||||||
return m_error.Success();
|
return m_error.Success();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -642,21 +642,25 @@ ReadRegisterValueAsScalar
|
|||||||
if (reg_value.GetScalarValue(value.GetScalar()))
|
if (reg_value.GetScalarValue(value.GetScalar()))
|
||||||
{
|
{
|
||||||
value.SetValueType (Value::eValueTypeScalar);
|
value.SetValueType (Value::eValueTypeScalar);
|
||||||
value.SetContext (Value::eContextTypeRegisterInfo, const_cast<RegisterInfo *>(reg_info));
|
value.SetContext (Value::eContextTypeRegisterInfo,
|
||||||
|
const_cast<RegisterInfo *>(reg_info));
|
||||||
if (error_ptr)
|
if (error_ptr)
|
||||||
error_ptr->Clear();
|
error_ptr->Clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// If we get this error, then we need to implement a value
|
||||||
|
// buffer in the dwarf expression evaluation function...
|
||||||
if (error_ptr)
|
if (error_ptr)
|
||||||
error_ptr->SetErrorStringWithFormat("Failed to read register %u.\n", native_reg);
|
error_ptr->SetErrorStringWithFormat ("register %s can't be converted to a scalar value",
|
||||||
|
reg_info->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (error_ptr)
|
if (error_ptr)
|
||||||
error_ptr->SetErrorStringWithFormat("Failed to read register %u.\n", native_reg);
|
error_ptr->SetErrorStringWithFormat("register %s is not available", reg_info->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -817,7 +821,7 @@ DWARFExpression::Evaluate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error_ptr)
|
if (error_ptr)
|
||||||
error_ptr->SetErrorStringWithFormat("Out of scope.");
|
error_ptr->SetErrorString ("variable not available");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ static const char *vtable_demangled_prefix = "vtable for ";
|
|||||||
bool
|
bool
|
||||||
ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value)
|
ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value)
|
||||||
{
|
{
|
||||||
return in_value.IsPointerOrReferenceType();
|
return in_value.IsPossibleCPlusPlusDynamicType();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|||||||
@@ -4040,6 +4040,7 @@ SymbolFileDWARF::ParseVariableDIE
|
|||||||
DWARFExpression location;
|
DWARFExpression location;
|
||||||
bool is_external = false;
|
bool is_external = false;
|
||||||
bool is_artificial = false;
|
bool is_artificial = false;
|
||||||
|
bool location_is_const_value_data = false;
|
||||||
AccessType accessibility = eAccessNone;
|
AccessType accessibility = eAccessNone;
|
||||||
|
|
||||||
for (i=0; i<num_attributes; ++i)
|
for (i=0; i<num_attributes; ++i)
|
||||||
@@ -4057,6 +4058,9 @@ SymbolFileDWARF::ParseVariableDIE
|
|||||||
case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
|
case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
|
||||||
case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
|
case DW_AT_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
|
||||||
case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
|
case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
|
||||||
|
case DW_AT_const_value:
|
||||||
|
location_is_const_value_data = true;
|
||||||
|
// Fall through...
|
||||||
case DW_AT_location:
|
case DW_AT_location:
|
||||||
{
|
{
|
||||||
if (form_value.BlockData())
|
if (form_value.BlockData())
|
||||||
@@ -4085,7 +4089,6 @@ SymbolFileDWARF::ParseVariableDIE
|
|||||||
|
|
||||||
case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
|
case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
|
||||||
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
|
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
|
||||||
case DW_AT_const_value:
|
|
||||||
case DW_AT_declaration:
|
case DW_AT_declaration:
|
||||||
case DW_AT_description:
|
case DW_AT_description:
|
||||||
case DW_AT_endianity:
|
case DW_AT_endianity:
|
||||||
@@ -4141,6 +4144,7 @@ SymbolFileDWARF::ParseVariableDIE
|
|||||||
is_external,
|
is_external,
|
||||||
is_artificial));
|
is_artificial));
|
||||||
|
|
||||||
|
var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Cache var_sp even if NULL (the variable was just a specification or
|
// Cache var_sp even if NULL (the variable was just a specification or
|
||||||
|
|||||||
@@ -87,11 +87,14 @@ GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
|
|||||||
|
|
||||||
if (tag_decl->hasExternalLexicalStorage())
|
if (tag_decl->hasExternalLexicalStorage())
|
||||||
{
|
{
|
||||||
ExternalASTSource *external_ast_source = ast->getExternalSource();
|
if (ast)
|
||||||
if (external_ast_source)
|
|
||||||
{
|
{
|
||||||
external_ast_source->CompleteType(tag_decl);
|
ExternalASTSource *external_ast_source = ast->getExternalSource();
|
||||||
return !tag_type->isIncompleteType();
|
if (external_ast_source)
|
||||||
|
{
|
||||||
|
external_ast_source->CompleteType(tag_decl);
|
||||||
|
return !tag_type->isIncompleteType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -113,11 +116,14 @@ GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
|
|||||||
bool is_forward_decl = class_interface_decl->isForwardDecl();
|
bool is_forward_decl = class_interface_decl->isForwardDecl();
|
||||||
if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
|
if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
|
||||||
{
|
{
|
||||||
ExternalASTSource *external_ast_source = ast->getExternalSource();
|
if (ast)
|
||||||
if (external_ast_source)
|
|
||||||
{
|
{
|
||||||
external_ast_source->CompleteType (class_interface_decl);
|
ExternalASTSource *external_ast_source = ast->getExternalSource();
|
||||||
is_forward_decl = class_interface_decl->isForwardDecl();
|
if (external_ast_source)
|
||||||
|
{
|
||||||
|
external_ast_source->CompleteType (class_interface_decl);
|
||||||
|
is_forward_decl = class_interface_decl->isForwardDecl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return is_forward_decl == false;
|
return is_forward_decl == false;
|
||||||
}
|
}
|
||||||
@@ -3979,6 +3985,121 @@ ClangASTContext::GetPointerBitSize ()
|
|||||||
return ast->getTypeSize(ast->VoidPtrTy);
|
return ast->getTypeSize(ast->VoidPtrTy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
|
||||||
|
{
|
||||||
|
QualType pointee_qual_type;
|
||||||
|
if (clang_type)
|
||||||
|
{
|
||||||
|
QualType qual_type (QualType::getFromOpaquePtr(clang_type));
|
||||||
|
const clang::Type::TypeClass type_class = qual_type->getTypeClass();
|
||||||
|
bool success = false;
|
||||||
|
switch (type_class)
|
||||||
|
{
|
||||||
|
case clang::Type::Pointer:
|
||||||
|
pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case clang::Type::LValueReference:
|
||||||
|
case clang::Type::RValueReference:
|
||||||
|
pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case clang::Type::Typedef:
|
||||||
|
return ClangASTContext::IsPossibleCPlusPlusDynamicType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), dynamic_pointee_type);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
// Check to make sure what we are pointing too is a possible dynamic C++ type
|
||||||
|
// We currently accept any "void *" (in case we have a class that has been
|
||||||
|
// watered down to an opaque pointer) and virtual C++ classes.
|
||||||
|
const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
|
||||||
|
switch (pointee_type_class)
|
||||||
|
{
|
||||||
|
case clang::Type::Builtin:
|
||||||
|
switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
|
||||||
|
{
|
||||||
|
case clang::BuiltinType::UnknownAny:
|
||||||
|
case clang::BuiltinType::Void:
|
||||||
|
if (dynamic_pointee_type)
|
||||||
|
*dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case clang::BuiltinType::NullPtr:
|
||||||
|
case clang::BuiltinType::Bool:
|
||||||
|
case clang::BuiltinType::Char_U:
|
||||||
|
case clang::BuiltinType::UChar:
|
||||||
|
case clang::BuiltinType::WChar_U:
|
||||||
|
case clang::BuiltinType::Char16:
|
||||||
|
case clang::BuiltinType::Char32:
|
||||||
|
case clang::BuiltinType::UShort:
|
||||||
|
case clang::BuiltinType::UInt:
|
||||||
|
case clang::BuiltinType::ULong:
|
||||||
|
case clang::BuiltinType::ULongLong:
|
||||||
|
case clang::BuiltinType::UInt128:
|
||||||
|
case clang::BuiltinType::Char_S:
|
||||||
|
case clang::BuiltinType::SChar:
|
||||||
|
case clang::BuiltinType::WChar_S:
|
||||||
|
case clang::BuiltinType::Short:
|
||||||
|
case clang::BuiltinType::Int:
|
||||||
|
case clang::BuiltinType::Long:
|
||||||
|
case clang::BuiltinType::LongLong:
|
||||||
|
case clang::BuiltinType::Int128:
|
||||||
|
case clang::BuiltinType::Float:
|
||||||
|
case clang::BuiltinType::Double:
|
||||||
|
case clang::BuiltinType::LongDouble:
|
||||||
|
case clang::BuiltinType::Dependent:
|
||||||
|
case clang::BuiltinType::Overload:
|
||||||
|
case clang::BuiltinType::ObjCId:
|
||||||
|
case clang::BuiltinType::ObjCClass:
|
||||||
|
case clang::BuiltinType::ObjCSel:
|
||||||
|
case clang::BuiltinType::BoundMember:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case clang::Type::Record:
|
||||||
|
{
|
||||||
|
CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
|
||||||
|
if (cxx_record_decl)
|
||||||
|
{
|
||||||
|
if (GetCompleteQualType (ast, pointee_qual_type))
|
||||||
|
{
|
||||||
|
success = cxx_record_decl->isPolymorphic() || cxx_record_decl->isAbstract();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We failed to get the complete type, so we have to
|
||||||
|
// treat this as a void * which we might possibly be
|
||||||
|
// able to complete
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
if (dynamic_pointee_type)
|
||||||
|
*dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dynamic_pointee_type)
|
||||||
|
*dynamic_pointee_type = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
|
ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -156,40 +156,53 @@ Variable::CalculateSymbolContext (SymbolContext *sc)
|
|||||||
sc->Clear();
|
sc->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Variable::LocationIsValidForFrame (StackFrame *frame)
|
||||||
|
{
|
||||||
|
// Is the variable is described by a single location?
|
||||||
|
if (!m_location.IsLocationList())
|
||||||
|
{
|
||||||
|
// Yes it is, the location is valid.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame)
|
||||||
|
{
|
||||||
|
Target *target = &frame->GetThread().GetProcess().GetTarget();
|
||||||
|
|
||||||
|
Function *function = frame->GetSymbolContext(eSymbolContextFunction).function;
|
||||||
|
if (function)
|
||||||
|
{
|
||||||
|
addr_t loclist_base_load_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
|
||||||
|
if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
|
||||||
|
return false;
|
||||||
|
// It is a location list. We just need to tell if the location
|
||||||
|
// list contains the current address when converted to a load
|
||||||
|
// address
|
||||||
|
return m_location.LocationListContainsAddress (loclist_base_load_addr,
|
||||||
|
frame->GetFrameCodeAddress().GetLoadAddress (target));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Variable::IsInScope (StackFrame *frame)
|
Variable::IsInScope (StackFrame *frame)
|
||||||
{
|
{
|
||||||
switch (m_scope)
|
switch (m_scope)
|
||||||
{
|
{
|
||||||
case eValueTypeVariableGlobal:
|
case eValueTypeRegister:
|
||||||
case eValueTypeVariableStatic:
|
case eValueTypeRegisterSet:
|
||||||
// Globals and statics are always in scope.
|
return frame != NULL;
|
||||||
|
|
||||||
|
case eValueTypeConstResult:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case eValueTypeVariableGlobal:
|
||||||
|
case eValueTypeVariableStatic:
|
||||||
case eValueTypeVariableArgument:
|
case eValueTypeVariableArgument:
|
||||||
case eValueTypeVariableLocal:
|
case eValueTypeVariableLocal:
|
||||||
// Check if the location has a location list that describes the value
|
if (frame)
|
||||||
// of the variable with address ranges and different locations for each
|
|
||||||
// address range?
|
|
||||||
if (m_location.IsLocationList())
|
|
||||||
{
|
|
||||||
SymbolContext sc;
|
|
||||||
CalculateSymbolContext(&sc);
|
|
||||||
|
|
||||||
// Currently we only support functions that have things with
|
|
||||||
// locations lists. If this expands, we will need to add support
|
|
||||||
assert (sc.function);
|
|
||||||
Target *target = &frame->GetThread().GetProcess().GetTarget();
|
|
||||||
addr_t loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
|
|
||||||
if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
|
|
||||||
return false;
|
|
||||||
// It is a location list. We just need to tell if the location
|
|
||||||
// list contains the current address when converted to a load
|
|
||||||
// address
|
|
||||||
return m_location.LocationListContainsAddress (loclist_base_load_addr, frame->GetFrameCodeAddress().GetLoadAddress (target));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// We don't have a location list, we just need to see if the block
|
// We don't have a location list, we just need to see if the block
|
||||||
// that this variable was defined in is currently
|
// that this variable was defined in is currently
|
||||||
@@ -198,16 +211,19 @@ Variable::IsInScope (StackFrame *frame)
|
|||||||
{
|
{
|
||||||
SymbolContext variable_sc;
|
SymbolContext variable_sc;
|
||||||
CalculateSymbolContext (&variable_sc);
|
CalculateSymbolContext (&variable_sc);
|
||||||
|
// Check for static or global variable defined at the compile unit
|
||||||
|
// level that wasn't defined in a block
|
||||||
|
if (variable_sc.block == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
if (variable_sc.block == deepest_frame_block)
|
if (variable_sc.block == deepest_frame_block)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return variable_sc.block->Contains (deepest_frame_block);
|
return variable_sc.block->Contains (deepest_frame_block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert (!"Unhandled case");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//virtual
|
virtual
|
||||||
~A()
|
~A()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//virtual
|
virtual
|
||||||
~B()
|
~B()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ public:
|
|||||||
printf("Within C::ctor() m_c_int=%d\n", m_c_int); // Set break point at this line.
|
printf("Within C::ctor() m_c_int=%d\n", m_c_int); // Set break point at this line.
|
||||||
}
|
}
|
||||||
|
|
||||||
//virtual
|
virtual
|
||||||
~C()
|
~C()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -119,6 +119,14 @@ main (int argc, char const *argv[])
|
|||||||
A a(12);
|
A a(12);
|
||||||
B b(22,33);
|
B b(22,33);
|
||||||
C c(44,55,66);
|
C c(44,55,66);
|
||||||
|
A *c_as_a = &c;
|
||||||
|
B *c_as_b = &c;
|
||||||
|
void *a_as_void_ptr = &a;
|
||||||
|
void *b_as_void_ptr = &b;
|
||||||
|
void *c_as_void_ptr = &c;
|
||||||
|
const void *a_as_const_void_ptr = &a;
|
||||||
|
const void *b_as_const_void_ptr = &b;
|
||||||
|
const void *c_as_const_void_ptr = &c;
|
||||||
Conversion conv(1);
|
Conversion conv(1);
|
||||||
if (conv)
|
if (conv)
|
||||||
return b.GetIntegerB() - a.GetInteger() + c.GetInteger();
|
return b.GetIntegerB() - a.GetInteger() + c.GetInteger();
|
||||||
|
|||||||
Reference in New Issue
Block a user