fixes
diff --git a/src/cmd/acidtypes/dat.h b/src/cmd/acidtypes/dat.h
index a7d5f5d..5039070 100644
--- a/src/cmd/acidtypes/dat.h
+++ b/src/cmd/acidtypes/dat.h
@@ -79,10 +79,12 @@
 void freetypes(void);
 
 extern char *prefix;
+extern int verbose;
+
 char *fixname(char*);
+char *cleanstl(char*);
 
 void addsymx(char*, char*, Type*);
 void dumpsyms(Biobuf*);
 
 
-
diff --git a/src/cmd/acidtypes/main.c b/src/cmd/acidtypes/main.c
index 0c74752..1efff63 100644
--- a/src/cmd/acidtypes/main.c
+++ b/src/cmd/acidtypes/main.c
@@ -4,17 +4,19 @@
 #include <mach.h>
 #include "dat.h"
 
+int verbose;
+
 void
 usage(void)
 {
-	fprint(2, "usage: acidtypes [-p prefix] executable...\n");
+	fprint(2, "usage: acidtypes [-v] [-p prefix] executable...\n");
 	exits("usage");
 }
 
 void
 main(int argc, char **argv)
 {
-	int i;
+	int i, have;
 	Fhdr *fp;
 	Biobuf b;
 	char err[ERRMAX];
@@ -22,6 +24,9 @@
 	quotefmtinstall();
 
 	ARGBEGIN{
+	case 'v':
+		verbose = 1;
+		break;
 	case 'p':
 		prefix = EARGF(usage());
 		break;
@@ -41,19 +46,25 @@
 			fprint(2, "open %s: %s\n", argv[i], err);
 			continue;
 		}
+		have = 0;
 		if(fp->dwarf){
 			if(dwarf2acid(fp->dwarf, &b) < 0){
 				rerrstr(err, sizeof err);
 				Bprint(&b, "// dwarf2acid %s: %s\n\n", argv[i], err);
 				fprint(2, "dwarf2acid %s: %s\n", argv[i], err);
 			}
-		}else if(fp->stabs.stabbase){
+			have = 1;
+		}
+		if(fp->stabs.stabbase){
 			if(stabs2acid(&fp->stabs, &b) < 0){
 				rerrstr(err, sizeof err);
 				Bprint(&b, "// dwarf2acid %s: %s\n\n", argv[i], err);
 				fprint(2, "dwarf2acid %s: %s\n", argv[i], err);
 			}
-		}else{
+			have = 1;
+		}
+		
+		if(!have){
 			Bprint(&b, "// no debugging symbols in %s\n\n", argv[i]);
 		//	fprint(2, "no debugging symbols in %s\n", argv[i]);
 		}
diff --git a/src/cmd/acidtypes/stabs.c b/src/cmd/acidtypes/stabs.c
index 7cc45c2..862f943 100644
--- a/src/cmd/acidtypes/stabs.c
+++ b/src/cmd/acidtypes/stabs.c
@@ -43,7 +43,7 @@
 mkpath(char *dir, char *name)
 {
 	char *s;
-	if(name[0] == '/')
+	if(name[0] == '/' || dir == nil)
 		return estrdup(name);
 	else{
 		s = emalloc(strlen(dir)+strlen(name)+1);
@@ -384,6 +384,7 @@
 		break;
 	case '*':	/* pointer */
 	case 'A':	/* open array */
+	case '&':	/* reference */	/* guess - C++? (rob) */
 		t->ty = Pointer;
 		t->sub = parseinfo(p+1, &p);
 		break;
@@ -613,6 +614,8 @@
 	fno = 0;
 	fn = nil;
 	for(i=0; stabsym(stabs, i, &sym)>=0; i++){
+		if(verbose)
+			print("%d %s\n", sym.type, sym.name);
 		switch(sym.type){
 		case N_SO:
 			if(sym.name){
@@ -638,7 +641,10 @@
 		case N_EXCL:
 			fno++;
 			if((f = findftypes(dir, sym.name)) == nil){
-				fprint(2, "cannot find remembered %s\n", sym.name);
+				static int cannotprint;
+				
+				if(cannotprint++ == 0)
+					fprint(2, "cannot find remembered %s\n", sym.name);
 				continue;
 			}
 			renumber(f->list, fno);
@@ -656,7 +662,7 @@
 					fn = nil;
 				continue;
 			}
-			if((p = strchr(name, ':')) == nil)
+			if((p = findcolon(name)) == nil)
 				continue;
 			name = estrndup(name, p-name);
 			desc = ++p;
@@ -666,14 +672,21 @@
 				continue;
 			}
 			if(setjmp(kaboom)){
-				fprint(2, "cannot parse %s\n", name);
+				static int cannotparse;
+				
+				if(cannotparse++ == 0)
+					fprint(2, "cannot parse %s\n", name);
 				continue;
 			}
 			t = parsename(desc, &p);
 			if(t == nil)
 				continue;
-			if(*p != 0)
-				fprint(2, "extra desc '%s' in '%s'\n", p, desc);
+			if(*p != 0){
+				static int extradesc;
+				
+				if(extradesc++ == 0)
+					fprint(2, "extra desc '%s' in '%s'\n", p, desc);
+			}
 			/* void is defined as itself */
 			if(t->ty==Defer && t->sub==t && strcmp(name, "void")==0){
 				t->ty = Base;
@@ -729,6 +742,7 @@
 			}
 			break;
 		}
+if(1) print("");
 	}
 
 	printtypes(b);
diff --git a/src/cmd/acidtypes/sym.c b/src/cmd/acidtypes/sym.c
index 7250ed4..3c9bd49 100644
--- a/src/cmd/acidtypes/sym.c
+++ b/src/cmd/acidtypes/sym.c
@@ -41,7 +41,7 @@
 		}
 		if(t == nil || t->ty != Aggr)
 			continue;
-		Bprint(b, "complex %s %s%s%s;\n", nameof(t, 1),
+		Bprint(b, "complex %s %s%s%s;\n", cleanstl(nameof(t, 1)),
 			s->fn ? fixname(s->fn) : "", s->fn ? ":" : "", fixname(s->name));
 	}
 
diff --git a/src/cmd/acidtypes/type.c b/src/cmd/acidtypes/type.c
index 5757a32..69bf015 100644
--- a/src/cmd/acidtypes/type.c
+++ b/src/cmd/acidtypes/type.c
@@ -239,16 +239,74 @@
 };
 
 char*
+nonempty(char *name)
+{
+	if(name[0] == '\0')
+		return "__empty__name__";
+	return name;
+}
+
+char*
+cleanstl(char *name)
+{
+	char *b, *p;
+	static char buf[65536];	/* These can be huge. */
+	
+	if(strchr(name, '<') == nil)
+		return nonempty(name);
+	
+	b = buf;
+	for(p = name; *p != 0; p++){
+		switch(*p){
+		case '<':
+			strcpy(b, "_L_");
+			b += 3;
+			break;
+		case '>':
+			strcpy(b, "_R_");
+			b += 3;
+			break;
+		case '*':
+			strcpy(b, "_A_");
+			b += 3;
+			break;
+		case ',':
+			strcpy(b, "_C_");
+			b += 3;
+			break;
+		case '.':
+			strcpy(b, "_D_");
+			b += 3;
+			break;
+		default:
+			*b++ = *p;
+			break;
+		}
+	}
+	*b = 0;
+	return buf;
+}
+
+char*
 fixname(char *name)
 {
 	int i;
+	char *s;
+	static int nbuf;
+	static char buf[8][65536];
 
 	if(name == nil)
 		return nil;
+	s = demangle(name, buf[nbuf], 1);
+	if(s != name){
+		if(++nbuf == nelem(buf))
+			nbuf = 0;
+		name = s;
+	}
 	for(i=0; i<nelem(fixes); i++)
 		if(name[0]==fixes[i].old[0] && strcmp(name, fixes[i].old)==0)
-			return fixes[i].new;
-	return name;
+			return nonempty(fixes[i].new);
+	return nonempty(name);
 }
 
 void
@@ -261,12 +319,14 @@
 void
 renumber(TypeList *tl, uint n1)
 {
-	Type *t;
+	Type *t, *tt;
 
 	for(; tl; tl=tl->tl){
 		t = tl->hd;
-		t->n1 = n1;
-		addhash(t);
+		tt = typebynum(n1, t->n2);
+		*tt = *t;
+		tt->n1 = n1;
+		addhash(tt);
 	}
 }
 
@@ -276,6 +336,10 @@
 	Type *u, *oldt;
 	int n;
 
+	if(t == nil)
+		return nil;
+
+/* XXX rob has return t; here */
 	u = t;
 	n = 0;
 	oldt = t;
@@ -286,6 +350,8 @@
 		if(t == u)	/* cycle */
 			goto cycle;
 	}
+	if(oldt != t)
+		oldt->sub = t;
 	return t;
 
 cycle:
@@ -361,7 +427,7 @@
 char*
 nameof(Type *t, int doanon)
 {
-	static char buf[1024];
+	static char buf[65536];
 	char *p;
 
 	if(t->name)
@@ -499,7 +565,7 @@
 	t->printed = 1;
 	switch(t->ty){
 	case Aggr:
-		name = nameof(t, 1);
+		name = cleanstl(nameof(t, 1));
 		Bprint(b, "sizeof%s = %lud;\n", name, t->xsizeof);
 		Bprint(b, "aggr %s {\n", name);
 		nprint = 0;
@@ -516,11 +582,13 @@
 				Bprint(b, "// oops: unknown type %d for %p/%s (%d,%d; %c,%s; %p)\n",
 					tt->ty, tt, fixname(t->tname[j]),
 					tt->n1, tt->n2, tt->sue ? tt->sue : '.', tt->suename, tt->sub);
+if(0){
 Bprint(b, "// t->t[j] = %p\n", ttt=t->t[j]);
 while(ttt){
 Bprint(b, "// %s %d (%d,%d) sub %p\n", ttt->name, ttt->ty, ttt->n1, ttt->n2, ttt->sub);
 ttt=ttt->sub;
 }
+}
 			case Base:
 			case Pointer:
 			case Enum:
@@ -539,9 +607,9 @@
 			Bprint(b, "\t'X' 0 __dummy;\n");
 		Bprint(b, "};\n\n");
 	
-		name = nameof(t, 1);	/* might have smashed it */
+		name = cleanstl(nameof(t, 1));	/* might have smashed it */
 		Bprint(b, "defn %s(addr) { indent_%s(addr, \"\"); }\n", name, name);
-		Bprint(b, "defn\nindent_%s(addr, indent) {\n", name);
+		Bprint(b, "defn indent_%s(addr, indent) {\n", name);
 		Bprint(b, "\tcomplex %s addr;\n", name);
 		for(j=0; j<t->n; j++){
 			name = fixname(t->tname[j]);
@@ -598,7 +666,7 @@
 		for(j=0; j<t->n; j++)
 			Bprint(b, "\t\"%s\",\n", fixname(t->tname[j]));
 		Bprint(b, "};\n");
-		Bprint(b, "defn\n%s(val) {\n", name);
+		Bprint(b, "defn %s(val) {\n", name);
 		Bprint(b, "\tlocal i;\n");
 		Bprint(b, "\ti = match(val, vals_%s);\n", name);
 		Bprint(b, "\tif i >= 0 then return names_%s[i];\n", name);
@@ -620,7 +688,7 @@
 		t = tl->hd;
 		if(t->ty==None){
 			if(t->n1 || t->n2)
-				warn("type %d,%d referenced but not defined", t->n1, t->n2);
+				warn("type %d,%d referenced but not defined - %p", t->n1, t->n2, t);
 			else if(t->sue && t->suename)
 				warn("%s %s referenced but not defined",
 					t->sue=='s' ? "struct" :