mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
[svn r25] * Fixed a lot of problems with string literals
* Fixed slice-slice copying assignment
This commit is contained in:
68
gen/arrays.c
68
gen/arrays.c
@@ -303,7 +303,73 @@ llvm::Constant* LLVM_DtoArrayInitializer(ArrayInitializer* arrinit)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -17,4 +17,6 @@ void LLVM_DtoArrayCopy(elem* dst, elem* src);
|
||||
|
||||
void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r);
|
||||
|
||||
llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr);
|
||||
|
||||
#endif // LLVMC_GEN_ARRAYS_H
|
||||
|
||||
29
gen/toir.c
29
gen/toir.c
@@ -239,7 +239,7 @@ elem* NullExp::toElem(IRState* p)
|
||||
|
||||
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 @@ elem* StringExp::toElem(IRState* p)
|
||||
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 @@ elem* StringExp::toElem(IRState* p)
|
||||
}
|
||||
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 @@ elem* StringExp::toElem(IRState* p)
|
||||
assert(0);
|
||||
}
|
||||
|
||||
e->inplace = true;
|
||||
e->type = elem::VAL;
|
||||
|
||||
return e;
|
||||
@@ -934,10 +945,13 @@ elem* CallExp::toElem(IRState* p)
|
||||
}
|
||||
}
|
||||
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 @@ elem* CallExp::toElem(IRState* p)
|
||||
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 @@ elem* SymOffExp::toElem(IRState* p)
|
||||
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) {
|
||||
|
||||
@@ -803,9 +803,10 @@ void LLVM_DtoInitClass(TypeClass* tc, llvm::Value* dst)
|
||||
|
||||
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 @@ llvm::Constant* LLVM_DtoInitializer(Type* type, Initializer* init)
|
||||
}
|
||||
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 @@ llvm::Constant* LLVM_DtoInitializer(Type* type, Initializer* init)
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
23
gen/toobj.c
23
gen/toobj.c
@@ -504,14 +504,20 @@ void VarDeclaration::toObjFile()
|
||||
_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 @@ void VarDeclaration::toObjFile()
|
||||
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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
10
test/globals1.d
Normal file
10
test/globals1.d
Normal file
@@ -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);
|
||||
}
|
||||
15
test/strings1.d
Normal file
15
test/strings1.d
Normal file
@@ -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");}
|
||||
}
|
||||
18
test/tuple1.d
Normal file
18
test/tuple1.d
Normal file
@@ -0,0 +1,18 @@
|
||||
module tuple1;
|
||||
|
||||
template Tuple(T...) {
|
||||
alias T Tuple;
|
||||
}
|
||||
|
||||
struct S
|
||||
{
|
||||
int i;
|
||||
long l;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
S s = S(Tuple!(1,2L));
|
||||
assert(s.i == 1);
|
||||
assert(s.l == 2);
|
||||
}
|
||||
Reference in New Issue
Block a user