xref: /llvm-project/lldb/test/API/lang/cpp/trivial_abi/TestTrivialABI.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"""
2Test that we work properly with classes with the trivial_abi attribute
3"""
4
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class TestTrivialABI(TestBase):
13    NO_DEBUG_INFO_TESTCASE = True
14
15    @skipUnlessSupportedTypeAttribute("trivial_abi")
16    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr37995")
17    @expectedFailureAll(
18        archs=["aarch64"], oslist=["freebsd", "linux"], bugnumber="llvm.org/pr44161"
19    )
20    def test_call_trivial(self):
21        """Test that we can print a variable & call a function with a trivial ABI class."""
22        self.build()
23        self.main_source_file = lldb.SBFileSpec("main.cpp")
24        self.expr_test(True)
25
26    @skipUnlessSupportedTypeAttribute("trivial_abi")
27    # fixed for SysV-x86_64 ABI, but not Windows-x86_64
28    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr36870")
29    @expectedFailureAll(
30        archs=["arm", "aarch64"],
31        oslist=["freebsd", "linux"],
32        bugnumber="llvm.org/pr44161",
33    )
34    @expectedFailureAll(
35        archs=["arm64", "arm64e"], bugnumber="<rdar://problem/57844240>"
36    )
37    def test_call_nontrivial(self):
38        """Test that we can print a variable & call a function on the same class w/o the trivial ABI marker."""
39        self.build()
40        self.main_source_file = lldb.SBFileSpec("main.cpp")
41        self.expr_test(False)
42
43    def check_value(self, test_var, ivar_value):
44        self.assertSuccess(test_var.GetError(), "Invalid valobj")
45        ivar = test_var.GetChildMemberWithName("ivar")
46        self.assertSuccess(test_var.GetError(), "Failed to fetch ivar")
47        self.assertEqual(
48            ivar_value, ivar.GetValueAsSigned(), "Got the right value for ivar"
49        )
50
51    def check_frame(self, thread):
52        frame = thread.frames[0]
53        inVal_var = frame.FindVariable("inVal")
54        self.check_value(inVal_var, 10)
55
56        options = lldb.SBExpressionOptions()
57        inVal_expr = frame.EvaluateExpression("inVal", options)
58        self.check_value(inVal_expr, 10)
59
60        thread.StepOut()
61        outVal_ret = thread.GetStopReturnValue()
62        self.check_value(outVal_ret, 30)
63
64    def expr_test(self, trivial):
65        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
66            self, "Set a breakpoint here", self.main_source_file
67        )
68
69        # Stop in a function that takes a trivial value, and try both frame var & expr to get its value:
70        if trivial:
71            self.check_frame(thread)
72            return
73
74        # Now continue to the same thing without the trivial_abi and see if we get that right:
75        threads = lldbutil.continue_to_breakpoint(process, bkpt)
76        self.assertEqual(len(threads), 1, "Hit my breakpoint the second time.")
77
78        self.check_frame(threads[0])
79