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