[Lldb-commits] [lldb] r287189 - Make GetValueForVariableExpression use StringRef.
Jim Ingham via lldb-commits
lldb-commits at lists.llvm.org
Wed Nov 16 17:54:01 PST 2016
Probably just an oversight, but changing var_expr_cstr to a StringRef, but leaving it called "_cstr" will cause confusion.
Jim
> On Nov 16, 2016, at 5:37 PM, Zachary Turner via lldb-commits <lldb-commits at lists.llvm.org> wrote:
>
> Author: zturner
> Date: Wed Nov 16 19:37:52 2016
> New Revision: 287189
>
> URL: http://llvm.org/viewvc/llvm-project?rev=287189&view=rev
> Log:
> Make GetValueForVariableExpression use StringRef.
>
> Also significantly reduced the indentation level by use of
> early returns, and simplified some of the logic by using
> StringRef functions such as consumeInteger() and getAsInteger()
> instead of strtoll, etc.
>
> Modified:
> lldb/trunk/include/lldb/Target/StackFrame.h
> lldb/trunk/source/Target/StackFrame.cpp
>
> Modified: lldb/trunk/include/lldb/Target/StackFrame.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=287189&r1=287188&r2=287189&view=diff
> ==============================================================================
> --- lldb/trunk/include/lldb/Target/StackFrame.h (original)
> +++ lldb/trunk/include/lldb/Target/StackFrame.h Wed Nov 16 19:37:52 2016
> @@ -313,7 +313,7 @@ public:
> /// A shared pointer to the ValueObject described by var_expr.
> //------------------------------------------------------------------
> lldb::ValueObjectSP GetValueForVariableExpressionPath(
> - const char *var_expr, lldb::DynamicValueType use_dynamic,
> + llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
> uint32_t options, lldb::VariableSP &var_sp, Error &error);
>
> //------------------------------------------------------------------
>
> Modified: lldb/trunk/source/Target/StackFrame.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=287189&r1=287188&r2=287189&view=diff
> ==============================================================================
> --- lldb/trunk/source/Target/StackFrame.cpp (original)
> +++ lldb/trunk/source/Target/StackFrame.cpp Wed Nov 16 19:37:52 2016
> @@ -221,18 +221,17 @@ bool StackFrame::ChangePC(addr_t pc) {
>
> const char *StackFrame::Disassemble() {
> std::lock_guard<std::recursive_mutex> guard(m_mutex);
> - if (m_disassembly.GetSize() == 0) {
> - ExecutionContext exe_ctx(shared_from_this());
> - Target *target = exe_ctx.GetTargetPtr();
> - if (target) {
> - const char *plugin_name = nullptr;
> - const char *flavor = nullptr;
> - Disassembler::Disassemble(target->GetDebugger(),
> - target->GetArchitecture(), plugin_name, flavor,
> - exe_ctx, 0, false, 0, 0, m_disassembly);
> - }
> - if (m_disassembly.GetSize() == 0)
> - return nullptr;
> + if (m_disassembly.Empty())
> + return nullptr;
> +
> + ExecutionContext exe_ctx(shared_from_this());
> + Target *target = exe_ctx.GetTargetPtr();
> + if (target) {
> + const char *plugin_name = nullptr;
> + const char *flavor = nullptr;
> + Disassembler::Disassemble(target->GetDebugger(), target->GetArchitecture(),
> + plugin_name, flavor, exe_ctx, 0, false, 0, 0,
> + m_disassembly);
> }
> return m_disassembly.GetData();
> }
> @@ -485,579 +484,557 @@ StackFrame::GetInScopeVariableList(bool
> }
>
> ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
> - const char *var_expr_cstr, DynamicValueType use_dynamic, uint32_t options,
> - VariableSP &var_sp, Error &error) {
> + llvm::StringRef var_expr_cstr, DynamicValueType use_dynamic,
> + uint32_t options, VariableSP &var_sp, Error &error) {
> // We can't fetch variable information for a history stack frame.
> if (m_is_history_frame)
> return ValueObjectSP();
>
> - if (var_expr_cstr && var_expr_cstr[0]) {
> - const bool check_ptr_vs_member =
> - (options & eExpressionPathOptionCheckPtrVsMember) != 0;
> - const bool no_fragile_ivar =
> - (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
> - const bool no_synth_child =
> - (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
> - // const bool no_synth_array = (options &
> - // eExpressionPathOptionsNoSyntheticArrayRange) != 0;
> - error.Clear();
> - bool deref = false;
> - bool address_of = false;
> - ValueObjectSP valobj_sp;
> - const bool get_file_globals = true;
> - // When looking up a variable for an expression, we need only consider the
> - // variables that are in scope.
> - VariableListSP var_list_sp(GetInScopeVariableList(get_file_globals));
> - VariableList *variable_list = var_list_sp.get();
> -
> - if (variable_list) {
> - // If first character is a '*', then show pointer contents
> - const char *var_expr = var_expr_cstr;
> - if (var_expr[0] == '*') {
> - deref = true;
> - var_expr++; // Skip the '*'
> - } else if (var_expr[0] == '&') {
> - address_of = true;
> - var_expr++; // Skip the '&'
> - }
> -
> - std::string var_path(var_expr);
> - size_t separator_idx = var_path.find_first_of(".-[=+~|&^%#@!/?,<>{}");
> - StreamString var_expr_path_strm;
> -
> - ConstString name_const_string;
> - if (separator_idx == std::string::npos)
> - name_const_string.SetCString(var_path.c_str());
> - else
> - name_const_string.SetCStringWithLength(var_path.c_str(), separator_idx);
> + if (var_expr_cstr.empty()) {
> + error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr);
> + return ValueObjectSP();
> + }
> +
> + const bool check_ptr_vs_member =
> + (options & eExpressionPathOptionCheckPtrVsMember) != 0;
> + const bool no_fragile_ivar =
> + (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
> + const bool no_synth_child =
> + (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
> + // const bool no_synth_array = (options &
> + // eExpressionPathOptionsNoSyntheticArrayRange) != 0;
> + error.Clear();
> + bool deref = false;
> + bool address_of = false;
> + ValueObjectSP valobj_sp;
> + const bool get_file_globals = true;
> + // When looking up a variable for an expression, we need only consider the
> + // variables that are in scope.
> + VariableListSP var_list_sp(GetInScopeVariableList(get_file_globals));
> + VariableList *variable_list = var_list_sp.get();
> +
> + if (!variable_list)
> + return ValueObjectSP();
> +
> + // If first character is a '*', then show pointer contents
> + llvm::StringRef var_expr = var_expr_cstr;
> + std::string var_expr_storage;
> + if (var_expr[0] == '*') {
> + deref = true;
> + var_expr = var_expr.drop_front(); // Skip the '*'
> + } else if (var_expr[0] == '&') {
> + address_of = true;
> + var_expr = var_expr.drop_front(); // Skip the '&'
> + }
> +
> + size_t separator_idx = var_expr.find_first_of(".-[=+~|&^%#@!/?,<>{}");
> + StreamString var_expr_path_strm;
>
> - var_sp = variable_list->FindVariable(name_const_string, false);
> + ConstString name_const_string(var_expr.substr(0, separator_idx));
>
> - bool synthetically_added_instance_object = false;
> + var_sp = variable_list->FindVariable(name_const_string, false);
>
> - if (var_sp) {
> - var_path.erase(0, name_const_string.GetLength());
> + bool synthetically_added_instance_object = false;
> +
> + if (var_sp) {
> + var_expr = var_expr.drop_front(name_const_string.GetLength());
> + }
> +
> + if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) {
> + // Check for direct ivars access which helps us with implicit
> + // access to ivars with the "this->" or "self->"
> + GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock);
> + lldb::LanguageType method_language = eLanguageTypeUnknown;
> + bool is_instance_method = false;
> + ConstString method_object_name;
> + if (m_sc.GetFunctionMethodInfo(method_language, is_instance_method,
> + method_object_name)) {
> + if (is_instance_method && method_object_name) {
> + var_sp = variable_list->FindVariable(method_object_name);
> + if (var_sp) {
> + separator_idx = 0;
> + var_expr_storage = "->";
> + var_expr_storage += var_expr;
> + var_expr = var_expr_storage;
> + synthetically_added_instance_object = true;
> + }
> }
> + }
> + }
>
> - if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess)) {
> - // Check for direct ivars access which helps us with implicit
> - // access to ivars with the "this->" or "self->"
> - GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock);
> - lldb::LanguageType method_language = eLanguageTypeUnknown;
> - bool is_instance_method = false;
> - ConstString method_object_name;
> - if (m_sc.GetFunctionMethodInfo(method_language, is_instance_method,
> - method_object_name)) {
> - if (is_instance_method && method_object_name) {
> - var_sp = variable_list->FindVariable(method_object_name);
> - if (var_sp) {
> - separator_idx = 0;
> - var_path.insert(0, "->");
> - synthetically_added_instance_object = true;
> - }
> - }
> + if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) {
> + // Check if any anonymous unions are there which contain a variable with
> + // the name we need
> + for (size_t i = 0; i < variable_list->GetSize(); i++) {
> + VariableSP variable_sp = variable_list->GetVariableAtIndex(i);
> + if (!variable_sp)
> + continue;
> + if (!variable_sp->GetName().IsEmpty())
> + continue;
> +
> + Type *var_type = variable_sp->GetType();
> + if (!var_type)
> + continue;
> +
> + if (!var_type->GetForwardCompilerType().IsAnonymousType())
> + continue;
> + valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic);
> + if (!valobj_sp)
> + return valobj_sp;
> + valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string, true);
> + if (valobj_sp)
> + break;
> + }
> + }
> +
> + if (var_sp && !valobj_sp) {
> + valobj_sp = GetValueObjectForFrameVariable(var_sp, use_dynamic);
> + if (!valobj_sp)
> + return valobj_sp;
> + }
> + if (!valobj_sp) {
> + error.SetErrorStringWithFormat("no variable named '%s' found in this frame",
> + name_const_string.GetCString());
> + return ValueObjectSP();
> + }
> +
> + // We are dumping at least one child
> + while (separator_idx != std::string::npos) {
> + // Calculate the next separator index ahead of time
> + ValueObjectSP child_valobj_sp;
> + const char separator_type = var_expr[0];
> + switch (separator_type) {
> + case '-':
> + if (var_expr.size() >= 2 && var_expr[1] != '>')
> + return ValueObjectSP();
> +
> + if (no_fragile_ivar) {
> + // Make sure we aren't trying to deref an objective
> + // C ivar if this is not allowed
> + const uint32_t pointer_type_flags =
> + valobj_sp->GetCompilerType().GetTypeInfo(nullptr);
> + if ((pointer_type_flags & eTypeIsObjC) &&
> + (pointer_type_flags & eTypeIsPointer)) {
> + // This was an objective C object pointer and
> + // it was requested we skip any fragile ivars
> + // so return nothing here
> + return ValueObjectSP();
> + }
> + }
> + var_expr = var_expr.drop_front(); // Remove the '-'
> + LLVM_FALLTHROUGH;
> + case '.': {
> + const bool expr_is_ptr = var_expr[0] == '>';
> +
> + var_expr = var_expr.drop_front(); // Remove the '.' or '>'
> + separator_idx = var_expr.find_first_of(".-[");
> + ConstString child_name(var_expr.substr(0, var_expr.find_first_of(".-[")));
> +
> + if (check_ptr_vs_member) {
> + // We either have a pointer type and need to verify
> + // valobj_sp is a pointer, or we have a member of a
> + // class/union/struct being accessed with the . syntax
> + // and need to verify we don't have a pointer.
> + const bool actual_is_ptr = valobj_sp->IsPointerType();
> +
> + if (actual_is_ptr != expr_is_ptr) {
> + // Incorrect use of "." with a pointer, or "->" with
> + // a class/union/struct instance or reference.
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + if (actual_is_ptr)
> + error.SetErrorStringWithFormat(
> + "\"%s\" is a pointer and . was used to attempt to access "
> + "\"%s\". Did you mean \"%s->%s\"?",
> + var_expr_path_strm.GetData(), child_name.GetCString(),
> + var_expr_path_strm.GetData(), var_expr.str().c_str());
> + else
> + error.SetErrorStringWithFormat(
> + "\"%s\" is not a pointer and -> was used to attempt to "
> + "access \"%s\". Did you mean \"%s.%s\"?",
> + var_expr_path_strm.GetData(), child_name.GetCString(),
> + var_expr_path_strm.GetData(), var_expr.str().c_str());
> + return ValueObjectSP();
> }
> }
> + child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name, true);
> + if (!child_valobj_sp) {
> + if (!no_synth_child) {
> + child_valobj_sp = valobj_sp->GetSyntheticValue();
> + if (child_valobj_sp)
> + child_valobj_sp =
> + child_valobj_sp->GetChildMemberWithName(child_name, true);
> + }
>
> - if (!var_sp && (options & eExpressionPathOptionsInspectAnonymousUnions)) {
> - // Check if any anonymous unions are there which contain a variable with
> - // the name we need
> - for (size_t i = 0; i < variable_list->GetSize(); i++) {
> - if (VariableSP variable_sp = variable_list->GetVariableAtIndex(i)) {
> - if (variable_sp->GetName().IsEmpty()) {
> - if (Type *var_type = variable_sp->GetType()) {
> - if (var_type->GetForwardCompilerType().IsAnonymousType()) {
> - valobj_sp =
> - GetValueObjectForFrameVariable(variable_sp, use_dynamic);
> - if (!valobj_sp)
> - return valobj_sp;
> - valobj_sp = valobj_sp->GetChildMemberWithName(
> - name_const_string, true);
> - if (valobj_sp)
> - break;
> - }
> - }
> + if (no_synth_child || !child_valobj_sp) {
> + // No child member with name "child_name"
> + if (synthetically_added_instance_object) {
> + // We added a "this->" or "self->" to the beginning of the
> + // expression
> + // and this is the first pointer ivar access, so just return
> + // the normal
> + // error
> + error.SetErrorStringWithFormat(
> + "no variable or instance variable named '%s' found in "
> + "this frame",
> + name_const_string.GetCString());
> + } else {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + if (child_name) {
> + error.SetErrorStringWithFormat(
> + "\"%s\" is not a member of \"(%s) %s\"",
> + child_name.GetCString(),
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + } else {
> + error.SetErrorStringWithFormat(
> + "incomplete expression path after \"%s\" in \"%s\"",
> + var_expr_path_strm.GetData(), var_expr_cstr);
> }
> }
> + return ValueObjectSP();
> }
> }
> + synthetically_added_instance_object = false;
> + // Remove the child name from the path
> + var_expr = var_expr.drop_front(child_name.GetLength());
> + if (use_dynamic != eNoDynamicValues) {
> + ValueObjectSP dynamic_value_sp(
> + child_valobj_sp->GetDynamicValue(use_dynamic));
> + if (dynamic_value_sp)
> + child_valobj_sp = dynamic_value_sp;
> + }
> + } break;
> +
> + case '[': {
> + // Array member access, or treating pointer as an array
> + // Need at least two brackets and a number
> + if (var_expr.size() <= 2) {
> + error.SetErrorStringWithFormat(
> + "invalid square bracket encountered after \"%s\" in \"%s\"",
> + var_expr_path_strm.GetData(), var_expr.str().c_str());
> + return ValueObjectSP();
> + }
>
> - if (var_sp && !valobj_sp) {
> - valobj_sp = GetValueObjectForFrameVariable(var_sp, use_dynamic);
> - if (!valobj_sp)
> - return valobj_sp;
> - }
> - if (valobj_sp) {
> - // We are dumping at least one child
> - while (separator_idx != std::string::npos) {
> - // Calculate the next separator index ahead of time
> - ValueObjectSP child_valobj_sp;
> - const char separator_type = var_path[0];
> - switch (separator_type) {
> - case '-':
> - if (var_path.size() >= 2 && var_path[1] != '>')
> - return ValueObjectSP();
> -
> - if (no_fragile_ivar) {
> - // Make sure we aren't trying to deref an objective
> - // C ivar if this is not allowed
> - const uint32_t pointer_type_flags =
> - valobj_sp->GetCompilerType().GetTypeInfo(nullptr);
> - if ((pointer_type_flags & eTypeIsObjC) &&
> - (pointer_type_flags & eTypeIsPointer)) {
> - // This was an objective C object pointer and
> - // it was requested we skip any fragile ivars
> - // so return nothing here
> - return ValueObjectSP();
> - }
> - }
> - var_path.erase(0, 1); // Remove the '-'
> - LLVM_FALLTHROUGH;
> - case '.': {
> - const bool expr_is_ptr = var_path[0] == '>';
> -
> - var_path.erase(0, 1); // Remove the '.' or '>'
> - separator_idx = var_path.find_first_of(".-[");
> - ConstString child_name;
> - if (separator_idx == std::string::npos)
> - child_name.SetCString(var_path.c_str());
> - else
> - child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
> -
> - if (check_ptr_vs_member) {
> - // We either have a pointer type and need to verify
> - // valobj_sp is a pointer, or we have a member of a
> - // class/union/struct being accessed with the . syntax
> - // and need to verify we don't have a pointer.
> - const bool actual_is_ptr = valobj_sp->IsPointerType();
> -
> - if (actual_is_ptr != expr_is_ptr) {
> - // Incorrect use of "." with a pointer, or "->" with
> - // a class/union/struct instance or reference.
> + // Drop the open brace.
> + var_expr = var_expr.drop_front();
> + long child_index = 0;
> +
> + // If there's no closing brace, this is an invalid expression.
> + size_t end_pos = var_expr.find_first_of(']');
> + if (end_pos == llvm::StringRef::npos) {
> + error.SetErrorStringWithFormat(
> + "missing closing square bracket in expression \"%s\"",
> + var_expr_path_strm.GetData());
> + return ValueObjectSP();
> + }
> + llvm::StringRef index_expr = var_expr.take_front(end_pos);
> + llvm::StringRef original_index_expr = index_expr;
> + // Drop all of "[index_expr]"
> + var_expr = var_expr.drop_front(end_pos + 1);
> +
> + if (index_expr.consumeInteger(0, child_index)) {
> + // If there was no integer anywhere in the index expression, this is
> + // erroneous expression.
> + error.SetErrorStringWithFormat("invalid index expression \"%s\"",
> + index_expr.str().c_str());
> + return ValueObjectSP();
> + }
> +
> + if (index_expr.empty()) {
> + // The entire index expression was a single integer.
> +
> + if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
> + // what we have is *ptr[low]. the most similar C++ syntax is to deref
> + // ptr and extract bit low out of it. reading array item low would be
> + // done by saying ptr[low], without a deref * sign
> + Error error;
> + ValueObjectSP temp(valobj_sp->Dereference(error));
> + if (error.Fail()) {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + error.SetErrorStringWithFormat(
> + "could not dereference \"(%s) %s\"",
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + return ValueObjectSP();
> + }
> + valobj_sp = temp;
> + deref = false;
> + } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
> + deref) {
> + // what we have is *arr[low]. the most similar C++ syntax is
> + // to get arr[0]
> + // (an operation that is equivalent to deref-ing arr)
> + // and extract bit low out of it. reading array item low
> + // would be done by saying arr[low], without a deref * sign
> + Error error;
> + ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
> + if (error.Fail()) {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + error.SetErrorStringWithFormat(
> + "could not get item 0 for \"(%s) %s\"",
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + return ValueObjectSP();
> + }
> + valobj_sp = temp;
> + deref = false;
> + }
> +
> + bool is_incomplete_array = false;
> + if (valobj_sp->IsPointerType()) {
> + bool is_objc_pointer = true;
> +
> + if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
> + eLanguageTypeObjC)
> + is_objc_pointer = false;
> + else if (!valobj_sp->GetCompilerType().IsPointerType())
> + is_objc_pointer = false;
> +
> + if (no_synth_child && is_objc_pointer) {
> + error.SetErrorStringWithFormat(
> + "\"(%s) %s\" is an Objective-C pointer, and cannot be "
> + "subscripted",
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> +
> + return ValueObjectSP();
> + } else if (is_objc_pointer) {
> + // dereferencing ObjC variables is not valid.. so let's try
> + // and recur to synthetic children
> + ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
> + if (!synthetic /* no synthetic */
> + || synthetic == valobj_sp) /* synthetic is the same as
> + the original object */
> + {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + error.SetErrorStringWithFormat(
> + "\"(%s) %s\" is not an array type",
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + } else if (
> + static_cast<uint32_t>(child_index) >=
> + synthetic
> + ->GetNumChildren() /* synthetic does not have that many values */) {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + error.SetErrorStringWithFormat(
> + "array index %ld is not valid for \"(%s) %s\"", child_index,
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + } else {
> + child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
> + if (!child_valobj_sp) {
> valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - if (actual_is_ptr)
> - error.SetErrorStringWithFormat(
> - "\"%s\" is a pointer and . was used to attempt to access "
> - "\"%s\". Did you mean \"%s->%s\"?",
> - var_expr_path_strm.GetData(), child_name.GetCString(),
> - var_expr_path_strm.GetData(), var_path.c_str());
> - else
> - error.SetErrorStringWithFormat(
> - "\"%s\" is not a pointer and -> was used to attempt to "
> - "access \"%s\". Did you mean \"%s.%s\"?",
> - var_expr_path_strm.GetData(), child_name.GetCString(),
> - var_expr_path_strm.GetData(), var_path.c_str());
> - return ValueObjectSP();
> + error.SetErrorStringWithFormat(
> + "array index %ld is not valid for \"(%s) %s\"", child_index,
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> }
> }
> + } else {
> child_valobj_sp =
> - valobj_sp->GetChildMemberWithName(child_name, true);
> + valobj_sp->GetSyntheticArrayMember(child_index, true);
> if (!child_valobj_sp) {
> - if (!no_synth_child) {
> - child_valobj_sp = valobj_sp->GetSyntheticValue();
> - if (child_valobj_sp)
> - child_valobj_sp =
> - child_valobj_sp->GetChildMemberWithName(child_name, true);
> - }
> -
> - if (no_synth_child || !child_valobj_sp) {
> - // No child member with name "child_name"
> - if (synthetically_added_instance_object) {
> - // We added a "this->" or "self->" to the beginning of the
> - // expression
> - // and this is the first pointer ivar access, so just return
> - // the normal
> - // error
> - error.SetErrorStringWithFormat(
> - "no variable or instance variable named '%s' found in "
> - "this frame",
> - name_const_string.GetCString());
> - } else {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - if (child_name) {
> - error.SetErrorStringWithFormat(
> - "\"%s\" is not a member of \"(%s) %s\"",
> - child_name.GetCString(),
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - } else {
> - error.SetErrorStringWithFormat(
> - "incomplete expression path after \"%s\" in \"%s\"",
> - var_expr_path_strm.GetData(), var_expr_cstr);
> - }
> - }
> - return ValueObjectSP();
> - }
> - }
> - synthetically_added_instance_object = false;
> - // Remove the child name from the path
> - var_path.erase(0, child_name.GetLength());
> - if (use_dynamic != eNoDynamicValues) {
> - ValueObjectSP dynamic_value_sp(
> - child_valobj_sp->GetDynamicValue(use_dynamic));
> - if (dynamic_value_sp)
> - child_valobj_sp = dynamic_value_sp;
> - }
> - } break;
> -
> - case '[':
> - // Array member access, or treating pointer as an array
> - if (var_path.size() > 2) // Need at least two brackets and a number
> - {
> - char *end = nullptr;
> - long child_index = ::strtol(&var_path[1], &end, 0);
> - if (end && *end == ']' &&
> - *(end - 1) != '[') // this code forces an error in the case of
> - // arr[]. as bitfield[] is not a good
> - // syntax we're good to go
> - {
> - if (valobj_sp->GetCompilerType().IsPointerToScalarType() &&
> - deref) {
> - // what we have is *ptr[low]. the most similar C++ syntax is
> - // to deref ptr
> - // and extract bit low out of it. reading array item low
> - // would be done by saying ptr[low], without a deref * sign
> - Error error;
> - ValueObjectSP temp(valobj_sp->Dereference(error));
> - if (error.Fail()) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "could not dereference \"(%s) %s\"",
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - return ValueObjectSP();
> - }
> - valobj_sp = temp;
> - deref = false;
> - } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
> - deref) {
> - // what we have is *arr[low]. the most similar C++ syntax is
> - // to get arr[0]
> - // (an operation that is equivalent to deref-ing arr)
> - // and extract bit low out of it. reading array item low
> - // would be done by saying arr[low], without a deref * sign
> - Error error;
> - ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
> - if (error.Fail()) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "could not get item 0 for \"(%s) %s\"",
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - return ValueObjectSP();
> - }
> - valobj_sp = temp;
> - deref = false;
> - }
> -
> - bool is_incomplete_array = false;
> - if (valobj_sp->IsPointerType()) {
> - bool is_objc_pointer = true;
> -
> - if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
> - eLanguageTypeObjC)
> - is_objc_pointer = false;
> - else if (!valobj_sp->GetCompilerType().IsPointerType())
> - is_objc_pointer = false;
> -
> - if (no_synth_child && is_objc_pointer) {
> - error.SetErrorStringWithFormat(
> - "\"(%s) %s\" is an Objective-C pointer, and cannot be "
> - "subscripted",
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> -
> - return ValueObjectSP();
> - } else if (is_objc_pointer) {
> - // dereferencing ObjC variables is not valid.. so let's try
> - // and recur to synthetic children
> - ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
> - if (!synthetic /* no synthetic */
> - || synthetic == valobj_sp) /* synthetic is the same as
> - the original object */
> - {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "\"(%s) %s\" is not an array type",
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - } else if (
> - static_cast<uint32_t>(child_index) >=
> - synthetic
> - ->GetNumChildren() /* synthetic does not have that many values */) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "array index %ld is not valid for \"(%s) %s\"",
> - child_index,
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - } else {
> - child_valobj_sp =
> - synthetic->GetChildAtIndex(child_index, true);
> - if (!child_valobj_sp) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "array index %ld is not valid for \"(%s) %s\"",
> - child_index, valobj_sp->GetTypeName().AsCString(
> - "<invalid type>"),
> - var_expr_path_strm.GetData());
> - }
> - }
> - } else {
> - child_valobj_sp =
> - valobj_sp->GetSyntheticArrayMember(child_index, true);
> - if (!child_valobj_sp) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "failed to use pointer as array for index %ld for "
> - "\"(%s) %s\"",
> - child_index,
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - }
> - }
> - } else if (valobj_sp->GetCompilerType().IsArrayType(
> - nullptr, nullptr, &is_incomplete_array)) {
> - // Pass false to dynamic_value here so we can tell the
> - // difference between
> - // no dynamic value and no member of this type...
> - child_valobj_sp =
> - valobj_sp->GetChildAtIndex(child_index, true);
> - if (!child_valobj_sp &&
> - (is_incomplete_array || !no_synth_child))
> - child_valobj_sp =
> - valobj_sp->GetSyntheticArrayMember(child_index, true);
> -
> - if (!child_valobj_sp) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "array index %ld is not valid for \"(%s) %s\"",
> - child_index,
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - }
> - } else if (valobj_sp->GetCompilerType().IsScalarType()) {
> - // this is a bitfield asking to display just one bit
> - child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
> - child_index, child_index, true);
> - if (!child_valobj_sp) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
> - child_index, child_index,
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - }
> - } else {
> - ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
> - if (no_synth_child /* synthetic is forbidden */ ||
> - !synthetic /* no synthetic */
> - || synthetic == valobj_sp) /* synthetic is the same as the
> - original object */
> - {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "\"(%s) %s\" is not an array type",
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - } else if (
> - static_cast<uint32_t>(child_index) >=
> - synthetic
> - ->GetNumChildren() /* synthetic does not have that many values */) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "array index %ld is not valid for \"(%s) %s\"",
> - child_index,
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - } else {
> - child_valobj_sp =
> - synthetic->GetChildAtIndex(child_index, true);
> - if (!child_valobj_sp) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "array index %ld is not valid for \"(%s) %s\"",
> - child_index,
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - }
> - }
> - }
> -
> - if (!child_valobj_sp) {
> - // Invalid array index...
> - return ValueObjectSP();
> - }
> -
> - // Erase the array member specification '[%i]' where
> - // %i is the array index
> - var_path.erase(0, (end - var_path.c_str()) + 1);
> - separator_idx = var_path.find_first_of(".-[");
> - if (use_dynamic != eNoDynamicValues) {
> - ValueObjectSP dynamic_value_sp(
> - child_valobj_sp->GetDynamicValue(use_dynamic));
> - if (dynamic_value_sp)
> - child_valobj_sp = dynamic_value_sp;
> - }
> - // Break out early from the switch since we were
> - // able to find the child member
> - break;
> - } else if (end && *end == '-') {
> - // this is most probably a BitField, let's take a look
> - char *real_end = nullptr;
> - long final_index = ::strtol(end + 1, &real_end, 0);
> - bool expand_bitfield = true;
> - if (real_end && *real_end == ']') {
> - // if the format given is [high-low], swap range
> - if (child_index > final_index) {
> - long temp = child_index;
> - child_index = final_index;
> - final_index = temp;
> - }
> -
> - if (valobj_sp->GetCompilerType().IsPointerToScalarType() &&
> - deref) {
> - // what we have is *ptr[low-high]. the most similar C++
> - // syntax is to deref ptr
> - // and extract bits low thru high out of it. reading array
> - // items low thru high
> - // would be done by saying ptr[low-high], without a deref *
> - // sign
> - Error error;
> - ValueObjectSP temp(valobj_sp->Dereference(error));
> - if (error.Fail()) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "could not dereference \"(%s) %s\"",
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - return ValueObjectSP();
> - }
> - valobj_sp = temp;
> - deref = false;
> - } else if (valobj_sp->GetCompilerType()
> - .IsArrayOfScalarType() &&
> - deref) {
> - // what we have is *arr[low-high]. the most similar C++
> - // syntax is to get arr[0]
> - // (an operation that is equivalent to deref-ing arr)
> - // and extract bits low thru high out of it. reading array
> - // items low thru high
> - // would be done by saying arr[low-high], without a deref *
> - // sign
> - Error error;
> - ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
> - if (error.Fail()) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "could not get item 0 for \"(%s) %s\"",
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - return ValueObjectSP();
> - }
> - valobj_sp = temp;
> - deref = false;
> - }
> - /*else if (valobj_sp->IsArrayType() ||
> - valobj_sp->IsPointerType())
> - {
> - child_valobj_sp =
> - valobj_sp->GetSyntheticArrayRangeChild(child_index,
> - final_index, true);
> - expand_bitfield = false;
> - if (!child_valobj_sp)
> - {
> - valobj_sp->GetExpressionPath (var_expr_path_strm,
> - false);
> - error.SetErrorStringWithFormat ("array range %i-%i is
> - not valid for \"(%s) %s\"",
> - child_index,
> - final_index,
> - valobj_sp->GetTypeName().AsCString("<invalid
> - type>"),
> - var_expr_path_strm.c_str());
> - }
> - }*/
> -
> - if (expand_bitfield) {
> - child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
> - child_index, final_index, true);
> - if (!child_valobj_sp) {
> - valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> - error.SetErrorStringWithFormat(
> - "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
> - child_index, final_index,
> - valobj_sp->GetTypeName().AsCString("<invalid type>"),
> - var_expr_path_strm.GetData());
> - }
> - }
> - }
> -
> - if (!child_valobj_sp) {
> - // Invalid bitfield range...
> - return ValueObjectSP();
> - }
> -
> - // Erase the bitfield member specification '[%i-%i]' where
> - // %i is the index
> - var_path.erase(0, (real_end - var_path.c_str()) + 1);
> - separator_idx = var_path.find_first_of(".-[");
> - if (use_dynamic != eNoDynamicValues) {
> - ValueObjectSP dynamic_value_sp(
> - child_valobj_sp->GetDynamicValue(use_dynamic));
> - if (dynamic_value_sp)
> - child_valobj_sp = dynamic_value_sp;
> - }
> - // Break out early from the switch since we were
> - // able to find the child member
> - break;
> - }
> - } else {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> error.SetErrorStringWithFormat(
> - "invalid square bracket encountered after \"%s\" in \"%s\"",
> - var_expr_path_strm.GetData(), var_path.c_str());
> + "failed to use pointer as array for index %ld for "
> + "\"(%s) %s\"",
> + child_index,
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> }
> - return ValueObjectSP();
> + }
> + } else if (valobj_sp->GetCompilerType().IsArrayType(
> + nullptr, nullptr, &is_incomplete_array)) {
> + // Pass false to dynamic_value here so we can tell the
> + // difference between
> + // no dynamic value and no member of this type...
> + child_valobj_sp = valobj_sp->GetChildAtIndex(child_index, true);
> + if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
> + child_valobj_sp =
> + valobj_sp->GetSyntheticArrayMember(child_index, true);
>
> - default:
> - // Failure...
> - {
> + if (!child_valobj_sp) {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + error.SetErrorStringWithFormat(
> + "array index %ld is not valid for \"(%s) %s\"", child_index,
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + }
> + } else if (valobj_sp->GetCompilerType().IsScalarType()) {
> + // this is a bitfield asking to display just one bit
> + child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
> + child_index, child_index, true);
> + if (!child_valobj_sp) {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + error.SetErrorStringWithFormat(
> + "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
> + child_index, child_index,
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + }
> + } else {
> + ValueObjectSP synthetic = valobj_sp->GetSyntheticValue();
> + if (no_synth_child /* synthetic is forbidden */ ||
> + !synthetic /* no synthetic */
> + || synthetic == valobj_sp) /* synthetic is the same as the
> + original object */
> + {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + error.SetErrorStringWithFormat(
> + "\"(%s) %s\" is not an array type",
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + } else if (
> + static_cast<uint32_t>(child_index) >=
> + synthetic
> + ->GetNumChildren() /* synthetic does not have that many values */) {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + error.SetErrorStringWithFormat(
> + "array index %ld is not valid for \"(%s) %s\"", child_index,
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + } else {
> + child_valobj_sp = synthetic->GetChildAtIndex(child_index, true);
> + if (!child_valobj_sp) {
> valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> error.SetErrorStringWithFormat(
> - "unexpected char '%c' encountered after \"%s\" in \"%s\"",
> - separator_type, var_expr_path_strm.GetData(),
> - var_path.c_str());
> -
> - return ValueObjectSP();
> + "array index %ld is not valid for \"(%s) %s\"", child_index,
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> }
> }
> -
> - if (child_valobj_sp)
> - valobj_sp = child_valobj_sp;
> -
> - if (var_path.empty())
> - break;
> - }
> - if (valobj_sp) {
> - if (deref) {
> - ValueObjectSP deref_valobj_sp(valobj_sp->Dereference(error));
> - valobj_sp = deref_valobj_sp;
> - } else if (address_of) {
> - ValueObjectSP address_of_valobj_sp(valobj_sp->AddressOf(error));
> - valobj_sp = address_of_valobj_sp;
> - }
> }
> - return valobj_sp;
> - } else {
> +
> + if (!child_valobj_sp) {
> + // Invalid array index...
> + return ValueObjectSP();
> + }
> +
> + separator_idx = var_expr.find_first_of(".-[");
> + if (use_dynamic != eNoDynamicValues) {
> + ValueObjectSP dynamic_value_sp(
> + child_valobj_sp->GetDynamicValue(use_dynamic));
> + if (dynamic_value_sp)
> + child_valobj_sp = dynamic_value_sp;
> + }
> + // Break out early from the switch since we were able to find the child
> + // member
> + break;
> + }
> +
> + // this is most probably a BitField, let's take a look
> + if (index_expr.front() != '-') {
> + error.SetErrorStringWithFormat("invalid range expression \"'%s'\"",
> + original_index_expr.str().c_str());
> + return ValueObjectSP();
> + }
> +
> + index_expr.drop_front();
> + long final_index = 0;
> + if (index_expr.getAsInteger(0, final_index)) {
> + error.SetErrorStringWithFormat("invalid range expression \"'%s'\"",
> + original_index_expr.str().c_str());
> + return ValueObjectSP();
> + }
> +
> + // if the format given is [high-low], swap range
> + if (child_index > final_index) {
> + long temp = child_index;
> + child_index = final_index;
> + final_index = temp;
> + }
> +
> + if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
> + // what we have is *ptr[low-high]. the most similar C++ syntax is to
> + // deref ptr and extract bits low thru high out of it. reading array
> + // items low thru high would be done by saying ptr[low-high], without
> + // a deref * sign
> + Error error;
> + ValueObjectSP temp(valobj_sp->Dereference(error));
> + if (error.Fail()) {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + error.SetErrorStringWithFormat(
> + "could not dereference \"(%s) %s\"",
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + return ValueObjectSP();
> + }
> + valobj_sp = temp;
> + deref = false;
> + } else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
> + // what we have is *arr[low-high]. the most similar C++ syntax is to get
> + // arr[0] (an operation that is equivalent to deref-ing arr) and extract
> + // bits low thru high out of it. reading array items low thru high would
> + // be done by saying arr[low-high], without a deref * sign
> + Error error;
> + ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true));
> + if (error.Fail()) {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + error.SetErrorStringWithFormat(
> + "could not get item 0 for \"(%s) %s\"",
> + valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + return ValueObjectSP();
> + }
> + valobj_sp = temp;
> + deref = false;
> + }
> +
> + child_valobj_sp =
> + valobj_sp->GetSyntheticBitFieldChild(child_index, final_index, true);
> + if (!child_valobj_sp) {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> error.SetErrorStringWithFormat(
> - "no variable named '%s' found in this frame",
> - name_const_string.GetCString());
> + "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index,
> + final_index, valobj_sp->GetTypeName().AsCString("<invalid type>"),
> + var_expr_path_strm.GetData());
> + }
> +
> + if (!child_valobj_sp) {
> + // Invalid bitfield range...
> + return ValueObjectSP();
> + }
> +
> + separator_idx = var_expr.find_first_of(".-[");
> + if (use_dynamic != eNoDynamicValues) {
> + ValueObjectSP dynamic_value_sp(
> + child_valobj_sp->GetDynamicValue(use_dynamic));
> + if (dynamic_value_sp)
> + child_valobj_sp = dynamic_value_sp;
> + }
> + // Break out early from the switch since we were able to find the child
> + // member
> + break;
> + }
> + default:
> + // Failure...
> + {
> + valobj_sp->GetExpressionPath(var_expr_path_strm, false);
> + error.SetErrorStringWithFormat(
> + "unexpected char '%c' encountered after \"%s\" in \"%s\"",
> + separator_type, var_expr_path_strm.GetData(),
> + var_expr.str().c_str());
> +
> + return ValueObjectSP();
> }
> }
> - } else {
> - error.SetErrorStringWithFormat("invalid variable path '%s'", var_expr_cstr);
> +
> + if (child_valobj_sp)
> + valobj_sp = child_valobj_sp;
> +
> + if (var_expr.empty())
> + break;
> + }
> + if (valobj_sp) {
> + if (deref) {
> + ValueObjectSP deref_valobj_sp(valobj_sp->Dereference(error));
> + valobj_sp = deref_valobj_sp;
> + } else if (address_of) {
> + ValueObjectSP address_of_valobj_sp(valobj_sp->AddressOf(error));
> + valobj_sp = address_of_valobj_sp;
> + }
> }
> - return ValueObjectSP();
> + return valobj_sp;
> }
>
> bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Error *error_ptr) {
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
More information about the lldb-commits
mailing list