[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.

Unit tests are now implemented.
This commit is contained in:
Tomas Lindquist Olsen 2007-11-27 03:09:36 +01:00
parent 935dfae9c8
commit ea362d8402
17 changed files with 144 additions and 111 deletions

View file

@ -104,9 +104,10 @@ struct AggregateDeclaration : ScopeDsymbol
bool llvmInProgress; bool llvmInProgress;
llvm::GlobalVariable* llvmVtbl; llvm::GlobalVariable* llvmVtbl;
llvm::ConstantStruct* llvmConstVtbl; llvm::ConstantStruct* llvmConstVtbl;
llvm::Constant* llvmInitZ; llvm::GlobalVariable* llvmInit;
llvm::Constant* llvmConstInit;
llvm::GlobalVariable* llvmClass; llvm::GlobalVariable* llvmClass;
llvm::Constant* llvmClassZ; llvm::Constant* llvmConstClass;
bool llvmHasUnions; bool llvmHasUnions;
DUnion* llvmUnion; DUnion* llvmUnion;
IRStruct* llvmIRStruct; IRStruct* llvmIRStruct;

View file

@ -615,6 +615,7 @@ struct FuncDeclaration : Declaration
llvm::Constant* llvmDwarfSubProgram; llvm::Constant* llvmDwarfSubProgram;
bool llvmRunTimeHack; bool llvmRunTimeHack;
IRFunction* llvmIRFunc; IRFunction* llvmIRFunc;
llvm::Value* llvmRetArg;
}; };
struct FuncAliasDeclaration : FuncDeclaration struct FuncAliasDeclaration : FuncDeclaration

View file

@ -81,6 +81,7 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC s
llvmDwarfSubProgram = NULL; llvmDwarfSubProgram = NULL;
llvmRunTimeHack = false; llvmRunTimeHack = false;
llvmIRFunc = NULL; llvmIRFunc = NULL;
llvmRetArg = NULL;
} }
Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s) Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)

View file

@ -2560,8 +2560,6 @@ TypeFunction::TypeFunction(Arguments *parameters, Type *treturn, int varargs, en
this->inuse = 0; this->inuse = 0;
this->llvmRetInPtr = false; this->llvmRetInPtr = false;
this->llvmUsesThis = false; this->llvmUsesThis = false;
this->llvmRetArg = 0;
this->llvmAllocaPoint = 0;
} }
Type *TypeFunction::syntaxCopy() Type *TypeFunction::syntaxCopy()
@ -4094,7 +4092,6 @@ TypeStruct::TypeStruct(StructDeclaration *sym)
: Type(Tstruct, NULL) : Type(Tstruct, NULL)
{ {
this->sym = sym; this->sym = sym;
llvmInit = 0;
} }
char *TypeStruct::toChars() char *TypeStruct::toChars()
@ -4383,7 +4380,6 @@ TypeClass::TypeClass(ClassDeclaration *sym)
: Type(Tclass, NULL) : Type(Tclass, NULL)
{ {
this->sym = sym; this->sym = sym;
llvmInit = 0;
llvmVtblType = 0; llvmVtblType = 0;
} }

View file

@ -437,8 +437,6 @@ struct TypeFunction : Type
bool llvmRetInPtr; bool llvmRetInPtr;
bool llvmUsesThis; bool llvmUsesThis;
llvm::Value* llvmRetArg;
llvm::Instruction* llvmAllocaPoint;
}; };
struct TypeDelegate : Type struct TypeDelegate : Type
@ -542,8 +540,6 @@ struct TypeStruct : Type
int hasPointers(); int hasPointers();
type *toCtype(); type *toCtype();
llvm::GlobalVariable* llvmInit;
}; };
struct TypeEnum : Type struct TypeEnum : Type
@ -641,7 +637,6 @@ struct TypeClass : Type
Symbol *toSymbol(); Symbol *toSymbol();
llvm::GlobalVariable* llvmInit;
llvm::PATypeHolder* llvmVtblType; llvm::PATypeHolder* llvmVtblType;
}; };

View file

@ -47,9 +47,10 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
llvmVtbl = NULL; llvmVtbl = NULL;
llvmConstVtbl = NULL; llvmConstVtbl = NULL;
llvmInitZ = NULL; llvmInit = NULL;
llvmConstInit = NULL;
llvmClass = NULL; llvmClass = NULL;
llvmClassZ = NULL; llvmConstClass = NULL;
llvmInProgress = false; llvmInProgress = false;
llvmHasUnions = false; llvmHasUnions = false;
llvmUnion = NULL; llvmUnion = NULL;

View file

@ -305,7 +305,7 @@ void DtoDeclareClass(ClassDeclaration* cd)
initname.append("6__initZ"); initname.append("6__initZ");
llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module);
ts->llvmInit = initvar; cd->llvmInit = initvar;
} }
gIR->classes.pop_back(); gIR->classes.pop_back();
@ -394,7 +394,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits); llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits);
assert(_init); assert(_init);
cd->llvmInitZ = _init; cd->llvmConstInit = _init;
// generate vtable initializer // generate vtable initializer
std::vector<llvm::Constant*> sinits; std::vector<llvm::Constant*> sinits;
@ -524,7 +524,7 @@ void DtoDefineClass(ClassDeclaration* cd)
if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) { if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) {
// interfaces don't have initializers // interfaces don't have initializers
if (!cd->isInterfaceDeclaration()) { if (!cd->isInterfaceDeclaration()) {
ts->llvmInit->setInitializer(cd->llvmInitZ); cd->llvmInit->setInitializer(cd->llvmConstInit);
cd->llvmVtbl->setInitializer(cd->llvmConstVtbl); cd->llvmVtbl->setInitializer(cd->llvmConstVtbl);
// initialize interface vtables // initialize interface vtables
@ -579,15 +579,15 @@ void DtoInitClass(TypeClass* tc, llvm::Value* dst)
// copy the static initializer // copy the static initializer
if (n > 0) { if (n > 0) {
assert(tc->llvmInit); assert(tc->sym->llvmInit);
assert(dst->getType() == tc->llvmInit->getType()); assert(dst->getType() == tc->sym->llvmInit->getType());
llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb()); dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb());
llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb()); llvm::Value* srcarr = new llvm::BitCastInst(tc->sym->llvmInit,arrty,"tmp",gIR->scopebb());
srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb()); srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb());
llvm::Function* fn = LLVM_DeclareMemCpy32(); llvm::Function* fn = LLVM_DeclareMemCpy32();
@ -912,10 +912,10 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
TypeClass* cdty = (TypeClass*)cd->type; TypeClass* cdty = (TypeClass*)cd->type;
if (!cd->isInterfaceDeclaration()) { if (!cd->isInterfaceDeclaration()) {
assert(cd->llvmInitZ); assert(cd->llvmInit);
assert(cd->llvmConstInit);
assert(cd->llvmVtbl); assert(cd->llvmVtbl);
assert(cd->llvmConstVtbl); assert(cd->llvmConstVtbl);
assert(cdty->llvmInit);
} }
// holds the list of initializers for llvm // holds the list of initializers for llvm
@ -923,28 +923,28 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
ClassDeclaration* cinfo = ClassDeclaration::classinfo; ClassDeclaration* cinfo = ClassDeclaration::classinfo;
DtoForceConstInitDsymbol(cinfo); DtoForceConstInitDsymbol(cinfo);
assert(cinfo->llvmInitZ); assert(cinfo->llvmConstInit);
llvm::Constant* c; llvm::Constant* c;
// own vtable // own vtable
c = cinfo->llvmInitZ->getOperand(0); c = cinfo->llvmConstInit->getOperand(0);
assert(c); assert(c);
inits.push_back(c); inits.push_back(c);
// monitor // monitor
c = cinfo->llvmInitZ->getOperand(1); c = cinfo->llvmConstInit->getOperand(1);
inits.push_back(c); inits.push_back(c);
// byte[] init // byte[] init
const llvm::Type* byteptrty = llvm::PointerType::get(llvm::Type::Int8Ty); const llvm::Type* byteptrty = llvm::PointerType::get(llvm::Type::Int8Ty);
if (cd->isInterfaceDeclaration()) { if (cd->isInterfaceDeclaration()) {
c = cinfo->llvmInitZ->getOperand(2); c = cinfo->llvmConstInit->getOperand(2);
} }
else { else {
c = llvm::ConstantExpr::getBitCast(cdty->llvmInit, byteptrty); c = llvm::ConstantExpr::getBitCast(cd->llvmInit, byteptrty);
assert(!cd->llvmInitZ->getType()->isAbstract()); assert(!cd->llvmConstInit->getType()->isAbstract());
size_t initsz = gTargetData->getTypeSize(cd->llvmInitZ->getType()); size_t initsz = gTargetData->getTypeSize(cd->llvmConstInit->getType());
c = DtoConstSlice(DtoConstSize_t(initsz), c); c = DtoConstSlice(DtoConstSize_t(initsz), c);
} }
inits.push_back(c); inits.push_back(c);
@ -963,7 +963,7 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
// vtbl array // vtbl array
if (cd->isInterfaceDeclaration()) { if (cd->isInterfaceDeclaration()) {
c = cinfo->llvmInitZ->getOperand(4); c = cinfo->llvmConstInit->getOperand(4);
} }
else { else {
const llvm::Type* byteptrptrty = llvm::PointerType::get(byteptrty); const llvm::Type* byteptrptrty = llvm::PointerType::get(byteptrty);
@ -978,10 +978,10 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
// interfaces array // interfaces array
IRStruct* irstruct = cd->llvmIRStruct; IRStruct* irstruct = cd->llvmIRStruct;
if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos) { if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos) {
c = cinfo->llvmInitZ->getOperand(5); c = cinfo->llvmConstInit->getOperand(5);
} }
else { else {
const llvm::Type* t = cinfo->llvmInitZ->getOperand(5)->getType()->getContainedType(1); const llvm::Type* t = cinfo->llvmConstInit->getOperand(5)->getType()->getContainedType(1);
c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t);
size_t iisz = irstruct->interfaceInfosTy->getNumElements(); size_t iisz = irstruct->interfaceInfosTy->getNumElements();
c = DtoConstSlice(DtoConstSize_t(iisz), c); c = DtoConstSlice(DtoConstSize_t(iisz), c);
@ -997,13 +997,13 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
} }
else { else {
// null // null
c = cinfo->llvmInitZ->getOperand(6); c = cinfo->llvmConstInit->getOperand(6);
inits.push_back(c); inits.push_back(c);
} }
// destructor // destructor
if (cd->isInterfaceDeclaration()) { if (cd->isInterfaceDeclaration()) {
c = cinfo->llvmInitZ->getOperand(7); c = cinfo->llvmConstInit->getOperand(7);
} }
else { else {
c = build_class_dtor(cd); c = build_class_dtor(cd);
@ -1012,12 +1012,12 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
// invariant // invariant
// TODO // TODO
c = cinfo->llvmInitZ->getOperand(8); c = cinfo->llvmConstInit->getOperand(8);
inits.push_back(c); inits.push_back(c);
// uint flags // uint flags
if (cd->isInterfaceDeclaration()) { if (cd->isInterfaceDeclaration()) {
c = cinfo->llvmInitZ->getOperand(9); c = cinfo->llvmConstInit->getOperand(9);
} }
else { else {
uint flags = build_classinfo_flags(cd); uint flags = build_classinfo_flags(cd);
@ -1027,15 +1027,15 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
// allocator // allocator
// TODO // TODO
c = cinfo->llvmInitZ->getOperand(10); c = cinfo->llvmConstInit->getOperand(10);
inits.push_back(c); inits.push_back(c);
// offset typeinfo // offset typeinfo
if (cd->isInterfaceDeclaration()) { if (cd->isInterfaceDeclaration()) {
c = cinfo->llvmInitZ->getOperand(11); c = cinfo->llvmConstInit->getOperand(11);
} }
else { else {
c = build_offti_array(cd, cinfo->llvmInitZ->getOperand(11)); c = build_offti_array(cd, cinfo->llvmConstInit->getOperand(11));
} }
inits.push_back(c); inits.push_back(c);
@ -1043,11 +1043,11 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
if (cd->defaultCtor && !cd->isInterfaceDeclaration()) { if (cd->defaultCtor && !cd->isInterfaceDeclaration()) {
DtoForceDeclareDsymbol(cd->defaultCtor); DtoForceDeclareDsymbol(cd->defaultCtor);
c = isaConstant(cd->defaultCtor->llvmValue); c = isaConstant(cd->defaultCtor->llvmValue);
const llvm::Type* toTy = cinfo->llvmInitZ->getOperand(12)->getType(); const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType();
c = llvm::ConstantExpr::getBitCast(c, toTy); c = llvm::ConstantExpr::getBitCast(c, toTy);
} }
else { else {
c = cinfo->llvmInitZ->getOperand(12); c = cinfo->llvmConstInit->getOperand(12);
} }
inits.push_back(c); inits.push_back(c);
@ -1058,10 +1058,10 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
}*/ }*/
// build the initializer // build the initializer
const llvm::StructType* st = isaStruct(cinfo->llvmInitZ->getType()); const llvm::StructType* st = isaStruct(cinfo->llvmConstInit->getType());
llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits); llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits);
//Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n';
cd->llvmClassZ = finalinit; cd->llvmConstClass = finalinit;
cd->llvmClass->setInitializer(finalinit); cd->llvmClass->setInitializer(finalinit);
} }

View file

@ -73,10 +73,10 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const llvm::Type* thistype
ClassDeclaration* ti = Type::typeinfo; ClassDeclaration* ti = Type::typeinfo;
ti->toObjFile(); ti->toObjFile();
DtoForceConstInitDsymbol(ti); DtoForceConstInitDsymbol(ti);
assert(ti->llvmInitZ); assert(ti->llvmConstInit);
std::vector<const llvm::Type*> types; std::vector<const llvm::Type*> types;
types.push_back(DtoSize_t()); types.push_back(DtoSize_t());
types.push_back(llvm::PointerType::get(llvm::PointerType::get(ti->llvmInitZ->getType()))); types.push_back(llvm::PointerType::get(llvm::PointerType::get(ti->llvmConstInit->getType())));
const llvm::Type* t1 = llvm::StructType::get(types); const llvm::Type* t1 = llvm::StructType::get(types);
paramvec.push_back(llvm::PointerType::get(t1)); paramvec.push_back(llvm::PointerType::get(t1));
paramvec.push_back(llvm::PointerType::get(llvm::Type::Int8Ty)); paramvec.push_back(llvm::PointerType::get(llvm::Type::Int8Ty));
@ -182,6 +182,12 @@ const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
return DtoVaFunctionType(fdecl); return DtoVaFunctionType(fdecl);
} }
// unittest has null type, just build it manually
/*if (fdecl->isUnitTestDeclaration()) {
std::vector<const llvm::Type*> args;
return llvm::FunctionType::get(llvm::Type::VoidTy, args, false);
}*/
// type has already been resolved // type has already been resolved
if (fdecl->type->llvmType != 0) { if (fdecl->type->llvmType != 0) {
return llvm::cast<llvm::FunctionType>(fdecl->type->llvmType->get()); return llvm::cast<llvm::FunctionType>(fdecl->type->llvmType->get());
@ -238,6 +244,10 @@ static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl)
void DtoResolveFunction(FuncDeclaration* fdecl) void DtoResolveFunction(FuncDeclaration* fdecl)
{ {
if (!global.params.useUnitTests && fdecl->isUnitTestDeclaration()) {
return; // ignore declaration completely
}
if (fdecl->llvmResolved) return; if (fdecl->llvmResolved) return;
fdecl->llvmResolved = true; fdecl->llvmResolved = true;
@ -249,11 +259,6 @@ void DtoResolveFunction(FuncDeclaration* fdecl)
return; return;
} }
if (fdecl->isUnitTestDeclaration()) {
Logger::attention("ignoring unittest declaration: %s", fdecl->toChars());
return;
}
if (fdecl->parent) if (fdecl->parent)
if (TemplateInstance* tinst = fdecl->parent->isTemplateInstance()) if (TemplateInstance* tinst = fdecl->parent->isTemplateInstance())
{ {
@ -293,6 +298,12 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
assert(!fdecl->isAbstract()); assert(!fdecl->isAbstract());
// intrinsic sanity check
if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) {
error(fdecl->loc, "intrinsics cannot have function bodies");
fatal();
}
if (fdecl->llvmRunTimeHack) { if (fdecl->llvmRunTimeHack) {
Logger::println("runtime hack func chars: %s", fdecl->toChars()); Logger::println("runtime hack func chars: %s", fdecl->toChars());
if (!fdecl->llvmValue) if (!fdecl->llvmValue)
@ -318,26 +329,6 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
else else
mangled_name = fdecl->mangle(); mangled_name = fdecl->mangle();
// unit test special handling
if (fdecl->isUnitTestDeclaration())
{
assert(0 && "no unittests yet");
/*const llvm::FunctionType* fnty = llvm::FunctionType::get(llvm::Type::VoidTy, std::vector<const llvm::Type*>(), false);
// make the function
llvm::Function* func = gIR->module->getFunction(mangled_name);
if (func == 0)
func = new llvm::Function(fnty,llvm::GlobalValue::InternalLinkage,mangled_name,gIR->module);
func->setCallingConv(llvm::CallingConv::Fast);
fdecl->llvmValue = func;
return func;
*/
}
if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) {
error("intrinsics cannot have function bodies");
fatal();
}
llvm::Function* vafunc = 0; llvm::Function* vafunc = 0;
if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) { if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) {
vafunc = DtoDeclareVaFunction(fdecl); vafunc = DtoDeclareVaFunction(fdecl);
@ -387,7 +378,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
int k = 0; int k = 0;
if (f->llvmRetInPtr) { if (f->llvmRetInPtr) {
iarg->setName("retval"); iarg->setName("retval");
f->llvmRetArg = iarg; fdecl->llvmRetArg = iarg;
++iarg; ++iarg;
} }
if (f->llvmUsesThis) { if (f->llvmUsesThis) {
@ -422,6 +413,9 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
} }
} }
if (fdecl->isUnitTestDeclaration())
gIR->unitTests.push_back(fdecl);
if (!declareOnly) if (!declareOnly)
gIR->defineList.push_back(fdecl); gIR->defineList.push_back(fdecl);
@ -430,7 +424,6 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// TODO split this monster up
void DtoDefineFunc(FuncDeclaration* fd) void DtoDefineFunc(FuncDeclaration* fd)
{ {
if (fd->llvmDefined) return; if (fd->llvmDefined) return;
@ -452,8 +445,8 @@ void DtoDefineFunc(FuncDeclaration* fd)
Type* t = DtoDType(fd->type); Type* t = DtoDType(fd->type);
TypeFunction* f = (TypeFunction*)t; TypeFunction* f = (TypeFunction*)t;
assert(f->llvmType); assert(f->llvmType);
llvm::Function* func = fd->llvmIRFunc->func; llvm::Function* func = fd->llvmIRFunc->func;
const llvm::FunctionType* functype = func->getFunctionType(); const llvm::FunctionType* functype = func->getFunctionType();
@ -479,13 +472,13 @@ void DtoDefineFunc(FuncDeclaration* fd)
gIR->scopes.push_back(IRScope(beginbb, endbb)); gIR->scopes.push_back(IRScope(beginbb, endbb));
// create alloca point // create alloca point
f->llvmAllocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb()); llvm::Instruction* allocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb());
gIR->func()->allocapoint = f->llvmAllocaPoint; gIR->func()->allocapoint = allocaPoint;
// need result variable? (not nested) // need result variable? (not nested)
if (fd->vresult && !fd->vresult->nestedref) { if (fd->vresult && !fd->vresult->nestedref) {
Logger::println("non-nested vresult value"); Logger::println("non-nested vresult value");
fd->vresult->llvmValue = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",f->llvmAllocaPoint); fd->vresult->llvmValue = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
} }
// give arguments storage // give arguments storage
@ -501,7 +494,7 @@ void DtoDefineFunc(FuncDeclaration* fd)
std::string s(a->getName()); std::string s(a->getName());
Logger::println("giving argument '%s' storage", s.c_str()); Logger::println("giving argument '%s' storage", s.c_str());
s.append("_storage"); s.append("_storage");
llvm::Value* v = new llvm::AllocaInst(a->getType(),s,f->llvmAllocaPoint); llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
gIR->ir->CreateStore(a,v); gIR->ir->CreateStore(a,v);
vd->llvmValue = v; vd->llvmValue = v;
} }
@ -546,7 +539,7 @@ void DtoDefineFunc(FuncDeclaration* fd)
} }
const llvm::StructType* nestSType = llvm::StructType::get(nestTypes); const llvm::StructType* nestSType = llvm::StructType::get(nestTypes);
Logger::cout() << "nested var struct has type:" << '\n' << *nestSType; Logger::cout() << "nested var struct has type:" << '\n' << *nestSType;
fd->llvmNested = new llvm::AllocaInst(nestSType,"nestedvars",f->llvmAllocaPoint); fd->llvmNested = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
if (parentNested) { if (parentNested) {
assert(fd->llvmThisVar); assert(fd->llvmThisVar);
llvm::Value* ptr = gIR->ir->CreateBitCast(fd->llvmThisVar, parentNested->getType(), "tmp"); llvm::Value* ptr = gIR->ir->CreateBitCast(fd->llvmThisVar, parentNested->getType(), "tmp");
@ -588,8 +581,8 @@ void DtoDefineFunc(FuncDeclaration* fd)
} }
// erase alloca point // erase alloca point
f->llvmAllocaPoint->eraseFromParent(); allocaPoint->eraseFromParent();
f->llvmAllocaPoint = 0; allocaPoint = 0;
gIR->func()->allocapoint = 0; gIR->func()->allocapoint = 0;
gIR->scopes.pop_back(); gIR->scopes.pop_back();
@ -649,6 +642,12 @@ void DtoMain()
llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_moduleCtor"); llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_moduleCtor");
llvm::Instruction* apt = new llvm::CallInst(fn,"",bb); llvm::Instruction* apt = new llvm::CallInst(fn,"",bb);
// run unit tests if -unittest is provided
if (global.params.useUnitTests) {
fn = LLVM_D_GetRuntimeFunction(ir.module,"_moduleUnitTests");
llvm::Instruction* apt = new llvm::CallInst(fn,"",bb);
}
// call user main function // call user main function
const llvm::FunctionType* mainty = ir.mainFunc->getFunctionType(); const llvm::FunctionType* mainty = ir.mainFunc->getFunctionType();
llvm::CallInst* call; llvm::CallInst* call;

View file

@ -57,12 +57,13 @@ void ReturnStatement::toIR(IRState* p)
if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
assert(DtoIsPassedByRef(exptype)); assert(DtoIsPassedByRef(exptype));
TypeFunction* f = p->topfunctype(); IRFunction* f = p->func();
assert(f->llvmRetInPtr && f->llvmRetArg); assert(f->type->llvmRetInPtr);
assert(f->decl->llvmRetArg);
if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum);
DValue* rvar = new DVarValue(f->next, f->llvmRetArg, true); DValue* rvar = new DVarValue(f->type->next, f->decl->llvmRetArg, true);
p->exps.push_back(IRExp(NULL,exp,rvar)); p->exps.push_back(IRExp(NULL,exp,rvar));
DValue* e = exp->toElem(p); DValue* e = exp->toElem(p);
@ -71,9 +72,9 @@ void ReturnStatement::toIR(IRState* p)
if (!e->inPlace()) if (!e->inPlace())
DtoAssign(rvar, e); DtoAssign(rvar, e);
IRFunction::FinallyVec& fin = p->func()->finallys; IRFunction::FinallyVec& fin = f->finallys;
if (fin.empty()) { if (fin.empty()) {
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
new llvm::ReturnInst(p->scopebb()); new llvm::ReturnInst(p->scopebb());
} }
else { else {

View file

@ -304,7 +304,7 @@ void DtoDeclareStruct(StructDeclaration* sd)
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module);
ts->llvmInit = initvar; sd->llvmInit = initvar;
gIR->constInitList.push_back(sd); gIR->constInitList.push_back(sd);
if (sd->getModule() == gIR->dmodule) if (sd->getModule() == gIR->dmodule)
@ -369,11 +369,11 @@ void DtoConstInitStruct(StructDeclaration* sd)
} }
Logger::cout() << "Initializer printed" << '\n'; Logger::cout() << "Initializer printed" << '\n';
#endif #endif
sd->llvmInitZ = llvm::ConstantStruct::get(structtype,fieldinits_ll); sd->llvmConstInit = llvm::ConstantStruct::get(structtype,fieldinits_ll);
} }
else { else {
Logger::println("Zero initialized"); Logger::println("Zero initialized");
sd->llvmInitZ = llvm::ConstantAggregateZero::get(structtype); sd->llvmConstInit = llvm::ConstantAggregateZero::get(structtype);
} }
gIR->structs.pop_back(); gIR->structs.pop_back();
@ -395,7 +395,7 @@ void DtoDefineStruct(StructDeclaration* sd)
assert(sd->type->ty == Tstruct); assert(sd->type->ty == Tstruct);
TypeStruct* ts = (TypeStruct*)sd->type; TypeStruct* ts = (TypeStruct*)sd->type;
ts->llvmInit->setInitializer(sd->llvmInitZ); sd->llvmInit->setInitializer(sd->llvmConstInit);
sd->llvmDModule = gIR->dmodule; sd->llvmDModule = gIR->dmodule;
} }

View file

@ -215,8 +215,9 @@ DValue* VarExp::toElem(IRState* p)
Logger::print("Sym: type=%s\n", sdecltype->toChars()); Logger::print("Sym: type=%s\n", sdecltype->toChars());
assert(sdecltype->ty == Tstruct); assert(sdecltype->ty == Tstruct);
TypeStruct* ts = (TypeStruct*)sdecltype; TypeStruct* ts = (TypeStruct*)sdecltype;
assert(ts->llvmInit); assert(ts->sym);
return new DVarValue(type, ts->llvmInit, true); assert(ts->sym->llvmInit);
return new DVarValue(type, ts->sym->llvmInit, true);
} }
else else
{ {
@ -240,8 +241,8 @@ llvm::Constant* VarExp::toConstElem(IRState* p)
assert(sdecltype->ty == Tstruct); assert(sdecltype->ty == Tstruct);
TypeStruct* ts = (TypeStruct*)sdecltype; TypeStruct* ts = (TypeStruct*)sdecltype;
DtoForceConstInitDsymbol(ts->sym); DtoForceConstInitDsymbol(ts->sym);
assert(ts->sym->llvmInitZ); assert(ts->sym->llvmConstInit);
return ts->sym->llvmInitZ; return ts->sym->llvmConstInit;
} }
assert(0 && "Only supported const VarExp is of a SymbolDeclaration"); assert(0 && "Only supported const VarExp is of a SymbolDeclaration");
return NULL; return NULL;
@ -1004,8 +1005,8 @@ DValue* CallExp::toElem(IRState* p)
p->ir->CreateStore(vvalues[i], DtoGEPi(mem,0,i,"tmp")); p->ir->CreateStore(vvalues[i], DtoGEPi(mem,0,i,"tmp"));
//llvm::Constant* typeinfoparam = llvm::ConstantPointerNull::get(isaPointer(llfnty->getParamType(j))); //llvm::Constant* typeinfoparam = llvm::ConstantPointerNull::get(isaPointer(llfnty->getParamType(j)));
assert(Type::typeinfo->llvmInitZ); assert(Type::typeinfo->llvmConstInit);
const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmInitZ->getType()); const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmConstInit->getType());
Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n'; Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n';
const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint()); llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint());
@ -1830,7 +1831,8 @@ DValue* NewExp::toElem(IRState* p)
DtoStructZeroInit(emem); DtoStructZeroInit(emem);
} }
else { else {
DtoStructCopy(emem,ts->llvmInit); assert(ts->sym);
DtoStructCopy(emem,ts->sym->llvmInit);
} }
} }

View file

@ -522,8 +522,8 @@ llvm::Constant* DtoConstFieldInitializer(Type* t, Initializer* init)
TypeStruct* ts = (TypeStruct*)t; TypeStruct* ts = (TypeStruct*)t;
assert(ts); assert(ts);
assert(ts->sym); assert(ts->sym);
assert(ts->sym->llvmInitZ); assert(ts->sym->llvmConstInit);
_init = ts->sym->llvmInitZ; _init = ts->sym->llvmConstInit;
} }
else if (t->ty == Tclass) else if (t->ty == Tclass)
{ {
@ -1529,8 +1529,8 @@ void DtoConstInitGlobal(VarDeclaration* vd)
llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init); llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init);
assert(t->ty == Tstruct); assert(t->ty == Tstruct);
TypeStruct* ts = (TypeStruct*)t; TypeStruct* ts = (TypeStruct*)t;
assert(ts->sym->llvmInitZ); assert(ts->sym->llvmConstInit);
_init = ts->sym->llvmInitZ; _init = ts->sym->llvmConstInit;
} }
// array single value init // array single value init
else if (isaArray(_type)) else if (isaArray(_type))

View file

@ -223,6 +223,39 @@ static llvm::Function* build_module_dtor()
return fn; return fn;
} }
// build module unittest
static llvm::Function* build_module_unittest()
{
if (gIR->unitTests.empty())
return NULL;
size_t n = gIR->unitTests.size();
if (n == 1)
return llvm::cast<llvm::Function>(gIR->unitTests[0]->llvmValue);
std::string name("_D");
name.append(gIR->dmodule->mangle());
name.append("10__unittestZ");
std::vector<const llvm::Type*> argsTy;
const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy,argsTy,false);
llvm::Function* fn = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, name, gIR->module);
fn->setCallingConv(llvm::CallingConv::Fast);
llvm::BasicBlock* bb = new llvm::BasicBlock("entry", fn);
LLVMBuilder builder(bb);
for (size_t i=0; i<n; i++) {
llvm::Function* f = llvm::cast<llvm::Function>(gIR->unitTests[i]->llvmValue);
llvm::CallInst* call = builder.CreateCall(f,"");
call->setCallingConv(llvm::CallingConv::Fast);
}
builder.CreateRetVoid();
return fn;
}
// Put out instance of ModuleInfo for this Module // Put out instance of ModuleInfo for this Module
void Module::genmoduleinfo() void Module::genmoduleinfo()
@ -296,7 +329,7 @@ void Module::genmoduleinfo()
c = DtoConstSlice(DtoConstSize_t(importInits.size()), c); c = DtoConstSlice(DtoConstSize_t(importInits.size()), c);
} }
else else
c = moduleinfo->llvmInitZ->getOperand(3); c = moduleinfo->llvmConstInit->getOperand(3);
initVec.push_back(c); initVec.push_back(c);
// localClasses[] // localClasses[]
@ -330,7 +363,7 @@ void Module::genmoduleinfo()
c = DtoConstSlice(DtoConstSize_t(classInits.size()), c); c = DtoConstSlice(DtoConstSize_t(classInits.size()), c);
} }
else else
c = moduleinfo->llvmInitZ->getOperand(4); c = moduleinfo->llvmConstInit->getOperand(4);
initVec.push_back(c); initVec.push_back(c);
// flags // flags
@ -342,16 +375,17 @@ void Module::genmoduleinfo()
// ctor // ctor
llvm::Function* fctor = build_module_ctor(); llvm::Function* fctor = build_module_ctor();
c = fctor ? fctor : moduleinfo->llvmInitZ->getOperand(6); c = fctor ? fctor : moduleinfo->llvmConstInit->getOperand(6);
initVec.push_back(c); initVec.push_back(c);
// dtor // dtor
llvm::Function* fdtor = build_module_dtor(); llvm::Function* fdtor = build_module_dtor();
c = fdtor ? fdtor : moduleinfo->llvmInitZ->getOperand(7); c = fdtor ? fdtor : moduleinfo->llvmConstInit->getOperand(7);
initVec.push_back(c); initVec.push_back(c);
// unitTest // unitTest
c = moduleinfo->llvmInitZ->getOperand(8); llvm::Function* unittest = build_module_unittest();
c = unittest ? unittest : moduleinfo->llvmConstInit->getOperand(8);
initVec.push_back(c); initVec.push_back(c);
// create initializer // create initializer

View file

@ -852,9 +852,8 @@ void TypeInfoStructDeclaration::llvmDefine()
} }
else else
{ {
assert(sd->llvmInitZ);
size_t cisize = gTargetData->getTypeSize(tc->llvmType->get()); size_t cisize = gTargetData->getTypeSize(tc->llvmType->get());
llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(tc->llvmInit, initpt); llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(sd->llvmInit, initpt);
sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast)); sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
} }

View file

@ -98,7 +98,7 @@
<hidenonlocation>false</hidenonlocation> <hidenonlocation>false</hidenonlocation>
</groups> </groups>
<tree> <tree>
<hidepatterns>*.bc,*.ll</hidepatterns> <hidepatterns>*.bc</hidepatterns>
<hidenonprojectfiles>false</hidenonprojectfiles> <hidenonprojectfiles>false</hidenonprojectfiles>
</tree> </tree>
</kdevfileview> </kdevfileview>

View file

@ -12,6 +12,8 @@ void main()
len = strlen(prefix); len = strlen(prefix);
assert(len == 0); assert(len == 0);
} }
func();
} }
func2(); func2();
} }

View file

@ -1,9 +1,10 @@
module unittest1; module unittest1;
unittest
{
}
void main() void main()
{ {
} }
unittest
{
printf("hello\n");
}