Commit | Line | Data |
---|---|---|
de17c821 DJ |
1 | /* Helper routines for C++ support in GDB. |
2 | Copyright 2002 Free Software Foundation, Inc. | |
3 | ||
4 | Contributed by MontaVista Software. | |
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_string.h" | |
26 | #include "demangle.h" | |
27 | ||
28 | /* Find the last component of the demangled C++ name NAME. NAME | |
29 | must be a method name including arguments, in order to correctly | |
30 | locate the last component. | |
31 | ||
32 | This function return a pointer to the first colon before the | |
33 | last component, or NULL if the name had only one component. */ | |
34 | ||
35 | static const char * | |
36 | find_last_component (const char *name) | |
37 | { | |
38 | const char *p; | |
39 | int depth; | |
40 | ||
41 | /* Functions can have local classes, so we need to find the | |
42 | beginning of the last argument list, not the end of the first | |
43 | one. */ | |
44 | p = name + strlen (name) - 1; | |
45 | while (p > name && *p != ')') | |
46 | p--; | |
47 | ||
48 | if (p == name) | |
49 | return NULL; | |
50 | ||
51 | /* P now points at the `)' at the end of the argument list. Walk | |
52 | back to the beginning. */ | |
53 | p--; | |
54 | depth = 1; | |
55 | while (p > name && depth > 0) | |
56 | { | |
57 | if (*p == '<' || *p == '(') | |
58 | depth--; | |
59 | else if (*p == '>' || *p == ')') | |
60 | depth++; | |
61 | p--; | |
62 | } | |
63 | ||
64 | if (p == name) | |
65 | return NULL; | |
66 | ||
67 | while (p > name && *p != ':') | |
68 | p--; | |
69 | ||
70 | if (p == name || p == name + 1 || p[-1] != ':') | |
71 | return NULL; | |
72 | ||
73 | return p - 1; | |
74 | } | |
75 | ||
76 | /* Return the name of the class containing method PHYSNAME. */ | |
77 | ||
78 | char * | |
79 | class_name_from_physname (const char *physname) | |
80 | { | |
81 | char *ret = NULL; | |
82 | const char *end; | |
83 | int depth = 0; | |
84 | char *demangled_name = cplus_demangle (physname, DMGL_ANSI); | |
85 | ||
86 | if (demangled_name == NULL) | |
87 | return NULL; | |
88 | ||
89 | end = find_last_component (demangled_name); | |
90 | if (end != NULL) | |
91 | { | |
92 | ret = xmalloc (end - demangled_name + 1); | |
93 | memcpy (ret, demangled_name, end - demangled_name); | |
94 | ret[end - demangled_name] = '\0'; | |
95 | } | |
96 | ||
97 | xfree (demangled_name); | |
98 | return ret; | |
99 | } | |
100 | ||
101 | /* Return the name of the method whose linkage name is PHYSNAME. */ | |
102 | ||
103 | char * | |
104 | method_name_from_physname (const char *physname) | |
105 | { | |
106 | char *ret = NULL; | |
107 | const char *end; | |
108 | int depth = 0; | |
109 | char *demangled_name = cplus_demangle (physname, DMGL_ANSI); | |
110 | ||
111 | if (demangled_name == NULL) | |
112 | return NULL; | |
113 | ||
114 | end = find_last_component (demangled_name); | |
115 | if (end != NULL) | |
116 | { | |
117 | char *args; | |
118 | int len; | |
119 | ||
120 | /* Skip "::". */ | |
121 | end = end + 2; | |
122 | ||
123 | /* Find the argument list, if any. */ | |
124 | args = strchr (end, '('); | |
125 | if (args == NULL) | |
126 | len = strlen (end + 2); | |
127 | else | |
128 | { | |
129 | args --; | |
130 | while (*args == ' ') | |
131 | args --; | |
132 | len = args - end + 1; | |
133 | } | |
134 | ret = xmalloc (len + 1); | |
135 | memcpy (ret, end, len); | |
136 | ret[len] = 0; | |
137 | } | |
138 | ||
139 | xfree (demangled_name); | |
140 | return ret; | |
141 | } |