1 # Copyright 2018-2019 Free Software Foundation, Inc. 2 3 # This program is free software; you can redistribute it and/or modify 4 # it under the terms of the GNU General Public License as published by 5 # the Free Software Foundation; either version 3 of the License, or 6 # (at your option) any later version. 7 # 8 # This program is distributed in the hope that it will be useful, 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 # GNU General Public License for more details. 12 # 13 # You should have received a copy of the GNU General Public License 14 # along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 # Test DW_TAG_variant_part and DW_TAG_variant. 17 18 load_lib dwarf.exp 19 20 # This test can only be run on targets which support DWARF-2 and use 21 # gas. 22 if {![dwarf2_support]} { 23 return 0 24 } 25 26 standard_testfile .c variant.S 27 28 # Make some DWARF for the test. 29 set asm_file [standard_output_file $srcfile2] 30 Dwarf::assemble $asm_file { 31 upvar cu_lang cu_lang 32 33 declare_labels uinteger_label float_label int8_label 34 declare_labels discr_1_label discr_2_label discr_3_label 35 declare_labels one_label two_label 36 37 # Creating a CU with 4-byte addresses lets this test link on 38 # both 32- and 64-bit machines. 39 cu { addr_size 4 } { 40 compile_unit { 41 {name file1.txt} 42 {language @DW_LANG_Rust} 43 } { 44 uinteger_label: DW_TAG_base_type { 45 {DW_AT_byte_size 4 DW_FORM_sdata} 46 {DW_AT_encoding @DW_ATE_unsigned} 47 {DW_AT_name {unsigned integer}} 48 } 49 50 int8_label: DW_TAG_base_type { 51 {DW_AT_byte_size 1 DW_FORM_sdata} 52 {DW_AT_encoding @DW_ATE_signed} 53 {DW_AT_name i8} 54 } 55 56 float_label: base_type { 57 {name float} 58 {encoding @DW_ATE_float} 59 {byte_size 4 DW_FORM_sdata} 60 } 61 62 one_label: structure_type { 63 {name One} 64 {byte_size 4 DW_FORM_sdata} 65 } { 66 member { 67 {name __0} 68 {type :$uinteger_label} 69 {data_member_location 0 data1} 70 } 71 } 72 73 two_label: structure_type { 74 {name Two} 75 {byte_size 4 DW_FORM_sdata} 76 } { 77 member { 78 {name __0} 79 {type :$float_label} 80 {data_member_location 0 data1} 81 } 82 } 83 84 structure_type { 85 {name Simple} 86 {byte_size 8 DW_FORM_sdata} 87 } { 88 variant_part { 89 {discr :$discr_1_label DW_FORM_ref4} 90 } { 91 discr_1_label: member { 92 {type :$uinteger_label} 93 {data_member_location 0 data1} 94 } 95 96 variant { 97 {discr_value 23 udata} 98 } { 99 member { 100 {type :$one_label} 101 {data_member_location 4 data1} 102 } 103 } 104 105 variant { 106 {discr_value 1 udata} 107 } { 108 member { 109 {type :$two_label} 110 {data_member_location 4 data1} 111 } 112 } 113 } 114 } 115 116 structure_type { 117 {name Defaulted} 118 {byte_size 8 DW_FORM_sdata} 119 } { 120 variant_part { 121 {discr :$discr_2_label DW_FORM_ref4} 122 } { 123 discr_2_label: member { 124 {type :$uinteger_label} 125 {data_member_location 0 data1} 126 } 127 128 variant { 129 } { 130 member { 131 {type :$one_label} 132 {data_member_location 4 data1} 133 } 134 } 135 136 variant { 137 {discr_value 1 udata} 138 } { 139 member { 140 {type :$two_label} 141 {data_member_location 4 data1} 142 } 143 } 144 } 145 } 146 147 structure_type { 148 {name Univariant} 149 {byte_size 8 DW_FORM_sdata} 150 } { 151 variant_part { 152 } { 153 variant { 154 } { 155 member { 156 {type :$one_label} 157 {data_member_location 4 data1} 158 } 159 } 160 } 161 } 162 163 # Rust won't emit a negative discriminant like this, but 164 # we want to test the code path anyway. 165 structure_type { 166 {name Negative} 167 {byte_size 8 DW_FORM_sdata} 168 } { 169 variant_part { 170 {discr :$discr_3_label DW_FORM_ref4} 171 } { 172 discr_3_label: member { 173 {type :$int8_label} 174 {data_member_location 0 data1} 175 } 176 177 variant { 178 {discr_value -1 sdata} 179 } { 180 member { 181 {type :$one_label} 182 {data_member_location 4 data1} 183 } 184 } 185 186 # Make this the default value so we'll see an 187 # incorrect result if we mishandle signed 188 # discriminants. 189 variant { 190 } { 191 member { 192 {type :$two_label} 193 {data_member_location 4 data1} 194 } 195 } 196 } 197 } 198 } 199 } 200 } 201 202 if { [prepare_for_testing "failed to prepare" ${testfile} \ 203 [list $srcfile $asm_file] debug] } { 204 return -1 205 } 206 207 if ![runto func] { 208 return -1 209 } 210 211 # Get the values into history so we can use it from Rust. 212 gdb_test "print (void *) buffer" "\\\$1 = .void .. $hex .buffer." 213 gdb_test "print (void *) buffer2" "\\\$2 = .void .. $hex .buffer2." 214 215 gdb_test "set language rust" 216 gdb_test "print *(\$1 as *mut Simple)" " = One\\(23\\)" \ 217 "print as Simple" 218 gdb_test "print *(\$1 as *mut Defaulted)" " = One\\(23\\)" \ 219 "print as Defaulted" 220 gdb_test "print *(\$1 as *mut Univariant)" " = One\\(23\\)" \ 221 "print as Univariant" 222 223 gdb_test "print *(\$2 as *mut Negative)" " = One\\(23\\)" \ 224 "print as Negative" 225