1  /* As part of inlining, a BLOCK (described as DW_TAG_lexical_block DIE's) may
       2     be present both as an abstract instance and a concrete one in the DWARF
       3     output.  This testcase attempts to make sure that the concrete ones refer to
       4     the abstract ones thanks to the DW_AT_abstract_origin attribute.
       5  
       6     Such a back-link enables debuggers to make entities present in the abstract
       7     instance only available in concrete ones.  */
       8  
       9  /* { dg-options "-O2 -g -std=gnu99 -gdwarf -dA" } */
      10  /* { dg-final { scan-assembler-times "\\(DIE \\(0x.*\\) DW_TAG_lexical_block\\)\[^)\]*DW_AT_abstract_origin" 1 } } */
      11  
      12  extern void *create (const char *);
      13  extern void destroy (void *);
      14  extern void do_nothing (char);
      15  
      16  struct string
      17  {
      18    const char *data;
      19    int lb;
      20    int ub;
      21  };
      22  
      23  int
      24  main (void)
      25  {
      26    void *o1 = create ("foo");
      27  
      28    void
      29    parent (void)
      30    {
      31      {
      32        void *o2 = create ("bar");
      33  
      34        int
      35        child (struct string s)
      36        {
      37  	int i = s.lb;
      38  
      39  	if (s.lb <= s.ub)
      40  	  while (1)
      41  	    {
      42  	      char c = s.data[i - s.lb];
      43  	      do_nothing (c);
      44  	      if (c == 'o')
      45  		return 1;
      46  	      if (i == s.ub)
      47  		break;
      48  	      ++i;
      49  	    }
      50  	return 0;
      51        }
      52  
      53        int r;
      54  
      55        r = child ((struct string) {"baz", 1, 3});
      56        r = child ((struct string) {"qux", 2, 4});
      57        r = child ((struct string) {"foobar", 1, 6});
      58      }
      59  
      60      do_nothing (0);
      61    }
      62  
      63    parent ();
      64    return 0;
      65  }