File: | src/gnu/usr.bin/binutils/gdb/block.c |
Warning: | line 90, column 3 Value stored to 'b' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 (const struct block *a, const struct block *b) |
48 | { |
49 | if (!a || !b) |
50 | return 0; |
51 | return BLOCK_START (a)(a)->startaddr >= BLOCK_START (b)(b)->startaddr |
52 | && BLOCK_END (a)(a)->endaddr <= BLOCK_END (b)(b)->endaddr; |
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 (const struct block *bl) |
61 | { |
62 | while (BLOCK_FUNCTION (bl)(bl)->function == 0 && BLOCK_SUPERBLOCK (bl)(bl)->superblock != 0) |
63 | bl = BLOCK_SUPERBLOCK (bl)(bl)->superblock; |
64 | |
65 | return BLOCK_FUNCTION (bl)(bl)->function; |
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 (CORE_ADDR pc, struct bfd_section *section, |
75 | int *pindex, struct symtab *symtab) |
76 | { |
77 | struct block *b; |
78 | 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 | symtab = find_pc_sect_symtab (pc, section); |
85 | if (symtab == 0) |
86 | return 0; |
87 | } |
88 | |
89 | bl = BLOCKVECTOR (symtab)(symtab)->blockvector; |
90 | b = BLOCKVECTOR_BLOCK (bl, 0)(bl)->block[0]; |
Value stored to 'b' is never read | |
91 | |
92 | /* Then search that symtab for the smallest block that wins. */ |
93 | /* Use binary search to find the last block that starts before PC. */ |
94 | |
95 | bot = 0; |
96 | top = BLOCKVECTOR_NBLOCKS (bl)(bl)->nblocks; |
97 | |
98 | while (top - bot > 1) |
99 | { |
100 | half = (top - bot + 1) >> 1; |
101 | b = BLOCKVECTOR_BLOCK (bl, bot + half)(bl)->block[bot + half]; |
102 | if (BLOCK_START (b)(b)->startaddr <= pc) |
103 | bot += half; |
104 | else |
105 | top = bot + half; |
106 | } |
107 | |
108 | /* Now search backward for a block that ends after PC. */ |
109 | |
110 | while (bot >= 0) |
111 | { |
112 | b = BLOCKVECTOR_BLOCK (bl, bot)(bl)->block[bot]; |
113 | if (BLOCK_END (b)(b)->endaddr > pc) |
114 | { |
115 | if (pindex) |
116 | *pindex = bot; |
117 | return bl; |
118 | } |
119 | bot--; |
120 | } |
121 | return 0; |
122 | } |
123 | |
124 | /* Return the blockvector immediately containing the innermost lexical block |
125 | containing the specified pc value, or 0 if there is none. |
126 | Backward compatibility, no section. */ |
127 | |
128 | struct blockvector * |
129 | blockvector_for_pc (CORE_ADDR pc, int *pindex) |
130 | { |
131 | return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc), |
132 | pindex, NULL((void*)0)); |
133 | } |
134 | |
135 | /* Return the innermost lexical block containing the specified pc value |
136 | in the specified section, or 0 if there is none. */ |
137 | |
138 | struct block * |
139 | block_for_pc_sect (CORE_ADDR pc, struct bfd_section *section) |
140 | { |
141 | struct blockvector *bl; |
142 | int index; |
143 | |
144 | bl = blockvector_for_pc_sect (pc, section, &index, NULL((void*)0)); |
145 | if (bl) |
146 | return BLOCKVECTOR_BLOCK (bl, index)(bl)->block[index]; |
147 | return 0; |
148 | } |
149 | |
150 | /* Return the innermost lexical block containing the specified pc value, |
151 | or 0 if there is none. Backward compatibility, no section. */ |
152 | |
153 | struct block * |
154 | block_for_pc (CORE_ADDR pc) |
155 | { |
156 | return block_for_pc_sect (pc, find_pc_mapped_section (pc)); |
157 | } |
158 | |
159 | /* Now come some functions designed to deal with C++ namespace issues. |
160 | The accessors are safe to use even in the non-C++ case. */ |
161 | |
162 | /* This returns the namespace that BLOCK is enclosed in, or "" if it |
163 | isn't enclosed in a namespace at all. This travels the chain of |
164 | superblocks looking for a scope, if necessary. */ |
165 | |
166 | const char * |
167 | block_scope (const struct block *block) |
168 | { |
169 | for (; block != NULL((void*)0); block = BLOCK_SUPERBLOCK (block)(block)->superblock) |
170 | { |
171 | if (BLOCK_NAMESPACE (block)(block)->language_specific.cplus_specific.namespace != NULL((void*)0) |
172 | && BLOCK_NAMESPACE (block)(block)->language_specific.cplus_specific.namespace->scope != NULL((void*)0)) |
173 | return BLOCK_NAMESPACE (block)(block)->language_specific.cplus_specific.namespace->scope; |
174 | } |
175 | |
176 | return ""; |
177 | } |
178 | |
179 | /* Set BLOCK's scope member to SCOPE; if needed, allocate memory via |
180 | OBSTACK. (It won't make a copy of SCOPE, however, so that already |
181 | has to be allocated correctly.) */ |
182 | |
183 | void |
184 | block_set_scope (struct block *block, const char *scope, |
185 | struct obstack *obstack) |
186 | { |
187 | block_initialize_namespace (block, obstack); |
188 | |
189 | BLOCK_NAMESPACE (block)(block)->language_specific.cplus_specific.namespace->scope = scope; |
190 | } |
191 | |
192 | /* This returns the first using directives associated to BLOCK, if |
193 | any. */ |
194 | |
195 | /* FIXME: carlton/2003-04-23: This uses the fact that we currently |
196 | only have using directives in static blocks, because we only |
197 | generate using directives from anonymous namespaces. Eventually, |
198 | when we support using directives everywhere, we'll want to replace |
199 | this by some iterator functions. */ |
200 | |
201 | struct using_direct * |
202 | block_using (const struct block *block) |
203 | { |
204 | const struct block *static_block = block_static_block (block); |
205 | |
206 | if (static_block == NULL((void*)0) |
207 | || BLOCK_NAMESPACE (static_block)(static_block)->language_specific.cplus_specific.namespace == NULL((void*)0)) |
208 | return NULL((void*)0); |
209 | else |
210 | return BLOCK_NAMESPACE (static_block)(static_block)->language_specific.cplus_specific.namespace->using; |
211 | } |
212 | |
213 | /* Set BLOCK's using member to USING; if needed, allocate memory via |
214 | OBSTACK. (It won't make a copy of USING, however, so that already |
215 | has to be allocated correctly.) */ |
216 | |
217 | void |
218 | block_set_using (struct block *block, |
219 | struct using_direct *using, |
220 | struct obstack *obstack) |
221 | { |
222 | block_initialize_namespace (block, obstack); |
223 | |
224 | BLOCK_NAMESPACE (block)(block)->language_specific.cplus_specific.namespace->using = using; |
225 | } |
226 | |
227 | /* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and |
228 | ititialize its members to zero. */ |
229 | |
230 | static void |
231 | block_initialize_namespace (struct block *block, struct obstack *obstack) |
232 | { |
233 | if (BLOCK_NAMESPACE (block)(block)->language_specific.cplus_specific.namespace == NULL((void*)0)) |
234 | { |
235 | BLOCK_NAMESPACE (block)(block)->language_specific.cplus_specific.namespace |
236 | = obstack_alloc (obstack, sizeof (struct block_namespace_info))__extension__ ({ struct obstack *__h = (obstack); __extension__ ({ struct obstack *__o = (__h); int __len = ((sizeof (struct block_namespace_info))); if (__o->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len)); (void) 0; }); __extension__ ({ struct obstack * __o1 = (__h); void *value; value = (void *) __o1->object_base ; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char * ) 0)+__o1->alignment_mask) & ~ (__o1->alignment_mask )) + (char *) 0); if (__o1->next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1-> next_free = __o1->chunk_limit; __o1->object_base = __o1 ->next_free; value; }); }); |
237 | BLOCK_NAMESPACE (block)(block)->language_specific.cplus_specific.namespace->scope = NULL((void*)0); |
238 | BLOCK_NAMESPACE (block)(block)->language_specific.cplus_specific.namespace->using = NULL((void*)0); |
239 | } |
240 | } |
241 | |
242 | /* Return the static block associated to BLOCK. Return NULL if block |
243 | is NULL or if block is a global block. */ |
244 | |
245 | const struct block * |
246 | block_static_block (const struct block *block) |
247 | { |
248 | if (block == NULL((void*)0) || BLOCK_SUPERBLOCK (block)(block)->superblock == NULL((void*)0)) |
249 | return NULL((void*)0); |
250 | |
251 | while (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block))((block)->superblock)->superblock != NULL((void*)0)) |
252 | block = BLOCK_SUPERBLOCK (block)(block)->superblock; |
253 | |
254 | return block; |
255 | } |
256 | |
257 | /* Return the static block associated to BLOCK. Return NULL if block |
258 | is NULL. */ |
259 | |
260 | const struct block * |
261 | block_global_block (const struct block *block) |
262 | { |
263 | if (block == NULL((void*)0)) |
264 | return NULL((void*)0); |
265 | |
266 | while (BLOCK_SUPERBLOCK (block)(block)->superblock != NULL((void*)0)) |
267 | block = BLOCK_SUPERBLOCK (block)(block)->superblock; |
268 | |
269 | return block; |
270 | } |
271 | |
272 | /* Allocate a block on OBSTACK, and initialize its elements to |
273 | zero/NULL. This is useful for creating "dummy" blocks that don't |
274 | correspond to actual source files. |
275 | |
276 | Warning: it sets the block's BLOCK_DICT to NULL, which isn't a |
277 | valid value. If you really don't want the block to have a |
278 | dictionary, then you should subsequently set its BLOCK_DICT to |
279 | dict_create_linear (obstack, NULL). */ |
280 | |
281 | struct block * |
282 | allocate_block (struct obstack *obstack) |
283 | { |
284 | struct block *bl = obstack_alloc (obstack, sizeof (struct block))__extension__ ({ struct obstack *__h = (obstack); __extension__ ({ struct obstack *__o = (__h); int __len = ((sizeof (struct block))); if (__o->chunk_limit - __o->next_free < __len ) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len )); (void) 0; }); __extension__ ({ struct obstack *__o1 = (__h ); void *value; value = (void *) __o1->object_base; if (__o1 ->next_free == value) __o1->maybe_empty_object = 1; __o1 ->next_free = (((((__o1->next_free) - (char *) 0)+__o1-> alignment_mask) & ~ (__o1->alignment_mask)) + (char *) 0); if (__o1->next_free - (char *)__o1->chunk > __o1 ->chunk_limit - (char *)__o1->chunk) __o1->next_free = __o1->chunk_limit; __o1->object_base = __o1->next_free ; value; }); }); |
285 | |
286 | BLOCK_START (bl)(bl)->startaddr = 0; |
287 | BLOCK_END (bl)(bl)->endaddr = 0; |
288 | BLOCK_FUNCTION (bl)(bl)->function = NULL((void*)0); |
289 | BLOCK_SUPERBLOCK (bl)(bl)->superblock = NULL((void*)0); |
290 | BLOCK_DICT (bl)(bl)->dict = NULL((void*)0); |
291 | BLOCK_NAMESPACE (bl)(bl)->language_specific.cplus_specific.namespace = NULL((void*)0); |
292 | BLOCK_GCC_COMPILED (bl)(bl)->gcc_compile_flag = 0; |
293 | |
294 | return bl; |
295 | } |