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 mydir = TestBase.compute_mydir(__file__) 17 18 def prepareProcess(self): 19 self.build() 20 21 # Create a target by the debugger. 22 exe = self.getBuildArtifact("a.out") 23 target = self.dbg.CreateTarget(exe) 24 self.assertTrue(target, VALID_TARGET) 25 26 # Set breakpoints inside and outside methods that take pointers to the 27 # containing struct. 28 line = line_number('main.cpp', '// Breakpoint 1') 29 lldbutil.run_break_set_by_file_and_line( 30 self, "main.cpp", line, num_expected_locations=1, loc_exact=True) 31 32 arguments = None 33 environment = None 34 35 # Now launch the process, and do not stop at entry point. 36 process = target.LaunchSimple( 37 arguments, environment, self.get_process_working_directory()) 38 self.assertTrue(process, PROCESS_IS_VALID) 39 40 # Get the thread of the process 41 self.assertTrue( 42 process.GetState() == lldb.eStateStopped, 43 PROCESS_STOPPED) 44 thread = lldbutil.get_stopped_thread( 45 process, lldb.eStopReasonBreakpoint) 46 47 # Get frame for current thread 48 return thread.GetSelectedFrame() 49 50 def test_integer_args(self): 51 frame = self.prepareProcess() 52 53 testpos = frame.FindVariable('testpos') 54 self.assertTrue( 55 testpos.IsValid(), 56 'make sure we find a local variabble named "testpos"') 57 self.assertEquals(testpos.GetType().GetName(), 'TestObj<1>') 58 59 expr_result = frame.EvaluateExpression("testpos.getArg()") 60 self.assertTrue( 61 expr_result.IsValid(), 62 'got a valid expression result from expression "testpos.getArg()"') 63 self.assertEquals(expr_result.GetValue(), "1", "testpos.getArg() == 1") 64 self.assertTrue( 65 expr_result.GetType().GetName() == "int", 66 'expr_result.GetType().GetName() == "int"') 67 68 testneg = frame.FindVariable('testneg') 69 self.assertTrue( 70 testneg.IsValid(), 71 'make sure we find a local variabble named "testneg"') 72 self.assertEquals(testneg.GetType().GetName(), 'TestObj<-1>') 73 74 expr_result = frame.EvaluateExpression("testneg.getArg()") 75 self.assertTrue( 76 expr_result.IsValid(), 77 'got a valid expression result from expression "testneg.getArg()"') 78 self.assertTrue( 79 expr_result.GetValue() == "-1", 80 "testneg.getArg() == -1") 81 self.assertTrue( 82 expr_result.GetType().GetName() == "int", 83 'expr_result.GetType().GetName() == "int"') 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( 91 c1.IsValid(), 92 'make sure we find a local variabble named "c1"') 93 self.assertEquals(c1.GetType().GetName(), 'C<float, T1>') 94 f1 = c1.GetChildMemberWithName("V").GetChildAtIndex(0).GetChildMemberWithName("f") 95 self.assertEquals(f1.GetType().GetName(), 'float') 96 self.assertEquals(f1.GetValue(), '1.5') 97 98 c2 = frame.FindVariable('c2') 99 self.assertTrue( 100 c2.IsValid(), 101 'make sure we find a local variabble named "c2"') 102 self.assertEquals(c2.GetType().GetName(), 'C<double, T1, T2>') 103 f2 = c2.GetChildMemberWithName("V").GetChildAtIndex(0).GetChildMemberWithName("f") 104 self.assertEquals(f2.GetType().GetName(), 'double') 105 self.assertEquals(f2.GetValue(), '1.5') 106 f3 = c2.GetChildMemberWithName("V").GetChildAtIndex(1).GetChildMemberWithName("f") 107 self.assertEquals(f3.GetType().GetName(), 'double') 108 self.assertEquals(f3.GetValue(), '2.5') 109 f4 = c2.GetChildMemberWithName("V").GetChildAtIndex(1).GetChildMemberWithName("i") 110 self.assertEquals(f4.GetType().GetName(), 'int') 111 self.assertEquals(f4.GetValue(), '42') 112 113 # Gcc does not generate the necessary DWARF attribute for enum template 114 # parameters. 115 @expectedFailureAll(bugnumber="llvm.org/pr28354", compiler="gcc") 116 @skipIf(dwarf_version=['<', '4']) 117 def test_enum_args(self): 118 frame = self.prepareProcess() 119 120 # Make sure "member" can be displayed and also used in an expression 121 # correctly 122 member = frame.FindVariable('member') 123 self.assertTrue( 124 member.IsValid(), 125 'make sure we find a local variabble named "member"') 126 self.assertTrue(member.GetType().GetName() == 127 'EnumTemplate<EnumType::Member>') 128 129 expr_result = frame.EvaluateExpression("member.getMember()") 130 self.assertTrue( 131 expr_result.IsValid(), 132 'got a valid expression result from expression "member.getMember()"') 133 self.assertTrue( 134 expr_result.GetValue() == "123", 135 "member.getMember() == 123") 136 self.assertTrue( 137 expr_result.GetType().GetName() == "int", 138 'expr_result.GetType().GetName() == "int"') 139 140 # Make sure "subclass" can be displayed and also used in an expression 141 # correctly 142 subclass = frame.FindVariable('subclass') 143 self.assertTrue( 144 subclass.IsValid(), 145 'make sure we find a local variabble named "subclass"') 146 self.assertTrue(subclass.GetType().GetName() == 147 'EnumTemplate<EnumType::Subclass>') 148 149 expr_result = frame.EvaluateExpression("subclass.getMember()") 150 self.assertTrue( 151 expr_result.IsValid(), 152 'got a valid expression result from expression "subclass.getMember()"') 153 self.assertTrue( 154 expr_result.GetValue() == "246", 155 "subclass.getMember() == 246") 156 self.assertTrue( 157 expr_result.GetType().GetName() == "int", 158 'expr_result.GetType().GetName() == "int"') 159