1"""
2Test that the language option for breakpoints works correctly
3with symbol load on-demand.
4"""
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10import lldbsuite.test.lldbutil as lldbutil
11
12
13class TestBreakpointLanguage(TestBase):
14
15    def check_location_file(self, bp, loc, test_name):
16        bp_loc = bp.GetLocationAtIndex(loc)
17        addr = bp_loc.GetAddress()
18        comp_unit = addr.GetCompileUnit()
19        comp_name = comp_unit.GetFileSpec().GetFilename()
20        return comp_name == test_name
21
22    @skipIfWindows
23    def test_regex_breakpoint_language(self):
24        """Test that the name regex breakpoint commands obey the language filter."""
25
26        self.build()
27
28        # Load symbols on-demand
29        self.runCmd("settings set symbols.load-on-demand true")
30
31        # Create a target by the debugger.
32        exe = self.getBuildArtifact("a.out")
33        error = lldb.SBError()
34        # Don't read in dependencies so we don't come across false matches that
35        # add unwanted breakpoint hits.
36        self.target = self.dbg.CreateTarget(exe, None, None, False, error)
37        self.assertTrue(self.target, VALID_TARGET)
38
39        cpp_bp = self.target.BreakpointCreateByRegex(
40            "func_from",
41            lldb.eLanguageTypeC_plus_plus,
42            lldb.SBFileSpecList(),
43            lldb.SBFileSpecList())
44        self.assertEqual(
45            cpp_bp.GetNumLocations(), 1,
46            "Only one C++ symbol matches")
47        self.assertTrue(self.check_location_file(cpp_bp, 0, "cpp_lang.cpp"))
48
49        c_bp = self.target.BreakpointCreateByRegex(
50            "func_from",
51            lldb.eLanguageTypeC,
52            lldb.SBFileSpecList(),
53            lldb.SBFileSpecList())
54        self.assertEqual(
55            c_bp.GetNumLocations(), 1,
56            "Only one C symbol matches")
57        self.assertTrue(self.check_location_file(c_bp, 0, "c_lang.c"))
58
59        objc_bp = self.target.BreakpointCreateByRegex(
60            "func_from",
61            lldb.eLanguageTypeObjC,
62            lldb.SBFileSpecList(),
63            lldb.SBFileSpecList())
64        self.assertEqual(
65            objc_bp.GetNumLocations(), 0,
66            "No ObjC symbol matches")
67
68    @skipIfWindows
69    def test_by_name_breakpoint_language(self):
70        """Test that the name regex breakpoint commands obey the language filter."""
71
72        self.build()
73
74        # Load symbols on-demand
75        self.runCmd("settings set symbols.load-on-demand true")
76
77        # Create a target by the debugger.
78        exe = self.getBuildArtifact("a.out")
79        error = lldb.SBError()
80        # Don't read in dependencies so we don't come across false matches that
81        # add unwanted breakpoint hits.
82        self.target = self.dbg.CreateTarget(exe, None, None, False, error)
83        self.assertTrue(self.target, VALID_TARGET)
84
85        cpp_bp = self.target.BreakpointCreateByName(
86            "func_from_cpp",
87            lldb.eFunctionNameTypeAuto,
88            lldb.eLanguageTypeC_plus_plus,
89            lldb.SBFileSpecList(),
90            lldb.SBFileSpecList())
91        self.assertEqual(
92            cpp_bp.GetNumLocations(), 1,
93            "Only one C++ symbol matches")
94        self.assertTrue(self.check_location_file(cpp_bp, 0, "cpp_lang.cpp"))
95
96        no_cpp_bp = self.target.BreakpointCreateByName(
97            "func_from_c",
98            lldb.eFunctionNameTypeAuto,
99            lldb.eLanguageTypeC_plus_plus,
100            lldb.SBFileSpecList(),
101            lldb.SBFileSpecList())
102        self.assertEqual(
103            no_cpp_bp.GetNumLocations(), 0,
104            "And the C one doesn't match")
105
106        c_bp = self.target.BreakpointCreateByName(
107            "func_from_c",
108            lldb.eFunctionNameTypeAuto,
109            lldb.eLanguageTypeC,
110            lldb.SBFileSpecList(),
111            lldb.SBFileSpecList())
112        self.assertEqual(
113            c_bp.GetNumLocations(), 1,
114            "Only one C symbol matches")
115        self.assertTrue(self.check_location_file(c_bp, 0, "c_lang.c"))
116
117        no_c_bp = self.target.BreakpointCreateByName(
118            "func_from_cpp",
119            lldb.eFunctionNameTypeAuto,
120            lldb.eLanguageTypeC,
121            lldb.SBFileSpecList(),
122            lldb.SBFileSpecList())
123        self.assertEqual(
124            no_c_bp.GetNumLocations(), 0,
125            "And the C++ one doesn't match")
126
127        objc_bp = self.target.BreakpointCreateByName(
128            "func_from_cpp",
129            lldb.eFunctionNameTypeAuto,
130            lldb.eLanguageTypeObjC,
131            lldb.SBFileSpecList(),
132            lldb.SBFileSpecList())
133        self.assertEqual(
134            objc_bp.GetNumLocations(), 0,
135            "No ObjC symbol matches")
136