2003-04-15 David Carlton <carlton@math.stanford.edu>
[external/binutils.git] / gdb / block.c
1 /* Block-related functions for the GNU debugger, GDB.
2
3    Copyright 2003 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include "defs.h"
23 #include "block.h"
24 #include "symtab.h"
25 #include "symfile.h"
26 #include "gdb_obstack.h"
27 #include "cp-support.h"
28
29 /* This is used by struct block to store namespace-related info for
30    C++ files, namely using declarations and the current namespace in
31    scope.  */
32
33 struct block_namespace_info
34 {
35   const char *scope;
36   struct using_direct *using;
37 };
38
39 static void block_initialize_namespace (struct block *block,
40                                         struct obstack *obstack);
41
42 /* Return Nonzero if block a is lexically nested within block b,
43    or if a and b have the same pc range.
44    Return zero otherwise. */
45
46 int
47 contained_in (struct block *a, struct block *b)
48 {
49   if (!a || !b)
50     return 0;
51   return BLOCK_START (a) >= BLOCK_START (b)
52     && BLOCK_END (a) <= BLOCK_END (b);
53 }
54
55
56 /* Return the symbol for the function which contains a specified
57    lexical block, described by a struct block BL.  */
58
59 struct symbol *
60 block_function (struct block *bl)
61 {
62   while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0)
63     bl = BLOCK_SUPERBLOCK (bl);
64
65   return BLOCK_FUNCTION (bl);
66 }
67
68 /* Return the blockvector immediately containing the innermost lexical block
69    containing the specified pc value and section, or 0 if there is none.
70    PINDEX is a pointer to the index value of the block.  If PINDEX
71    is NULL, we don't pass this information back to the caller.  */
72
73 struct blockvector *
74 blockvector_for_pc_sect (register CORE_ADDR pc, struct sec *section,
75                          int *pindex, struct symtab *symtab)
76 {
77   register struct block *b;
78   register int bot, top, half;
79   struct blockvector *bl;
80
81   if (symtab == 0)              /* if no symtab specified by caller */
82     {
83       /* First search all symtabs for one whose file contains our pc */
84       if ((symtab = find_pc_sect_symtab (pc, section)) == 0)
85         return 0;
86     }
87
88   bl = BLOCKVECTOR (symtab);
89   b = BLOCKVECTOR_BLOCK (bl, 0);
90
91   /* Then search that symtab for the smallest block that wins.  */
92   /* Use binary search to find the last block that starts before PC.  */
93
94   bot = 0;
95   top = BLOCKVECTOR_NBLOCKS (bl);
96
97   while (top - bot > 1)
98     {
99       half = (top - bot + 1) >> 1;
100       b = BLOCKVECTOR_BLOCK (bl, bot + half);
101       if (BLOCK_START (b) <= pc)
102         bot += half;
103       else
104         top = bot + half;
105     }
106
107   /* Now search backward for a block that ends after PC.  */
108
109   while (bot >= 0)
110     {
111       b = BLOCKVECTOR_BLOCK (bl, bot);
112       if (BLOCK_END (b) > pc)
113         {
114           if (pindex)
115             *pindex = bot;
116           return bl;
117         }
118       bot--;
119     }
120   return 0;
121 }
122
123 /* Return the blockvector immediately containing the innermost lexical block
124    containing the specified pc value, or 0 if there is none.
125    Backward compatibility, no section.  */
126
127 struct blockvector *
128 blockvector_for_pc (register CORE_ADDR pc, int *pindex)
129 {
130   return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc),
131                                   pindex, NULL);
132 }
133
134 /* Return the innermost lexical block containing the specified pc value
135    in the specified section, or 0 if there is none.  */
136
137 struct block *
138 block_for_pc_sect (register CORE_ADDR pc, struct sec *section)
139 {
140   register struct blockvector *bl;
141   int index;
142
143   bl = blockvector_for_pc_sect (pc, section, &index, NULL);
144   if (bl)
145     return BLOCKVECTOR_BLOCK (bl, index);
146   return 0;
147 }
148
149 /* Return the innermost lexical block containing the specified pc value,
150    or 0 if there is none.  Backward compatibility, no section.  */
151
152 struct block *
153 block_for_pc (register CORE_ADDR pc)
154 {
155   return block_for_pc_sect (pc, find_pc_mapped_section (pc));
156 }
157
158 /* Now come some functions designed to deal with C++ namespace
159    issues.  */
160
161 /* Set BLOCK's scope member to SCOPE; if needed, allocate memory via
162    OBSTACK.  (It won't make a copy of SCOPE, however, so that already
163    has to be allocated correctly.)  */
164
165 void
166 block_set_scope (struct block *block, const char *scope,
167                  struct obstack *obstack)
168 {
169   block_initialize_namespace (block, obstack);
170
171   BLOCK_NAMESPACE (block)->scope = scope;
172 }
173
174 /* Set BLOCK's using member to USING; if needed, allocate memory via
175    OBSTACK.  (It won't make a copy of USING, however, so that already
176    has to be allocated correctly.)  */
177
178 void
179 block_set_using (struct block *block,
180                  struct using_direct *using,
181                  struct obstack *obstack)
182 {
183   block_initialize_namespace (block, obstack);
184
185   BLOCK_NAMESPACE (block)->using = using;
186 }
187
188 /* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and
189    ititialize its members to zero.  */
190
191 static void
192 block_initialize_namespace (struct block *block, struct obstack *obstack)
193 {
194   if (BLOCK_NAMESPACE (block) == NULL)
195     {
196       BLOCK_NAMESPACE (block)
197         = obstack_alloc (obstack, sizeof (struct block_namespace_info));
198       BLOCK_NAMESPACE (block)->scope = NULL;
199       BLOCK_NAMESPACE (block)->using = NULL;
200     }
201 }