199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTests that C++ member and static variables have correct layout and scope.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht
699451b44SJordan Rupprecht
799451b44SJordan Rupprechtimport unittest2
899451b44SJordan Rupprechtimport lldb
999451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
1099451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1199451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprecht
148b656b88SRaphael Isemannclass TestCase(TestBase):
1599451b44SJordan Rupprecht
16a3a95286SRaphael Isemann    # We fail to lookup static members on Windows.
17a3a95286SRaphael Isemann    @expectedFailureAll(oslist=["windows"])
188b656b88SRaphael Isemann    def test_access_from_main(self):
1999451b44SJordan Rupprecht        self.build()
208b656b88SRaphael Isemann        lldbutil.run_to_source_breakpoint(self, "// stop in main", lldb.SBFileSpec("main.cpp"))
2199451b44SJordan Rupprecht
228b656b88SRaphael Isemann        self.expect_expr("my_a.m_a", result_type="short", result_value="1")
238b656b88SRaphael Isemann        self.expect_expr("my_a.s_b", result_type="long", result_value="2")
248b656b88SRaphael Isemann        self.expect_expr("my_a.s_c", result_type="int", result_value="3")
2599451b44SJordan Rupprecht
26a3a95286SRaphael Isemann    # We fail to lookup static members on Windows.
27a3a95286SRaphael Isemann    @expectedFailureAll(oslist=["windows"])
288b656b88SRaphael Isemann    def test_access_from_member_function(self):
298b656b88SRaphael Isemann        self.build()
308b656b88SRaphael Isemann        lldbutil.run_to_source_breakpoint(self, "// stop in member function", lldb.SBFileSpec("main.cpp"))
318b656b88SRaphael Isemann        self.expect_expr("m_a", result_type="short", result_value="1")
328b656b88SRaphael Isemann        self.expect_expr("s_b", result_type="long", result_value="2")
338b656b88SRaphael Isemann        self.expect_expr("s_c", result_type="int", result_value="3")
3499451b44SJordan Rupprecht
358b656b88SRaphael Isemann    # Currently lookups find variables that are in any scope.
368b656b88SRaphael Isemann    @expectedFailureAll()
378b656b88SRaphael Isemann    def test_access_without_scope(self):
388b656b88SRaphael Isemann        self.build()
398b656b88SRaphael Isemann        self.createTestTarget()
408b656b88SRaphael Isemann        self.expect("expression s_c", error=True,
4199451b44SJordan Rupprecht                    startstr="error: use of undeclared identifier 's_d'")
42afb446e8SAndy Yankovsky
43e0f2375bSAndy Yankovsky    # We fail to lookup static members on Windows.
44e0f2375bSAndy Yankovsky    @expectedFailureAll(oslist=["windows"])
45afb446e8SAndy Yankovsky    def test_no_crash_in_IR_arithmetic(self):
46afb446e8SAndy Yankovsky        """
47afb446e8SAndy Yankovsky        Test that LLDB doesn't crash on evaluating specific expression involving
48afb446e8SAndy Yankovsky        pointer arithmetic and taking the address of a static class member.
49afb446e8SAndy Yankovsky        See https://bugs.llvm.org/show_bug.cgi?id=52449
50afb446e8SAndy Yankovsky        """
51afb446e8SAndy Yankovsky        self.build()
52afb446e8SAndy Yankovsky        lldbutil.run_to_source_breakpoint(self, "// stop in main", lldb.SBFileSpec("main.cpp"))
53afb446e8SAndy Yankovsky
54afb446e8SAndy Yankovsky        # This expression contains the following IR code:
55afb446e8SAndy Yankovsky        # ... i64 ptrtoint (i32* @_ZN1A3s_cE to i64)) ...
56afb446e8SAndy Yankovsky        expr = "(int*)100 + (long long)(&A::s_c)"
57afb446e8SAndy Yankovsky
58afb446e8SAndy Yankovsky        # The IR interpreter doesn't support non-const operands to the
59afb446e8SAndy Yankovsky        # `GetElementPtr` IR instruction, so verify that it correctly fails to
60afb446e8SAndy Yankovsky        # evaluate expression.
61afb446e8SAndy Yankovsky        opts = lldb.SBExpressionOptions()
62afb446e8SAndy Yankovsky        opts.SetAllowJIT(False)
63afb446e8SAndy Yankovsky        value = self.target().EvaluateExpression(expr, opts)
64afb446e8SAndy Yankovsky        self.assertTrue(value.GetError().Fail())
65afb446e8SAndy Yankovsky        self.assertIn(
66afb446e8SAndy Yankovsky            "Can't evaluate the expression without a running target",
67afb446e8SAndy Yankovsky            value.GetError().GetCString())
68afb446e8SAndy Yankovsky
69afb446e8SAndy Yankovsky        # Evaluating the expression via JIT should work fine.
70afb446e8SAndy Yankovsky        value = self.target().EvaluateExpression(expr)
71afb446e8SAndy Yankovsky        self.assertSuccess(value.GetError())
72*2e0ef179SAndy Yankovsky
73*2e0ef179SAndy Yankovsky    def test_IR_interpreter_can_handle_getelementptr_constants_args(self):
74*2e0ef179SAndy Yankovsky        self.build()
75*2e0ef179SAndy Yankovsky        lldbutil.run_to_source_breakpoint(self, "// stop in main", lldb.SBFileSpec("main.cpp"))
76*2e0ef179SAndy Yankovsky
77*2e0ef179SAndy Yankovsky        # This expression contains the following IR code:
78*2e0ef179SAndy Yankovsky        # ... getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
79*2e0ef179SAndy Yankovsky        expr = "arr[0]"
80*2e0ef179SAndy Yankovsky
81*2e0ef179SAndy Yankovsky        # The IR interpreter supports const operands to the `GetElementPtr` IR
82*2e0ef179SAndy Yankovsky        # instruction, so it should be able to evaluate expression without JIT.
83*2e0ef179SAndy Yankovsky        opts = lldb.SBExpressionOptions()
84*2e0ef179SAndy Yankovsky        opts.SetAllowJIT(False)
85*2e0ef179SAndy Yankovsky        value = self.target().EvaluateExpression(expr, opts)
86*2e0ef179SAndy Yankovsky        self.assertSuccess(value.GetError())
87