mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-07-29 10:30:04 +02:00
[svn r56] Initial support for TypeInfo.
Enums not work. Several other bugfixes.
This commit is contained in:
702
gen/typinf.c
702
gen/typinf.c
@@ -11,6 +11,8 @@
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
#include "gen/llvm.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "module.h"
|
||||
#include "mtype.h"
|
||||
@@ -25,347 +27,171 @@
|
||||
#include "import.h"
|
||||
#include "aggregate.h"
|
||||
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/logger.h"
|
||||
#include "gen/runtime.h"
|
||||
|
||||
/*******************************************
|
||||
|
||||
* Get a canonicalized form of the TypeInfo for use with the internal
|
||||
|
||||
* runtime library routines. Canonicalized in that static arrays are
|
||||
|
||||
* represented as dynamic arrays, enums are represented by their
|
||||
|
||||
* underlying type, etc. This reduces the number of TypeInfo's needed,
|
||||
|
||||
* so we can use the custom internal ones more.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
Expression *Type::getInternalTypeInfo(Scope *sc)
|
||||
|
||||
{ TypeInfoDeclaration *tid;
|
||||
|
||||
Expression *e;
|
||||
|
||||
Type *t;
|
||||
|
||||
static TypeInfoDeclaration *internalTI[TMAX];
|
||||
|
||||
|
||||
|
||||
//printf("Type::getInternalTypeInfo() %s\n", toChars());
|
||||
|
||||
t = toBasetype();
|
||||
|
||||
switch (t->ty)
|
||||
|
||||
{
|
||||
|
||||
case Tsarray:
|
||||
|
||||
t = t->next->arrayOf(); // convert to corresponding dynamic array type
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case Tclass:
|
||||
|
||||
if (((TypeClass *)t)->sym->isInterfaceDeclaration())
|
||||
|
||||
break;
|
||||
|
||||
goto Linternal;
|
||||
|
||||
|
||||
|
||||
case Tarray:
|
||||
|
||||
if (t->next->ty != Tclass)
|
||||
|
||||
break;
|
||||
|
||||
goto Linternal;
|
||||
|
||||
|
||||
|
||||
case Tfunction:
|
||||
|
||||
case Tdelegate:
|
||||
|
||||
case Tpointer:
|
||||
|
||||
Linternal:
|
||||
|
||||
tid = internalTI[t->ty];
|
||||
|
||||
if (!tid)
|
||||
|
||||
{ tid = new TypeInfoDeclaration(t, 1);
|
||||
|
||||
internalTI[t->ty] = tid;
|
||||
|
||||
}
|
||||
|
||||
e = new VarExp(0, tid);
|
||||
|
||||
e = e->addressOf(sc);
|
||||
|
||||
//e = e->addressOf(sc);
|
||||
e->type = tid->type; // do this so we don't get redundant dereference
|
||||
|
||||
return e;
|
||||
|
||||
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
//printf("\tcalling getTypeInfo() %s\n", t->toChars());
|
||||
|
||||
return t->getTypeInfo(sc);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************
|
||||
|
||||
* Get the exact TypeInfo.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
Expression *Type::getTypeInfo(Scope *sc)
|
||||
|
||||
{
|
||||
|
||||
Expression *e;
|
||||
|
||||
Type *t;
|
||||
|
||||
|
||||
|
||||
//printf("Type::getTypeInfo() %p, %s\n", this, toChars());
|
||||
|
||||
t = merge(); // do this since not all Type's are merge'd
|
||||
|
||||
if (!t->vtinfo)
|
||||
|
||||
{ t->vtinfo = t->getTypeInfoDeclaration();
|
||||
|
||||
assert(t->vtinfo);
|
||||
|
||||
|
||||
|
||||
/* If this has a custom implementation in std/typeinfo, then
|
||||
|
||||
* do not generate a COMDAT for it.
|
||||
|
||||
*/
|
||||
|
||||
if (!t->builtinTypeInfo())
|
||||
|
||||
{ // Generate COMDAT
|
||||
|
||||
if (sc) // if in semantic() pass
|
||||
|
||||
{ // Find module that will go all the way to an object file
|
||||
|
||||
Module *m = sc->module->importedFrom;
|
||||
|
||||
m->members->push(t->vtinfo);
|
||||
|
||||
}
|
||||
|
||||
else // if in obj generation pass
|
||||
|
||||
{
|
||||
|
||||
t->vtinfo->toObjFile();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
e = new VarExp(0, t->vtinfo);
|
||||
|
||||
//e = e->addressOf(sc);
|
||||
e->type = t->vtinfo->type; // do this so we don't get redundant dereference
|
||||
|
||||
return e;
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum RET TypeFunction::retStyle()
|
||||
{
|
||||
return RETstack;
|
||||
}
|
||||
|
||||
TypeInfoDeclaration *Type::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
//printf("Type::getTypeInfoDeclaration() %s\n", toChars());
|
||||
|
||||
return new TypeInfoDeclaration(this, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeTypedef::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoTypedefDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypePointer::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoPointerDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoArrayDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoStaticArrayDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoAssociativeArrayDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoStructDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
if (sym->isInterfaceDeclaration())
|
||||
|
||||
return new TypeInfoInterfaceDeclaration(this);
|
||||
|
||||
else
|
||||
|
||||
return new TypeInfoClassDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoEnumDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoFunctionDeclaration(this);
|
||||
|
||||
}
|
||||
enum RET TypeFunction::retStyle()
|
||||
|
||||
{
|
||||
|
||||
return RETstack;
|
||||
|
||||
}
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoDelegateDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoTupleDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void TypeInfoDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
|
||||
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
|
||||
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
|
||||
void TypeInfoClassDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
|
||||
void TypeInfoDeclaration::toObjFile()
|
||||
{
|
||||
Logger::println("TypeInfoDeclaration::toObjFile()");
|
||||
LOG_SCOPE;
|
||||
Logger::println("type = '%s'", tinfo->toChars());
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
/* These decide if there's an instance for them already in std.typeinfo,
|
||||
@@ -384,7 +210,7 @@ int TypeBasic::builtinTypeInfo()
|
||||
|
||||
int TypeDArray::builtinTypeInfo()
|
||||
{
|
||||
return 0;
|
||||
return next->isTypeBasic() != NULL;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
@@ -401,3 +227,511 @@ Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// MAGIC PLACE
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TypeInfoDeclaration::toObjFile()
|
||||
{
|
||||
Logger::println("TypeInfoDeclaration::toObjFile()");
|
||||
LOG_SCOPE;
|
||||
Logger::println("type = '%s'", tinfo->toChars());
|
||||
|
||||
if (llvmTouched) return;
|
||||
else llvmTouched = true;
|
||||
|
||||
Logger::println("Getting typeinfo var: %s", mangle());
|
||||
llvmValue = LLVM_D_GetRuntimeGlobal(gIR->module, mangle());
|
||||
assert(llvmValue);
|
||||
Logger::cout() << "Got:" << '\n' << *llvmValue << '\n';
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
void TypeInfoDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoTypedefDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoEnumDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoPointerDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoArrayDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoStaticArrayDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoAssociativeArrayDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoFunctionDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoDelegateDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoStructDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoClassDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoClassDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoInterfaceDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoTupleDeclaration");
|
||||
}
|
||||
|
||||
// original dmdfe toDt code for reference
|
||||
|
||||
#if 0
|
||||
|
||||
void TypeInfoDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoDeclaration::toDt() %s\n", toChars());
|
||||
dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
|
||||
dtdword(pdt, 0); // monitor
|
||||
}
|
||||
|
||||
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars());
|
||||
|
||||
dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Ttypedef);
|
||||
|
||||
TypeTypedef *tc = (TypeTypedef *)tinfo;
|
||||
TypedefDeclaration *sd = tc->sym;
|
||||
//printf("basetype = %s\n", sd->basetype->toChars());
|
||||
|
||||
/* Put out:
|
||||
* TypeInfo base;
|
||||
* char[] name;
|
||||
* void[] m_init;
|
||||
*/
|
||||
|
||||
sd->basetype = sd->basetype->merge();
|
||||
sd->basetype->getTypeInfo(NULL); // generate vtinfo
|
||||
assert(sd->basetype->vtinfo);
|
||||
dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype
|
||||
|
||||
char *name = sd->toPrettyChars();
|
||||
size_t namelen = strlen(name);
|
||||
dtdword(pdt, namelen);
|
||||
dtabytes(pdt, TYnptr, 0, namelen + 1, name);
|
||||
|
||||
// void[] init;
|
||||
if (tinfo->isZeroInit() || !sd->init)
|
||||
{ // 0 initializer, or the same as the base type
|
||||
dtdword(pdt, 0); // init.length
|
||||
dtdword(pdt, 0); // init.ptr
|
||||
}
|
||||
else
|
||||
{
|
||||
dtdword(pdt, sd->type->size()); // init.length
|
||||
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
|
||||
}
|
||||
}
|
||||
|
||||
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoEnumDeclaration::toDt()\n");
|
||||
dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tenum);
|
||||
|
||||
TypeEnum *tc = (TypeEnum *)tinfo;
|
||||
EnumDeclaration *sd = tc->sym;
|
||||
|
||||
/* Put out:
|
||||
* TypeInfo base;
|
||||
* char[] name;
|
||||
* void[] m_init;
|
||||
*/
|
||||
|
||||
sd->memtype->getTypeInfo(NULL);
|
||||
dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for enum members
|
||||
|
||||
char *name = sd->toPrettyChars();
|
||||
size_t namelen = strlen(name);
|
||||
dtdword(pdt, namelen);
|
||||
dtabytes(pdt, TYnptr, 0, namelen + 1, name);
|
||||
|
||||
// void[] init;
|
||||
if (tinfo->isZeroInit() || !sd->defaultval)
|
||||
{ // 0 initializer, or the same as the base type
|
||||
dtdword(pdt, 0); // init.length
|
||||
dtdword(pdt, 0); // init.ptr
|
||||
}
|
||||
else
|
||||
{
|
||||
dtdword(pdt, sd->type->size()); // init.length
|
||||
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
|
||||
}
|
||||
}
|
||||
|
||||
void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoPointerDeclaration::toDt()\n");
|
||||
dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tpointer);
|
||||
|
||||
TypePointer *tc = (TypePointer *)tinfo;
|
||||
|
||||
tc->next->getTypeInfo(NULL);
|
||||
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to
|
||||
}
|
||||
|
||||
void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoArrayDeclaration::toDt()\n");
|
||||
dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tarray);
|
||||
|
||||
TypeDArray *tc = (TypeDArray *)tinfo;
|
||||
|
||||
tc->next->getTypeInfo(NULL);
|
||||
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
|
||||
}
|
||||
|
||||
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoStaticArrayDeclaration::toDt()\n");
|
||||
dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tsarray);
|
||||
|
||||
TypeSArray *tc = (TypeSArray *)tinfo;
|
||||
|
||||
tc->next->getTypeInfo(NULL);
|
||||
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
|
||||
|
||||
dtdword(pdt, tc->dim->toInteger()); // length
|
||||
}
|
||||
|
||||
void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
|
||||
dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Taarray);
|
||||
|
||||
TypeAArray *tc = (TypeAArray *)tinfo;
|
||||
|
||||
tc->next->getTypeInfo(NULL);
|
||||
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
|
||||
|
||||
tc->index->getTypeInfo(NULL);
|
||||
dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
|
||||
}
|
||||
|
||||
void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoFunctionDeclaration::toDt()\n");
|
||||
dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tfunction);
|
||||
|
||||
TypeFunction *tc = (TypeFunction *)tinfo;
|
||||
|
||||
tc->next->getTypeInfo(NULL);
|
||||
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value
|
||||
}
|
||||
|
||||
void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoDelegateDeclaration::toDt()\n");
|
||||
dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tdelegate);
|
||||
|
||||
TypeDelegate *tc = (TypeDelegate *)tinfo;
|
||||
|
||||
tc->next->next->getTypeInfo(NULL);
|
||||
dtxoff(pdt, tc->next->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value
|
||||
}
|
||||
|
||||
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
|
||||
|
||||
unsigned offset = Type::typeinfostruct->structsize;
|
||||
|
||||
dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tstruct);
|
||||
|
||||
TypeStruct *tc = (TypeStruct *)tinfo;
|
||||
StructDeclaration *sd = tc->sym;
|
||||
|
||||
/* Put out:
|
||||
* char[] name;
|
||||
* void[] init;
|
||||
* hash_t function(void*) xtoHash;
|
||||
* int function(void*,void*) xopEquals;
|
||||
* int function(void*,void*) xopCmp;
|
||||
* char[] function(void*) xtoString;
|
||||
* uint m_flags;
|
||||
*
|
||||
* name[]
|
||||
*/
|
||||
|
||||
char *name = sd->toPrettyChars();
|
||||
size_t namelen = strlen(name);
|
||||
dtdword(pdt, namelen);
|
||||
//dtabytes(pdt, TYnptr, 0, namelen + 1, name);
|
||||
dtxoff(pdt, toSymbol(), offset, TYnptr);
|
||||
offset += namelen + 1;
|
||||
|
||||
// void[] init;
|
||||
dtdword(pdt, sd->structsize); // init.length
|
||||
if (sd->zeroInit)
|
||||
dtdword(pdt, 0); // NULL for 0 initialization
|
||||
else
|
||||
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
|
||||
|
||||
FuncDeclaration *fd;
|
||||
FuncDeclaration *fdx;
|
||||
TypeFunction *tf;
|
||||
Type *ta;
|
||||
Dsymbol *s;
|
||||
|
||||
static TypeFunction *tftohash;
|
||||
static TypeFunction *tftostring;
|
||||
|
||||
if (!tftohash)
|
||||
{
|
||||
Scope sc;
|
||||
|
||||
tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
|
||||
tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
|
||||
|
||||
tftostring = new TypeFunction(NULL, Type::tchar->arrayOf(), 0, LINKd);
|
||||
tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
|
||||
}
|
||||
|
||||
TypeFunction *tfeqptr;
|
||||
{
|
||||
Scope sc;
|
||||
Arguments *arguments = new Arguments;
|
||||
Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL);
|
||||
|
||||
arguments->push(arg);
|
||||
tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
|
||||
tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc);
|
||||
}
|
||||
|
||||
#if 0
|
||||
TypeFunction *tfeq;
|
||||
{
|
||||
Scope sc;
|
||||
Array *arguments = new Array;
|
||||
Argument *arg = new Argument(In, tc, NULL, NULL);
|
||||
|
||||
arguments->push(arg);
|
||||
tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
|
||||
tfeq = (TypeFunction *)tfeq->semantic(0, &sc);
|
||||
}
|
||||
#endif
|
||||
|
||||
s = search_function(sd, Id::tohash);
|
||||
fdx = s ? s->isFuncDeclaration() : NULL;
|
||||
if (fdx)
|
||||
{ fd = fdx->overloadExactMatch(tftohash);
|
||||
if (fd)
|
||||
dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
|
||||
else
|
||||
//fdx->error("must be declared as extern (D) uint toHash()");
|
||||
dtdword(pdt, 0);
|
||||
}
|
||||
else
|
||||
dtdword(pdt, 0);
|
||||
|
||||
s = search_function(sd, Id::eq);
|
||||
fdx = s ? s->isFuncDeclaration() : NULL;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (fdx)
|
||||
{ fd = fdx->overloadExactMatch(tfeqptr);
|
||||
if (fd)
|
||||
dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
|
||||
else
|
||||
//fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
|
||||
dtdword(pdt, 0);
|
||||
}
|
||||
else
|
||||
dtdword(pdt, 0);
|
||||
|
||||
s = search_function(sd, Id::cmp);
|
||||
fdx = s ? s->isFuncDeclaration() : NULL;
|
||||
}
|
||||
|
||||
s = search_function(sd, Id::tostring);
|
||||
fdx = s ? s->isFuncDeclaration() : NULL;
|
||||
if (fdx)
|
||||
{ fd = fdx->overloadExactMatch(tftostring);
|
||||
if (fd)
|
||||
dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
|
||||
else
|
||||
//fdx->error("must be declared as extern (D) char[] toString()");
|
||||
dtdword(pdt, 0);
|
||||
}
|
||||
else
|
||||
dtdword(pdt, 0);
|
||||
|
||||
// uint m_flags;
|
||||
dtdword(pdt, tc->hasPointers());
|
||||
|
||||
// name[]
|
||||
dtnbytes(pdt, namelen + 1, name);
|
||||
}
|
||||
|
||||
void TypeInfoClassDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
|
||||
dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tclass);
|
||||
|
||||
TypeClass *tc = (TypeClass *)tinfo;
|
||||
Symbol *s;
|
||||
|
||||
if (!tc->sym->vclassinfo)
|
||||
tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
|
||||
s = tc->sym->vclassinfo->toSymbol();
|
||||
dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
|
||||
}
|
||||
|
||||
void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
|
||||
dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tclass);
|
||||
|
||||
TypeClass *tc = (TypeClass *)tinfo;
|
||||
Symbol *s;
|
||||
|
||||
if (!tc->sym->vclassinfo)
|
||||
tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
|
||||
s = tc->sym->vclassinfo->toSymbol();
|
||||
dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
|
||||
}
|
||||
|
||||
void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
|
||||
dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Ttuple);
|
||||
|
||||
TypeTuple *tu = (TypeTuple *)tinfo;
|
||||
|
||||
size_t dim = tu->arguments->dim;
|
||||
dtdword(pdt, dim); // elements.length
|
||||
|
||||
dt_t *d = NULL;
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ Argument *arg = (Argument *)tu->arguments->data[i];
|
||||
Expression *e = arg->type->getTypeInfo(NULL);
|
||||
e = e->optimize(WANTvalue);
|
||||
e->toDt(&d);
|
||||
}
|
||||
|
||||
Symbol *s;
|
||||
s = static_sym();
|
||||
s->Sdt = d;
|
||||
outdata(s);
|
||||
|
||||
dtxoff(pdt, s, 0, TYnptr); // elements.ptr
|
||||
}
|
||||
|
||||
void TypeInfoDeclaration::toObjFile()
|
||||
{
|
||||
Symbol *s;
|
||||
unsigned sz;
|
||||
Dsymbol *parent;
|
||||
|
||||
//printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection);
|
||||
|
||||
s = toSymbol();
|
||||
sz = type->size();
|
||||
|
||||
parent = this->toParent();
|
||||
s->Sclass = SCcomdat;
|
||||
s->Sfl = FLdata;
|
||||
|
||||
toDt(&s->Sdt);
|
||||
|
||||
dt_optimize(s->Sdt);
|
||||
|
||||
// See if we can convert a comdat to a comdef,
|
||||
// which saves on exe file space.
|
||||
if (s->Sclass == SCcomdat &&
|
||||
s->Sdt->dt == DT_azeros &&
|
||||
s->Sdt->DTnext == NULL)
|
||||
{
|
||||
s->Sclass = SCglobal;
|
||||
s->Sdt->dt = DT_common;
|
||||
}
|
||||
|
||||
#if ELFOBJ // Burton
|
||||
if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL)
|
||||
s->Sseg = UDATA;
|
||||
else
|
||||
s->Sseg = DATA;
|
||||
#endif /* ELFOBJ */
|
||||
outdata(s);
|
||||
if (isExport())
|
||||
obj_export(s,0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user