[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
This commit is contained in:
Tomas Lindquist Olsen
2007-11-07 04:52:56 +01:00
parent 4a5659c04e
commit ea18cd8e75
5 changed files with 77 additions and 3 deletions

View File

@@ -1747,7 +1747,7 @@ DValue* SliceExp::toElem(IRState* p)
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);

View File

@@ -660,10 +660,39 @@ void DtoMain()
// 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

View File

@@ -5,6 +5,7 @@ private import llvm.intrinsic;
extern(C):
int memcmp(void*,void*,size_t);
size_t strlen(char*);
version(LLVM64)
alias llvm_memcpy_i64 llvm_memcpy;
@@ -132,3 +133,21 @@ size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
}
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)];
}
}

17
test/bug54.d Normal file
View File

@@ -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()
{
}

9
test/mainargs1.d Normal file
View File

@@ -0,0 +1,9 @@
module mainargs1;
void main(string[] args)
{
foreach(v; args)
{
printf("%.*s\n", v.length, v.ptr);
}
}