Commit | Line | Data |
---|---|---|
9219021c DC |
1 | /* Helper routines for C++ support in GDB. |
2 | Copyright 2003 Free Software Foundation, Inc. | |
3 | ||
4 | Contributed by David Carlton. | |
5 | ||
6 | This file is part of GDB. | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2 of the License, or | |
11 | (at your option) any later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program; if not, write to the Free Software | |
20 | Foundation, Inc., 59 Temple Place - Suite 330, | |
21 | Boston, MA 02111-1307, USA. */ | |
22 | ||
23 | #include "defs.h" | |
24 | #include "cp-support.h" | |
25 | #include "gdb_obstack.h" | |
26 | #include "symtab.h" | |
27 | #include "symfile.h" | |
28 | #include "gdb_assert.h" | |
29 | #include "block.h" | |
30 | ||
31 | /* When set, the file that we're processing seems to have debugging | |
32 | info for C++ namespaces, so cp-namespace.c shouldn't try to guess | |
33 | namespace info itself. */ | |
34 | ||
35 | unsigned char processing_has_namespace_info; | |
36 | ||
37 | /* If processing_has_namespace_info is nonzero, this string should | |
38 | contain the name of the current namespace. The string is | |
39 | temporary; copy it if you need it. */ | |
40 | ||
41 | const char *processing_current_namespace; | |
42 | ||
43 | /* List of using directives that are active in the current file. */ | |
44 | ||
45 | static struct using_direct *using_list; | |
46 | ||
47 | static struct using_direct *cp_add_using (const char *name, | |
48 | unsigned int inner_len, | |
49 | unsigned int outer_len, | |
50 | struct using_direct *next); | |
51 | ||
52 | static struct using_direct *cp_copy_usings (struct using_direct *using, | |
53 | struct obstack *obstack); | |
54 | ||
55 | /* Set up support for dealing with C++ namespace info in the current | |
56 | symtab. */ | |
57 | ||
58 | void cp_initialize_namespace () | |
59 | { | |
60 | processing_has_namespace_info = 0; | |
61 | using_list = NULL; | |
62 | } | |
63 | ||
64 | /* Add all the using directives we've gathered to the current symtab. | |
65 | STATIC_BLOCK should be the symtab's static block; OBSTACK is used | |
66 | for allocation. */ | |
67 | ||
68 | void | |
69 | cp_finalize_namespace (struct block *static_block, | |
70 | struct obstack *obstack) | |
71 | { | |
72 | if (using_list != NULL) | |
73 | { | |
74 | block_set_using (static_block, | |
75 | cp_copy_usings (using_list, obstack), | |
76 | obstack); | |
77 | using_list = NULL; | |
78 | } | |
79 | } | |
80 | ||
81 | /* Check to see if SYMBOL refers to an object contained within an | |
82 | anonymous namespace; if so, add an appropriate using directive. */ | |
83 | ||
84 | /* Optimize away strlen ("(anonymous namespace)"). */ | |
85 | ||
86 | #define ANONYMOUS_NAMESPACE_LEN 21 | |
87 | ||
88 | void | |
89 | cp_scan_for_anonymous_namespaces (const struct symbol *symbol) | |
90 | { | |
91 | if (!processing_has_namespace_info | |
92 | && SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL) | |
93 | { | |
94 | const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol); | |
95 | unsigned int previous_component; | |
96 | unsigned int next_component; | |
97 | const char *len; | |
98 | ||
99 | /* Start with a quick-and-dirty check for mention of "(anonymous | |
100 | namespace)". */ | |
101 | ||
102 | if (!cp_is_anonymous (name)) | |
103 | return; | |
104 | ||
105 | previous_component = 0; | |
106 | next_component = cp_find_first_component (name + previous_component); | |
107 | ||
108 | while (name[next_component] == ':') | |
109 | { | |
110 | if ((next_component - previous_component) == ANONYMOUS_NAMESPACE_LEN | |
111 | && strncmp (name + previous_component, | |
112 | "(anonymous namespace)", | |
113 | ANONYMOUS_NAMESPACE_LEN) == 0) | |
114 | { | |
115 | /* We've found a component of the name that's an | |
116 | anonymous namespace. So add symbols in it to the | |
117 | namespace given by the previous component if there is | |
118 | one, or to the global namespace if there isn't. */ | |
119 | cp_add_using_directive (name, | |
120 | previous_component == 0 | |
121 | ? 0 : previous_component - 2, | |
122 | next_component); | |
123 | } | |
124 | /* The "+ 2" is for the "::". */ | |
125 | previous_component = next_component + 2; | |
126 | next_component = (previous_component | |
127 | + cp_find_first_component (name | |
128 | + previous_component)); | |
129 | } | |
130 | } | |
131 | } | |
132 | ||
133 | /* Add a using directive to using_list. NAME is the start of a string | |
134 | that should contain the namespaces we want to add as initial | |
135 | substrings, OUTER_LENGTH is the end of the outer namespace, and | |
136 | INNER_LENGTH is the end of the inner namespace. If the using | |
137 | directive in question has already been added, don't add it | |
138 | twice. */ | |
139 | ||
140 | void | |
141 | cp_add_using_directive (const char *name, unsigned int outer_length, | |
142 | unsigned int inner_length) | |
143 | { | |
144 | struct using_direct *current; | |
145 | struct using_direct *new; | |
146 | ||
147 | /* Has it already been added? */ | |
148 | ||
149 | for (current = using_list; current != NULL; current = current->next) | |
150 | { | |
151 | if ((strncmp (current->inner, name, inner_length) == 0) | |
152 | && (strlen (current->inner) == inner_length) | |
153 | && (strlen (current->outer) == outer_length)) | |
154 | return; | |
155 | } | |
156 | ||
157 | using_list = cp_add_using (name, inner_length, outer_length, | |
158 | using_list); | |
159 | } | |
160 | ||
161 | /* Record the namespace that the function defined by SYMBOL was | |
162 | defined in, if necessary. BLOCK is the associated block; use | |
163 | OBSTACK for allocation. */ | |
164 | ||
165 | void | |
166 | cp_set_block_scope (const struct symbol *symbol, | |
167 | struct block *block, | |
168 | struct obstack *obstack) | |
169 | { | |
170 | /* Make sure that the name was originally mangled: if not, there | |
171 | certainly isn't any namespace information to worry about! */ | |
172 | ||
173 | if (SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL) | |
174 | { | |
175 | if (processing_has_namespace_info) | |
176 | { | |
177 | block_set_scope | |
178 | (block, obsavestring (processing_current_namespace, | |
179 | strlen (processing_current_namespace), | |
180 | obstack), | |
181 | obstack); | |
182 | } | |
183 | else | |
184 | { | |
185 | /* Try to figure out the appropriate namespace from the | |
186 | demangled name. */ | |
187 | ||
188 | /* FIXME: carlton/2003-04-15: If the function in question is | |
189 | a method of a class, the name will actually include the | |
190 | name of the class as well. This should be harmless, but | |
191 | is a little unfortunate. */ | |
192 | ||
193 | const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol); | |
194 | unsigned int prefix_len = cp_entire_prefix_len (name); | |
195 | ||
196 | block_set_scope (block, | |
197 | obsavestring (name, prefix_len, obstack), | |
198 | obstack); | |
199 | } | |
200 | } | |
201 | } | |
202 | ||
203 | /* Test whether or not NAMESPACE looks like it mentions an anonymous | |
204 | namespace; return nonzero if so. */ | |
205 | ||
206 | int | |
207 | cp_is_anonymous (const char *namespace) | |
208 | { | |
209 | return (strstr (namespace, "(anonymous namespace)") | |
210 | != NULL); | |
211 | } | |
212 | ||
213 | /* Create a new struct using direct whose inner namespace is the | |
214 | initial substring of NAME of leng INNER_LEN and whose outer | |
215 | namespace is the initial substring of NAME of length OUTER_LENGTH. | |
216 | Set its next member in the linked list to NEXT; allocate all memory | |
217 | using xmalloc. It copies the strings, so NAME can be a temporary | |
218 | string. */ | |
219 | ||
220 | static struct using_direct * | |
221 | cp_add_using (const char *name, | |
222 | unsigned int inner_len, | |
223 | unsigned int outer_len, | |
224 | struct using_direct *next) | |
225 | { | |
226 | struct using_direct *retval; | |
227 | ||
228 | gdb_assert (outer_len < inner_len); | |
229 | ||
230 | retval = xmalloc (sizeof (struct using_direct)); | |
231 | retval->inner = savestring (name, inner_len); | |
232 | retval->outer = savestring (name, outer_len); | |
233 | retval->next = next; | |
234 | ||
235 | return retval; | |
236 | } | |
237 | ||
238 | /* Make a copy of the using directives in the list pointed to by | |
239 | USING, using OBSTACK to allocate memory. Free all memory pointed | |
240 | to by USING via xfree. */ | |
241 | ||
242 | static struct using_direct * | |
243 | cp_copy_usings (struct using_direct *using, | |
244 | struct obstack *obstack) | |
245 | { | |
246 | if (using == NULL) | |
247 | { | |
248 | return NULL; | |
249 | } | |
250 | else | |
251 | { | |
252 | struct using_direct *retval | |
253 | = obstack_alloc (obstack, sizeof (struct using_direct)); | |
254 | retval->inner = obsavestring (using->inner, strlen (using->inner), | |
255 | obstack); | |
256 | retval->outer = obsavestring (using->outer, strlen (using->outer), | |
257 | obstack); | |
258 | retval->next = cp_copy_usings (using->next, obstack); | |
259 | ||
260 | xfree (using->inner); | |
261 | xfree (using->outer); | |
262 | xfree (using); | |
263 | ||
264 | return retval; | |
265 | } | |
266 | } |