changeset 91:3f949c6e2e9d trunk

[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
author lindquist
date Wed, 07 Nov 2007 04:52:56 +0100
parents 16e88334bba7
children 70d6113eeb8c
files gen/toir.cpp gen/tollvm.cpp lphobos/internal/arrays.d test/bug54.d test/mainargs1.d
diffstat 5 files changed, 77 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- 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);
--- 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<llvm::Value*> 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
--- 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)];
+    }
+}
+
+
+
+
+
+
+
+
--- /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()
+{
+}
--- /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);
+    }
+}