Add Garbage Collection support to new-style classes (not yet to their
instances).

Also added GC support to various auxiliary types: super, property,
descriptors, wrappers, dictproxy.  (Only type objects have a tp_clear
field; the other types are.)

One change was necessary to the GC infrastructure.  We have statically
allocated type objects that don't have a GC header (and can't easily
be given one) and heap-allocated type objects that do have a GC
header.  Giving these different metatypes would be really ugly: I
tried, and I had to modify pickle.py, cPickle.c, copy.py, add a new
invent a new name for the new metatype and make it a built-in, change
affected tests...  In short, a mess.  So instead, we add a new type
slot tp_is_gc, which is a simple Boolean function that determines
whether a particular instance has GC headers or not.  This slot is
only relevant for types that have the (new) GC flag bit set.  If the
tp_is_gc slot is NULL (by far the most common case), all instances of
the type are deemed to have GC headers.  This slot is called by the
PyObject_IS_GC() macro (which is only used twice, both times in
gcmodule.c).

I also changed the extern declarations for a bunch of GC-related
functions (_PyObject_GC_Del etc.): these always exist but objimpl.h
only declared them when WITH_CYCLE_GC was defined, but I needed to be
able to reference them without #ifdefs.  (When WITH_CYCLE_GC is not
defined, they do the same as their non-GC counterparts anyway.)
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 8a11dff..295be89 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -265,7 +265,7 @@
 
 	/* Finalize GC if the base doesn't do GC and we do */
 	if (PyType_IS_GC(type) && !PyType_IS_GC(base))
-		PyObject_GC_Fini(self);
+		_PyObject_GC_UNTRACK(self);
 
 	/* Call the base tp_dealloc() */
 	assert(f);
@@ -864,6 +864,8 @@
 		Py_TPFLAGS_BASETYPE;
 	if (dynamic)
 		type->tp_flags |= Py_TPFLAGS_DYNAMICTYPE;
+	if (base->tp_flags & Py_TPFLAGS_HAVE_GC)
+		type->tp_flags |= Py_TPFLAGS_HAVE_GC;
 
 	/* It's a new-style number unless it specifically inherits any
 	   old-style numeric behavior */
@@ -934,7 +936,8 @@
 	else {
 		if (add_dict) {
 			if (base->tp_itemsize)
-				type->tp_dictoffset = -(long)sizeof(PyObject *);
+				type->tp_dictoffset =
+					-(long)sizeof(PyObject *);
 			else
 				type->tp_dictoffset = slotoffset;
 			slotoffset += sizeof(PyObject *);
@@ -966,7 +969,13 @@
 
 	/* Always override allocation strategy to use regular heap */
 	type->tp_alloc = PyType_GenericAlloc;
-	type->tp_free = _PyObject_Del;
+	if (type->tp_flags & Py_TPFLAGS_HAVE_GC) {
+		type->tp_free = _PyObject_GC_Del;
+		type->tp_traverse = base->tp_traverse;
+		type->tp_clear = base->tp_clear;
+	}
+	else
+		type->tp_free = _PyObject_Del;
 
 	/* Initialize the rest */
 	if (PyType_Ready(type) < 0) {
@@ -1080,6 +1089,7 @@
 
 	/* Assert this is a heap-allocated type object */
 	assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
+	_PyObject_GC_UNTRACK(type);
 	et = (etype *)type;
 	Py_XDECREF(type->tp_base);
 	Py_XDECREF(type->tp_dict);
@@ -1102,6 +1112,72 @@
 "type(object) -> the object's type\n"
 "type(name, bases, dict) -> a new type";
 
+static int
+type_traverse(PyTypeObject *type, visitproc visit, void *arg)
+{
+	etype *et;
+	int err;
+
+	if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
+		return 0;
+
+	et = (etype *)type;
+
+#define VISIT(SLOT) \
+	if (SLOT) { \
+		err = visit((PyObject *)(SLOT), arg); \
+		if (err) \
+			return err; \
+	}
+
+	VISIT(type->tp_dict);
+	VISIT(type->tp_defined);
+	VISIT(type->tp_mro);
+	VISIT(type->tp_bases);
+	VISIT(type->tp_base);
+	VISIT(et->slots);
+
+#undef VISIT
+
+	return 0;
+}
+
+static int
+type_clear(PyTypeObject *type)
+{
+	etype *et;
+	PyObject *tmp;
+
+	if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
+		return 0;
+
+	et = (etype *)type;
+
+#define CLEAR(SLOT) \
+	if (SLOT) { \
+		tmp = (PyObject *)(SLOT); \
+		SLOT = NULL; \
+		Py_DECREF(tmp); \
+	}
+
+	CLEAR(type->tp_dict);
+	CLEAR(type->tp_defined);
+	CLEAR(type->tp_mro);
+	CLEAR(type->tp_bases);
+	CLEAR(type->tp_base);
+	CLEAR(et->slots);
+
+#undef CLEAR
+
+	return 0;
+}
+
+static int
+type_is_gc(PyTypeObject *type)
+{
+	return type->tp_flags & Py_TPFLAGS_HEAPTYPE;
+}
+
 PyTypeObject PyType_Type = {
 	PyObject_HEAD_INIT(&PyType_Type)
 	0,					/* ob_size */
@@ -1123,10 +1199,11 @@
 	(getattrofunc)type_getattro,		/* tp_getattro */
 	(setattrofunc)type_setattro,		/* tp_setattro */
 	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
 	type_doc,				/* tp_doc */
-	0,					/* tp_traverse */
-	0,					/* tp_clear */
+	(traverseproc)type_traverse,		/* tp_traverse */
+	(inquiry)type_clear,			/* tp_clear */
 	0,					/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
 	0,					/* tp_iter */
@@ -1142,6 +1219,8 @@
 	0,					/* tp_init */
 	0,					/* tp_alloc */
 	type_new,				/* tp_new */
+	_PyObject_GC_Del,			/* tp_free */
+	(inquiry)type_is_gc,			/* tp_is_gc */
 };
 
 
@@ -3531,6 +3610,7 @@
 {
 	superobject *su = (superobject *)self;
 
+	_PyObject_GC_UNTRACK(self);
 	Py_XDECREF(su->obj);
 	Py_XDECREF(su->type);
 	self->ob_type->tp_free(self);
@@ -3666,6 +3746,27 @@
 "    def meth(self, arg):\n"
 "        super(C, self).meth(arg)";
 
+static int
+super_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	superobject *su = (superobject *)self;
+	int err;
+
+#define VISIT(SLOT) \
+	if (SLOT) { \
+		err = visit((PyObject *)(SLOT), arg); \
+		if (err) \
+			return err; \
+	}
+
+	VISIT(su->obj);
+	VISIT(su->type);
+
+#undef VISIT
+
+	return 0;
+}
+
 PyTypeObject PySuper_Type = {
 	PyObject_HEAD_INIT(&PyType_Type)
 	0,					/* ob_size */
@@ -3688,9 +3789,10 @@
 	super_getattro,				/* tp_getattro */
 	0,					/* tp_setattro */
 	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
  	super_doc,				/* tp_doc */
- 	0,					/* tp_traverse */
+ 	super_traverse,				/* tp_traverse */
  	0,					/* tp_clear */
 	0,					/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
@@ -3707,5 +3809,5 @@
 	super_init,				/* tp_init */
 	PyType_GenericAlloc,			/* tp_alloc */
 	PyType_GenericNew,			/* tp_new */
-	_PyObject_Del,				/* tp_free */
+	_PyObject_GC_Del,			/* tp_free */
 };