Re: Need DMD AST expertise

2016-06-21 Thread Guillaume Chatelet via Digitalmars-d

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:

[...]


The templated function is the child symbol of the 
TemplateDeclaration which shares the same name i.e


[...]


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:
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 A


It 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!


Re: Need DMD AST expertise

2016-06-21 Thread Elie Morisse via Digitalmars-d

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..


Re: Need DMD AST expertise

2016-06-21 Thread Elie Morisse via Digitalmars-d

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, , 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.


Re: Need DMD AST expertise

2016-06-21 Thread Guillaume Chatelet via Digitalmars-d

On Tuesday, 21 June 2016 at 09:13:26 UTC, Jacob Carlborg wrote:

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.


Thx anyways! I'll continue my journey [1] :)

1. https://cdn.meme.am/instances/39916320.jpg


Re: Need DMD AST expertise

2016-06-21 Thread Jacob Carlborg via Digitalmars-d

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


Re: Need DMD AST expertise

2016-06-21 Thread Guillaume Chatelet via Digitalmars-d

On Tuesday, 21 June 2016 at 06:25:26 UTC, Jacob Carlborg wrote:

On 2016-06-20 22:52, Guillaume Chatelet wrote:


[...]


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)(*);

"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?


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.


Re: Need DMD AST expertise

2016-06-21 Thread Jacob Carlborg via Digitalmars-d

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)(*);

"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);
  ^^   ^^  ^
  12   21  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


Are the types the same objects so you can compare by just comparing the 
pointers?


--
/Jacob Carlborg


Re: Need DMD AST expertise

2016-06-20 Thread Guillaume Chatelet via Digitalmars-d

On Monday, 20 June 2016 at 18:59:09 UTC, Jacob Carlborg wrote:

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.


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'?




Not sure I understand the question.


Sorry about not being too clear.

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);
  ^^   ^^  ^
  12   21  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


Re: Need DMD AST expertise

2016-06-20 Thread Jacob Carlborg via Digitalmars-d

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.


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'?




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 Carlborg


Re: Need DMD AST expertise

2016-06-20 Thread Johan Engelen via Digitalmars-d

On Monday, 20 June 2016 at 14:06:57 UTC, Guillaume Chatelet wrote:


Thx Johan. I'm confused though


Sorry for misreading your question.




Re: Need DMD AST expertise

2016-06-20 Thread Guillaume Chatelet via Digitalmars-d

On Monday, 20 June 2016 at 14:42:22 UTC, Jacob Carlborg wrote:

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)


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...


Re: Need DMD AST expertise

2016-06-20 Thread Jacob Carlborg via Digitalmars-d

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


Re: Need DMD AST expertise

2016-06-20 Thread Guillaume Chatelet via Digitalmars-d

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:



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.


A FuncDeclaration is a Declaration, which contains the field 
`LINK linkage;`. That's the one you want.


-Johan


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?


Re: Need DMD AST expertise

2016-06-20 Thread Johan Engelen via Digitalmars-d

On Monday, 20 June 2016 at 12:33:31 UTC, Guillaume Chatelet wrote:



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.


A FuncDeclaration is a Declaration, which contains the field 
`LINK linkage;`. That's the one you want.


-Johan


Need DMD AST expertise

2016-06-20 Thread Guillaume Chatelet via Digitalmars-d

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!