www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Retrieving the mangle of a member of a class impossible, when class is typedefed

reply Matthias Walter <Matthias.Walter st.ovgu.de> writes:
Content-Type: text/plain

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
Jul 13 2008
parent reply Don <nospam nospam.com.au> writes:
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
 

Jul 14 2008
parent Matthias Walter <Matthias.Walter st.ovgu.de> writes:
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
Jul 14 2008