digitalmars.D - Need DMD AST expertise
- Guillaume Chatelet (29/34) Jun 20 2016 Context:
- Johan Engelen (4/12) Jun 20 2016 A FuncDeclaration is a Declaration, which contains the field
- Guillaume Chatelet (6/21) Jun 20 2016 Thx Johan. I'm confused though: `FuncDeclaration.linkage` is the
- Jacob Carlborg (10/14) Jun 20 2016 1. Check if the type is a class. There's a field "ty" in Type
- Guillaume Chatelet (5/20) Jun 20 2016 Pretty cool. Thx Jacob!
- Johan Engelen (2/4) Jun 20 2016 Sorry for misreading your question.
- Jacob Carlborg (7/20) Jun 20 2016 Not sure I understand the question. Are you saying that the two integers...
- Guillaume Chatelet (25/52) Jun 20 2016 Yes exactly.
- Jacob Carlborg (12/33) Jun 20 2016 A guess: "tiargs" is the types of the values passed to the template.
- Guillaume Chatelet (4/17) Jun 21 2016 AFAIK basic types are instantiated once and reused:
- Jacob Carlborg (4/7) Jun 21 2016 Yeah. I'm just guessing here :). Sorry, I don't think I can help you.
- Guillaume Chatelet (3/11) Jun 21 2016 Thx anyways! I'll continue my journey [1] :)
- Elie Morisse (11/13) Jun 21 2016 The templated function is the child symbol of the
- Elie Morisse (2/5) Jun 21 2016 Mixing C++ and D once more..
- Guillaume Chatelet (11/49) Jun 21 2016 Thx Elie! It helps :)
Context: I'm working on a more correct implementation of the C++ name mangling for Linux/OSX. This is needed for the integration with C++/STL. ------------------------------------------------------------ Problem 1: ---------- In the following D code 'Expression' is a D class, 'foo' is a C++ function, its argument must be mangled as a pointer to Expression because D has reference semantic (whereas C++ has value semantic).class Expression; extern(C++) void foo(Expression);Question: --------- - How to I get the linkage for Expression from a FunDeclaration? This will ensure the added indirection is put only for the D classes, not the C++ ones. I tried looking at Parameter, ClassDeclaration or TypeClass but couldn't find it. ------------------------------------------------------------ Problem 2: ---------- Template arguments that are of basic types are mangled in a special way which requires to understand which 'int' is which.extern(C++) A foo(A, B)(B, A, B); static assert(foo!(int,int).mangleof == "_Z3fooIiiET_T0_S0_S1_");In the example above the first 'int' is not the same as the second one, it's a distinct substitution. Question: --------- - How can I know which is which since from the AST perspective, the FunDeclaration's Parameters are just TypeBasic 'int'? ------------------------------------------------------------ Thx in advance!
Jun 20 2016
On Monday, 20 June 2016 at 12:33:31 UTC, Guillaume Chatelet wrote:A FuncDeclaration is a Declaration, which contains the field `LINK linkage;`. That's the one you want. -Johanclass Expression; extern(C++) void foo(Expression);Question: --------- - How to I get the linkage for Expression from a FunDeclaration? This will ensure the added indirection is put only for the D classes, not the C++ ones. I tried looking at Parameter, ClassDeclaration or TypeClass but couldn't find it.
Jun 20 2016
On Monday, 20 June 2016 at 13:50:45 UTC, Johan Engelen wrote:On Monday, 20 June 2016 at 12:33:31 UTC, Guillaume Chatelet wrote:Thx Johan. I'm confused though: `FuncDeclaration.linkage` is the linkage for the function (which I already know is C++ function since I'm mangling it) but I need the linkage for the Parameter. Parameter has a Type but I can't get the linkage from here. What did I miss?A FuncDeclaration is a Declaration, which contains the field `LINK linkage;`. That's the one you want. -Johanclass Expression; extern(C++) void foo(Expression);Question: --------- - How to I get the linkage for Expression from a FunDeclaration? This will ensure the added indirection is put only for the D classes, not the C++ ones. I tried looking at Parameter, ClassDeclaration or TypeClass but couldn't find it.
Jun 20 2016
On 2016-06-20 16:06, Guillaume Chatelet wrote:Thx Johan. I'm confused though: `FuncDeclaration.linkage` is the linkage for the function (which I already know is C++ function since I'm mangling it) but I need the linkage for the Parameter. Parameter has a Type but I can't get the linkage from here. What did I miss?1. Check if the type is a class. There's a field "ty" in Type 2. If it's a class, cast it to TypeClass 3. TypeClass has a field "sym" of type ClassDeclaration 4. ClassDeclaration has three fields: "com", "cpp" and "objc". I think these fields indicate if the class declaration has extern(C++), extern(Objective-C) and so on. If none of them are true, it's standard extern(D) -- /Jacob Carlborg
Jun 20 2016
On Monday, 20 June 2016 at 14:42:22 UTC, Jacob Carlborg wrote:On 2016-06-20 16:06, Guillaume Chatelet wrote:Pretty cool. Thx Jacob! Anyone has a suggestion for my second problem? If not I'll have to do some kind of mapping between the template args and the parameters...Thx Johan. I'm confused though: `FuncDeclaration.linkage` is the linkage for the function (which I already know is C++ function since I'm mangling it) but I need the linkage for the Parameter. Parameter has a Type but I can't get the linkage from here. What did I miss?1. Check if the type is a class. There's a field "ty" in Type 2. If it's a class, cast it to TypeClass 3. TypeClass has a field "sym" of type ClassDeclaration 4. ClassDeclaration has three fields: "com", "cpp" and "objc". I think these fields indicate if the class declaration has extern(C++), extern(Objective-C) and so on. If none of them are true, it's standard extern(D)
Jun 20 2016
On Monday, 20 June 2016 at 14:06:57 UTC, Guillaume Chatelet wrote:Thx Johan. I'm confused thoughSorry for misreading your question.
Jun 20 2016
On 2016-06-20 14:33, Guillaume Chatelet wrote:Problem 2: ---------- Template arguments that are of basic types are mangled in a special way which requires to understand which 'int' is which.Not sure I understand the question. Are you saying that the two integers are mangled differently because there are two template parameters? I'm guessing you need to look at the template declaration to get more information about the template parameters. -- /Jacob Carlborgextern(C++) A foo(A, B)(B, A, B); static assert(foo!(int,int).mangleof == "_Z3fooIiiET_T0_S0_S1_");In the example above the first 'int' is not the same as the second one, it's a distinct substitution. Question: --------- - How can I know which is which since from the AST perspective, the FunDeclaration's Parameters are just TypeBasic 'int'? ------------------------------------------------------------
Jun 20 2016
On Monday, 20 June 2016 at 18:59:09 UTC, Jacob Carlborg wrote:On 2016-06-20 14:33, Guillaume Chatelet wrote:Sorry about not being too clear.Problem 2: ---------- Template arguments that are of basic types are mangled in a special way which requires to understand which 'int' is which.Not sure I understand the question.extern(C++) A foo(A, B)(B, A, B); static assert(foo!(int,int).mangleof == "_Z3fooIiiET_T0_S0_S1_");In the example above the first 'int' is not the same as the second one, it's a distinct substitution. Question: --------- - How can I know which is which since from the AST perspective, the FunDeclaration's Parameters are just TypeBasic 'int'? ------------------------------------------------------------Are you saying that the two integers are mangled differently because there are two template parameters?Yes exactly.I'm guessing you need to look at the template declaration to get more information about the template parameters.The TemplateInstance [1] gives me `tiargs` and `tdtypes`. // Array of Types/Expressions of template // instance arguments [int*, char, 10*10] Objects* tiargs; // Array of Types/Expressions corresponding // to TemplateDeclaration.parameters // [int, char, 100] Objects tdtypes; I'm using `tiargs` right now (I'm not really sure what `tdtypes` is). AFAIU I can access TemplateDeclaration from TemplateInstance through `tempdecl` even though it's stored as a Dsymbol. I'll have a look at `parameters` from TemplateDeclaration [2] but I still need to match it to the function arguments somehow. The following example illustrates the process of pairing the int to the template parameter. extern(C++) B foo(A, B)(*B, ref const A); foo!(int, int) => int foo(*int, ref const int); ^ ^ ^ ^ ^ 1 2 2 1 2 1. https://github.com/dlang/dmd/blob/master/src/dtemplate.d#L5895 2. https://github.com/dlang/dmd/blob/master/src/dtemplate.d#L406
Jun 20 2016
On 2016-06-20 22:52, Guillaume Chatelet wrote:The TemplateInstance [1] gives me `tiargs` and `tdtypes`. // Array of Types/Expressions of template // instance arguments [int*, char, 10*10] Objects* tiargs; // Array of Types/Expressions corresponding // to TemplateDeclaration.parameters // [int, char, 100] Objects tdtypes; I'm using `tiargs` right now (I'm not really sure what `tdtypes` is).A guess: "tiargs" is the types of the values passed to the template. "tdtypes" is the types the template is instantiated with. void foo(T)(T* a); int b; foo!(int)(&b*); "tiargs" is "int*" and "tdtypes" is "int". But this can easily be confirmed using some printf debugging.AFAIU I can access TemplateDeclaration from TemplateInstance through `tempdecl` even though it's stored as a Dsymbol. I'll have a look at `parameters` from TemplateDeclaration [2] but I still need to match it to the function arguments somehow. The following example illustrates the process of pairing the int to the template parameter. extern(C++) B foo(A, B)(*B, ref const A); foo!(int, int) => int foo(*int, ref const int); ^ ^ ^ ^ ^ 1 2 2 1 2 1. https://github.com/dlang/dmd/blob/master/src/dtemplate.d#L5895 2. https://github.com/dlang/dmd/blob/master/src/dtemplate.d#L406Are the types the same objects so you can compare by just comparing the pointers? -- /Jacob Carlborg
Jun 20 2016
On Tuesday, 21 June 2016 at 06:25:26 UTC, Jacob Carlborg wrote:On 2016-06-20 22:52, Guillaume Chatelet wrote:AFAIK basic types are instantiated once and reused: https://github.com/dlang/dmd/blob/b67694a0d74437d3a1581da2b9f1b785dc7b3c88/src/mtype.d#L861 So comparing pointers wouldn't work.[...]A guess: "tiargs" is the types of the values passed to the template. "tdtypes" is the types the template is instantiated with. void foo(T)(T* a); int b; foo!(int)(&b*); "tiargs" is "int*" and "tdtypes" is "int". But this can easily be confirmed using some printf debugging.[...]Are the types the same objects so you can compare by just comparing the pointers?
Jun 21 2016
On 2016-06-21 09:45, Guillaume Chatelet wrote:AFAIK basic types are instantiated once and reused: https://github.com/dlang/dmd/blob/b67694a0d74437d3a1581da2b9f1b785dc7b3c88/src/mtype.d#L861 So comparing pointers wouldn't work.Yeah. I'm just guessing here :). Sorry, I don't think I can help you. -- /Jacob Carlborg
Jun 21 2016
On Tuesday, 21 June 2016 at 09:13:26 UTC, Jacob Carlborg wrote:On 2016-06-21 09:45, Guillaume Chatelet wrote:Thx anyways! I'll continue my journey [1] :) 1. https://cdn.meme.am/instances/39916320.jpgAFAIK basic types are instantiated once and reused: https://github.com/dlang/dmd/blob/b67694a0d74437d3a1581da2b9f1b785dc7b3c88/src/mtype.d#L861 So comparing pointers wouldn't work.Yeah. I'm just guessing here :). Sorry, I don't think I can help you.
Jun 21 2016
On Monday, 20 June 2016 at 20:52:02 UTC, Guillaume Chatelet wrote:I'll have a look at `parameters` from TemplateDeclaration [2] but I still need to match it to the function arguments somehow.The templated function is the child symbol of the TemplateDeclaration which shares the same name i.e Dsymbol* s; Dsymbol.oneMembers(tempdecl->members, &s, tempdecl->ident); auto fd = cast(FuncDeclaration) s; You then need to visit the templated function parameters « (cast(TypeFunction) fd->type)->parameters » and look for identifiers that match the TemplateDeclaration.parameters[].ident. In the simplest cases the types of templated function parameters are TypeIdentifier.
Jun 21 2016
On Tuesday, 21 June 2016 at 19:42:54 UTC, Elie Morisse wrote:On Monday, 20 June 2016 at 20:52:02 UTC, Guillaume Chatelet wrote: « (cast(TypeFunction) fd->type)->parameters »Mixing C++ and D once more..
Jun 21 2016
On Tuesday, 21 June 2016 at 19:42:54 UTC, Elie Morisse wrote:On Monday, 20 June 2016 at 20:52:02 UTC, Guillaume Chatelet wrote:Thx Elie! It helps :) I came up with this quick and dirty piece of code to get the parameters from the template declaration and the function declaration: code:[...]The templated function is the child symbol of the TemplateDeclaration which shares the same name i.e [...]auto declaration = cast(TemplateDeclaration)templateInstance.tempdecl; assert(declaration); printf("TemplateDeclaration %x\n", declaration); foreach(parameter; *declaration.parameters) { printf("Parameter %s\n", parameter.ident.toChars()); } if (declaration.onemember) { FuncDeclaration fd = declaration.onemember.isFuncDeclaration(); if (fd && fd.type) { TypeFunction tf = cast(TypeFunction)fd.type; assert(tf); printf("TypeFunction %x\n", tf); if(tf.next) printf("Parameter return %s\n", tf.next.toChars()); if(tf.parameters) foreach(parameter; *tf.parameters) { printf("Parameter %s\n", parameter.type.toChars()); } } }input:extern(C++) C foo(A, B, C)(B, A);output:TemplateDeclaration 764f76b0 Parameter A Parameter B Parameter C TypeFunction 764f7370 Parameter return C Parameter B Parameter AIt works as expected. I still need to do the mapping and handle subtleties like this but I'm on the right track.extern(C++) ref C foo(A, B, C)(B*, const(A)*);Thx!
Jun 21 2016