Fix private name mangling.  The symtable also must do mangles so that
the scope of names can be correctly determined.
diff --git a/Include/symtable.h b/Include/symtable.h
index c8d8636..ad7334b 100644
--- a/Include/symtable.h
+++ b/Include/symtable.h
@@ -17,7 +17,7 @@
         PyObject *st_stack;      /* stack of namespace info */
 	PyObject *st_global;     /* borrowed ref to MODULE in st_symbols */
 	int st_nblocks;          /* number of blocks */
-	char *st_private;        /* name of current class or NULL */
+	PyObject *st_private;        /* name of current class or NULL */
         int st_tmpname;          /* temporary name counter */
 	PyFutureFeatures *st_future; /* module's future features */
 };
diff --git a/Python/compile.c b/Python/compile.c
index 5e7f35d..fe6fd50 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -2701,10 +2701,11 @@
 static int
 compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
 {
-	int op, scope;
+	int op, scope, r, arg;
 	enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype;
 
         PyObject *dict = c->u->u_names;
+	PyObject *mangled;
 	/* XXX AugStore isn't used anywhere! */
 
 	/* First check for assignment to __debug__. Param? */
@@ -2713,9 +2714,13 @@
 		return compiler_error(c, "can not assign to __debug__");
 	}
 
+	mangled = _Py_Mangle(c->u->u_private, name);
+	if (!mangled)
+		return 0;
+
 	op = 0;
 	optype = OP_NAME;
-	scope = PyST_GetScope(c->u->u_ste, name);
+	scope = PyST_GetScope(c->u->u_ste, mangled);
 	switch (scope) {
 	case FREE:
                 dict = c->u->u_freevars;
@@ -2755,6 +2760,7 @@
 				     "can not delete variable '%s' referenced "
 				     "in nested scope",
 				     PyString_AS_STRING(name));
+			Py_DECREF(mangled);
 			return 0;
 			break;
 		case Param:
@@ -2772,7 +2778,8 @@
 		case Param:
 			assert(0); /* impossible */
 		}
-		ADDOP_O(c, op, name, varnames);
+		ADDOP_O(c, op, mangled, varnames);
+		Py_DECREF(mangled);
 		return 1;
 	case OP_GLOBAL:
 		switch (ctx) {
@@ -2801,7 +2808,12 @@
 	}
 
 	assert(op);
-	return compiler_addop_name(c, op, dict, name);
+	arg = compiler_add_o(c, dict, mangled);
+	if (arg < 0)
+		return 0;
+	r = compiler_addop_i(c, op, arg);
+	Py_DECREF(mangled);
+	return r;
 }
 
 static int
diff --git a/Python/symtable.c b/Python/symtable.c
index 49d153b..cbf0344 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -740,8 +740,11 @@
 symtable_lookup(struct symtable *st, PyObject *name)
 {
 	PyObject *o;
-
-	o = PyDict_GetItem(st->st_cur->ste_symbols, name);
+	PyObject *mangled = _Py_Mangle(st->st_private, name);
+	if (!mangled)
+		return 0;
+	o = PyDict_GetItem(st->st_cur->ste_symbols, mangled);
+	Py_DECREF(mangled);
 	if (!o)
 		return 0;
 	return PyInt_AsLong(o);
@@ -753,49 +756,57 @@
 	PyObject *o;
 	PyObject *dict;
 	int val;
+	PyObject *mangled = _Py_Mangle(st->st_private, name);
 
+	if (!mangled)
+		return 0;
 	dict = st->st_cur->ste_symbols;
-	if ((o = PyDict_GetItem(dict, name))) {
+	if ((o = PyDict_GetItem(dict, mangled))) {
 	    val = PyInt_AS_LONG(o);
 	    if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
+		    /* Is it better to use 'mangled' or 'name' here? */
 		    PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT,
 				 PyString_AsString(name));
 		    PyErr_SyntaxLocation(st->st_filename,
 				       st->st_cur->ste_lineno);
-		    return 0;
+		    goto error;
 	    }
 	    val |= flag;
 	} else
 	    val = flag;
 	o = PyInt_FromLong(val);
         if (o == NULL)
-            return 0;
-	if (PyDict_SetItem(dict, name, o) < 0) {
+	    goto error;
+	if (PyDict_SetItem(dict, mangled, o) < 0) {
 		Py_DECREF(o);
-		return 0;
+		goto error;
 	}
 	Py_DECREF(o);
 
 	if (flag & DEF_PARAM) {
-		if (PyList_Append(st->st_cur->ste_varnames, name) < 0) 
-			return 0;
+		if (PyList_Append(st->st_cur->ste_varnames, mangled) < 0)
+			goto error;
 	} else	if (flag & DEF_GLOBAL) {
 		/* XXX need to update DEF_GLOBAL for other flags too;
 		   perhaps only DEF_FREE_GLOBAL */
 		val = flag;
-		if ((o = PyDict_GetItem(st->st_global, name))) {
+		if ((o = PyDict_GetItem(st->st_global, mangled))) {
 			val |= PyInt_AS_LONG(o);
 		}
 		o = PyInt_FromLong(val);
 		if (o == NULL)
-			return 0;
-		if (PyDict_SetItem(st->st_global, name, o) < 0) {
+			goto error;
+		if (PyDict_SetItem(st->st_global, mangled, o) < 0) {
 			Py_DECREF(o);
-			return 0;
+			goto error;
 		}
 		Py_DECREF(o);
 	}
 	return 1;
+
+error:
+	Py_DECREF(mangled);
+	return 0;
 }
 
 /* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument.
@@ -849,17 +860,22 @@
 		if (!symtable_exit_block(st, s))
 			return 0;
 		break;
-        case ClassDef_kind:
+        case ClassDef_kind: {
+		PyObject *tmp;
 		if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL))
 			return 0;
 		VISIT_SEQ(st, expr, s->v.ClassDef.bases);
 		if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, 
 					  (void *)s, s->lineno))
 			return 0;
+		tmp = st->st_private;
+		st->st_private = s->v.ClassDef.name;
 		VISIT_SEQ(st, stmt, s->v.ClassDef.body);
+		st->st_private = tmp;
 		if (!symtable_exit_block(st, s))
 			return 0;
 		break;
+	}
         case Return_kind:
 		if (s->v.Return.value)
 			VISIT(st, expr, s->v.Return.value);