Thread overview
Retrieving the mangle of a member of a class impossible, when class is typedefed
Jul 13, 2008
Matthias Walter
Jul 14, 2008
Don
Re: Retrieving the mangle of a member of a class impossible, when
Jul 14, 2008
Matthias Walter
July 13, 2008
Hi,

as the subject is a bit complicated, I'll post an example. One way to retrieve the mangle of nearly any identifier at compile-time is the following. (It's legally stolen from ddl/meta :-) )

class Inner (alias A) {}

template Outer (alias A)
{
    void function (Inner !(A)) Outer;
}

template rawIdentifierMangle (alias A)
{
    const char[] rawIdentifierMangle = typeof (&Outer !(A)).mangleof;
}

rawIdentifierMangle !(<identifier>) returns a mangle of your identifier (together with some mangled stuff of Inner, Outer, etc.). It works for Types, variables, members of classes, etc. but the following one fails to compile if on of the commented lines get in.

| class MyClass
| {
|     public int member;
|     public static int static_member;
| }
|
| typedef MyClass MyTypedef;
|
| int main (char[][] args)
| {
|     auto instance1 = new MyClass ();
|     auto instance3 = new MyTypedef ();
|
|     Stdout.formatln ("args: {}", rawIdentifierMangle !(args));
|     Stdout.formatln ("main: {}\n", rawIdentifierMangle !(main));
|
|     Stdout.formatln ("MyClass.static_member: {}", rawIdentifierMangle !(MyClass.static_member));
|     Stdout.formatln ("MyClass.member: {}", rawIdentifierMangle !(MyClass.member));
|     Stdout.formatln ("instance1: {}", rawIdentifierMangle !(instance1));
|     Stdout.formatln ("instance1.static_member: {}", rawIdentifierMangle !(instance1.static_member));
|     Stdout.formatln ("instance1.member: {}\n", rawIdentifierMangle !(instance1.member));
|
|     Stdout.formatln ("MyTypedef.static_member: {}", rawIdentifierMangle !(MyTypedef.static_member));
|     //Stdout.formatln ("MyTypedef.member: {}", rawIdentifierMangle !(MyTypedef.member));
|     Stdout.formatln ("instance3: {}", rawIdentifierMangle !(instance3));
|     Stdout.formatln ("instance3.static_member: {}", rawIdentifierMangle !(instance3.static_member));
|     //Stdout.formatln ("instance3.member: {}\n", rawIdentifierMangle !(instance3.member));
|
|     return 0;
| }

I've also attached the output file of the program.
Both commented lines fail to compile with the error:

Error: 'this' is only allowed in non-static member functions, not main Error: this for member needs to be type MyClass not type int

The mangle-retrieval works for aliases to the class and even for templated identifiers! Is this behavior here a bug or a feature?

best regards
Matthias Walter


July 14, 2008
Matthias Walter wrote:
> Hi,
> 
> as the subject is a bit complicated, I'll post an example. One way to retrieve the mangle of nearly any identifier at compile-time is the following. (It's legally stolen from ddl/meta :-) )
> 
> class Inner (alias A) {}
> 
> template Outer (alias A)
> {
>     void function (Inner !(A)) Outer;
> }
> 
> template rawIdentifierMangle (alias A)
> {
>     const char[] rawIdentifierMangle = typeof (&Outer !(A)).mangleof;
> }
> 
> rawIdentifierMangle !(<identifier>) returns a mangle of your identifier (together with some mangled stuff of Inner, Outer, etc.). It works for Types, variables, members of classes, etc. but the following one fails to compile if on of the commented lines get in.
> 
> | class MyClass
> | {
> |     public int member;
> |     public static int static_member;
> | }
> | | typedef MyClass MyTypedef;
> | | int main (char[][] args)
> | {
> |     auto instance1 = new MyClass ();
> |     auto instance3 = new MyTypedef ();
> | |     Stdout.formatln ("args: {}", rawIdentifierMangle !(args));
> |     Stdout.formatln ("main: {}\n", rawIdentifierMangle !(main));
> | |     Stdout.formatln ("MyClass.static_member: {}", rawIdentifierMangle !(MyClass.static_member));
> |     Stdout.formatln ("MyClass.member: {}", rawIdentifierMangle !(MyClass.member));
> |     Stdout.formatln ("instance1: {}", rawIdentifierMangle !(instance1));
> |     Stdout.formatln ("instance1.static_member: {}", rawIdentifierMangle !(instance1.static_member));
> |     Stdout.formatln ("instance1.member: {}\n", rawIdentifierMangle !(instance1.member));
> | |     Stdout.formatln ("MyTypedef.static_member: {}", rawIdentifierMangle !(MyTypedef.static_member));
> |     //Stdout.formatln ("MyTypedef.member: {}", rawIdentifierMangle !(MyTypedef.member));                                                                                |     Stdout.formatln ("instance3: {}", rawIdentifierMangle !(instance3));
> |     Stdout.formatln ("instance3.static_member: {}", rawIdentifierMangle !(instance3.static_member));
> |     //Stdout.formatln ("instance3.member: {}\n", rawIdentifierMangle !(instance3.member));                                                                              | |     return 0;
> | }
> 
> I've also attached the output file of the program.
> Both commented lines fail to compile with the error:
> 
> Error: 'this' is only allowed in non-static member functions, not main
> Error: this for member needs to be type MyClass not type int

Is this with DMD1.033?
Probably the problems are caused by the changes to typeof. Not sure if they can easily be worked around (although almost *anything* can be fixed with a mixin<g>).
Note that I haven't updated meta.mangleof for a long time (before DMD2.0 was released), there have been several changes to name mangling since then. There are a few cases where it fails.
> 
> The mangle-retrieval works for aliases to the class and even for templated identifiers! Is this behavior here a bug or a feature?
> 
> best regards
> Matthias Walter
> 
July 14, 2008
Don Wrote:

> Matthias Walter wrote:
> > Hi,
> > 
> > as the subject is a bit complicated, I'll post an example. One way to retrieve the mangle of nearly any identifier at compile-time is the following. (It's legally stolen from ddl/meta :-) )
> > 
> > class Inner (alias A) {}
> > 
> > template Outer (alias A)
> > {
> >     void function (Inner !(A)) Outer;
> > }
> > 
> > template rawIdentifierMangle (alias A)
> > {
> >     const char[] rawIdentifierMangle = typeof (&Outer !(A)).mangleof;
> > }
> > 
> > rawIdentifierMangle !(<identifier>) returns a mangle of your identifier (together with some mangled stuff of Inner, Outer, etc.). It works for Types, variables, members of classes, etc. but the following one fails to compile if on of the commented lines get in.
> > 
> > | class MyClass
> > | {
> > |     public int member;
> > |     public static int static_member;
> > | }
> > |
> > | typedef MyClass MyTypedef;
> > |
> > | int main (char[][] args)
> > | {
> > |     auto instance1 = new MyClass ();
> > |     auto instance3 = new MyTypedef ();
> > |
> > |     Stdout.formatln ("args: {}", rawIdentifierMangle !(args));
> > |     Stdout.formatln ("main: {}\n", rawIdentifierMangle !(main));
> > |
> > |     Stdout.formatln ("MyClass.static_member: {}", rawIdentifierMangle !(MyClass.static_member));
> > |     Stdout.formatln ("MyClass.member: {}", rawIdentifierMangle !(MyClass.member));
> > |     Stdout.formatln ("instance1: {}", rawIdentifierMangle !(instance1));
> > |     Stdout.formatln ("instance1.static_member: {}", rawIdentifierMangle !(instance1.static_member));
> > |     Stdout.formatln ("instance1.member: {}\n", rawIdentifierMangle !(instance1.member));
> > |
> > |     Stdout.formatln ("MyTypedef.static_member: {}", rawIdentifierMangle !(MyTypedef.static_member));
> > |     //Stdout.formatln ("MyTypedef.member: {}", rawIdentifierMangle !(MyTypedef.member));
> > |     Stdout.formatln ("instance3: {}", rawIdentifierMangle !(instance3));
> > |     Stdout.formatln ("instance3.static_member: {}", rawIdentifierMangle !(instance3.static_member));
> > |     //Stdout.formatln ("instance3.member: {}\n", rawIdentifierMangle !(instance3.member));
> > |
> > |     return 0;
> > | }
> > 
> > I've also attached the output file of the program.
> > Both commented lines fail to compile with the error:
> > 
> > Error: 'this' is only allowed in non-static member functions, not main Error: this for member needs to be type MyClass not type int
> 
> Is this with DMD1.033?
> Probably the problems are caused by the changes to typeof. Not sure if
> they can easily be worked around (although almost *anything* can be
> fixed with a mixin<g>).
> Note that I haven't updated meta.mangleof for a long time (before DMD2.0
> was released), there have been several changes to name mangling since
> then. There are a few cases where it fails.

I've updated my dmd from 1.031 to 1.33 and now the error is more verbose:

Error: 'this' is only allowed in non-static member functions, not main
Error: this for member needs to be type MyClass not type int
template instance rawIdentifierMangle!(this.member) does not match any template declaration
Error: expression rawIdentifierMangle!(this.member) is void and has no value