Clang 导入器是 Swift 编译器的一个核心组件,它允许 Swift 代码与 C、C++ 和 Objective-C 代码进行交互。它通过将 Clang(Swift 使用的 C/C++/Objective-C 编译器前端)中的声明导入到 Swift AST 中,使它们可供 Swift 代码使用。本文档描述了 Clang 导入器的架构、核心进程和特殊功能。
有关导入特定 Swift 模块的信息,请参阅 模块系统。有关导入类型如何在 Swift 中表示的详细信息,请参阅 类型系统。
Clang 导入器通过翻译声明并妥善管理其语义,在 Swift 类型系统与 C 家族语言之间架起了桥梁。
来源
Clang 导入器包含几个关键组件
来源
导入过程始于 Swift 代码引用需要导入的 C 家族声明。导入器遵循以下一般步骤:
来源
Clang 导入器维护缓存以避免重复导入相同的声明
来源
Clang 导入器将 Clang 类型映射到等效的 Swift 类型。此过程处理各种特殊情况和类型转换。
下表显示了 Clang 和 Swift 之间常见的类型映射:
| Clang 类型 | Swift 类型 | 备注 |
|---|---|---|
void | Void | 在 Swift 中表示为空元组 () |
bool | Bool | |
char, signed char | CChar | |
unsigned char | CUnsignedChar | |
short | CShort | |
unsigned short | CUnsignedShort | |
int | CInt | |
unsigned int | CUnsignedInt | |
long | CLong | |
unsigned long | CUnsignedLong | |
long long | CLongLong | |
unsigned long long | CUnsignedLongLong | |
浮点数 | CFloat | |
double | CDouble | |
T* | UnsafePointer<T> 或 UnsafeMutablePointer<T> | 取决于 const 限定符 |
const void* | UnsafeRawPointer | |
void* | UnsafeMutableRawPointer | |
id | 任意 | Objective-C 的泛型对象类型 |
NSString* | 字符串 | 桥接类型 |
NSArray* | 数组 | 桥接类型 |
模块 | 带有 @convention(block) 的函数类型 |
来源
来源
Clang 导入器最强大的功能之一是能够自动将 Objective-C 完成处理程序模式转换为 Swift 现代的 async/await 语法。
来源
导入器检测到几种 Objective-C 完成处理程序模式:
具有最后一个名为
completionHandlercompletioncompletionBlockreplyreplyTo的参数的方法
NSError* 参数的块表示 throwsBOOL 或整数结果的块可以表示错误状态来源
名称翻译
| Clang 导入器执行复杂的名称翻译,以将 C/Objective-C 命名约定转换为 Swift 约定。 | C/Objective-C 模式 | 示例 |
|---|---|---|
Swift 转换 | NSUnimportantPrefix | 删除常见前缀 |
| methodWithParam:andOtherParam | 转换为 Swift 方法语法 |
method(withParam:otherParam:) | initWithX | 转换为初始化方法 |
init(x:) | handleWithBlock | 将块转换为尾随闭包 |
handle() { ... } | getProperty | 转换为属性访问 |
property | setProperty | 转换为属性设置器 |
property = ... | kConstant | 常量 |
删除前导 'k' | ABCIDType | 将缩写转换为 camelCase |
来源
Clang 导入器还处理桥接头,允许混合语言项目中的 Swift 代码访问 Objective-C 声明。
来源
Clang 导入器包含健全的错误处理功能,以管理导入过程中可能出现的各种问题。
| 诊断类别 | 描述 | 示例 |
|---|---|---|
| 导入失败 | 无法导入声明 | 类型无法在 Swift 中表示 |
| 不可用 API | 标记为不可用的 API | 已弃用或特定于平台的 API |
| 名称冲突 | 导入后发生命名冲突 | 两个方法导入到相同的 Swift 名称 |
| 类型不匹配 | 类型无法准确映射 | 没有 Swift 等效项的 C++ 模板 |
| 桥接错误 | 桥接头中的错误 | 丢失或无效的桥接头 |
来源
Clang 导入器可以通过多个选项进行配置
来源
Clang 导入器是 Swift 编译器的一个复杂组件,它实现了 Swift 代码与 C、C++ 和 Objective-C 代码之间的无缝互操作。它处理了不同语言范式之间声明、类型和语义映射的复杂任务,使 Swift 开发人员能够使用现有的库和框架。其功能(如 Objective-C API 的自动 async/await 转换)展示了 Swift 即使在处理遗留代码时,也致力于提供现代化、符合人体工程学的接口。