1""" 2Test top-level expressions. 3""" 4 5 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11 12class TopLevelExpressionsTestCase(TestBase): 13 def setUp(self): 14 # Call super's setUp(). 15 TestBase.setUp(self) 16 # Find the line number to break for main.c. 17 self.line = line_number("main.cpp", "// Set breakpoint here") 18 self.dummy_line = line_number("dummy.cpp", "// Set breakpoint here") 19 20 # Disable confirmation prompt to avoid infinite wait 21 self.runCmd("settings set auto-confirm true") 22 self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm")) 23 24 def build_and_run(self): 25 """Test top-level expressions.""" 26 self.build() 27 28 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 29 30 lldbutil.run_break_set_by_file_and_line( 31 self, "main.cpp", self.line, num_expected_locations=1, loc_exact=False 32 ) 33 34 self.runCmd("run", RUN_SUCCEEDED) 35 36 def run_dummy(self): 37 self.runCmd("file " + self.getBuildArtifact("dummy"), CURRENT_EXECUTABLE_SET) 38 39 lldbutil.run_break_set_by_file_and_line( 40 self, 41 "dummy.cpp", 42 self.dummy_line, 43 num_expected_locations=1, 44 loc_exact=False, 45 ) 46 47 self.runCmd("run", RUN_SUCCEEDED) 48 49 @add_test_categories(["pyapi"]) 50 @skipIf(debug_info="gmodules") # not relevant 51 @skipIf(oslist=["windows"]) # Error in record layout on Windows 52 def test_top_level_expressions(self): 53 self.build_and_run() 54 55 resultFromCode = ( 56 self.frame().EvaluateExpression("doTest()").GetValueAsUnsigned() 57 ) 58 59 self.runCmd("kill") 60 61 self.run_dummy() 62 63 codeFile = open("test.cpp", "r") 64 65 expressions = [] 66 current_expression = "" 67 68 for line in codeFile: 69 if line.startswith("// --"): 70 expressions.append(current_expression) 71 current_expression = "" 72 else: 73 current_expression += line 74 75 options = lldb.SBExpressionOptions() 76 options.SetLanguage(lldb.eLanguageTypeC_plus_plus) 77 options.SetTopLevel(True) 78 79 for expression in expressions: 80 self.frame().EvaluateExpression(expression, options) 81 82 resultFromTopLevel = self.frame().EvaluateExpression("doTest()") 83 84 self.assertTrue(resultFromTopLevel.IsValid()) 85 self.assertEqual(resultFromCode, resultFromTopLevel.GetValueAsUnsigned()) 86 87 # Make sure the command line version works as well: 88 self.runCmd("expr --top-level -- int TopLevelFunction() { return 101; }") 89 resultFromTopLevel = self.frame().EvaluateExpression("TopLevelFunction()") 90 self.assertTrue(resultFromTopLevel.IsValid()) 91 self.assertEqual( 92 101, resultFromTopLevel.GetValueAsUnsigned(), "Command line version works." 93 ) 94 95 def test_top_level_expression_without_target(self): 96 self.expect( 97 "expr --top-level -- void func() {}", 98 error=True, 99 substrs=["Top-level code needs to be inserted into a runnable target"], 100 ) 101 102 # FIXME: This doesn't actually generate any code, so LLDB should probably 103 # allow these expressions. 104 self.expect( 105 "expr --top-level -- template<typename T> struct StructT { T m; };", 106 error=True, 107 substrs=["Top-level code needs to be inserted into a runnable target"], 108 ) 109 self.expect( 110 "expr --top-level -- struct Struct { int i; };", 111 error=True, 112 substrs=["Top-level code needs to be inserted into a runnable target"], 113 ) 114