mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-14 15:16:07 +03:00
[svn r209] Fixed: exotic array to pointer casts were broken.
Changed: classes now have opaque vtables.
This commit is contained in:
parent
7c78e3665b
commit
9f3be435b0
11 changed files with 129 additions and 48 deletions
|
@ -934,10 +934,9 @@ DValue* DtoCastArray(DValue* u, Type* to)
|
||||||
Logger::cout() << "from array or sarray" << '\n';
|
Logger::cout() << "from array or sarray" << '\n';
|
||||||
if (totype->ty == Tpointer) {
|
if (totype->ty == Tpointer) {
|
||||||
Logger::cout() << "to pointer" << '\n';
|
Logger::cout() << "to pointer" << '\n';
|
||||||
assert(fromtype->next == totype->next || totype->next->ty == Tvoid);
|
|
||||||
rval = DtoArrayPtr(u);
|
rval = DtoArrayPtr(u);
|
||||||
if (fromtype->next != totype->next)
|
if (rval->getType() != tolltype)
|
||||||
rval = gIR->ir->CreateBitCast(rval, getPtrToType(llvm::Type::Int8Ty), "tmp");
|
rval = gIR->ir->CreateBitCast(rval, tolltype, "tmp");
|
||||||
}
|
}
|
||||||
else if (totype->ty == Tarray) {
|
else if (totype->ty == Tarray) {
|
||||||
Logger::cout() << "to array" << '\n';
|
Logger::cout() << "to array" << '\n';
|
||||||
|
|
131
gen/classes.cpp
131
gen/classes.cpp
|
@ -124,18 +124,20 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
// push state
|
||||||
gIR->structs.push_back(irstruct);
|
gIR->structs.push_back(irstruct);
|
||||||
gIR->classes.push_back(cd);
|
gIR->classes.push_back(cd);
|
||||||
|
|
||||||
|
// vector holding the field types
|
||||||
|
std::vector<const llvm::Type*> fieldtypes;
|
||||||
|
|
||||||
// add vtable
|
// add vtable
|
||||||
ts->ir.vtblType = new llvm::PATypeHolder(llvm::OpaqueType::get());
|
ts->ir.vtblType = new llvm::PATypeHolder(llvm::OpaqueType::get());
|
||||||
const llvm::Type* vtabty = getPtrToType(ts->ir.vtblType->get());
|
const llvm::Type* vtabty = getPtrToType(ts->ir.vtblType->get());
|
||||||
|
|
||||||
std::vector<const llvm::Type*> fieldtypes;
|
|
||||||
fieldtypes.push_back(vtabty);
|
fieldtypes.push_back(vtabty);
|
||||||
|
|
||||||
// add monitor
|
// add monitor
|
||||||
fieldtypes.push_back(getPtrToType(llvm::Type::Int8Ty));
|
fieldtypes.push_back(getVoidPtrType());
|
||||||
|
|
||||||
// add base class data fields first
|
// add base class data fields first
|
||||||
LLVM_AddBaseClassData(&cd->baseclasses);
|
LLVM_AddBaseClassData(&cd->baseclasses);
|
||||||
|
@ -241,7 +243,11 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||||
fieldtypes.push_back(ivtblTy);
|
fieldtypes.push_back(ivtblTy);
|
||||||
|
|
||||||
// fix the interface vtable type
|
// fix the interface vtable type
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
iri->vtblTy = isaArray(itc->ir.vtblType->get());
|
||||||
|
#else
|
||||||
iri->vtblTy = isaStruct(itc->ir.vtblType->get());
|
iri->vtblTy = isaStruct(itc->ir.vtblType->get());
|
||||||
|
#endif
|
||||||
|
|
||||||
// set index
|
// set index
|
||||||
iri->index = interIdx++;
|
iri->index = interIdx++;
|
||||||
|
@ -273,6 +279,12 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||||
|
|
||||||
// create vtable type
|
// create vtable type
|
||||||
llvm::GlobalVariable* svtblVar = 0;
|
llvm::GlobalVariable* svtblVar = 0;
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
// void*[vtbl.dim]
|
||||||
|
const llvm::ArrayType* svtbl_ty
|
||||||
|
= llvm::ArrayType::get(getVoidPtrType(), cd->vtbl.dim);
|
||||||
|
|
||||||
|
#else
|
||||||
std::vector<const llvm::Type*> sinits_ty;
|
std::vector<const llvm::Type*> sinits_ty;
|
||||||
|
|
||||||
for (int k=0; k < cd->vtbl.dim; k++)
|
for (int k=0; k < cd->vtbl.dim; k++)
|
||||||
|
@ -310,19 +322,29 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get type
|
||||||
assert(!sinits_ty.empty());
|
assert(!sinits_ty.empty());
|
||||||
const llvm::StructType* svtbl_ty = llvm::StructType::get(sinits_ty);
|
const llvm::StructType* svtbl_ty = llvm::StructType::get(sinits_ty);
|
||||||
|
#endif
|
||||||
std::string styname(cd->mangle());
|
|
||||||
styname.append("__vtblType");
|
|
||||||
gIR->module->addTypeName(styname, svtbl_ty);
|
|
||||||
|
|
||||||
// refine for final vtable type
|
// refine for final vtable type
|
||||||
llvm::cast<llvm::OpaqueType>(ts->ir.vtblType->get())->refineAbstractTypeTo(svtbl_ty);
|
llvm::cast<llvm::OpaqueType>(ts->ir.vtblType->get())->refineAbstractTypeTo(svtbl_ty);
|
||||||
|
|
||||||
|
#if !OPAQUE_VTBLS
|
||||||
|
// name vtbl type
|
||||||
|
std::string styname(cd->mangle());
|
||||||
|
styname.append("__vtblType");
|
||||||
|
gIR->module->addTypeName(styname, svtbl_ty);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// log
|
||||||
|
Logger::cout() << "final class type: " << *ts->ir.type->get() << '\n';
|
||||||
|
|
||||||
|
// pop state
|
||||||
gIR->classes.pop_back();
|
gIR->classes.pop_back();
|
||||||
gIR->structs.pop_back();
|
gIR->structs.pop_back();
|
||||||
|
|
||||||
|
// queue declare
|
||||||
gIR->declareList.push_back(cd);
|
gIR->declareList.push_back(cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,9 +381,7 @@ void DtoDeclareClass(ClassDeclaration* cd)
|
||||||
std::string varname("_D");
|
std::string varname("_D");
|
||||||
varname.append(cd->mangle());
|
varname.append(cd->mangle());
|
||||||
varname.append("6__vtblZ");
|
varname.append("6__vtblZ");
|
||||||
|
cd->ir.irStruct->vtbl = new llvm::GlobalVariable(ts->ir.vtblType->get(), true, _linkage, 0, varname, gIR->module);
|
||||||
const llvm::StructType* svtbl_ty = isaStruct(ts->ir.vtblType->get());
|
|
||||||
cd->ir.irStruct->vtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get interface info type
|
// get interface info type
|
||||||
|
@ -445,7 +465,11 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||||
assert(cd->type->ty == Tclass);
|
assert(cd->type->ty == Tclass);
|
||||||
TypeClass* ts = (TypeClass*)cd->type;
|
TypeClass* ts = (TypeClass*)cd->type;
|
||||||
const llvm::StructType* structtype = isaStruct(ts->ir.type->get());
|
const llvm::StructType* structtype = isaStruct(ts->ir.type->get());
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
const llvm::ArrayType* vtbltype = isaArray(ts->ir.vtblType->get());
|
||||||
|
#else
|
||||||
const llvm::StructType* vtbltype = isaStruct(ts->ir.vtblType->get());
|
const llvm::StructType* vtbltype = isaStruct(ts->ir.vtblType->get());
|
||||||
|
#endif
|
||||||
|
|
||||||
// make sure each offset knows its default initializer
|
// make sure each offset knows its default initializer
|
||||||
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
|
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
|
||||||
|
@ -543,37 +567,40 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||||
assert(dsym);
|
assert(dsym);
|
||||||
//Logger::cout() << "vtblsym: " << dsym->toChars() << '\n';
|
//Logger::cout() << "vtblsym: " << dsym->toChars() << '\n';
|
||||||
|
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
const llvm::Type* targetTy = getVoidPtrType();
|
||||||
|
#else
|
||||||
|
const llvm::Type* targetTy = vtbltype->getElementType(k);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
llvm::Constant* c = NULL;
|
||||||
|
// virtual method
|
||||||
if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
|
if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
|
||||||
DtoForceDeclareDsymbol(fd);
|
DtoForceDeclareDsymbol(fd);
|
||||||
assert(fd->ir.irFunc->func);
|
assert(fd->ir.irFunc->func);
|
||||||
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->ir.irFunc->func);
|
c = llvm::cast<llvm::Constant>(fd->ir.irFunc->func);
|
||||||
// cast if necessary (overridden method)
|
|
||||||
if (c->getType() != vtbltype->getElementType(k))
|
|
||||||
c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k));
|
|
||||||
sinits.push_back(c);
|
|
||||||
}
|
}
|
||||||
|
// classinfo
|
||||||
else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) {
|
else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) {
|
||||||
assert(cd->ir.irStruct->classInfo);
|
assert(cd->ir.irStruct->classInfo);
|
||||||
llvm::Constant* c = cd->ir.irStruct->classInfo;
|
c = cd->ir.irStruct->classInfo;
|
||||||
|
}
|
||||||
|
assert(c != NULL);
|
||||||
|
|
||||||
|
// cast if necessary (overridden method)
|
||||||
|
if (c->getType() != targetTy)
|
||||||
|
c = llvm::ConstantExpr::getBitCast(c, targetTy);
|
||||||
sinits.push_back(c);
|
sinits.push_back(c);
|
||||||
}
|
}
|
||||||
else
|
#if OPAQUE_VTBLS
|
||||||
assert(0);
|
const llvm::ArrayType* svtbl_ty = isaArray(ts->ir.vtblType->get());
|
||||||
}
|
llvm::Constant* cvtblInit = llvm::ConstantArray::get(svtbl_ty, sinits);
|
||||||
|
cd->ir.irStruct->constVtbl = llvm::cast<llvm::ConstantArray>(cvtblInit);
|
||||||
|
#else
|
||||||
const llvm::StructType* svtbl_ty = isaStruct(ts->ir.vtblType->get());
|
const llvm::StructType* svtbl_ty = isaStruct(ts->ir.vtblType->get());
|
||||||
|
|
||||||
#if 0
|
|
||||||
for (size_t i=0; i< sinits.size(); ++i)
|
|
||||||
{
|
|
||||||
Logger::cout() << "field[" << i << "] = " << *svtbl_ty->getElementType(i) << '\n';
|
|
||||||
Logger::cout() << "init [" << i << "] = " << *sinits[i]->getType() << '\n';
|
|
||||||
assert(svtbl_ty->getElementType(i) == sinits[i]->getType());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits);
|
llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits);
|
||||||
cd->ir.irStruct->constVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit);
|
cd->ir.irStruct->constVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit);
|
||||||
|
#endif
|
||||||
|
|
||||||
// create interface vtable const initalizers
|
// create interface vtable const initalizers
|
||||||
for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
|
for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
|
||||||
|
@ -585,7 +612,11 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||||
assert(id->type->ty == Tclass);
|
assert(id->type->ty == Tclass);
|
||||||
TypeClass* its = (TypeClass*)id->type;
|
TypeClass* its = (TypeClass*)id->type;
|
||||||
|
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
const llvm::ArrayType* ivtbl_ty = isaArray(its->ir.vtblType->get());
|
||||||
|
#else
|
||||||
const llvm::StructType* ivtbl_ty = isaStruct(its->ir.vtblType->get());
|
const llvm::StructType* ivtbl_ty = isaStruct(its->ir.vtblType->get());
|
||||||
|
#endif
|
||||||
|
|
||||||
// generate interface info initializer
|
// generate interface info initializer
|
||||||
std::vector<llvm::Constant*> infoInits;
|
std::vector<llvm::Constant*> infoInits;
|
||||||
|
@ -613,7 +644,12 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||||
std::vector<llvm::Constant*> iinits;
|
std::vector<llvm::Constant*> iinits;
|
||||||
|
|
||||||
// add interface info
|
// add interface info
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
const llvm::Type* targetTy = getVoidPtrType();
|
||||||
|
iinits.push_back(llvm::ConstantExpr::getBitCast(iri->info, targetTy));
|
||||||
|
#else
|
||||||
iinits.push_back(iri->info);
|
iinits.push_back(iri->info);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int k=1; k < b->vtbl.dim; k++)
|
for (int k=1; k < b->vtbl.dim; k++)
|
||||||
{
|
{
|
||||||
|
@ -626,22 +662,24 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||||
assert(fd->ir.irFunc->func);
|
assert(fd->ir.irFunc->func);
|
||||||
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->ir.irFunc->func);
|
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->ir.irFunc->func);
|
||||||
|
|
||||||
// we have to bitcast, as the type created in ResolveClass expects a different this type
|
#if !OPAQUE_VTBLS
|
||||||
c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k));
|
const llvm::Type* targetTy = iri->vtblTy->getContainedType(k);
|
||||||
iinits.push_back(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
for (size_t x=0; x< iinits.size(); ++x)
|
|
||||||
{
|
|
||||||
Logger::cout() << "field[" << x << "] = " << *ivtbl_ty->getElementType(x) << "\n\n";
|
|
||||||
Logger::cout() << "init [" << x << "] = " << *iinits[x] << "\n\n";
|
|
||||||
assert(ivtbl_ty->getElementType(x) == iinits[x]->getType());
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// we have to bitcast, as the type created in ResolveClass expects a different this type
|
||||||
|
c = llvm::ConstantExpr::getBitCast(c, targetTy);
|
||||||
|
iinits.push_back(c);
|
||||||
|
Logger::cout() << "c: " << *c << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
Logger::cout() << "n: " << iinits.size() << " ivtbl_ty: " << *ivtbl_ty << '\n';
|
||||||
|
llvm::Constant* civtblInit = llvm::ConstantArray::get(ivtbl_ty, iinits);
|
||||||
|
iri->vtblInit = llvm::cast<llvm::ConstantArray>(civtblInit);
|
||||||
|
#else
|
||||||
llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits);
|
llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits);
|
||||||
iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit);
|
iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// we always generate interfaceinfos as best we can
|
// we always generate interfaceinfos as best we can
|
||||||
|
@ -1171,7 +1209,7 @@ llvm::Value* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl)
|
||||||
assert(DtoDType(inst->getType())->ty == Tclass);
|
assert(DtoDType(inst->getType())->ty == Tclass);
|
||||||
|
|
||||||
llvm::Value* vthis = inst->getRVal();
|
llvm::Value* vthis = inst->getRVal();
|
||||||
//Logger::cout() << "vthis: " << *vthis << '\n';
|
Logger::cout() << "vthis: " << *vthis << '\n';
|
||||||
|
|
||||||
llvm::Value* funcval;
|
llvm::Value* funcval;
|
||||||
funcval = DtoGEPi(vthis, 0, 0, "tmp");
|
funcval = DtoGEPi(vthis, 0, 0, "tmp");
|
||||||
|
@ -1179,6 +1217,13 @@ llvm::Value* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl)
|
||||||
funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toPrettyChars());
|
funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toPrettyChars());
|
||||||
funcval = DtoLoad(funcval);
|
funcval = DtoLoad(funcval);
|
||||||
|
|
||||||
|
Logger::cout() << "funcval: " << *funcval << '\n';
|
||||||
|
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
|
||||||
|
Logger::cout() << "funcval casted: " << *funcval << '\n';
|
||||||
|
#endif
|
||||||
|
|
||||||
//assert(funcval->getType() == DtoType(fdecl->type));
|
//assert(funcval->getType() == DtoType(fdecl->type));
|
||||||
//cc = DtoCallingConv(fdecl->linkage);
|
//cc = DtoCallingConv(fdecl->linkage);
|
||||||
|
|
||||||
|
|
|
@ -1474,6 +1474,10 @@ DValue* DotVarExp::toElem(IRState* p)
|
||||||
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
|
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
|
||||||
funcval = DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb());
|
funcval = DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb());
|
||||||
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
|
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
|
||||||
|
Logger::cout() << "funcval casted: " << *funcval << '\n';
|
||||||
|
#endif
|
||||||
//assert(funcval->getType() == DtoType(fdecl->type));
|
//assert(funcval->getType() == DtoType(fdecl->type));
|
||||||
//cc = DtoCallingConv(fdecl->linkage);
|
//cc = DtoCallingConv(fdecl->linkage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1428,6 +1428,11 @@ const llvm::PointerType* getPtrToType(const llvm::Type* t)
|
||||||
return llvm::PointerType::get(t, 0);
|
return llvm::PointerType::get(t, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const llvm::PointerType* getVoidPtrType()
|
||||||
|
{
|
||||||
|
return getPtrToType(llvm::Type::Int8Ty);
|
||||||
|
}
|
||||||
|
|
||||||
llvm::ConstantPointerNull* getNullPtr(const llvm::Type* t)
|
llvm::ConstantPointerNull* getNullPtr(const llvm::Type* t)
|
||||||
{
|
{
|
||||||
const llvm::PointerType* pt = llvm::cast<llvm::PointerType>(t);
|
const llvm::PointerType* pt = llvm::cast<llvm::PointerType>(t);
|
||||||
|
|
|
@ -123,6 +123,7 @@ llvm::GlobalVariable* isaGlobalVar(llvm::Value* v);
|
||||||
|
|
||||||
// llvm::T::get(...) wrappers
|
// llvm::T::get(...) wrappers
|
||||||
const llvm::PointerType* getPtrToType(const llvm::Type* t);
|
const llvm::PointerType* getPtrToType(const llvm::Type* t);
|
||||||
|
const llvm::PointerType* getVoidPtrType();
|
||||||
llvm::ConstantPointerNull* getNullPtr(const llvm::Type* t);
|
llvm::ConstantPointerNull* getNullPtr(const llvm::Type* t);
|
||||||
|
|
||||||
// type sizes
|
// type sizes
|
||||||
|
|
|
@ -4,7 +4,11 @@
|
||||||
#include "ir/irstruct.h"
|
#include "ir/irstruct.h"
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
|
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
IrInterface::IrInterface(BaseClass* b, const llvm::ArrayType* vt)
|
||||||
|
#else
|
||||||
IrInterface::IrInterface(BaseClass* b, const llvm::StructType* vt)
|
IrInterface::IrInterface(BaseClass* b, const llvm::StructType* vt)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
base = b;
|
base = b;
|
||||||
decl = b->base;
|
decl = b->base;
|
||||||
|
|
|
@ -11,8 +11,13 @@ struct IrInterface : IrBase
|
||||||
BaseClass* base;
|
BaseClass* base;
|
||||||
ClassDeclaration* decl;
|
ClassDeclaration* decl;
|
||||||
|
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
const llvm::ArrayType* vtblTy;
|
||||||
|
llvm::ConstantArray* vtblInit;
|
||||||
|
#else
|
||||||
const llvm::StructType* vtblTy;
|
const llvm::StructType* vtblTy;
|
||||||
llvm::ConstantStruct* vtblInit;
|
llvm::ConstantStruct* vtblInit;
|
||||||
|
#endif
|
||||||
llvm::GlobalVariable* vtbl;
|
llvm::GlobalVariable* vtbl;
|
||||||
|
|
||||||
const llvm::StructType* infoTy;
|
const llvm::StructType* infoTy;
|
||||||
|
@ -21,7 +26,11 @@ struct IrInterface : IrBase
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
IrInterface(BaseClass* b, const llvm::ArrayType* vt);
|
||||||
|
#else
|
||||||
IrInterface(BaseClass* b, const llvm::StructType* vt);
|
IrInterface(BaseClass* b, const llvm::StructType* vt);
|
||||||
|
#endif
|
||||||
~IrInterface();
|
~IrInterface();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,7 +76,11 @@ public:
|
||||||
bool constinited;
|
bool constinited;
|
||||||
|
|
||||||
llvm::GlobalVariable* vtbl;
|
llvm::GlobalVariable* vtbl;
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
|
llvm::ConstantArray* constVtbl;
|
||||||
|
#else
|
||||||
llvm::ConstantStruct* constVtbl;
|
llvm::ConstantStruct* constVtbl;
|
||||||
|
#endif
|
||||||
llvm::GlobalVariable* init;
|
llvm::GlobalVariable* init;
|
||||||
llvm::Constant* constInit;
|
llvm::Constant* constInit;
|
||||||
llvm::GlobalVariable* classInfo;
|
llvm::GlobalVariable* classInfo;
|
||||||
|
|
|
@ -21,7 +21,9 @@ IrType::IrType(const IrType& s)
|
||||||
{
|
{
|
||||||
assert(list.insert(this).second);
|
assert(list.insert(this).second);
|
||||||
type = s.type;
|
type = s.type;
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
vtblType = s.type;
|
vtblType = s.type;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
IrType::~IrType()
|
IrType::~IrType()
|
||||||
|
@ -32,5 +34,7 @@ IrType::~IrType()
|
||||||
void IrType::reset()
|
void IrType::reset()
|
||||||
{
|
{
|
||||||
type = NULL;
|
type = NULL;
|
||||||
|
#if OPAQUE_VTBLS
|
||||||
vtblType = NULL;
|
vtblType = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,9 @@ struct IrType
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
llvm::PATypeHolder* type;
|
llvm::PATypeHolder* type;
|
||||||
|
#if !OPAQUE_VTBLS
|
||||||
llvm::PATypeHolder* vtblType;
|
llvm::PATypeHolder* vtblType;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,9 +27,13 @@ package.buildoptions = { "-x c++", "`llvm-config --cxxflags`" }
|
||||||
package.linkoptions = {
|
package.linkoptions = {
|
||||||
-- long but it's faster than just 'all'
|
-- long but it's faster than just 'all'
|
||||||
"`llvm-config --libs core asmparser bitreader bitwriter support target transformutils scalaropts ipo instrumentation x86 powerpc`",
|
"`llvm-config --libs core asmparser bitreader bitwriter support target transformutils scalaropts ipo instrumentation x86 powerpc`",
|
||||||
"`llvm-config --ldflags`"
|
"`llvm-config --ldflags`",
|
||||||
|
}
|
||||||
|
package.defines = {
|
||||||
|
"IN_LLVM",
|
||||||
|
"_DH",
|
||||||
|
"OPAQUE_VTBLS=1",
|
||||||
}
|
}
|
||||||
package.defines = { "IN_LLVM", "_DH" }
|
|
||||||
package.config.Release.defines = { "LLVMD_NO_LOGGER" }
|
package.config.Release.defines = { "LLVMD_NO_LOGGER" }
|
||||||
package.config.Debug.buildoptions = { "-g -O0" }
|
package.config.Debug.buildoptions = { "-g -O0" }
|
||||||
--package.targetprefix = "llvm"
|
--package.targetprefix = "llvm"
|
||||||
|
|
|
@ -31,8 +31,8 @@ DC=llvmdc
|
||||||
ADD_CFLAGS=
|
ADD_CFLAGS=
|
||||||
ADD_DFLAGS=
|
ADD_DFLAGS=
|
||||||
|
|
||||||
targets : lib clib doc
|
targets : lib doc
|
||||||
all : lib clib doc
|
all : lib doc
|
||||||
|
|
||||||
######################################################
|
######################################################
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue