1"""
2Test the printing of anonymous and named namespace variables.
3"""
4
5import os, time
6import unittest2
7import lldb
8from lldbtest import *
9import lldbutil
10
11class NamespaceTestCase(TestBase):
12
13    mydir = os.path.join("lang", "cpp", "namespace")
14
15    # rdar://problem/8668674
16    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
17    @dsym_test
18    def test_with_dsym_and_run_command(self):
19        """Test that anonymous and named namespace variables display correctly."""
20        self.buildDsym()
21        self.namespace_variable_commands()
22
23    # rdar://problem/8668674
24    @expectedFailureGcc # llvm.org/pr15302: lldb does not print 'anonymous namespace' when the inferior is built with GCC (4.7)
25    @dwarf_test
26    def test_with_dwarf_and_run_command(self):
27        """Test that anonymous and named namespace variables display correctly."""
28        self.buildDwarf()
29        self.namespace_variable_commands()
30
31    def setUp(self):
32        # Call super's setUp().
33        TestBase.setUp(self)
34        # Find the line numbers for declarations of namespace variables i and j.
35        self.line_var_i = line_number('main.cpp',
36                '// Find the line number for anonymous namespace variable i.')
37        self.line_var_j = line_number('main.cpp',
38                '// Find the line number for named namespace variable j.')
39        # And the line number to break at.
40        self.line_break = line_number('main.cpp',
41                '// Set break point at this line.')
42
43    def namespace_variable_commands(self):
44        """Test that anonymous and named namespace variables display correctly."""
45        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
46
47        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line_break, num_expected_locations=1, loc_exact=True)
48
49        self.runCmd("run", RUN_SUCCEEDED)
50
51        # The stop reason of the thread should be breakpoint.
52        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
53            substrs = ['stopped',
54                       'stop reason = breakpoint'])
55
56        # On Mac OS X, gcc 4.2 emits the wrong debug info with respect to types.
57        slist = ['(int) a = 12', 'anon_uint', 'a_uint', 'b_uint', 'y_uint']
58        if sys.platform.startswith("darwin") and self.getCompiler() in ['clang', 'llvm-gcc']:
59            slist = ['(int) a = 12',
60                     '::my_uint_t', 'anon_uint = 0',
61                     '(A::uint_t) a_uint = 1',
62                     '(A::B::uint_t) b_uint = 2',
63                     '(Y::uint_t) y_uint = 3']
64
65        # 'frame variable' displays the local variables with type information.
66        self.expect('frame variable', VARIABLES_DISPLAYED_CORRECTLY,
67            substrs = slist)
68
69        # 'frame variable' with basename 'i' should work.
70        self.expect("frame variable --show-declaration --show-globals i",
71            startstr = "main.cpp:%d: (int) (anonymous namespace)::i = 3" % self.line_var_i)
72        # main.cpp:12: (int) (anonymous namespace)::i = 3
73
74        # 'frame variable' with basename 'j' should work, too.
75        self.expect("frame variable --show-declaration --show-globals j",
76            startstr = "main.cpp:%d: (int) A::B::j = 4" % self.line_var_j)
77        # main.cpp:19: (int) A::B::j = 4
78
79        # 'frame variable' should support address-of operator.
80        self.runCmd("frame variable &i")
81
82        # 'frame variable' with fully qualified name 'A::B::j' should work.
83        self.expect("frame variable A::B::j", VARIABLES_DISPLAYED_CORRECTLY,
84            startstr = '(int) A::B::j = 4',
85            patterns = [' = 4$'])
86
87        # So should the anonymous namespace case.
88        self.expect("frame variable '(anonymous namespace)::i'", VARIABLES_DISPLAYED_CORRECTLY,
89            startstr = '(int) (anonymous namespace)::i = 3',
90            patterns = [' = 3$'])
91
92        # rdar://problem/8660275
93        # test/namespace: 'expression -- i+j' not working
94        # This has been fixed.
95        self.expect("expression -- i + j",
96            startstr = "(int) $0 = 7")
97        # (int) $0 = 7
98
99        self.runCmd("expression -- i")
100        self.runCmd("expression -- j")
101
102        # rdar://problem/8668674
103        # expression command with fully qualified namespace for a variable does not work
104        self.expect("expression -- ::i", VARIABLES_DISPLAYED_CORRECTLY,
105            patterns = [' = 3$'])
106        self.expect("expression -- A::B::j", VARIABLES_DISPLAYED_CORRECTLY,
107            patterns = [' = 4$'])
108
109        # expression command with function in anonymous namespace
110        self.expect("expression -- myanonfunc(3)",
111            patterns = [' = 6'])
112
113        # global namespace qualification with function in anonymous namespace
114        self.expect("expression -- ::myanonfunc(4)",
115            patterns = [' = 8'])
116
117        self.expect("p myanonfunc",
118            patterns = ['\(anonymous namespace\)::myanonfunc\(int\)'])
119
120if __name__ == '__main__':
121    import atexit
122    lldb.SBDebugger.Initialize()
123    atexit.register(lambda: lldb.SBDebugger.Terminate())
124    unittest2.main()
125