1import lldb
2from lldbsuite.test.decorators import *
3from lldbsuite.test.lldbtest import *
4from lldbsuite.test import lldbutil
5
6USE_LIBSTDCPP = "USE_LIBSTDCPP"
7USE_LIBCPP = "USE_LIBCPP"
8
9class GenericOptionalDataFormatterTestCase(TestBase):
10
11    def do_test_with_run_command(self, stdlib_type):
12        """Test that that file and class static variables display correctly."""
13        # This is the function to remove the custom formats in order to have a
14        # clean slate for the next test case.
15        def cleanup():
16            self.runCmd('type format clear', check=False)
17            self.runCmd('type summary clear', check=False)
18            self.runCmd('type filter clear', check=False)
19            self.runCmd('type synth clear', check=False)
20        self.addTearDownHook(cleanup)
21
22        self.build(dictionary={stdlib_type: "1"})
23        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
24
25        bkpt = self.target().FindBreakpointByID(
26            lldbutil.run_break_set_by_source_regexp(
27                self, "break here"))
28
29        self.runCmd("run", RUN_SUCCEEDED)
30
31        # The stop reason of the thread should be breakpoint.
32        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
33                    substrs=['stopped',
34                             'stop reason = breakpoint'])
35
36        self.runCmd( "frame variable has_optional" )
37
38        output = self.res.GetOutput()
39
40        ## The variable has_optional tells us if the test program
41        ## detected we have a sufficient libc++ version to support optional
42        ## false means we do not and therefore should skip the test
43        if output.find("(bool) has_optional = false") != -1 :
44           self.skipTest( "Optional not supported" )
45
46        lldbutil.continue_to_breakpoint(self.process(), bkpt)
47
48        self.expect("frame variable number_not_engaged",
49                    substrs=['Has Value=false'])
50
51        self.expect("frame variable number_engaged",
52                    substrs=['Has Value=true',
53                             'Value = 42',
54                             '}'])
55
56        self.expect("frame var numbers",
57                    substrs=['(optional_int_vect) numbers =  Has Value=true  {',
58                             'Value = size=4 {',
59                               '[0] = 1',
60                               '[1] = 2',
61                               '[2] = 3',
62                               '[3] = 4',
63                               '}',
64                             '}'])
65
66        self.expect("frame var ostring",
67                    substrs=['(optional_string) ostring =  Has Value=true  {',
68                        'Value = "hello"',
69                        '}'])
70
71    @add_test_categories(["libc++"])
72    ## Clang 7.0 is the oldest Clang that can reliably parse newer libc++ versions
73    ## with -std=c++17.
74    @skipIf(oslist=no_match(["macosx"]), compiler="clang", compiler_version=['<', '7.0'])
75    ## We are skipping gcc version less that 5.1 since this test requires -std=c++17
76    @skipIf(compiler="gcc", compiler_version=['<', '5.1'])
77    def test_with_run_command_libcpp(self):
78        self.do_test_with_run_command(USE_LIBCPP)
79
80    @add_test_categories(["libstdcxx"])
81    ## Clang 7.0 is the oldest Clang that can reliably parse newer libc++ versions
82    ## with -std=c++17.
83    @skipIf(compiler="clang", compiler_version=['<', '7.0'])
84    ## We are skipping gcc version less that 5.1 since this test requires -std=c++17
85    @skipIf(compiler="gcc", compiler_version=['<', '5.1'])
86    def test_with_run_command_libstdcpp(self):
87        self.do_test_with_run_command(USE_LIBSTDCPP)
88