Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

[WIP] core.stdcpp.{exception,typeinfo}: Fix D/C++ symbol conflicts and undefined D vtable entries #2788

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions src/core/stdcpp/exception.d
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,14 @@ version (GenericBaseException)
class exception
{
@nogc:
extern(D):
///
this() nothrow {}
///
~this() nothrow {} // HACK: this should extern, but then we have link errors!
~this() nothrow {}

///
const(char)* what() const nothrow { return "unknown"; } // HACK: this should extern, but then we have link errors!
const(char)* what() const nothrow { return "unknown"; }

protected:
this(const(char)*, int = 1) nothrow { this(); } // compat with MS derived classes
Expand All @@ -85,19 +86,20 @@ else version (CppRuntime_Microsoft)
class exception
{
@nogc:
extern (D):
///
this(const(char)* message = "unknown", int = 1) nothrow { msg = message; }
///
extern(D) ~this() nothrow {}
~this() nothrow {}

///
extern(D) const(char)* what() const nothrow { return msg != null ? msg : "unknown exception"; }
const(char)* what() const nothrow { return msg != null ? msg : "unknown exception"; }

// TODO: do we want this? exceptions are classes... ref types.
// final ref exception opAssign(ref const(exception) e) nothrow { msg = e.msg; return this; }

protected:
void _Doraise() const {}
void _Doraise() const { assert(0); }

protected:
const(char)* msg;
Expand All @@ -111,6 +113,15 @@ else
class bad_exception : exception
{
@nogc:
extern(D):
private static immutable msg = "bad exception";

///
this(const(char)* message = "bad exception") { super(message); }
this(const(char)* message = msg.ptr) nothrow { super(message); }

version (GenericBaseException)
{
///
override const(char)* what() const nothrow { return msg.ptr; }
}
}
52 changes: 29 additions & 23 deletions src/core/stdcpp/typeinfo.d
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ else version (CppRuntime_Microsoft)

class type_info
{
//virtual ~this();
void dtor() { } // reserve slot in vtbl[]
@nogc:
extern(D) ~this() nothrow {}
//bool operator==(const type_info rhs) const;
//bool operator!=(const type_info rhs) const;
final bool before(const type_info rhs) const;
final const(char)* name(__type_info_node* p = &__type_info_root_node) const;
final bool before(const type_info rhs) const nothrow;
final const(char)* name(__type_info_node* p = &__type_info_root_node) const nothrow;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's actually the wrong signature for VS 2017 (which takes no params), but I guess DMD has to maintain VS 2010 compatibility or whatever.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have -extern-std=, so we can version the C++ code according to the C++ version it binds to.


private:
void* pdata;
Expand All @@ -85,14 +85,12 @@ else version (CppRuntime_Microsoft)

class bad_cast : exception
{
this(const(char)* msg = "bad cast");
//virtual ~this();
extern(D) this(const(char)* msg = "bad cast") @nogc nothrow { super(msg); }
}

class bad_typeid : exception
{
this(const(char)* msg = "bad typeid");
//virtual ~this();
extern(D) this(const(char)* msg = "bad typeid") @nogc nothrow { super(msg); }
}
}
else version (CppRuntime_Gcc)
Expand All @@ -108,39 +106,47 @@ else version (CppRuntime_Gcc)

class type_info
{
void dtor1(); // consume destructor slot in vtbl[]
void dtor2(); // consume destructor slot in vtbl[]
final const(char)* name()() const nothrow {
@nogc:
extern(D):
~this() {}
final const(char)* name()() const nothrow
{
return _name[0] == '*' ? _name + 1 : _name;
}
final bool before()(const type_info _arg) const {
final bool before()(const type_info _arg) const nothrow
{
import core.stdc.string : strcmp;
return (_name[0] == '*' && _arg._name[0] == '*')
? _name < _arg._name
: strcmp(_name, _arg._name) < 0;
}
//bool operator==(const type_info) const;
bool __is_pointer_p() const;
bool __is_function_p() const;
bool __do_catch(const type_info, void**, uint) const;
bool __do_upcast(const __class_type_info, void**) const;
// dummy implementations to populate the D vtable:
bool __is_pointer_p() const { assert(0); }
bool __is_function_p() const { assert(0); };
bool __do_catch(const type_info, void**, uint) const { assert(0); };
bool __do_upcast(const __class_type_info, void**) const { assert(0); };

protected:
const(char)* _name;
this(const(char)*);

this(const(char)* name) { _name = name; }
}

class bad_cast : exception
{
this();
//~this();
override const(char)* what() const;
@nogc:
extern(D):
this() nothrow {}
override const(char)* what() const nothrow { return "bad cast"; }
}

class bad_typeid : exception
{
this();
//~this();
override const(char)* what() const;
@nogc:
extern(D):
this() nothrow {}
override const(char)* what() const nothrow { return "bad typeid"; }
}
}
else
Expand Down