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