I'm trying to parse the type metadata for a struct, to extract the fields with the types. I'm aware of libraries that do this, but I want to understand it myself, for a combination of educational purposes and keeping dependencies of the thing I'm working on to a minimum. I'm working off of code in the compiler like this to understand the ABI, since the documentation is out of date and inaccurate.
My end goal is to get an array [(String, Any.Type)
, where the string is the field name and the type is the the type of the field.
Say that I have the following struct:
struct S {
let subtitle: Subtitle // a struct declared in my executable
let name: (Int, Int)
let title: String
let bc2: Bool
let b3: BigTypeName // a struct declared in my executable
}
Note that the first and last types are my own, while the ones in the middle are built in Swift types. The output from the compiler includes a bunch of references to the fields, which I can see by running nm
on my binary:
0000000100003b44 s _symbolic _____ 12MetadataTest8SubtitleV
0000000100003b4a s _symbolic Si_Sit
0000000100003b52 s _symbolic SS
0000000100003b56 s _symbolic Sb
0000000100003b5a s _symbolic _____ 12MetadataTest11BigTypeNameV
So nm
is able to understand what the mangled names of the two custom types are. I can see in the compiler source that a relative pointer (presumable direct) is stored for each field type.
When I run my code, the output is this:
[("\u{01}7\u{02}", "subtitle"), ("Si_Sit", "name"), ("SS", "title"), ("Sb", "bc2"), ("\u{01}5\u{02}", "b3")]
As you can see, my types are... something, while the Swift types are something that _typeByName()
understands and can produce the appropriate Any.Type
. I'm not sure if this is the name mangled version of those types, but it would make sense.
So, what is "\u{01}7\u{02}"
? Is it an offset? Any suggestions would be incredibly helpful.