Home | History | Annotate | Line # | Download | only in gdb.cp
nsalias.exp revision 1.1.1.8
      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 
     19 load_lib dwarf.exp
     20 
     21 require dwarf2_support allow_cplus_tests
     22 
     23 standard_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 
     56 set asm_file [standard_output_file $srcfile2]
     57 Dwarf::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 
    169 if {[gdb_compile $srcdir/$subdir/$srcfile ${binfile}1.o \
    170 	 object {c++ debug}] != ""} {
    171     return -1
    172 }
    173 
    174 if {[gdb_compile $asm_file ${binfile}2.o object {nodebug}] != ""} {
    175     return -1
    176 }
    177 
    178 if {[gdb_compile [list ${binfile}1.o ${binfile}2.o] \
    179 	 $binfile executable {c++}] != ""} {
    180     return -1
    181 }
    182 
    183 clean_restart $testfile
    184 
    185 # A procedure to run various tests on aliased namespaces.
    186 proc 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 
    223 set permutations {}
    224 lappend permutations "outer"
    225 lappend permutations "Outer"
    226 lappend permutations "outer::inner"
    227 lappend permutations "Outer::inner"
    228 lappend permutations "outer::Inner"
    229 lappend permutations "Outer::Inner"
    230 lappend permutations "outer::inner::innermost"
    231 lappend permutations "outer::inner::Innermost"
    232 lappend permutations "outer::Inner::innermost"
    233 lappend permutations "outer::Inner::Innermost"
    234 lappend permutations "Outer::inner::innermost"
    235 lappend permutations "Outer::inner::Innermost"
    236 lappend permutations "Outer::Inner::innermost"
    237 lappend permutations "Outer::Inner::Innermost"
    238 
    239 foreach p $permutations {
    240     do_alias_tests $p
    241 }
    242 
    243 # Test recursively imported aliases.
    244 foreach 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 
    252 set 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 
    272 for {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 
    281 standard_testfile .cc nsalias-r-dw.S
    282 
    283 set asm_file [standard_output_file $srcfile2]
    284 set 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 
    300 Dwarf::assemble $asm_file $the_dwarf
    301 
    302 if {[gdb_compile $asm_file ${binfile}3.o object {nodebug}] != ""} {
    303     return -1
    304 }
    305 
    306 if {[gdb_compile [list ${binfile}1.o ${binfile}3.o] \
    307 	 ${binfile}-r executable {c++}] != ""} {
    308     return -1
    309 }
    310 
    311 clean_restart
    312 
    313 # Set complaints before loading the file.  Otherwise the complaint won't
    314 # trigger for -readnow.
    315 gdb_test_no_output "set complaints 1"
    316 
    317 gdb_load [standard_output_file ${testfile}-r]
    318 
    319 set readnow_p [readnow]
    320 
    321 set test "complaint for too many recursively imported declarations"
    322 set re ".* has too many recursively imported declarations.*"
    323 if { $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