forked from OSchip/llvm-project
Fix up LLDB for a change in the way clang represents anonymous unions such that the 'frame variable' command can still find the members of such union as if they were top-level variables in the current scope
llvm-svn: 253613
This commit is contained in:
parent
379cc5e71b
commit
46252398f0
|
@ -47,11 +47,12 @@ class StackFrame :
|
|||
public:
|
||||
enum ExpressionPathOption
|
||||
{
|
||||
eExpressionPathOptionCheckPtrVsMember = (1u << 0),
|
||||
eExpressionPathOptionsNoFragileObjcIvar = (1u << 1),
|
||||
eExpressionPathOptionsNoSyntheticChildren = (1u << 2),
|
||||
eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3),
|
||||
eExpressionPathOptionsAllowDirectIVarAccess = (1u << 4)
|
||||
eExpressionPathOptionCheckPtrVsMember = (1u << 0),
|
||||
eExpressionPathOptionsNoFragileObjcIvar = (1u << 1),
|
||||
eExpressionPathOptionsNoSyntheticChildren = (1u << 2),
|
||||
eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3),
|
||||
eExpressionPathOptionsAllowDirectIVarAccess = (1u << 4),
|
||||
eExpressionPathOptionsInspectAnonymousUnions = (1u << 5)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -0,0 +1,27 @@
|
|||
"""
|
||||
Tests that frame variable looks into anonymous unions
|
||||
"""
|
||||
import lldb
|
||||
from lldbsuite.test.lldbtest import *
|
||||
import lldbsuite.test.lldbutil as lldbutil
|
||||
|
||||
class FrameVariableAnonymousUnionsTestCase(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
def test_with_run_command(self):
|
||||
"""Tests that frame variable looks into anonymous unions"""
|
||||
self.build()
|
||||
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
|
||||
|
||||
line = line_number('main.cpp', '// break here')
|
||||
lldbutil.run_break_set_by_file_and_line (self, "main.cpp", line, num_expected_locations=-1, loc_exact=False)
|
||||
|
||||
self.runCmd("process launch", RUN_SUCCEEDED)
|
||||
|
||||
self.expect('frame variable -f x i', substrs=['ffffff41'])
|
||||
self.expect('frame variable c', substrs=["'A"])
|
||||
|
||||
self.expect('frame variable x', matching=False, substrs=['3'])
|
||||
self.expect('frame variable y', matching=False, substrs=["'B'"])
|
||||
self.expect('frame variable z', matching=False, substrs=['14'])
|
|
@ -0,0 +1,23 @@
|
|||
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
int main() {
|
||||
union {
|
||||
int i;
|
||||
char c;
|
||||
};
|
||||
struct {
|
||||
int x;
|
||||
char y;
|
||||
short z;
|
||||
} s{3,'B',14};
|
||||
i = 0xFFFFFF00;
|
||||
c = 'A';
|
||||
return c; // break here
|
||||
}
|
|
@ -478,7 +478,8 @@ protected:
|
|||
{
|
||||
Error error;
|
||||
uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
|
||||
StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
|
||||
StackFrame::eExpressionPathOptionsAllowDirectIVarAccess |
|
||||
StackFrame::eExpressionPathOptionsInspectAnonymousUnions;
|
||||
lldb::VariableSP var_sp;
|
||||
valobj_sp = frame->GetValueForVariableExpressionPath (name_cstr,
|
||||
m_varobj_options.use_dynamic,
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "lldb/Symbol/Function.h"
|
||||
#include "lldb/Symbol/Symbol.h"
|
||||
#include "lldb/Symbol/SymbolContextScope.h"
|
||||
#include "lldb/Symbol/Type.h"
|
||||
#include "lldb/Symbol/VariableList.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
|
@ -667,7 +668,8 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
|
|||
{
|
||||
var_path.erase (0, name_const_string.GetLength ());
|
||||
}
|
||||
else if (options & eExpressionPathOptionsAllowDirectIVarAccess)
|
||||
|
||||
if (!var_sp && (options & eExpressionPathOptionsAllowDirectIVarAccess))
|
||||
{
|
||||
// Check for direct ivars access which helps us with implicit
|
||||
// access to ivars with the "this->" or "self->"
|
||||
|
@ -689,13 +691,43 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 (var_sp)
|
||||
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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue