I think we should provide this functionality somehow, but I'm uncomfortable with a few aspects of the design.
"Demangle" is a weird word, but it is a single-word name being given to a very esoteric Swift-internal function in the standard library. Although it's definitely not as bad as Perl 5 giving dump()
to a function that causes the process to dump core, I'm uncomfortable with the similarities they do have. I think I would be happier with this if it had a more complicated name that made its uses more clear, like demangle(swiftSymbolName:)
.
For inputs, we've talked in the past about having an UnsafeString
type. Once we have that, would we wish we had designed this with only UnsafeString
as an input, instead of having String
and UnsafeBufferPointer<Int8>
variants?
For outputs, I wonder if a TextOutputStreamable
variant might be helpful; after all, we imagine logging these things to be a major use case.
Given the matrix of inputs and outputs, it might make sense to actually think of this as a type instead of a function:
public struct SwiftSymbol {
// These initializers try to demangle with an empty buffer so they can check validity
// and fill in `requiredCapacity`.
public init?(mangledName: String)
public init?(mangledName: UnsafeBufferPointer<Int8>) // or UnsafeString?
// This is set by the initializers when they do their validity
// checks.
public let requiredCapacity: Int
}
extension SwiftSymbol {
// This no longer needs an error return--it just fits what it
// can into the buffer; you can presize the buffer with
// `requiredCapacity` if you want to be sure the whole thing
// will fit.
public func demangle(into buffer: UnsafeBufferPointer<Int8>)
}
extension SwiftSymbol: TextOutputStreamable {
public func write<Stream: TextOutputStream>(to stream: inout Stream)
}
extension SwiftSymbol: CustomStringConvertible {
// This is how you'd get a plain string out of the demangler.
public var description: String { get }
}
This design should be easier to use and is namespaced better, but it does force two runtime calls, which isn't the best.
In shortā¦I dunno, this doesn't feel right yet. I'm tempted to say we should add the runtime entry point but not expose it in the language until we have more comprehensive reflection facilities, but that's really just punting.
One non-wishy-washy bit of feedback: The overloads that use UnsafeBufferPointer
as either inputs or outputs need to document their behavior very specifically. For example, is the output buffer null-terminated? Is it null-terminated even when truncated? This needs to be laid out in the documentation comments, not just the proposal text.