199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest that C++ template classes that have integer parameters work correctly.
399451b44SJordan Rupprecht
499451b44SJordan RupprechtWe must reconstruct the types correctly so the template types are correct
599451b44SJordan Rupprechtand display correctly, and also make sure the expression parser works and
699451b44SJordan Rupprechtis able the find all needed functions when evaluating expressions
799451b44SJordan Rupprecht"""
899451b44SJordan Rupprechtimport lldb
999451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
1099451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1199451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprecht
1499451b44SJordan Rupprechtclass TemplateArgsTestCase(TestBase):
1599451b44SJordan Rupprecht
1699451b44SJordan Rupprecht    def prepareProcess(self):
1799451b44SJordan Rupprecht        self.build()
1899451b44SJordan Rupprecht
1999451b44SJordan Rupprecht        # Create a target by the debugger.
2099451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
2199451b44SJordan Rupprecht        target = self.dbg.CreateTarget(exe)
2299451b44SJordan Rupprecht        self.assertTrue(target, VALID_TARGET)
2399451b44SJordan Rupprecht
2499451b44SJordan Rupprecht        # Set breakpoints inside and outside methods that take pointers to the
2599451b44SJordan Rupprecht        # containing struct.
2699451b44SJordan Rupprecht        line = line_number('main.cpp', '// Breakpoint 1')
2799451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
2899451b44SJordan Rupprecht            self, "main.cpp", line, num_expected_locations=1, loc_exact=True)
2999451b44SJordan Rupprecht
3099451b44SJordan Rupprecht        arguments = None
3199451b44SJordan Rupprecht        environment = None
3299451b44SJordan Rupprecht
3399451b44SJordan Rupprecht        # Now launch the process, and do not stop at entry point.
3499451b44SJordan Rupprecht        process = target.LaunchSimple(
3599451b44SJordan Rupprecht            arguments, environment, self.get_process_working_directory())
3699451b44SJordan Rupprecht        self.assertTrue(process, PROCESS_IS_VALID)
3799451b44SJordan Rupprecht
3899451b44SJordan Rupprecht        # Get the thread of the process
39*0ed758b2SDave Lee        self.assertEqual(
40*0ed758b2SDave Lee            process.GetState(), lldb.eStateStopped,
4199451b44SJordan Rupprecht            PROCESS_STOPPED)
4299451b44SJordan Rupprecht        thread = lldbutil.get_stopped_thread(
4399451b44SJordan Rupprecht            process, lldb.eStopReasonBreakpoint)
4499451b44SJordan Rupprecht
4599451b44SJordan Rupprecht        # Get frame for current thread
4699451b44SJordan Rupprecht        return thread.GetSelectedFrame()
4799451b44SJordan Rupprecht
4899451b44SJordan Rupprecht    def test_integer_args(self):
4999451b44SJordan Rupprecht        frame = self.prepareProcess()
5099451b44SJordan Rupprecht
5199451b44SJordan Rupprecht        testpos = frame.FindVariable('testpos')
5299451b44SJordan Rupprecht        self.assertTrue(
5399451b44SJordan Rupprecht            testpos.IsValid(),
5499451b44SJordan Rupprecht            'make sure we find a local variabble named "testpos"')
55b3a0c4d7SRaphael Isemann        self.assertEquals(testpos.GetType().GetName(), 'TestObj<1>')
5699451b44SJordan Rupprecht
5799451b44SJordan Rupprecht        expr_result = frame.EvaluateExpression("testpos.getArg()")
5899451b44SJordan Rupprecht        self.assertTrue(
5999451b44SJordan Rupprecht            expr_result.IsValid(),
6099451b44SJordan Rupprecht            'got a valid expression result from expression "testpos.getArg()"')
61b3a0c4d7SRaphael Isemann        self.assertEquals(expr_result.GetValue(), "1", "testpos.getArg() == 1")
62*0ed758b2SDave Lee        self.assertEqual(
63*0ed758b2SDave Lee            expr_result.GetType().GetName(), "int",
6499451b44SJordan Rupprecht            'expr_result.GetType().GetName() == "int"')
6599451b44SJordan Rupprecht
6699451b44SJordan Rupprecht        testneg = frame.FindVariable('testneg')
6799451b44SJordan Rupprecht        self.assertTrue(
6899451b44SJordan Rupprecht            testneg.IsValid(),
6999451b44SJordan Rupprecht            'make sure we find a local variabble named "testneg"')
70b3a0c4d7SRaphael Isemann        self.assertEquals(testneg.GetType().GetName(), 'TestObj<-1>')
7199451b44SJordan Rupprecht
7299451b44SJordan Rupprecht        expr_result = frame.EvaluateExpression("testneg.getArg()")
7399451b44SJordan Rupprecht        self.assertTrue(
7499451b44SJordan Rupprecht            expr_result.IsValid(),
7599451b44SJordan Rupprecht            'got a valid expression result from expression "testneg.getArg()"')
76*0ed758b2SDave Lee        self.assertEqual(
77*0ed758b2SDave Lee            expr_result.GetValue(), "-1",
7899451b44SJordan Rupprecht            "testneg.getArg() == -1")
79*0ed758b2SDave Lee        self.assertEqual(
80*0ed758b2SDave Lee            expr_result.GetType().GetName(), "int",
8199451b44SJordan Rupprecht            'expr_result.GetType().GetName() == "int"')
8299451b44SJordan Rupprecht
8399451b44SJordan Rupprecht    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489")
8499451b44SJordan Rupprecht    def test_template_template_args(self):
8599451b44SJordan Rupprecht        frame = self.prepareProcess()
8699451b44SJordan Rupprecht
8799451b44SJordan Rupprecht        c1 = frame.FindVariable('c1')
8899451b44SJordan Rupprecht        self.assertTrue(
8999451b44SJordan Rupprecht            c1.IsValid(),
9099451b44SJordan Rupprecht            'make sure we find a local variabble named "c1"')
91b3a0c4d7SRaphael Isemann        self.assertEquals(c1.GetType().GetName(), 'C<float, T1>')
9299451b44SJordan Rupprecht        f1 = c1.GetChildMemberWithName("V").GetChildAtIndex(0).GetChildMemberWithName("f")
93b3a0c4d7SRaphael Isemann        self.assertEquals(f1.GetType().GetName(), 'float')
94b3a0c4d7SRaphael Isemann        self.assertEquals(f1.GetValue(), '1.5')
9599451b44SJordan Rupprecht
9699451b44SJordan Rupprecht        c2 = frame.FindVariable('c2')
9799451b44SJordan Rupprecht        self.assertTrue(
9899451b44SJordan Rupprecht            c2.IsValid(),
9999451b44SJordan Rupprecht            'make sure we find a local variabble named "c2"')
100b3a0c4d7SRaphael Isemann        self.assertEquals(c2.GetType().GetName(), 'C<double, T1, T2>')
10199451b44SJordan Rupprecht        f2 = c2.GetChildMemberWithName("V").GetChildAtIndex(0).GetChildMemberWithName("f")
102b3a0c4d7SRaphael Isemann        self.assertEquals(f2.GetType().GetName(), 'double')
103b3a0c4d7SRaphael Isemann        self.assertEquals(f2.GetValue(), '1.5')
10499451b44SJordan Rupprecht        f3 = c2.GetChildMemberWithName("V").GetChildAtIndex(1).GetChildMemberWithName("f")
105b3a0c4d7SRaphael Isemann        self.assertEquals(f3.GetType().GetName(), 'double')
106b3a0c4d7SRaphael Isemann        self.assertEquals(f3.GetValue(), '2.5')
10799451b44SJordan Rupprecht        f4 = c2.GetChildMemberWithName("V").GetChildAtIndex(1).GetChildMemberWithName("i")
108b3a0c4d7SRaphael Isemann        self.assertEquals(f4.GetType().GetName(), 'int')
109b3a0c4d7SRaphael Isemann        self.assertEquals(f4.GetValue(), '42')
11099451b44SJordan Rupprecht
11199451b44SJordan Rupprecht    # Gcc does not generate the necessary DWARF attribute for enum template
11299451b44SJordan Rupprecht    # parameters.
11399451b44SJordan Rupprecht    @expectedFailureAll(bugnumber="llvm.org/pr28354", compiler="gcc")
11499451b44SJordan Rupprecht    @skipIf(dwarf_version=['<', '4'])
11599451b44SJordan Rupprecht    def test_enum_args(self):
11699451b44SJordan Rupprecht        frame = self.prepareProcess()
11799451b44SJordan Rupprecht
11899451b44SJordan Rupprecht        # Make sure "member" can be displayed and also used in an expression
11999451b44SJordan Rupprecht        # correctly
12099451b44SJordan Rupprecht        member = frame.FindVariable('member')
12199451b44SJordan Rupprecht        self.assertTrue(
12299451b44SJordan Rupprecht            member.IsValid(),
12399451b44SJordan Rupprecht            'make sure we find a local variabble named "member"')
124619e2e09SDave Lee        self.assertEqual(member.GetType().GetName(),
12599451b44SJordan Rupprecht                        'EnumTemplate<EnumType::Member>')
12699451b44SJordan Rupprecht
12799451b44SJordan Rupprecht        expr_result = frame.EvaluateExpression("member.getMember()")
12899451b44SJordan Rupprecht        self.assertTrue(
12999451b44SJordan Rupprecht            expr_result.IsValid(),
13099451b44SJordan Rupprecht            'got a valid expression result from expression "member.getMember()"')
131*0ed758b2SDave Lee        self.assertEqual(
132*0ed758b2SDave Lee            expr_result.GetValue(), "123",
13399451b44SJordan Rupprecht            "member.getMember() == 123")
134*0ed758b2SDave Lee        self.assertEqual(
135*0ed758b2SDave Lee            expr_result.GetType().GetName(), "int",
13699451b44SJordan Rupprecht            'expr_result.GetType().GetName() == "int"')
13799451b44SJordan Rupprecht
13899451b44SJordan Rupprecht        # Make sure "subclass" can be displayed and also used in an expression
13999451b44SJordan Rupprecht        # correctly
14099451b44SJordan Rupprecht        subclass = frame.FindVariable('subclass')
14199451b44SJordan Rupprecht        self.assertTrue(
14299451b44SJordan Rupprecht            subclass.IsValid(),
14399451b44SJordan Rupprecht            'make sure we find a local variabble named "subclass"')
144619e2e09SDave Lee        self.assertEqual(subclass.GetType().GetName(),
14599451b44SJordan Rupprecht                        'EnumTemplate<EnumType::Subclass>')
14699451b44SJordan Rupprecht
14799451b44SJordan Rupprecht        expr_result = frame.EvaluateExpression("subclass.getMember()")
14899451b44SJordan Rupprecht        self.assertTrue(
14999451b44SJordan Rupprecht            expr_result.IsValid(),
15099451b44SJordan Rupprecht            'got a valid expression result from expression "subclass.getMember()"')
151*0ed758b2SDave Lee        self.assertEqual(
152*0ed758b2SDave Lee            expr_result.GetValue(), "246",
15399451b44SJordan Rupprecht            "subclass.getMember() == 246")
154*0ed758b2SDave Lee        self.assertEqual(
155*0ed758b2SDave Lee            expr_result.GetType().GetName(), "int",
15699451b44SJordan Rupprecht            'expr_result.GetType().GetName() == "int"')
157