Extend APINotes to support always importing C pointers as OpaquePointer

In the Android workgroup we are currently looking at bringing the Android SDK minimum API level down from 28 to 24 or 23.

One of the "annoying" things about Android API 23, is specifically a difference in the stdio.h header file. The linked conditional import, makes FILE* import as UnsafeMutablePointer<FILE> on API 23 and OpaquePointer on API 24+.

This difference means that any libraries that explicitly type the FILE* pointer, like swift-log does, would not compile on API 23.

#if canImport(WASILibc) || os(Android) 
 internal typealias CFilePointer = OpaquePointer 
 #else 
 internal typealias CFilePointer = UnsafeMutablePointer<FILE> 
 #endif 

There are solutions, like a C shim or using closures to hide the type. However, this is something that each library that needs the type FILE* has to do.

It would be nice if we could have some sort of unified solution in the compiler/stdlib to fix this issue. One of the ideas that has been brought up, is the use of APINotes.

However, I could not get the current features of APINotes to change the imported type of FILE*, but please correct me if I am wrong. The only possible way, is that we would have to redefine all the NDK function headers that use FILE* using APINotes.

Extending SwiftImportAs

My proposal is that we extend the SwiftImportAs API note with an opaque_pointer type, such that we can change the way we import any C structs. This would allow us to unify the imported type of FILE* on Android, like so:

     Tags:
       - Name: __sFILE
         SwiftImportAs: opaque_pointer

That would mean we would have to extend swiftlang/llvm-project to apply something like __attribute__((swift_attr("import_pointer_as_opaque"))) when that API note is present, and the ClangImporter in the compiler to respect this attribute.

Before I endeavor on implementing this, I just wanted to make sure people think this is the right direction to head or we should pursue another direction than extending API notes?

Thanks!

5 Likes