mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-02 16:11:08 +03:00
1201 lines
36 KiB
C++
1201 lines
36 KiB
C++
|
|
|
|
// Copyright (c) 1999-2004 by Digital Mars
|
|
// All Rights Reserved
|
|
// written by Walter Bright
|
|
// www.digitalmars.com
|
|
// License for redistribution is by either the Artistic License
|
|
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
|
// See the included readme.txt for details.
|
|
|
|
// Modifications for LLVMDC:
|
|
// Copyright (c) 2007 by Tomas Lindquist Olsen
|
|
// tomas at famolsen dk
|
|
|
|
#include <cstdio>
|
|
#include <cassert>
|
|
|
|
#include "gen/llvm.h"
|
|
|
|
#include "mars.h"
|
|
#include "module.h"
|
|
#include "mtype.h"
|
|
#include "scope.h"
|
|
#include "init.h"
|
|
#include "expression.h"
|
|
#include "attrib.h"
|
|
#include "declaration.h"
|
|
#include "template.h"
|
|
#include "id.h"
|
|
#include "enum.h"
|
|
#include "import.h"
|
|
#include "aggregate.h"
|
|
|
|
#include "gen/irstate.h"
|
|
#include "gen/logger.h"
|
|
#include "gen/runtime.h"
|
|
#include "gen/tollvm.h"
|
|
#include "gen/arrays.h"
|
|
#include "gen/structs.h"
|
|
#include "gen/classes.h"
|
|
|
|
#include "ir/irvar.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->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);
|
|
}
|
|
|
|
TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration()
|
|
{
|
|
return new TypeInfoDelegateDeclaration(this);
|
|
}
|
|
|
|
TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration()
|
|
{
|
|
return new TypeInfoTupleDeclaration(this);
|
|
}
|
|
|
|
|
|
/* ========================================================================= */
|
|
|
|
/* These decide if there's an instance for them already in std.typeinfo,
|
|
* because then the compiler doesn't need to build one.
|
|
*/
|
|
|
|
int Type::builtinTypeInfo()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int TypeBasic::builtinTypeInfo()
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
int TypeDArray::builtinTypeInfo()
|
|
{
|
|
return next->isTypeBasic() != NULL;
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
/***************************************
|
|
* Create a static array of TypeInfo references
|
|
* corresponding to an array of Expression's.
|
|
* Used to supply hidden _arguments[] value for variadic D functions.
|
|
*/
|
|
|
|
Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
|
|
{
|
|
assert(0);
|
|
return NULL;
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// MAGIC PLACE
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
void TypeInfoDeclaration::toObjFile()
|
|
{
|
|
gIR->resolveList.push_back(this);
|
|
}
|
|
|
|
void DtoResolveTypeInfo(TypeInfoDeclaration* tid)
|
|
{
|
|
if (tid->llvmResolved) return;
|
|
tid->llvmResolved = true;
|
|
|
|
Logger::println("DtoResolveTypeInfo(%s)", tid->toChars());
|
|
LOG_SCOPE;
|
|
|
|
tid->irGlobal = new IrGlobal(tid);
|
|
|
|
gIR->declareList.push_back(tid);
|
|
}
|
|
|
|
void DtoDeclareTypeInfo(TypeInfoDeclaration* tid)
|
|
{
|
|
if (tid->llvmDeclared) return;
|
|
tid->llvmDeclared = true;
|
|
|
|
Logger::println("DtoDeclareTypeInfo(%s)", tid->toChars());
|
|
LOG_SCOPE;
|
|
|
|
std::string mangled(tid->mangle());
|
|
|
|
Logger::println("type = '%s'", tid->tinfo->toChars());
|
|
Logger::println("typeinfo mangle: %s", mangled.c_str());
|
|
|
|
// this is a declaration of a builtin __initZ var
|
|
if (tid->tinfo->builtinTypeInfo()) {
|
|
llvm::Value* found = gIR->module->getNamedGlobal(mangled);
|
|
if (!found)
|
|
{
|
|
const llvm::Type* t = llvm::OpaqueType::get();
|
|
llvm::GlobalVariable* g = new llvm::GlobalVariable(t, true, llvm::GlobalValue::ExternalLinkage, NULL, mangled, gIR->module);
|
|
assert(g);
|
|
/*if (!tid->irGlobal)
|
|
tid->irGlobal = new IrGlobal(tid);*/
|
|
tid->irGlobal->value = g;
|
|
mangled.append("__TYPE");
|
|
gIR->module->addTypeName(mangled, tid->irGlobal->value->getType()->getContainedType(0));
|
|
Logger::println("Got typeinfo var: %s", tid->irGlobal->value->getName().c_str());
|
|
tid->llvmInitialized = true;
|
|
tid->llvmDefined = true;
|
|
}
|
|
else if (!tid->irGlobal->value) {
|
|
tid->irGlobal->value = found;
|
|
tid->llvmInitialized = true;
|
|
tid->llvmDefined = true;
|
|
}
|
|
}
|
|
// custom typedef
|
|
else {
|
|
tid->llvmDeclare();
|
|
gIR->constInitList.push_back(tid);
|
|
}
|
|
}
|
|
|
|
void DtoConstInitTypeInfo(TypeInfoDeclaration* tid)
|
|
{
|
|
if (tid->llvmInitialized) return;
|
|
tid->llvmInitialized = true;
|
|
|
|
Logger::println("DtoConstInitTypeInfo(%s)", tid->toChars());
|
|
LOG_SCOPE;
|
|
|
|
gIR->defineList.push_back(tid);
|
|
}
|
|
|
|
void DtoDefineTypeInfo(TypeInfoDeclaration* tid)
|
|
{
|
|
if (tid->llvmDefined) return;
|
|
tid->llvmDefined = true;
|
|
|
|
Logger::println("DtoDefineTypeInfo(%s)", tid->toChars());
|
|
LOG_SCOPE;
|
|
|
|
tid->llvmDefine();
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0 && "TypeInfoDeclaration::toDt");
|
|
}
|
|
|
|
void TypeInfoDeclaration::llvmDeclare()
|
|
{
|
|
assert(0 && "TypeInfoDeclaration::llvmDeclare");
|
|
}
|
|
|
|
void TypeInfoDeclaration::llvmDefine()
|
|
{
|
|
assert(0 && "TypeInfoDeclaration::llvmDeclare");
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoTypedefDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoTypedefDeclaration::llvmDeclare() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
ClassDeclaration* base = Type::typeinfotypedef;
|
|
DtoResolveClass(base);
|
|
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// create the symbol
|
|
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
|
}
|
|
|
|
void TypeInfoTypedefDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoTypedefDeclaration::llvmDefine() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
ClassDeclaration* base = Type::typeinfotypedef;
|
|
DtoForceConstInitDsymbol(base);
|
|
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
Logger::cout() << "got stype: " << *stype << '\n';
|
|
|
|
// vtbl
|
|
std::vector<llvm::Constant*> sinits;
|
|
sinits.push_back(base->irStruct->vtbl);
|
|
|
|
// monitor
|
|
sinits.push_back(getNullPtr(getPtrToType(llvm::Type::Int8Ty)));
|
|
|
|
assert(tinfo->ty == Ttypedef);
|
|
TypeTypedef *tc = (TypeTypedef *)tinfo;
|
|
TypedefDeclaration *sd = tc->sym;
|
|
|
|
// TypeInfo base
|
|
//const llvm::PointerType* basept = isaPointer(initZ->getOperand(1)->getType());
|
|
//sinits.push_back(llvm::ConstantPointerNull::get(basept));
|
|
Logger::println("generating base typeinfo");
|
|
//sd->basetype = sd->basetype->merge();
|
|
|
|
sd->basetype->getTypeInfo(NULL); // generate vtinfo
|
|
assert(sd->basetype->vtinfo);
|
|
DtoForceDeclareDsymbol(sd->basetype->vtinfo);
|
|
|
|
assert(sd->basetype->vtinfo->irGlobal->value);
|
|
assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->irGlobal->value));
|
|
llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->basetype->vtinfo->irGlobal->value);
|
|
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
|
|
sinits.push_back(castbase);
|
|
|
|
// char[] name
|
|
char *name = sd->toPrettyChars();
|
|
sinits.push_back(DtoConstString(name));
|
|
assert(sinits.back()->getType() == stype->getElementType(3));
|
|
|
|
// void[] init
|
|
const llvm::PointerType* initpt = getPtrToType(llvm::Type::Int8Ty);
|
|
if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type
|
|
{
|
|
sinits.push_back(DtoConstSlice(DtoConstSize_t(0), getNullPtr(initpt)));
|
|
}
|
|
else
|
|
{
|
|
llvm::Constant* ci = DtoConstInitializer(sd->basetype, sd->init);
|
|
std::string ciname(sd->mangle());
|
|
ciname.append("__init");
|
|
llvm::GlobalVariable* civar = new llvm::GlobalVariable(DtoType(sd->basetype),true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module);
|
|
llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt);
|
|
size_t cisize = getTypeStoreSize(DtoType(sd->basetype));
|
|
sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
|
|
}
|
|
|
|
// create the symbol
|
|
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
|
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
|
}
|
|
|
|
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoEnumDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoEnumDeclaration::llvmDeclare() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
ClassDeclaration* base = Type::typeinfoenum;
|
|
DtoResolveClass(base);
|
|
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// create the symbol
|
|
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
|
}
|
|
|
|
void TypeInfoEnumDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
ClassDeclaration* base = Type::typeinfoenum;
|
|
DtoForceConstInitDsymbol(base);
|
|
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// vtbl
|
|
std::vector<llvm::Constant*> sinits;
|
|
sinits.push_back(base->irStruct->vtbl);
|
|
|
|
// monitor
|
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
|
|
|
assert(tinfo->ty == Tenum);
|
|
TypeEnum *tc = (TypeEnum *)tinfo;
|
|
EnumDeclaration *sd = tc->sym;
|
|
|
|
// TypeInfo base
|
|
//const llvm::PointerType* basept = isaPointer(initZ->getOperand(1)->getType());
|
|
//sinits.push_back(llvm::ConstantPointerNull::get(basept));
|
|
Logger::println("generating base typeinfo");
|
|
//sd->basetype = sd->basetype->merge();
|
|
|
|
sd->memtype->getTypeInfo(NULL); // generate vtinfo
|
|
assert(sd->memtype->vtinfo);
|
|
DtoForceDeclareDsymbol(sd->memtype->vtinfo);
|
|
|
|
assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->irGlobal->value));
|
|
llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->irGlobal->value);
|
|
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
|
|
sinits.push_back(castbase);
|
|
|
|
// char[] name
|
|
char *name = sd->toPrettyChars();
|
|
sinits.push_back(DtoConstString(name));
|
|
assert(sinits.back()->getType() == stype->getElementType(3));
|
|
|
|
// void[] init
|
|
const llvm::PointerType* initpt = getPtrToType(llvm::Type::Int8Ty);
|
|
if (tinfo->isZeroInit() || !sd->defaultval) // 0 initializer, or the same as the base type
|
|
{
|
|
sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
|
|
}
|
|
else
|
|
{
|
|
const llvm::Type* memty = DtoType(sd->memtype);
|
|
llvm::Constant* ci = llvm::ConstantInt::get(memty, sd->defaultval, !sd->memtype->isunsigned());
|
|
std::string ciname(sd->mangle());
|
|
ciname.append("__init");
|
|
llvm::GlobalVariable* civar = new llvm::GlobalVariable(memty,true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module);
|
|
llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt);
|
|
size_t cisize = getTypeStoreSize(memty);
|
|
sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
|
|
}
|
|
|
|
// create the symbol
|
|
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
|
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
|
}
|
|
|
|
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
static llvm::Constant* LLVM_D_Declare_TypeInfoBase(TypeInfoDeclaration* tid, ClassDeclaration* cd)
|
|
{
|
|
ClassDeclaration* base = cd;
|
|
DtoResolveClass(base);
|
|
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// create the symbol
|
|
tid->irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
|
|
}
|
|
|
|
static llvm::Constant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
|
|
{
|
|
ClassDeclaration* base = cd;
|
|
DtoForceConstInitDsymbol(base);
|
|
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// vtbl
|
|
std::vector<llvm::Constant*> sinits;
|
|
sinits.push_back(base->irStruct->vtbl);
|
|
|
|
// monitor
|
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
|
|
|
// TypeInfo base
|
|
Logger::println("generating base typeinfo");
|
|
basetype->getTypeInfo(NULL);
|
|
assert(basetype->vtinfo);
|
|
DtoForceDeclareDsymbol(basetype->vtinfo);
|
|
assert(llvm::isa<llvm::Constant>(basetype->vtinfo->irGlobal->value));
|
|
llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->irGlobal->value);
|
|
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
|
|
sinits.push_back(castbase);
|
|
|
|
// create the symbol
|
|
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
|
isaGlobalVar(tid->irGlobal->value)->setInitializer(tiInit);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoPointerDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoPointerDeclaration::llvmDeclare() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
assert(tinfo->ty == Tpointer);
|
|
TypePointer *tc = (TypePointer *)tinfo;
|
|
|
|
LLVM_D_Declare_TypeInfoBase(this, Type::typeinfopointer);
|
|
}
|
|
|
|
void TypeInfoPointerDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoPointerDeclaration::llvmDefine() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
assert(tinfo->ty == Tpointer);
|
|
TypePointer *tc = (TypePointer *)tinfo;
|
|
|
|
LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfopointer);
|
|
}
|
|
|
|
void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoArrayDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoArrayDeclaration::llvmDeclare() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
assert(tinfo->ty == Tarray);
|
|
TypeDArray *tc = (TypeDArray *)tinfo;
|
|
|
|
LLVM_D_Declare_TypeInfoBase(this, Type::typeinfoarray);
|
|
}
|
|
|
|
void TypeInfoArrayDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoArrayDeclaration::llvmDefine() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
assert(tinfo->ty == Tarray);
|
|
TypeDArray *tc = (TypeDArray *)tinfo;
|
|
|
|
LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfoarray);
|
|
}
|
|
|
|
void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoStaticArrayDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoStaticArrayDeclaration::toDt() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
// init typeinfo class
|
|
ClassDeclaration* base = Type::typeinfostaticarray;
|
|
DtoResolveClass(base);
|
|
|
|
// get type of typeinfo class
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// create the symbol
|
|
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
|
}
|
|
|
|
void TypeInfoStaticArrayDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoStaticArrayDeclaration::toDt() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
// init typeinfo class
|
|
ClassDeclaration* base = Type::typeinfostaticarray;
|
|
DtoForceConstInitDsymbol(base);
|
|
|
|
// get type of typeinfo class
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// initializer vector
|
|
std::vector<llvm::Constant*> sinits;
|
|
// first is always the vtable
|
|
sinits.push_back(base->irStruct->vtbl);
|
|
|
|
// monitor
|
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
|
|
|
// value typeinfo
|
|
assert(tinfo->ty == Tsarray);
|
|
TypeSArray *tc = (TypeSArray *)tinfo;
|
|
tc->next->getTypeInfo(NULL);
|
|
|
|
// get symbol
|
|
assert(tc->next->vtinfo);
|
|
DtoForceDeclareDsymbol(tc->next->vtinfo);
|
|
llvm::Constant* castbase = isaConstant(tc->next->vtinfo->irGlobal->value);
|
|
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
|
|
sinits.push_back(castbase);
|
|
|
|
// length
|
|
sinits.push_back(DtoConstSize_t(tc->dim->toInteger()));
|
|
|
|
// create the symbol
|
|
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
|
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
|
}
|
|
|
|
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoAssociativeArrayDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoAssociativeArrayDeclaration::toDt() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
// init typeinfo class
|
|
ClassDeclaration* base = Type::typeinfoassociativearray;
|
|
DtoResolveClass(base);
|
|
|
|
// get type of typeinfo class
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// create the symbol
|
|
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
|
}
|
|
|
|
void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoAssociativeArrayDeclaration::toDt() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
// init typeinfo class
|
|
ClassDeclaration* base = Type::typeinfoassociativearray;
|
|
DtoForceConstInitDsymbol(base);
|
|
|
|
// get type of typeinfo class
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// initializer vector
|
|
std::vector<llvm::Constant*> sinits;
|
|
// first is always the vtable
|
|
sinits.push_back(base->irStruct->vtbl);
|
|
|
|
// monitor
|
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
|
|
|
// get type
|
|
assert(tinfo->ty == Taarray);
|
|
TypeAArray *tc = (TypeAArray *)tinfo;
|
|
|
|
// value typeinfo
|
|
tc->next->getTypeInfo(NULL);
|
|
|
|
// get symbol
|
|
assert(tc->next->vtinfo);
|
|
DtoForceDeclareDsymbol(tc->next->vtinfo);
|
|
llvm::Constant* castbase = isaConstant(tc->next->vtinfo->irGlobal->value);
|
|
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
|
|
sinits.push_back(castbase);
|
|
|
|
// key typeinfo
|
|
tc->index->getTypeInfo(NULL);
|
|
|
|
// get symbol
|
|
assert(tc->index->vtinfo);
|
|
DtoForceDeclareDsymbol(tc->index->vtinfo);
|
|
castbase = isaConstant(tc->index->vtinfo->irGlobal->value);
|
|
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(3));
|
|
sinits.push_back(castbase);
|
|
|
|
// create the symbol
|
|
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
|
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
|
}
|
|
|
|
void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoFunctionDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoFunctionDeclaration::toDt() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
assert(tinfo->ty == Tfunction);
|
|
TypeFunction *tc = (TypeFunction *)tinfo;
|
|
|
|
LLVM_D_Declare_TypeInfoBase(this, Type::typeinfofunction);
|
|
}
|
|
|
|
void TypeInfoFunctionDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoFunctionDeclaration::toDt() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
assert(tinfo->ty == Tfunction);
|
|
TypeFunction *tc = (TypeFunction *)tinfo;
|
|
|
|
LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfofunction);
|
|
}
|
|
|
|
void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoDelegateDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoDelegateDeclaration::toDt() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
assert(tinfo->ty == Tdelegate);
|
|
TypeDelegate *tc = (TypeDelegate *)tinfo;
|
|
|
|
LLVM_D_Declare_TypeInfoBase(this, Type::typeinfodelegate);
|
|
}
|
|
|
|
void TypeInfoDelegateDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoDelegateDeclaration::toDt() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
assert(tinfo->ty == Tdelegate);
|
|
TypeDelegate *tc = (TypeDelegate *)tinfo;
|
|
|
|
LLVM_D_Define_TypeInfoBase(tc->next->next, this, Type::typeinfodelegate);
|
|
}
|
|
|
|
void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoStructDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoStructDeclaration::llvmDeclare() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
assert(tinfo->ty == Tstruct);
|
|
TypeStruct *tc = (TypeStruct *)tinfo;
|
|
StructDeclaration *sd = tc->sym;
|
|
DtoResolveDsymbol(sd);
|
|
|
|
ClassDeclaration* base = Type::typeinfostruct;
|
|
DtoResolveClass(base);
|
|
|
|
const llvm::StructType* stype = isaStruct(((TypeClass*)base->type)->llvmType->get());
|
|
|
|
// create the symbol
|
|
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
|
}
|
|
|
|
void TypeInfoStructDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoStructDeclaration::llvmDefine() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
assert(tinfo->ty == Tstruct);
|
|
TypeStruct *tc = (TypeStruct *)tinfo;
|
|
StructDeclaration *sd = tc->sym;
|
|
DtoForceConstInitDsymbol(sd);
|
|
|
|
ClassDeclaration* base = Type::typeinfostruct;
|
|
DtoForceConstInitDsymbol(base);
|
|
|
|
const llvm::StructType* stype = isaStruct(((TypeClass*)base->type)->llvmType->get());
|
|
|
|
// vtbl
|
|
std::vector<llvm::Constant*> sinits;
|
|
sinits.push_back(base->irStruct->vtbl);
|
|
|
|
// monitor
|
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
|
|
|
// char[] name
|
|
char *name = sd->toPrettyChars();
|
|
sinits.push_back(DtoConstString(name));
|
|
//Logger::println("************** A");
|
|
assert(sinits.back()->getType() == stype->getElementType(2));
|
|
|
|
// void[] init
|
|
const llvm::PointerType* initpt = getPtrToType(llvm::Type::Int8Ty);
|
|
if (sd->zeroInit) // 0 initializer, or the same as the base type
|
|
{
|
|
sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
|
|
}
|
|
else
|
|
{
|
|
size_t cisize = getTypeStoreSize(tc->llvmType->get());
|
|
llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(sd->irStruct->init, initpt);
|
|
sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
|
|
}
|
|
|
|
// toX functions ground work
|
|
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
|
|
|
|
//Logger::println("************** B");
|
|
const llvm::PointerType* ptty = isaPointer(stype->getElementType(4));
|
|
assert(ptty);
|
|
|
|
s = search_function(sd, Id::tohash);
|
|
fdx = s ? s->isFuncDeclaration() : NULL;
|
|
if (fdx)
|
|
{
|
|
fd = fdx->overloadExactMatch(tftohash);
|
|
if (fd) {
|
|
DtoForceDeclareDsymbol(fd);
|
|
assert(fd->irFunc->func != 0);
|
|
llvm::Constant* c = isaConstant(fd->irFunc->func);
|
|
assert(c);
|
|
c = llvm::ConstantExpr::getBitCast(c, ptty);
|
|
sinits.push_back(c);
|
|
}
|
|
else {
|
|
//fdx->error("must be declared as extern (D) uint toHash()");
|
|
sinits.push_back(llvm::ConstantPointerNull::get(ptty));
|
|
}
|
|
}
|
|
else {
|
|
sinits.push_back(llvm::ConstantPointerNull::get(ptty));
|
|
}
|
|
|
|
s = search_function(sd, Id::eq);
|
|
fdx = s ? s->isFuncDeclaration() : NULL;
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
//Logger::println("************** C %d", i);
|
|
ptty = isaPointer(stype->getElementType(5+i));
|
|
if (fdx)
|
|
{
|
|
fd = fdx->overloadExactMatch(tfeqptr);
|
|
if (fd) {
|
|
DtoForceDeclareDsymbol(fd);
|
|
assert(fd->irFunc->func != 0);
|
|
llvm::Constant* c = isaConstant(fd->irFunc->func);
|
|
assert(c);
|
|
c = llvm::ConstantExpr::getBitCast(c, ptty);
|
|
sinits.push_back(c);
|
|
}
|
|
else {
|
|
//fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
|
|
sinits.push_back(llvm::ConstantPointerNull::get(ptty));
|
|
}
|
|
}
|
|
else {
|
|
sinits.push_back(llvm::ConstantPointerNull::get(ptty));
|
|
}
|
|
|
|
s = search_function(sd, Id::cmp);
|
|
fdx = s ? s->isFuncDeclaration() : NULL;
|
|
}
|
|
|
|
//Logger::println("************** D");
|
|
ptty = isaPointer(stype->getElementType(7));
|
|
s = search_function(sd, Id::tostring);
|
|
fdx = s ? s->isFuncDeclaration() : NULL;
|
|
if (fdx)
|
|
{
|
|
fd = fdx->overloadExactMatch(tftostring);
|
|
if (fd) {
|
|
DtoForceDeclareDsymbol(fd);
|
|
assert(fd->irFunc->func != 0);
|
|
llvm::Constant* c = isaConstant(fd->irFunc->func);
|
|
assert(c);
|
|
c = llvm::ConstantExpr::getBitCast(c, ptty);
|
|
sinits.push_back(c);
|
|
}
|
|
else {
|
|
//fdx->error("must be declared as extern (D) char[] toString()");
|
|
sinits.push_back(llvm::ConstantPointerNull::get(ptty));
|
|
}
|
|
}
|
|
else {
|
|
sinits.push_back(llvm::ConstantPointerNull::get(ptty));
|
|
}
|
|
|
|
// uint m_flags;
|
|
sinits.push_back(DtoConstUint(tc->hasPointers()));
|
|
|
|
// create the symbol
|
|
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
|
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module);
|
|
|
|
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
|
}
|
|
|
|
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoClassDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoClassDeclaration::llvmDeclare() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
// init typeinfo class
|
|
ClassDeclaration* base = Type::typeinfoclass;
|
|
assert(base);
|
|
DtoResolveClass(base);
|
|
|
|
// get type of typeinfo class
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// create the symbol
|
|
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
|
}
|
|
|
|
void TypeInfoClassDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoClassDeclaration::llvmDefine() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
// init typeinfo class
|
|
ClassDeclaration* base = Type::typeinfoclass;
|
|
assert(base);
|
|
DtoForceConstInitDsymbol(base);
|
|
|
|
// get type of typeinfo class
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// initializer vector
|
|
std::vector<llvm::Constant*> sinits;
|
|
// first is always the vtable
|
|
sinits.push_back(base->irStruct->vtbl);
|
|
|
|
// monitor
|
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
|
|
|
// get classinfo
|
|
assert(tinfo->ty == Tclass);
|
|
TypeClass *tc = (TypeClass *)tinfo;
|
|
assert(tc->sym->irStruct->classInfo);
|
|
sinits.push_back(tc->sym->irStruct->classInfo);
|
|
|
|
// create the symbol
|
|
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
|
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
|
}
|
|
|
|
void TypeInfoClassDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoInterfaceDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoInterfaceDeclaration::llvmDeclare() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
// init typeinfo class
|
|
ClassDeclaration* base = Type::typeinfointerface;
|
|
assert(base);
|
|
DtoResolveClass(base);
|
|
|
|
// get type of typeinfo class
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// create the symbol
|
|
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
|
}
|
|
|
|
void TypeInfoInterfaceDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoInterfaceDeclaration::llvmDefine() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
// init typeinfo class
|
|
ClassDeclaration* base = Type::typeinfointerface;
|
|
assert(base);
|
|
DtoForceConstInitDsymbol(base);
|
|
|
|
// get type of typeinfo class
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// initializer vector
|
|
std::vector<llvm::Constant*> sinits;
|
|
// first is always the vtable
|
|
sinits.push_back(base->irStruct->vtbl);
|
|
|
|
// monitor
|
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
|
|
|
// get classinfo
|
|
assert(tinfo->ty == Tclass);
|
|
TypeClass *tc = (TypeClass *)tinfo;
|
|
assert(tc->sym->irStruct->classInfo);
|
|
sinits.push_back(tc->sym->irStruct->classInfo);
|
|
|
|
// create the symbol
|
|
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
|
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
|
}
|
|
|
|
void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
|
|
void TypeInfoTupleDeclaration::llvmDeclare()
|
|
{
|
|
Logger::println("TypeInfoTupleDeclaration::llvmDeclare() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
// init typeinfo class
|
|
ClassDeclaration* base = Type::typeinfotypelist;
|
|
assert(base);
|
|
DtoResolveClass(base);
|
|
|
|
// get type of typeinfo class
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// create the symbol
|
|
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
|
}
|
|
|
|
void TypeInfoTupleDeclaration::llvmDefine()
|
|
{
|
|
Logger::println("TypeInfoTupleDeclaration::llvmDefine() %s", toChars());
|
|
LOG_SCOPE;
|
|
|
|
// init typeinfo class
|
|
ClassDeclaration* base = Type::typeinfotypelist;
|
|
assert(base);
|
|
DtoForceConstInitDsymbol(base);
|
|
|
|
// get type of typeinfo class
|
|
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
|
|
|
// initializer vector
|
|
std::vector<llvm::Constant*> sinits;
|
|
// first is always the vtable
|
|
sinits.push_back(base->irStruct->vtbl);
|
|
|
|
// monitor
|
|
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
|
|
|
|
// create elements array
|
|
assert(tinfo->ty == Ttuple);
|
|
TypeTuple *tu = (TypeTuple *)tinfo;
|
|
|
|
size_t dim = tu->arguments->dim;
|
|
std::vector<llvm::Constant*> arrInits;
|
|
|
|
const llvm::Type* tiTy = Type::typeinfo->type->llvmType->get();
|
|
tiTy = getPtrToType(tiTy);
|
|
|
|
for (size_t i = 0; i < dim; i++)
|
|
{
|
|
Argument *arg = (Argument *)tu->arguments->data[i];
|
|
arg->type->getTypeInfo(NULL);
|
|
DtoForceDeclareDsymbol(arg->type->vtinfo);
|
|
assert(arg->type->vtinfo->irGlobal->value);
|
|
llvm::Constant* c = isaConstant(arg->type->vtinfo->irGlobal->value);
|
|
c = llvm::ConstantExpr::getBitCast(c, tiTy);
|
|
arrInits.push_back(c);
|
|
}
|
|
|
|
// build array type
|
|
const llvm::ArrayType* arrTy = llvm::ArrayType::get(tiTy, dim);
|
|
llvm::Constant* arrC = llvm::ConstantArray::get(arrTy, arrInits);
|
|
|
|
// build the slice
|
|
llvm::Constant* slice = DtoConstSlice(DtoConstSize_t(dim), arrC);
|
|
sinits.push_back(slice);
|
|
|
|
// create the symbol
|
|
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
|
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
|
}
|
|
|
|
void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
|
|
{
|
|
assert(0);
|
|
}
|