Mercurial > projects > ldc
changeset 21:8d45266bbabe trunk
[svn r25] * Fixed a lot of problems with string literals
* Fixed slice-slice copying assignment
author | lindquist |
---|---|
date | Thu, 04 Oct 2007 07:01:15 +0200 |
parents | 42bf2eb2973b |
children | a6360e68134a |
files | gen/arrays.c gen/arrays.h gen/toir.c gen/tollvm.c gen/toobj.c lphobos/std/stdio.d test/globals1.d test/strings1.d test/tuple1.d |
diffstat | 9 files changed, 163 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/gen/arrays.c Thu Oct 04 04:28:30 2007 +0200 +++ b/gen/arrays.c Thu Oct 04 07:01:15 2007 +0200 @@ -303,7 +303,73 @@ } ////////////////////////////////////////////////////////////////////////////////////////// +static llvm::Value* get_slice_ptr(elem* e, llvm::Value*& sz) +{ + assert(e->mem); + const llvm::Type* t = e->mem->getType()->getContainedType(0); + llvm::Value* ret = 0; + if (llvm::isa<llvm::ArrayType>(t)) { + ret = LLVM_DtoGEPi(e->mem, 0, 0, "tmp", gIR->scopebb()); + + size_t elembsz = gTargetData->getTypeSize(ret->getType()->getContainedType(0)); + llvm::ConstantInt* elemsz = llvm::ConstantInt::get(LLVM_DtoSize_t(), elembsz, false); + + size_t numelements = llvm::cast<llvm::ArrayType>(t)->getNumElements(); + llvm::ConstantInt* nelems = llvm::ConstantInt::get(LLVM_DtoSize_t(), numelements, false); + + sz = llvm::ConstantExpr::getMul(elemsz, nelems); + } + else if (llvm::isa<llvm::StructType>(t)) { + ret = LLVM_DtoGEPi(e->mem, 0, 1, "tmp", gIR->scopebb()); + ret = new llvm::LoadInst(ret, "tmp", gIR->scopebb()); + + size_t elembsz = gTargetData->getTypeSize(ret->getType()->getContainedType(0)); + llvm::ConstantInt* elemsz = llvm::ConstantInt::get(LLVM_DtoSize_t(), elembsz, false); + + llvm::Value* len = LLVM_DtoGEPi(e->mem, 0, 0, "tmp", gIR->scopebb()); + len = new llvm::LoadInst(len, "tmp", gIR->scopebb()); + sz = llvm::BinaryOperator::createMul(len,elemsz,"tmp",gIR->scopebb()); + } + else { + assert(0); + } + return ret; +} + void LLVM_DtoArrayCopy(elem* dst, elem* src) { - assert(0); + Logger::cout() << "Array copy ((((" << *src->mem << ")))) into ((((" << *dst->mem << "))))\n"; + + assert(dst->type == elem::SLICE); + assert(src->type == elem::SLICE); + + llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); + + llvm::Value* sz1; + llvm::Value* sz2; + llvm::Value* dstarr = new llvm::BitCastInst(get_slice_ptr(dst,sz1),arrty,"tmp",gIR->scopebb()); + llvm::Value* srcarr = new llvm::BitCastInst(get_slice_ptr(src,sz2),arrty,"tmp",gIR->scopebb()); + + llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); + std::vector<llvm::Value*> llargs; + llargs.resize(4); + llargs[0] = dstarr; + llargs[1] = srcarr; + llargs[2] = sz1; + llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); + + new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); } + +////////////////////////////////////////////////////////////////////////////////////////// +llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr) +{ + std::vector<const llvm::Type*> types; + types.push_back(dim->getType()); + types.push_back(ptr->getType()); + const llvm::StructType* type = llvm::StructType::get(types); + std::vector<llvm::Constant*> values; + values.push_back(dim); + values.push_back(ptr); + return llvm::ConstantStruct::get(type,values); +}
--- a/gen/arrays.h Thu Oct 04 04:28:30 2007 +0200 +++ b/gen/arrays.h Thu Oct 04 07:01:15 2007 +0200 @@ -17,4 +17,6 @@ void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r); +llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr); + #endif // LLVMC_GEN_ARRAYS_H
--- a/gen/toir.c Thu Oct 04 04:28:30 2007 +0200 +++ b/gen/toir.c Thu Oct 04 07:01:15 2007 +0200 @@ -239,7 +239,7 @@ elem* StringExp::toElem(IRState* p) { - Logger::print("StringExp::toElem: %s\n", toChars()); + Logger::print("StringExp::toElem: %s | \n", toChars(), type->toChars()); LOG_SCOPE; assert(type->next->ty == Tchar && "Only char is supported"); @@ -257,8 +257,10 @@ llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,"stringliteral",gIR->module); - llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); - llvm::Value* arrptr = LLVM_DtoGEP(gvar,zero,zero,"tmp",p->scopebb()); + llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); + //llvm::Value* arrptr = LLVM_DtoGEP(gvar,zero,zero,"tmp",p->scopebb()); + llvm::Constant* idxs[2] = { zero, zero }; + llvm::Constant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); elem* e = new elem; @@ -272,9 +274,19 @@ } else { llvm::Value* arr = p->toplval(); - LLVM_DtoSetArray(arr, clen, arrptr); + if (llvm::isa<llvm::GlobalVariable>(arr)) { + e->val = LLVM_DtoConstantSlice(clen, arrptr); + } + else { + LLVM_DtoSetArray(arr, clen, arrptr); + e->inplace = true; + } } } + else if (type->ty == Tsarray) { + const llvm::Type* dstType = llvm::PointerType::get(llvm::ArrayType::get(ct, len)); + e->mem = new llvm::BitCastInst(gvar, dstType, "tmp", gIR->scopebb()); + } else if (type->ty == Tpointer) { e->mem = arrptr; } @@ -282,7 +294,6 @@ assert(0); } - e->inplace = true; e->type = elem::VAL; return e; @@ -934,10 +945,13 @@ } } else if (!fnarg || fnarg->llvmCopy) { - llargs[j] = arg->getValue(); + Logger::println("regular arg"); + assert(arg->type != elem::SLICE); + llargs[j] = arg->arg ? arg->arg : arg->getValue(); assert(llargs[j] != 0); } else { + Logger::println("as ptr arg"); llargs[j] = arg->mem ? arg->mem : arg->val; assert(llargs[j] != 0); } @@ -956,7 +970,7 @@ Logger::cout() << *llargs[i] << '\n'; } - //Logger::cout() << "Calling: " << *funcval->getType() << '\n'; + Logger::cout() << "Calling: " << *funcval->getType() << '\n'; // call the function llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); @@ -1155,6 +1169,7 @@ llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); //llvm::Value* idx1 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); e->mem = LLVM_DtoGEP(vd->llvmValue,idx0,idx0,"tmp",p->scopebb()); + e->arg = vd->llvmValue; e->type = elem::VAL; } else if (offset == 0) {
--- a/gen/tollvm.c Thu Oct 04 04:28:30 2007 +0200 +++ b/gen/tollvm.c Thu Oct 04 07:01:15 2007 +0200 @@ -803,9 +803,10 @@ llvm::Constant* LLVM_DtoInitializer(Type* type, Initializer* init) { - llvm::Constant* _init = 0; + llvm::Constant* _init = 0; // may return zero if (!init) { + Logger::println("default initializer"); elem* e = type->defaultInit()->toElem(gIR); if (!e->inplace && !e->isNull()) { _init = llvm::cast<llvm::Constant>(e->getValue()); @@ -814,6 +815,7 @@ } else if (ExpInitializer* ex = init->isExpInitializer()) { + Logger::println("expression initializer"); elem* e = ex->exp->toElem(gIR); if (!e->inplace && !e->isNull()) { _init = llvm::cast<llvm::Constant>(e->getValue()); @@ -822,14 +824,17 @@ } else if (StructInitializer* si = init->isStructInitializer()) { + Logger::println("struct initializer"); _init = LLVM_DtoStructInitializer(si); } else if (ArrayInitializer* ai = init->isArrayInitializer()) { + Logger::println("array initializer"); _init = LLVM_DtoArrayInitializer(ai); } else if (init->isVoidInitializer()) { + Logger::println("void initializer"); const llvm::Type* ty = LLVM_DtoType(type); _init = llvm::Constant::getNullValue(ty); }
--- a/gen/toobj.c Thu Oct 04 04:28:30 2007 +0200 +++ b/gen/toobj.c Thu Oct 04 07:01:15 2007 +0200 @@ -504,14 +504,20 @@ _isconst = (storage_class & STCconst) ? true : false; // doesn't seem to work ): llvm::GlobalValue::LinkageTypes _linkage = LLVM_DtoLinkage(protection, storage_class); const llvm::Type* _type = LLVM_DtoType(type); + assert(_type); llvm::Constant* _init = 0; bool _signed = !type->isunsigned(); - _init = LLVM_DtoInitializer(type, init); + Logger::println("Creating global variable"); + std::string _name(mangle()); + llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M); + llvmValue = gvar; + gIR->lvals.push_back(gvar); - assert(_type); + _init = LLVM_DtoInitializer(type, init); assert(_init); + //Logger::cout() << "initializer: " << *_init << '\n'; if (_type != _init->getType()) { Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; @@ -537,14 +543,15 @@ initvals.resize(at->getNumElements(), _init); _init = llvm::ConstantArray::get(at, initvals); } - else - assert(0); + else { + Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; + //assert(0); + } } - Logger::println("Creating global variable"); - std::string _name(mangle()); - llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,_init,_name,M); - llvmValue = gvar; + gIR->lvals.pop_back(); + + gvar->setInitializer(_init); //if (storage_class & STCprivate) // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility);
--- a/lphobos/std/stdio.d Thu Oct 04 04:28:30 2007 +0200 +++ b/lphobos/std/stdio.d Thu Oct 04 07:01:15 2007 +0200 @@ -1,8 +1,15 @@ module std.stdio; void _writef(T)(T t) { - //static if(is(T: Object)) _writef(t.toString()); else + static if(is(T: Object)) _writef(t.toString()); else + static if(is(T==char)) _writef("%c", t); else static if(is(T: char[])) printf("%.*s", t.length, t.ptr); else + static if(isArray!(T)) { + _writef('['); + if (t.length) _writef(t[0]); + for (int i=1; i<elem.length; ++i) { _writef(','); _writef(t[i]); } + _writef(']'); + } else static if(is(T==int)) printf("%i", t); else static assert(false, "Cannot print "~T.stringof); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/globals1.d Thu Oct 04 07:01:15 2007 +0200 @@ -0,0 +1,10 @@ +module globals1; + +char[] gstr = "hello world"; + +void main() +{ + printf("%.*s\n", gstr.length, gstr.ptr); + char[] str = gstr; + printf("%.*s\n", str.length, str.ptr); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/strings1.d Thu Oct 04 07:01:15 2007 +0200 @@ -0,0 +1,15 @@ +module strings1; + +void f(char[11] buffer) +{ + printf("%.*s\n", buffer.length, buffer.ptr); +} + +void main() +{ + char[11] buffer; + char[] hello = "hello world"; + {buffer[] = hello[];} + {f(buffer);} + {f("eleven char");} +}