1 # Copyright 2013-2014 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 namespace aliases. 17 # PRs c++/7935, c++/10541 18 19 load_lib dwarf.exp 20 21 if {![dwarf2_support]} { 22 return 0 23 } 24 25 if {[skip_cplus_tests]} { 26 continue 27 } 28 29 standard_testfile .cc nsalias-dw.S 30 31 # Make the DWARF used for the test. This is necessary to work 32 # around compiler issues. Not all versions of gcc output the 33 # correct debuginfo we need. 34 # 35 # This should create the equivalent DWARF to: 36 # 37 # namespace outer 38 # { 39 # namespace inner 40 # { 41 # namespace innermost 42 # { 43 # const int x = 2; 44 # int foo (void) { return x; } 45 # } 46 # 47 # namespace Innermost = innermost; 48 # 49 # const int x = 1; 50 # int foo (void) { return x + Innermost::foo (); } 51 # } 52 # 53 # namespace Inner = inner; 54 # 55 # const int x = 0; 56 # int foo (void) { return x + Inner::foo (); } 57 # } 58 # 59 # namespace Outer = outer; 60 # namespace oi = Outer::Inner; 61 62 set asm_file [standard_output_file $srcfile2] 63 Dwarf::assemble $asm_file { 64 cu {} { 65 compile_unit {{language @DW_LANG_C_plus_plus}} { 66 declare_labels int_label outer_label inner_label innermost_label 67 declare_labels im_foo_label i_foo_label o_foo_label 68 declare_labels OuterInner_label oi1_label oi2_label 69 70 int_label: base_type { 71 {name int} 72 {encoding @DW_ATE_signed} 73 {byte_size 4 DW_FORM_sdata} 74 } 75 76 outer_label: DW_TAG_namespace { 77 {name outer} 78 } { 79 inner_label: DW_TAG_namespace { 80 {name inner} 81 } { 82 innermost_label: DW_TAG_namespace { 83 {name innermost} 84 } { 85 DW_TAG_variable { 86 {name x} 87 {type :$int_label} 88 {const_value 2 DW_FORM_data1} 89 } 90 91 im_foo_label: DW_TAG_subprogram { 92 {name foo} 93 {external 1} 94 {declaration 1} 95 } 96 } 97 98 imported_declaration { 99 {name Innermost} 100 {import :$innermost_label} 101 } 102 103 DW_TAG_variable { 104 {name x} 105 {type :$int_label} 106 {const_value 1 DW_FORM_data1} 107 } 108 109 i_foo_label: subprogram { 110 {name foo} 111 {external 1} 112 {declaration 1} 113 } 114 } 115 116 OuterInner_label: imported_declaration { 117 {name Inner} 118 {import :$inner_label} 119 } 120 121 DW_TAG_variable { 122 {name x} 123 {type :$int_label} 124 {const_value 0 DW_FORM_data1} 125 } 126 127 o_foo_label: subprogram { 128 {name foo} 129 {external 1} 130 {declaration 1} 131 } 132 } 133 134 imported_declaration { 135 {name Outer} 136 {import :$outer_label} 137 } 138 139 oi1_label: imported_declaration { 140 {name oi1} 141 {import :$OuterInner_label} 142 } 143 144 oi2_label: imported_declaration { 145 {name oi2} 146 {import :$oi1_label} 147 } 148 149 imported_declaration { 150 {name oi3} 151 {import :$oi2_label} 152 } 153 154 subprogram { 155 {specification :$im_foo_label} 156 {low_pc 0x0} 157 {high_pc 0x1} 158 } 159 160 subprogram { 161 {specification :$i_foo_label} 162 {low_pc 0x2} 163 {high_pc 0x3} 164 } 165 166 subprogram { 167 {specification :$o_foo_label} 168 {low_pc 0x4} 169 {high_pc 0x5} 170 } 171 } 172 } 173 } 174 175 if {[gdb_compile $srcdir/$subdir/$srcfile ${binfile}1.o \ 176 object {c++ debug}] != ""} { 177 return -1 178 } 179 180 if {[gdb_compile $asm_file ${binfile}2.o object {nodebug}] != ""} { 181 return -1 182 } 183 184 if {[gdb_compile [list ${binfile}1.o ${binfile}2.o] \ 185 $binfile executable {c++}] != ""} { 186 return -1 187 } 188 189 clean_restart $testfile 190 191 # A procedure to run various tests on aliased namespaces. 192 proc do_alias_tests {ns {real ""} {x ""}} { 193 194 # The "real" namespace is simply NS in all lowercase. 195 if {$real == ""} { 196 set real [string tolower $ns] 197 } 198 199 # The value of `x' is the number of '::' in NS. 200 if {$x == ""} { 201 set x [expr {[llength [split $ns ":"]] / 2}] 202 } 203 204 # Test "whatis" 205 gdb_test "whatis $ns" "type = $real" 206 207 # Test "ptype" 208 gdb_test "ptype $ns" "type = namespace $real" 209 210 # Print 'x' 211 send_log "expecting x = $x\n" 212 gdb_test "print ${ns}::x" " = $x" 213 214 # Attempt to list the function. 215 gdb_test_no_output "list ${ns}::foo" 216 217 # Attempt to break on the start of the function. 218 gdb_breakpoint "*${ns}::foo" 219 220 # And then erase it 221 with_test_prefix "($ns)" { 222 gdb_test_no_output "delete \$bpnum" 223 } 224 } 225 226 # This is a list of all the permutations to be tested. For troubleshooting 227 # purposes, this list is explicitly enumerated. 228 229 set permutations {} 230 lappend permutations "outer" 231 lappend permutations "Outer" 232 lappend permutations "outer::inner" 233 lappend permutations "Outer::inner" 234 lappend permutations "outer::Inner" 235 lappend permutations "Outer::Inner" 236 lappend permutations "outer::inner::innermost" 237 lappend permutations "outer::inner::Innermost" 238 lappend permutations "outer::Inner::innermost" 239 lappend permutations "outer::Inner::Innermost" 240 lappend permutations "Outer::inner::innermost" 241 lappend permutations "Outer::inner::Innermost" 242 lappend permutations "Outer::Inner::innermost" 243 lappend permutations "Outer::Inner::Innermost" 244 245 foreach p $permutations { 246 do_alias_tests $p 247 } 248 249 # Test recursively imported aliases. 250 foreach ns {"oi1" "oi2" "oi3"} { 251 do_alias_tests $ns "outer::inner" 1 252 do_alias_tests "${ns}::innermost" "outer::inner::innermost" 2 253 do_alias_tests "${ns}::Innermost" "outer::inner::innermost" 2 254 } 255 256 # Generate another objfile with nested imported declarations. 257 258 set imports { 259 declare_labels n0_label 260 261 n0_label: DW_TAG_namespace { 262 {name n0} 263 } { 264 DW_TAG_variable { 265 {name x} 266 {type :$int_label} 267 {const_value 3 DW_FORM_data1} 268 } 269 } 270 271 declare_labels n0_import 272 n0_import: imported_declaration { 273 {name N0} 274 {import :$n0_label} 275 } 276 } 277 278 for {set i 1} {$i <= 100} {incr i} { 279 append imports [format " 280 declare_labels n%d_import 281 n%d_import: imported_declaration { 282 {name N%d} 283 {import :\$n%d_import} 284 }" $i $i $i [expr {$i - 1}]] 285 } 286 287 standard_testfile .cc nsalias-r-dw.S 288 289 set asm_file [standard_output_file $srcfile2] 290 set the_dwarf [format { 291 cu {} { 292 compile_unit {{language @DW_LANG_C_plus_plus}} { 293 declare_labels int_label n0_label 294 295 int_label: base_type { 296 {name int} 297 {encoding @DW_ATE_signed} 298 {byte_size 4 DW_FORM_sdata} 299 } 300 301 %s 302 } 303 } 304 } $imports] 305 306 Dwarf::assemble $asm_file $the_dwarf 307 308 if {[gdb_compile $asm_file ${binfile}3.o object {nodebug}] != ""} { 309 return -1 310 } 311 312 if {[gdb_compile [list ${binfile}1.o ${binfile}3.o] \ 313 ${binfile}-r executable {c++}] != ""} { 314 return -1 315 } 316 317 clean_restart ${testfile}-r 318 319 gdb_test_no_output "set complaints 1" 320 gdb_test "print N100::x" \ 321 ".* has too many recursively imported declarations.*" \ 322 "compaint for too many recursively imported declarations" 323