+#if defined(__clang__) && defined(__cplusplus)
+#define __MISMATCH_TAGS_PUSH \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wmismatched-tags\"")
+#define __MISMATCH_TAGS_POP \
+ _Pragma("clang diagnostic pop")
+#else
+#define __MISMATCH_TAGS_PUSH
+#define __MISMATCH_TAGS_POP
+#endif
+
+/*!
+ * Ensures that these macros can safely be used in structs when compiling with
+ * clang. The macros do not allow for nullability attributes to be specified due
+ * to how they are expanded. For example:
+ *
+ * SLIST_HEAD(, foo _Nullable) bar;
+ *
+ * expands to
+ *
+ * struct {
+ * struct foo _Nullable *slh_first;
+ * }
+ *
+ * which is not valid because the nullability specifier has to apply to the
+ * pointer. So just ignore nullability completeness in all the places where this
+ * is an issue.
+ */
+#if defined(__clang__)
+#define __NULLABILITY_COMPLETENESS_PUSH \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wnullability-completeness\"")
+#define __NULLABILITY_COMPLETENESS_POP \
+ _Pragma("clang diagnostic pop")
+#else
+#define __NULLABILITY_COMPLETENESS_PUSH
+#define __NULLABILITY_COMPLETENESS_POP
+#endif
+
+/*
+ * Singly-linked List declarations.
+ */
+#define SLIST_HEAD(name, type) \
+__MISMATCH_TAGS_PUSH \
+__NULLABILITY_COMPLETENESS_PUSH \
+struct name { \
+ struct type *slh_first; /* first element */ \
+} \
+__NULLABILITY_COMPLETENESS_POP \
+__MISMATCH_TAGS_POP
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define SLIST_ENTRY(type) \
+__MISMATCH_TAGS_PUSH \
+__NULLABILITY_COMPLETENESS_PUSH \
+struct { \
+ struct type *sle_next; /* next element */ \
+} \
+__NULLABILITY_COMPLETENESS_POP \
+__MISMATCH_TAGS_POP
+