# HG changeset patch # User lindquist # Date 1196129376 -3600 # Node ID 9c79b61fb63837e198da7fce3f0b07b0ca2bc93a # Parent 5ce8ab11e75a7867113c54fc432c8f9337344b06 [svn r125] Renamed/moved a few backend member inside DMD structures for consistency. Unit tests are now implemented. diff -r 5ce8ab11e75a -r 9c79b61fb638 dmd/aggregate.h --- a/dmd/aggregate.h Mon Nov 26 07:26:21 2007 +0100 +++ b/dmd/aggregate.h Tue Nov 27 03:09:36 2007 +0100 @@ -104,9 +104,10 @@ bool llvmInProgress; llvm::GlobalVariable* llvmVtbl; llvm::ConstantStruct* llvmConstVtbl; - llvm::Constant* llvmInitZ; + llvm::GlobalVariable* llvmInit; + llvm::Constant* llvmConstInit; llvm::GlobalVariable* llvmClass; - llvm::Constant* llvmClassZ; + llvm::Constant* llvmConstClass; bool llvmHasUnions; DUnion* llvmUnion; IRStruct* llvmIRStruct; diff -r 5ce8ab11e75a -r 9c79b61fb638 dmd/declaration.h --- a/dmd/declaration.h Mon Nov 26 07:26:21 2007 +0100 +++ b/dmd/declaration.h Tue Nov 27 03:09:36 2007 +0100 @@ -615,6 +615,7 @@ llvm::Constant* llvmDwarfSubProgram; bool llvmRunTimeHack; IRFunction* llvmIRFunc; + llvm::Value* llvmRetArg; }; struct FuncAliasDeclaration : FuncDeclaration diff -r 5ce8ab11e75a -r 9c79b61fb638 dmd/func.c --- a/dmd/func.c Mon Nov 26 07:26:21 2007 +0100 +++ b/dmd/func.c Tue Nov 27 03:09:36 2007 +0100 @@ -81,6 +81,7 @@ llvmDwarfSubProgram = NULL; llvmRunTimeHack = false; llvmIRFunc = NULL; + llvmRetArg = NULL; } Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s) diff -r 5ce8ab11e75a -r 9c79b61fb638 dmd/mtype.c --- a/dmd/mtype.c Mon Nov 26 07:26:21 2007 +0100 +++ b/dmd/mtype.c Tue Nov 27 03:09:36 2007 +0100 @@ -2560,8 +2560,6 @@ this->inuse = 0; this->llvmRetInPtr = false; this->llvmUsesThis = false; - this->llvmRetArg = 0; - this->llvmAllocaPoint = 0; } Type *TypeFunction::syntaxCopy() @@ -4094,7 +4092,6 @@ : Type(Tstruct, NULL) { this->sym = sym; - llvmInit = 0; } char *TypeStruct::toChars() @@ -4383,7 +4380,6 @@ : Type(Tclass, NULL) { this->sym = sym; - llvmInit = 0; llvmVtblType = 0; } diff -r 5ce8ab11e75a -r 9c79b61fb638 dmd/mtype.h --- a/dmd/mtype.h Mon Nov 26 07:26:21 2007 +0100 +++ b/dmd/mtype.h Tue Nov 27 03:09:36 2007 +0100 @@ -437,8 +437,6 @@ bool llvmRetInPtr; bool llvmUsesThis; - llvm::Value* llvmRetArg; - llvm::Instruction* llvmAllocaPoint; }; struct TypeDelegate : Type @@ -542,8 +540,6 @@ int hasPointers(); type *toCtype(); - - llvm::GlobalVariable* llvmInit; }; struct TypeEnum : Type @@ -641,7 +637,6 @@ Symbol *toSymbol(); - llvm::GlobalVariable* llvmInit; llvm::PATypeHolder* llvmVtblType; }; diff -r 5ce8ab11e75a -r 9c79b61fb638 dmd/struct.c --- a/dmd/struct.c Mon Nov 26 07:26:21 2007 +0100 +++ b/dmd/struct.c Tue Nov 27 03:09:36 2007 +0100 @@ -47,9 +47,10 @@ llvmVtbl = NULL; llvmConstVtbl = NULL; - llvmInitZ = NULL; + llvmInit = NULL; + llvmConstInit = NULL; llvmClass = NULL; - llvmClassZ = NULL; + llvmConstClass = NULL; llvmInProgress = false; llvmHasUnions = false; llvmUnion = NULL; diff -r 5ce8ab11e75a -r 9c79b61fb638 gen/classes.cpp --- a/gen/classes.cpp Mon Nov 26 07:26:21 2007 +0100 +++ b/gen/classes.cpp Tue Nov 27 03:09:36 2007 +0100 @@ -305,7 +305,7 @@ initname.append("6__initZ"); 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(); @@ -394,7 +394,7 @@ llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits); assert(_init); - cd->llvmInitZ = _init; + cd->llvmConstInit = _init; // generate vtable initializer std::vector sinits; @@ -524,7 +524,7 @@ if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) { // interfaces don't have initializers if (!cd->isInterfaceDeclaration()) { - ts->llvmInit->setInitializer(cd->llvmInitZ); + cd->llvmInit->setInitializer(cd->llvmConstInit); cd->llvmVtbl->setInitializer(cd->llvmConstVtbl); // initialize interface vtables @@ -579,15 +579,15 @@ // copy the static initializer if (n > 0) { - assert(tc->llvmInit); - assert(dst->getType() == tc->llvmInit->getType()); + assert(tc->sym->llvmInit); + assert(dst->getType() == tc->sym->llvmInit->getType()); llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"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()); llvm::Function* fn = LLVM_DeclareMemCpy32(); @@ -912,10 +912,10 @@ TypeClass* cdty = (TypeClass*)cd->type; if (!cd->isInterfaceDeclaration()) { - assert(cd->llvmInitZ); + assert(cd->llvmInit); + assert(cd->llvmConstInit); assert(cd->llvmVtbl); assert(cd->llvmConstVtbl); - assert(cdty->llvmInit); } // holds the list of initializers for llvm @@ -923,28 +923,28 @@ ClassDeclaration* cinfo = ClassDeclaration::classinfo; DtoForceConstInitDsymbol(cinfo); - assert(cinfo->llvmInitZ); + assert(cinfo->llvmConstInit); llvm::Constant* c; // own vtable - c = cinfo->llvmInitZ->getOperand(0); + c = cinfo->llvmConstInit->getOperand(0); assert(c); inits.push_back(c); // monitor - c = cinfo->llvmInitZ->getOperand(1); + c = cinfo->llvmConstInit->getOperand(1); inits.push_back(c); // byte[] init const llvm::Type* byteptrty = llvm::PointerType::get(llvm::Type::Int8Ty); if (cd->isInterfaceDeclaration()) { - c = cinfo->llvmInitZ->getOperand(2); + c = cinfo->llvmConstInit->getOperand(2); } else { - c = llvm::ConstantExpr::getBitCast(cdty->llvmInit, byteptrty); - assert(!cd->llvmInitZ->getType()->isAbstract()); - size_t initsz = gTargetData->getTypeSize(cd->llvmInitZ->getType()); + c = llvm::ConstantExpr::getBitCast(cd->llvmInit, byteptrty); + assert(!cd->llvmConstInit->getType()->isAbstract()); + size_t initsz = gTargetData->getTypeSize(cd->llvmConstInit->getType()); c = DtoConstSlice(DtoConstSize_t(initsz), c); } inits.push_back(c); @@ -963,7 +963,7 @@ // vtbl array if (cd->isInterfaceDeclaration()) { - c = cinfo->llvmInitZ->getOperand(4); + c = cinfo->llvmConstInit->getOperand(4); } else { const llvm::Type* byteptrptrty = llvm::PointerType::get(byteptrty); @@ -978,10 +978,10 @@ // interfaces array IRStruct* irstruct = cd->llvmIRStruct; if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos) { - c = cinfo->llvmInitZ->getOperand(5); + c = cinfo->llvmConstInit->getOperand(5); } 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); size_t iisz = irstruct->interfaceInfosTy->getNumElements(); c = DtoConstSlice(DtoConstSize_t(iisz), c); @@ -997,13 +997,13 @@ } else { // null - c = cinfo->llvmInitZ->getOperand(6); + c = cinfo->llvmConstInit->getOperand(6); inits.push_back(c); } // destructor if (cd->isInterfaceDeclaration()) { - c = cinfo->llvmInitZ->getOperand(7); + c = cinfo->llvmConstInit->getOperand(7); } else { c = build_class_dtor(cd); @@ -1012,12 +1012,12 @@ // invariant // TODO - c = cinfo->llvmInitZ->getOperand(8); + c = cinfo->llvmConstInit->getOperand(8); inits.push_back(c); // uint flags if (cd->isInterfaceDeclaration()) { - c = cinfo->llvmInitZ->getOperand(9); + c = cinfo->llvmConstInit->getOperand(9); } else { uint flags = build_classinfo_flags(cd); @@ -1027,15 +1027,15 @@ // allocator // TODO - c = cinfo->llvmInitZ->getOperand(10); + c = cinfo->llvmConstInit->getOperand(10); inits.push_back(c); // offset typeinfo if (cd->isInterfaceDeclaration()) { - c = cinfo->llvmInitZ->getOperand(11); + c = cinfo->llvmConstInit->getOperand(11); } else { - c = build_offti_array(cd, cinfo->llvmInitZ->getOperand(11)); + c = build_offti_array(cd, cinfo->llvmConstInit->getOperand(11)); } inits.push_back(c); @@ -1043,11 +1043,11 @@ if (cd->defaultCtor && !cd->isInterfaceDeclaration()) { DtoForceDeclareDsymbol(cd->defaultCtor); 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); } else { - c = cinfo->llvmInitZ->getOperand(12); + c = cinfo->llvmConstInit->getOperand(12); } inits.push_back(c); @@ -1058,10 +1058,10 @@ }*/ // 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); //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; - cd->llvmClassZ = finalinit; + cd->llvmConstClass = finalinit; cd->llvmClass->setInitializer(finalinit); } diff -r 5ce8ab11e75a -r 9c79b61fb638 gen/functions.cpp --- a/gen/functions.cpp Mon Nov 26 07:26:21 2007 +0100 +++ b/gen/functions.cpp Tue Nov 27 03:09:36 2007 +0100 @@ -73,10 +73,10 @@ ClassDeclaration* ti = Type::typeinfo; ti->toObjFile(); DtoForceConstInitDsymbol(ti); - assert(ti->llvmInitZ); + assert(ti->llvmConstInit); std::vector types; 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); paramvec.push_back(llvm::PointerType::get(t1)); paramvec.push_back(llvm::PointerType::get(llvm::Type::Int8Ty)); @@ -182,6 +182,12 @@ return DtoVaFunctionType(fdecl); } + // unittest has null type, just build it manually + /*if (fdecl->isUnitTestDeclaration()) { + std::vector args; + return llvm::FunctionType::get(llvm::Type::VoidTy, args, false); + }*/ + // type has already been resolved if (fdecl->type->llvmType != 0) { return llvm::cast(fdecl->type->llvmType->get()); @@ -238,6 +244,10 @@ void DtoResolveFunction(FuncDeclaration* fdecl) { + if (!global.params.useUnitTests && fdecl->isUnitTestDeclaration()) { + return; // ignore declaration completely + } + if (fdecl->llvmResolved) return; fdecl->llvmResolved = true; @@ -249,11 +259,6 @@ return; } - if (fdecl->isUnitTestDeclaration()) { - Logger::attention("ignoring unittest declaration: %s", fdecl->toChars()); - return; - } - if (fdecl->parent) if (TemplateInstance* tinst = fdecl->parent->isTemplateInstance()) { @@ -293,6 +298,12 @@ assert(!fdecl->isAbstract()); + // intrinsic sanity check + if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) { + error(fdecl->loc, "intrinsics cannot have function bodies"); + fatal(); + } + if (fdecl->llvmRunTimeHack) { Logger::println("runtime hack func chars: %s", fdecl->toChars()); if (!fdecl->llvmValue) @@ -318,26 +329,6 @@ else 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(), 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; if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) { vafunc = DtoDeclareVaFunction(fdecl); @@ -387,7 +378,7 @@ int k = 0; if (f->llvmRetInPtr) { iarg->setName("retval"); - f->llvmRetArg = iarg; + fdecl->llvmRetArg = iarg; ++iarg; } if (f->llvmUsesThis) { @@ -422,6 +413,9 @@ } } + if (fdecl->isUnitTestDeclaration()) + gIR->unitTests.push_back(fdecl); + if (!declareOnly) gIR->defineList.push_back(fdecl); @@ -430,7 +424,6 @@ ////////////////////////////////////////////////////////////////////////////////////////// -// TODO split this monster up void DtoDefineFunc(FuncDeclaration* fd) { if (fd->llvmDefined) return; @@ -452,8 +445,8 @@ Type* t = DtoDType(fd->type); TypeFunction* f = (TypeFunction*)t; + assert(f->llvmType); - assert(f->llvmType); llvm::Function* func = fd->llvmIRFunc->func; const llvm::FunctionType* functype = func->getFunctionType(); @@ -479,13 +472,13 @@ gIR->scopes.push_back(IRScope(beginbb, endbb)); // create alloca point - f->llvmAllocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb()); - gIR->func()->allocapoint = f->llvmAllocaPoint; + llvm::Instruction* allocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb()); + gIR->func()->allocapoint = allocaPoint; // need result variable? (not nested) if (fd->vresult && !fd->vresult->nestedref) { 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 @@ -501,7 +494,7 @@ std::string s(a->getName()); Logger::println("giving argument '%s' storage", s.c_str()); 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); vd->llvmValue = v; } @@ -546,7 +539,7 @@ } const llvm::StructType* nestSType = llvm::StructType::get(nestTypes); 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) { assert(fd->llvmThisVar); llvm::Value* ptr = gIR->ir->CreateBitCast(fd->llvmThisVar, parentNested->getType(), "tmp"); @@ -588,8 +581,8 @@ } // erase alloca point - f->llvmAllocaPoint->eraseFromParent(); - f->llvmAllocaPoint = 0; + allocaPoint->eraseFromParent(); + allocaPoint = 0; gIR->func()->allocapoint = 0; gIR->scopes.pop_back(); @@ -649,6 +642,12 @@ llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_moduleCtor"); 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 const llvm::FunctionType* mainty = ir.mainFunc->getFunctionType(); llvm::CallInst* call; diff -r 5ce8ab11e75a -r 9c79b61fb638 gen/statements.cpp --- a/gen/statements.cpp Mon Nov 26 07:26:21 2007 +0100 +++ b/gen/statements.cpp Tue Nov 27 03:09:36 2007 +0100 @@ -57,12 +57,13 @@ if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { assert(DtoIsPassedByRef(exptype)); - TypeFunction* f = p->topfunctype(); - assert(f->llvmRetInPtr && f->llvmRetArg); + IRFunction* f = p->func(); + assert(f->type->llvmRetInPtr); + assert(f->decl->llvmRetArg); 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)); DValue* e = exp->toElem(p); @@ -71,9 +72,9 @@ if (!e->inPlace()) DtoAssign(rvar, e); - IRFunction::FinallyVec& fin = p->func()->finallys; + IRFunction::FinallyVec& fin = f->finallys; if (fin.empty()) { - if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); + if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); new llvm::ReturnInst(p->scopebb()); } else { diff -r 5ce8ab11e75a -r 9c79b61fb638 gen/structs.cpp --- a/gen/structs.cpp Mon Nov 26 07:26:21 2007 +0100 +++ b/gen/structs.cpp Tue Nov 27 03:09:36 2007 +0100 @@ -304,7 +304,7 @@ llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; 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); if (sd->getModule() == gIR->dmodule) @@ -369,11 +369,11 @@ } Logger::cout() << "Initializer printed" << '\n'; #endif - sd->llvmInitZ = llvm::ConstantStruct::get(structtype,fieldinits_ll); + sd->llvmConstInit = llvm::ConstantStruct::get(structtype,fieldinits_ll); } else { Logger::println("Zero initialized"); - sd->llvmInitZ = llvm::ConstantAggregateZero::get(structtype); + sd->llvmConstInit = llvm::ConstantAggregateZero::get(structtype); } gIR->structs.pop_back(); @@ -395,7 +395,7 @@ assert(sd->type->ty == Tstruct); TypeStruct* ts = (TypeStruct*)sd->type; - ts->llvmInit->setInitializer(sd->llvmInitZ); + sd->llvmInit->setInitializer(sd->llvmConstInit); sd->llvmDModule = gIR->dmodule; } diff -r 5ce8ab11e75a -r 9c79b61fb638 gen/toir.cpp --- a/gen/toir.cpp Mon Nov 26 07:26:21 2007 +0100 +++ b/gen/toir.cpp Tue Nov 27 03:09:36 2007 +0100 @@ -215,8 +215,9 @@ Logger::print("Sym: type=%s\n", sdecltype->toChars()); assert(sdecltype->ty == Tstruct); TypeStruct* ts = (TypeStruct*)sdecltype; - assert(ts->llvmInit); - return new DVarValue(type, ts->llvmInit, true); + assert(ts->sym); + assert(ts->sym->llvmInit); + return new DVarValue(type, ts->sym->llvmInit, true); } else { @@ -240,8 +241,8 @@ assert(sdecltype->ty == Tstruct); TypeStruct* ts = (TypeStruct*)sdecltype; DtoForceConstInitDsymbol(ts->sym); - assert(ts->sym->llvmInitZ); - return ts->sym->llvmInitZ; + assert(ts->sym->llvmConstInit); + return ts->sym->llvmConstInit; } assert(0 && "Only supported const VarExp is of a SymbolDeclaration"); return NULL; @@ -1004,8 +1005,8 @@ p->ir->CreateStore(vvalues[i], DtoGEPi(mem,0,i,"tmp")); //llvm::Constant* typeinfoparam = llvm::ConstantPointerNull::get(isaPointer(llfnty->getParamType(j))); - assert(Type::typeinfo->llvmInitZ); - const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmInitZ->getType()); + assert(Type::typeinfo->llvmConstInit); + const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmConstInit->getType()); Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n'; const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint()); @@ -1830,7 +1831,8 @@ DtoStructZeroInit(emem); } else { - DtoStructCopy(emem,ts->llvmInit); + assert(ts->sym); + DtoStructCopy(emem,ts->sym->llvmInit); } } diff -r 5ce8ab11e75a -r 9c79b61fb638 gen/tollvm.cpp --- a/gen/tollvm.cpp Mon Nov 26 07:26:21 2007 +0100 +++ b/gen/tollvm.cpp Tue Nov 27 03:09:36 2007 +0100 @@ -522,8 +522,8 @@ TypeStruct* ts = (TypeStruct*)t; assert(ts); assert(ts->sym); - assert(ts->sym->llvmInitZ); - _init = ts->sym->llvmInitZ; + assert(ts->sym->llvmConstInit); + _init = ts->sym->llvmConstInit; } else if (t->ty == Tclass) { @@ -1529,8 +1529,8 @@ llvm::GlobalVariable* gv = llvm::cast(_init); assert(t->ty == Tstruct); TypeStruct* ts = (TypeStruct*)t; - assert(ts->sym->llvmInitZ); - _init = ts->sym->llvmInitZ; + assert(ts->sym->llvmConstInit); + _init = ts->sym->llvmConstInit; } // array single value init else if (isaArray(_type)) diff -r 5ce8ab11e75a -r 9c79b61fb638 gen/toobj.cpp --- a/gen/toobj.cpp Mon Nov 26 07:26:21 2007 +0100 +++ b/gen/toobj.cpp Tue Nov 27 03:09:36 2007 +0100 @@ -223,6 +223,39 @@ 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(gIR->unitTests[0]->llvmValue); + + std::string name("_D"); + name.append(gIR->dmodule->mangle()); + name.append("10__unittestZ"); + + std::vector 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(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 void Module::genmoduleinfo() @@ -296,7 +329,7 @@ c = DtoConstSlice(DtoConstSize_t(importInits.size()), c); } else - c = moduleinfo->llvmInitZ->getOperand(3); + c = moduleinfo->llvmConstInit->getOperand(3); initVec.push_back(c); // localClasses[] @@ -330,7 +363,7 @@ c = DtoConstSlice(DtoConstSize_t(classInits.size()), c); } else - c = moduleinfo->llvmInitZ->getOperand(4); + c = moduleinfo->llvmConstInit->getOperand(4); initVec.push_back(c); // flags @@ -342,16 +375,17 @@ // 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); // 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); // unitTest - c = moduleinfo->llvmInitZ->getOperand(8); + llvm::Function* unittest = build_module_unittest(); + c = unittest ? unittest : moduleinfo->llvmConstInit->getOperand(8); initVec.push_back(c); // create initializer diff -r 5ce8ab11e75a -r 9c79b61fb638 gen/typinf.cpp --- a/gen/typinf.cpp Mon Nov 26 07:26:21 2007 +0100 +++ b/gen/typinf.cpp Tue Nov 27 03:09:36 2007 +0100 @@ -852,9 +852,8 @@ } else { - assert(sd->llvmInitZ); 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)); } diff -r 5ce8ab11e75a -r 9c79b61fb638 llvmdc.kdevelop --- a/llvmdc.kdevelop Mon Nov 26 07:26:21 2007 +0100 +++ b/llvmdc.kdevelop Tue Nov 27 03:09:36 2007 +0100 @@ -98,7 +98,7 @@ false - *.bc,*.ll + *.bc false diff -r 5ce8ab11e75a -r 9c79b61fb638 test/bug77.d --- a/test/bug77.d Mon Nov 26 07:26:21 2007 +0100 +++ b/test/bug77.d Tue Nov 27 03:09:36 2007 +0100 @@ -12,6 +12,8 @@ len = strlen(prefix); assert(len == 0); } + + func(); } func2(); } diff -r 5ce8ab11e75a -r 9c79b61fb638 test/unittest1.d --- a/test/unittest1.d Mon Nov 26 07:26:21 2007 +0100 +++ b/test/unittest1.d Tue Nov 27 03:09:36 2007 +0100 @@ -1,9 +1,10 @@ module unittest1; -unittest -{ -} - void main() { } + +unittest +{ + printf("hello\n"); +}