D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 15473 - C++ mangling problem
Summary: C++ mangling problem
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 Windows
: P1 enhancement
Assignee: No Owner
URL:
Keywords: C++, industry, mangling
Depends on:
Blocks:
 
Reported: 2015-12-24 13:42 UTC by Manu
Modified: 2018-10-23 17:54 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Manu 2015-12-24 13:42:03 UTC
C++ produces this symbol:
?asAssocArray@Variant@ep@@QEBA?AU?$SharedMap@U?$AVLTree@UVariant@ep@@U12@U?$Compare@UVariant@ep@@@2@@ep@@@2@XZ

D produces this symbol:
?asAssocArray@Variant@ep@@QEBA?AU?$SharedMap@U?$AVLTree@UVariant@ep@@0U?$Compare@UVariant@ep@@@2@@ep@@@2@XZ


The difference is that little 'U12@' vs '0'. The MS linker de-mangles both symbols to read identical, so I don't know what it means.


The C declaration:

namespace ep {
struct Variant
{
  ep::SharedMap<ep::AVLTree<ep::Variant, ep::Variant, ep::Compare<ep::Variant>>> asAssocArray() const;
};
} // namespace


The D declaration:

extern (C++, ep) {
struct Variant
{
  SharedMap!(AVLTree!(Variant, Variant, Compare!Variant)) asAssocArray() const;
}
}


All those things are extern(C++, ep), and they work properly on their own.
Comment 1 Manu 2015-12-24 13:50:47 UTC
On a tangent, I'm having a lot of trouble with the fact that MSVC mangles classes differently than struct's... I feel like I need a way to control which to choose on the D side. UDA perhaps?
Comment 2 Jacob Carlborg 2015-12-24 16:41:57 UTC
A(In reply to Manu from comment #1)
> On a tangent, I'm having a lot of trouble with the fact that MSVC mangles
> classes differently than struct's... I feel like I need a way to control
> which to choose on the D side. UDA perhaps?

An ugly workaround would be to specify the fully mangled name using pragma(mangle).
Comment 3 Manu 2016-01-02 10:04:16 UTC
Here's another case:

C++:
  ?CreateImplInternal@Component@ep@@IEAAPEAXU?$BaseString@D@2@U?$SharedMap@U?$AVLTree@UVariant@ep@@U12@U?$Compare@UVariant@ep@@@2@@ep@@@2@@Z

D:
  ?CreateImplInternal@Component@ep@@IEAAPEAXU?$BaseString@D@2@U?$SharedMap@U?$AVLTree@UVariant@ep@@0U?$Compare@UVariant@ep@@@2@@ep@@@2@@Z

The difference being that same little '0U' which is meant to be 'U12@U' again.


C++ declaration:

namespace ep {
  class Component : public RefCounted, public IComponent
  {
    void* CreateImplInternal(String ComponentType, Variant::VarMap initParams);
  };
}

D declaration:

extern (C++, ep) class Component : RefCounted, IComponent
{
  void* CreateImplInternal(String componentType, Variant.VarMap initParams);
}


In both cases, the function involves, Variant::VarMap, which expands to:

  C++: ep::SharedMap<ep::AVLTree<ep::Variant, ep::Variant, ep::Compare<ep::Variant>>>
  D: SharedMap!(AVLTree!(Variant, Variant, Compare!Variant))

That's the same type as the return value in the first issue, with the same problem in the symbol name.
This is a pretty long symbol name, but the missing 'U12@' seems deterministic.
Comment 4 Walter Bright 2016-01-26 06:09:34 UTC
Need complete examples, not undefined names.
Comment 5 Manu 2016-01-26 06:14:48 UTC
*sigh*, like everything, this only appears when the case becomes sufficient complex, and reduction takes ages.

I was hoping you'd able to look at the difference in the mangled names, and infer what the problem is by the difference in attributes.
Assuming you understand the mangled names, it should be pretty revealing.
Comment 6 Walter Bright 2016-01-26 06:46:48 UTC
The mangler:

https://github.com/D-Programming-Language/dmd/blob/master/src/cppmangle.d

is useful for figuring out what the various things, like Q vs U, mean.
Comment 7 Mathias LANG 2018-10-22 18:20:52 UTC
Do you still see this ? Without a proper way to reproduce, I don't know what we can do about this bug.