| 1 | # Copyright 2011-2021 Free Software Foundation, Inc. |
| 2 | # |
| 3 | # Contributed by Red Hat, originally written by Keith Seitz. |
| 4 | # |
| 5 | # This program is free software; you can redistribute it and/or modify |
| 6 | # it under the terms of the GNU General Public License as published by |
| 7 | # the Free Software Foundation; either version 3 of the License, or |
| 8 | # (at your option) any later version. |
| 9 | # |
| 10 | # This program is distributed in the hope that it will be useful, |
| 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | # GNU General Public License for more details. |
| 14 | # |
| 15 | # You should have received a copy of the GNU General Public License |
| 16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 | |
| 18 | # This file is part of the gdb testsuite. |
| 19 | |
| 20 | proc add {var name params expected {kind {func}}} { |
| 21 | upvar $var result |
| 22 | |
| 23 | if {[string compare $kind "template"] == 0} { |
| 24 | set method_name "${name}<$expected>" |
| 25 | } else { |
| 26 | set method_name "$name" |
| 27 | } |
| 28 | |
| 29 | set expect ".*// ${method_name}\\($expected\\)" |
| 30 | lappend result [list "${method_name}($params)" $expect] |
| 31 | } |
| 32 | |
| 33 | if {[skip_cplus_tests]} { continue } |
| 34 | |
| 35 | # Tests for c++/12266 et al |
| 36 | standard_testfile .cc |
| 37 | |
| 38 | if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ |
| 39 | {c++ debug additional_flags=-std=c++11}]} { |
| 40 | return -1 |
| 41 | } |
| 42 | |
| 43 | if {![runto_main]} { |
| 44 | perror "couldn't run to breakpoint" |
| 45 | continue |
| 46 | } |
| 47 | |
| 48 | array set typedefs { |
| 49 | "my_other_type" {"my_other_type" "my_type" "const char* const*"} |
| 50 | "my_other_type_2" {"my_other_type_2" "my_type_2" "int"} |
| 51 | "CORE_ADDR" { "CORE_ADDR" "unsigned long" } |
| 52 | "_BAR_" { "_BAR_" "a::b::BAR" "a::b::c::d::bar" } |
| 53 | "aenum" { "aenum" "anon_enum" } |
| 54 | "astruct" { "astruct" "anon_struct" } |
| 55 | "aunion" { "aunion" "anon_union" } |
| 56 | } |
| 57 | |
| 58 | set methods {} |
| 59 | |
| 60 | # Add the simple, one-parameter methods |
| 61 | foreach meth {A::FOO::test A::FOO::foo} { |
| 62 | foreach type {my_other_type my_other_type_2} { |
| 63 | foreach t $typedefs($type) { |
| 64 | add methods $meth $t $type |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | # Add two-parameter methods |
| 70 | foreach meth {A::FOO::test A::FOO::foo} { |
| 71 | set type "my_other_type_2, const my_other_type" |
| 72 | foreach t1 $typedefs(my_other_type_2) { |
| 73 | foreach t2 $typedefs(my_other_type) { |
| 74 | add methods $meth "$t1, const $t2" $type |
| 75 | add methods $meth "$t1, $t2" $type |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | # Add three-parameter methods/functions |
| 81 | foreach meth {A::FOO::test A::FOO::foo B::test test} { |
| 82 | set type "aenum, astruct const&, aunion const\\*\\*\\*" |
| 83 | foreach t1 $typedefs(aenum) { |
| 84 | foreach t2 $typedefs(astruct) { |
| 85 | foreach t3 $typedefs(aunion) { |
| 86 | add methods $meth "$t1, $t2 const&, $t3 const***" $type |
| 87 | } |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | # Add the array-of-function pointer methods |
| 93 | set type "fptr1\\*" |
| 94 | foreach meth {A::FOO::test A::FOO::foo} { |
| 95 | add methods $meth "fptr1*" $type |
| 96 | foreach t $typedefs(my_other_type) { |
| 97 | add methods $meth "void (**) ($t)" $type |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | # Add the function pointer methods |
| 102 | set type "fptr3" |
| 103 | foreach meth {A::FOO::test A::FOO::foo} { |
| 104 | add methods $meth "fptr3" $type |
| 105 | |
| 106 | foreach t1 $typedefs(my_other_type) { |
| 107 | add methods $meth "void (*)(fptr2, $t1)" $type |
| 108 | foreach t2 $typedefs(my_other_type_2) { |
| 109 | add methods $meth "void (*)(void (*)(fptr1, $t2), $t1)" $type |
| 110 | foreach t3 $typedefs(my_other_type) { |
| 111 | add methods $meth \ |
| 112 | "void (*)(void (*)(void (*) ($t3), $t2), $t1)" $type |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | set type1 "my_other_type" |
| 119 | set type2 "my_other_type, my_other_type_2" |
| 120 | foreach meth {"test" "B::test"} { |
| 121 | foreach t1 $typedefs(my_other_type) { |
| 122 | add methods $meth $t1 $type1 |
| 123 | foreach t2 $typedefs(my_other_type_2) { |
| 124 | add methods $meth "$t1, $t2" $type2 template |
| 125 | } |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | # Miscellaneous tests |
| 130 | set type {CORE_ADDR \(\*\) \[10\]} |
| 131 | foreach meth {A::FOO::foo A::FOO::test} { |
| 132 | foreach t $typedefs(CORE_ADDR) { |
| 133 | add methods $meth "$t (*) \[10\]" $type |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | foreach t $typedefs(_BAR_) { |
| 138 | add methods "test" "$t&" {_BAR_&} |
| 139 | } |
| 140 | |
| 141 | # Tests for c++/24367 |
| 142 | foreach t {int incomplete_struct another_incomplete_struct} { |
| 143 | add methods "test_incomplete" "${t}*" [string_to_regexp "${t}*"] |
| 144 | } |
| 145 | |
| 146 | gdb_test_no_output "set listsize 1" "" |
| 147 | |
| 148 | # Finally, for each method in the list METHODS, check whether |
| 149 | # the user can "list" it and "break" on it (both quoted and unquoted). |
| 150 | foreach test $methods { |
| 151 | set func [lindex $test 0] |
| 152 | set result [lindex $test 1] |
| 153 | |
| 154 | gdb_test "list -qualified $func" $result |
| 155 | gdb_test "list -qualified '$func'" $result |
| 156 | if {[gdb_breakpoint "-qualified $func"]} { |
| 157 | pass "break -qualified $func" |
| 158 | } |
| 159 | if {[gdb_breakpoint "-qualified '$func'"]} { |
| 160 | pass "break -qualified '$func'" |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | # The tests above use -qualified to explicitly pick the one "test" |
| 165 | # symbol each test cares about. Now check that both "break test(..)" |
| 166 | # and "list test(..)" without -qualified find "test(..)" in all the 3 |
| 167 | # scopes that have the this particular overload. |
| 168 | set func "test(aenum, astruct const&, aunion const***)" |
| 169 | set func_re "test\\(anon_enum, anon_struct const&, anon_union const\\*\\*\\*\\)" |
| 170 | set line1 [gdb_get_line_number " A::FOO::$func"] |
| 171 | set line2 [gdb_get_line_number " B::$func"] |
| 172 | set line3 [gdb_get_line_number " $func"] |
| 173 | |
| 174 | foreach f [list "$func" "'$func'"] { |
| 175 | set any "\[^\r\n\]*" |
| 176 | gdb_test \ |
| 177 | "list $f" \ |
| 178 | [multi_line \ |
| 179 | "file: \".*$srcfile\", line number: $line1, symbol: \"A::foo::$func_re\"" \ |
| 180 | "$line1${any}A::FOO::test${any}" \ |
| 181 | "file: \".*$srcfile\", line number: $line2, symbol: \"B::$func_re\"" \ |
| 182 | "$line2${any}B::test${any}" \ |
| 183 | "file: \".*$srcfile\", line number: $line3, symbol: \"$func_re\"" \ |
| 184 | "$line3${any}// test${any}"] |
| 185 | |
| 186 | delete_breakpoints |
| 187 | gdb_test "break $f" "\\(3 locations\\)" |
| 188 | } |
| 189 | |
| 190 | gdb_exit |
| 191 | return 0 |