Formalizing @cdecl

It's also important to note that this attribute serves two purposes. 1. To change the linkage name of a Swift function (must include body) 2. To define an external Swift function to be used within the current context (must not include function body).

// This represents number 1, where this function is lowered as
// hello with no mangling whatsoever in the binary.
@_silgen_name("hello")
func goodbye() {
  print("hello")
}

// This represents number 2. We know that in this binary there is
// a function named hello (the one we just defined up top), so define
// a function prototype that calls said method. Super important to note
// that this defines an external SWIFT function, thus it'll call the function
// using the Swift calling convention, not the C calling convention.
//
// This is similar to the following C code (if it were valid):
//
// extern "Swift" void hello();
//
@_silgen_name("hello")
func hello()

// From Swift, we call number 1 as the name in the function, not the linkage
// name.
goodbye() // hello

// This calls the second function we defined with using number 2.
hello() // hello

So I'm of the camp that this attribute needs to separate into two separate attributes, one for each purpose. We can define something like @link_name("") to achieve the desired result you're looking for, and we can define something like @extern for the second purpose. I think it'd also be interesting if we could do something like @extern(c) to define external C functions within Swift so that we don't have to go through a shim header, but that's derailing off topic :slight_smile: