Fix bug 76780 - implement stabs type '@' for pointer to member.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2289 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_stabs.c b/coregrind/vg_stabs.c
index a8456c7..05f4822 100644
--- a/coregrind/vg_stabs.c
+++ b/coregrind/vg_stabs.c
@@ -300,35 +300,41 @@
return &sf->types[sym];
}
-static Bool isdigit(Char c, Int base, Int *v)
+static Bool isdigit(Char c, Int base, Int *vp)
{
+ Bool ret = False;
+ Int v = 0;
+
switch(base) {
case 10:
case 0:
- *v = c - '0';
- return c >= '0' && c <= '9';
+ v = c - '0';
+ ret = (c >= '0' && c <= '9');
+ break;
case 8:
- *v = c - '0';
- return c >= '0' && c <= '7';
+ v = c - '0';
+ ret = (c >= '0' && c <= '7');
+ break;
case 16:
if (c >= '0' && c <= '9') {
- *v = c - '0';
- return True;
+ v = c - '0';
+ ret = True;
+ } else if (c >= 'a' && c <= 'f') {
+ v = c - 'a';
+ ret = True;
+ } else if (c >= 'A' && c <= 'F') {
+ v = c - 'F';
+ ret = True;
}
- if (c >= 'a' && c <= 'f') {
- *v = c - 'a';
- return True;
- }
- if (c >= 'A' && c <= 'F') {
- *v = c - 'F';
- return True;
- }
- return False;
+ break;
}
- return False;
+ if (vp && ret)
+ *vp = v;
+
+ return ret;
}
static inline Int getbase(Char **pp)
@@ -534,8 +540,11 @@
if (debug)
VG_(printf)("defining type %p (%d,%d) = %s\n", symtype, file, sym, p);
- /* skip type attributes */
- while(*p == '@')
+ /* Skip type attributes
+ '@' could also be pointer-to-member, so we need to see if
+ the following character looks like a type reference or not.
+ */
+ while(*p == '@' && !(VG_(isdigit)(p[1]) || p[1] == '-' || p[1] == '(') )
p = SKIPPAST(p+1, ';', "type attrib");
prev = p;
@@ -644,7 +653,7 @@
case '&': /* reference */
case '*': { /* pointer */
- /* '*' TYPE */
+ /* ('*' | '&') TYPE */
type = stabtype_parser(si, NULL, &p);
type = VG_(st_mkpointer)(def, type);
break;
@@ -652,7 +661,7 @@
case 'k': /* const */
case 'B': { /* volatile */
- /* 'k' TYPE */
+ /* ('k' | 'B') TYPE */
type = stabtype_parser(si, NULL, &p);
break;
}
@@ -701,7 +710,7 @@
case 'P': /* packed array */
case 'a': { /* array */
- /* a IDX-TYPE TYPE */
+ /* ( 'a' | 'P' ) IDX-TYPE TYPE */
SymType *idxtype;
SymType *artype;
@@ -732,7 +741,7 @@
case 's': { /* struct */
/* Gad. Here we go:
- 's' SIZE
+ ( 's' | 'u' ) SIZE
( '!' NBASE ',' ( VIRT PUB OFF ',' BASE-TYPE ){NBASE} )?
( NAME ( ':' ( '/' [0-9] )? TYPE ',' OFFSET ( ',' SIZE )?
@@ -931,6 +940,15 @@
EXPECT(';', "method definition");
break;
+ case '@': /* pointer to member */
+ /* '@' CLASS-TYPE ',' MEMBER-TYPE */
+ type = VG_(st_mkint)(def, sizeof(int), False); /* make it an int for our use */
+
+ stabtype_parser(si, NULL, &p); /* CLASS-TYPE */
+ EXPECT(',', "member-pointer CLASS-TYPE");
+ stabtype_parser(si, NULL, &p); /* MEMBER-TYPE */
+ break;
+
default:
VG_(printf)(" @@ don't know what type '%c' is\n", t);
type = NULL;