mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-07 11:26:02 +03:00
Cleaned up TypeInfo generation, still need to do TypeInfo_Struct/Tuple. Eventually do ClassInfo and ModuleInfo as well using same interface.
This commit is contained in:
parent
371cdb71ba
commit
f3c7278e88
3 changed files with 219 additions and 238 deletions
93
gen/rttibuilder.cpp
Normal file
93
gen/rttibuilder.cpp
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
#include "gen/llvm.h"
|
||||||
|
|
||||||
|
#include "aggregate.h"
|
||||||
|
#include "mtype.h"
|
||||||
|
|
||||||
|
#include "gen/arrays.h"
|
||||||
|
#include "gen/irstate.h"
|
||||||
|
#include "gen/linkage.h"
|
||||||
|
#include "gen/llvmhelpers.h"
|
||||||
|
#include "gen/rttibuilder.h"
|
||||||
|
#include "gen/tollvm.h"
|
||||||
|
|
||||||
|
#include "ir/irstruct.h"
|
||||||
|
|
||||||
|
TypeInfoBuilder::TypeInfoBuilder(ClassDeclaration* base_class)
|
||||||
|
{
|
||||||
|
// make sure the base typeinfo class has been processed
|
||||||
|
base_class->codegen(Type::sir);
|
||||||
|
|
||||||
|
base = base_class;
|
||||||
|
basetype = (TypeClass*)base->type;
|
||||||
|
|
||||||
|
baseir = base->ir.irStruct;
|
||||||
|
assert(baseir && "no IrStruct for TypeInfo base class");
|
||||||
|
|
||||||
|
// just start with adding the vtbl
|
||||||
|
inits.push_back(baseir->getVtblSymbol());
|
||||||
|
// and monitor
|
||||||
|
push_null_vp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeInfoBuilder::push(llvm::Constant* C)
|
||||||
|
{
|
||||||
|
inits.push_back(C);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeInfoBuilder::push_null_vp()
|
||||||
|
{
|
||||||
|
inits.push_back(getNullValue(getVoidPtrType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeInfoBuilder::push_typeinfo(Type* t)
|
||||||
|
{
|
||||||
|
inits.push_back(DtoTypeInfoOf(t, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeInfoBuilder::push_classinfo(ClassDeclaration* cd)
|
||||||
|
{
|
||||||
|
inits.push_back(cd->ir.irStruct->getClassInfoSymbol());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeInfoBuilder::push_string(const char* str)
|
||||||
|
{
|
||||||
|
inits.push_back(DtoConstString(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeInfoBuilder::push_null_void_array()
|
||||||
|
{
|
||||||
|
const llvm::Type* T = DtoType(Type::tvoid->arrayOf());
|
||||||
|
inits.push_back(getNullValue(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeInfoBuilder::push_void_array(size_t dim, llvm::Constant* ptr)
|
||||||
|
{
|
||||||
|
inits.push_back(DtoConstSlice(
|
||||||
|
DtoConstSize_t(dim),
|
||||||
|
DtoBitCast(ptr, getVoidPtrType())));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeInfoBuilder::push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* sym)
|
||||||
|
{
|
||||||
|
std::string initname(sym->mangle());
|
||||||
|
initname.append("13__defaultInitZ");
|
||||||
|
|
||||||
|
LLGlobalVariable* G = new llvm::GlobalVariable(
|
||||||
|
CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname, gIR->module);
|
||||||
|
G->setAlignment(valtype->alignsize());
|
||||||
|
|
||||||
|
size_t dim = getTypePaddedSize(CI->getType());
|
||||||
|
push_void_array(dim, G);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TypeInfoBuilder::finalize(IrGlobal* tid)
|
||||||
|
{
|
||||||
|
// create the inititalizer
|
||||||
|
LLConstant* tiInit = llvm::ConstantStruct::get(&inits[0], inits.size(), false);
|
||||||
|
|
||||||
|
// refine global type
|
||||||
|
llvm::cast<llvm::OpaqueType>(tid->type.get())->refineAbstractTypeTo(tiInit->getType());
|
||||||
|
|
||||||
|
// set the initializer
|
||||||
|
isaGlobalVar(tid->value)->setInitializer(tiInit);
|
||||||
|
}
|
34
gen/rttibuilder.h
Normal file
34
gen/rttibuilder.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef __LDC_GEN_RTTIBUILDER_H__
|
||||||
|
#define __LDC_GEN_RTTIBUILDER_H__
|
||||||
|
|
||||||
|
#include "llvm/Constant.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
|
||||||
|
struct ClassDeclaration;
|
||||||
|
struct TypeClass;
|
||||||
|
|
||||||
|
struct IrStruct;
|
||||||
|
|
||||||
|
struct TypeInfoBuilder
|
||||||
|
{
|
||||||
|
ClassDeclaration* base;
|
||||||
|
TypeClass* basetype;
|
||||||
|
IrStruct* baseir;
|
||||||
|
|
||||||
|
// 10 is enough for any D1 typeinfo
|
||||||
|
llvm::SmallVector<llvm::Constant*, 10> inits;
|
||||||
|
|
||||||
|
TypeInfoBuilder(ClassDeclaration* base_class);
|
||||||
|
|
||||||
|
void push(llvm::Constant* C);
|
||||||
|
void push_null_vp();
|
||||||
|
void push_typeinfo(Type* t);
|
||||||
|
void push_classinfo(ClassDeclaration* cd);
|
||||||
|
void push_string(const char* str);
|
||||||
|
void push_null_void_array();
|
||||||
|
void push_void_array(size_t dim, llvm::Constant* ptr);
|
||||||
|
void push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* sym);
|
||||||
|
void finalize(IrGlobal* tid);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
330
gen/typinf.cpp
330
gen/typinf.cpp
|
@ -41,6 +41,7 @@
|
||||||
#include "gen/classes.h"
|
#include "gen/classes.h"
|
||||||
#include "gen/linkage.h"
|
#include "gen/linkage.h"
|
||||||
#include "gen/metadata.h"
|
#include "gen/metadata.h"
|
||||||
|
#include "gen/rttibuilder.h"
|
||||||
|
|
||||||
#include "ir/irvar.h"
|
#include "ir/irvar.h"
|
||||||
#include "ir/irtype.h"
|
#include "ir/irtype.h"
|
||||||
|
@ -271,11 +272,11 @@ int TypeClass::builtinTypeInfo()
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// MAGIC PLACE
|
// MAGIC PLACE
|
||||||
|
// (wut?)
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void DtoResolveTypeInfo(TypeInfoDeclaration* tid);
|
void DtoResolveTypeInfo(TypeInfoDeclaration* tid);
|
||||||
void DtoDeclareTypeInfo(TypeInfoDeclaration* tid);
|
void DtoDeclareTypeInfo(TypeInfoDeclaration* tid);
|
||||||
void DtoConstInitTypeInfo(TypeInfoDeclaration* tid);
|
|
||||||
|
|
||||||
void TypeInfoDeclaration::codegen(Ir*)
|
void TypeInfoDeclaration::codegen(Ir*)
|
||||||
{
|
{
|
||||||
|
@ -334,37 +335,27 @@ void DtoDeclareTypeInfo(TypeInfoDeclaration* tid)
|
||||||
Logger::println("DtoDeclareTypeInfo(%s)", tid->toChars());
|
Logger::println("DtoDeclareTypeInfo(%s)", tid->toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
|
if (Logger::enabled())
|
||||||
|
{
|
||||||
|
std::string mangled(tid->mangle());
|
||||||
|
Logger::println("type = '%s'", tid->tinfo->toChars());
|
||||||
|
Logger::println("typeinfo mangle: %s", mangled.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
IrGlobal* irg = tid->ir.irGlobal;
|
IrGlobal* irg = tid->ir.irGlobal;
|
||||||
|
|
||||||
std::string mangled(tid->mangle());
|
|
||||||
|
|
||||||
Logger::println("type = '%s'", tid->tinfo->toChars());
|
|
||||||
Logger::println("typeinfo mangle: %s", mangled.c_str());
|
|
||||||
|
|
||||||
assert(irg->value != NULL);
|
assert(irg->value != NULL);
|
||||||
|
|
||||||
// this is a declaration of a builtin __initZ var
|
// this is a declaration of a builtin __initZ var
|
||||||
if (tid->tinfo->builtinTypeInfo()) {
|
if (tid->tinfo->builtinTypeInfo()) {
|
||||||
// fixup the global
|
// fixup the global
|
||||||
const llvm::Type* rty = Type::typeinfo->type->irtype->getPA().get();
|
const llvm::Type* rty = Type::typeinfo->type->irtype->getPA();
|
||||||
llvm::cast<llvm::OpaqueType>(irg->type.get())->refineAbstractTypeTo(rty);
|
llvm::cast<llvm::OpaqueType>(irg->type.get())->refineAbstractTypeTo(rty);
|
||||||
LLGlobalVariable* g = isaGlobalVar(irg->value);
|
LLGlobalVariable* g = isaGlobalVar(irg->value);
|
||||||
g->setLinkage(llvm::GlobalValue::ExternalLinkage);
|
g->setLinkage(llvm::GlobalValue::ExternalLinkage);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// custom typedef
|
// define custom typedef
|
||||||
DtoConstInitTypeInfo(tid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DtoConstInitTypeInfo(TypeInfoDeclaration* tid)
|
|
||||||
{
|
|
||||||
if (tid->ir.initialized) return;
|
|
||||||
tid->ir.initialized = true;
|
|
||||||
|
|
||||||
Logger::println("DtoConstInitTypeInfo(%s)", tid->toChars());
|
|
||||||
LOG_SCOPE;
|
|
||||||
|
|
||||||
tid->llvmDefine();
|
tid->llvmDefine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +363,7 @@ void DtoConstInitTypeInfo(TypeInfoDeclaration* tid)
|
||||||
|
|
||||||
void TypeInfoDeclaration::llvmDefine()
|
void TypeInfoDeclaration::llvmDefine()
|
||||||
{
|
{
|
||||||
assert(0 && "TypeInfoDeclaration::llvmDeclare");
|
assert(0 && "cannot generate generic typeinfo");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -382,54 +373,35 @@ void TypeInfoTypedefDeclaration::llvmDefine()
|
||||||
Logger::println("TypeInfoTypedefDeclaration::llvmDefine() %s", toChars());
|
Logger::println("TypeInfoTypedefDeclaration::llvmDefine() %s", toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
ClassDeclaration* base = Type::typeinfotypedef;
|
TypeInfoBuilder b(Type::typeinfotypedef);
|
||||||
base->codegen(Type::sir);
|
|
||||||
|
|
||||||
// vtbl
|
|
||||||
std::vector<LLConstant*> sinits;
|
|
||||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
|
||||||
|
|
||||||
// monitor
|
|
||||||
sinits.push_back(getNullPtr(getPtrToType(LLType::Int8Ty)));
|
|
||||||
|
|
||||||
assert(tinfo->ty == Ttypedef);
|
assert(tinfo->ty == Ttypedef);
|
||||||
TypeTypedef *tc = (TypeTypedef *)tinfo;
|
TypeTypedef *tc = (TypeTypedef *)tinfo;
|
||||||
TypedefDeclaration *sd = tc->sym;
|
TypedefDeclaration *sd = tc->sym;
|
||||||
|
|
||||||
// TypeInfo base
|
// TypeInfo base
|
||||||
sd->basetype = sd->basetype->merge(); // DMD does this!
|
sd->basetype = sd->basetype->merge(); // dmd does it ... why?
|
||||||
LLConstant* castbase = DtoTypeInfoOf(sd->basetype, true);
|
b.push_typeinfo(sd->basetype);
|
||||||
sinits.push_back(castbase);
|
|
||||||
|
|
||||||
// char[] name
|
// char[] name
|
||||||
char *name = sd->toPrettyChars();
|
b.push_string(sd->toPrettyChars());
|
||||||
sinits.push_back(DtoConstString(name));
|
|
||||||
|
|
||||||
// void[] init
|
// void[] init
|
||||||
const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
|
// emit null array if we should use the basetype, or if the basetype
|
||||||
if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type
|
// uses default initialization.
|
||||||
|
if (!sd->init || tinfo->isZeroInit(0))
|
||||||
{
|
{
|
||||||
sinits.push_back(DtoConstSlice(DtoConstSize_t(0), getNullPtr(initpt)));
|
b.push_null_void_array();
|
||||||
}
|
}
|
||||||
|
// otherwise emit a void[] with the default initializer
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LLConstant* ci = DtoConstInitializer(sd->loc, sd->basetype, sd->init);
|
LLConstant* C = DtoConstInitializer(sd->loc, sd->basetype, sd->init);
|
||||||
std::string ciname(sd->mangle());
|
b.push_void_array(C, sd->basetype, sd);
|
||||||
ciname.append("__init");
|
|
||||||
llvm::GlobalVariable* civar = new llvm::GlobalVariable(DtoType(sd->basetype),true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module);
|
|
||||||
LLConstant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt);
|
|
||||||
size_t cisize = getTypeStoreSize(DtoType(sd->basetype));
|
|
||||||
sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the inititalizer
|
// finish
|
||||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
b.finalize(ir.irGlobal);
|
||||||
|
|
||||||
// refine global type
|
|
||||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
|
||||||
|
|
||||||
// set the initializer
|
|
||||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -439,86 +411,35 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
||||||
Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s", toChars());
|
Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s", toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
ClassDeclaration* base = Type::typeinfoenum;
|
TypeInfoBuilder b(Type::typeinfoenum);
|
||||||
base->codegen(Type::sir);
|
|
||||||
|
|
||||||
// vtbl
|
|
||||||
std::vector<LLConstant*> sinits;
|
|
||||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
|
||||||
|
|
||||||
// monitor
|
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
|
||||||
|
|
||||||
assert(tinfo->ty == Tenum);
|
assert(tinfo->ty == Tenum);
|
||||||
TypeEnum *tc = (TypeEnum *)tinfo;
|
TypeEnum *tc = (TypeEnum *)tinfo;
|
||||||
EnumDeclaration *sd = tc->sym;
|
EnumDeclaration *sd = tc->sym;
|
||||||
|
|
||||||
// TypeInfo base
|
// TypeInfo base
|
||||||
LLConstant* castbase = DtoTypeInfoOf(sd->memtype, true);
|
b.push_typeinfo(sd->memtype);
|
||||||
sinits.push_back(castbase);
|
|
||||||
|
|
||||||
// char[] name
|
// char[] name
|
||||||
char *name = sd->toPrettyChars();
|
b.push_string(sd->toPrettyChars());
|
||||||
sinits.push_back(DtoConstString(name));
|
|
||||||
|
|
||||||
// void[] init
|
// void[] init
|
||||||
const LLPointerType* initpt = getPtrToType(LLType::Int8Ty);
|
// emit void[] with the default initialier, the array is null if the default
|
||||||
if (tinfo->isZeroInit() || !sd->defaultval) // 0 initializer, or the same as the base type
|
// initializer is zero
|
||||||
|
if (!sd->defaultval || tinfo->isZeroInit(0))
|
||||||
{
|
{
|
||||||
sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
|
b.push_null_void_array();
|
||||||
}
|
}
|
||||||
|
// otherwise emit a void[] with the default initializer
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if DMDV2
|
|
||||||
assert(0 && "initializer not implemented");
|
|
||||||
#else
|
|
||||||
const LLType* memty = DtoType(sd->memtype);
|
const LLType* memty = DtoType(sd->memtype);
|
||||||
LLConstant* ci = llvm::ConstantInt::get(memty, sd->defaultval, !sd->memtype->isunsigned());
|
LLConstant* C = llvm::ConstantInt::get(memty, sd->defaultval, !sd->memtype->isunsigned());
|
||||||
std::string ciname(sd->mangle());
|
b.push_void_array(C, sd->memtype, sd);
|
||||||
ciname.append("__init");
|
|
||||||
llvm::GlobalVariable* civar = new llvm::GlobalVariable(memty,true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module);
|
|
||||||
LLConstant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt);
|
|
||||||
size_t cisize = getTypeStoreSize(memty);
|
|
||||||
sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the inititalizer
|
// finish
|
||||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
b.finalize(ir.irGlobal);
|
||||||
|
|
||||||
// refine global type
|
|
||||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
|
||||||
|
|
||||||
// set the initializer
|
|
||||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
|
||||||
|
|
||||||
static void LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
|
|
||||||
{
|
|
||||||
ClassDeclaration* base = cd;
|
|
||||||
base->codegen(Type::sir);
|
|
||||||
|
|
||||||
// vtbl
|
|
||||||
std::vector<LLConstant*> sinits;
|
|
||||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
|
||||||
|
|
||||||
// monitor
|
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
|
||||||
|
|
||||||
// TypeInfo base
|
|
||||||
LLConstant* castbase = DtoTypeInfoOf(basetype, true);
|
|
||||||
sinits.push_back(castbase);
|
|
||||||
|
|
||||||
// create the inititalizer
|
|
||||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
|
||||||
|
|
||||||
// refine global type
|
|
||||||
llvm::cast<llvm::OpaqueType>(tid->ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
|
||||||
|
|
||||||
// set the initializer
|
|
||||||
isaGlobalVar(tid->ir.irGlobal->value)->setInitializer(tiInit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -528,10 +449,11 @@ void TypeInfoPointerDeclaration::llvmDefine()
|
||||||
Logger::println("TypeInfoPointerDeclaration::llvmDefine() %s", toChars());
|
Logger::println("TypeInfoPointerDeclaration::llvmDefine() %s", toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
assert(tinfo->ty == Tpointer);
|
TypeInfoBuilder b(Type::typeinfopointer);
|
||||||
TypePointer *tc = (TypePointer *)tinfo;
|
// TypeInfo base
|
||||||
|
b.push_typeinfo(tinfo->nextOf());
|
||||||
LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfopointer);
|
// finish
|
||||||
|
b.finalize(ir.irGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -541,10 +463,11 @@ void TypeInfoArrayDeclaration::llvmDefine()
|
||||||
Logger::println("TypeInfoArrayDeclaration::llvmDefine() %s", toChars());
|
Logger::println("TypeInfoArrayDeclaration::llvmDefine() %s", toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
assert(tinfo->ty == Tarray);
|
TypeInfoBuilder b(Type::typeinfoarray);
|
||||||
TypeDArray *tc = (TypeDArray *)tinfo;
|
// TypeInfo base
|
||||||
|
b.push_typeinfo(tinfo->nextOf());
|
||||||
LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfoarray);
|
// finish
|
||||||
|
b.finalize(ir.irGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -554,39 +477,19 @@ void TypeInfoStaticArrayDeclaration::llvmDefine()
|
||||||
Logger::println("TypeInfoStaticArrayDeclaration::llvmDefine() %s", toChars());
|
Logger::println("TypeInfoStaticArrayDeclaration::llvmDefine() %s", toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
// init typeinfo class
|
|
||||||
ClassDeclaration* base = Type::typeinfostaticarray;
|
|
||||||
base->codegen(Type::sir);
|
|
||||||
|
|
||||||
// get type of typeinfo class
|
|
||||||
const LLStructType* stype = isaStruct(base->type->irtype->getPA().get());
|
|
||||||
|
|
||||||
// initializer vector
|
|
||||||
std::vector<LLConstant*> sinits;
|
|
||||||
// first is always the vtable
|
|
||||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
|
||||||
|
|
||||||
// monitor
|
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
|
||||||
|
|
||||||
// value typeinfo
|
|
||||||
assert(tinfo->ty == Tsarray);
|
assert(tinfo->ty == Tsarray);
|
||||||
TypeSArray *tc = (TypeSArray *)tinfo;
|
TypeSArray *tc = (TypeSArray *)tinfo;
|
||||||
LLConstant* castbase = DtoTypeInfoOf(tc->next, true);
|
|
||||||
assert(castbase->getType() == stype->getElementType(2));
|
TypeInfoBuilder b(Type::typeinfostaticarray);
|
||||||
sinits.push_back(castbase);
|
|
||||||
|
// value typeinfo
|
||||||
|
b.push_typeinfo(tc->nextOf());
|
||||||
|
|
||||||
// length
|
// length
|
||||||
sinits.push_back(DtoConstSize_t(tc->dim->toInteger()));
|
b.push(DtoConstSize_t((size_t)tc->dim->toUInteger()));
|
||||||
|
|
||||||
// create the inititalizer
|
// finish
|
||||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
b.finalize(ir.irGlobal);
|
||||||
|
|
||||||
// refine global type
|
|
||||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
|
||||||
|
|
||||||
// set the initializer
|
|
||||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -596,38 +499,19 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
||||||
Logger::println("TypeInfoAssociativeArrayDeclaration::llvmDefine() %s", toChars());
|
Logger::println("TypeInfoAssociativeArrayDeclaration::llvmDefine() %s", toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
// init typeinfo class
|
|
||||||
ClassDeclaration* base = Type::typeinfoassociativearray;
|
|
||||||
base->codegen(Type::sir);
|
|
||||||
|
|
||||||
// initializer vector
|
|
||||||
std::vector<LLConstant*> sinits;
|
|
||||||
// first is always the vtable
|
|
||||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
|
||||||
|
|
||||||
// monitor
|
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
|
||||||
|
|
||||||
// get type
|
|
||||||
assert(tinfo->ty == Taarray);
|
assert(tinfo->ty == Taarray);
|
||||||
TypeAArray *tc = (TypeAArray *)tinfo;
|
TypeAArray *tc = (TypeAArray *)tinfo;
|
||||||
|
|
||||||
|
TypeInfoBuilder b(Type::typeinfoassociativearray);
|
||||||
|
|
||||||
// value typeinfo
|
// value typeinfo
|
||||||
LLConstant* castbase = DtoTypeInfoOf(tc->next, true);
|
b.push_typeinfo(tc->nextOf());
|
||||||
sinits.push_back(castbase);
|
|
||||||
|
|
||||||
// key typeinfo
|
// key typeinfo
|
||||||
castbase = DtoTypeInfoOf(tc->index, true);
|
b.push_typeinfo(tc->index);
|
||||||
sinits.push_back(castbase);
|
|
||||||
|
|
||||||
// create the inititalizer
|
// finish
|
||||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
b.finalize(ir.irGlobal);
|
||||||
|
|
||||||
// refine global type
|
|
||||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
|
||||||
|
|
||||||
// set the initializer
|
|
||||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -637,10 +521,11 @@ void TypeInfoFunctionDeclaration::llvmDefine()
|
||||||
Logger::println("TypeInfoFunctionDeclaration::llvmDefine() %s", toChars());
|
Logger::println("TypeInfoFunctionDeclaration::llvmDefine() %s", toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
assert(tinfo->ty == Tfunction);
|
TypeInfoBuilder b(Type::typeinfofunction);
|
||||||
TypeFunction *tc = (TypeFunction *)tinfo;
|
// TypeInfo base
|
||||||
|
b.push_typeinfo(tinfo->nextOf());
|
||||||
LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfofunction);
|
// finish
|
||||||
|
b.finalize(ir.irGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -651,9 +536,13 @@ void TypeInfoDelegateDeclaration::llvmDefine()
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
assert(tinfo->ty == Tdelegate);
|
assert(tinfo->ty == Tdelegate);
|
||||||
TypeDelegate *tc = (TypeDelegate *)tinfo;
|
Type* ret_type = tinfo->nextOf()->nextOf();
|
||||||
|
|
||||||
LLVM_D_Define_TypeInfoBase(tc->nextOf()->nextOf(), this, Type::typeinfodelegate);
|
TypeInfoBuilder b(Type::typeinfodelegate);
|
||||||
|
// TypeInfo base
|
||||||
|
b.push_typeinfo(ret_type);
|
||||||
|
// finish
|
||||||
|
b.finalize(ir.irGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -874,30 +763,13 @@ void TypeInfoClassDeclaration::llvmDefine()
|
||||||
TypeClass *tc = (TypeClass *)tinfo;
|
TypeClass *tc = (TypeClass *)tinfo;
|
||||||
tc->sym->codegen(Type::sir);
|
tc->sym->codegen(Type::sir);
|
||||||
|
|
||||||
// init typeinfo class
|
TypeInfoBuilder b(Type::typeinfoclass);
|
||||||
ClassDeclaration* base = Type::typeinfoclass;
|
|
||||||
assert(base);
|
|
||||||
base->codegen(Type::sir);
|
|
||||||
|
|
||||||
// initializer vector
|
// TypeInfo base
|
||||||
std::vector<LLConstant*> sinits;
|
b.push_classinfo(tc->sym);
|
||||||
// first is always the vtable
|
|
||||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
|
||||||
|
|
||||||
// monitor
|
// finish
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
b.finalize(ir.irGlobal);
|
||||||
|
|
||||||
// get classinfo
|
|
||||||
sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol());
|
|
||||||
|
|
||||||
// create the inititalizer
|
|
||||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
|
||||||
|
|
||||||
// refine global type
|
|
||||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
|
||||||
|
|
||||||
// set the initializer
|
|
||||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -912,33 +784,13 @@ void TypeInfoInterfaceDeclaration::llvmDefine()
|
||||||
TypeClass *tc = (TypeClass *)tinfo;
|
TypeClass *tc = (TypeClass *)tinfo;
|
||||||
tc->sym->codegen(Type::sir);
|
tc->sym->codegen(Type::sir);
|
||||||
|
|
||||||
// init typeinfo class
|
TypeInfoBuilder b(Type::typeinfointerface);
|
||||||
ClassDeclaration* base = Type::typeinfointerface;
|
|
||||||
assert(base);
|
|
||||||
base->codegen(Type::sir);
|
|
||||||
|
|
||||||
// get type of typeinfo class
|
// TypeInfo base
|
||||||
const LLStructType* stype = isaStruct(base->type->irtype->getPA());
|
b.push_classinfo(tc->sym);
|
||||||
|
|
||||||
// initializer vector
|
// finish
|
||||||
std::vector<LLConstant*> sinits;
|
b.finalize(ir.irGlobal);
|
||||||
// first is always the vtable
|
|
||||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
|
||||||
|
|
||||||
// monitor
|
|
||||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
|
||||||
|
|
||||||
// get classinfo
|
|
||||||
sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol());
|
|
||||||
|
|
||||||
// create the inititalizer
|
|
||||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
|
||||||
|
|
||||||
// refine global type
|
|
||||||
llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType());
|
|
||||||
|
|
||||||
// set the initializer
|
|
||||||
isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -1018,10 +870,11 @@ void TypeInfoConstDeclaration::llvmDefine()
|
||||||
Logger::println("TypeInfoConstDeclaration::llvmDefine() %s", toChars());
|
Logger::println("TypeInfoConstDeclaration::llvmDefine() %s", toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
Type *tm = tinfo->mutableOf();
|
TypeInfoBuilder b(Type::typeinfoconst);
|
||||||
tm = tm->merge();
|
// TypeInfo base
|
||||||
|
b.push_typeinfo(tinfo->mutableOf()->merge());
|
||||||
LLVM_D_Define_TypeInfoBase(tm, this, Type::typeinfoconst);
|
// finish
|
||||||
|
b.finalize(ir.irGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -1031,10 +884,11 @@ void TypeInfoInvariantDeclaration::llvmDefine()
|
||||||
Logger::println("TypeInfoInvariantDeclaration::llvmDefine() %s", toChars());
|
Logger::println("TypeInfoInvariantDeclaration::llvmDefine() %s", toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
Type *tm = tinfo->mutableOf();
|
TypeInfoBuilder b(Type::typeinfoinvariant);
|
||||||
tm = tm->merge();
|
// TypeInfo base
|
||||||
|
b.push_typeinfo(tinfo->mutableOf()->merge());
|
||||||
LLVM_D_Define_TypeInfoBase(tm, this, Type::typeinfoinvariant);
|
// finish
|
||||||
|
b.finalize(ir.irGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue