Fix resolution conflict between global and class static variables in C++

llvm-svn: 245381
This commit is contained in:
Paul Herman 2015-08-18 22:46:57 +00:00
parent b058fb47db
commit 10bc1a4e83
9 changed files with 146 additions and 15 deletions

View File

@ -36,7 +36,8 @@ public:
Declaration* decl,
const DWARFExpression& location,
bool external,
bool artificial);
bool artificial,
bool static_member = false);
virtual
~Variable();
@ -99,6 +100,11 @@ public:
return m_artificial;
}
bool IsStaticMember() const
{
return m_static_member;
}
DWARFExpression &
LocationExpression()
{
@ -171,7 +177,8 @@ protected:
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_loc_is_const_data:1; // The m_location expression contains the constant variable value data, not a DWARF location
m_loc_is_const_data:1, // The m_location expression contains the constant variable value data, not a DWARF location
m_static_member:1; // Non-zero if variable is static member of a class or struct.
private:
Variable(const Variable& rhs);
Variable& operator=(const Variable& rhs);

View File

@ -48,10 +48,10 @@ public:
RemoveVariableAtIndex (size_t idx);
lldb::VariableSP
FindVariable (const ConstString& name);
FindVariable (const ConstString& name, bool include_static_members = true);
lldb::VariableSP
FindVariable (const ConstString& name, lldb::ValueType value_type);
FindVariable (const ConstString& name, lldb::ValueType value_type, bool include_static_members = true);
uint32_t
FindVariableIndex (const lldb::VariableSP &var_sp);

View File

@ -3968,7 +3968,6 @@ SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
return 0;
}
VariableSP
SymbolFileDWARF::ParseVariableDIE
(
@ -4124,6 +4123,9 @@ SymbolFileDWARF::ParseVariableDIE
}
}
const DWARFDebugInfoEntry *parent_context_die = GetDeclContextDIEContainingDIE(dwarf_cu, die);
bool is_static_member = die->GetParent()->Tag() == DW_TAG_compile_unit && (parent_context_die->Tag() == DW_TAG_class_type || parent_context_die->Tag() == DW_TAG_structure_type);
ValueType scope = eValueTypeInvalid;
const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
@ -4301,7 +4303,8 @@ SymbolFileDWARF::ParseVariableDIE
&decl,
location,
is_external,
is_artificial));
is_artificial,
is_static_member));
var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
}

View File

@ -44,7 +44,8 @@ Variable::Variable
Declaration* decl_ptr,
const DWARFExpression& location,
bool external,
bool artificial
bool artificial,
bool static_member
) :
UserID(uid),
m_name(name),
@ -55,7 +56,8 @@ Variable::Variable
m_declaration(decl_ptr),
m_location(location),
m_external(external),
m_artificial(artificial)
m_artificial(artificial),
m_static_member(static_member)
{
}

View File

@ -100,7 +100,7 @@ VariableList::FindVariableIndex (const VariableSP &var_sp)
}
VariableSP
VariableList::FindVariable(const ConstString& name)
VariableList::FindVariable(const ConstString& name, bool include_static_members)
{
VariableSP var_sp;
iterator pos, end = m_variables.end();
@ -108,15 +108,18 @@ VariableList::FindVariable(const ConstString& name)
{
if ((*pos)->NameMatches(name))
{
var_sp = (*pos);
break;
if (include_static_members || !(*pos)->IsStaticMember())
{
var_sp = (*pos);
break;
}
}
}
return var_sp;
}
VariableSP
VariableList::FindVariable (const ConstString& name, lldb::ValueType value_type)
VariableList::FindVariable (const ConstString& name, lldb::ValueType value_type, bool include_static_members)
{
VariableSP var_sp;
iterator pos, end = m_variables.end();
@ -124,8 +127,11 @@ VariableList::FindVariable (const ConstString& name, lldb::ValueType value_type)
{
if ((*pos)->NameMatches(name) && (*pos)->GetScope() == value_type)
{
var_sp = (*pos);
break;
if (include_static_members || !(*pos)->IsStaticMember())
{
var_sp = (*pos);
break;
}
}
}
return var_sp;

View File

@ -659,7 +659,7 @@ StackFrame::GetValueForVariableExpressionPath (const char *var_expr_cstr,
else
name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
var_sp = variable_list->FindVariable(name_const_string);
var_sp = variable_list->FindVariable(name_const_string, false);
bool synthetically_added_instance_object = false;

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,83 @@
"""
Test scopes in C++.
"""
import lldb
from lldbtest import *
import lldbutil
class TestCppScopes(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipUnlessDarwin
@dsym_test
def test_with_dsym_and_run_command(self):
self.buildDsym()
self.check()
@dwarf_test
def test_with_dwarf_and_run_command(self):
self.buildDwarf()
self.check()
def setUp(self):
TestBase.setUp(self)
def check(self):
# Get main source file
src_file = "main.cpp"
src_file_spec = lldb.SBFileSpec(src_file)
self.assertTrue(src_file_spec.IsValid(), "Main source file")
# Get the path of the executable
cwd = os.getcwd()
exe_file = "a.out"
exe_path = os.path.join(cwd, exe_file)
# Load the executable
target = self.dbg.CreateTarget(exe_path)
self.assertTrue(target.IsValid(), VALID_TARGET)
# Break on main function
main_breakpoint = target.BreakpointCreateBySourceRegex("// break here", src_file_spec)
self.assertTrue(main_breakpoint.IsValid() and main_breakpoint.GetNumLocations() >= 1, VALID_BREAKPOINT)
# Launch the process
args = None
env = None
process = target.LaunchSimple(args, env, cwd)
self.assertTrue(process.IsValid(), PROCESS_IS_VALID)
# Get the thread of the process
self.assertTrue(process.GetState() == lldb.eStateStopped, PROCESS_STOPPED)
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
# Get current fream of the thread at the breakpoint
frame = thread.GetSelectedFrame()
# Test result for scopes of variables
global_variables = frame.GetVariables(True, True, True, False)
global_variables_assert = {
'A::a': 1111,
'B::a': 2222,
'C::a': 3333,
'::a': 4444,
'a': 4444
}
self.assertTrue(global_variables.GetSize() == 4, "target variable returns all variables")
for variable in global_variables:
name = variable.GetName()
self.assertTrue(name in global_variables_assert, "target variable returns wrong variable " + name)
for name in global_variables_assert:
value = frame.EvaluateExpression(name)
assert_value = global_variables_assert[name]
self.assertTrue(value.IsValid() and value.GetValueAsSigned() == assert_value, name + " = " + str(assert_value))
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@ -0,0 +1,25 @@
class A {
public:
static int a;
int b;
};
class B {
public:
static int a;
int b;
};
struct C {
static int a;
};
int A::a = 1111;
int B::a = 2222;
int C::a = 3333;
int a = 4444;
int main() // break here
{
return 0;
}