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