[Pitch] always export entry points in .swiftinterface files

For any entry point/function/property, include an attribute that represents the actual entry point in the compiled library.

Similar to how @_silgen_name can change the entry point name, always put the entry point in the .swiftinterface file.

This will allow easier interoperation with other languages that consume the swiftinterface file and will reduce or eliminate the need for scanning the output library and finding and demangling all the entrypoints to correlate with the .swiftinterface file or mangling the entry points and trying to find matches.

1 Like

By "entry point" do you mean the linker symbols associated with declarations?

If so, @kubamracek's Low-level linkage control pitch from a few weeks ago, and the discussion in that thread about representing the different symbols associated with declarations, is probably relevant here. Swift declarations in general are not necessarily associated with just one linker symbol; there can be many symbols for many different purposes that would have to be enumerated in order to provide full coverage of the possible symbols that would be needed in order to support interoperation with other languages.

That's quite a rabbit hole of a discussion, still, it strikes me as reasonable to do this. The alternative for code that does static analysis or other similar tasks is significant amount of onerous work that has already been done by the compiler.

“Entry point” is weirdly privileging functions as far as Swift goes. I can’t imagine static analysis that wants to know the high-level definitions of function symbols but doesn’t care about types. You should, in fact, be consuming swiftinterface files using the same libraries as SourceKit; their entire validity is predicated on source stability and using Swift syntax as the canonical way to describe a library.

Now, I think it’s totally valid to say SourceKit and indexstore aren’t providing the tools you need. But trying to parse swiftinterface files without them is equivalent to keeping up with a huge portion of the Swift surface language, by design, and no amount of “here’s the symbol used for this, here’s the layout used for that” is going to change that as long as types are still spelled like they are in source.

EDIT: I realize this is coming off as harsh. But at the moment, it is not a project goal for swiftinterface files to be consumed by other languages; the way to interoperate with other languages is C and C++. If that is to change, then yes, it might make sense for swiftinterface files or something similar to provide more direct information about how to interoperate with Swift. But, well, there’s a reason Swift embeds Clang to interoperate with C and C++: interoperation does mean doing all the work the native compiler does. You can’t avoid that.


Yeah, I think instead of attempting to extend swiftinterface files to make them easier to consume directly, a better long-term goal is Implementing parts of the Swift compiler in Swift: semantic analysis should eventually be implemented in the form of reusable libraries, like swift-syntax already is today.


The reusable library approach that Slava alludes to is definitely what I'd want to see long term. Short term, though, maybe it would be reasonable to add a new swift-frontend action that can emit the necessary module information in a structured format suitable for other compilers and tools to consume.


I mean, I already have a working .swiftinterface parser and a working demangler. I use the parser to give me a structured look at the API surface of a swift module and the demangler to give me all the entry points and a chunk of code that puts the two together so that for any type/function, I can find the symbols that represent the entry points, type metadata, value witness tables, protocol witness tables, forwarders, thunks, etc. One possible option is to find a way to remove the demangling and correlation steps, which becomes much easier if the actual symbols are in the swiftinterface file.

Looking at the @linkage proposal, I see that there are two ways to view the attribute: assertion and information (ie, write and read). If it's in a .swift file, it's an assertion. If it's in a .swiftinterface file, it's informational.
That there can be multiple symbols associated with any given code structure is a good thing. Especially when you could have things like:

@linkage (class=metadata, symbol="$SMT....")
@linkage (class=full-typemetadata, symbol = "...")
@linkage (class=value-witnesstable, symbol="...")
@linkage (class=protocol-witness-table, with-respect-to="SomeProtocol", symbol="")
public struct Foo : SomeProtocol {
    @linkage (class=getter, symbol="...")
    @linkage (class=setter, symbol="...")
    public var Item { get; set }

In no way is this meant to be an exhaustive example, but something akin to this would make my life so much easier.

Outside of my own domain, which is to provide interoperation with other languages, you could also see the same information being useful for automated mocking, writing code shims for telemetry etc.

1 Like