Mercurial > projects > ldc
diff gen/functions.cpp @ 121:9c79b61fb638 trunk
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
Unit tests are now implemented.
author | lindquist |
---|---|
date | Tue, 27 Nov 2007 03:09:36 +0100 |
parents | 79c9ac745fbc |
children | 7f9a0a58394b |
line wrap: on
line diff
--- 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<const llvm::Type*> 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<const llvm::Type*> args; + return llvm::FunctionType::get(llvm::Type::VoidTy, args, false); + }*/ + // type has already been resolved if (fdecl->type->llvmType != 0) { return llvm::cast<llvm::FunctionType>(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<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; 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;