# HG changeset patch # User lindquist # Date 1194407576 -3600 # Node ID 3f949c6e2e9d4fd574d298748798a19fc1b715a2 # Parent 16e88334bba7040512fbbd882e0b4d4eb6648308 [svn r95] added support for mains like: T main(string[] args) fixed a bug with slicing a pointer that is an argument with no storage diff -r 16e88334bba7 -r 3f949c6e2e9d gen/toir.cpp --- a/gen/toir.cpp Wed Nov 07 03:36:07 2007 +0100 +++ b/gen/toir.cpp Wed Nov 07 04:52:56 2007 +0100 @@ -1747,7 +1747,7 @@ Type* e1type = DtoDType(e1->type); DValue* v = e1->toElem(p); - llvm::Value* vmem = v->getLVal(); + llvm::Value* vmem = v->isIm() ? v->getRVal() : v->getLVal(); assert(vmem); llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); diff -r 16e88334bba7 -r 3f949c6e2e9d gen/tollvm.cpp --- a/gen/tollvm.cpp Wed Nov 07 03:36:07 2007 +0100 +++ b/gen/tollvm.cpp Wed Nov 07 04:52:56 2007 +0100 @@ -660,10 +660,39 @@ // call static ctors llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_ctors"); - new llvm::CallInst(fn,"",bb); + llvm::Instruction* apt = new llvm::CallInst(fn,"",bb); // call user main function - llvm::CallInst* call = new llvm::CallInst(ir.mainFunc,"ret",bb); + const llvm::FunctionType* mainty = ir.mainFunc->getFunctionType(); + llvm::CallInst* call; + if (mainty->getNumParams() > 0) + { + // main with arguments + assert(mainty->getNumParams() == 1); + std::vector args; + llvm::Function* mfn = LLVM_D_GetRuntimeFunction(ir.module,"_d_main_args"); + + llvm::Function::arg_iterator argi = func->arg_begin(); + args.push_back(argi++); + args.push_back(argi++); + + const llvm::Type* at = mainty->getParamType(0)->getContainedType(0); + llvm::Value* arr = new llvm::AllocaInst(at->getContainedType(1)->getContainedType(0), func->arg_begin(), "argstorage", apt); + llvm::Value* a = new llvm::AllocaInst(at, "argarray", apt); + llvm::Value* ptr = DtoGEPi(a,0,0,"tmp",bb); + llvm::Value* v = new llvm::ZExtInst(args[0], DtoSize_t(), "tmp", bb); + new llvm::StoreInst(v,ptr,bb); + ptr = DtoGEPi(a,0,1,"tmp",bb); + new llvm::StoreInst(arr,ptr,bb); + args.push_back(a); + new llvm::CallInst(mfn, args.begin(), args.end(), "", bb); + call = new llvm::CallInst(ir.mainFunc,a,"ret",bb); + } + else + { + // main with no arguments + call = new llvm::CallInst(ir.mainFunc,"ret",bb); + } call->setCallingConv(ir.mainFunc->getCallingConv()); // call static dtors diff -r 16e88334bba7 -r 3f949c6e2e9d lphobos/internal/arrays.d --- a/lphobos/internal/arrays.d Wed Nov 07 03:36:07 2007 +0100 +++ b/lphobos/internal/arrays.d Wed Nov 07 04:52:56 2007 +0100 @@ -5,6 +5,7 @@ extern(C): int memcmp(void*,void*,size_t); +size_t strlen(char*); version(LLVM64) alias llvm_memcpy_i64 llvm_memcpy; @@ -132,3 +133,21 @@ } return (len*elemsz)/newelemsz; } + +// creating args for main +void _d_main_args(uint n, char** args, ref char[][] res) +{ + assert(res.length == n); + foreach(i,v; args[0..n]) + { + res[i] = v[0 .. strlen(v)]; + } +} + + + + + + + + diff -r 16e88334bba7 -r 3f949c6e2e9d test/bug54.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug54.d Wed Nov 07 04:52:56 2007 +0100 @@ -0,0 +1,17 @@ +module bug54; + +extern(C) size_t strlen(char*); + +// creating args for main +void d_main_args(size_t n, char** args, ref char[][] res) +{ + assert(res.length == n); + foreach(i,v; args[0..n]) + { + res[i] = v[0 .. strlen(v)]; + } +} + +void main() +{ +} diff -r 16e88334bba7 -r 3f949c6e2e9d test/mainargs1.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/mainargs1.d Wed Nov 07 04:52:56 2007 +0100 @@ -0,0 +1,9 @@ +module mainargs1; + +void main(string[] args) +{ + foreach(v; args) + { + printf("%.*s\n", v.length, v.ptr); + } +}