-
-
Notifications
You must be signed in to change notification settings - Fork 607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix issue 18716: type const(char)[]
can not be mapped to C++
#8120
base: master
Are you sure you want to change the base?
Conversation
Thanks for your pull request and interest in making D better, @jacob-carlborg! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + dmd#8120" |
7a3dcd6
to
fd88f12
Compare
Thanks for doing the work on this, it's a nice job. I've thought about doing this now and then, having run into the issue myself, but I have reservations:
The conclusion I always come to is it is not worth the extra complexity in the D core language. |
@WalterBright This primarily for use within DMD. Based on your conclusion, you don’t want this feature? |
As @jacob-carlborg mentioned this is primarily intended for DMD, s.t. D strings can be used everywhere and passed to LDC/GDC. See also: #7893 (another attempt at making the interoperability possible)
FWIW: Last time I checked, this hit multiple dead-ends (see: dlang/druntime#1316) :/
Hmm what's your plan on passing D strings to LDC/GDC then? |
I think this is a much more sensible approach. Instead of introducing another symbol, could we turn |
I disagree. It would be more complicated to rewrite the AST or the IR. I think it’s too late to do it in the backend. My approach is ABI compatible so no rewriting is required. |
@wilzbach auto-tester is reporting that all tests passed here, but looking at the details, one test failed. |
d854bde
to
deb51eb
Compare
Then I definitely feel this is not worth it. It would be simple enough to manually rewrite:
as:
Right, not worth it. |
Hmm. When I think about moving the dmd implementation from
|
How can we know which methods are used in GDC/LDC? |
We will tell you. 😉 ... Let's start with a rule of thumb. The role of the interface is to initialize the frontend, call entrypoints to read, parse, semantic, and optionally generate header/ddoc/json files for all modules. Whatever doesn't fall into any of those categories should be good for the taking. i.e: AST types that only live during semantic analysis, anything that sets or mutates state, and resolver methods and functions. Off the top of my head, the only functions that need to continue returning a |
For example (this might already have been done), the only function that needs to be exposed to C++ for header generation is |
@WalterBright with the (questionable) power of C++ implicit conversions this is a #include <vector>
template<typename T> struct __dslice {
size_t length; T* ptr;
__dslice(const std::vector<T>& x)
{
length = x.size();
ptr = (T*)&x[0]; // seems to default to const not sure why hence the cast
}
};
void foo(__dslice<int> a) {};
int main(int a, char** b)
{
std::vector<int> x;
foo(x);
} Proof this compiles: https://godbolt.org/g/VFA1xV If somebody is using the code then they are already |
@ibuclaw Unfortunately it's not possible to overload a function taking void symbol_name(const(char)* name) {}
void symbol_name(const(char)[] name) {}
void main()
{
symbol_name("foo");
}
|
deb51eb
to
e72d80f
Compare
@jacob-carlborg - then make the C++ overload include a length parameter? Identifier::idPool is a good example of this, the D: Lines 175 to 193 in f1effe0
C++: Lines 42 to 47 in f1effe0
|
@ibuclaw there’s already one overload with and one without the length parameter. I’m trying to avoid breaking all existing usages. https://github.com/dlang/dmd/blob/master/src/dmd/backend/global.d#L335 |
e72d80f
to
3572ad0
Compare
@thewilsonator rebased. |
Hmm, it seems to be segfaulting on windows? No idea why though. See e.g. https://auto-tester.puremagic.com/show-run.ghtml?projectid=1&runid=3231832&isPull=true |
Also with the |
@WalterBright ahh I get you.
The point of its constructor is that given
you can pass a Likewise template<typename T struct __dslice
{
size_t length; T* ptr;
...
operator gsl::span<T>(){ return gsl::span<T>(ptr,length);}
};
__dslice<int> bar();
...
gsl::span<int> c = bar(); works. This means that you don't ever have to use We can synthesise D |
D arrays don't have any corresponding type in C++. Instead we mangle it as a templated struct with the name `__dslice`, i.e. `struct __dslice(T)`, where `T` is the element type of the array. For an array of ints it would be mangled as the following type: `__dslice!int`.
54ac4b5
to
740a866
Compare
@thewilsonator rebased. |
Thanks. @WalterBright can we please get the green light for this? |
I don't see how you can simply discard the ABI mismatch on Win64. If the purpose is direct slices interop between D and C++, but it doesn't work on all platforms, it's useless to me. Edit: I think that at least for LDC, there are potential ABI mismatches for non-Windows x86_64 targets as well. If there's only one available GP register left, the slice's size is put in there, and the ptr is pushed on the stack, IIRC. This isn't done for a regular struct, which is either passed completely in registers or on the stack. |
// D slices as parameters in extern(C++) functions | ||
|
||
struct Test18716 {} | ||
struct __dslice(T) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests needs to be in runnable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ABI doesn't match, so there's no point, at least not yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point is exactly that the ABI does not match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not following. This whole PR is moot as long as the ABI problem exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I was just saying that it's not obvious, since there are tests, and the PR is green.
But IMO, this PR should ultimately be accepted, but it looks like you fear it to be vetoed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It should, but Walter hasn't responded to the reasoning why his concerns are unfounded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m not going to spend time on moving the tests if/until I fix the ABI issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Walter did already vetoed it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But not sensibly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#11073 contains a runnable_cxx
test (if someone wants to use it)
Sorry for the confusion, I meant green light as in he's be happy with the feature, so that it would then not be a waste of time fixing ABI issues for a PR that would be rejected anyway. |
WIP due to missing ABI compatibility. |
I'm not familiar with the DMD ABI details, but at least for LDC, a half-feasible option would be mangling a slice parameter as 2 separate C++ parameters - |
Any update on this? |
@WalterBright how should we proceed here? |
Ping @WalterBright . This is a good step to make the compiler |
How? Many things are still being passed to the front-end from C++ land. |
I'm sure there is a lot of benefits on make this step, especially making the compiler use more |
D arrays don't have any corresponding type in C++. Instead we mangle it as a templated struct with the name
__dslice
, i.e.struct __dslice(T)
, whereT
is the element type of the array. For an array of ints it would be mangled as the following type:__dslice!int
.Reboot of #7893.
@WalterBright this should interesting for you since you want to kill C string in DMD.