菜单

Clang 导入器

相关源文件

Clang 导入器是 Swift 编译器的一个核心组件,它允许 Swift 代码与 C、C++ 和 Objective-C 代码进行交互。它通过将 Clang(Swift 使用的 C/C++/Objective-C 编译器前端)中的声明导入到 Swift AST 中,使它们可供 Swift 代码使用。本文档描述了 Clang 导入器的架构、核心进程和特殊功能。

有关导入特定 Swift 模块的信息,请参阅 模块系统。有关导入类型如何在 Swift 中表示的详细信息,请参阅 类型系统

架构概述

Clang 导入器通过翻译声明并妥善管理其语义,在 Swift 类型系统与 C 家族语言之间架起了桥梁。

来源

核心组件

Clang 导入器包含几个关键组件

  1. ClangImporter:用于导入 Clang 模块的公共接口
  2. ClangImporter::Implementation:处理实际导入逻辑的内部实现
  3. Clang 实例:用于解析和分析 C 家族代码的 Clang 编译器实例
  4. 导入表:缓存导入声明和类型的各种查找表
  5. 名称映射:用于将 C 家族名称转换为 Swift 友好名称的逻辑

来源

导入流程

导入过程始于 Swift 代码引用需要导入的 C 家族声明。导入器遵循以下一般步骤:

  1. 查找要导入的 Clang 声明
  2. 根据命名约定和属性确定适当的 Swift 名称
  3. 创建相应的 Swift 声明,并包含适当的类型
  4. 处理 C 函数、Objective-C 方法等特殊情况
  5. 缓存导入的声明以供将来查找

来源

声明缓存

Clang 导入器维护缓存以避免重复导入相同的声明

来源

类型导入

Clang 导入器将 Clang 类型映射到等效的 Swift 类型。此过程处理各种特殊情况和类型转换。

类型映射

下表显示了 Clang 和 Swift 之间常见的类型映射:

Clang 类型Swift 类型备注
voidVoid在 Swift 中表示为空元组 ()
boolBool
char, signed charCChar
unsigned charCUnsignedChar
shortCShort
unsigned shortCUnsignedShort
intCInt
unsigned intCUnsignedInt
longCLong
unsigned longCUnsignedLong
long longCLongLong
unsigned long longCUnsignedLongLong
浮点数CFloat
doubleCDouble
T*UnsafePointer<T>UnsafeMutablePointer<T>取决于 const 限定符
const void*UnsafeRawPointer
void*UnsafeMutableRawPointer
id任意Objective-C 的泛型对象类型
NSString*字符串桥接类型
NSArray*数组桥接类型
模块带有 @convention(block) 的函数类型

来源

类型导入过程

来源

特殊功能

Objective-C 到 Swift 异步转换

Clang 导入器最强大的功能之一是能够自动将 Objective-C 完成处理程序模式转换为 Swift 现代的 async/await 语法。

来源

完成处理程序检测

导入器检测到几种 Objective-C 完成处理程序模式:

  1. 具有最后一个名为

    • completionHandler
    • completion
    • completionBlock
    • reply
    • replyTo
  2. 的参数的方法

    • 带有已知错误模式的块参数
    • 带有 NSError* 参数的块表示 throws
    • 具有 BOOL 或整数结果的块可以表示错误状态

来源

test/IDE/print_clang_objc_async.swift13-67

名称翻译

Clang 导入器执行复杂的名称翻译,以将 C/Objective-C 命名约定转换为 Swift 约定。C/Objective-C 模式示例
Swift 转换NSUnimportantPrefix删除常见前缀
NSStringStringmethodWithParam:andOtherParam转换为 Swift 方法语法
method(withParam:otherParam:)initWithX转换为初始化方法
init(x:)handleWithBlock将块转换为尾随闭包
handle() { ... }getProperty转换为属性访问
propertysetProperty转换为属性设置器
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 即使在处理遗留代码时,也致力于提供现代化、符合人体工程学的接口。