172 lines · python
1"""2Test that C++ template classes that have integer parameters work correctly.3 4We must reconstruct the types correctly so the template types are correct5and display correctly, and also make sure the expression parser works and6is able the find all needed functions when evaluating expressions7"""8import lldb9from lldbsuite.test.decorators import *10from lldbsuite.test.lldbtest import *11from lldbsuite.test import lldbutil12 13 14class TemplateArgsTestCase(TestBase):15 def prepareProcess(self):16 self.build()17 18 # Create a target by the debugger.19 exe = self.getBuildArtifact("a.out")20 target = self.dbg.CreateTarget(exe)21 self.assertTrue(target, VALID_TARGET)22 23 # Set breakpoints inside and outside methods that take pointers to the24 # containing struct.25 line = line_number("main.cpp", "// Breakpoint 1")26 lldbutil.run_break_set_by_file_and_line(27 self, "main.cpp", line, num_expected_locations=1, loc_exact=True28 )29 30 arguments = None31 environment = None32 33 # Now launch the process, and do not stop at entry point.34 process = target.LaunchSimple(35 arguments, environment, self.get_process_working_directory()36 )37 self.assertTrue(process, PROCESS_IS_VALID)38 39 # Get the thread of the process40 self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)41 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)42 43 # Get frame for current thread44 return thread.GetSelectedFrame()45 46 def test_integer_args(self):47 frame = self.prepareProcess()48 49 testpos = frame.FindVariable("testpos")50 self.assertTrue(51 testpos.IsValid(), 'make sure we find a local variabble named "testpos"'52 )53 self.assertEqual(testpos.GetType().GetName(), "TestObj<1>")54 55 expr_result = frame.EvaluateExpression("testpos.getArg()")56 self.assertTrue(57 expr_result.IsValid(),58 'got a valid expression result from expression "testpos.getArg()"',59 )60 self.assertEqual(expr_result.GetValue(), "1", "testpos.getArg() == 1")61 self.assertEqual(62 expr_result.GetType().GetName(),63 "int",64 'expr_result.GetType().GetName() == "int"',65 )66 67 testneg = frame.FindVariable("testneg")68 self.assertTrue(69 testneg.IsValid(), 'make sure we find a local variabble named "testneg"'70 )71 self.assertEqual(testneg.GetType().GetName(), "TestObj<-1>")72 73 expr_result = frame.EvaluateExpression("testneg.getArg()")74 self.assertTrue(75 expr_result.IsValid(),76 'got a valid expression result from expression "testneg.getArg()"',77 )78 self.assertEqual(expr_result.GetValue(), "-1", "testneg.getArg() == -1")79 self.assertEqual(80 expr_result.GetType().GetName(),81 "int",82 'expr_result.GetType().GetName() == "int"',83 )84 85 def test_template_template_args(self):86 frame = self.prepareProcess()87 88 c1 = frame.FindVariable("c1")89 self.assertTrue(c1.IsValid(), 'make sure we find a local variabble named "c1"')90 self.assertEqual(c1.GetType().GetName(), "C<float, T1>")91 f1 = (92 c1.GetChildMemberWithName("V")93 .GetChildAtIndex(0)94 .GetChildMemberWithName("f")95 )96 self.assertEqual(f1.GetType().GetName(), "float")97 self.assertEqual(f1.GetValue(), "1.5")98 99 c2 = frame.FindVariable("c2")100 self.assertTrue(c2.IsValid(), 'make sure we find a local variabble named "c2"')101 self.assertEqual(c2.GetType().GetName(), "C<double, T1, T2>")102 f2 = (103 c2.GetChildMemberWithName("V")104 .GetChildAtIndex(0)105 .GetChildMemberWithName("f")106 )107 self.assertEqual(f2.GetType().GetName(), "double")108 self.assertEqual(f2.GetValue(), "1.5")109 f3 = (110 c2.GetChildMemberWithName("V")111 .GetChildAtIndex(1)112 .GetChildMemberWithName("f")113 )114 self.assertEqual(f3.GetType().GetName(), "double")115 self.assertEqual(f3.GetValue(), "2.5")116 f4 = (117 c2.GetChildMemberWithName("V")118 .GetChildAtIndex(1)119 .GetChildMemberWithName("i")120 )121 self.assertEqual(f4.GetType().GetName(), "int")122 self.assertEqual(f4.GetValue(), "42")123 124 # Gcc does not generate the necessary DWARF attribute for enum template125 # parameters.126 @expectedFailureAll(bugnumber="llvm.org/pr28354", compiler="gcc")127 @skipIf(dwarf_version=["<", "4"])128 def test_enum_args(self):129 frame = self.prepareProcess()130 131 # Make sure "member" can be displayed and also used in an expression132 # correctly133 member = frame.FindVariable("member")134 self.assertTrue(135 member.IsValid(), 'make sure we find a local variabble named "member"'136 )137 self.assertEqual(member.GetType().GetName(), "EnumTemplate<EnumType::Member>")138 139 expr_result = frame.EvaluateExpression("member.getMember()")140 self.assertTrue(141 expr_result.IsValid(),142 'got a valid expression result from expression "member.getMember()"',143 )144 self.assertEqual(expr_result.GetValue(), "123", "member.getMember() == 123")145 self.assertEqual(146 expr_result.GetType().GetName(),147 "int",148 'expr_result.GetType().GetName() == "int"',149 )150 151 # Make sure "subclass" can be displayed and also used in an expression152 # correctly153 subclass = frame.FindVariable("subclass")154 self.assertTrue(155 subclass.IsValid(), 'make sure we find a local variabble named "subclass"'156 )157 self.assertEqual(158 subclass.GetType().GetName(), "EnumTemplate<EnumType::Subclass>"159 )160 161 expr_result = frame.EvaluateExpression("subclass.getMember()")162 self.assertTrue(163 expr_result.IsValid(),164 'got a valid expression result from expression "subclass.getMember()"',165 )166 self.assertEqual(expr_result.GetValue(), "246", "subclass.getMember() == 246")167 self.assertEqual(168 expr_result.GetType().GetName(),169 "int",170 'expr_result.GetType().GetName() == "int"',171 )172