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/descrobject.c b/Objects/descrobject.c
index fea67f3..3a65902 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -38,9 +38,10 @@
 static void
 descr_dealloc(PyDescrObject *descr)
 {
+	_PyObject_GC_UNTRACK(descr);
 	Py_XDECREF(descr->d_type);
 	Py_XDECREF(descr->d_name);
-	PyObject_DEL(descr);
+	PyObject_GC_Del(descr);
 }
 
 static char *
@@ -352,6 +353,20 @@
 	{0}
 };
 
+static int
+descr_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	PyDescrObject *descr = (PyDescrObject *)self;
+	int err;
+
+	if (descr->d_type) {
+		err = visit((PyObject *)(descr->d_type), arg);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
 static PyTypeObject PyMethodDescr_Type = {
 	PyObject_HEAD_INIT(&PyType_Type)
 	0,
@@ -373,9 +388,9 @@
 	PyObject_GenericGetAttr,		/* tp_getattro */
 	0,					/* tp_setattro */
 	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
 	0,					/* tp_doc */
-	0,					/* tp_traverse */
+	descr_traverse,				/* tp_traverse */
 	0,					/* tp_clear */
 	0,					/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
@@ -411,9 +426,9 @@
 	PyObject_GenericGetAttr,		/* tp_getattro */
 	0,					/* tp_setattro */
 	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
 	0,					/* tp_doc */
-	0,					/* tp_traverse */
+	descr_traverse,				/* tp_traverse */
 	0,					/* tp_clear */
 	0,					/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
@@ -449,9 +464,9 @@
 	PyObject_GenericGetAttr,		/* tp_getattro */
 	0,					/* tp_setattro */
 	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
 	0,					/* tp_doc */
-	0,					/* tp_traverse */
+	descr_traverse,				/* tp_traverse */
 	0,					/* tp_clear */
 	0,					/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
@@ -487,9 +502,9 @@
 	PyObject_GenericGetAttr,		/* tp_getattro */
 	0,					/* tp_setattro */
 	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
 	0,					/* tp_doc */
-	0,					/* tp_traverse */
+	descr_traverse,				/* tp_traverse */
 	0,					/* tp_clear */
 	0,					/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
@@ -679,8 +694,9 @@
 static void
 proxy_dealloc(proxyobject *pp)
 {
+	_PyObject_GC_UNTRACK(pp);
 	Py_DECREF(pp->dict);
-	PyObject_DEL(pp);
+	PyObject_GC_Del(pp);
 }
 
 static PyObject *
@@ -695,6 +711,20 @@
 	return PyObject_Str(pp->dict);
 }
 
+static int
+proxy_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	proxyobject *pp = (proxyobject *)self;
+	int err;
+
+	if (pp->dict) {
+		err = visit(pp->dict, arg);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
 PyTypeObject proxytype = {
 	PyObject_HEAD_INIT(&PyType_Type)
 	0,					/* ob_size */
@@ -717,9 +747,9 @@
 	PyObject_GenericGetAttr,		/* tp_getattro */
 	0,					/* tp_setattro */
 	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
  	0,					/* tp_doc */
- 	0,					/* tp_traverse */
+	proxy_traverse,				/* tp_traverse */
  	0,					/* tp_clear */
 	0,					/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
@@ -739,10 +769,11 @@
 {
 	proxyobject *pp;
 
-	pp = PyObject_NEW(proxyobject, &proxytype);
+	pp = PyObject_GC_New(proxyobject, &proxytype);
 	if (pp != NULL) {
 		Py_INCREF(dict);
 		pp->dict = dict;
+		_PyObject_GC_TRACK(pp);
 	}
 	return (PyObject *)pp;
 }
@@ -762,9 +793,10 @@
 static void
 wrapper_dealloc(wrapperobject *wp)
 {
+	_PyObject_GC_UNTRACK(wp);
 	Py_XDECREF(wp->descr);
 	Py_XDECREF(wp->self);
-	PyObject_DEL(wp);
+	PyObject_GC_Del(wp);
 }
 
 static PyMethodDef wrapper_methods[] = {
@@ -808,6 +840,25 @@
 	return (*wrapper)(self, args, wp->descr->d_wrapped);
 }
 
+static int
+wrapper_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	wrapperobject *wp = (wrapperobject *)self;
+	int err;
+
+	if (wp->descr) {
+		err = visit((PyObject *)(wp->descr), arg);
+		if (err)
+			return err;
+	}
+	if (wp->self) {
+		err = visit(wp->self, arg);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
 PyTypeObject wrappertype = {
 	PyObject_HEAD_INIT(&PyType_Type)
 	0,					/* ob_size */
@@ -830,9 +881,9 @@
 	PyObject_GenericGetAttr,		/* tp_getattro */
 	0,					/* tp_setattro */
 	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
  	0,					/* tp_doc */
- 	0,					/* tp_traverse */
+	wrapper_traverse,			/* tp_traverse */
  	0,					/* tp_clear */
 	0,					/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
@@ -857,12 +908,13 @@
 	descr = (PyWrapperDescrObject *)d;
 	assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type)));
 
-	wp = PyObject_NEW(wrapperobject, &wrappertype);
+	wp = PyObject_GC_New(wrapperobject, &wrappertype);
 	if (wp != NULL) {
 		Py_INCREF(descr);
 		wp->descr = descr;
 		Py_INCREF(self);
 		wp->self = self;
+		_PyObject_GC_TRACK(wp);
 	}
 	return (PyObject *)wp;
 }
@@ -919,6 +971,7 @@
 {
 	propertyobject *gs = (propertyobject *)self;
 
+	_PyObject_GC_UNTRACK(self);
 	Py_XDECREF(gs->prop_get);
 	Py_XDECREF(gs->prop_set);
 	Py_XDECREF(gs->prop_del);
@@ -1012,6 +1065,26 @@
 "    def delx(self): del self.__x\n"
 "    x = property(getx, setx, delx, \"I'm the 'x' property.\")";
 
+static int
+property_traverse(PyObject *self, visitproc visit, void *arg)
+{
+	propertyobject *pp = (propertyobject *)self;
+	int err;
+
+#define VISIT(SLOT) \
+	if (pp->SLOT) { \
+		err = visit((PyObject *)(pp->SLOT), arg); \
+		if (err) \
+			return err; \
+	}
+
+	VISIT(prop_get);
+	VISIT(prop_set);
+	VISIT(prop_del);
+
+	return 0;
+}
+
 PyTypeObject PyProperty_Type = {
 	PyObject_HEAD_INIT(&PyType_Type)
 	0,					/* ob_size */
@@ -1034,9 +1107,10 @@
 	PyObject_GenericGetAttr,		/* 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 */
  	property_doc,				/* tp_doc */
- 	0,					/* tp_traverse */
+	property_traverse,			/* tp_traverse */
  	0,					/* tp_clear */
 	0,					/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
@@ -1053,5 +1127,5 @@
 	property_init,				/* tp_init */
 	PyType_GenericAlloc,			/* tp_alloc */
 	PyType_GenericNew,			/* tp_new */
-	_PyObject_Del,				/* tp_free */
+	_PyObject_GC_Del,			/* tp_free */
 };