| 1 |
// Compiler implementation of the D programming language |
|---|
| 2 |
// Copyright (c) 1999-2010 by Digital Mars |
|---|
| 3 |
// All Rights Reserved |
|---|
| 4 |
// written by Walter Bright |
|---|
| 5 |
// http://www.digitalmars.com |
|---|
| 6 |
// License for redistribution is by either the Artistic License |
|---|
| 7 |
// in artistic.txt, or the GNU General Public License in gnu.txt. |
|---|
| 8 |
// See the included readme.txt for details. |
|---|
| 9 |
|
|---|
| 10 |
#include <stdio.h> |
|---|
| 11 |
#include <assert.h> |
|---|
| 12 |
|
|---|
| 13 |
//#include "mem.h" |
|---|
| 14 |
|
|---|
| 15 |
#include "mars.h" |
|---|
| 16 |
#include "module.h" |
|---|
| 17 |
#include "mtype.h" |
|---|
| 18 |
#include "scope.h" |
|---|
| 19 |
#include "init.h" |
|---|
| 20 |
#include "expression.h" |
|---|
| 21 |
#include "attrib.h" |
|---|
| 22 |
#include "declaration.h" |
|---|
| 23 |
#include "template.h" |
|---|
| 24 |
#include "id.h" |
|---|
| 25 |
#include "enum.h" |
|---|
| 26 |
#include "import.h" |
|---|
| 27 |
#include "aggregate.h" |
|---|
| 28 |
|
|---|
| 29 |
#ifndef TARGET_NET |
|---|
| 30 |
#include "rmem.h" |
|---|
| 31 |
#include "cc.h" |
|---|
| 32 |
#include "global.h" |
|---|
| 33 |
#include "oper.h" |
|---|
| 34 |
#include "code.h" |
|---|
| 35 |
#include "type.h" |
|---|
| 36 |
#include "dt.h" |
|---|
| 37 |
#include "cgcv.h" |
|---|
| 38 |
#include "outbuf.h" |
|---|
| 39 |
#include "irstate.h" |
|---|
| 40 |
#endif |
|---|
| 41 |
|
|---|
| 42 |
extern Symbol *static_sym(); |
|---|
| 43 |
|
|---|
| 44 |
/******************************************* |
|---|
| 45 |
* Get a canonicalized form of the TypeInfo for use with the internal |
|---|
| 46 |
* runtime library routines. Canonicalized in that static arrays are |
|---|
| 47 |
* represented as dynamic arrays, enums are represented by their |
|---|
| 48 |
* underlying type, etc. This reduces the number of TypeInfo's needed, |
|---|
| 49 |
* so we can use the custom internal ones more. |
|---|
| 50 |
*/ |
|---|
| 51 |
|
|---|
| 52 |
Expression *Type::getInternalTypeInfo(Scope *sc) |
|---|
| 53 |
{ TypeInfoDeclaration *tid; |
|---|
| 54 |
Expression *e; |
|---|
| 55 |
Type *t; |
|---|
| 56 |
static TypeInfoDeclaration *internalTI[TMAX]; |
|---|
| 57 |
|
|---|
| 58 |
//printf("Type::getInternalTypeInfo() %s\n", toChars()); |
|---|
| 59 |
t = toBasetype(); |
|---|
| 60 |
switch (t->ty) |
|---|
| 61 |
{ |
|---|
| 62 |
case Tsarray: |
|---|
| 63 |
#if 0 |
|---|
| 64 |
// convert to corresponding dynamic array type |
|---|
| 65 |
t = t->nextOf()->mutableOf()->arrayOf(); |
|---|
| 66 |
#endif |
|---|
| 67 |
break; |
|---|
| 68 |
|
|---|
| 69 |
case Tclass: |
|---|
| 70 |
if (((TypeClass *)t)->sym->isInterfaceDeclaration()) |
|---|
| 71 |
break; |
|---|
| 72 |
goto Linternal; |
|---|
| 73 |
|
|---|
| 74 |
case Tarray: |
|---|
| 75 |
// convert to corresponding dynamic array type |
|---|
| 76 |
t = t->nextOf()->mutableOf()->arrayOf(); |
|---|
| 77 |
if (t->nextOf()->ty != Tclass) |
|---|
| 78 |
break; |
|---|
| 79 |
goto Linternal; |
|---|
| 80 |
|
|---|
| 81 |
case Tfunction: |
|---|
| 82 |
case Tdelegate: |
|---|
| 83 |
case Tpointer: |
|---|
| 84 |
Linternal: |
|---|
| 85 |
tid = internalTI[t->ty]; |
|---|
| 86 |
if (!tid) |
|---|
| 87 |
{ tid = new TypeInfoDeclaration(t, 1); |
|---|
| 88 |
internalTI[t->ty] = tid; |
|---|
| 89 |
} |
|---|
| 90 |
e = new VarExp(0, tid); |
|---|
| 91 |
e = e->addressOf(sc); |
|---|
| 92 |
e->type = tid->type; // do this so we don't get redundant dereference |
|---|
| 93 |
return e; |
|---|
| 94 |
|
|---|
| 95 |
default: |
|---|
| 96 |
break; |
|---|
| 97 |
} |
|---|
| 98 |
//printf("\tcalling getTypeInfo() %s\n", t->toChars()); |
|---|
| 99 |
return t->getTypeInfo(sc); |
|---|
| 100 |
} |
|---|
| 101 |
|
|---|
| 102 |
|
|---|
| 103 |
/**************************************************** |
|---|
| 104 |
* Get the exact TypeInfo. |
|---|
| 105 |
*/ |
|---|
| 106 |
|
|---|
| 107 |
Expression *Type::getTypeInfo(Scope *sc) |
|---|
| 108 |
{ |
|---|
| 109 |
//printf("Type::getTypeInfo() %p, %s\n", this, toChars()); |
|---|
| 110 |
if (!Type::typeinfo) |
|---|
| 111 |
{ |
|---|
| 112 |
error(0, "TypeInfo not found. object.d may be incorrectly installed or corrupt, compile with -v switch"); |
|---|
| 113 |
fatal(); |
|---|
| 114 |
} |
|---|
| 115 |
|
|---|
| 116 |
Type *t = merge2(); // do this since not all Type's are merge'd |
|---|
| 117 |
if (!t->vtinfo) |
|---|
| 118 |
{ |
|---|
| 119 |
#if DMDV2 |
|---|
| 120 |
if (t->isShared()) // does both 'shared' and 'shared const' |
|---|
| 121 |
t->vtinfo = new TypeInfoSharedDeclaration(t); |
|---|
| 122 |
else if (t->isConst()) |
|---|
| 123 |
t->vtinfo = new TypeInfoConstDeclaration(t); |
|---|
| 124 |
else if (t->isImmutable()) |
|---|
| 125 |
t->vtinfo = new TypeInfoInvariantDeclaration(t); |
|---|
| 126 |
else if (t->isWild()) |
|---|
| 127 |
t->vtinfo = new TypeInfoWildDeclaration(t); |
|---|
| 128 |
else |
|---|
| 129 |
#endif |
|---|
| 130 |
t->vtinfo = t->getTypeInfoDeclaration(); |
|---|
| 131 |
assert(t->vtinfo); |
|---|
| 132 |
vtinfo = t->vtinfo; |
|---|
| 133 |
|
|---|
| 134 |
/* If this has a custom implementation in std/typeinfo, then |
|---|
| 135 |
* do not generate a COMDAT for it. |
|---|
| 136 |
*/ |
|---|
| 137 |
if (!t->builtinTypeInfo()) |
|---|
| 138 |
{ // Generate COMDAT |
|---|
| 139 |
if (sc) // if in semantic() pass |
|---|
| 140 |
{ // Find module that will go all the way to an object file |
|---|
| 141 |
Module *m = sc->module->importedFrom; |
|---|
| 142 |
m->members->push(t->vtinfo); |
|---|
| 143 |
} |
|---|
| 144 |
else // if in obj generation pass |
|---|
| 145 |
{ |
|---|
| 146 |
t->vtinfo->toObjFile(global.params.multiobj); |
|---|
| 147 |
} |
|---|
| 148 |
} |
|---|
| 149 |
} |
|---|
| 150 |
if (!vtinfo) |
|---|
| 151 |
vtinfo = t->vtinfo; // Types aren't merged, but we can share the vtinfo's |
|---|
| 152 |
Expression *e = new VarExp(0, t->vtinfo); |
|---|
| 153 |
e = e->addressOf(sc); |
|---|
| 154 |
e->type = t->vtinfo->type; // do this so we don't get redundant dereference |
|---|
| 155 |
return e; |
|---|
| 156 |
} |
|---|
| 157 |
|
|---|
| 158 |
TypeInfoDeclaration *Type::getTypeInfoDeclaration() |
|---|
| 159 |
{ |
|---|
| 160 |
//printf("Type::getTypeInfoDeclaration() %s\n", toChars()); |
|---|
| 161 |
return new TypeInfoDeclaration(this, 0); |
|---|
| 162 |
} |
|---|
| 163 |
|
|---|
| 164 |
TypeInfoDeclaration *TypeTypedef::getTypeInfoDeclaration() |
|---|
| 165 |
{ |
|---|
| 166 |
return new TypeInfoTypedefDeclaration(this); |
|---|
| 167 |
} |
|---|
| 168 |
|
|---|
| 169 |
TypeInfoDeclaration *TypePointer::getTypeInfoDeclaration() |
|---|
| 170 |
{ |
|---|
| 171 |
return new TypeInfoPointerDeclaration(this); |
|---|
| 172 |
} |
|---|
| 173 |
|
|---|
| 174 |
TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration() |
|---|
| 175 |
{ |
|---|
| 176 |
return new TypeInfoArrayDeclaration(this); |
|---|
| 177 |
} |
|---|
| 178 |
|
|---|
| 179 |
TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration() |
|---|
| 180 |
{ |
|---|
| 181 |
return new TypeInfoStaticArrayDeclaration(this); |
|---|
| 182 |
} |
|---|
| 183 |
|
|---|
| 184 |
TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration() |
|---|
| 185 |
{ |
|---|
| 186 |
return new TypeInfoAssociativeArrayDeclaration(this); |
|---|
| 187 |
} |
|---|
| 188 |
|
|---|
| 189 |
TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration() |
|---|
| 190 |
{ |
|---|
| 191 |
return new TypeInfoStructDeclaration(this); |
|---|
| 192 |
} |
|---|
| 193 |
|
|---|
| 194 |
TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration() |
|---|
| 195 |
{ |
|---|
| 196 |
if (sym->isInterfaceDeclaration()) |
|---|
| 197 |
return new TypeInfoInterfaceDeclaration(this); |
|---|
| 198 |
else |
|---|
| 199 |
return new TypeInfoClassDeclaration(this); |
|---|
| 200 |
} |
|---|
| 201 |
|
|---|
| 202 |
TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration() |
|---|
| 203 |
{ |
|---|
| 204 |
return new TypeInfoEnumDeclaration(this); |
|---|
| 205 |
} |
|---|
| 206 |
|
|---|
| 207 |
TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration() |
|---|
| 208 |
{ |
|---|
| 209 |
return new TypeInfoFunctionDeclaration(this); |
|---|
| 210 |
} |
|---|
| 211 |
|
|---|
| 212 |
TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration() |
|---|
| 213 |
{ |
|---|
| 214 |
return new TypeInfoDelegateDeclaration(this); |
|---|
| 215 |
} |
|---|
| 216 |
|
|---|
| 217 |
TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration() |
|---|
| 218 |
{ |
|---|
| 219 |
return new TypeInfoTupleDeclaration(this); |
|---|
| 220 |
} |
|---|
| 221 |
|
|---|
| 222 |
#ifndef TARGET_NET |
|---|
| 223 |
/**************************************************** |
|---|
| 224 |
*/ |
|---|
| 225 |
|
|---|
| 226 |
#if 1 |
|---|
| 227 |
|
|---|
| 228 |
void TypeInfoDeclaration::toDt(dt_t **pdt) |
|---|
| 229 |
{ |
|---|
| 230 |
//printf("TypeInfoDeclaration::toDt() %s\n", toChars()); |
|---|
| 231 |
dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo |
|---|
| 232 |
dtsize_t(pdt, 0); // monitor |
|---|
| 233 |
} |
|---|
| 234 |
|
|---|
| 235 |
#if DMDV2 |
|---|
| 236 |
void TypeInfoConstDeclaration::toDt(dt_t **pdt) |
|---|
| 237 |
{ |
|---|
| 238 |
//printf("TypeInfoConstDeclaration::toDt() %s\n", toChars()); |
|---|
| 239 |
dtxoff(pdt, Type::typeinfoconst->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Const |
|---|
| 240 |
dtsize_t(pdt, 0); // monitor |
|---|
| 241 |
Type *tm = tinfo->mutableOf(); |
|---|
| 242 |
tm = tm->merge(); |
|---|
| 243 |
tm->getTypeInfo(NULL); |
|---|
| 244 |
dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr); |
|---|
| 245 |
} |
|---|
| 246 |
|
|---|
| 247 |
void TypeInfoInvariantDeclaration::toDt(dt_t **pdt) |
|---|
| 248 |
{ |
|---|
| 249 |
//printf("TypeInfoInvariantDeclaration::toDt() %s\n", toChars()); |
|---|
| 250 |
dtxoff(pdt, Type::typeinfoinvariant->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Invariant |
|---|
| 251 |
dtsize_t(pdt, 0); // monitor |
|---|
| 252 |
Type *tm = tinfo->mutableOf(); |
|---|
| 253 |
tm = tm->merge(); |
|---|
| 254 |
tm->getTypeInfo(NULL); |
|---|
| 255 |
dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr); |
|---|
| 256 |
} |
|---|
| 257 |
|
|---|
| 258 |
void TypeInfoSharedDeclaration::toDt(dt_t **pdt) |
|---|
| 259 |
{ |
|---|
| 260 |
//printf("TypeInfoSharedDeclaration::toDt() %s\n", toChars()); |
|---|
| 261 |
dtxoff(pdt, Type::typeinfoshared->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Shared |
|---|
| 262 |
dtsize_t(pdt, 0); // monitor |
|---|
| 263 |
Type *tm = tinfo->unSharedOf(); |
|---|
| 264 |
tm = tm->merge(); |
|---|
| 265 |
tm->getTypeInfo(NULL); |
|---|
| 266 |
dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr); |
|---|
| 267 |
} |
|---|
| 268 |
|
|---|
| 269 |
void TypeInfoWildDeclaration::toDt(dt_t **pdt) |
|---|
| 270 |
{ |
|---|
| 271 |
//printf("TypeInfoWildDeclaration::toDt() %s\n", toChars()); |
|---|
| 272 |
dtxoff(pdt, Type::typeinfowild->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Wild |
|---|
| 273 |
dtsize_t(pdt, 0); // monitor |
|---|
| 274 |
Type *tm = tinfo->mutableOf(); |
|---|
| 275 |
tm = tm->merge(); |
|---|
| 276 |
tm->getTypeInfo(NULL); |
|---|
| 277 |
dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr); |
|---|
| 278 |
} |
|---|
| 279 |
|
|---|
| 280 |
#endif |
|---|
| 281 |
|
|---|
| 282 |
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) |
|---|
| 283 |
{ |
|---|
| 284 |
//printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars()); |
|---|
| 285 |
|
|---|
| 286 |
dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef |
|---|
| 287 |
dtsize_t(pdt, 0); // monitor |
|---|
| 288 |
|
|---|
| 289 |
assert(tinfo->ty == Ttypedef); |
|---|
| 290 |
|
|---|
| 291 |
TypeTypedef *tc = (TypeTypedef *)tinfo; |
|---|
| 292 |
TypedefDeclaration *sd = tc->sym; |
|---|
| 293 |
//printf("basetype = %s\n", sd->basetype->toChars()); |
|---|
| 294 |
|
|---|
| 295 |
/* Put out: |
|---|
| 296 |
* TypeInfo base; |
|---|
| 297 |
* char[] name; |
|---|
| 298 |
* void[] m_init; |
|---|
| 299 |
*/ |
|---|
| 300 |
|
|---|
| 301 |
sd->basetype = sd->basetype->merge(); |
|---|
| 302 |
sd->basetype->getTypeInfo(NULL); // generate vtinfo |
|---|
| 303 |
assert(sd->basetype->vtinfo); |
|---|
| 304 |
dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype |
|---|
| 305 |
|
|---|
| 306 |
const char *name = sd->toPrettyChars(); |
|---|
| 307 |
size_t namelen = strlen(name); |
|---|
| 308 |
dtsize_t(pdt, namelen); |
|---|
| 309 |
dtabytes(pdt, TYnptr, 0, namelen + 1, name); |
|---|
| 310 |
|
|---|
| 311 |
// void[] init; |
|---|
| 312 |
if (tinfo->isZeroInit() || !sd->init) |
|---|
| 313 |
{ // 0 initializer, or the same as the base type |
|---|
| 314 |
dtsize_t(pdt, 0); // init.length |
|---|
| 315 |
dtsize_t(pdt, 0); // init.ptr |
|---|
| 316 |
} |
|---|
| 317 |
else |
|---|
| 318 |
{ |
|---|
| 319 |
dtsize_t(pdt, sd->type->size()); // init.length |
|---|
| 320 |
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr |
|---|
| 321 |
} |
|---|
| 322 |
} |
|---|
| 323 |
|
|---|
| 324 |
void TypeInfoEnumDeclaration::toDt(dt_t **pdt) |
|---|
| 325 |
{ |
|---|
| 326 |
//printf("TypeInfoEnumDeclaration::toDt()\n"); |
|---|
| 327 |
dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum |
|---|
| 328 |
dtsize_t(pdt, 0); // monitor |
|---|
| 329 |
|
|---|
| 330 |
assert(tinfo->ty == Tenum); |
|---|
| 331 |
|
|---|
| 332 |
TypeEnum *tc = (TypeEnum *)tinfo; |
|---|
| 333 |
EnumDeclaration *sd = tc->sym; |
|---|
| 334 |
|
|---|
| 335 |
/* Put out: |
|---|
| 336 |
* TypeInfo base; |
|---|
| 337 |
* char[] name; |
|---|
| 338 |
* void[] m_init; |
|---|
| 339 |
*/ |
|---|
| 340 |
|
|---|
| 341 |
if (sd->memtype) |
|---|
| 342 |
{ sd->memtype->getTypeInfo(NULL); |
|---|
| 343 |
dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for enum members |
|---|
| 344 |
} |
|---|
| 345 |
else |
|---|
| 346 |
dtsize_t(pdt, 0); |
|---|
| 347 |
|
|---|
| 348 |
const char *name = sd->toPrettyChars(); |
|---|
| 349 |
size_t namelen = strlen(name); |
|---|
| 350 |
dtsize_t(pdt, namelen); |
|---|
| 351 |
dtabytes(pdt, TYnptr, 0, namelen + 1, name); |
|---|
| 352 |
|
|---|
| 353 |
// void[] init; |
|---|
| 354 |
if (!sd->defaultval || tinfo->isZeroInit()) |
|---|
| 355 |
{ // 0 initializer, or the same as the base type |
|---|
| 356 |
dtsize_t(pdt, 0); // init.length |
|---|
| 357 |
dtsize_t(pdt, 0); // init.ptr |
|---|
| 358 |
} |
|---|
| 359 |
else |
|---|
| 360 |
{ |
|---|
| 361 |
dtsize_t(pdt, sd->type->size()); // init.length |
|---|
| 362 |
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr |
|---|
| 363 |
} |
|---|
| 364 |
} |
|---|
| 365 |
|
|---|
| 366 |
void TypeInfoPointerDeclaration::toDt(dt_t **pdt) |
|---|
| 367 |
{ |
|---|
| 368 |
//printf("TypeInfoPointerDeclaration::toDt()\n"); |
|---|
| 369 |
dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer |
|---|
| 370 |
dtsize_t(pdt, 0); // monitor |
|---|
| 371 |
|
|---|
| 372 |
assert(tinfo->ty == Tpointer); |
|---|
| 373 |
|
|---|
| 374 |
TypePointer *tc = (TypePointer *)tinfo; |
|---|
| 375 |
|
|---|
| 376 |
tc->next->getTypeInfo(NULL); |
|---|
| 377 |
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to |
|---|
| 378 |
} |
|---|
| 379 |
|
|---|
| 380 |
void TypeInfoArrayDeclaration::toDt(dt_t **pdt) |
|---|
| 381 |
{ |
|---|
| 382 |
//printf("TypeInfoArrayDeclaration::toDt()\n"); |
|---|
| 383 |
dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array |
|---|
| 384 |
dtsize_t(pdt, 0); // monitor |
|---|
| 385 |
|
|---|
| 386 |
assert(tinfo->ty == Tarray); |
|---|
| 387 |
|
|---|
| 388 |
TypeDArray *tc = (TypeDArray *)tinfo; |
|---|
| 389 |
|
|---|
| 390 |
tc->next->getTypeInfo(NULL); |
|---|
| 391 |
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type |
|---|
| 392 |
} |
|---|
| 393 |
|
|---|
| 394 |
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt) |
|---|
| 395 |
{ |
|---|
| 396 |
//printf("TypeInfoStaticArrayDeclaration::toDt()\n"); |
|---|
| 397 |
dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray |
|---|
| 398 |
dtsize_t(pdt, 0); // monitor |
|---|
| 399 |
|
|---|
| 400 |
assert(tinfo->ty == Tsarray); |
|---|
| 401 |
|
|---|
| 402 |
TypeSArray *tc = (TypeSArray *)tinfo; |
|---|
| 403 |
|
|---|
| 404 |
tc->next->getTypeInfo(NULL); |
|---|
| 405 |
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type |
|---|
| 406 |
|
|---|
| 407 |
dtsize_t(pdt, tc->dim->toInteger()); // length |
|---|
| 408 |
} |
|---|
| 409 |
|
|---|
| 410 |
void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt) |
|---|
| 411 |
{ |
|---|
| 412 |
//printf("TypeInfoAssociativeArrayDeclaration::toDt()\n"); |
|---|
| 413 |
dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray |
|---|
| 414 |
dtsize_t(pdt, 0); // monitor |
|---|
| 415 |
|
|---|
| 416 |
assert(tinfo->ty == Taarray); |
|---|
| 417 |
|
|---|
| 418 |
TypeAArray *tc = (TypeAArray *)tinfo; |
|---|
| 419 |
|
|---|
| 420 |
tc->next->getTypeInfo(NULL); |
|---|
| 421 |
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type |
|---|
| 422 |
|
|---|
| 423 |
tc->index->getTypeInfo(NULL); |
|---|
| 424 |
dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type |
|---|
| 425 |
|
|---|
| 426 |
#if DMDV2 |
|---|
| 427 |
tc->getImpl()->type->getTypeInfo(NULL); |
|---|
| 428 |
dtxoff(pdt, tc->getImpl()->type->vtinfo->toSymbol(), 0, TYnptr); // impl |
|---|
| 429 |
#endif |
|---|
| 430 |
} |
|---|
| 431 |
|
|---|
| 432 |
void TypeInfoFunctionDeclaration::toDt(dt_t **pdt) |
|---|
| 433 |
{ |
|---|
| 434 |
//printf("TypeInfoFunctionDeclaration::toDt()\n"); |
|---|
| 435 |
dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function |
|---|
| 436 |
dtsize_t(pdt, 0); // monitor |
|---|
| 437 |
|
|---|
| 438 |
assert(tinfo->ty == Tfunction); |
|---|
| 439 |
|
|---|
| 440 |
TypeFunction *tc = (TypeFunction *)tinfo; |
|---|
| 441 |
|
|---|
| 442 |
tc->next->getTypeInfo(NULL); |
|---|
| 443 |
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value |
|---|
| 444 |
} |
|---|
| 445 |
|
|---|
| 446 |
void TypeInfoDelegateDeclaration::toDt(dt_t **pdt) |
|---|
| 447 |
{ |
|---|
| 448 |
//printf("TypeInfoDelegateDeclaration::toDt()\n"); |
|---|
| 449 |
dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate |
|---|
| 450 |
dtsize_t(pdt, 0); // monitor |
|---|
| 451 |
|
|---|
| 452 |
assert(tinfo->ty == Tdelegate); |
|---|
| 453 |
|
|---|
| 454 |
TypeDelegate *tc = (TypeDelegate *)tinfo; |
|---|
| 455 |
|
|---|
| 456 |
tc->next->nextOf()->getTypeInfo(NULL); |
|---|
| 457 |
dtxoff(pdt, tc->next->nextOf()->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value |
|---|
| 458 |
} |
|---|
| 459 |
|
|---|
| 460 |
void TypeInfoStructDeclaration::toDt(dt_t **pdt) |
|---|
| 461 |
{ |
|---|
| 462 |
//printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars()); |
|---|
| 463 |
|
|---|
| 464 |
unsigned offset = Type::typeinfostruct->structsize; |
|---|
| 465 |
|
|---|
| 466 |
dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct |
|---|
| 467 |
dtsize_t(pdt, 0); // monitor |
|---|
| 468 |
|
|---|
| 469 |
assert(tinfo->ty == Tstruct); |
|---|
| 470 |
|
|---|
| 471 |
TypeStruct *tc = (TypeStruct *)tinfo; |
|---|
| 472 |
StructDeclaration *sd = tc->sym; |
|---|
| 473 |
|
|---|
| 474 |
/* Put out: |
|---|
| 475 |
* char[] name; |
|---|
| 476 |
* void[] init; |
|---|
| 477 |
* hash_t function(in void*) xtoHash; |
|---|
| 478 |
* bool function(in void*, in void*) xopEquals; |
|---|
| 479 |
* int function(in void*, in void*) xopCmp; |
|---|
| 480 |
* string function(const(void)*) xtoString; |
|---|
| 481 |
* uint m_flags; |
|---|
| 482 |
* xgetMembers; |
|---|
| 483 |
* xdtor; |
|---|
| 484 |
* xpostblit; |
|---|
| 485 |
* uint m_align; |
|---|
| 486 |
* version (X86_64) |
|---|
| 487 |
* TypeInfo m_arg1; |
|---|
| 488 |
* TypeInfo m_arg2; |
|---|
| 489 |
* |
|---|
| 490 |
* name[] |
|---|
| 491 |
*/ |
|---|
| 492 |
|
|---|
| 493 |
const char *name = sd->toPrettyChars(); |
|---|
| 494 |
size_t namelen = strlen(name); |
|---|
| 495 |
dtsize_t(pdt, namelen); |
|---|
| 496 |
//dtabytes(pdt, TYnptr, 0, namelen + 1, name); |
|---|
| 497 |
dtxoff(pdt, toSymbol(), offset, TYnptr); |
|---|
| 498 |
offset += namelen + 1; |
|---|
| 499 |
|
|---|
| 500 |
// void[] init; |
|---|
| 501 |
dtsize_t(pdt, sd->structsize); // init.length |
|---|
| 502 |
if (sd->zeroInit) |
|---|
| 503 |
dtsize_t(pdt, 0); // NULL for 0 initialization |
|---|
| 504 |
else |
|---|
| 505 |
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr |
|---|
| 506 |
|
|---|
| 507 |
FuncDeclaration *fd; |
|---|
| 508 |
FuncDeclaration *fdx; |
|---|
| 509 |
TypeFunction *tf; |
|---|
| 510 |
Type *ta; |
|---|
| 511 |
Dsymbol *s; |
|---|
| 512 |
|
|---|
| 513 |
static TypeFunction *tftohash; |
|---|
| 514 |
static TypeFunction *tftostring; |
|---|
| 515 |
|
|---|
| 516 |
if (!tftohash) |
|---|
| 517 |
{ |
|---|
| 518 |
Scope sc; |
|---|
| 519 |
|
|---|
| 520 |
tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd); |
|---|
| 521 |
tftohash->mod = MODconst; |
|---|
| 522 |
tftohash = (TypeFunction *)tftohash->semantic(0, &sc); |
|---|
| 523 |
|
|---|
| 524 |
tftostring = new TypeFunction(NULL, Type::tchar->invariantOf()->arrayOf(), 0, LINKd); |
|---|
| 525 |
tftostring = (TypeFunction *)tftostring->semantic(0, &sc); |
|---|
| 526 |
} |
|---|
| 527 |
|
|---|
| 528 |
TypeFunction *tfcmpptr; |
|---|
| 529 |
{ |
|---|
| 530 |
Scope sc; |
|---|
| 531 |
Parameters *arguments = new Parameters; |
|---|
| 532 |
#if STRUCTTHISREF |
|---|
| 533 |
// arg type is ref const T |
|---|
| 534 |
Parameter *arg = new Parameter(STCref, tc->constOf(), NULL, NULL); |
|---|
| 535 |
#else |
|---|
| 536 |
// arg type is const T* |
|---|
| 537 |
Parameter *arg = new Parameter(STCin, tc->pointerTo(), NULL, NULL); |
|---|
| 538 |
#endif |
|---|
| 539 |
|
|---|
| 540 |
arguments->push(arg); |
|---|
| 541 |
tfcmpptr = new TypeFunction(arguments, Type::tint32, 0, LINKd); |
|---|
| 542 |
tfcmpptr->mod = MODconst; |
|---|
| 543 |
tfcmpptr = (TypeFunction *)tfcmpptr->semantic(0, &sc); |
|---|
| 544 |
} |
|---|
| 545 |
|
|---|
| 546 |
s = search_function(sd, Id::tohash); |
|---|
| 547 |
fdx = s ? s->isFuncDeclaration() : NULL; |
|---|
| 548 |
if (fdx) |
|---|
| 549 |
{ fd = fdx->overloadExactMatch(tftohash); |
|---|
| 550 |
if (fd) |
|---|
| 551 |
dtxoff(pdt, fd->toSymbol(), 0, TYnptr); |
|---|
| 552 |
else |
|---|
| 553 |
//fdx->error("must be declared as extern (D) uint toHash()"); |
|---|
| 554 |
dtsize_t(pdt, 0); |
|---|
| 555 |
} |
|---|
| 556 |
else |
|---|
| 557 |
dtsize_t(pdt, 0); |
|---|
| 558 |
|
|---|
| 559 |
if (sd->eq) |
|---|
| 560 |
dtxoff(pdt, sd->eq->toSymbol(), 0, TYnptr); |
|---|
| 561 |
else |
|---|
| 562 |
dtsize_t(pdt, 0); |
|---|
| 563 |
|
|---|
| 564 |
s = search_function(sd, Id::cmp); |
|---|
| 565 |
fdx = s ? s->isFuncDeclaration() : NULL; |
|---|
| 566 |
if (fdx) |
|---|
| 567 |
{ |
|---|
| 568 |
//printf("test1 %s, %s, %s\n", fdx->toChars(), fdx->type->toChars(), tfeqptr->toChars()); |
|---|
| 569 |
fd = fdx->overloadExactMatch(tfcmpptr); |
|---|
| 570 |
if (fd) |
|---|
| 571 |
{ dtxoff(pdt, fd->toSymbol(), 0, TYnptr); |
|---|
| 572 |
//printf("test2\n"); |
|---|
| 573 |
} |
|---|
| 574 |
else |
|---|
| 575 |
//fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars()); |
|---|
| 576 |
dtsize_t(pdt, 0); |
|---|
| 577 |
} |
|---|
| 578 |
else |
|---|
| 579 |
dtsize_t(pdt, 0); |
|---|
| 580 |
|
|---|
| 581 |
s = search_function(sd, Id::tostring); |
|---|
| 582 |
fdx = s ? s->isFuncDeclaration() : NULL; |
|---|
| 583 |
if (fdx) |
|---|
| 584 |
{ fd = fdx->overloadExactMatch(tftostring); |
|---|
| 585 |
if (fd) |
|---|
| 586 |
dtxoff(pdt, fd->toSymbol(), 0, TYnptr); |
|---|
| 587 |
else |
|---|
| 588 |
//fdx->error("must be declared as extern (D) char[] toString()"); |
|---|
| 589 |
dtsize_t(pdt, 0); |
|---|
| 590 |
} |
|---|
| 591 |
else |
|---|
| 592 |
dtsize_t(pdt, 0); |
|---|
| 593 |
|
|---|
| 594 |
// uint m_flags; |
|---|
| 595 |
dtsize_t(pdt, tc->hasPointers()); |
|---|
| 596 |
|
|---|
| 597 |
#if DMDV2 |
|---|
| 598 |
// xgetMembers |
|---|
| 599 |
FuncDeclaration *sgetmembers = sd->findGetMembers(); |
|---|
| 600 |
if (sgetmembers) |
|---|
| 601 |
dtxoff(pdt, sgetmembers->toSymbol(), 0, TYnptr); |
|---|
| 602 |
else |
|---|
| 603 |
dtsize_t(pdt, 0); // xgetMembers |
|---|
| 604 |
|
|---|
| 605 |
// xdtor |
|---|
| 606 |
FuncDeclaration *sdtor = sd->dtor; |
|---|
| 607 |
if (sdtor) |
|---|
| 608 |
dtxoff(pdt, sdtor->toSymbol(), 0, TYnptr); |
|---|
| 609 |
else |
|---|
| 610 |
dtsize_t(pdt, 0); // xdtor |
|---|
| 611 |
|
|---|
| 612 |
// xpostblit |
|---|
| 613 |
FuncDeclaration *spostblit = sd->postblit; |
|---|
| 614 |
if (spostblit) |
|---|
| 615 |
dtxoff(pdt, spostblit->toSymbol(), 0, TYnptr); |
|---|
| 616 |
else |
|---|
| 617 |
dtsize_t(pdt, 0); // xpostblit |
|---|
| 618 |
#endif |
|---|
| 619 |
|
|---|
| 620 |
// uint m_align; |
|---|
| 621 |
dtsize_t(pdt, tc->alignsize()); |
|---|
| 622 |
|
|---|
| 623 |
if (global.params.isX86_64) |
|---|
| 624 |
{ |
|---|
| 625 |
TypeTuple *tup = tc->toArgTypes(); |
|---|
| 626 |
assert(tup->arguments->dim <= 2); |
|---|
| 627 |
for (int i = 0; i < 2; i++) |
|---|
| 628 |
{ |
|---|
| 629 |
if (i < tup->arguments->dim) |
|---|
| 630 |
{ |
|---|
| 631 |
Type *targ = ((Parameter *)tup->arguments->data[i])->type; |
|---|
| 632 |
targ = targ->merge(); |
|---|
| 633 |
targ->getTypeInfo(NULL); |
|---|
| 634 |
dtxoff(pdt, targ->vtinfo->toSymbol(), 0, TYnptr); // m_argi |
|---|
| 635 |
} |
|---|
| 636 |
else |
|---|
| 637 |
dtsize_t(pdt, 0); // m_argi |
|---|
| 638 |
} |
|---|
| 639 |
} |
|---|
| 640 |
|
|---|
| 641 |
// name[] |
|---|
| 642 |
dtnbytes(pdt, namelen + 1, name); |
|---|
| 643 |
} |
|---|
| 644 |
|
|---|
| 645 |
void TypeInfoClassDeclaration::toDt(dt_t **pdt) |
|---|
| 646 |
{ |
|---|
| 647 |
//printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars()); |
|---|
| 648 |
#if DMDV1 |
|---|
| 649 |
dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass |
|---|
| 650 |
dtsize_t(pdt, 0); // monitor |
|---|
| 651 |
|
|---|
| 652 |
assert(tinfo->ty == Tclass); |
|---|
| 653 |
|
|---|
| 654 |
TypeClass *tc = (TypeClass *)tinfo; |
|---|
| 655 |
Symbol *s; |
|---|
| 656 |
|
|---|
| 657 |
if (!tc->sym->vclassinfo) |
|---|
| 658 |
tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym); |
|---|
| 659 |
s = tc->sym->vclassinfo->toSymbol(); |
|---|
| 660 |
dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo |
|---|
| 661 |
#else |
|---|
| 662 |
assert(0); |
|---|
| 663 |
#endif |
|---|
| 664 |
} |
|---|
| 665 |
|
|---|
| 666 |
void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt) |
|---|
| 667 |
{ |
|---|
| 668 |
//printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars()); |
|---|
| 669 |
dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface |
|---|
| 670 |
dtsize_t(pdt, 0); // monitor |
|---|
| 671 |
|
|---|
| 672 |
assert(tinfo->ty == Tclass); |
|---|
| 673 |
|
|---|
| 674 |
TypeClass *tc = (TypeClass *)tinfo; |
|---|
| 675 |
Symbol *s; |
|---|
| 676 |
|
|---|
| 677 |
if (!tc->sym->vclassinfo) |
|---|
| 678 |
#if DMDV1 |
|---|
| 679 |
tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym); |
|---|
| 680 |
#else |
|---|
| 681 |
tc->sym->vclassinfo = new TypeInfoClassDeclaration(tc); |
|---|
| 682 |
#endif |
|---|
| 683 |
s = tc->sym->vclassinfo->toSymbol(); |
|---|
| 684 |
dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo |
|---|
| 685 |
} |
|---|
| 686 |
|
|---|
| 687 |
void TypeInfoTupleDeclaration::toDt(dt_t **pdt) |
|---|
| 688 |
{ |
|---|
| 689 |
//printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars()); |
|---|
| 690 |
dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface |
|---|
| 691 |
dtsize_t(pdt, 0); // monitor |
|---|
| 692 |
|
|---|
| 693 |
assert(tinfo->ty == Ttuple); |
|---|
| 694 |
|
|---|
| 695 |
TypeTuple *tu = (TypeTuple *)tinfo; |
|---|
| 696 |
|
|---|
| 697 |
size_t dim = tu->arguments->dim; |
|---|
| 698 |
dtsize_t(pdt, dim); // elements.length |
|---|
| 699 |
|
|---|
| 700 |
dt_t *d = NULL; |
|---|
| 701 |
for (size_t i = 0; i < dim; i++) |
|---|
| 702 |
{ Parameter *arg = (Parameter *)tu->arguments->data[i]; |
|---|
| 703 |
Expression *e = arg->type->getTypeInfo(NULL); |
|---|
| 704 |
e = e->optimize(WANTvalue); |
|---|
| 705 |
e->toDt(&d); |
|---|
| 706 |
} |
|---|
| 707 |
|
|---|
| 708 |
Symbol *s; |
|---|
| 709 |
s = static_sym(); |
|---|
| 710 |
s->Sdt = d; |
|---|
| 711 |
outdata(s); |
|---|
| 712 |
|
|---|
| 713 |
dtxoff(pdt, s, 0, TYnptr); // elements.ptr |
|---|
| 714 |
} |
|---|
| 715 |
|
|---|
| 716 |
void TypeInfoDeclaration::toObjFile(int multiobj) |
|---|
| 717 |
{ |
|---|
| 718 |
Symbol *s; |
|---|
| 719 |
unsigned sz; |
|---|
| 720 |
Dsymbol *parent; |
|---|
| 721 |
|
|---|
| 722 |
//printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection); |
|---|
| 723 |
|
|---|
| 724 |
if (multiobj) |
|---|
| 725 |
{ |
|---|
| 726 |
obj_append(this); |
|---|
| 727 |
return; |
|---|
| 728 |
} |
|---|
| 729 |
|
|---|
| 730 |
s = toSymbol(); |
|---|
| 731 |
sz = type->size(); |
|---|
| 732 |
|
|---|
| 733 |
parent = this->toParent(); |
|---|
| 734 |
s->Sclass = SCcomdat; |
|---|
| 735 |
s->Sfl = FLdata; |
|---|
| 736 |
|
|---|
| 737 |
toDt(&s->Sdt); |
|---|
| 738 |
|
|---|
| 739 |
dt_optimize(s->Sdt); |
|---|
| 740 |
|
|---|
| 741 |
// See if we can convert a comdat to a comdef, |
|---|
| 742 |
// which saves on exe file space. |
|---|
| 743 |
if (s->Sclass == SCcomdat && |
|---|
| 744 |
s->Sdt->dt == DT_azeros && |
|---|
| 745 |
s->Sdt->DTnext == NULL) |
|---|
| 746 |
{ |
|---|
| 747 |
s->Sclass = SCglobal; |
|---|
| 748 |
s->Sdt->dt = DT_common; |
|---|
| 749 |
} |
|---|
| 750 |
|
|---|
| 751 |
#if ELFOBJ || MACHOBJ // Burton |
|---|
| 752 |
if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL) |
|---|
| 753 |
s->Sseg = UDATA; |
|---|
| 754 |
else |
|---|
| 755 |
s->Sseg = DATA; |
|---|
| 756 |
#endif |
|---|
| 757 |
outdata(s); |
|---|
| 758 |
if (isExport()) |
|---|
| 759 |
obj_export(s,0); |
|---|
| 760 |
} |
|---|
| 761 |
|
|---|
| 762 |
#endif |
|---|
| 763 |
#endif // TARGET_NET |
|---|
| 764 |
|
|---|
| 765 |
/* ========================================================================= */ |
|---|
| 766 |
|
|---|
| 767 |
/* These decide if there's an instance for them already in std.typeinfo, |
|---|
| 768 |
* because then the compiler doesn't need to build one. |
|---|
| 769 |
*/ |
|---|
| 770 |
|
|---|
| 771 |
int Type::builtinTypeInfo() |
|---|
| 772 |
{ |
|---|
| 773 |
return 0; |
|---|
| 774 |
} |
|---|
| 775 |
|
|---|
| 776 |
int TypeBasic::builtinTypeInfo() |
|---|
| 777 |
{ |
|---|
| 778 |
#if DMDV2 |
|---|
| 779 |
return mod ? 0 : 1; |
|---|
| 780 |
#else |
|---|
| 781 |
return 1; |
|---|
| 782 |
#endif |
|---|
| 783 |
} |
|---|
| 784 |
|
|---|
| 785 |
int TypeDArray::builtinTypeInfo() |
|---|
| 786 |
{ |
|---|
| 787 |
#if DMDV2 |
|---|
| 788 |
return !mod && (next->isTypeBasic() != NULL && !next->mod || |
|---|
| 789 |
// strings are so common, make them builtin |
|---|
| 790 |
next->ty == Tchar && next->mod == MODimmutable); |
|---|
| 791 |
#else |
|---|
| 792 |
return next->isTypeBasic() != NULL; |
|---|
| 793 |
#endif |
|---|
| 794 |
} |
|---|
| 795 |
|
|---|
| 796 |
int TypeClass::builtinTypeInfo() |
|---|
| 797 |
{ |
|---|
| 798 |
/* This is statically put out with the ClassInfo, so |
|---|
| 799 |
* claim it is built in so it isn't regenerated by each module. |
|---|
| 800 |
*/ |
|---|
| 801 |
#if DMDV2 |
|---|
| 802 |
return mod ? 0 : 1; |
|---|
| 803 |
#else |
|---|
| 804 |
return 1; |
|---|
| 805 |
#endif |
|---|
| 806 |
} |
|---|
| 807 |
|
|---|
| 808 |
/* ========================================================================= */ |
|---|
| 809 |
|
|---|
| 810 |
/*************************************** |
|---|
| 811 |
* Create a static array of TypeInfo references |
|---|
| 812 |
* corresponding to an array of Expression's. |
|---|
| 813 |
* Used to supply hidden _arguments[] value for variadic D functions. |
|---|
| 814 |
*/ |
|---|
| 815 |
|
|---|
| 816 |
Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim) |
|---|
| 817 |
{ |
|---|
| 818 |
#if 1 |
|---|
| 819 |
/* Get the corresponding TypeInfo_Tuple and |
|---|
| 820 |
* point at its elements[]. |
|---|
| 821 |
*/ |
|---|
| 822 |
|
|---|
| 823 |
/* Create the TypeTuple corresponding to the types of args[] |
|---|
| 824 |
*/ |
|---|
| 825 |
Parameters *args = new Parameters; |
|---|
| 826 |
args->setDim(dim); |
|---|
| 827 |
for (size_t i = 0; i < dim; i++) |
|---|
| 828 |
{ Parameter *arg = new Parameter(STCin, exps[i]->type, NULL, NULL); |
|---|
| 829 |
args->data[i] = (void *)arg; |
|---|
| 830 |
} |
|---|
| 831 |
TypeTuple *tup = new TypeTuple(args); |
|---|
| 832 |
Expression *e = tup->getTypeInfo(sc); |
|---|
| 833 |
e = e->optimize(WANTvalue); |
|---|
| 834 |
assert(e->op == TOKsymoff); // should be SymOffExp |
|---|
| 835 |
|
|---|
| 836 |
#if BREAKABI |
|---|
| 837 |
/* |
|---|
| 838 |
* Should just pass a reference to TypeInfo_Tuple instead, |
|---|
| 839 |
* but that would require existing code to be recompiled. |
|---|
| 840 |
* Source compatibility can be maintained by computing _arguments[] |
|---|
| 841 |
* at the start of the called function by offseting into the |
|---|
| 842 |
* TypeInfo_Tuple reference. |
|---|
| 843 |
*/ |
|---|
| 844 |
|
|---|
| 845 |
#else |
|---|
| 846 |
// Advance to elements[] member of TypeInfo_Tuple |
|---|
| 847 |
SymOffExp *se = (SymOffExp *)e; |
|---|
| 848 |
se->offset += PTRSIZE + PTRSIZE; |
|---|
| 849 |
|
|---|
| 850 |
// Set type to TypeInfo[]* |
|---|
| 851 |
se->type = Type::typeinfo->type->arrayOf()->pointerTo(); |
|---|
| 852 |
|
|---|
| 853 |
// Indirect to get the _arguments[] value |
|---|
| 854 |
e = new PtrExp(0, se); |
|---|
| 855 |
e->type = se->type->next; |
|---|
| 856 |
#endif |
|---|
| 857 |
return e; |
|---|
| 858 |
#else |
|---|
| 859 |
/* Improvements: |
|---|
| 860 |
* 1) create an array literal instead, |
|---|
| 861 |
* as it would eliminate the extra dereference of loading the |
|---|
| 862 |
* static variable. |
|---|
| 863 |
*/ |
|---|
| 864 |
|
|---|
| 865 |
ArrayInitializer *ai = new ArrayInitializer(0); |
|---|
| 866 |
VarDeclaration *v; |
|---|
| 867 |
Type *t; |
|---|
| 868 |
Expression *e; |
|---|
| 869 |
OutBuffer buf; |
|---|
| 870 |
Identifier *id; |
|---|
| 871 |
char *name; |
|---|
| 872 |
|
|---|
| 873 |
// Generate identifier for _arguments[] |
|---|
| 874 |
buf.writestring("_arguments_"); |
|---|
| 875 |
for (int i = 0; i < dim; i++) |
|---|
| 876 |
{ t = exps[i]->type; |
|---|
| 877 |
t->toDecoBuffer(&buf); |
|---|
| 878 |
} |
|---|
| 879 |
buf.writeByte(0); |
|---|
| 880 |
id = Lexer::idPool((char *)buf.data); |
|---|
| 881 |
|
|---|
| 882 |
Module *m = sc->module; |
|---|
| 883 |
Dsymbol *s = m->symtab->lookup(id); |
|---|
| 884 |
|
|---|
| 885 |
if (s && s->parent == m) |
|---|
| 886 |
{ // Use existing one |
|---|
| 887 |
v = s->isVarDeclaration(); |
|---|
| 888 |
assert(v); |
|---|
| 889 |
} |
|---|
| 890 |
else |
|---|
| 891 |
{ // Generate new one |
|---|
| 892 |
|
|---|
| 893 |
for (int i = 0; i < dim; i++) |
|---|
| 894 |
{ t = exps[i]->type; |
|---|
| 895 |
e = t->getTypeInfo(sc); |
|---|
| 896 |
ai->addInit(new IntegerExp(i), new ExpInitializer(0, e)); |
|---|
| 897 |
} |
|---|
| 898 |
|
|---|
| 899 |
t = Type::typeinfo->type->arrayOf(); |
|---|
| 900 |
ai->type = t; |
|---|
| 901 |
v = new VarDeclaration(0, t, id, ai); |
|---|
| 902 |
m->members->push(v); |
|---|
| 903 |
m->symtabInsert(v); |
|---|
| 904 |
sc = sc->push(); |
|---|
| 905 |
sc->linkage = LINKc; |
|---|
| 906 |
sc->stc = STCstatic | STCcomdat; |
|---|
| 907 |
ai->semantic(sc, t); |
|---|
| 908 |
v->semantic(sc); |
|---|
| 909 |
v->parent = m; |
|---|
| 910 |
sc = sc->pop(); |
|---|
| 911 |
} |
|---|
| 912 |
e = new VarExp(0, v); |
|---|
| 913 |
e = e->semantic(sc); |
|---|
| 914 |
return e; |
|---|
| 915 |
#endif |
|---|
| 916 |
} |
|---|