# Test macro scoping.
-# Copyright 2002, 2007, 2008 Free Software Foundation, Inc.
+# Copyright 2002, 2007, 2008, 2009 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-# Please email any bugs, comments, and/or additions to this file to:
-# bug-gdb@prep.ai.mit.edu
-
if $tracelevel then {
strace $tracelevel
}
set srcfile macscp1.c
set testfile "macscp"
+set objfile ${objdir}/${subdir}/${testfile}.o
set binfile ${objdir}/${subdir}/${testfile}
-set options { debug }
+set options { debug additional_flags=-DFROM_COMMANDLINE=ARG}
get_compiler_info ${binfile}
if [test_compiler_info gcc*] {
lappend options additional_flags=-g3
}
-if {[gdb_compile "${srcdir}/${subdir}/macscp1.c" "${binfile}" executable $options] != "" } {
+# Generate the intermediate object file. This is required by Darwin to
+# have access to the .debug_macinfo section.
+if {[gdb_compile "${srcdir}/${subdir}/macscp1.c" "${objfile}" \
+ object $options] != ""
+ || [gdb_compile "${objfile}" "${binfile}" executable $options] != "" } {
untested macscp.exp
return -1
}
proc info_macro {macro} {
global gdb_prompt
- global decimal
set filepat {macscp[0-9]+\.[ch]}
set definition {}
set location {}
+ # Line number zero is set for macros defined from the compiler command-line.
+ # Such macros are not being tested by this function.
+ set nonzero {[1-9][0-9]*}
+
send_gdb "info macro ${macro}\n"
set debug_me 0
if {$debug_me} {exp_internal 1}
gdb_expect {
- -re "Defined at \[^\r\n\]*(${filepat}):${decimal}\[\r\n\]" {
+ -re "Defined at \[^\r\n\]*(${filepat}):${nonzero}\[\r\n\]" {
# `location' and `definition' should be empty when we see
# this message.
if {[llength $location] == 0 && [llength $definition] == 0} {
set definition {}
}
}
- -re "^\[\r\n\]* included at \[^\r\n\]*(${filepat}):${decimal}\[\r\n\]" {
+ -re "^\[\r\n\]* included at \[^\r\n\]*(${filepat}):${nonzero}\[\r\n\]" {
# `location' should *not* be empty when we see this
# message. It should have recorded at least the initial
# `Defined at ' message (for definitions) or ` at' message
set definition {}
}
}
- -re "^\[\r\n\]*at \[^\r\n\]*(${filepat}):${decimal}\[\r\n\]" {
+ -re "^\[\r\n\]*at \[^\r\n\]*(${filepat}):${nonzero}\[\r\n\]" {
# This appears after a `has no definition' message.
# `location' should be empty when we see it.
if {[string compare $definition undefined] == 0 \
switch -exact -- $definition {
no-macro-info { return no-macro-info }
timeout { return timeout }
- undefined -
+ undefined { return undefined }
default {
if {[llength $location] >= 1} {
return [concat $location [list $definition]]
xfail "executable includes no macro debugging information"
return 1
}
+ undefined {
+ fail "info macro $macro $where (undefined)"
+ return 1
+ }
timeout {
fail "info macro $macro $where (timeout)"
}
}
return 0
}
-
+
# List the function FUNC, and then show the definition of MACRO,
# expecting the result EXPECTED.
proc list_and_check_macro {func macro expected} {
- gdb_test "list $func" ".*${func}.*"
+ gdb_test "list $func" ".*${func}.*" "list $func for $macro"
return [check_macro $macro $expected "after `list $func'"]
}
if {[list_and_check_macro main WHERE {macscp1.c {before macscp1_3}}]} {
- return 0
+ global verbose
+ set macro_support "unknown"
+ send_gdb "info source\n"
+ gdb_test_multiple "info source" "Test macro information" {
+ -re "Includes preprocessor macro info\..*$gdb_prompt $" {
+ set macro_support 1
+ verbose "Source has macro information"
+ }
+ -re "Does not include preprocessor macro info\..*$gdb_prompt $" {
+ set macro_support 0
+ verbose "Source has no macro information"
+ }
+ default {
+ warning "couldn't check macro support (no valid response)."
+ }
+ }
+ if {$macro_support == 0} {
+ unsupported "Skipping test because debug information does not include macro information."
+ return 0
+ }
}
+
list_and_check_macro macscp2_2 WHERE {macscp2.h macscp1.c {before macscp2_2}}
list_and_check_macro macscp3_2 WHERE {macscp3.h macscp1.c {before macscp3_2}}
+# Assuming the current position inside program by `list' from above.
+gdb_test "info macro FROM_COMMANDLINE" \
+ "Defined at \[^\r\n\]*:0\r\n-DFROM_COMMANDLINE=ARG"
+
+
# Although GDB's macro table structures distinguish between multiple
# #inclusions of the same file, GDB's other structures don't. So the
# `list' command here doesn't reliably select one #inclusion or the
gdb_test "continue" "foo = 0;.*" "continue to macsp_expr"
-gdb_test "print M" \
- "No symbol \"M\" in current context\." \
+gdb_test "print address.addr" \
+ " = 0" \
+ "print address.addr"
+
+gdb_test "print MACRO_TO_EXPAND" \
+ "No symbol \"MACRO_TO_EXPAND\" in current context\." \
"print expression with macro before define."
-gdb_test "next" "foo = 1;" "next to definition"
+gdb_test "next" "foo = 1;" "next to definition 1"
-gdb_test "print M" \
+gdb_test "print MACRO_TO_EXPAND" \
" = 0" \
"print expression with macro in scope."
-gdb_test "macro define M 72" \
+gdb_test "macro define MACRO_TO_EXPAND 72" \
"" \
"user macro override"
-gdb_test "print M" \
+gdb_test "print MACRO_TO_EXPAND" \
" = 72" \
"choose user macro"
-gdb_test "macro undef M" \
+gdb_test "macro undef MACRO_TO_EXPAND" \
"" \
"remove user override"
-gdb_test "print M" \
+gdb_test "print MACRO_TO_EXPAND" \
" = 0" \
"print expression with macro after removing override"
-gdb_test "next" "foo = 2;" "next to definition"
+gdb_test "next" "foo = 2;" "next to definition 2"
-gdb_test "print M" \
- "No symbol \"M\" in current context\." \
+gdb_test "print MACRO_TO_EXPAND" \
+ "No symbol \"MACRO_TO_EXPAND\" in current context\." \
"print expression with macro after undef."
-gdb_test "macro define M 5" \
+gdb_test "macro define MACRO_TO_EXPAND 5" \
"" \
"basic macro define"
-gdb_test "print M" \
+gdb_test "print MACRO_TO_EXPAND" \
" = 5" \
"expansion of defined macro"
gdb_test "macro list" \
- "macro define M 5" \
+ "macro define MACRO_TO_EXPAND 5" \
"basic macro list"
-gdb_test "macro define M(x) x" \
+gdb_test "macro define MACRO_TO_EXPAND(x) x" \
"" \
"basic redefine, macro with args"
-gdb_test "print M (7)" \
+gdb_test "print MACRO_TO_EXPAND (7)" \
" = 7" \
"expansion of macro with arguments"
-gdb_test "macro undef M" \
+gdb_test "macro undef MACRO_TO_EXPAND" \
"" \
"basic macro undef"
-gdb_test "print M" \
- "No symbol \"M\" in current context\." \
+gdb_test "print MACRO_TO_EXPAND" \
+ "No symbol \"MACRO_TO_EXPAND\" in current context\." \
"print expression with macro after user undef."
+
+# Regression test; this used to crash.
+gdb_test "macro define" \
+ "usage: macro define.*" \
+ "macro define with no arguments"
+
+# Regression test; this used to crash.
+gdb_test "macro undef" \
+ "usage: macro undef.*" \
+ "macro undef with no arguments"
+
+# Completion tests.
+
+# The macro FIFTY_SEVEN is in scope at this point.
+send_gdb "p FIFTY_\t"
+gdb_expect {
+ -re "^p FIFTY_SEVEN $"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "^.* = 57.*$gdb_prompt $"\
+ { pass "complete 'p FIFTY_SEVEN'"}
+ -re ".*$gdb_prompt $" { fail "complete 'p FIFTY_SEVEN'"}
+ timeout {fail "(timeout) complete 'p FIFTY_SEVEN'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'p FIFTY_SEVEN'" }
+ timeout { fail "(timeout) complete 'p FIFTY_SEVEN' 2" }
+ }
+
+# The macro TWENTY_THREE is not in scope.
+send_gdb "p TWENTY_\t"
+gdb_expect {
+ -re "^p TWENTY_\\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "No symbol \"TWENTY_\" in current context\\..*$gdb_prompt $"\
+ { pass "complete 'p TWENTY_'"}
+ -re ".*$gdb_prompt $" { fail "complete 'p TWENTY_'"}
+ timeout {fail "(timeout) complete 'p TWENTY_'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'p TWENTY_'" }
+ timeout { fail "(timeout) complete 'p TWENTY_' 2" }
+ }
+
+# The macro FORTY_EIGHT was undefined and thus is not in scope.
+send_gdb "p FORTY_\t"
+gdb_expect {
+ -re "^p FORTY_\\\x07$"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "No symbol \"FORTY_\" in current context\\..*$gdb_prompt $"\
+ { pass "complete 'p FORTY_'"}
+ -re ".*$gdb_prompt $" { fail "complete 'p FORTY_'"}
+ timeout {fail "(timeout) complete 'p FORTY_'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'p FORTY_'" }
+ timeout { fail "(timeout) complete 'p FORTY_' 2" }
+ }
+
+gdb_test "macro define TWENTY_THREE 25" \
+ "" \
+ "defining TWENTY_THREE"
+
+# User-defined macros are always in scope.
+send_gdb "p TWENTY_\t"
+gdb_expect {
+ -re "^p TWENTY_THREE $"\
+ { send_gdb "\n"
+ gdb_expect {
+ -re "^.* = 25.*$gdb_prompt $"\
+ { pass "complete 'p TWENTY_THREE'"}
+ -re ".*$gdb_prompt $" { fail "complete 'p TWENTY_THREE'"}
+ timeout {fail "(timeout) complete 'p TWENTY_THREE'"}
+ }
+ }
+ -re ".*$gdb_prompt $" { fail "complete 'p TWENTY_THREE'" }
+ timeout { fail "(timeout) complete 'p TWENTY_THREE' 2" }
+ }
+
+# Splicing tests.
+
+gdb_test "macro expand SPLICE(x, y)" \
+ "expands to: xy" \
+ "basic macro splicing"
+
+gdb_test "macro define robotinvasion 2010" \
+ "" \
+ "define splice helper"
+
+gdb_test "macro expand SPLICE(robot, invasion)" \
+ "expands to: *2010" \
+ "splicing plus expansion"
+
+# Varargs tests.
+
+gdb_test "macro define va_c99(...) varfunc (fixedarg, __VA_ARGS__)" \
+ "" \
+ "define first varargs helper"
+
+gdb_test "macro define va2_c99(x, y, ...) varfunc (fixedarg, x, y, __VA_ARGS__)" \
+ "" \
+ "define second varargs helper"
+
+gdb_test "macro define va_gnu(args...) varfunc (fixedarg, args)" \
+ "" \
+ "define third varargs helper"
+
+gdb_test "macro define va2_gnu(args...) varfunc (fixedarg, ## args)" \
+ "" \
+ "define fourth varargs helper"
+
+gdb_test "macro expand va_c99(one, two, three)" \
+ "expands to: *varfunc \\(fixedarg, *one, two, three\\)" \
+ "c99 varargs expansion"
+
+gdb_test "macro expand va_c99()" \
+ "expands to: *varfunc \\(fixedarg, *\\)" \
+ "c99 varargs expansion without an argument"
+
+gdb_test "macro expand va2_c99(one, two, three, four)" \
+ "expands to: *varfunc \\(fixedarg, *one, two, three, four\\)" \
+ "c99 varargs expansion, multiple formal arguments"
+
+gdb_test "macro expand va_gnu(one, two, three, four)" \
+ "expands to: *varfunc \\(fixedarg, *one, two, three, four\\)" \
+ "gnu varargs expansion"
+
+gdb_test "macro expand va_gnu()" \
+ "expands to: *varfunc \\(fixedarg, *\\)" \
+ "gnu varargs expansion without an argument"
+
+gdb_test "macro expand va2_gnu()" \
+ "expands to: *varfunc \\(fixedarg\\)" \
+ "gnu varargs expansion special splicing without an argument"
+
+# Stringification tests.
+
+gdb_test "macro define str(x) #x" \
+ "" \
+ "define stringification macro"
+
+gdb_test "macro define maude 5" \
+ "" \
+ "define first stringification helper"
+
+gdb_test "macro define xstr(x) str(x)" \
+ "" \
+ "define second stringification helper"
+
+gdb_test "print str(5)" \
+ " = \"5\"" \
+ "simple stringify"
+
+gdb_test "print str(hi bob)" \
+ " = \"hi bob\"" \
+ "stringify with one space"
+
+gdb_test "print str( hi bob )" \
+ " = \"hi bob\"" \
+ "stringify with many spaces"
+
+gdb_test "print str(hi \"bob\")" \
+ " = \"hi \\\\\"bob\\\\\"\"" \
+ "stringify with quotes"
+
+gdb_test "print str(hi \\bob\\)" \
+ " = \"hi \\\\\\\\bob\\\\\\\\\"" \
+ "stringify with backslashes"
+
+gdb_test "print str(maude)" \
+ " = \"maude\"" \
+ "stringify without substitution"
+
+gdb_test "print xstr(maude)" \
+ " = \"5\"" \
+ "stringify with substitution"
+
+# Regression test for pp-number bug.
+gdb_test "macro define si_addr fields.fault.si_addr" \
+ "" \
+ "define si_addr macro"
+gdb_test "macro expand siginfo.si_addr" \
+ "expands to: siginfo.fields.fault.si_addr" \
+ "macro expand siginfo.si_addr"