Thread overview
Trying to add C++ header generation to dmd
Mar 19, 2019
Gregor Mückl
Mar 20, 2019
albr
Mar 20, 2019
Jacob Carlborg
Mar 20, 2019
Gregor Mückl
Mar 20, 2019
Stefan Koch
Mar 20, 2019
Jacob Carlborg
March 19, 2019
Hi!

I tried to hack a bit on dmd to have it generate a C++ header for a D module. I've copied the visitor in hdrgen.d and did truly terrible things to it, to the point where I don't feel confident that I want to show that code to anyone.

So now I get something almost resembling C++ code for a few really trivial definitions in the input D module. But that is for all definitions, not just the ones marked external(C++).

This is the point where I'm actually stumped now. The PrettyPrintVisitor, which I used as a template, does not really make it easy to discover the context of a visited AST node. In particular, I don't know how to determine if one of the parent nodes possess the required extern(C++) linkage specification to be considered for exporting.

If there was a way for the visitor to know when the subtree below a certain node has been visited completely, it could then trivially track linkage as a kind of a contextual information.

So to anyone who knows dmd better than me: how would you go about implementing the visitor in such a way that it only exports the correct AST subtrees?

Gregor
March 20, 2019
On Tuesday, 19 March 2019 at 20:55:34 UTC, Gregor Mückl wrote:
> If there was a way for the visitor to know when the subtree below a certain node has been visited completely, it could then trivially track linkage as a kind of a contextual information.

DFS traversal?
March 20, 2019
On 2019-03-19 21:55, Gregor Mückl wrote:
> Hi!
> 
> I tried to hack a bit on dmd to have it generate a C++ header for a D module. I've copied the visitor in hdrgen.d and did truly terrible things to it, to the point where I don't feel confident that I want to show that code to anyone.
> 
> So now I get something almost resembling C++ code for a few really trivial definitions in the input D module. But that is for all definitions, not just the ones marked external(C++).
> 
> This is the point where I'm actually stumped now. The PrettyPrintVisitor, which I used as a template, does not really make it easy to discover the context of a visited AST node. In particular, I don't know how to determine if one of the parent nodes possess the required extern(C++) linkage specification to be considered for exporting.
> 
> If there was a way for the visitor to know when the subtree below a certain node has been visited completely, it could then trivially track linkage as a kind of a contextual information.
> 
> So to anyone who knows dmd better than me: how would you go about implementing the visitor in such a way that it only exports the correct AST subtrees?

I'm not sure if you need to look at the parent. Every declaration has a "linkage" field [1] identifying if it's C++, D or something else. Classes and structs, which don't inherit from Declaration, has a "classKind" field [2].

You can also have a look at this work in progress PR [3].

[1] https://github.com/dlang/dmd/blob/3a298e504707ccd8d633c6ea5511d46c5758fa8b/src/dmd/declaration.d#L289

[2] https://github.com/dlang/dmd/blob/3a298e504707ccd8d633c6ea5511d46c5758fa8b/src/dmd/aggregate.d#L86

[3] https://github.com/dlang/dmd/pull/8591

-- 
/Jacob Carlborg
March 20, 2019
On Wednesday, 20 March 2019 at 10:27:27 UTC, Jacob Carlborg wrote:
> On 2019-03-19 21:55, Gregor Mückl wrote:
>> [snip]
> I'm not sure if you need to look at the parent. Every declaration has a "linkage" field [1] identifying if it's C++, D or something else. Classes and structs, which don't inherit from Declaration, has a "classKind" field [2].
>
> You can also have a look at this work in progress PR [3].
>
> [1] https://github.com/dlang/dmd/blob/3a298e504707ccd8d633c6ea5511d46c5758fa8b/src/dmd/declaration.d#L289
>
> [2] https://github.com/dlang/dmd/blob/3a298e504707ccd8d633c6ea5511d46c5758fa8b/src/dmd/aggregate.d#L86
>
> [3] https://github.com/dlang/dmd/pull/8591

Do these fields extend properly to children? Consider the following code:

extern(C++) class C
{
  int foo(int a, int b);
}

Will foo be marked with C++ linkage? The parameters as well? That would simplify the matter a lot.

The pull request does indeed look useful. Thanks!
March 20, 2019
On Wednesday, 20 March 2019 at 14:26:17 UTC, Gregor Mückl wrote:
> On Wednesday, 20 March 2019 at 10:27:27 UTC, Jacob Carlborg wrote:
>> [...]
>
> Do these fields extend properly to children? Consider the following code:
>
> extern(C++) class C
> {
>   int foo(int a, int b);
> }
>
> Will foo be marked with C++ linkage? The parameters as well? That would simplify the matter a lot.
>
> The pull request does indeed look useful. Thanks!

It _should_ you can test it by looking if the mangle changes from the class without extern(C++).
March 20, 2019
On 2019-03-20 15:26, Gregor Mückl wrote:

> Do these fields extend properly to children? Consider the following code:
> 
> extern(C++) class C
> {
>    int foo(int a, int b);
> }
> 
> Will foo be marked with C++ linkage? 

"foo" will definitely have C++ linkage.

The parameters as well? That would simplify the matter a lot.

Not sure. I don't think that matters in this case.

-- 
/Jacob Carlborg