www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 20805] New: C++ mangling mismatch with templates and namespaces

https://issues.dlang.org/show_bug.cgi?id=20805

          Issue ID: 20805
           Summary: C++ mangling mismatch with templates and namespaces
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Windows
            Status: NEW
          Severity: major
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: andrej.mitrovich gmail.com

Using DMD v2.091.1.

Take these two files:

cpp.cpp

-----
#include <vector>

static const uint32_t XDR_MAX_LEN = 0xfffffffc;

namespace xdr
{
    template<typename T, uint32_t N = XDR_MAX_LEN>
    struct xvector
    {
    };
}

template<typename T, typename VectorT>
void push_back(VectorT& this_, T& value)
{
}

#define PUSHBACKINST1(T) template void push_back<T, xdr::xvector<T>
(xdr::xvector<T>&, T&);
PUSHBACKINST1(xdr::xvector<unsigned char>) ----- and d.d: ----- import core.stdc.stdint; extern (D) static immutable XDR_MAX_LEN = 0xffff_fffc; extern (C++, `xdr`) struct xvector(T, uint32_t N = XDR_MAX_LEN) { } extern (C++) public void push_back(T, VectorT) (ref VectorT this_, ref T value); void main () { xvector!(xvector!ubyte) vec; xvector!ubyte val; vec.push_back(val); } ----- $ cl /JMC /MP /GS /c /Zc:forScope /std:c++14 cpp.cpp $ dmd -m64 cpp.obj d.d d.obj : error LNK2019: unresolved external symbol "void __cdecl push_back<struct xdr::xvector<unsigned char,4294967292>,struct xdr::xvector<struct xdr::xvector<unsigned char,4294967292>,4294967292> >(struct xdr::xvector<struct xdr::xvector<unsigned char,4294967292>,4294967292> &,struct xvector<unsigned char,4294967292>::xvector<unsigned char,4294967292> &)" (??$push_back U?$xvector E$0PPPPPPPM xdr U?$xvector U?$xvector E$0PPPPPPPM xdr $0PPPPPPPM 2 YAXAEAU?$xvector U?$xvector E$0PPPPPPPM xdr $0PPPPPPPM xdr AEAU?$xvector E$0PPPPPPPM 2 Z) referenced in function _Dmain cpp.exe : fatal error LNK1120: 1 unresolved externals The actual exported symbol is: void __cdecl push_back<struct xdr::xvector<unsigned char,4294967292>,struct xdr::xvector<struct xdr::xvector<unsigned char,4294967292>,4294967292> >(struct xdr::xvector<struct xdr::xvector<unsigned char,4294967292>,4294967292> &,struct xdr::xvector<unsigned char,4294967292> &)" (??$push_back U?$xvector E$0PPPPPPPM xdr U?$xvector U?$xvector E$0PPPPPPPM xdr $0PPPPPPPM 2 YAXAEAU?$xvector U?$xvector E$0PPPPPPPM xdr $0PPPPPPPM xdr AEAU?$xvector E$0PPPPPPPM 1 Z) The difference is at the very end. 2 Z in D vs 1 Z in C++. It seems the namespace is not mangled properly. Demangled D: void __cdecl push_back<struct xdr::xvector<unsigned char,-4>,struct xdr::xvector<struct xdr::xvector<unsigned char,-4>,-4> >(struct xdr::xvector<struct xdr::xvector<unsigned char,-4>,-4> & __ptr64,struct xvector<unsigned char,-4>::xvector<unsigned char,-4> & __ptr64) Demangled C++: void __cdecl push_back<struct xdr::xvector<unsigned char,-4>,struct xdr::xvector<struct xdr::xvector<unsigned char,-4>,-4> >(struct xdr::xvector<struct xdr::xvector<unsigned char,-4>,-4> & __ptr64,struct xdr::xvector<unsigned char,-4> & __ptr64) Notice the missing 'xdr::' close to the end. --
May 08 2020