2003-05-19 David Carlton <carlton@bactrian.org>
[platform/upstream/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 issues.
159    The accessors are safe to use even in the non-C++ case.  */
160
161 /* This returns the namespace that BLOCK is enclosed in, or "" if it
162    isn't enclosed in a namespace at all.  This travels the chain of
163    superblocks looking for a scope, if necessary.  */
164
165 const char *
166 block_scope (const struct block *block)
167 {
168   for (; block != NULL; block = BLOCK_SUPERBLOCK (block))
169     {
170       if (BLOCK_NAMESPACE (block) != NULL
171           && BLOCK_NAMESPACE (block)->scope != NULL)
172         return BLOCK_NAMESPACE (block)->scope;
173     }
174
175   return "";
176 }
177
178 /* Set BLOCK's scope member to SCOPE; if needed, allocate memory via
179    OBSTACK.  (It won't make a copy of SCOPE, however, so that already
180    has to be allocated correctly.)  */
181
182 void
183 block_set_scope (struct block *block, const char *scope,
184                  struct obstack *obstack)
185 {
186   block_initialize_namespace (block, obstack);
187
188   BLOCK_NAMESPACE (block)->scope = scope;
189 }
190
191 /* This returns the first using directives associated to BLOCK, if
192    any.  */
193
194 /* FIXME: carlton/2003-04-23: This uses the fact that we currently
195    only have using directives in static blocks, because we only
196    generate using directives from anonymous namespaces.  Eventually,
197    when we support using directives everywhere, we'll want to replace
198    this by some iterator functions.  */
199
200 struct using_direct *
201 block_using (const struct block *block)
202 {
203   const struct block *static_block = block_static_block (block);
204
205   if (static_block == NULL
206       || BLOCK_NAMESPACE (static_block) == NULL)
207     return NULL;
208   else
209     return BLOCK_NAMESPACE (static_block)->using;
210 }
211
212 /* Set BLOCK's using member to USING; if needed, allocate memory via
213    OBSTACK.  (It won't make a copy of USING, however, so that already
214    has to be allocated correctly.)  */
215
216 void
217 block_set_using (struct block *block,
218                  struct using_direct *using,
219                  struct obstack *obstack)
220 {
221   block_initialize_namespace (block, obstack);
222
223   BLOCK_NAMESPACE (block)->using = using;
224 }
225
226 /* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and
227    ititialize its members to zero.  */
228
229 static void
230 block_initialize_namespace (struct block *block, struct obstack *obstack)
231 {
232   if (BLOCK_NAMESPACE (block) == NULL)
233     {
234       BLOCK_NAMESPACE (block)
235         = obstack_alloc (obstack, sizeof (struct block_namespace_info));
236       BLOCK_NAMESPACE (block)->scope = NULL;
237       BLOCK_NAMESPACE (block)->using = NULL;
238     }
239 }
240
241 /* Return the static block associated to BLOCK.  Return NULL if block
242    is NULL or if block is a global block.  */
243
244 const struct block *
245 block_static_block (const struct block *block)
246 {
247   if (block == NULL || BLOCK_SUPERBLOCK (block) == NULL)
248     return NULL;
249
250   while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) != NULL)
251     block = BLOCK_SUPERBLOCK (block);
252
253   return block;
254 }
255
256 /* Return the static block associated to BLOCK.  Return NULL if block
257    is NULL.  */
258
259 const struct block *
260 block_global_block (const struct block *block)
261 {
262   if (block == NULL)
263     return NULL;
264
265   while (BLOCK_SUPERBLOCK (block) != NULL)
266     block = BLOCK_SUPERBLOCK (block);
267
268   return block;
269 }