+#define CLASS(...) EVAL_CLASS(OVERLOAD__(CLASS, __VA_ARGS__))
+#define EVAL_CLASS(...) __VA_ARGS__
+
+#define ATTRIB(...) EVAL_ATTRIB(OVERLOAD_(ATTRIB, __VA_ARGS__))
+#define EVAL_ATTRIB(...) __VA_ARGS__
+
+#ifdef QCC_SUPPORT_CLASS
+
+#warning "QCC_SUPPORT_CLASS not implemented"
+
+#define CLASS_1(name) CLASS_2(name, entity)
+#define CLASS_2(name, base) class name : base {
+
+#define INIT(class) void class::class()
+#define CONSTRUCTOR(class, ...) void class::class(__VA_ARGS__)
+#define DESTRUCTOR(class) class::~class()
+
+#define SUPER(class) super
+
+#define ATTRIB_3(class, name, T) T name
+#define ATTRIB_4(class, name, T, val) ATTRIB_3(class, name, T) = val
+#define STATIC_ATTRIB(class, name, T, val) static T name = val
+
+#define ATTRIB_STRZONE(class, name, T, val) T name = val
+#define STATIC_ATTRIB_STRZONE(class, name, T, val) static T name = val
+
+#define ATTRIBARRAY(class, name, T, val) T name[val]
+
+#define METHOD(class, name, prototype) virtual void class::name()
+#define STATIC_METHOD(class, name, prototype) static void class::name()
+
+#define ENDCLASS(class) };
+
+#else
+
+#define CLASS_1(cname) CLASS_2(cname, )
+#define CLASS_2(cname, base) \
+ entityclass(cname, base); \
+ classfield(cname).bool instanceOf##cname; \
+ DEBUG_STUFF(cname) \
+ VTBL(cname, base) \
+ _INIT_STATIC(cname) \
+ { \
+ if (cname##_vtbl && !this.transmute) \
+ { \
+ copyentity(cname##_vtbl, this); \
+ return; \
+ } \
+ spawn##base##_static(this); \
+ this.instanceOf##cname = true; \
+ } \
+ INIT(cname) \
+ { \
+ /* Only statically initialize the current class, it contains everything it inherits */ \
+ if (cname##_vtbl.vtblname == this.classname) \
+ { \
+ spawn##cname##_static(this); \
+ this.transmute = false; \
+ this.classname = #cname; \
+ this.vtblname = string_null; \
+ this.vtblbase = cname##_vtbl; \
+ } \
+ spawn##base##_1(this); \
+ }
+
+#define INIT(cname) \
+ ACCUMULATE cname spawn##cname##_1(cname this)
+
+#define CONSTRUCTOR(cname, ...) \
+ cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) \
+ { \
+ return = this; \
+ } \
+ ACCUMULATE cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__)
+
+#define DESTRUCTOR(cname) \
+ STATIC_METHOD(cname, dtorimpl, void(cname this)); \
+ METHOD(cname, dtor, void(cname this)) \
+ { \
+ METHOD_REFERENCE(cname, dtorimpl)(this); \
+ this.instanceOf##cname = false; \
+ entity super = SUPER(cname); \
+ if (super != cname##_vtbl) super.dtor(this); \
+ } \
+ STATIC_METHOD(cname, dtorimpl, void(cname this))
+
+#define SUPER(cname) (cname##_vtbl.vtblbase)
+
+#define ATTRIB_3(cname, name, type) classfield(cname) .type name
+#define ATTRIB_4(cname, name, type, val) \
+ ATTRIB_3(cname, name, type); \
+ INIT(cname) \
+ { \
+ noref bool strzone; /* Error on strzone() calls. */ \
+ this.name = val; \
+ } \
+ ATTRIB_3(cname, name, type)
+
+#define STATIC_ATTRIB(cname, name, type, val) \
+ type cname##_##name; \
+ _INIT_STATIC(cname) \
+ { \
+ noref bool strzone; /* Error on strzone() calls. */ \
+ cname##_##name = val; \
+ }
+
+// cleanup potentially zoned strings from base classes
+#define ATTRIB_STRZONE(cname, name, type, val) \
+ classfield(cname).type name; \
+ INIT(cname) \
+ { \
+ strcpy(this.name, val); \
+ }
+
+#define STATIC_ATTRIB_STRZONE(cname, name, type, val) \
+ type cname##_##name; \
+ _INIT_STATIC(cname) \
+ { \
+ strcpy(cname##_##name, val); \
+ }
+
+#define ATTRIBARRAY(cname, name, type, cnt) \
+ classfield(cname) .type name[cnt]
+
+#define METHOD(cname, name, prototype) \
+ STATIC_METHOD(cname, name, prototype); \
+ classfield(cname) .prototype name; \
+ _INIT_STATIC(cname) \
+ { \
+ this.name = METHOD_REFERENCE(cname, name); \
+ } \
+ STATIC_METHOD(cname, name, prototype)
+
+#define STATIC_METHOD(cname, name, prototype) \
+ prototype METHOD_REFERENCE(cname, name)
+
+#define ENDCLASS(cname) \
+ INIT(cname) \
+ { \
+ return this; \
+ }
+
+// impl