什么是Swift语言中的'@_silgen_name'?

Seu*_*Lee 12 darwin swift

在Swift 2.2中阅读Darwin库时,我发现下面的代码.

@warn_unused_result
@_silgen_name("_swift_Darwin_sem_open2")
internal func _swift_Darwin_sem_open2(
  name: UnsafePointer<CChar>,
  _ oflag: CInt
) -> UnsafeMutablePointer<sem_t>
Run Code Online (Sandbox Code Playgroud)

第二行的'@_silgen_name'是什么?

我从这里找到了以下信息,但我想要更多详细信息,比如Apple Developer Library.

如果它只是您要从C调用的一组特定Swift函数,则可以使用@_silgen_name属性覆盖损坏的名称,和/或使它们@convention(c)使用C调用约定.

dfr*_*fri 17

@_silgen_name最近刚刚使用以下提交消息重命名@asmname(请参阅以下提交):

这反映了这样的事实:该属性仅用于编译器内部使用,并且实际上并不等同于C的asm属性,因为它不会将调用约定更改为C兼容.

因此,作为一般的Swift开发人员,除非使用Swift移植到其他平台,否则不会遇到此属性.

现在,@_silgen_nameSILGenNameAttr具有某些选项的类的属性(宏),其中后者是Swifts 抽象语法树(AST)的一部分.从swift/AST/Attr.def源代码(另请参见swift/lib/AST/Attr.cpp)

// Schema for DECL_ATTR:
//
// - Attribute name.
// - Class name without the 'Attr' suffix (ignored for
// - Options for the attribute, including:
//    * the declarations the attribute can appear on
//    * whether duplicates are allowed
//    * whether the attribute is considered a decl modifier or not (no '@')
// - Unique attribute identifier used for serialization.  This
//   can never be changed.
//
// SIMPLE_DECL_ATTR is the same, but the class becomes
// SimpleDeclAttr<DAK_##NAME>.
//

DECL_ATTR(_silgen_name, SILGenName,
          OnFunc | OnConstructor | OnDestructor | LongAttribute |
          UserInaccessible, 0)
Run Code Online (Sandbox Code Playgroud)

我们SILGeneNameAttrswift/AST/Attr.h中找到声明:

/// Defines the @_silgen_name attribute.
class SILGenNameAttr : public DeclAttribute {
public:
  SILGenNameAttr(StringRef Name, SourceLoc AtLoc, SourceRange Range, bool Implicit)
    : DeclAttribute(DAK_SILGenName, AtLoc, Range, Implicit),
      Name(Name) {}

  SILGenNameAttr(StringRef Name, bool Implicit)
    : SILGenNameAttr(Name, SourceLoc(), SourceRange(), /*Implicit=*/true) {}

  /// The symbol name.
  const StringRef Name;

  static bool classof(const DeclAttribute *DA) {
    return DA->getKind() == DAK_SILGenName;
  }
};
Run Code Online (Sandbox Code Playgroud)

总结一下; 它与为C函数提供Swift接口有关.您很可能很难SILGenNameAttr在开发人员库中找到任何有关详细信息,并且可以将其视为未记录的功能.


最后,您可能会对以下与Russ Bishop的谈话感兴趣:

工具箱:这里有龙(34:20)

在任何情况下,我都不会在生产应用程序中发送此信息.但如果你有冒险精神的话,他们就是这样.

@asmname是一个装饰函数的属性.你肯定需要了解ABI来使用这个.斯威夫特不会帮助你很好地编制参数.编译器不会非常宽容,因此您必须确保已将参数操作为与其兼容的格式.以下代码显示了如何声明它.给出函数属性,@asmname和字符串符号; 然后在返回类型中运行其参数.如果您的参数错误或返回类型不正确,编译器不会抱怨.它只期望该符号存在,当它跳转到它时,它最好采用这些参数并具有该返回类型.

@asmname("dispatch_get_current_queue") func _get_current_queue() -> dispatch_queue_t
Run Code Online (Sandbox Code Playgroud)

问答(37:08)

:显然,Apple并未记录所有这些内容,那么您发现所有这些行为的过程是什么?

Russ:我先看一下文档,但你说的很多东西都没有.如果你去Swift REPL并使用标志 - 我认为它就像 -deprecated-integrated-repl- 你可以要求它打印Swift模块和Xcode没有显示的所有位.如果你深入到工具链目录Xcode,你也可以在libswiftCore和libswiftRuntime中找到东西.

JP:如果你对使用Swift做一些不安全的事情感兴趣,你可以在GitHub @asmname和语言"Swift"中进行代码搜索,你会看到一堆非常糟糕但有趣的东西.

来自Bishops博客的一篇略微更老的帖子:

...

首先注意@asmname属性.这相当于 DllImportextern.它告诉Swift我们将在某个库中链接,该库定义具有给定名称的函数并匹配给定的参数."只要相信我斯威夫特,我知道我在做什么".提示:你最好知道自己在做什么.