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