/usr/lib/gcc/x86_64-linux-gnu/5/include/d/rt/cast_.d is in libphobos-5-dev 5.5.0-12ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | /**
* Implementation of array assignment support routines.
*
* Copyright: Copyright Digital Mars 2004 - 2010.
* License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Walter Bright, Sean Kelly
*/
/* Copyright Digital Mars 2004 - 2010.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
module rt.cast_;
extern (C):
/******************************************
* Given a pointer:
* If it is an Object, return that Object.
* If it is an interface, return the Object implementing the interface.
* If it is null, return null.
* Else, undefined crash
*/
Object _d_toObject(void* p)
{
if(!p)
return null;
Object o = cast(Object) p;
ClassInfo oc = typeid(o);
Interface* pi = **cast(Interface***) p;
/* Interface.offset lines up with ClassInfo.name.ptr,
* so we rely on pointers never being less than 64K,
* and Objects never being greater.
*/
if(pi.offset < 0x10000)
{
debug(cast_) printf("\tpi.offset = %d\n", pi.offset);
return cast(Object)(p - pi.offset);
}
return o;
}
/*************************************
* Attempts to cast Object o to class c.
* Returns o if successful, null if not.
*/
void* _d_interface_cast(void* p, ClassInfo c)
{
debug(cast_) printf("_d_interface_cast(p = %p, c = '%.*s')\n", p, c.name);
if(!p)
return null;
Interface* pi = **cast(Interface***) p;
debug(cast_) printf("\tpi.offset = %d\n", pi.offset);
return _d_dynamic_cast(cast(Object)(p - pi.offset), c);
}
void* _d_dynamic_cast(Object o, ClassInfo c)
{
debug(cast_) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name);
void* res = null;
size_t offset = 0;
if(o && _d_isbaseof2(typeid(o), c, offset))
{
debug(cast_) printf("\toffset = %d\n", offset);
res = cast(void*) o + offset;
}
debug(cast_) printf("\tresult = %p\n", res);
return res;
}
int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset)
{
if(oc is c)
return true;
do
{
if(oc.base is c)
return true;
foreach(iface; oc.interfaces)
{
if(iface.classinfo is c)
{
offset = iface.offset;
return true;
}
}
foreach(iface; oc.interfaces)
{
if(_d_isbaseof2(iface.classinfo, c, offset))
{
offset = iface.offset;
return true;
}
}
oc = oc.base;
}
while(oc);
return false;
}
int _d_isbaseof(ClassInfo oc, ClassInfo c)
{
if(oc is c)
return true;
do
{
if(oc.base is c)
return true;
foreach(iface; oc.interfaces)
if(iface.classinfo is c || _d_isbaseof(iface.classinfo, c))
return true;
oc = oc.base;
}
while(oc);
return false;
}
/*********************************
* Find the vtbl[] associated with Interface ic.
*/
void* _d_interface_vtbl(ClassInfo ic, Object o)
{
debug(cast_) printf("__d_interface_vtbl(o = %p, ic = %p)\n", o, ic);
assert(o);
foreach(iface; typeid(o).interfaces)
if(iface.classinfo is ic)
return cast(void*) iface.vtbl;
assert(0);
}
|