undefined reference to `_D16TypeInfo_HAyayAa6__initZ'

Adam D. Ruppe destructionator at gmail.com
Sat Nov 23 19:41:09 PST 2013


On Sunday, 24 November 2013 at 00:14:22 UTC, Jeroen Bollen wrote:
> Does yHAyaAa mean:
>
>> immutable (immutable char)[char[]]

Looks like you got the key and value backwards there and missed 
an 'A' too (I was just writing about this on SO too, but the 
comment limit meant I cut a bit short there).

You're right about the outer immutable, the first 'y'. Then 'H' 
is assoc array. Then you read the next type as the key: 'Aya', 
which is array of immutable char, or immutable(char)[]. ('Aya' is 
one you'll see a lot in mangles, since it means string. recall 
that string is just an alias for immutable(char)[].)

Then, you read the value type, 'Aa', which is indeed array of 
char, aka char[].


Putting it together:

we have an immutable associative array ('yH')
key type: immutable(char)[] (or string) ('Aya')
value type: char[] ('Aa')

most likely written in the code as:
immutable char[][string]




There really shouldn't be a reason to do this by hand, though it 
can be useful to recognize the patterns by eyeball, when 
debugging and such. core.demangle, or the ddemangle included in 
the dmd distribution, generally do a good job with these, so when 
in doubt, you can just paste the mangled name into them. There's 
just a few cases it doesn't handle:


There's some mangled names that cannot be demangled. dmd can 
generate some *really* long names, including some that optlink 
can't. The solution to that dilemma is if a name is too long (128 
chars), it first tries to do a simple compression on it. This 
replaces long subsequences with a length-offset pair. Potentially 
readable by a computer, but would be a pain to do by hand. You'd 
recognize these if the name has non-ascii characters.

Then, if it is still too long, the end gets chopped off and 
replaced with a partial MD5 sum instead. Since md5 sums are a 
one-way hash, not even a bug-free demangle program would reliably 
be able to understand these.


I think the reason that "_D16TypeInfo_HAyayAa6__initZ" couldn't 
get automatically demangled is because it is a special name that 
doesn't actually follow the ABI spec. It's compiler generated 
info whose mangle looks kinda like a function, but it lacks the 
calling convention or return value that core.demangle requires to 
be there to consider a valid name.

http://dlang.org/abi.html

Let's go ahead and add that info though. A fully mangled name 
starts with "_D", then has the name with all scope info. The way 
this is encoded is simply length of piece, string name, repeat 
for all pieces. So "foo.bar" becomes "3foo3bar".

Then, the type is encoded, as we discussed above. The typeinfo 
name is closest to a function: 'Z' near the end terminates the 
argument list... but the spec says a function type mangle should 
first have given a calling convention, and at the end, given a 
return type of the function.

'F' means function with D calling convention. We'll put that at 
the end of the name, right before the 'Z':

"_D16TypeInfo_HAyayAa6__initFZ"

then the spec says return value goes at the very end. Let's use 
'v' for void:

"_D16TypeInfo_HAyayAa6__initFZv"


Does ddemangle accept it?

$ echo "_D16TypeInfo_HAyayAa6__initFZv" | ./ddemangle
void TypeInfo_HAyayAa.__init()


Yes, it did! Why, then is there still 'HAyayAa' in there? The 
reason is that's actually the internal name of the TypeInfo 
class, so strictly speaking, it is correct to demangle it to this.

Pop open dmd2/src/druntime/src/rt/typeinfo/ty_int.d for example. 
In that file, you'll see:

"class TypeInfo_i : TypeInfo"

Try ti_void.d in the same file, and you'll see:

"class TypeInfo_v : TypeInfo"

all the names in those files follow the same pattern: create a 
subclass of Typeinfo with the name "Typeinfo_mangle".

(BTW, I'm pretty sure that whole group of files could be 
auto-generated with __traits in modern D, but they had to be 
hand-written in old D to provide some foundation.)


So that crazy name "TypeInfo_HAyayAa" actually follows the very 
same pattern. This might be the one time outside eyeball 
debugging when knowing your mangles by hand is actually useful!

On the other hand, perhaps it'd be a good idea to add recognition 
of this pattern to core.demangle, so it can print out the much 
prettier

typeid(immutable char[][immutable(char)[]])

cuz that's how you'd likely refer to it in code anyway (and 
that's close to what i wrote for the hack fix too). I'll do an 
enhancement request in bugzilla after I submit this and maybe 
write it myself later too, but it is bed time now.


More information about the Digitalmars-d-learn mailing list