summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/DataExtractor.h5
-rw-r--r--lldb/include/lldb/Core/ValueObject.h3
-rw-r--r--lldb/include/lldb/Expression/DWARFExpression.h7
-rw-r--r--lldb/include/lldb/Symbol/ClangASTContext.h5
-rw-r--r--lldb/include/lldb/Symbol/Variable.h18
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj30
-rw-r--r--lldb/resources/LLDB-Info.plist2
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp2
-rw-r--r--lldb/source/Core/DataExtractor.cpp17
-rw-r--r--lldb/source/Core/Error.cpp1
-rw-r--r--lldb/source/Core/ValueObject.cpp23
-rw-r--r--lldb/source/Core/ValueObjectDynamicValue.cpp3
-rw-r--r--lldb/source/Core/ValueObjectVariable.cpp162
-rw-r--r--lldb/source/Expression/DWARFExpression.cpp12
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp6
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp137
-rw-r--r--lldb/source/Symbol/Variable.cpp64
-rw-r--r--lldb/test/class_types/main.cpp14
19 files changed, 369 insertions, 144 deletions
diff --git a/lldb/include/lldb/Core/DataExtractor.h b/lldb/include/lldb/Core/DataExtractor.h
index e0498fa28e7..e4ec102d1e8 100644
--- a/lldb/include/lldb/Core/DataExtractor.h
+++ b/lldb/include/lldb/Core/DataExtractor.h
@@ -124,8 +124,9 @@ public:
/// @param[in] length
/// 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.
///
@@ -1086,7 +1087,7 @@ public:
/// The number of bytes that this object now contains.
//------------------------------------------------------------------
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.
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h
index a5d7a5c5f40..fcf2b0b25d6 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -236,6 +236,9 @@ public:
virtual bool
IsPointerOrReferenceType ();
+
+ virtual bool
+ IsPossibleCPlusPlusDynamicType ();
virtual bool
IsBaseClass ()
diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h
index 60f278abba0..72b9c63ca52 100644
--- a/lldb/include/lldb/Expression/DWARFExpression.h
+++ b/lldb/include/lldb/Expression/DWARFExpression.h
@@ -304,6 +304,13 @@ public:
void
SetExpressionDeclMap (ClangExpressionDeclMap *decl_map);
+ bool
+ GetExpressionData (DataExtractor &data) const
+ {
+ data = m_data;
+ return data.GetByteSize() > 0;
+ }
+
protected:
//------------------------------------------------------------------
/// Pretty-prints the location expression to a stream
diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h
index 337ea8186e0..6b0b4a89747 100644
--- a/lldb/include/lldb/Symbol/ClangASTContext.h
+++ b/lldb/include/lldb/Symbol/ClangASTContext.h
@@ -612,6 +612,11 @@ public:
static bool
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
IsCStringType (lldb::clang_type_t clang_type, uint32_t &length);
diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h
index 89a1bbcecc8..c6656cc6368 100644
--- a/lldb/include/lldb/Symbol/Variable.h
+++ b/lldb/include/lldb/Symbol/Variable.h
@@ -120,6 +120,21 @@ public:
bool
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:
ConstString m_name; // The basename of the variable (no namespaces)
Mangled m_mangled; // The mangled name of hte variable
@@ -129,7 +144,8 @@ protected:
Declaration m_declaration; // Declaration location for this item.
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?
- 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:
Variable(const Variable& rhs);
Variable& operator=(const Variable& rhs);
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index e7b8a5344ca..6679beaa242 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -3374,10 +3374,10 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 58;
+ CURRENT_PROJECT_VERSION = 59;
DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 58;
+ DYLIB_CURRENT_VERSION = 59;
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -3423,11 +3423,11 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 58;
+ CURRENT_PROJECT_VERSION = 59;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 58;
+ DYLIB_CURRENT_VERSION = 59;
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -3471,8 +3471,8 @@
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 58;
- DYLIB_CURRENT_VERSION = 58;
+ CURRENT_PROJECT_VERSION = 59;
+ DYLIB_CURRENT_VERSION = 59;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -3510,9 +3510,9 @@
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 58;
+ CURRENT_PROJECT_VERSION = 59;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- DYLIB_CURRENT_VERSION = 58;
+ DYLIB_CURRENT_VERSION = 59;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -3550,9 +3550,9 @@
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 58;
+ CURRENT_PROJECT_VERSION = 59;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- DYLIB_CURRENT_VERSION = 58;
+ DYLIB_CURRENT_VERSION = 59;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -3620,7 +3620,7 @@
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 58;
+ CURRENT_PROJECT_VERSION = 59;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -3651,11 +3651,11 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 58;
+ CURRENT_PROJECT_VERSION = 59;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 58;
+ DYLIB_CURRENT_VERSION = 59;
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -3777,7 +3777,7 @@
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 58;
+ CURRENT_PROJECT_VERSION = 59;
DEBUG_INFORMATION_FORMAT = dwarf;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -3809,7 +3809,7 @@
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 58;
+ CURRENT_PROJECT_VERSION = 59;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
diff --git a/lldb/resources/LLDB-Info.plist b/lldb/resources/LLDB-Info.plist
index bb3eec65099..928ae78e053 100644
--- a/lldb/resources/LLDB-Info.plist
+++ b/lldb/resources/LLDB-Info.plist
@@ -17,7 +17,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>58</string>
+ <string>59</string>
<key>CFBundleName</key>
<string>${EXECUTABLE_NAME}</string>
</dict>
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index f8facfd1ba4..4c8b152f6e7 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -87,7 +87,7 @@ CommandObjectExpression::CommandOptions::SetOptionValue (uint32_t option_idx, co
else
{
if (result)
- use_dynamic = eLazyBoolYes;
+ use_dynamic = eLazyBoolYes;
else
use_dynamic = eLazyBoolNo;
}
diff --git a/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp
index 8ce7b8f3224..bc26c8645e1 100644
--- a/lldb/source/Core/DataExtractor.cpp
+++ b/lldb/source/Core/DataExtractor.cpp
@@ -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
//----------------------------------------------------------------------
@@ -135,11 +144,11 @@ DataExtractor::operator= (const DataExtractor& rhs)
{
if (this != &rhs)
{
- m_start = rhs.m_start;
- m_end = rhs.m_end;
- m_byte_order= rhs.m_byte_order;
+ 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;
+ m_data_sp = rhs.m_data_sp;
}
return *this;
}
diff --git a/lldb/source/Core/Error.cpp b/lldb/source/Core/Error.cpp
index 6614769f8a0..6e21fe7ee2b 100644
--- a/lldb/source/Core/Error.cpp
+++ b/lldb/source/Core/Error.cpp
@@ -302,7 +302,6 @@ Error::SetErrorString (const char *err_str)
if (Success())
SetErrorToGenericError();
m_string = err_str;
- m_string.append("\n");
}
else
m_string.clear();
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 10247db11e2..ee44876a0ec 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -690,7 +690,12 @@ ValueObject::GetValueAsCString ()
GetBitfieldBitOffset())) // Bitfield bit offset
m_value_str.swap(sstr.GetString());
else
+ {
+ m_error.SetErrorStringWithFormat ("unsufficient data for value (only %u of %u bytes available)",
+ m_data.GetByteSize(),
+ GetByteSize());
m_value_str.clear();
+ }
}
}
break;
@@ -953,7 +958,13 @@ ValueObject::IsIntegerType (bool &is_signed)
bool
ValueObject::IsPointerOrReferenceType ()
{
- return ClangASTContext::IsPointerOrReferenceType(GetClangType());
+ return ClangASTContext::IsPointerOrReferenceType (GetClangType());
+}
+
+bool
+ValueObject::IsPossibleCPlusPlusDynamicType ()
+{
+ return ClangASTContext::IsPossibleCPlusPlusDynamicType (GetClangAST (), GetClangType());
}
ValueObjectSP
@@ -1149,9 +1160,11 @@ ValueObject::DumpValueObject
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();
if (dynamic_value)
@@ -1196,7 +1209,7 @@ ValueObject::DumpValueObject
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)
{
- s.Printf (" error: %s\n", err_cstr);
+ s.Printf (" <%s>\n", err_cstr);
}
else
{
diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp
index ee50d45433f..a8d48891ab3 100644
--- a/lldb/source/Core/ValueObjectDynamicValue.cpp
+++ b/lldb/source/Core/ValueObjectDynamicValue.cpp
@@ -120,6 +120,9 @@ ValueObjectDynamicValue::UpdateValue ()
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;
}
diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp
index 882b7021f49..e2a281b7f95 100644
--- a/lldb/source/Core/ValueObjectVariable.cpp
+++ b/lldb/source/Core/ValueObjectVariable.cpp
@@ -88,7 +88,10 @@ ValueObjectVariable::GetClangAST ()
size_t
ValueObjectVariable::GetByteSize()
{
- return m_variable_sp->GetType()->GetByteSize();
+ Type *type = m_variable_sp->GetType();
+ if (type)
+ return type->GetByteSize();
+ return 0;
}
lldb::ValueType
@@ -107,96 +110,109 @@ ValueObjectVariable::UpdateValue ()
Variable *variable = m_variable_sp.get();
DWARFExpression &expr = variable->LocationExpression();
- lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
- ExecutionContext exe_ctx (GetExecutionContextScope());
- if (exe_ctx.target)
- {
- m_data.SetByteOrder(exe_ctx.target->GetArchitecture().GetByteOrder());
- m_data.SetAddressByteSize(exe_ctx.target->GetArchitecture().GetAddressByteSize());
- }
-
- if (expr.IsLocationList())
+ if (variable->GetLocationIsConstantValueData())
{
- SymbolContext sc;
- variable->CalculateSymbolContext (&sc);
- if (sc.function)
- loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
+ // expr doesn't contain DWARF bytes, it contains the constant variable
+ // value bytes themselves...
+ if (expr.GetExpressionData(m_data))
+ m_value.SetContext(Value::eContextTypeVariable, variable);
+ else
+ m_error.SetErrorString ("empty constant data");
}
- Value old_value(m_value);
- if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error))
+ else
{
- m_value.SetContext(Value::eContextTypeVariable, variable);
-
- Value::ValueType value_type = m_value.GetValueType();
+ lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
+ ExecutionContext exe_ctx (GetExecutionContextScope());
+
+ if (exe_ctx.target)
+ {
+ m_data.SetByteOrder(exe_ctx.target->GetArchitecture().GetByteOrder());
+ m_data.SetAddressByteSize(exe_ctx.target->GetArchitecture().GetAddressByteSize());
+ }
- switch (value_type)
+ if (expr.IsLocationList())
{
- default:
- 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 sc;
+ variable->CalculateSymbolContext (&sc);
+ 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);
+
+ Value::ValueType value_type = m_value.GetValueType();
+
+ switch (value_type)
{
- lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- if (file_addr != LLDB_INVALID_ADDRESS)
+ default:
+ 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;
- variable->CalculateSymbolContext(&var_sc);
- if (var_sc.module_sp)
+ lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ if (file_addr != LLDB_INVALID_ADDRESS)
{
- ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
- if (objfile)
+ SymbolContext var_sc;
+ variable->CalculateSymbolContext(&var_sc);
+ if (var_sc.module_sp)
{
- Address so_addr(file_addr, objfile->GetSectionList());
- lldb::addr_t load_addr = so_addr.GetLoadAddress (exe_ctx.target);
- if (load_addr != LLDB_INVALID_ADDRESS)
+ ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
+ if (objfile)
{
- m_value.SetValueType(Value::eValueTypeLoadAddress);
- m_value.GetScalar() = load_addr;
+ Address so_addr(file_addr, objfile->GetSectionList());
+ 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);
+ 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;
}
- break;
- }
- SetValueIsValid (m_error.Success());
+ SetValueIsValid (m_error.Success());
+ }
}
return m_error.Success();
}
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 161fd957d5c..b038a5622e4 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -642,21 +642,25 @@ ReadRegisterValueAsScalar
if (reg_value.GetScalarValue(value.GetScalar()))
{
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)
error_ptr->Clear();
return true;
}
else
{
+ // If we get this error, then we need to implement a value
+ // buffer in the dwarf expression evaluation function...
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
{
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)
- error_ptr->SetErrorStringWithFormat("Out of scope.");
+ error_ptr->SetErrorString ("variable not available");
return false;
}
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 76a549a1735..00b450e9aab 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -37,7 +37,7 @@ static const char *vtable_demangled_prefix = "vtable for ";
bool
ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value)
{
- return in_value.IsPointerOrReferenceType();
+ return in_value.IsPossibleCPlusPlusDynamicType();
}
bool
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 342de4c6e07..fa2d003c966 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -4040,6 +4040,7 @@ SymbolFileDWARF::ParseVariableDIE
DWARFExpression location;
bool is_external = false;
bool is_artificial = false;
+ bool location_is_const_value_data = false;
AccessType accessibility = eAccessNone;
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_type: var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); 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:
{
if (form_value.BlockData())
@@ -4085,7 +4089,6 @@ SymbolFileDWARF::ParseVariableDIE
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_const_value:
case DW_AT_declaration:
case DW_AT_description:
case DW_AT_endianity:
@@ -4141,6 +4144,7 @@ SymbolFileDWARF::ParseVariableDIE
is_external,
is_artificial));
+ var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
}
}
// Cache var_sp even if NULL (the variable was just a specification or
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 7759164e51c..cf55db8d243 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -87,11 +87,14 @@ GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
if (tag_decl->hasExternalLexicalStorage())
{
- ExternalASTSource *external_ast_source = ast->getExternalSource();
- if (external_ast_source)
+ if (ast)
{
- external_ast_source->CompleteType(tag_decl);
- return !tag_type->isIncompleteType();
+ ExternalASTSource *external_ast_source = ast->getExternalSource();
+ if (external_ast_source)
+ {
+ external_ast_source->CompleteType(tag_decl);
+ return !tag_type->isIncompleteType();
+ }
}
}
return false;
@@ -113,11 +116,14 @@ GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type)
bool is_forward_decl = class_interface_decl->isForwardDecl();
if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
{
- ExternalASTSource *external_ast_source = ast->getExternalSource();
- if (external_ast_source)
+ if (ast)
{
- external_ast_source->CompleteType (class_interface_decl);
- is_forward_decl = class_interface_decl->isForwardDecl();
+ ExternalASTSource *external_ast_source = ast->getExternalSource();
+ if (external_ast_source)
+ {
+ external_ast_source->CompleteType (class_interface_decl);
+ is_forward_decl = class_interface_decl->isForwardDecl();
+ }
}
return is_forward_decl == false;
}
@@ -3980,6 +3986,121 @@ ClangASTContext::GetPointerBitSize ()
}
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
ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
{
if (clang_type == NULL)
diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp
index f264e142fef..7f841b4856a 100644
--- a/lldb/source/Symbol/Variable.cpp
+++ b/lldb/source/Symbol/Variable.cpp
@@ -156,40 +156,53 @@ Variable::CalculateSymbolContext (SymbolContext *sc)
sc->Clear();
}
-
bool
-Variable::IsInScope (StackFrame *frame)
+Variable::LocationIsValidForFrame (StackFrame *frame)
{
- switch (m_scope)
+ // Is the variable is described by a single location?
+ if (!m_location.IsLocationList())
{
- case eValueTypeVariableGlobal:
- case eValueTypeVariableStatic:
- // Globals and statics are always in scope.
+ // Yes it is, the location is valid.
return true;
+ }
- case eValueTypeVariableArgument:
- case eValueTypeVariableLocal:
- // Check if the location has a location list that describes the value
- // of the variable with address ranges and different locations for each
- // address range?
- if (m_location.IsLocationList())
+ if (frame)
+ {
+ Target *target = &frame->GetThread().GetProcess().GetTarget();
+
+ Function *function = frame->GetSymbolContext(eSymbolContextFunction).function;
+ if (function)
{
- 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);
+ 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 m_location.LocationListContainsAddress (loclist_base_load_addr,
+ frame->GetFrameCodeAddress().GetLoadAddress (target));
}
- else
+ }
+ return false;
+}
+
+bool
+Variable::IsInScope (StackFrame *frame)
+{
+ switch (m_scope)
+ {
+ case eValueTypeRegister:
+ case eValueTypeRegisterSet:
+ return frame != NULL;
+
+ case eValueTypeConstResult:
+ return true;
+
+ case eValueTypeVariableGlobal:
+ case eValueTypeVariableStatic:
+ case eValueTypeVariableArgument:
+ case eValueTypeVariableLocal:
+ if (frame)
{
// We don't have a location list, we just need to see if the block
// that this variable was defined in is currently
@@ -198,16 +211,19 @@ Variable::IsInScope (StackFrame *frame)
{
SymbolContext 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)
return true;
-
return variable_sc.block->Contains (deepest_frame_block);
}
}
break;
default:
- assert (!"Unhandled case");
break;
}
return false;
diff --git a/lldb/test/class_types/main.cpp b/lldb/test/class_types/main.cpp
index 251e66c3c9f..4cee7f80637 100644
--- a/lldb/test/class_types/main.cpp
+++ b/lldb/test/class_types/main.cpp
@@ -32,7 +32,7 @@ public:
{
}
- //virtual
+ virtual
~A()
{
}
@@ -62,7 +62,7 @@ public:
{
}
- //virtual
+ virtual
~B()
{
}
@@ -93,7 +93,7 @@ public:
printf("Within C::ctor() m_c_int=%d\n", m_c_int); // Set break point at this line.
}
- //virtual
+ virtual
~C()
{
}
@@ -119,6 +119,14 @@ main (int argc, char const *argv[])
A a(12);
B b(22,33);
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);
if (conv)
return b.GetIntegerB() - a.GetInteger() + c.GetInteger();
OpenPOWER on IntegriCloud