diff --git a/dmd/func.c b/dmd/func.c index be2561a2..0aa5f540 100644 --- a/dmd/func.c +++ b/dmd/func.c @@ -787,8 +787,6 @@ void FuncDeclaration::semantic3(Scope *sc) parameters->push(v); localsymtab->insert(v); v->parent = this; - // for llvm d - arg->vardecl = v; } } diff --git a/dmd/mtype.c b/dmd/mtype.c index d7657e3f..fa927a84 100644 --- a/dmd/mtype.c +++ b/dmd/mtype.c @@ -5057,7 +5057,6 @@ Argument::Argument(unsigned storageClass, Type *type, Identifier *ident, Express this->ident = ident; this->storageClass = storageClass; this->defaultArg = defaultArg; - this->vardecl = 0; } Argument *Argument::syntaxCopy() diff --git a/dmd/mtype.h b/dmd/mtype.h index 2b39bdc5..886e2c99 100644 --- a/dmd/mtype.h +++ b/dmd/mtype.h @@ -674,9 +674,6 @@ struct Argument : Object static void argsToDecoBuffer(OutBuffer *buf, Arguments *arguments); static size_t dim(Arguments *arguments); static Argument *getNth(Arguments *arguments, size_t nth, size_t *pn = NULL); - - // backend - VarDeclaration* vardecl; }; extern int PTRSIZE; diff --git a/gen/arrays.cpp b/gen/arrays.cpp index f0541f4c..835d5eb1 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -604,6 +604,17 @@ void DtoCatArrayElement(llvm::Value* arr, Expression* exp1, Expression* exp2) Type* t1 = DtoDType(exp1->type); Type* t2 = DtoDType(exp2->type); + // handle reverse case + if (t2->next && t1 == DtoDType(t2->next)) + { + Type* tmp = t1; + t1 = t2; + t2 = tmp; + Expression* e = exp1; + exp1 = exp2; + exp2 = e; + } + assert(t1->ty == Tarray); assert(t2 == DtoDType(t1->next)); @@ -778,7 +789,7 @@ llvm::Value* DtoDynArrayIs(TOK op, llvm::Value* l, llvm::Value* r) if (r == NULL) { llvm::Value* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp"); - llvm::Value* rl = DtoConstSize_t(0); + llvm::Value* rl = llvm::Constant::getNullValue(ll->getType());//DtoConstSize_t(0); llvm::Value* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); llvm::Value* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp"); diff --git a/gen/functions.cpp b/gen/functions.cpp index 6112949c..c705cba3 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -28,8 +28,13 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const llvm::Type* thistype } bool typesafeVararg = false; - if (f->linkage == LINKd && f->varargs == 1) { - typesafeVararg = true; + bool arrayVararg = false; + if (f->linkage == LINKd) + { + if (f->varargs == 1) + typesafeVararg = true; + else if (f->varargs == 2) + arrayVararg = true; } // return value type @@ -82,6 +87,10 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const llvm::Type* thistype paramvec.push_back(getPtrToType(t1)); paramvec.push_back(getPtrToType(llvm::Type::Int8Ty)); } + else if (arrayVararg) + { + // do nothing? + } size_t n = Argument::dim(f->parameters); @@ -120,7 +129,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const llvm::Type* thistype } // construct function type - bool isvararg = !typesafeVararg && f->varargs; + bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); f->llvmRetInPtr = retinptr; @@ -383,51 +392,49 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) gIR->dtors.push_back(fdecl); } - // name parameters - llvm::Function::arg_iterator iarg = func->arg_begin(); - int k = 0; - if (f->llvmRetInPtr) { - iarg->setName("retval"); - gIR->irDsymbol[fdecl].irFunc->retArg = iarg; - ++iarg; - } - if (f->llvmUsesThis) { - iarg->setName("this"); - gIR->irDsymbol[fdecl].irFunc->thisVar = iarg; - assert(gIR->irDsymbol[fdecl].irFunc->thisVar); - ++iarg; - } - - if (f->linkage == LINKd && f->varargs == 1) { - iarg->setName("_arguments"); - gIR->irDsymbol[fdecl].irFunc->_arguments = iarg; - ++iarg; - iarg->setName("_argptr"); - gIR->irDsymbol[fdecl].irFunc->_argptr = iarg; - ++iarg; - } - - for (; iarg != func->arg_end(); ++iarg) + // we never reference parameters of function prototypes + if (!declareOnly) { - Argument* arg = Argument::getNth(f->parameters, k++); - //arg->llvmValue = iarg; - //Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident); - if (arg && arg->ident != 0) { - if (arg->vardecl) { - if (gIR->irDsymbol[arg->vardecl].irLocal) - { - Logger::cout() << "WTF!?!: " << *gIR->irDsymbol[arg->vardecl].irLocal->value << '\n'; - } - assert(!gIR->irDsymbol[arg->vardecl].irLocal); - assert(!gIR->irDsymbol[arg->vardecl].irGlobal); - assert(!gIR->irDsymbol[arg->vardecl].irField); - gIR->irDsymbol[arg->vardecl].irLocal = new IrLocal(arg->vardecl); - gIR->irDsymbol[arg->vardecl].irLocal->value = iarg; - } - iarg->setName(arg->ident->toChars()); + // name parameters + llvm::Function::arg_iterator iarg = func->arg_begin(); + int k = 0; + if (f->llvmRetInPtr) { + iarg->setName("retval"); + gIR->irDsymbol[fdecl].irFunc->retArg = iarg; + ++iarg; } - else { - iarg->setName("unnamed"); + if (f->llvmUsesThis) { + iarg->setName("this"); + gIR->irDsymbol[fdecl].irFunc->thisVar = iarg; + assert(gIR->irDsymbol[fdecl].irFunc->thisVar); + ++iarg; + } + + if (f->linkage == LINKd && f->varargs == 1) { + iarg->setName("_arguments"); + gIR->irDsymbol[fdecl].irFunc->_arguments = iarg; + ++iarg; + iarg->setName("_argptr"); + gIR->irDsymbol[fdecl].irFunc->_argptr = iarg; + ++iarg; + } + + for (; iarg != func->arg_end(); ++iarg) + { + if (fdecl->parameters && fdecl->parameters->dim > k) + { + Dsymbol* argsym = (Dsymbol*)fdecl->parameters->data[k++]; + VarDeclaration* argvd = argsym->isVarDeclaration(); + assert(argvd); + assert(!gIR->irDsymbol[argvd].irLocal); + gIR->irDsymbol[argvd].irLocal = new IrLocal(argvd); + gIR->irDsymbol[argvd].irLocal->value = iarg; + iarg->setName(argvd->ident->toChars()); + } + else + { + iarg->setName("unnamed"); + } } } @@ -500,25 +507,28 @@ void DtoDefineFunc(FuncDeclaration* fd) } // give arguments storage - size_t n = Argument::dim(f->parameters); - for (int i=0; i < n; ++i) { - Argument* arg = Argument::getNth(f->parameters, i); - if (arg && arg->vardecl) { - VarDeclaration* vd = arg->vardecl; + if (fd->parameters) + { + size_t n = fd->parameters->dim; + for (int i=0; i < n; ++i) + { + Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i]; + VarDeclaration* vd = argsym->isVarDeclaration(); + assert(vd); + if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)) continue; + llvm::Value* a = gIR->irDsymbol[vd].irLocal->value; assert(a); std::string s(a->getName()); Logger::println("giving argument '%s' storage", s.c_str()); s.append("_storage"); + llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint); gIR->ir->CreateStore(a,v); gIR->irDsymbol[vd].irLocal->value = v; } - else { - Logger::attention(fd->loc, "some unknown argument: %s", arg ? arg->toChars() : 0); - } } // debug info diff --git a/gen/toir.cpp b/gen/toir.cpp index ff5d70e0..10de5fa6 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -253,6 +253,7 @@ DValue* VarExp::toElem(IRState* p) assert(sdecltype->ty == Tstruct); TypeStruct* ts = (TypeStruct*)sdecltype; assert(ts->sym); + DtoForceConstInitDsymbol(ts->sym); assert(gIR->irDsymbol[ts->sym].irStruct->init); return new DVarValue(type, gIR->irDsymbol[ts->sym].irStruct->init, true); } @@ -2291,6 +2292,15 @@ DValue* IdentityExp::toElem(IRState* p) } eval = DtoDynArrayIs(op,l,r); } + else if (t1->ty == Tdelegate) { + if (v->isNull()) { + r = NULL; + } + else { + assert(l->getType() == r->getType()); + } + eval = DtoDynArrayIs(op,l,r); + } else if (t1->isfloating()) { llvm::FCmpInst::Predicate pred = (op == TOKidentity) ? llvm::FCmpInst::FCMP_OEQ : llvm::FCmpInst::FCMP_ONE; diff --git a/llvmdc.kdevelop.filelist b/llvmdc.kdevelop.filelist index f550c48e..2c545b01 100644 --- a/llvmdc.kdevelop.filelist +++ b/llvmdc.kdevelop.filelist @@ -753,6 +753,7 @@ tangotests/constructors.d tangotests/d.d tangotests/e.d tangotests/f.d +tangotests/files1.d tangotests/g.d tangotests/h.d tangotests/i.d @@ -768,6 +769,7 @@ tangotests/r.d tangotests/s.d tangotests/stdout1.d tangotests/t.d +tangotests/vararg1.d test test/a.d test/aa1.d diff --git a/tangotests/files1.d b/tangotests/files1.d new file mode 100644 index 00000000..3bc88df0 --- /dev/null +++ b/tangotests/files1.d @@ -0,0 +1,12 @@ +module tangotests.files1; + +//import tango.io.Stdout; +import tango.io.File; + +void main() +{ + auto file = new File("files1.output"); + char[] str = "hello world from files1 test\n"; + void[] data = cast(void[])str; + file.write(str); +}