[clang] [WebKit Checkers] Recognize Objective-C and CF pointer conversion functions. (PR #132784)
Ryosuke Niwa via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 27 13:48:02 PDT 2025
================
@@ -273,11 +279,148 @@ inline CFTypeRef bridge_cast(NSObject *object)
return (__bridge CFTypeRef)object;
}
+template <typename ExpectedType>
+struct ObjCTypeCastTraits {
+public:
+ static bool isType(id object) { return [object isKindOfClass:[ExpectedType class]]; }
+
+ template <typename ArgType>
+ static bool isType(const ArgType *object) { return [object isKindOfClass:[ExpectedType class]]; }
+};
+
+template <typename ExpectedType, typename ArgType>
+inline bool is_objc(ArgType * source)
+{
+ return source && ObjCTypeCastTraits<ExpectedType>::isType(source);
+}
+
+template<typename T> inline T *checked_objc_cast(id object)
+{
+ if (!object)
+ return nullptr;
+
+ if (!is_objc<T>(object))
+ WTFCrash();
+
+ return reinterpret_cast<T*>(object);
+}
+
+template<typename T, typename U> inline T *checked_objc_cast(U *object)
+{
+ if (!object)
+ return nullptr;
+
+ if (!is_objc<T>(object))
+ WTFCrash();
+
+ return static_cast<T*>(object);
+}
+
+template<typename T, typename U> RetainPtr<T> dynamic_objc_cast(RetainPtr<U>&& object)
+{
+ if (!is_objc<T>(object.get()))
+ return nullptr;
+ return adoptNS(static_cast<T*>(object.leakRef()));
+}
+
+template<typename T> RetainPtr<T> dynamic_objc_cast(RetainPtr<id>&& object)
+{
+ if (!is_objc<T>(object.get()))
+ return nullptr;
+ return adoptNS(reinterpret_cast<T*>(object.leakRef()));
+}
+
+template<typename T, typename U> RetainPtr<T> dynamic_objc_cast(const RetainPtr<U>& object)
+{
+ if (!is_objc<T>(object.get()))
+ return nullptr;
+ return static_cast<T*>(object.get());
+}
+
+template<typename T> RetainPtr<T> dynamic_objc_cast(const RetainPtr<id>& object)
+{
+ if (!is_objc<T>(object.get()))
+ return nullptr;
+ return reinterpret_cast<T*>(object.get());
+}
+
+template<typename T> T *dynamic_objc_cast(NSObject *object)
+{
+ if (!is_objc<T>(object))
+ return nullptr;
+ return static_cast<T*>(object);
+}
+
+template<typename T> T *dynamic_objc_cast(id object)
+{
+ if (!is_objc<T>(object))
+ return nullptr;
+ return reinterpret_cast<T*>(object);
+}
+
+template <typename> struct CFTypeTrait;
+
+template<typename T> T dynamic_cf_cast(CFTypeRef object)
+{
+ if (!object)
+ return nullptr;
+
+ if (CFGetTypeID(object) != CFTypeTrait<T>::typeID())
+ return nullptr;
+
+ return static_cast<T>(const_cast<CF_BRIDGED_TYPE(id) void*>(object));
+}
+
+template<typename T> T checked_cf_cast(CFTypeRef object)
+{
+ if (!object)
+ return nullptr;
+
+ if (CFGetTypeID(object) != CFTypeTrait<T>::typeID())
+ WTFCrash();
+
+ return static_cast<T>(const_cast<CF_BRIDGED_TYPE(id) void*>(object));
+}
+
+template<typename T, typename U> RetainPtr<T> dynamic_cf_cast(RetainPtr<U>&& object)
+{
+ if (!object)
+ return nullptr;
+
+ if (CFGetTypeID(object.get()) != CFTypeTrait<T>::typeID())
+ return nullptr;
+
+ return adoptCF(static_cast<T>(const_cast<CF_BRIDGED_TYPE(id) void*>(object.leakRef())));
}
+} // namespace WTF
+
+#define WTF_DECLARE_CF_TYPE_TRAIT(ClassName) \
+template <> \
+struct WTF::CFTypeTrait<ClassName##Ref> { \
+ static inline CFTypeID typeID(void) { return ClassName##GetTypeID(); } \
+};
+
+WTF_DECLARE_CF_TYPE_TRAIT(CFArray);
+WTF_DECLARE_CF_TYPE_TRAIT(CFDictionary);
+
+#define WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT(ClassName, MutableClassName) \
+template <> \
+struct WTF::CFTypeTrait<MutableClassName##Ref> { \
+ static inline CFTypeID typeID(void) { return ClassName##GetTypeID(); } \
+};
+
+WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT(CFArray, CFMutableArray);
+WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT(CFDictionary, CFMutableDictionary);
+
using WTF::RetainPtr;
using WTF::adoptNS;
using WTF::adoptCF;
using WTF::retainPtr;
using WTF::downcast;
using WTF::bridge_cast;
+using WTF::is_objc;
+using WTF::checked_objc_cast;
+using WTF::dynamic_objc_cast;
+using WTF::checked_cf_cast;
+using WTF::dynamic_cf_cast;
----------------
rniwa wrote:
oh yeah, indeed, I'm missing `bridge_cast` and `bridge_id_cast`.
https://github.com/llvm/llvm-project/pull/132784
More information about the cfe-commits
mailing list