1# Test macro scoping. 2# Copyright 2002 Free Software Foundation, Inc. 3 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 2 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program; if not, write to the Free Software 16# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18# Please email any bugs, comments, and/or additions to this file to: 19# bug-gdb@prep.ai.mit.edu 20 21if $tracelevel then { 22 strace $tracelevel 23} 24 25set prms_id 0 26set bug_id 0 27 28set testfile "macscp" 29set binfile ${objdir}/${subdir}/${testfile} 30 31if {[gdb_compile "${srcdir}/${subdir}/macscp1.c" "${binfile}" executable {debug}] != "" } { 32 gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." 33} 34 35gdb_exit 36gdb_start 37gdb_reinitialize_dir $srcdir/$subdir 38gdb_load ${binfile} 39 40 41# Ask GDB to show the current definition of MACRO, and return a list 42# describing the result. 43# 44# The return value has the form {FILE1 FILE2 ... DEF}, which means 45# that MACRO has the definition `DEF', and was defined in `FILE1', 46# which was included from `FILE2', included from ... . 47# 48# If GDB says that MACRO has no definition, return the string `undefined'. 49# 50# If GDB complains that it doesn't have any information about 51# preprocessor macro definitions, return the string `no-macro-info'. 52# 53# If expect times out waiting for GDB, we return the string `timeout'. 54# 55# If GDB's output doesn't otherwise match what we're expecting, we 56# return the empty string. 57 58proc info_macro {macro} { 59 global gdb_prompt 60 global decimal 61 62 set filepat {macscp[0-9]+\.[ch]} 63 set definition {} 64 set location {} 65 66 send_gdb "info macro ${macro}\n" 67 68 set debug_me 0 69 70 if {$debug_me} {exp_internal 1} 71 gdb_expect { 72 -re "Defined at \[^\r\n\]*(${filepat}):${decimal}\[\r\n\]" { 73 # `location' and `definition' should be empty when we see 74 # this message. 75 if {[llength $location] == 0 && [llength $definition] == 0} { 76 set location $expect_out(1,string) 77 exp_continue 78 } else { 79 # Exit this expect loop, with a result indicating failure. 80 set definition {} 81 } 82 } 83 -re "The symbol `${macro}' has no definition as a C/C\\+\\+ preprocessor macro\[^\r\n\]*\[\r\n\]" { 84 # `location' and `definition' should be empty when we see 85 # this message. 86 if {[llength $location] == 0 && [llength $definition] == 0} { 87 set definition undefined 88 exp_continue 89 } else { 90 # Exit this expect loop, with a result indicating failure. 91 set definition {} 92 } 93 } 94 -re "^\[\r\n\]* included at \[^\r\n\]*(${filepat}):${decimal}\[\r\n\]" { 95 # `location' should *not* be empty when we see this 96 # message. It should have recorded at least the initial 97 # `Defined at ' message (for definitions) or ` at' message 98 # (for undefined symbols). 99 if {[llength $location] != 0} { 100 lappend location $expect_out(1,string) 101 exp_continue 102 } else { 103 # Exit this expect loop, with a result indicating failure. 104 set definition {} 105 } 106 } 107 -re "^\[\r\n\]*at \[^\r\n\]*(${filepat}):${decimal}\[\r\n\]" { 108 # This appears after a `has no definition' message. 109 # `location' should be empty when we see it. 110 if {[string compare $definition undefined] == 0 \ 111 && [llength $location] == 0} { 112 set location $expect_out(1,string) 113 exp_continue 114 } else { 115 # Exit this expect loop, with a result indicating failure. 116 set definition {} 117 } 118 } 119 -re "#define ${macro} (\[^\r\n\]*)\[\r\n\]" { 120 # `definition' should be empty when we see this message. 121 if {[string compare $definition ""] == 0} { 122 set definition $expect_out(1,string) 123 exp_continue 124 } else { 125 # Exit this expect loop, with a result indicating failure. 126 set definition {} 127 } 128 } 129 -re "has no preprocessor macro information.*$gdb_prompt $" { 130 set definition no-macro-info 131 } 132 -re "$gdb_prompt $" { 133 # Exit the expect loop; let the existing value of `definition' 134 # indicate failure or success. 135 } 136 timeout { 137 set definition timeout 138 } 139 } 140 if {$debug_me} {exp_internal 0} 141 142 switch -exact -- $definition { 143 no-macro-info { return no-macro-info } 144 timeout { return timeout } 145 undefined - 146 default { 147 if {[llength $location] >= 1} { 148 return [concat $location [list $definition]] 149 } else { 150 return {} 151 } 152 } 153 } 154} 155 156 157# Call info_macro to show the definition of MACRO. Expect a result of 158# EXPECTED. Use WHERE in pass/fail messages to identify the context. 159# Return non-zero if we should abort the entire test file, or zero if 160# we can continue. 161proc check_macro {macro expected where} { 162 set func_def [info_macro $macro] 163 if {[string compare $func_def $expected] == 0} { 164 pass "info macro $macro $where" 165 } else { 166 switch -exact -- $func_def { 167 no-macro-info { 168 xfail "executable includes no macro debugging information" 169 return 1 170 } 171 timeout { 172 fail "info macro $macro $where (timeout)" 173 } 174 default { 175 fail "info macro $macro $where" 176 } 177 } 178 } 179 return 0 180} 181 182 183# List the function FUNC, and then show the definition of MACRO, 184# expecting the result EXPECTED. 185proc list_and_check_macro {func macro expected} { 186 gdb_test "list $func" ".*${func}.*" 187 return [check_macro $macro $expected "after `list $func'"] 188} 189 190 191if {[list_and_check_macro main WHERE {macscp1.c {before macscp1_3}}]} { 192 return 0 193} 194list_and_check_macro macscp2_2 WHERE {macscp2.h macscp1.c {before macscp2_2}} 195list_and_check_macro macscp3_2 WHERE {macscp3.h macscp1.c {before macscp3_2}} 196 197 198# Although GDB's macro table structures distinguish between multiple 199# #inclusions of the same file, GDB's other structures don't. So the 200# `list' command here doesn't reliably select one #inclusion or the 201# other, even though it could. It would be nice to eventually change 202# GDB's structures to handle this correctly. 203gdb_test "list macscp4_2_from_macscp2" ".*macscp4_2_, MACSCP4_INCLUSION.*" 204switch -exact -- [info_macro WHERE] { 205 {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}} { 206 pass "info macro WHERE after `list macscp_4_2_from_macscp2'" 207 } 208 {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}} { 209 # setup_kfail "gdb/555" 210 fail "info macro WHERE after `list macscp_4_2_from_macscp2' (gdb/555)" 211 } 212 timeout { 213 fail "info macro WHERE after `list macscp_4_2_from_macscp2' (timeout)" 214 } 215 default { fail "info macro WHERE after `list macscp_4_2_from_macscp2'" } 216} 217 218gdb_test "list macscp4_2_from_macscp3" ".*macscp4_2_, MACSCP4_INCLUSION.*" 219switch -exact -- [info_macro WHERE] { 220 {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}} { 221 pass "info macro WHERE after `list macscp_4_2_from_macscp3'" 222 } 223 {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}} { 224 # setup_kfail "gdb/555" 225 fail "info macro WHERE after `list macscp_4_2_from_macscp3' (gdb/555)" 226 } 227 timeout { 228 fail "info macro WHERE after `list macscp_4_2_from_macscp3' (timeout)" 229 } 230 default { fail "info macro WHERE after `list macscp_4_2_from_macscp3'" } 231} 232 233 234#### Test the selection of the macro scope by the current frame. 235 236### A table of functions, in the order they will be reached, which is 237### also the order they appear in the preprocessed output. Each entry 238### has the form {FUNCNAME WHERE KFAILWHERE}, where: 239### - FUNCNAME is the name of the function, 240### - WHERE is the definition we expect to see for the macro `WHERE', as 241### returned by `info_macro', and 242### - KFAILWHERE is an alternate definition which should be reported 243### as a `known failure', due to GDB's inability to distinguish multiple 244### #inclusions of the same file. 245### KFAILWHERE may be omitted. 246 247set funcs { 248 { 249 macscp1_1 250 {macscp1.c {before macscp1_1}} 251 } 252 { 253 macscp2_1 254 {macscp2.h macscp1.c {before macscp2_1}} 255 } 256 { 257 macscp4_1_from_macscp2 258 {macscp4.h macscp2.h macscp1.c {before macscp4_1_..., from macscp2.h}} 259 {macscp4.h macscp3.h macscp1.c {before macscp4_1_..., from macscp3.h}} 260 } 261 { 262 macscp4_2_from_macscp2 263 {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}} 264 {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}} 265 } 266 { 267 macscp2_2 268 {macscp2.h macscp1.c {before macscp2_2}} 269 } 270 { 271 macscp1_2 272 {macscp1.c {before macscp1_2}} 273 } 274 { 275 macscp3_1 276 {macscp3.h macscp1.c {before macscp3_1}} 277 } 278 { 279 macscp4_1_from_macscp3 280 {macscp4.h macscp3.h macscp1.c {before macscp4_1_..., from macscp3.h}} 281 {macscp4.h macscp2.h macscp1.c {before macscp4_1_..., from macscp2.h}} 282 } 283 { 284 macscp4_2_from_macscp3 285 {macscp4.h macscp3.h macscp1.c {before macscp4_2_..., from macscp3.h}} 286 {macscp4.h macscp2.h macscp1.c {before macscp4_2_..., from macscp2.h}} 287 } 288 { 289 macscp3_2 290 {macscp3.h macscp1.c {before macscp3_2}} 291 } 292 { 293 macscp1_3 294 {macscp1.c {before macscp1_3}} 295 } 296} 297 298 299# Start the program running. 300if {! [runto_main]} { 301 fail "macro tests suppressed: couldn't run to main" 302 return 0 303} 304 305# Set a breakpoint on each of the functions. 306foreach func_entry $funcs { 307 set func [lindex $func_entry 0] 308 gdb_test "break $func" "Breakpoint.*" 309} 310 311# Run to each of the breakpoints and check the definition (or lack 312# thereof) of each macro. 313for {set i 0} {$i < [llength $funcs]} {incr i} { 314 set func_entry [lindex $funcs $i] 315 set func [lindex $func_entry 0] 316 set expected [lindex $func_entry 1] 317 set kfail_expected [lindex $func_entry 2] 318 319 # Run to the breakpoint for $func. 320 gdb_test "continue" "Breakpoint $decimal, $func .*" "continue to $func" 321 322 # Check the macro WHERE. 323 set result [info_macro WHERE] 324 if {[string compare $result $expected] == 0} { 325 pass "info macro WHERE stopped in $func" 326 } elseif {[string compare $result $kfail_expected] == 0} { 327 # setup_kfail "gdb/555" 328 fail "info macro WHERE stopped in $func (gdb/555)" 329 } elseif {[string compare $result timeout] == 0} { 330 fail "info macro WHERE stopped in $func (timeout)" 331 } else { 332 fail "info macro WHERE stopped in $func" 333 } 334 335 # Check that the BEFORE_<func> macros for all prior functions are 336 # #defined, and that those for all subsequent functions are not. 337 for {set j 0} {$j < [llength $funcs]} {incr j} { 338 if {$j != $i} { 339 set func_j_entry [lindex $funcs $j] 340 set func_j [lindex $func_j_entry 0] 341 342 set before_macro "BEFORE_[string toupper $func_j]" 343 set test_name \ 344 "$before_macro defined/undefined when stopped at $func" 345 set result [info_macro $before_macro] 346 347 # We can't get the right scope info when we're stopped in 348 # the macro4_ functions. 349 if {[string match macscp4_* $func]} { 350 # setup_kfail "gdb/555" 351 set test_name "$test_name (gdb/555)" 352 } 353 if {$j < $i} { 354 if {[llength $result] >= 2 && \ 355 [string compare [lindex $result end] {}] == 0} { 356 pass $test_name 357 } elseif {[string compare $result timeout] == 0} { 358 fail "$test_name (timeout)" 359 } else { 360 fail "$test_name" 361 } 362 } elseif {$j > $i} { 363 switch -- [lindex $result end] { 364 undefined { pass $test_name } 365 timeout { fail "$test_name (timeout)" } 366 default { 367 fail "$test_name" 368 } 369 } 370 } 371 372 set until_macro "UNTIL_[string toupper $func_j]" 373 set test_name \ 374 "$until_macro defined/undefined when stopped at $func" 375 set result [info_macro $until_macro] 376 377 # We can't get the right scope info when we're stopped in 378 # the macro4_ functions. 379 if {[string match macscp4_* $func]} { 380 # setup_kfail "gdb/555" 381 set test_name "$test_name (gdb/555)" 382 } 383 if {$j <= $i} { 384 switch -- [lindex $result end] { 385 undefined { pass $test_name } 386 timeout { fail "$test_name (timeout)" } 387 default { 388 fail "$test_name" 389 } 390 } 391 } elseif {$j > $i} { 392 if {[llength $result] >= 2 && \ 393 [string compare [lindex $result end] {}] == 0} { 394 pass $test_name 395 } elseif {[string compare $result timeout] == 0} { 396 fail "$test_name (timeout)" 397 } else { 398 fail "$test_name" 399 } 400 } 401 } 402 } 403} 404