323 lines
7.1 KiB
Plaintext
323 lines
7.1 KiB
Plaintext
# Copyright 2013-2018 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
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# Test namespace aliases.
|
|
# PRs c++/7935, c++/10541
|
|
|
|
load_lib dwarf.exp
|
|
|
|
if {![dwarf2_support]} {
|
|
return 0
|
|
}
|
|
|
|
if {[skip_cplus_tests]} {
|
|
continue
|
|
}
|
|
|
|
standard_testfile .cc nsalias-dw.S
|
|
|
|
# Make the DWARF used for the test. This is necessary to work
|
|
# around compiler issues. Not all versions of gcc output the
|
|
# correct debuginfo we need.
|
|
#
|
|
# This should create the equivalent DWARF to:
|
|
#
|
|
# namespace outer
|
|
# {
|
|
# namespace inner
|
|
# {
|
|
# namespace innermost
|
|
# {
|
|
# const int x = 2;
|
|
# int foo (void) { return x; }
|
|
# }
|
|
#
|
|
# namespace Innermost = innermost;
|
|
#
|
|
# const int x = 1;
|
|
# int foo (void) { return x + Innermost::foo (); }
|
|
# }
|
|
#
|
|
# namespace Inner = inner;
|
|
#
|
|
# const int x = 0;
|
|
# int foo (void) { return x + Inner::foo (); }
|
|
# }
|
|
#
|
|
# namespace Outer = outer;
|
|
# namespace oi = Outer::Inner;
|
|
|
|
set asm_file [standard_output_file $srcfile2]
|
|
Dwarf::assemble $asm_file {
|
|
cu {} {
|
|
compile_unit {{language @DW_LANG_C_plus_plus}} {
|
|
declare_labels int_label outer_label inner_label innermost_label
|
|
declare_labels im_foo_label i_foo_label o_foo_label
|
|
declare_labels OuterInner_label oi1_label oi2_label
|
|
|
|
int_label: base_type {
|
|
{name int}
|
|
{encoding @DW_ATE_signed}
|
|
{byte_size 4 DW_FORM_sdata}
|
|
}
|
|
|
|
outer_label: DW_TAG_namespace {
|
|
{name outer}
|
|
} {
|
|
inner_label: DW_TAG_namespace {
|
|
{name inner}
|
|
} {
|
|
innermost_label: DW_TAG_namespace {
|
|
{name innermost}
|
|
} {
|
|
DW_TAG_variable {
|
|
{name x}
|
|
{type :$int_label}
|
|
{const_value 2 DW_FORM_data1}
|
|
}
|
|
|
|
im_foo_label: DW_TAG_subprogram {
|
|
{name foo}
|
|
{external 1 flag_present}
|
|
{declaration 1 flag_present}
|
|
}
|
|
}
|
|
|
|
imported_declaration {
|
|
{name Innermost}
|
|
{import :$innermost_label}
|
|
}
|
|
|
|
DW_TAG_variable {
|
|
{name x}
|
|
{type :$int_label}
|
|
{const_value 1 DW_FORM_data1}
|
|
}
|
|
|
|
i_foo_label: subprogram {
|
|
{name foo}
|
|
{external 1 flag_present}
|
|
{declaration 1 flag_present}
|
|
}
|
|
}
|
|
|
|
OuterInner_label: imported_declaration {
|
|
{name Inner}
|
|
{import :$inner_label}
|
|
}
|
|
|
|
DW_TAG_variable {
|
|
{name x}
|
|
{type :$int_label}
|
|
{const_value 0 DW_FORM_data1}
|
|
}
|
|
|
|
o_foo_label: subprogram {
|
|
{name foo}
|
|
{external 1 flag_present}
|
|
{declaration 1 flag_present}
|
|
}
|
|
}
|
|
|
|
imported_declaration {
|
|
{name Outer}
|
|
{import :$outer_label}
|
|
}
|
|
|
|
oi1_label: imported_declaration {
|
|
{name oi1}
|
|
{import :$OuterInner_label}
|
|
}
|
|
|
|
oi2_label: imported_declaration {
|
|
{name oi2}
|
|
{import :$oi1_label}
|
|
}
|
|
|
|
imported_declaration {
|
|
{name oi3}
|
|
{import :$oi2_label}
|
|
}
|
|
|
|
subprogram {
|
|
{specification :$im_foo_label}
|
|
{low_pc 0x4 DW_FORM_addr}
|
|
{high_pc 0x7 DW_FORM_addr}
|
|
}
|
|
|
|
subprogram {
|
|
{specification :$i_foo_label}
|
|
{low_pc 0x8 DW_FORM_addr}
|
|
{high_pc 0xb DW_FORM_addr}
|
|
}
|
|
|
|
subprogram {
|
|
{specification :$o_foo_label}
|
|
{low_pc 0xc DW_FORM_addr}
|
|
{high_pc 0xf DW_FORM_addr}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if {[gdb_compile $srcdir/$subdir/$srcfile ${binfile}1.o \
|
|
object {c++ debug}] != ""} {
|
|
return -1
|
|
}
|
|
|
|
if {[gdb_compile $asm_file ${binfile}2.o object {nodebug}] != ""} {
|
|
return -1
|
|
}
|
|
|
|
if {[gdb_compile [list ${binfile}1.o ${binfile}2.o] \
|
|
$binfile executable {c++}] != ""} {
|
|
return -1
|
|
}
|
|
|
|
clean_restart $testfile
|
|
|
|
# A procedure to run various tests on aliased namespaces.
|
|
proc do_alias_tests {ns {real ""} {x ""}} {
|
|
|
|
# The "real" namespace is simply NS in all lowercase.
|
|
if {$real == ""} {
|
|
set real [string tolower $ns]
|
|
}
|
|
|
|
# The value of `x' is the number of '::' in NS.
|
|
if {$x == ""} {
|
|
set x [expr {[llength [split $ns ":"]] / 2}]
|
|
}
|
|
|
|
# Test "whatis"
|
|
gdb_test "whatis $ns" "type = $real"
|
|
|
|
# Test "ptype"
|
|
gdb_test "ptype $ns" "type = namespace $real"
|
|
|
|
# Print 'x'
|
|
send_log "expecting x = $x\n"
|
|
gdb_test "print ${ns}::x" " = $x"
|
|
|
|
# Attempt to list the function.
|
|
gdb_test_no_output "list ${ns}::foo"
|
|
|
|
# Attempt to break on the start of the function.
|
|
gdb_breakpoint "*${ns}::foo"
|
|
|
|
# And then erase it
|
|
with_test_prefix "($ns)" {
|
|
gdb_test_no_output "delete \$bpnum"
|
|
}
|
|
}
|
|
|
|
# This is a list of all the permutations to be tested. For troubleshooting
|
|
# purposes, this list is explicitly enumerated.
|
|
|
|
set permutations {}
|
|
lappend permutations "outer"
|
|
lappend permutations "Outer"
|
|
lappend permutations "outer::inner"
|
|
lappend permutations "Outer::inner"
|
|
lappend permutations "outer::Inner"
|
|
lappend permutations "Outer::Inner"
|
|
lappend permutations "outer::inner::innermost"
|
|
lappend permutations "outer::inner::Innermost"
|
|
lappend permutations "outer::Inner::innermost"
|
|
lappend permutations "outer::Inner::Innermost"
|
|
lappend permutations "Outer::inner::innermost"
|
|
lappend permutations "Outer::inner::Innermost"
|
|
lappend permutations "Outer::Inner::innermost"
|
|
lappend permutations "Outer::Inner::Innermost"
|
|
|
|
foreach p $permutations {
|
|
do_alias_tests $p
|
|
}
|
|
|
|
# Test recursively imported aliases.
|
|
foreach ns {"oi1" "oi2" "oi3"} {
|
|
do_alias_tests $ns "outer::inner" 1
|
|
do_alias_tests "${ns}::innermost" "outer::inner::innermost" 2
|
|
do_alias_tests "${ns}::Innermost" "outer::inner::innermost" 2
|
|
}
|
|
|
|
# Generate another objfile with nested imported declarations.
|
|
|
|
set imports {
|
|
declare_labels n0_label
|
|
|
|
n0_label: DW_TAG_namespace {
|
|
{name n0}
|
|
} {
|
|
DW_TAG_variable {
|
|
{name x}
|
|
{type :$int_label}
|
|
{const_value 3 DW_FORM_data1}
|
|
}
|
|
}
|
|
|
|
declare_labels n0_import
|
|
n0_import: imported_declaration {
|
|
{name N0}
|
|
{import :$n0_label}
|
|
}
|
|
}
|
|
|
|
for {set i 1} {$i <= 100} {incr i} {
|
|
append imports [format "
|
|
declare_labels n%d_import
|
|
n%d_import: imported_declaration {
|
|
{name N%d}
|
|
{import :\$n%d_import}
|
|
}" $i $i $i [expr {$i - 1}]]
|
|
}
|
|
|
|
standard_testfile .cc nsalias-r-dw.S
|
|
|
|
set asm_file [standard_output_file $srcfile2]
|
|
set the_dwarf [format {
|
|
cu {} {
|
|
compile_unit {{language @DW_LANG_C_plus_plus}} {
|
|
declare_labels int_label n0_label
|
|
|
|
int_label: base_type {
|
|
{name int}
|
|
{encoding @DW_ATE_signed}
|
|
{byte_size 4 DW_FORM_sdata}
|
|
}
|
|
|
|
%s
|
|
}
|
|
}
|
|
} $imports]
|
|
|
|
Dwarf::assemble $asm_file $the_dwarf
|
|
|
|
if {[gdb_compile $asm_file ${binfile}3.o object {nodebug}] != ""} {
|
|
return -1
|
|
}
|
|
|
|
if {[gdb_compile [list ${binfile}1.o ${binfile}3.o] \
|
|
${binfile}-r executable {c++}] != ""} {
|
|
return -1
|
|
}
|
|
|
|
clean_restart ${testfile}-r
|
|
|
|
gdb_test_no_output "set complaints 1"
|
|
gdb_test "print N100::x" \
|
|
".* has too many recursively imported declarations.*" \
|
|
"compaint for too many recursively imported declarations"
|