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 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 the 24 # 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=True 28 ) 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 ) 37 self.assertTrue(process, PROCESS_IS_VALID) 38 39 # Get the thread of the process 40 self.assertEqual(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 41 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) 42 43 # Get frame for current thread 44 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 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489") 86 def test_template_template_args(self): 87 frame = self.prepareProcess() 88 89 c1 = frame.FindVariable("c1") 90 self.assertTrue(c1.IsValid(), 'make sure we find a local variabble named "c1"') 91 self.assertEqual(c1.GetType().GetName(), "C<float, T1>") 92 f1 = ( 93 c1.GetChildMemberWithName("V") 94 .GetChildAtIndex(0) 95 .GetChildMemberWithName("f") 96 ) 97 self.assertEqual(f1.GetType().GetName(), "float") 98 self.assertEqual(f1.GetValue(), "1.5") 99 100 c2 = frame.FindVariable("c2") 101 self.assertTrue(c2.IsValid(), 'make sure we find a local variabble named "c2"') 102 self.assertEqual(c2.GetType().GetName(), "C<double, T1, T2>") 103 f2 = ( 104 c2.GetChildMemberWithName("V") 105 .GetChildAtIndex(0) 106 .GetChildMemberWithName("f") 107 ) 108 self.assertEqual(f2.GetType().GetName(), "double") 109 self.assertEqual(f2.GetValue(), "1.5") 110 f3 = ( 111 c2.GetChildMemberWithName("V") 112 .GetChildAtIndex(1) 113 .GetChildMemberWithName("f") 114 ) 115 self.assertEqual(f3.GetType().GetName(), "double") 116 self.assertEqual(f3.GetValue(), "2.5") 117 f4 = ( 118 c2.GetChildMemberWithName("V") 119 .GetChildAtIndex(1) 120 .GetChildMemberWithName("i") 121 ) 122 self.assertEqual(f4.GetType().GetName(), "int") 123 self.assertEqual(f4.GetValue(), "42") 124 125 # Gcc does not generate the necessary DWARF attribute for enum template 126 # parameters. 127 @expectedFailureAll(bugnumber="llvm.org/pr28354", compiler="gcc") 128 @skipIf(dwarf_version=["<", "4"]) 129 def test_enum_args(self): 130 frame = self.prepareProcess() 131 132 # Make sure "member" can be displayed and also used in an expression 133 # correctly 134 member = frame.FindVariable("member") 135 self.assertTrue( 136 member.IsValid(), 'make sure we find a local variabble named "member"' 137 ) 138 self.assertEqual(member.GetType().GetName(), "EnumTemplate<EnumType::Member>") 139 140 expr_result = frame.EvaluateExpression("member.getMember()") 141 self.assertTrue( 142 expr_result.IsValid(), 143 'got a valid expression result from expression "member.getMember()"', 144 ) 145 self.assertEqual(expr_result.GetValue(), "123", "member.getMember() == 123") 146 self.assertEqual( 147 expr_result.GetType().GetName(), 148 "int", 149 'expr_result.GetType().GetName() == "int"', 150 ) 151 152 # Make sure "subclass" can be displayed and also used in an expression 153 # correctly 154 subclass = frame.FindVariable("subclass") 155 self.assertTrue( 156 subclass.IsValid(), 'make sure we find a local variabble named "subclass"' 157 ) 158 self.assertEqual( 159 subclass.GetType().GetName(), "EnumTemplate<EnumType::Subclass>" 160 ) 161 162 expr_result = frame.EvaluateExpression("subclass.getMember()") 163 self.assertTrue( 164 expr_result.IsValid(), 165 'got a valid expression result from expression "subclass.getMember()"', 166 ) 167 self.assertEqual(expr_result.GetValue(), "246", "subclass.getMember() == 246") 168 self.assertEqual( 169 expr_result.GetType().GetName(), 170 "int", 171 'expr_result.GetType().GetName() == "int"', 172 ) 173