dan-zheng
(Dan Zheng)
1
I have some questions about mangling, specifically about function type mangling.
Looking at Mangling.rst, I noticed that function types are mangled with one "kind" modifier:
// From Mangling.rst:
type ::= function-signature 'c' // function type (escaping)
type ::= function-signature 'X' FUNCTION-KIND // special function type
FUNCTION-KIND ::= 'f' // @thin function type
FUNCTION-KIND ::= 'U' // uncurried function type (currently not used)
FUNCTION-KIND ::= 'K' // @auto_closure function type (noescape)
FUNCTION-KIND ::= 'B' // objc block function type
FUNCTION-KIND ::= 'L' // objc block function type (escaping) (DWARF only; otherwise use 'B')
FUNCTION-KIND ::= 'C' // C function pointer type
FUNCTION-KIND ::= 'A' // @auto_closure function type (escaping)
FUNCTION-KIND ::= 'E' // function type (noescape)
However, in practice, function types can have many modifiers. Some information about modifiers may be lost during mangling.
// The type of `f` has multiple modifiers.
func foo(_ f: @convention(c) @autoclosure () -> Void) -> Void {}
$ swiftc -emit-silgen mangle.swift
// foo(_:)
sil hidden [ossa] @$s6mangle3fooyyyyXCF : $@convention(thin) (@convention(c) @noescape () -> ()) -> () {
...
}
$ swift-demangle s6mangle3fooyyyyXCF
$s6mangle3fooyyyyXCF ---> mangle.foo(@convention(c) () -> ()) -> ()
// Lost information about `@noescape` and `@autoclosure`.
Questions:
- What is the significance of type mangling? Is it used by tools like LLDB to show the types of variables when debugging?
- Is it desirable/important to accurately mangle all modifiers for a function type? Mangling semantically-impactful modifiers seems more important than less impactful modifiers (e.g.
@convention(c) may be heavier than @noescape).
dan-zheng
(Dan Zheng)
2
Context: I started a patch to implement type mangling for @differentiable functions, and noticed that the current mangling scheme leads to an explosion of function type modifier combinations.
A more flexible scheme could encode multiple modifiers. Sketch:
// Old: modifier is coupled with function type.
// Some modifier information is lost.
kind=ThinFunctionType
kind=ArgumentTuple
kind=Type
kind=Structure
kind=Module, text="Swift"
kind=Identifier, text="Float"
kind=ReturnType
kind=Type
kind=Structure
kind=Module, text="Swift"
kind=Identifier, text="Float"
// New: modifiers are in a separate list.
// Modifier list can be run-length encoded, possibly in a
// backwards-compatible way.
kind=FunctionType
kind=FunctionTypeModifiers
kind=ThinFunction
kind=EscapingFunction
kind=DifferentiableFunction
kind=ArgumentTuple
kind=Type
kind=Structure
kind=Module, text="Swift"
kind=Identifier, text="Float"
kind=ReturnType
kind=Type
kind=Structure
kind=Module, text="Swift"
kind=Identifier, text="Float"
But I'm not sure about the use cases for mangling. If mangling modifiers isn't important, then I suppose there's no need for a more flexible scheme.
jrose
(Jordan Rose)
3
I'm not an expert, but there are a few things to remember.
-
Mangling must uniquely distinguish overloadable declarations in any ways they can be overloadable, since it's used for symbol names, indexing, and compact references to entities at runtime.
-
Mangling of existing decls must be stable across changes to other decls (library evolution) and changes to the compiler (ABI stability) when compiling with -enable-library-evolution. (Therefore you can't say "oh, this has no overloads, so I'm going to give it a simpler mangling. This comes up sometimes.)
-
Mangling is used by LLDB to describe types, but I forget how. :-/
Mangling is used to disambiguate overloads, to construct runtime metadata and to show types in lldb as you suggest.
Since @convention(c) functions do not have a context, escaping/noescape has no significance in the type system. However, not being able to express @convention(c) @autoclosure is a bug, albeit one that has no practical consequences. Perhaps we should not allow @convention(foo) @autoclosure at all. Do you mind filing a bug so that we can revisit this some day?
dan-zheng
(Dan Zheng)
5
Thanks for the swift replies! The purpose of mangling makes sense.
Some concrete follow-up questions:
- Is it worth pursuing a more flexible scheme for mangling a list of function type modifiers? And is it possible to do so in a backwards-compatible way? Please see my post above.
- Regarding
@differentiable functions: which @differentiable + @xxx modifier combinations would you recommend mangling in the current scheme?
Filed SR-11027! @convention(c) @autoclosure actually crashes today.