1*99451b44SJordan Rupprecht""" 2*99451b44SJordan RupprechtTest lldb data formatter subsystem. 3*99451b44SJordan Rupprecht""" 4*99451b44SJordan Rupprecht 5*99451b44SJordan Rupprecht 6*99451b44SJordan Rupprecht 7*99451b44SJordan Rupprechtimport lldb 8*99451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 9*99451b44SJordan Rupprechtimport lldbsuite.test.lldbutil as lldbutil 10*99451b44SJordan Rupprecht 11*99451b44SJordan Rupprecht 12*99451b44SJordan Rupprechtclass SynthDataFormatterTestCase(TestBase): 13*99451b44SJordan Rupprecht 14*99451b44SJordan Rupprecht def setUp(self): 15*99451b44SJordan Rupprecht # Call super's setUp(). 16*99451b44SJordan Rupprecht TestBase.setUp(self) 17*99451b44SJordan Rupprecht # Find the line number to break at. 18*99451b44SJordan Rupprecht self.line = line_number('main.cpp', '// Set break point at this line.') 19*99451b44SJordan Rupprecht 20*99451b44SJordan Rupprecht def test_with_run_command(self): 21*99451b44SJordan Rupprecht """Test that that file and class static variables display correctly.""" 22*99451b44SJordan Rupprecht self.build() 23*99451b44SJordan Rupprecht self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 24*99451b44SJordan Rupprecht 25*99451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 26*99451b44SJordan Rupprecht self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 27*99451b44SJordan Rupprecht 28*99451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 29*99451b44SJordan Rupprecht 30*99451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint. 31*99451b44SJordan Rupprecht self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 32*99451b44SJordan Rupprecht substrs=['stopped', 33*99451b44SJordan Rupprecht 'stop reason = breakpoint']) 34*99451b44SJordan Rupprecht 35*99451b44SJordan Rupprecht # This is the function to remove the custom formats in order to have a 36*99451b44SJordan Rupprecht # clean slate for the next test case. 37*99451b44SJordan Rupprecht def cleanup(): 38*99451b44SJordan Rupprecht self.runCmd('type format clear', check=False) 39*99451b44SJordan Rupprecht self.runCmd('type summary clear', check=False) 40*99451b44SJordan Rupprecht self.runCmd('type filter clear', check=False) 41*99451b44SJordan Rupprecht 42*99451b44SJordan Rupprecht # Execute the cleanup function during test case tear down. 43*99451b44SJordan Rupprecht self.addTearDownHook(cleanup) 44*99451b44SJordan Rupprecht 45*99451b44SJordan Rupprecht # Pick some values and check that the basics work 46*99451b44SJordan Rupprecht self.runCmd("type filter add BagOfInts --child x --child z") 47*99451b44SJordan Rupprecht self.expect("frame variable int_bag", 48*99451b44SJordan Rupprecht substrs=['x = 6', 49*99451b44SJordan Rupprecht 'z = 8']) 50*99451b44SJordan Rupprecht 51*99451b44SJordan Rupprecht # Check we can still access the missing child by summary 52*99451b44SJordan Rupprecht self.runCmd( 53*99451b44SJordan Rupprecht "type summary add BagOfInts --summary-string \"y=${var.y}\"") 54*99451b44SJordan Rupprecht self.expect('frame variable int_bag', 55*99451b44SJordan Rupprecht substrs=['y=7']) 56*99451b44SJordan Rupprecht 57*99451b44SJordan Rupprecht # Even if we have synth children, the summary prevails 58*99451b44SJordan Rupprecht self.expect("frame variable int_bag", matching=False, 59*99451b44SJordan Rupprecht substrs=['x = 6', 60*99451b44SJordan Rupprecht 'z = 8']) 61*99451b44SJordan Rupprecht 62*99451b44SJordan Rupprecht # if we skip synth and summary show y 63*99451b44SJordan Rupprecht self.expect( 64*99451b44SJordan Rupprecht "frame variable int_bag --synthetic-type false --no-summary-depth=1", 65*99451b44SJordan Rupprecht substrs=[ 66*99451b44SJordan Rupprecht 'x = 6', 67*99451b44SJordan Rupprecht 'y = 7', 68*99451b44SJordan Rupprecht 'z = 8']) 69*99451b44SJordan Rupprecht 70*99451b44SJordan Rupprecht # if we ask for raw output same happens 71*99451b44SJordan Rupprecht self.expect("frame variable int_bag --raw-output", 72*99451b44SJordan Rupprecht substrs=['x = 6', 73*99451b44SJordan Rupprecht 'y = 7', 74*99451b44SJordan Rupprecht 'z = 8']) 75*99451b44SJordan Rupprecht 76*99451b44SJordan Rupprecht # Summary+Synth must work together 77*99451b44SJordan Rupprecht self.runCmd( 78*99451b44SJordan Rupprecht "type summary add BagOfInts --summary-string \"x=${var.x}\" -e") 79*99451b44SJordan Rupprecht self.expect('frame variable int_bag', 80*99451b44SJordan Rupprecht substrs=['x=6', 81*99451b44SJordan Rupprecht 'x = 6', 82*99451b44SJordan Rupprecht 'z = 8']) 83*99451b44SJordan Rupprecht 84*99451b44SJordan Rupprecht # Same output, but using Python 85*99451b44SJordan Rupprecht self.runCmd( 86*99451b44SJordan Rupprecht "type summary add BagOfInts --python-script \"return 'x=%s' % valobj.GetChildMemberWithName('x').GetValue()\" -e") 87*99451b44SJordan Rupprecht self.expect('frame variable int_bag', 88*99451b44SJordan Rupprecht substrs=['x=6', 89*99451b44SJordan Rupprecht 'x = 6', 90*99451b44SJordan Rupprecht 'z = 8']) 91*99451b44SJordan Rupprecht 92*99451b44SJordan Rupprecht # If I skip summaries, still give me the artificial children 93*99451b44SJordan Rupprecht self.expect("frame variable int_bag --no-summary-depth=1", 94*99451b44SJordan Rupprecht substrs=['x = 6', 95*99451b44SJordan Rupprecht 'z = 8']) 96*99451b44SJordan Rupprecht 97*99451b44SJordan Rupprecht # Delete synth and check that the view reflects it immediately 98*99451b44SJordan Rupprecht self.runCmd("type filter delete BagOfInts") 99*99451b44SJordan Rupprecht self.expect("frame variable int_bag", 100*99451b44SJordan Rupprecht substrs=['x = 6', 101*99451b44SJordan Rupprecht 'y = 7', 102*99451b44SJordan Rupprecht 'z = 8']) 103*99451b44SJordan Rupprecht 104*99451b44SJordan Rupprecht # Add the synth again and check that it's honored deeper in the 105*99451b44SJordan Rupprecht # hierarchy 106*99451b44SJordan Rupprecht self.runCmd("type filter add BagOfInts --child x --child z") 107*99451b44SJordan Rupprecht self.expect('frame variable bag_bag', 108*99451b44SJordan Rupprecht substrs=['x = x=69 {', 109*99451b44SJordan Rupprecht 'x = 69', 110*99451b44SJordan Rupprecht 'z = 71', 111*99451b44SJordan Rupprecht 'y = x=66 {', 112*99451b44SJordan Rupprecht 'x = 66', 113*99451b44SJordan Rupprecht 'z = 68']) 114*99451b44SJordan Rupprecht self.expect('frame variable bag_bag', matching=False, 115*99451b44SJordan Rupprecht substrs=['y = 70', 116*99451b44SJordan Rupprecht 'y = 67']) 117*99451b44SJordan Rupprecht 118*99451b44SJordan Rupprecht # Check that a synth can expand nested stuff 119*99451b44SJordan Rupprecht self.runCmd("type filter add BagOfBags --child x.y --child y.z") 120*99451b44SJordan Rupprecht self.expect('frame variable bag_bag', 121*99451b44SJordan Rupprecht substrs=['x.y = 70', 122*99451b44SJordan Rupprecht 'y.z = 68']) 123*99451b44SJordan Rupprecht 124*99451b44SJordan Rupprecht # ...even if we get -> and . wrong 125*99451b44SJordan Rupprecht self.runCmd("type filter add BagOfBags --child x.y --child \"y->z\"") 126*99451b44SJordan Rupprecht self.expect('frame variable bag_bag', 127*99451b44SJordan Rupprecht substrs=['x.y = 70', 128*99451b44SJordan Rupprecht 'y->z = 68']) 129*99451b44SJordan Rupprecht 130*99451b44SJordan Rupprecht # ...even bitfields 131*99451b44SJordan Rupprecht self.runCmd( 132*99451b44SJordan Rupprecht "type filter add BagOfBags --child x.y --child \"y->z[1-2]\"") 133*99451b44SJordan Rupprecht self.expect('frame variable bag_bag --show-types', 134*99451b44SJordan Rupprecht substrs=['x.y = 70', 135*99451b44SJordan Rupprecht '(int:2) y->z[1-2] = 2']) 136*99451b44SJordan Rupprecht 137*99451b44SJordan Rupprecht # ...even if we format the bitfields 138*99451b44SJordan Rupprecht self.runCmd( 139*99451b44SJordan Rupprecht "type filter add BagOfBags --child x.y --child \"y->y[0-0]\"") 140*99451b44SJordan Rupprecht self.runCmd("type format add \"int:1\" -f bool") 141*99451b44SJordan Rupprecht self.expect('frame variable bag_bag --show-types', 142*99451b44SJordan Rupprecht substrs=['x.y = 70', 143*99451b44SJordan Rupprecht '(int:1) y->y[0-0] = true']) 144*99451b44SJordan Rupprecht 145*99451b44SJordan Rupprecht # ...even if we use one-liner summaries 146*99451b44SJordan Rupprecht self.runCmd("type summary add -c BagOfBags") 147*99451b44SJordan Rupprecht self.expect('frame variable bag_bag', substrs=[ 148*99451b44SJordan Rupprecht '(BagOfBags) bag_bag = (x.y = 70, y->y[0-0] = true)']) 149*99451b44SJordan Rupprecht 150*99451b44SJordan Rupprecht self.runCmd("type summary delete BagOfBags") 151*99451b44SJordan Rupprecht 152*99451b44SJordan Rupprecht # now check we are dynamic (and arrays work) 153*99451b44SJordan Rupprecht self.runCmd( 154*99451b44SJordan Rupprecht "type filter add Plenty --child bitfield --child array[0] --child array[2]") 155*99451b44SJordan Rupprecht self.expect('frame variable plenty_of_stuff', 156*99451b44SJordan Rupprecht substrs=['bitfield = 1', 157*99451b44SJordan Rupprecht 'array[0] = 5', 158*99451b44SJordan Rupprecht 'array[2] = 3']) 159*99451b44SJordan Rupprecht 160*99451b44SJordan Rupprecht self.runCmd("n") 161*99451b44SJordan Rupprecht self.expect('frame variable plenty_of_stuff', 162*99451b44SJordan Rupprecht substrs=['bitfield = 17', 163*99451b44SJordan Rupprecht 'array[0] = 5', 164*99451b44SJordan Rupprecht 'array[2] = 3']) 165*99451b44SJordan Rupprecht 166*99451b44SJordan Rupprecht # skip synthetic children 167*99451b44SJordan Rupprecht self.expect('frame variable plenty_of_stuff --synthetic-type no', 168*99451b44SJordan Rupprecht substrs=['some_values = 0x', 169*99451b44SJordan Rupprecht 'array = 0x', 170*99451b44SJordan Rupprecht 'array_size = 5']) 171*99451b44SJordan Rupprecht 172*99451b44SJordan Rupprecht # check flat printing with synthetic children 173*99451b44SJordan Rupprecht self.expect('frame variable plenty_of_stuff --flat', 174*99451b44SJordan Rupprecht substrs=['plenty_of_stuff.bitfield = 17', 175*99451b44SJordan Rupprecht '*(plenty_of_stuff.array) = 5', 176*99451b44SJordan Rupprecht '*(plenty_of_stuff.array) = 3']) 177*99451b44SJordan Rupprecht 178*99451b44SJordan Rupprecht # check that we do not lose location information for our children 179*99451b44SJordan Rupprecht self.expect('frame variable plenty_of_stuff --location', 180*99451b44SJordan Rupprecht substrs=['0x', 181*99451b44SJordan Rupprecht ': bitfield = 17']) 182*99451b44SJordan Rupprecht 183*99451b44SJordan Rupprecht # check we work across pointer boundaries 184*99451b44SJordan Rupprecht self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1', 185*99451b44SJordan Rupprecht substrs=['(BagOfInts *) plenty_of_stuff.some_values', 186*99451b44SJordan Rupprecht 'x = 5', 187*99451b44SJordan Rupprecht 'z = 7']) 188*99451b44SJordan Rupprecht 189*99451b44SJordan Rupprecht # but not if we don't want to 190*99451b44SJordan Rupprecht self.runCmd("type filter add BagOfInts --child x --child z -p") 191*99451b44SJordan Rupprecht self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1', 192*99451b44SJordan Rupprecht substrs=['(BagOfInts *) plenty_of_stuff.some_values', 193*99451b44SJordan Rupprecht 'x = 5', 194*99451b44SJordan Rupprecht 'y = 6', 195*99451b44SJordan Rupprecht 'z = 7']) 196*99451b44SJordan Rupprecht 197*99451b44SJordan Rupprecht # check we're dynamic even if nested 198*99451b44SJordan Rupprecht self.runCmd("type filter add BagOfBags --child x.z") 199*99451b44SJordan Rupprecht self.expect('frame variable bag_bag', 200*99451b44SJordan Rupprecht substrs=['x.z = 71']) 201*99451b44SJordan Rupprecht 202*99451b44SJordan Rupprecht self.runCmd("n") 203*99451b44SJordan Rupprecht self.expect('frame variable bag_bag', 204*99451b44SJordan Rupprecht substrs=['x.z = 12']) 205*99451b44SJordan Rupprecht 206*99451b44SJordan Rupprecht self.runCmd( 207*99451b44SJordan Rupprecht 'type summary add -e -s "I am always empty but have" EmptyStruct') 208*99451b44SJordan Rupprecht self.expect('frame variable es', substrs=[ 209*99451b44SJordan Rupprecht "I am always empty but have {}"]) 210*99451b44SJordan Rupprecht self.runCmd('type summary add -e -h -s "I am really empty" EmptyStruct') 211*99451b44SJordan Rupprecht self.expect('frame variable es', substrs=["I am really empty"]) 212*99451b44SJordan Rupprecht self.expect( 213*99451b44SJordan Rupprecht 'frame variable es', 214*99451b44SJordan Rupprecht substrs=["I am really empty {}"], 215*99451b44SJordan Rupprecht matching=False) 216