1"""
2Check that types only get completed when necessary.
3"""
4
5import os, time
6import unittest2
7import lldb
8from lldbtest import *
9import lldbutil
10
11class TypeCompletionTestCase(TestBase):
12
13    mydir = os.path.join("functionalities", "type_completion")
14
15    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
16    @dsym_test
17    def test_with_dsym_and_run_command(self):
18        """Check that types only get completed when necessary."""
19        self.buildDsym()
20        self.type_completion_commands()
21
22    @dwarf_test
23    @expectedFailureIcc # often fails with 'NameAndAddress should be valid'
24    # Fails with gcc 4.8.1 with llvm.org/pr15301 LLDB prints incorrect sizes of STL containers
25    def test_with_dwarf_and_run_command(self):
26        """Check that types only get completed when necessary."""
27        self.buildDwarf()
28        self.type_completion_commands()
29
30    def setUp(self):
31        # Call super's setUp().
32        TestBase.setUp(self)
33        # Find the line number to break at.
34        self.line = line_number('main.cpp', '// Set break point at this line.')
35
36    def type_completion_commands(self):
37        """Check that types only get completed when necessary."""
38        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
39
40        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
41
42        self.runCmd("run", RUN_SUCCEEDED)
43
44        # The stop reason of the thread should be breakpoint.
45        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
46            substrs = ['stopped',
47                       'stop reason = breakpoint'])
48
49        # This is the function to remove the custom formats in order to have a
50        # clean slate for the next test case.
51        def cleanup():
52            self.runCmd('type category enable gnu-libstdc++', check=False)
53            self.runCmd('type category enable libcxx', check=False)
54
55        self.runCmd('type category disable gnu-libstdc++', check=False)
56        self.runCmd('type category disable libcxx', check=False)
57
58        # Execute the cleanup function during test case tear down.
59        self.addTearDownHook(cleanup)
60
61        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
62        p_type = p_vector.GetType()
63        self.assertFalse(p_type.IsTypeComplete(), 'vector<T> complete but it should not be')
64
65        self.runCmd("next")
66        self.runCmd("next")
67
68        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
69        p_type = p_vector.GetType()
70        self.assertFalse(p_type.IsTypeComplete(), 'vector<T> complete but it should not be')
71
72        self.runCmd("next")
73        self.runCmd("next")
74
75        self.runCmd("frame variable p --show-types")
76
77        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
78        p_type = p_vector.GetType()
79        self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
80        name_address_type = p_type.GetTemplateArgumentType(0)
81        self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
82        self.assertFalse(name_address_type.IsTypeComplete(), 'NameAndAddress complete but it should not be')
83
84        self.runCmd("next")
85        self.runCmd("next")
86
87        self.runCmd("frame variable guy --show-types")
88
89        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
90        p_type = p_vector.GetType()
91        self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
92        name_address_type = p_type.GetTemplateArgumentType(0)
93        self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
94        self.assertTrue(name_address_type.IsTypeComplete(), 'NameAndAddress should now be complete')
95        field0 = name_address_type.GetFieldAtIndex(0)
96        if self.TraceOn():
97             print 'field0: ' + str(field0)
98        self.assertTrue(field0.IsValid(), 'NameAndAddress::m_name should be valid')
99        string = field0.GetType().GetPointeeType()
100        if self.TraceOn():
101             print 'string: ' + str(string)
102        self.assertTrue(string.IsValid(), 'std::string should be valid')
103        self.assertFalse(string.IsTypeComplete(), 'std::string complete but it should not be')
104
105        self.runCmd("next")
106        self.runCmd("next")
107
108        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
109        p_type = p_vector.GetType()
110        self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
111        name_address_type = p_type.GetTemplateArgumentType(0)
112        self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
113        self.assertTrue(name_address_type.IsTypeComplete(), 'NameAndAddress should now be complete')
114        field0 = name_address_type.GetFieldAtIndex(0)
115        if self.TraceOn():
116             print 'field0: ' + str(field0)
117        self.assertTrue(field0.IsValid(), 'NameAndAddress::m_name should be valid')
118        string = field0.GetType().GetPointeeType()
119        if self.TraceOn():
120             print 'string: ' + str(string)
121        self.assertTrue(string.IsValid(), 'std::string should be valid')
122        self.assertFalse(string.IsTypeComplete(), 'std::string complete but it should not be')
123
124        self.runCmd('type category enable gnu-libstdc++', check=False)
125        self.runCmd('type category enable libcxx', check=False)
126        self.runCmd('frame variable guy --show-types')
127
128        p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')
129        p_type = p_vector.GetType()
130        self.assertTrue(p_type.IsTypeComplete(), 'vector<T> should now be complete')
131        name_address_type = p_type.GetTemplateArgumentType(0)
132        self.assertTrue(name_address_type.IsValid(), 'NameAndAddress should be valid')
133        self.assertTrue(name_address_type.IsTypeComplete(), 'NameAndAddress should now be complete')
134        field0 = name_address_type.GetFieldAtIndex(0)
135        self.assertTrue(field0.IsValid(), 'NameAndAddress::m_name should be valid')
136        string = field0.GetType().GetPointeeType()
137        self.assertTrue(string.IsValid(), 'std::string should be valid')
138        self.assertTrue(string.IsTypeComplete(), 'std::string should now be complete')
139
140if __name__ == '__main__':
141    import atexit
142    lldb.SBDebugger.Initialize()
143    atexit.register(lambda: lldb.SBDebugger.Terminate())
144    unittest2.main()
145