brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.6 KiB · e35cfa6 Raw
138 lines · python
1""" Test that evaluating expressions from within C++ lambdas works2    Particularly, we test the case of capturing "this" and3    using members of the captured object in expression evaluation4    while we're on a breakpoint inside a lambda.5"""6 7 8import lldb9from lldbsuite.test.lldbtest import *10 11 12class ExprInsideLambdaTestCase(TestBase):13    def expectExprError(self, expr: str, expected: str):14        frame = self.thread.GetFrameAtIndex(0)15        value = frame.EvaluateExpression(expr)16        errmsg = value.GetError().GetCString()17        self.assertIn(expected, errmsg)18 19    def test_expr_inside_lambda(self):20        """Test that lldb evaluating expressions inside lambda expressions works correctly."""21        self.build()22        (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(23            self, "break here", lldb.SBFileSpec("main.cpp")24        )25 26        # Inside 'Foo::method'27 28        # Check access to captured 'this'29        self.expect_expr("class_var", result_type="int", result_value="109")30        self.expect_expr("this->class_var", result_type="int", result_value="109")31 32        # Check that captured shadowed variables take preference over the33        # corresponding member variable34        self.expect_expr("shadowed", result_type="int", result_value="5")35        self.expect_expr("this->shadowed", result_type="int", result_value="-137")36 37        # Check access to local captures38        self.expect_expr("local_var", result_type="int", result_value="137")39        self.expect_expr("*class_ptr", result_type="int", result_value="137")40 41        # Check access to base class variables42        self.expect_expr("base_var", result_type="int", result_value="14")43        self.expect_expr("base_base_var", result_type="int", result_value="11")44 45        # Check access to global variable46        self.expect_expr("global_var", result_type="int", result_value="-5")47 48        # Check access to multiple captures/member variables49        self.expect_expr(50            "(shadowed + this->shadowed) * (base_base_var + local_var - class_var)",51            result_type="int",52            result_value="-5148",53        )54 55        # Check base-class function call56        self.expect_expr("baz_virt()", result_type="int", result_value="2")57        self.expect_expr("base_var", result_type="int", result_value="14")58        self.expect_expr("this->shadowed", result_type="int", result_value="-1")59 60        # 'p this' should yield 'struct Foo*'61        frame = self.thread.GetFrameAtIndex(0)62        outer_class_addr = frame.GetValueForVariablePath("this->this")63        self.expect_expr("this", result_value=outer_class_addr.GetValue())64 65        lldbutil.continue_to_breakpoint(process, bkpt)66 67        # Inside 'nested_lambda'68 69        # Check access to captured 'this'. Should still be 'struct Foo*'70        self.expect_expr("class_var", result_type="int", result_value="109")71        self.expect_expr("global_var", result_type="int", result_value="-5")72        self.expect_expr("this", result_value=outer_class_addr.GetValue())73 74        # Check access to captures75        self.expect_expr("lambda_local_var", result_type="int", result_value="5")76        self.expect_expr("local_var", result_type="int", result_value="137")77 78        # Check access to variable in previous frame which we didn't capture79        self.expectExprError("local_var_copy", "use of undeclared identifier")80 81        lldbutil.continue_to_breakpoint(process, bkpt)82 83        # By-ref mutates source variable84        self.expect_expr("lambda_local_var", result_type="int", result_value="0")85 86        # By-value doesn't mutate source variable87        self.expect_expr("local_var_copy", result_type="int", result_value="136")88        self.expect_expr("local_var", result_type="int", result_value="137")89 90        lldbutil.continue_to_breakpoint(process, bkpt)91 92        # Inside 'LocalLambdaClass::inner_method'93 94        # Check access to captured 'this'95        self.expect_expr("lambda_class_local", result_type="int", result_value="-12345")96        self.expect_expr(97            "this->lambda_class_local", result_type="int", result_value="-12345"98        )99        self.expect_expr("outer_ptr->class_var", result_type="int", result_value="109")100 101        # 'p this' should yield 'struct LocalLambdaClass*'102        frame = self.thread.GetFrameAtIndex(0)103        local_class_addr = frame.GetValueForVariablePath("this->this")104        self.assertNotEqual(local_class_addr, outer_class_addr)105        self.expect_expr("this", result_value=local_class_addr.GetValue())106 107        # Can still access global variable108        self.expect_expr("global_var", result_type="int", result_value="-5")109 110        # Check access to outer top-level structure's members111        self.expectExprError(112            "class_var",113            ("use of non-static data member" " 'class_var' of 'Foo' from nested type"),114        )115 116        self.expectExprError(117            "base_var", ("use of non-static data member" " 'base_var'")118        )119 120        self.expectExprError(121            "local_var",122            (123                "use of non-static data member 'local_var'"124                " of '(unnamed class)' from nested type 'LocalLambdaClass'"125            ),126        )127 128        # Inside non_capturing_method129        lldbutil.continue_to_breakpoint(process, bkpt)130        self.expect_expr("local", result_type="int", result_value="5")131        self.expect_expr("local2", result_type="int", result_value="10")132        self.expect_expr("local2 * local", result_type="int", result_value="50")133 134        self.expectExprError(135            "class_var",136            ("use of non-static data member" " 'class_var' of 'Foo' from nested type"),137        )138