Cope with strange templated symbol names containing quoted ':'.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2298 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_stabs.c b/coregrind/vg_stabs.c
index 05f4822..f17f6df 100644
--- a/coregrind/vg_stabs.c
+++ b/coregrind/vg_stabs.c
@@ -402,12 +402,33 @@
return ret;
}
-/* Skip to end of name (':'); "::" in the name indicate nesting, and
- are included within the name */
-static Char *nested_name(Char *p) {
- while(*p && (p[0] != ':' || p[1] == ':')) {
- if (*p == ':')
- p++;
+/* Skip a ':'-delimited name which may have ::, 'char' or other things in
+ <> brackets */
+static Char *templ_name(Char *p)
+{
+ Int brac = 0;
+
+ for(;;) {
+ if (*p == '<')
+ brac++;
+ if (*p == '>')
+ brac--;
+ /* skip quoted character (note, it could be anything, even a
+ literal \0)
+
+ XXX This is a complete botch; we can't do anything sane here,
+ like support \-quoting, because gcc doesn't seem to generate
+ it, and even if it did, we wouldn't know what "'\'" means -
+ the begining of '\'' or a char in itself ('\\')?
+ */
+ if (brac && p[0] == '\'' && p[2] == '\'')
+ p += 3;
+ if (*p == ':') {
+ if (brac && p[1] == ':')
+ p++;
+ else
+ break;
+ }
p++;
}
@@ -668,24 +689,10 @@
case 'x': { /* reference to undefined type */
/* 'x' ('s' | 'u' | 'e') NAME ':' */
- Int brac = 0; /* < > brackets in type */
Char kind = *p++; /* get kind */
Char *name = p;
- /* name is delimited by : except for :: within <> */
- for(;;) {
- if (*p == '<')
- brac++;
- if (*p == '>')
- brac--;
- if (*p == ':') {
- if (brac && p[1] == ':')
- p += 1;
- else
- break;
- }
- p++;
- }
+ p = templ_name(name);
EXPECT(':', "struct/union/enum ref");
name = VG_(addStr)(si, name, p-1-name);
@@ -784,25 +791,8 @@
Char *name;
UInt off, sz;
SymType *fieldty;
- Int templ=0;
- /* Skip past field name, which ends with ':' or '::' - but
- '::' can appear within a template-mangled name, so keep
- track of '<' and '>'. */
- end = p;
- while(*end) {
- Char ch = *end++;
-
- if (ch == '<')
- templ++;
- else if (ch == '>')
- templ--;
- else if (templ == 0 && ch == ':') {
- end--;
- break;
- }
- }
- /* XXX check for *end != ':' */
+ end = templ_name(p);
if (end[1] == ':') {
/* c++ method names end in :: */
@@ -980,7 +970,7 @@
VG_(printf)("initSym(si=%p, tab=%p, sym=%p, kind=%d, name=%p \"%s\", val=%d)\n",
si, si->stab_typetab, sym, kind, name, name, val);
- ty = nested_name(name);
+ ty = templ_name(name);
len = ty - name;