SE-0492 added @section, but didn't support it on functions. This example is from its Future Directions:
// code for the function is placed into the custom section
@section("__TEXT,boot")
func firmwareBootEntrypoint() { ... }
We do need @section support on functions in the embedded space. I've written up a proposal to add it. It's mostly straightforward, but does introduce some inference rules involving accessors and closures.
This looks great and fills an important gap. Some initial thoughts:
It's not explicitly mentioned in the proposal (perhaps because it's obvious), but I'm assuming that for an async function, the attribute applies to all of the await/suspend partial thunks that get generated for a single function?
SE-0492 forbids @section on members inside generic contexts. Does that limitation apply here as well?
Today, @section can't be applied to an extension. Would it be prudent to allow that as a convenience shortcut to apply to all of the declarations in that extension? (Alternatively/in addition, would it make sense to allow it on a main type declaration?)
Do we need a way to put the real main entry point in a different section? If we have this:
IIUC this actually generates three symbols: main, which calls M.App.$main, which calls M.App.main. The @section attribute would presumably apply to the last one, but what about the other two? Would the attribute propagate to those?
I'm not sure if the embedded platforms this is targeted at actually use main vs. some other custom exported named symbol, but it could be a potential gap compared to C where you can trivially write __attribute__((section("..."))) int main(...).
There are a lot of other synthesized functions in Swift that we can't express this attribute on without having to give up the synthesis; for example, if I wanted to put the synthesized Equatable.==/Hashable.hash(into:) into a custom section. But I guess that's not a problem that this proposal needs to solve, because it applies to really all attributes—I can't make those @export(interface|implementation) either without writing the whole implementation out, and other attributes also seem like they'd be useful.
To think ahead and aloud, I wonder if there's room to adapt the attributed conformance syntax to apply to synthesized members like struct S: @section("whatever") Equatable or struct S: @export(interface) Equatable or if that's a bridge too far...
I see no reason not to allow this sort of thing, but we should make it clear in the proposal what calling conventions can be used. For instance, can @convention(c) be used? Can @objc @implementation? @convention(thick) doesn't make a whole lot of sense as there would be no context pointer, but @convention(thin) ought to work, yes? (etc. etc. etc.)
Yes, and I've added a statement to that effect to the proposal.
No, it does not. That limitation for variables is because in the cases that are prohibited, there's no actual data in the data segment. For functions, there's always an implementation there, so it works just as well for generic functions (or methods of generic types) as it does for non-generic ones. I've updated the proposal to call this out.
I don't think it does make sense because of the data/function section split. We wouldn't want the @section on the extension to put a TEXT-focused @section onto a static variable, or a DATA-focused @section on to a method.
Same issue as for extension, although this highlights something I hadn't thought through. We will emit some type metadata symbols, and potentially some type metadata accessor functions, and we don't have a way to put those into specific data or text sections. I'm not sure how much that matters given that they are small and fairly rare in embedded swift where this matters most.
This is a good point! I've added it in the same place as all of the various partial functions for async. (I am certain my implementation fails to cover this)
Sometimes it's a differently-named function that's similar to main, and there's a compiler flag (-entry-point-function-name) to override the name at compile time. It's not handled well.
Right. You have to explicitly declare the thing to customize it.
We would again run into the issue where some of the symbols associated with a conformance are data (the witness table) and some are functions (witnesses & instantiation functions). Perhaps we will have to grow some syntax in section that allows one to specify both a data section and a function section on the same declaration to cover all of the cases. At the risk of being right back here in 6 months having to add that feature because we realize that it was actually important, I'd rather keep that as a future direction.
As for attributes on conformances... I think it's a good idea for a number of attributes. Right now, we look to the extension or type where the conformance is declared for things like @available and @export(interface), and have carved out a small number of attributes like @unsafe that fit there. I think it would be beneficial to take a sweep through all of the attributes in the language to figure out which ones make sense on conformances and allow them. That doesn't feel like this proposal, though.
I think all calling conventions are fine, here. We're just dealing with the section into which the code is emitted; it doesn't matter what the parameters are.
As an aside, it occurs to me that if SE-0478 is accepted in some form, then default would also be tempting for the same reasons, but would have the same issues.