mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-14 20:03:14 +01:00
[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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
17
test/bug54.d
Normal 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
9
test/mainargs1.d
Normal file
@@ -0,0 +1,9 @@
|
||||
module mainargs1;
|
||||
|
||||
void main(string[] args)
|
||||
{
|
||||
foreach(v; args)
|
||||
{
|
||||
printf("%.*s\n", v.length, v.ptr);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user