diff --git a/sys/arm64/arm64/gicv3_its.c b/sys/arm64/arm64/gicv3_its.c --- a/sys/arm64/arm64/gicv3_its.c +++ b/sys/arm64/arm64/gicv3_its.c @@ -2204,10 +2204,8 @@ DEVMETHOD_END }; -#define its_baseclasses its_fdt_baseclasses DEFINE_CLASS_1(its, gicv3_its_fdt_driver, gicv3_its_fdt_methods, sizeof(struct gicv3_its_softc), gicv3_its_driver); -#undef its_baseclasses EARLY_DRIVER_MODULE(its_fdt, gic, gicv3_its_fdt_driver, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); @@ -2276,10 +2274,8 @@ DEVMETHOD_END }; -#define its_baseclasses its_acpi_baseclasses DEFINE_CLASS_1(its, gicv3_its_acpi_driver, gicv3_its_acpi_methods, sizeof(struct gicv3_its_softc), gicv3_its_driver); -#undef its_baseclasses EARLY_DRIVER_MODULE(its_acpi, gic, gicv3_its_acpi_driver, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c --- a/sys/arm64/arm64/nexus.c +++ b/sys/arm64/arm64/nexus.c @@ -444,9 +444,7 @@ DEVMETHOD_END, }; -#define nexus_baseclasses nexus_fdt_baseclasses DEFINE_CLASS_1(nexus, nexus_fdt_driver, nexus_fdt_methods, 1, nexus_driver); -#undef nexus_baseclasses EARLY_DRIVER_MODULE(nexus_fdt, root, nexus_fdt_driver, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_FIRST); @@ -534,10 +532,8 @@ DEVMETHOD_END, }; -#define nexus_baseclasses nexus_acpi_baseclasses DEFINE_CLASS_1(nexus, nexus_acpi_driver, nexus_acpi_methods, 1, nexus_driver); -#undef nexus_baseclasses EARLY_DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_FIRST); diff --git a/sys/sys/kobj.h b/sys/sys/kobj.h --- a/sys/sys/kobj.h +++ b/sys/sys/kobj.h @@ -107,72 +107,76 @@ */ #define DECLARE_CLASS(name) extern struct kobj_class name -/* - * Define a class with no base classes (api backward-compatible. with - * FreeBSD-5.1 and earlier). - */ +/* [DEPRECATED] */ #define DEFINE_CLASS(name, methods, size) \ DEFINE_CLASS_0(name, name ## _class, methods, size) -/* - * Define a class with no base classes. Use like this: - * - * DEFINE_CLASS_0(foo, foo_class, foo_methods, sizeof(foo_softc)); - */ +/* [DEPRECATED] */ #define DEFINE_CLASS_0(name, classvar, methods, size) \ \ struct kobj_class classvar = { \ #name, methods, size, NULL \ } -/* - * Define a class inheriting a single base class. Use like this: - * - * DEFINE_CLASS_1(foo, foo_class, foo_methods, sizeof(foo_softc), - * bar); - */ +/* [DEPRECATED] */ #define DEFINE_CLASS_1(name, classvar, methods, size, \ base1) \ - \ -static kobj_class_t name ## _baseclasses[] = \ - { &base1, NULL }; \ -struct kobj_class classvar = { \ - #name, methods, size, name ## _baseclasses \ -} + PUBLIC_DEFINE_CLASSN(name, classvar, methods, size, base1) + +/* [DEPRECATED] */ +#define DEFINE_CLASS_2(name, classvar, methods, size, \ + base1, base2) \ + PUBLIC_DEFINE_CLASSN(name, classvar, methods, size, base1, base2) /* - * Define a class inheriting two base classes. Use like this: + * Define a public class inheriting any number (including zero) base + * classes. Use like this: * - * DEFINE_CLASS_2(foo, foo_class, foo_methods, sizeof(foo_softc), - * bar, baz); + * PUBLIC_DEFINE_CLASSN(foo, foo_class, foo_methods, sizeof(foo_softc)[, + * bar[, baz[, foobar]]]); */ -#define DEFINE_CLASS_2(name, classvar, methods, size, \ - base1, base2) \ - \ -static kobj_class_t name ## _baseclasses[] = \ - { &base1, \ - &base2, NULL }; \ -struct kobj_class classvar = { \ - #name, methods, size, name ## _baseclasses \ +#define PUBLIC_DEFINE_CLASSN(_name, classvar, _methods, _size, ...) \ + \ +__VA_OPT__(static kobj_class_t classvar ## _baseclasses[] = { \ + __DEFINE_CLASSN_BASE_EXPANDER0(__VA_ARGS__)NULL }); \ +struct kobj_class classvar = { \ + .name = #_name, \ + .methods = _methods, \ + .size = _size, \ + __VA_OPT__(.baseclasses = classvar ## _baseclasses,) \ } /* - * Define a class inheriting three base classes. Use like this: + * Define a private class inheriting any number (including zero) base + * classes. Use like this: * - * DEFINE_CLASS_3(foo, foo_class, foo_methods, sizeof(foo_softc), - * bar, baz, foobar); + * PRIVATE_DEFINE_CLASSN(foo, foo_class, foo_methods, sizeof(foo_softc)[, + * bar[, baz[, foobar]]]); */ -#define DEFINE_CLASS_3(name, classvar, methods, size, \ - base1, base2, base3) \ - \ -static kobj_class_t name ## _baseclasses[] = \ - { &base1, \ - &base2, \ - &base3, NULL }; \ -struct kobj_class classvar = { \ - #name, methods, size, name ## _baseclasses \ +#define PRIVATE_DEFINE_CLASSN(_name, classvar, _methods, _size, ...) \ + \ +__VA_OPT__(static kobj_class_t classvar ## _baseclasses[] = { \ + __DEFINE_CLASSN_BASE_EXPANDER0(__VA_ARGS__)NULL }); \ +static struct kobj_class classvar = { \ + .name = #_name, \ + .methods = _methods, \ + .size = _size, \ + __VA_OPT__(.baseclasses = classvar ## _baseclasses,) \ } +/* Helper macros for the above, adding ampersands to parent class names */ +#define __DEFINE_CLASSN_BASE_EXPANDER0(base, ...) \ + &base, __VA_OPT__(__DEFINE_CLASSN_BASE_EXPANDER1(__VA_ARGS__)) + +#define __DEFINE_CLASSN_BASE_EXPANDER1(base, ...) \ + &base, __VA_OPT__(__DEFINE_CLASSN_BASE_EXPANDER2(__VA_ARGS__)) + +#define __DEFINE_CLASSN_BASE_EXPANDER2(base, ...) \ + &base, __VA_OPT__(__DEFINE_CLASSN_BASE_EXPANDER3(__VA_ARGS__)) + +#define __DEFINE_CLASSN_BASE_EXPANDER3(base, ...) \ + _Static_assert(false, "Expansion exceeded limit of DEFINE_CLASSN()") + /* * Compile the method table in a class. */