View mode: basic / threaded / horizontal-split · Log in · Help
November 08, 2006
D's insufficient name mangling
Apart from implementation issues like #211, #375 and #466,
D's current name mangling achieves the primary target:
> Make it possible for linkers to distinguish between different
> versions of overloaded functions.

However it fails to address the consistency issue:
> Make it possible for linkers to check that objects and
> functions are declared in exactly the same way in all modules.

The problem is that it isn't reversible,
causing all kinds of problems for runtime reflections.


issue 1: missing "static" information
#
# class C{
#    void foo(){}
#    static void bar(){}
# }
#
_D8mangling1C3fooFZv
_D8mangling1C3barFZv


issue 2: missing "struct"/"union" information
#
# union  Cat { int i; }
# struct Cow { int i; }
#
# Cat foo() { assert(0); }
# Cow bar() { assert(0); }

_init_8mangling3Cat
_init_8mangling3Cow
_D8mangling3fooFZS8mangling3Cat
_D8mangling3barFZS8mangling3Cow


issue 3: missing "const" information
#
# int X = 0;
# const int Y = 0;
#
_D8mangling1Xi
_D8mangling1Yi


issue 4: missing protection attributes

While the ELF object format used by Linux supports differentiation
of "private" and "public" (though see issue #463), 
"package" and "protected" can't be differentiated.

issue 5: missing "final" information
#
# class C{
#    final void foo() {}
#    void bar() {}
# }
#
_D8mangling1C3fooFZv
_D8mangling1C3barFZv


Especially the "static" and "struct"/"enum" issues pose a problem for
runtime reflection due to their effects on calling conventions.

Thomas
November 09, 2006
Re: D's insufficient name mangling
Thomas Kuehne wrote:
> Apart from implementation issues like #211, #375 and #466,
> D's current name mangling achieves the primary target:
>> Make it possible for linkers to distinguish between different
>> versions of overloaded functions.
> 
> However it fails to address the consistency issue:
>> Make it possible for linkers to check that objects and
>> functions are declared in exactly the same way in all modules.
> 
> The problem is that it isn't reversible,
> causing all kinds of problems for runtime reflections.
> 
> 
> issue 1: missing "static" information
> #
> # class C{
> #    void foo(){}
> #    static void bar(){}
> # }
> #
> _D8mangling1C3fooFZv
> _D8mangling1C3barFZv
> 
> 
> issue 2: missing "struct"/"union" information
> #
> # union  Cat { int i; }
> # struct Cow { int i; }
> #
> # Cat foo() { assert(0); }
> # Cow bar() { assert(0); }
> 
> _init_8mangling3Cat
> _init_8mangling3Cow
> _D8mangling3fooFZS8mangling3Cat
> _D8mangling3barFZS8mangling3Cow
> 
> 
> issue 3: missing "const" information
> #
> # int X = 0;
> # const int Y = 0;
> #
> _D8mangling1Xi
> _D8mangling1Yi
> 
> 
> issue 4: missing protection attributes
> 
> While the ELF object format used by Linux supports differentiation
> of "private" and "public" (though see issue #463), 
> "package" and "protected" can't be differentiated.
> 
> issue 5: missing "final" information
> #
> # class C{
> #    final void foo() {}
> #    void bar() {}
> # }
> #
> _D8mangling1C3fooFZv
> _D8mangling1C3barFZv
> 
> 
> Especially the "static" and "struct"/"enum" issues pose a problem for
> runtime reflection due to their effects on calling conventions.
> 
> Thomas

Here's another irreversible demangling.

Normally, anything declared as "extern (Windows)"/extern(C)/... has no 
type information in its name mangling; only the undecorated name is 
used. Yet nested classes, types and functions inside such an extern(XXX) 
function have decorated names. This is a very obscure situation because 
normally, such entities won't have external linkage. It might be more 
important now that local variables are allowed as template alias parameters.

In example 1 below, the mangled name of fox is:
Cwolf3fox. Note that there's no length before 'wolf' (it's not 4wolf).
Example 2 shows a (highly contrived) situation where two distinct 
classes have the same
mangled name "Cwolf5dingo3fox".
If length information were included, the mangled names would be 
"C4wolf5dingo3fox"
and "C10wolf5dingo3fox".
In example 3 (which has no extern(Windows)), the mangled name is 
"C4wolf5dingo3fox".

---
Example 1.
extern(Windows) {

void wolf()
{
	class fox {}
	pragma(msg, fox.mangleof);
}

}
---
Example 2.

extern(Windows) {
void wolf()
{
	class dingo {
		class fox {}
		pragma(msg, fox.mangleof);
	}
}
void wolf5dingo()
{
	class fox {}
	pragma(msg, fox.mangleof);
}

}
---
Example 3: file called 'wolf.d'.

module wolf;

class dingo {
	class fox {}
	pragma(msg, fox.mangleof);
}

=================
Top | Discussion index | About this forum | D home