13552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan"""Test that anonymous structs/unions are transparent to member access"""
23552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
33552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callananimport os, time
43552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callananimport unittest2
53552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callananimport lldb
63552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callananfrom lldbtest import *
7431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamimport lldbutil
83552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
93552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callananclass AnonymousTestCase(TestBase):
103552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
113552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan    mydir = os.path.join("lang", "c", "anonymous")
123552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
1321b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dsym_test
1414d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def test_expr_nest_with_dsym(self):
153552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        self.buildDsym()
1614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expr_nest()
173552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
1814d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    @dsym_test
1914d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def test_expr_child_with_dsym(self):
2014d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.buildDsym()
2114d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expr_child()
2214d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
2314d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    @dsym_test
2414d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def test_expr_grandchild_with_dsym(self):
2514d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.buildDsym()
2614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expr_grandchild()
2714d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
2814d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    @dsym_test
2914d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def test_expr_parent(self):
3014d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.buildDsym()
3114d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expr_parent()
3214d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
3314d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    @unittest2.expectedFailure # llvm.org/pr15591
3414d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    @dsym_test
3514d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def test_expr_null(self):
3614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.buildDsym()
3714d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expr_null()
3814d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
3914d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    @skipIfGcc # llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by GCC
4057d4ab262f574ed1e1da955a7b6eb091156c343cMatt Kopec    @skipIfIcc # llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by ICC
4121b1984e161b0cadee331d32bfd721eccfdf4b1fJohnny Chen    @dwarf_test
4214d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def test_expr_nest_with_dwarf(self):
4314d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.buildDwarf()
4414d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expr_nest()
4514d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
4614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    @dwarf_test
4714d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def test_expr_child_with_dwarf(self):
4814d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.skipTest("Skipped because LLDB asserts due to an incorrect AST layout for an anonymous struct: see llvm.org/pr15036")
4914d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.buildDwarf()
5014d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expr_child()
5114d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
5223dfe46d3dfad11bcb8fa5c3616893d616b68298Ashok Thirumurthi    @skipIfGcc # llvm.org/pr15036: This particular regression was introduced by r181498
5323dfe46d3dfad11bcb8fa5c3616893d616b68298Ashok Thirumurthi    @skipIfIcc # llvm.org/pr15036: This particular regression was introduced by r181498
5414d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    @dwarf_test
5514d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def test_expr_grandchild_with_dwarf(self):
5614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.buildDwarf()
5714d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expr_grandchild()
5814d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
5914d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    @dwarf_test
6014d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def test_expr_parent(self):
613552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        self.buildDwarf()
6214d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expr_parent()
6314d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
6414d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    @unittest2.expectedFailure # llvm.org/pr15591
6514d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    @dwarf_test
6614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def test_expr_null(self):
6714d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.buildDwarf()
6814d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expr_null()
693552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
703552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan    def setUp(self):
713552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        # Call super's setUp().
723552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        TestBase.setUp(self)
7314d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        # Find the line numbers to break in main.c.
7414d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.line0 = line_number('main.c', '// Set breakpoint 0 here.')
7514d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.line1 = line_number('main.c', '// Set breakpoint 1 here.')
7614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.line2 = line_number('main.c', '// Set breakpoint 2 here.')
773552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
7814d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def common_setup(self, line):
793552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        exe = os.path.join(os.getcwd(), "a.out")
803552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
813552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
8214d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        # Set breakpoints inside and outside methods that take pointers to the containing struct.
8314d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        lldbutil.run_break_set_by_file_and_line (self, "main.c", line, num_expected_locations=1, loc_exact=True)
843552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
853552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        self.runCmd("run", RUN_SUCCEEDED)
863552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
873552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        # The stop reason of the thread should be breakpoint.
883552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
893552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan            substrs = ['stopped',
903552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan                       'stop reason = breakpoint'])
913552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
923552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        # The breakpoint should have a hit count of 1.
933552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
943552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan            substrs = [' resolved, hit count = 1'])
953552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
9614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def expr_nest(self):
9714d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.common_setup(self.line0)
9814d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
9914d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        # These should display correctly.
10014d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expect("expression n->foo.d", VARIABLES_DISPLAYED_CORRECTLY,
10114d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi            substrs = ["= 4"])
10214d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
10314d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expect("expression n->b", VARIABLES_DISPLAYED_CORRECTLY,
10414d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi            substrs = ["= 2"])
10514d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
10614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def expr_child(self):
10714d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.common_setup(self.line1)
1083552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
10914d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        # These should display correctly.
1103552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan        self.expect("expression c->foo.d", VARIABLES_DISPLAYED_CORRECTLY,
1113552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan            substrs = ["= 4"])
1123552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
11314d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expect("expression c->grandchild.b", VARIABLES_DISPLAYED_CORRECTLY,
11414d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi            substrs = ["= 2"])
11514d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
11614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def expr_grandchild(self):
11714d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.common_setup(self.line2)
11814d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
11914d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        # These should display correctly.
12014d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expect("expression g.child.foo.d", VARIABLES_DISPLAYED_CORRECTLY,
12114d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi            substrs = ["= 4"])
12214d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
12314d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expect("expression g.child.b", VARIABLES_DISPLAYED_CORRECTLY,
1243552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan            substrs = ["= 2"])
1253552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan
12614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def expr_parent(self):
1277ae61126d72af10df5aef97b7f4ce34a8bdcb9daDaniel Malea        if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion():
1287ae61126d72af10df5aef97b7f4ce34a8bdcb9daDaniel Malea            self.skipTest("llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef")
12914d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.common_setup(self.line2)
13014d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
13114d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        # These should display correctly.
13214d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expect("expression pz", VARIABLES_DISPLAYED_CORRECTLY,
13314d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi            substrs = ["(type_z *) $0 = 0x0000"])
13414d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
13514d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expect("expression z.y", VARIABLES_DISPLAYED_CORRECTLY,
13614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi            substrs = ["(type_y) $1 = {"])
13714d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
1382921c36a96b2abcb4c6033f483bfb011052818d3Sean Callanan        self.expect("expression z", VARIABLES_DISPLAYED_CORRECTLY,
1392921c36a96b2abcb4c6033f483bfb011052818d3Sean Callanan            substrs = ["dummy = 2"])
1402921c36a96b2abcb4c6033f483bfb011052818d3Sean Callanan
14114d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi    def expr_null(self):
14214d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.common_setup(self.line2)
14314d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
14414d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        # This should fail because pz is 0, but it succeeds on OS/X.
14514d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        # This fails on Linux with an upstream error "Couldn't dematerialize struct", as does "p *n" with "int *n = 0".
14614d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        # Note that this can also trigger llvm.org/pr15036 when run interactively at the lldb command prompt.
14714d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi        self.expect("expression *(type_z *)pz",
14814d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi            substrs = ["Cannot access memory at address 0x0"], error = True)
14914d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
15014d09ee076ca8f5e56e249d813bee3ad2d180d26Ashok Thirumurthi
1513552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callananif __name__ == '__main__':
1523552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan    import atexit
1533552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan    lldb.SBDebugger.Initialize()
1543552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan    atexit.register(lambda: lldb.SBDebugger.Terminate())
1553552ed0afbb58f377a4677ae5253e59b3ed80954Sean Callanan    unittest2.main()
156