Mercurial > projects > ldc
changeset 94:61615fa85940 trunk
[svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca").
Added support for array .sort and .reverse properties.
Fixed some bugs with pointer arithmetic.
Disabled some DMD AST optimizations that was messing things up, destroying valuable information.
Added a KDevelop project file, this is what I use for coding LLVMDC now :)
Other minor stuff.
author | lindquist |
---|---|
date | Mon, 12 Nov 2007 06:32:46 +0100 |
parents | 08508eebbb3e |
children | 71b8fecdae38 |
files | demos/ray.d dmd/attrib.c dmd/cast.c dmd/module.c dmd/module.h dmd/mtype.c dmd/optimize.c gen/arrays.cpp gen/enums.h gen/irstate.cpp gen/irstate.h gen/logger.cpp gen/logger.h gen/statements.cpp gen/todebug.cpp gen/todebug.h gen/toir.cpp gen/tollvm.cpp gen/tollvm.h gen/toobj.cpp llvmdc.kdevelop llvmdc.kdevelop.filelist lphobos/build.sh lphobos/gc/gclinux.d lphobos/gc/gcstub.d lphobos/internal/adi.d lphobos/internal/arrays.d lphobos/internal/contract.d lphobos/internal/qsort2.d lphobos/std/c/stdlib.d lphobos/std/stdio.d lphobos/std/traits.d test/alloca1.d test/arrays5.d test/bug57.d test/bug58.d test/bug59.d test/bug60.d test/bug61.d test/bug62.d test/bug64.d test/fail2.d test/multiarr1.d test/ray.d test/sync1.d test/union2.d |
diffstat | 46 files changed, 2817 insertions(+), 254 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/ray.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,96 @@ +//import std.stdio, std.math, std.string; +//import tools.base; + +double delta; +static this() { delta=sqrt(real.epsilon); } + +struct Vec { + double x, y, z; + Vec opAdd(ref Vec other) { return Vec(x+other.x, y+other.y, z+other.z); } + Vec opSub(ref Vec other) { return Vec(x-other.x, y-other.y, z-other.z); } + Vec opMul(double a) { return Vec(x*a, y*a, z*a); } + double dot(ref Vec other) { return x*other.x+y*other.y+z*other.z; } + Vec unitise() { return opMul(1.0/sqrt(dot(*this))); } +} + +struct Pair(T, U) { T first; U second; } +typedef Pair!(double, Vec) Hit; + +struct Ray { Vec orig, dir; } + +class Scene { + abstract void intersect(ref Hit, ref Ray); +} + +class Sphere : Scene { + Vec center; + double radius; + this(ref Vec c, double r) + { + center = c; + radius = r; + } + double ray_sphere(ref Ray ray) { + auto v = center - ray.orig, b = v.dot(ray.dir), disc=b*b - v.dot(v) + radius*radius; + if (disc < 0) return double.infinity; + auto d = sqrt(disc), t2 = b + d; + if (t2 < 0) return double.infinity; + auto t1 = b - d; + return (t1 > 0 ? t1 : t2); + } + void intersect(ref Hit hit, ref Ray ray) { + auto lambda = ray_sphere(ray); + if (lambda < hit.first) + hit = Hit(lambda, (ray.orig + lambda*ray.dir - center).unitise); + } +} + +class Group : Scene { + Sphere bound; + Scene[] children; + mixin This!("bound, children"); + void intersect(ref Hit hit, ref Ray ray) { + auto l = bound.ray_sphere(ray); + if (l < hit.first) foreach (child; children) child.intersect(hit, ray); + } +} + +double ray_trace(ref Vec light, ref Ray ray, Scene s) { + auto hit=Hit(double.infinity, Vec(0, 0, 0)); + s.intersect(hit, ray); + if (hit.first == double.infinity) return 0.0; + auto g = hit.second.dot(light); + if (g >= 0) return 0.0; + auto p = ray.orig + ray.dir*hit.first + hit.second*delta; + auto hit2=Hit(double.infinity, Vec(0, 0, 0)); + s.intersect(hit2, Ray(p, light*-1.0)); + return (hit2.first < double.infinity ? 0 : -g); +} + +Scene create(int level, ref Vec c, double r) { + auto s = new Sphere(c, r); + if (level == 1) return s; + Scene[] children=[s]; + double rn = 3*r/sqrt(12.0); + for (int dz=-1; dz<=1; dz+=2) + for (int dx=-1; dx<=1; dx+=2) + children~=create(level-1, c + Vec(dx, 1, dz)*rn, r/2); + return new Group(new Sphere(c, 3*r), children); +} + +void main(string[] args) { + int level = (args.length==3 ? args[1].atoi() : 9), + n = (args.length==3 ? args[2].atoi() : 512), ss = 4; + auto light = Vec(-1, -3, 2).unitise(); + auto s=create(level, Vec(0, -1, 0), 1); + writefln("P5\n", n, " ", n, "\n255"); + for (int y=n-1; y>=0; --y) + for (int x=0; x<n; ++x) { + double g=0; + for (int d=0; d<ss*ss; ++d) { + auto dir=Vec(x+(d%ss)*1.0/ss-n/2.0, y+(d/ss)*1.0/ss-n/2.0, n).unitise(); + g += ray_trace(light, Ray(Vec(0, 0, -4), dir), s); + } + printf("%c", cast(ubyte)(0.5 + 255.0 * g / (ss*ss))); + } +}
--- a/dmd/attrib.c Thu Nov 08 19:21:05 2007 +0100 +++ b/dmd/attrib.c Mon Nov 12 06:32:46 2007 +0100 @@ -879,6 +879,10 @@ llvm_internal = LLVMnotypeinfo; assert(args->dim == 1); } + else if (strcmp(str,"alloca")==0) { + llvm_internal = LLVMalloca; + assert(args->dim == 1); + } else { error("unknown pragma command: %s", str); } @@ -904,6 +908,7 @@ case LLVMva_arg: case LLVMva_start: case LLVMnotypeinfo: + case LLVMalloca: break; default: @@ -960,6 +965,16 @@ s->llvmInternal = llvm_internal; break; + case LLVMalloca: + if (FuncDeclaration* fd = s->isFuncDeclaration()) { + fd->llvmInternal = llvm_internal; + } + else { + error("may only be used on function declarations"); + assert(0); + } + break; + default: assert(0 && "invalid LLVM_internal pragma got through :/"); }
--- a/dmd/cast.c Thu Nov 08 19:21:05 2007 +0100 +++ b/dmd/cast.c Mon Nov 12 06:32:46 2007 +0100 @@ -1116,7 +1116,7 @@ e2->type = t; type = e1->type; } - else if (t2b->ty && t1b->isintegral()) + else if (t2b->ty == Tpointer && t1b->isintegral()) { // Need to adjust operator by the stride // Replace (int + ptr) with (ptr + (int * stride)) Type *t = Type::tptrdiff_t; @@ -1127,11 +1127,13 @@ e = e1->castTo(sc, t); else e = e1; + #if !IN_LLVM if (t2b->next->isbit()) // BUG: should add runtime check for misaligned offsets e = new UshrExp(loc, e, new IntegerExp(0, 3, t)); else e = new MulExp(loc, e, new IntegerExp(0, stride, t)); + #endif e->type = t; type = e2->type; e1 = e2;
--- a/dmd/module.c Thu Nov 08 19:21:05 2007 +0100 +++ b/dmd/module.c Mon Nov 12 06:32:46 2007 +0100 @@ -159,6 +159,9 @@ bcfile = new File(bcfilename); llfile = new File(llfilename); symfile = new File(symfilename); + + // LLVMDC + llvmCompileUnit = 0; } void Module::setDocfile()
--- a/dmd/module.h Thu Nov 08 19:21:05 2007 +0100 +++ b/dmd/module.h Mon Nov 12 06:32:46 2007 +0100 @@ -29,6 +29,7 @@ #if IN_LLVM struct DValue; typedef DValue elem; +namespace llvm { class GlobalVariable; } #else #ifdef IN_GCC union tree_node; typedef union tree_node elem; @@ -166,6 +167,9 @@ Symbol *toSymbol(); void genmoduleinfo(); + // LLVMDC + llvm::GlobalVariable* llvmCompileUnit; + Module *isModule() { return this; } };
--- a/dmd/mtype.c Thu Nov 08 19:21:05 2007 +0100 +++ b/dmd/mtype.c Mon Nov 12 06:32:46 2007 +0100 @@ -1514,6 +1514,7 @@ nm = name[n->ty == Twchar]; fd = FuncDeclaration::genCfunc(Type::tindex, nm); + fd->llvmRunTimeHack = true; ec = new VarExp(0, fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); @@ -1531,6 +1532,7 @@ nm = name[n->ty == Twchar]; fd = FuncDeclaration::genCfunc(Type::tindex, nm); + fd->llvmRunTimeHack = true; ec = new VarExp(0, fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); @@ -1568,6 +1570,7 @@ fd = FuncDeclaration::genCfunc(tint32->arrayOf(), (char*)(n->ty == Tbit ? "_adSortBit" : "_adSort")); + fd->llvmRunTimeHack = true; ec = new VarExp(0, fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions();
--- a/dmd/optimize.c Thu Nov 08 19:21:05 2007 +0100 +++ b/dmd/optimize.c Mon Nov 12 06:32:46 2007 +0100 @@ -209,6 +209,7 @@ } return e; } +#if !IN_LLVM if (e1->op == TOKvar) { VarExp *ve = (VarExp *)e1; if (!ve->var->isOut() && !ve->var->isRef() && @@ -240,6 +241,7 @@ } } } +#endif return this; }
--- a/gen/arrays.cpp Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/arrays.cpp Mon Nov 12 06:32:46 2007 +0100 @@ -21,14 +21,6 @@ const llvm::Type* at = DtoType(t->next); const llvm::Type* arrty; - /*if (t->ty == Tsarray) { - TypeSArray* tsa = (TypeSArray*)t; - assert(tsa->dim->type->isintegral()); - arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger()); - } - else { - arrty = llvm::ArrayType::get(at,0); - }*/ if (at == llvm::Type::VoidTy) { at = llvm::Type::Int8Ty; } @@ -648,12 +640,17 @@ ////////////////////////////////////////////////////////////////////////////////////////// llvm::Value* DtoArrayCastLength(llvm::Value* len, const llvm::Type* elemty, const llvm::Type* newelemty) { - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len"); - assert(fn); + size_t esz = gTargetData->getTypeSize(elemty); + size_t nsz = gTargetData->getTypeSize(newelemty); + if (esz == nsz) + return len; + std::vector<llvm::Value*> args; args.push_back(len); - args.push_back(llvm::ConstantInt::get(DtoSize_t(), gTargetData->getTypeSize(elemty), false)); - args.push_back(llvm::ConstantInt::get(DtoSize_t(), gTargetData->getTypeSize(newelemty), false)); + args.push_back(llvm::ConstantInt::get(DtoSize_t(), esz, false)); + args.push_back(llvm::ConstantInt::get(DtoSize_t(), nsz, false)); + + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len"); return new llvm::CallInst(fn, args.begin(), args.end(), "tmp", gIR->scopebb()); } @@ -722,7 +719,9 @@ return DtoLoad(DtoGEPi(v->getRVal(), 0,0, "tmp")); } else if (t->ty == Tsarray) { - const llvm::ArrayType* t = llvm::cast<llvm::ArrayType>(v->getLVal()->getType()); + llvm::Value* rv = v->getRVal(); + Logger::cout() << "casting: " << *rv << '\n'; + const llvm::ArrayType* t = llvm::cast<llvm::ArrayType>(rv->getType()->getContainedType(0)); return DtoConstSize_t(t->getNumElements()); } assert(0);
--- a/gen/enums.h Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/enums.h Mon Nov 12 06:32:46 2007 +0100 @@ -5,5 +5,6 @@ LLVMva_arg, LLVMva_start, LLVMva_intrinsic, - LLVMnotypeinfo + LLVMnotypeinfo, + LLVMalloca };
--- a/gen/irstate.cpp Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/irstate.cpp Mon Nov 12 06:32:46 2007 +0100 @@ -38,7 +38,6 @@ emitMain = false; mainFunc = 0; ir.state = this; - dwarfCompileUnit = 0; } IRFunction& IRState::func()
--- a/gen/irstate.h Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/irstate.h Mon Nov 12 06:32:46 2007 +0100 @@ -162,9 +162,6 @@ // builder helper IRBuilderHelper ir; - - // Dwarf debugging info - llvm::GlobalVariable* dwarfCompileUnit; }; #endif // LLVMDC_GEN_IRSTATE_H
--- a/gen/logger.cpp Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/logger.cpp Mon Nov 12 06:32:46 2007 +0100 @@ -62,5 +62,13 @@ { enabled = false; } + void attention(const char* fmt,...) + { + printf("***ATTENTION*** "); + va_list va; + va_start(va,fmt); + vprintf(fmt,va); + va_end(va); + printf("\n"); + } } -
--- a/gen/logger.h Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/logger.h Mon Nov 12 06:32:46 2007 +0100 @@ -12,14 +12,14 @@ void print(const char* fmt, ...); void enable(); void disable(); - + + void attention(const char* fmt, ...); struct LoggerScope { LoggerScope() { Logger::indent(); - } ~LoggerScope() {
--- a/gen/statements.cpp Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/statements.cpp Mon Nov 12 06:32:46 2007 +0100 @@ -7,7 +7,6 @@ #include <iostream> #include "gen/llvm.h" -#include "llvm/Transforms/Utils/Cloning.h" #include "total.h" #include "init.h" @@ -39,8 +38,7 @@ if (s) s->toIR(p); else { - Logger::println("*** ATTENTION: null statement found in CompoundStatement"); - //assert(0); + Logger::println("??? null statement found in CompoundStatement"); } } } @@ -133,8 +131,8 @@ Logger::println("ExpStatement::toIR(%d): %s", esi++, toChars()); LOG_SCOPE; - if (global.params.symdebug) - DtoDwarfStopPoint(loc.linnum); +// if (global.params.symdebug) +// DtoDwarfStopPoint(loc.linnum); if (exp != 0) { elem* e = exp->toElem(p); @@ -255,8 +253,10 @@ // rewrite scope gIR->scope() = IRScope(whilebodybb,endbb); - // do while body code + // while body code + p->loopbbs.push_back(IRScope(whilebb,endbb)); body->toIR(p); + p->loopbbs.pop_back(); // loop new llvm::BranchInst(whilebb, gIR->scopebegin()); @@ -284,7 +284,7 @@ // replace current scope gIR->scope() = IRScope(dowhilebb,endbb); - // do do-while body code + // do-while body code body->toIR(p); // create the condition @@ -363,8 +363,7 @@ void BreakStatement::toIR(IRState* p) { - static int wsi = 0; - Logger::println("BreakStatement::toIR(%d): %s", wsi++, toChars()); + Logger::println("BreakStatement::toIR(): %s", toChars()); LOG_SCOPE; if (ident != 0) { @@ -380,8 +379,7 @@ void ContinueStatement::toIR(IRState* p) { - static int wsi = 0; - Logger::println("ContinueStatement::toIR(%d): %s", wsi++, toChars()); + Logger::println("ContinueStatement::toIR(): %s", toChars()); LOG_SCOPE; if (ident != 0) { @@ -397,8 +395,7 @@ void OnScopeStatement::toIR(IRState* p) { - static int wsi = 0; - Logger::println("OnScopeStatement::toIR(%d): %s", wsi++, toChars()); + Logger::println("OnScopeStatement::toIR(): %s", toChars()); LOG_SCOPE; assert(statement); @@ -407,10 +404,6 @@ ////////////////////////////////////////////////////////////////////////////// -static void replaceFinallyBBs(std::vector<llvm::BasicBlock*>& a, std::vector<llvm::BasicBlock*>& b) -{ -} - void TryFinallyStatement::toIR(IRState* p) { Logger::println("TryFinallyStatement::toIR(): %s", toChars()); @@ -495,7 +488,7 @@ Logger::println("TryCatchStatement::toIR(%d): %s", wsi++, toChars()); LOG_SCOPE; - Logger::println("*** ATTENTION: try-catch is not yet fully implemented, only the try block will be emitted."); + Logger::attention("try-catch is not yet fully implemented, only the try block will be emitted."); assert(body); body->toIR(p); @@ -516,10 +509,9 @@ Logger::println("ThrowStatement::toIR(%d): %s", wsi++, toChars()); LOG_SCOPE; - Logger::println("*** ATTENTION: throw is not yet implemented, replacing expression with assert(0);"); + Logger::attention("throw is not yet implemented, replacing expression with assert(0);"); - llvm::Value* line = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); - DtoAssert(NULL, line, NULL); + DtoAssert(NULL, &loc, NULL); /* assert(exp); @@ -657,42 +649,62 @@ //Logger::println("Argument is %s", arg->toChars()); Logger::println("aggr = %s", aggr->toChars()); - Logger::println("func = %s", func->toChars()); - DValue* arr = aggr->toElem(p); - llvm::Value* val = 0; - if (!arr->isSlice()) { - val = arr->getRVal(); - Logger::cout() << "aggr2llvm = " << *val << '\n'; - } - - llvm::Value* numiters = 0; - + // key const llvm::Type* keytype = key ? DtoType(key->type) : DtoSize_t(); llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint()); if (key) key->llvmValue = keyvar; + llvm::Value* zerokey = llvm::ConstantInt::get(keytype,0,false); + // value const llvm::Type* valtype = DtoType(value->type); - llvm::Value* valvar = !(value->isRef() || value->isOut()) ? new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint()) : NULL; + llvm::Value* valvar = NULL; + if (!value->isRef() && !value->isOut()) + valvar = new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint()); + // what to iterate + DValue* aggrval = aggr->toElem(p); Type* aggrtype = DtoDType(aggr->type); + + // get length and pointer + llvm::Value* val = 0; + llvm::Value* niters = 0; + + // static array if (aggrtype->ty == Tsarray) { + Logger::println("foreach over static array"); + val = aggrval->getRVal(); assert(llvm::isa<llvm::PointerType>(val->getType())); assert(llvm::isa<llvm::ArrayType>(val->getType()->getContainedType(0))); - size_t n = llvm::cast<llvm::ArrayType>(val->getType()->getContainedType(0))->getNumElements(); - assert(n > 0); - numiters = llvm::ConstantInt::get(keytype,n,false); + size_t nelems = llvm::cast<llvm::ArrayType>(val->getType()->getContainedType(0))->getNumElements(); + assert(nelems > 0); + niters = llvm::ConstantInt::get(keytype,nelems,false); } + // dynamic array else if (aggrtype->ty == Tarray) { - if (DSliceValue* slice = arr->isSlice()) { - numiters = slice->len; + if (DSliceValue* slice = aggrval->isSlice()) { + Logger::println("foreach over slice"); + niters = slice->len; + assert(niters); + if (llvm::isa<llvm::ConstantInt>(niters)) { + llvm::ConstantInt* ci = llvm::cast<llvm::ConstantInt>(niters); + Logger::println("const num iters: %u", ci); + } + else { + Logger::cout() << "numiters: " << *niters <<'\n'; + } val = slice->ptr; + assert(val); } else { - numiters = p->ir->CreateLoad(DtoGEPi(val,0,0,"tmp",p->scopebb())); - val = p->ir->CreateLoad(DtoGEPi(val,0,1,"tmp",p->scopebb())); + Logger::println("foreach over dynamic array"); + val = aggrval->getRVal(); + niters = DtoGEPi(val,0,0,"tmp",p->scopebb()); + niters = p->ir->CreateLoad(niters, "numiterations"); + val = DtoGEPi(val,0,1,"tmp",p->scopebb()); + val = p->ir->CreateLoad(val, "collection"); } } else @@ -700,41 +712,39 @@ assert(0 && "aggregate type is not Tarray or Tsarray"); } + llvm::Constant* delta = 0; if (op == TOKforeach) { - new llvm::StoreInst(llvm::ConstantInt::get(keytype,0,false), keyvar, p->scopebb()); + new llvm::StoreInst(zerokey, keyvar, p->scopebb()); } - else if (op == TOKforeach_reverse) { - llvm::Value* v = llvm::BinaryOperator::createSub(numiters, llvm::ConstantInt::get(keytype,1,false),"tmp",p->scopebb()); - new llvm::StoreInst(v, keyvar, p->scopebb()); + else { + new llvm::StoreInst(niters, keyvar, p->scopebb()); } - delete arr; - llvm::BasicBlock* oldend = gIR->scopeend(); - llvm::BasicBlock* nexbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend); - llvm::BasicBlock* begbb = new llvm::BasicBlock("foreachbegin", p->topfunc(), oldend); + llvm::BasicBlock* condbb = new llvm::BasicBlock("foreachcond", p->topfunc(), oldend); + llvm::BasicBlock* bodybb = new llvm::BasicBlock("foreachbody", p->topfunc(), oldend); + llvm::BasicBlock* nextbb = new llvm::BasicBlock("foreachnext", p->topfunc(), oldend); llvm::BasicBlock* endbb = new llvm::BasicBlock("foreachend", p->topfunc(), oldend); - new llvm::BranchInst(begbb, p->scopebb()); + new llvm::BranchInst(condbb, p->scopebb()); - // next - p->scope() = IRScope(nexbb,begbb); + // condition + p->scope() = IRScope(condbb,bodybb); + llvm::Value* done = 0; llvm::Value* load = new llvm::LoadInst(keyvar, "tmp", p->scopebb()); if (op == TOKforeach) { - load = llvm::BinaryOperator::createAdd(load,llvm::ConstantInt::get(keytype, 1, false),"tmp",p->scopebb()); - new llvm::StoreInst(load, keyvar, p->scopebb()); - done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, numiters, "tmp", p->scopebb()); + done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, niters, "tmp", p->scopebb()); } else if (op == TOKforeach_reverse) { - done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGT, load, llvm::ConstantInt::get(keytype, 0, false), "tmp", p->scopebb()); + done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGT, load, zerokey, "tmp", p->scopebb()); load = llvm::BinaryOperator::createSub(load,llvm::ConstantInt::get(keytype, 1, false),"tmp",p->scopebb()); new llvm::StoreInst(load, keyvar, p->scopebb()); } - new llvm::BranchInst(begbb, endbb, done, p->scopebb()); + new llvm::BranchInst(bodybb, endbb, done, p->scopebb()); - // begin - p->scope() = IRScope(begbb,nexbb); + // body + p->scope() = IRScope(bodybb,nextbb); // get value for this iteration llvm::Constant* zero = llvm::ConstantInt::get(keytype,0,false); @@ -754,13 +764,21 @@ } // body - p->scope() = IRScope(p->scopebb(),endbb); - p->loopbbs.push_back(IRScope(nexbb,endbb)); + p->loopbbs.push_back(IRScope(nextbb,endbb)); body->toIR(p); p->loopbbs.pop_back(); if (!p->scopereturned()) - new llvm::BranchInst(nexbb, p->scopebb()); + new llvm::BranchInst(nextbb, p->scopebb()); + + // next + p->scope() = IRScope(nextbb,endbb); + if (op == TOKforeach) { + llvm::Value* load = DtoLoad(keyvar); + load = p->ir->CreateAdd(load, llvm::ConstantInt::get(keytype, 1, false), "tmp"); + DtoStore(load, keyvar); + } + new llvm::BranchInst(condbb, p->scopebb()); // end p->scope() = IRScope(endbb,oldend); @@ -828,13 +846,25 @@ ////////////////////////////////////////////////////////////////////////////// +void SynchronizedStatement::toIR(IRState* p) +{ + Logger::println("SynchronizedStatement::toIR(): %s", toChars()); + LOG_SCOPE; + + Logger::attention("synchronized is currently ignored. only the body will be emitted"); + + body->toIR(p); +} + +////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// #define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();} //STUBST(BreakStatement); //STUBST(ForStatement); //STUBST(WithStatement); -STUBST(SynchronizedStatement); +//STUBST(SynchronizedStatement); //STUBST(ReturnStatement); //STUBST(ContinueStatement); STUBST(DefaultStatement);
--- a/gen/todebug.cpp Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/todebug.cpp Mon Nov 12 06:32:46 2007 +0100 @@ -56,7 +56,7 @@ */ if (!gIR->module->getNamedGlobal("llvm.dbg.compile_units")) { std::vector<llvm::Constant*> vals; - vals.push_back(DtoConstUint(0)); + vals.push_back(DtoConstUint(llvm::LLVMDebugVersion)); vals.push_back(DtoConstUint(DW_TAG_compile_unit)); llvm::Constant* i = llvm::ConstantStruct::get(t, vals); dbg_compile_units = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.compile_units",gIR->module); @@ -64,7 +64,7 @@ } if (!gIR->module->getNamedGlobal("llvm.dbg.global_variables")) { std::vector<llvm::Constant*> vals; - vals.push_back(DtoConstUint(0)); + vals.push_back(DtoConstUint(llvm::LLVMDebugVersion)); vals.push_back(DtoConstUint(DW_TAG_variable)); llvm::Constant* i = llvm::ConstantStruct::get(t, vals); dbg_global_variables = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.global_variables",gIR->module); @@ -72,7 +72,7 @@ } if (!gIR->module->getNamedGlobal("llvm.dbg.subprograms")) { std::vector<llvm::Constant*> vals; - vals.push_back(DtoConstUint(0)); + vals.push_back(DtoConstUint(llvm::LLVMDebugVersion)); vals.push_back(DtoConstUint(DW_TAG_subprogram)); llvm::Constant* i = llvm::ConstantStruct::get(t, vals); dbg_subprograms = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.subprograms",gIR->module); @@ -110,30 +110,33 @@ ////////////////////////////////////////////////////////////////////////////////////////////////// -llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m) +llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m, bool define) { - std::vector<llvm::Constant*> vals; - vals.push_back(llvm::ConstantExpr::getAdd( - DtoConstUint(DW_TAG_compile_unit), - DtoConstUint(llvm::LLVMDebugVersion))); - vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_compile_unit))); + llvm::Constant* c = NULL; + if (1 || define) { + std::vector<llvm::Constant*> vals; + vals.push_back(llvm::ConstantExpr::getAdd( + DtoConstUint(DW_TAG_compile_unit), + DtoConstUint(llvm::LLVMDebugVersion))); + vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_compile_unit))); - vals.push_back(DtoConstUint(DW_LANG_D)); - vals.push_back(DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata")); - std::string srcpath(FileName::path(m->srcfile->name->toChars())); - srcpath.append("/"); - vals.push_back(DtoConstStringPtr(srcpath.c_str(), "llvm.metadata")); - vals.push_back(DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata")); + vals.push_back(DtoConstUint(DW_LANG_D)); + vals.push_back(DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata")); + std::string srcpath(FileName::path(m->srcfile->name->toChars())); + srcpath.append("/"); + vals.push_back(DtoConstStringPtr(srcpath.c_str(), "llvm.metadata")); + vals.push_back(DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata")); - llvm::Constant* c = llvm::ConstantStruct::get(GetDwarfCompileUnitType(), vals); - llvm::GlobalVariable* gv = new llvm::GlobalVariable(c->getType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.compile_unit", gIR->module); + c = llvm::ConstantStruct::get(GetDwarfCompileUnitType(), vals); + } + llvm::GlobalVariable* gv = new llvm::GlobalVariable(GetDwarfCompileUnitType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.compile_unit", gIR->module); gv->setSection("llvm.metadata"); return gv; } ////////////////////////////////////////////////////////////////////////////////////////////////// -llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd) +llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit) { std::vector<llvm::Constant*> vals; vals.push_back(llvm::ConstantExpr::getAdd( @@ -141,11 +144,11 @@ DtoConstUint(llvm::LLVMDebugVersion))); vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_subprogram))); - vals.push_back(dbgToArrTy(gIR->dwarfCompileUnit)); + vals.push_back(dbgToArrTy(compileUnit)); vals.push_back(DtoConstStringPtr(fd->toPrettyChars(), "llvm.metadata")); + vals.push_back(vals.back()); vals.push_back(DtoConstStringPtr(fd->mangle(), "llvm.metadata")); - vals.push_back(llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty))); - vals.push_back(dbgToArrTy(gIR->dwarfCompileUnit)); + vals.push_back(dbgToArrTy(compileUnit)); vals.push_back(DtoConstUint(fd->loc.linnum)); vals.push_back(llvm::ConstantPointerNull::get(dbgArrTy())); vals.push_back(DtoConstBool(fd->protection == PROTprivate)); @@ -178,6 +181,7 @@ std::vector<llvm::Value*> args; args.push_back(DtoConstUint(ln)); args.push_back(DtoConstUint(0)); - args.push_back(dbgToArrTy(gIR->dwarfCompileUnit)); + assert(gIR->dmodule->llvmCompileUnit); + args.push_back(dbgToArrTy(gIR->dmodule->llvmCompileUnit)); gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end()); }
--- a/gen/todebug.h Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/todebug.h Mon Nov 12 06:32:46 2007 +0100 @@ -7,8 +7,8 @@ const llvm::StructType* GetDwarfCompileUnitType(); const llvm::StructType* GetDwarfSubProgramType(); -llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m); -llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd); +llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m, bool define); +llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit); void DtoDwarfFuncStart(FuncDeclaration* fd); void DtoDwarfFuncEnd(FuncDeclaration* fd);
--- a/gen/toir.cpp Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/toir.cpp Mon Nov 12 06:32:46 2007 +0100 @@ -66,9 +66,7 @@ //allocainst->setAlignment(vd->type->alignsize()); // TODO vd->llvmValue = allocainst; } - DVarValue* vv = new DVarValue(type, vd->llvmValue, true); - DValue* ie = DtoInitializer(vd->init, vv); - delete ie; + DValue* ie = DtoInitializer(vd->init); } return new DVarValue(vd, vd->llvmValue, true); @@ -465,6 +463,7 @@ DImValue* im = r->isIm(); if (!im || !im->inPlace()) { + Logger::println("assignment not inplace"); if (l->isArrayLen()) DtoResizeDynArray(l->getLVal(), r->getRVal()); else @@ -659,7 +658,14 @@ return new DFieldValue(type, v, true); } else if (e1type->ty == Tpointer) { - Logger::println("add to AddrExp of struct"); + Logger::println("add to pointer"); + if (r->isConst()) { + llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c); + if (cofs->isZero()) { + Logger::println("is zero"); + return new DImValue(type, l->getRVal()); + } + } llvm::Value* v = new llvm::GetElementPtrInst(l->getRVal(), r->getRVal(), "tmp", p->scopebb()); return new DImValue(type, v); } @@ -728,9 +734,14 @@ DValue* r = e2->toElem(p); if (DtoDType(e1->type)->ty == Tpointer) { - llvm::Value* left = p->ir->CreatePtrToInt(l->getRVal(), DtoSize_t(), "tmp"); - llvm::Value* right = p->ir->CreatePtrToInt(r->getRVal(), DtoSize_t(), "tmp"); - llvm::Value* diff = p->ir->CreateSub(left,right,"tmp"); + llvm::Value* lv = l->getRVal(); + llvm::Value* rv = r->getRVal(); + Logger::cout() << "lv: " << *lv << " rv: " << *rv << '\n'; + if (isaPointer(lv)) + lv = p->ir->CreatePtrToInt(lv, DtoSize_t(), "tmp"); + if (isaPointer(rv)) + rv = p->ir->CreatePtrToInt(rv, DtoSize_t(), "tmp"); + llvm::Value* diff = p->ir->CreateSub(lv,rv,"tmp"); if (diff->getType() != DtoType(type)) diff = p->ir->CreateIntToPtr(diff, DtoType(type)); return new DImValue(type, diff); @@ -1095,6 +1106,13 @@ llt = llvm::PointerType::get(llt); return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp")); } + else if (fndecl->llvmInternal == LLVMalloca) { + //Argument* fnarg = Argument::getNth(tf->parameters, 0); + Expression* exp = (Expression*)arguments->data[0]; + DValue* expv = exp->toElem(p); + llvm::Value* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb()); + return new DImValue(type, alloc); + } } // args @@ -1545,14 +1563,13 @@ if (offset != 0) { Logger::println("offset = %d\n", offset); } - if (llvalue->getType() != llt) { - varmem = p->ir->CreateBitCast(llvalue, llt, "tmp"); - if (offset != 0) - varmem = DtoGEPi(varmem, offset, "tmp"); + if (offset == 0) { + varmem = llvalue; } else { - assert(offset == 0); - varmem = DtoGEPi(llvalue,0,0,"tmp"); + const llvm::Type* elemtype = llvalue->getType()->getContainedType(0)->getContainedType(0); + size_t elemsz = gTargetData->getTypeSize(elemtype); + varmem = DtoGEPi(llvalue, 0, offset / elemsz, "tmp"); } } else if (offset == 0) { @@ -1571,17 +1588,30 @@ } return new DFieldValue(type, varmem, true); } - else if (FuncDeclaration* fd = var->isFuncDeclaration()) + + assert(0); + return 0; +} + +////////////////////////////////////////////////////////////////////////////////////////// + +DValue* AddrExp::toElem(IRState* p) +{ + Logger::print("AddrExp::toElem: %s | %s\n", toChars(), type->toChars()); + LOG_SCOPE; + DValue* v = e1->toElem(p); + if (v->isField()) + return v; + if (DFuncValue* fv = v->isFunc()) { Logger::println("FuncDeclaration"); - + FuncDeclaration* fd = fv->func; + assert(fd); if (fd->llvmValue == 0) fd->toObjFile(); return new DFuncValue(fd, fd->llvmValue); } - - assert(0); - return 0; + return new DFieldValue(type, v->getLVal(), false); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1700,18 +1730,6 @@ ////////////////////////////////////////////////////////////////////////////////////////// -DValue* AddrExp::toElem(IRState* p) -{ - Logger::print("AddrExp::toElem: %s | %s\n", toChars(), type->toChars()); - LOG_SCOPE; - DValue* v = e1->toElem(p); - if (v->isField()) - return v; - return new DFieldValue(type, v->getLVal(), false); -} - -////////////////////////////////////////////////////////////////////////////////////////// - DValue* IndexExp::toElem(IRState* p) { Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars()); @@ -1755,7 +1773,7 @@ Type* e1type = DtoDType(e1->type); DValue* v = e1->toElem(p); - llvm::Value* vmem = v->isIm() ? v->getRVal() : v->getLVal(); + llvm::Value* vmem = v->getRVal(); assert(vmem); llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); @@ -2100,47 +2118,46 @@ const llvm::Type* t = DtoType(ntype); llvm::Value* emem = 0; - bool inplace = true; + bool inplace = false; if (onstack) { assert(ntype->ty == Tclass); emem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint()); } - else { - if (ntype->ty == Tclass) { - emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb()); - } - else if (ntype->ty == Tarray) { - assert(arguments); - if (arguments->dim == 1) { - DValue* sz = ((Expression*)arguments->data[0])->toElem(p); - llvm::Value* dimval = sz->getRVal(); - Type* nnt = DtoDType(ntype->next); - if (nnt->ty == Tvoid) - nnt = Type::tint8; - if (!p->topexp() || p->topexp()->e2 != this) { - const llvm::Type* restype = DtoType(type); - Logger::cout() << "restype = " << *restype << '\n'; - emem = new llvm::AllocaInst(restype,"tmp",p->topallocapoint()); - DtoNewDynArray(emem, dimval, nnt); - inplace = false; - } - else if (p->topexp() || p->topexp()->e2 != this) { - assert(p->topexp()->v); - emem = p->topexp()->v->getLVal(); - DtoNewDynArray(emem, dimval, nnt); - } - else - assert(0); + else if (ntype->ty == Tclass) { + emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb()); + } + else if (ntype->ty == Tarray) { + assert(arguments); + if (arguments->dim == 1) { + DValue* sz = ((Expression*)arguments->data[0])->toElem(p); + llvm::Value* dimval = sz->getRVal(); + Type* nnt = DtoDType(ntype->next); + if (nnt->ty == Tvoid) + nnt = Type::tint8; + if (!p->topexp() || p->topexp()->e2 != this) { + const llvm::Type* restype = DtoType(type); + Logger::cout() << "restype = " << *restype << '\n'; + emem = new llvm::AllocaInst(restype,"newstorage",p->topallocapoint()); + DtoNewDynArray(emem, dimval, nnt); + return new DVarValue(newtype, emem, true); } - else { - assert(0); + else if (p->topexp() && p->topexp()->e2 == this) { + assert(p->topexp()->v); + emem = p->topexp()->v->getLVal(); + DtoNewDynArray(emem, dimval, nnt); + inplace = true; } + else + assert(0); } else { - emem = new llvm::MallocInst(t,"tmp",p->scopebb()); + assert(0); } } + else { + emem = new llvm::MallocInst(t,"tmp",p->scopebb()); + } if (ntype->ty == Tclass) { // first apply the static initializer @@ -2175,10 +2192,7 @@ } } - if (inplace) - return new DImValue(type, emem, true); - - return new DVarValue(type, emem, true); + return new DImValue(type, emem, inplace); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -2264,8 +2278,7 @@ DValue* u = e1->toElem(p); DValue* m = msg ? msg->toElem(p) : NULL; - llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); - DtoAssert(u->getRVal(), loca, m ? m->getRVal() : NULL); + DtoAssert(u->getRVal(), &loc, m); return 0; } @@ -2401,8 +2414,7 @@ Logger::print("HaltExp::toElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); - DtoAssert(llvm::ConstantInt::getFalse(), loca, NULL); + DtoAssert(DtoConstBool(false), &loc, NULL); new llvm::UnreachableInst(p->scopebb()); return 0; @@ -2634,18 +2646,18 @@ fd->toObjFile(); + bool temp = false; llvm::Value* lval = NULL; - if (!p->topexp() || p->topexp()->e2 != this) { + if (p->topexp() && p->topexp()->e2 == this) { + assert(p->topexp()->v); + lval = p->topexp()->v->getLVal(); + } + else { const llvm::Type* dgty = DtoType(type); Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); + temp = true; } - else if (p->topexp()->e2 == this) { - assert(p->topexp()->v); - lval = p->topexp()->v->getLVal();; - } - else - assert(0); llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb()); const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(context->getType()->getContainedType(0)); @@ -2665,7 +2677,10 @@ llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb()); new llvm::StoreInst(castfptr, fptr, p->scopebb()); - return new DImValue(type, lval, true); + if (temp) + return new DVarValue(type, lval, true); + else + return new DImValue(type, lval, true); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -3093,7 +3108,7 @@ AsmStatement::AsmStatement(Loc loc, Token *tokens) : Statement(loc) { - assert(0); + Logger::println("Ignoring AsmStatement"); } Statement *AsmStatement::syntaxCopy() {
--- a/gen/tollvm.cpp Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/tollvm.cpp Mon Nov 12 06:32:46 2007 +0100 @@ -797,15 +797,13 @@ ////////////////////////////////////////////////////////////////////////////////////////// -DValue* DtoInitializer(Initializer* init, DValue* v) +DValue* DtoInitializer(Initializer* init) { if (ExpInitializer* ex = init->isExpInitializer()) { Logger::println("expression initializer"); assert(ex->exp); - if (v) gIR->exps.push_back(IRExp(NULL,ex->exp,v)); return ex->exp->toElem(gIR); - if (v) gIR->exps.pop_back(); } else if (init->isVoidInitializer()) { @@ -1050,16 +1048,17 @@ ////////////////////////////////////////////////////////////////////////////////////////// -void DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg) +void DtoAssert(llvm::Value* cond, Loc* loc, DValue* msg) { - assert(loc); + llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assert"); + const llvm::FunctionType* fnt = fn->getFunctionType(); + std::vector<llvm::Value*> llargs; llargs.resize(3); llargs[0] = cond ? DtoBoolean(cond) : llvm::ConstantInt::getFalse(); - llargs[1] = loc; - llargs[2] = msg ? msg : llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); + llargs[1] = DtoConstUint(loc->linnum); + llargs[2] = msg ? msg->getRVal() : llvm::Constant::getNullValue(fnt->getParamType(2)); - llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assert"); assert(fn); llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); call->setCallingConv(llvm::CallingConv::C); @@ -1301,6 +1300,11 @@ llvm::Value* r = rhs->getRVal(); llvm::Value* l = lhs->getLVal(); Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; + const llvm::Type* lit = l->getType()->getContainedType(0); + if (r->getType() != lit) { + r = DtoBitCast(r, lit); + Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n'; + } gIR->ir->CreateStore(r, l); } } @@ -1404,6 +1408,31 @@ return gIR->ir->CreateBitCast(v, t, "tmp"); } +const llvm::PointerType* isaPointer(llvm::Value* v) +{ + return llvm::dyn_cast<llvm::PointerType>(v->getType()); +} + +const llvm::ArrayType* isaArray(llvm::Value* v) +{ + return llvm::dyn_cast<llvm::ArrayType>(v->getType()); +} + +const llvm::StructType* isaStruct(llvm::Value* v) +{ + return llvm::dyn_cast<llvm::StructType>(v->getType()); +} + +llvm::Constant* isaConstant(llvm::Value* v) +{ + return llvm::dyn_cast<llvm::Constant>(v); +} + +llvm::ConstantInt* isaConstantInt(llvm::Value* v) +{ + return llvm::dyn_cast<llvm::ConstantInt>(v); +} + ////////////////////////////////////////////////////////////////////////////////////////// bool DtoIsTemplateInstance(Dsymbol* s) @@ -1431,7 +1460,7 @@ llvm::Value* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false)); gIR->ir->CreateCondBr(cond, initbb, endinitbb); gIR->scope() = IRScope(initbb,endinitbb); - DValue* ie = DtoInitializer(init, NULL); + DValue* ie = DtoInitializer(init); if (!ie->inPlace()) { DValue* dst = new DVarValue(t, gvar, true); DtoAssign(dst, ie);
--- a/gen/tollvm.h Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/tollvm.h Mon Nov 12 06:32:46 2007 +0100 @@ -34,7 +34,7 @@ void DtoInitClass(TypeClass* tc, llvm::Value* dst); llvm::Constant* DtoConstInitializer(Type* type, Initializer* init); -DValue* DtoInitializer(Initializer* init, DValue* v); +DValue* DtoInitializer(Initializer* init); llvm::Function* LLVM_DeclareMemSet32(); llvm::Function* LLVM_DeclareMemSet64(); @@ -49,7 +49,7 @@ llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty); llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* len); -void DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg); +void DtoAssert(llvm::Value* cond, Loc* loc, DValue* msg); llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expression* argexp); @@ -75,6 +75,13 @@ void DtoStore(llvm::Value* src, llvm::Value* dst); llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t); +// llvm::dyn_cast wrappers +const llvm::PointerType* isaPointer(llvm::Value* v); +const llvm::ArrayType* isaArray(llvm::Value* v); +const llvm::StructType* isaStruct(llvm::Value* v); +llvm::Constant* isaConstant(llvm::Value* v); +llvm::ConstantInt* isaConstantInt(llvm::Value* v); + // basic operations void DtoAssign(DValue* lhs, DValue* rhs);
--- a/gen/toobj.cpp Thu Nov 08 19:21:05 2007 +0100 +++ b/gen/toobj.cpp Mon Nov 12 06:32:46 2007 +0100 @@ -81,7 +81,7 @@ // debug info if (global.params.symdebug) { RegisterDwarfSymbols(ir.module); - ir.dwarfCompileUnit = DtoDwarfCompileUnit(this); + ir.dmodule->llvmCompileUnit = DtoDwarfCompileUnit(this,true); } // process module members @@ -162,7 +162,7 @@ Logger::println("vmoduleinfo"); } if (needModuleInfo()) { - Logger::println("**** ATTENTION: module info is needed but skipped"); + Logger::attention("module info is needed but skipped"); } @@ -905,7 +905,7 @@ } if (isUnitTestDeclaration()) { - Logger::println("*** ATTENTION: ignoring unittest declaration: %s", toChars()); + Logger::attention("ignoring unittest declaration: %s", toChars()); return; } @@ -948,7 +948,11 @@ // debug info if (global.params.symdebug) { - llvmDwarfSubProgram = DtoDwarfSubProgram(this); + Module* mo = getModule(); + if (!mo->llvmCompileUnit) { + mo->llvmCompileUnit = DtoDwarfCompileUnit(mo,false); + } + llvmDwarfSubProgram = DtoDwarfSubProgram(this, mo->llvmCompileUnit); } assert(f->llvmType); @@ -1033,7 +1037,7 @@ vd->llvmValue = v; } else { - Logger::println("*** ATTENTION: some unknown argument: %s", arg ? arg->toChars() : 0); + Logger::attention("some unknown argument: %s", arg ? arg->toChars() : 0); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/llvmdc.kdevelop Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,380 @@ +<?xml version = '1.0'?> +<kdevelop> + <general> + <author>Tomas Lindquist Olsen</author> + <email>tomas.l.olsen@gmail.com</email> + <version>0.1</version> + <projectmanagement>KDevCustomProject</projectmanagement> + <primarylanguage>C++</primarylanguage> + <keywords> + <keyword>C++</keyword> + <keyword>Code</keyword> + </keywords> + <ignoreparts/> + <projectname>llvmdc</projectname> + <projectdirectory>.</projectdirectory> + <absoluteprojectpath>false</absoluteprojectpath> + <description></description> + <defaultencoding></defaultencoding> + </general> + <kdevautoproject> + <general/> + <run/> + <configurations> + <optimized> + <builddir>optimized</builddir> + <ccompiler>kdevgccoptions</ccompiler> + <cxxcompiler>kdevgppoptions</cxxcompiler> + <f77compiler>kdevg77options</f77compiler> + <cxxflags>-O2 -g0</cxxflags> + </optimized> + <debug> + <configargs>--enable-debug=full</configargs> + <builddir>debug</builddir> + <ccompiler>kdevgccoptions</ccompiler> + <cxxcompiler>kdevgppoptions</cxxcompiler> + <f77compiler>kdevg77options</f77compiler> + <cxxflags>-O0 -g3</cxxflags> + </debug> + </configurations> + </kdevautoproject> + <kdevdoctreeview> + <ignoretocs> + <toc>ada</toc> + <toc>ada_bugs_gcc</toc> + <toc>bash</toc> + <toc>bash_bugs</toc> + <toc>clanlib</toc> + <toc>w3c-dom-level2-html</toc> + <toc>fortran_bugs_gcc</toc> + <toc>gnome1</toc> + <toc>gnustep</toc> + <toc>gtk</toc> + <toc>gtk_bugs</toc> + <toc>haskell</toc> + <toc>haskell_bugs_ghc</toc> + <toc>java_bugs_gcc</toc> + <toc>java_bugs_sun</toc> + <toc>kde2book</toc> + <toc>opengl</toc> + <toc>pascal_bugs_fp</toc> + <toc>php</toc> + <toc>php_bugs</toc> + <toc>perl</toc> + <toc>perl_bugs</toc> + <toc>python</toc> + <toc>python_bugs</toc> + <toc>qt-kdev3</toc> + <toc>ruby</toc> + <toc>ruby_bugs</toc> + <toc>sdl</toc> + <toc>w3c-svg</toc> + <toc>sw</toc> + <toc>w3c-uaag10</toc> + <toc>wxwidgets_bugs</toc> + </ignoretocs> + <ignoreqt_xml> + <toc>Guide to the Qt Translation Tools</toc> + <toc>Qt Assistant Manual</toc> + <toc>Qt Designer Manual</toc> + <toc>Qt Reference Documentation</toc> + <toc>qmake User Guide</toc> + </ignoreqt_xml> + <ignoredoxygen> + <toc>KDE Libraries (Doxygen)</toc> + </ignoredoxygen> + </kdevdoctreeview> + <kdevfilecreate> + <useglobaltypes> + <type ext="cpp" /> + <type ext="h" /> + </useglobaltypes> + </kdevfilecreate> + <kdevfileview> + <groups> + <group pattern="*.h" name="Header files" /> + <group pattern="*.cpp" name="Source files" /> + <hidenonprojectfiles>true</hidenonprojectfiles> + <hidenonlocation>false</hidenonlocation> + </groups> + <tree> + <hidepatterns>*.o,*.lo,CVS</hidepatterns> + <hidenonprojectfiles>false</hidenonprojectfiles> + </tree> + </kdevfileview> + <kdevdocumentation> + <projectdoc> + <docsystem>Doxygen Documentation Collection</docsystem> + <docurl>llvmdc.tag</docurl> + </projectdoc> + </kdevdocumentation> + <substmap> + <APPNAME>llvmdc</APPNAME> + <APPNAMELC>llvmdc</APPNAMELC> + <APPNAMESC>Llvmdc</APPNAMESC> + <APPNAMEUC>LLVMDC</APPNAMEUC> + <AUTHOR>Tomas Lindquist Olsen</AUTHOR> + <EMAIL>tomas.l.olsen@gmail.com</EMAIL> + <LICENSE>GPL</LICENSE> + <LICENSEFILE>COPYING</LICENSEFILE> + <VERSION>0.1</VERSION> + <YEAR>2007</YEAR> + <dest>/home/tomas/projects/llvmdc</dest> + </substmap> + <kdevcppsupport> + <qt> + <used>false</used> + <version>3</version> + <includestyle>3</includestyle> + <root>/opt/qt</root> + <designerintegration>EmbeddedKDevDesigner</designerintegration> + <qmake>/opt/qt/bin/qmake</qmake> + <designer>/opt/qt/bin/designer</designer> + <designerpluginpaths/> + </qt> + <codecompletion> + <automaticCodeCompletion>false</automaticCodeCompletion> + <automaticArgumentsHint>true</automaticArgumentsHint> + <automaticHeaderCompletion>true</automaticHeaderCompletion> + <codeCompletionDelay>250</codeCompletionDelay> + <argumentsHintDelay>400</argumentsHintDelay> + <headerCompletionDelay>250</headerCompletionDelay> + <showOnlyAccessibleItems>false</showOnlyAccessibleItems> + <completionBoxItemOrder>0</completionBoxItemOrder> + <howEvaluationContextMenu>true</howEvaluationContextMenu> + <showCommentWithArgumentHint>true</showCommentWithArgumentHint> + <statusBarTypeEvaluation>false</statusBarTypeEvaluation> + <namespaceAliases>std=_GLIBCXX_STD;__gnu_cxx=std</namespaceAliases> + <processPrimaryTypes>true</processPrimaryTypes> + <processFunctionArguments>false</processFunctionArguments> + <preProcessAllHeaders>false</preProcessAllHeaders> + <parseMissingHeadersExperimental>false</parseMissingHeadersExperimental> + <resolveIncludePathsUsingMakeExperimental>false</resolveIncludePathsUsingMakeExperimental> + <alwaysParseInBackground>true</alwaysParseInBackground> + <usePermanentCaching>true</usePermanentCaching> + <alwaysIncludeNamespaces>false</alwaysIncludeNamespaces> + <includePaths>.;</includePaths> + </codecompletion> + <creategettersetter> + <prefixGet></prefixGet> + <prefixSet>set</prefixSet> + <prefixVariable>m_,_</prefixVariable> + <parameterName>theValue</parameterName> + <inlineGet>true</inlineGet> + <inlineSet>true</inlineSet> + </creategettersetter> + <splitheadersource> + <enabled>false</enabled> + <synchronize>true</synchronize> + <orientation>Vertical</orientation> + </splitheadersource> + <references/> + </kdevcppsupport> + <kdevcustomproject> + <run> + <directoryradio>executable</directoryradio> + <mainprogram>/home/tomas/kdevprojects/llvmdc</mainprogram> + <programargs></programargs> + <globaldebugarguments></globaldebugarguments> + <globalcwd>/home/tomas/kdevprojects/llvmdc</globalcwd> + <useglobalprogram>false</useglobalprogram> + <terminal>false</terminal> + <autocompile>false</autocompile> + <autoinstall>false</autoinstall> + <autokdesu>false</autokdesu> + <envvars/> + </run> + <filetypes> + <filetype>*.h</filetype> + <filetype>*.c</filetype> + <filetype>*.cpp</filetype> + <filetype>*.d</filetype> + </filetypes> + <blacklist> + <path>dbgtypes.bc.cpp</path> + <path>debuginfo.c</path> + <path>debuginfo.cpp</path> + <path>dmdorig</path> + <path>dmdorig/dmd</path> + <path>dmdorig/dmd/access.c</path> + <path>dmdorig/dmd/aggregate.h</path> + <path>dmdorig/dmd/array.c</path> + <path>dmdorig/dmd/arraytypes.h</path> + <path>dmdorig/dmd/attrib.c</path> + <path>dmdorig/dmd/attrib.h</path> + <path>dmdorig/dmd/bit.c</path> + <path>dmdorig/dmd/cast.c</path> + <path>dmdorig/dmd/class.c</path> + <path>dmdorig/dmd/complex_t.h</path> + <path>dmdorig/dmd/cond.c</path> + <path>dmdorig/dmd/cond.h</path> + <path>dmdorig/dmd/constfold.c</path> + <path>dmdorig/dmd/dchar.c</path> + <path>dmdorig/dmd/dchar.h</path> + <path>dmdorig/dmd/declaration.c</path> + <path>dmdorig/dmd/declaration.h</path> + <path>dmdorig/dmd/delegatize.c</path> + <path>dmdorig/dmd/doc.c</path> + <path>dmdorig/dmd/doc.h</path> + <path>dmdorig/dmd/dsymbol.c</path> + <path>dmdorig/dmd/dsymbol.h</path> + <path>dmdorig/dmd/dump.c</path> + <path>dmdorig/dmd/entity.c</path> + <path>dmdorig/dmd/enum.c</path> + <path>dmdorig/dmd/enum.h</path> + <path>dmdorig/dmd/expression.c</path> + <path>dmdorig/dmd/expression.h</path> + <path>dmdorig/dmd/func.c</path> + <path>dmdorig/dmd/gnuc.c</path> + <path>dmdorig/dmd/gnuc.h</path> + <path>dmdorig/dmd/hdrgen.c</path> + <path>dmdorig/dmd/hdrgen.h</path> + <path>dmdorig/dmd/html.c</path> + <path>dmdorig/dmd/html.h</path> + <path>dmdorig/dmd/identifier.c</path> + <path>dmdorig/dmd/identifier.h</path> + <path>dmdorig/dmd/idgen.c</path> + <path>dmdorig/dmd/impcnvgen.c</path> + <path>dmdorig/dmd/import.c</path> + <path>dmdorig/dmd/import.h</path> + <path>dmdorig/dmd/inifile.c</path> + <path>dmdorig/dmd/init.c</path> + <path>dmdorig/dmd/init.h</path> + <path>dmdorig/dmd/inline.c</path> + <path>dmdorig/dmd/interpret.c</path> + <path>dmdorig/dmd/lexer.c</path> + <path>dmdorig/dmd/lexer.h</path> + <path>dmdorig/dmd/link.c</path> + <path>dmdorig/dmd/lstring.c</path> + <path>dmdorig/dmd/lstring.h</path> + <path>dmdorig/dmd/macro.c</path> + <path>dmdorig/dmd/macro.h</path> + <path>dmdorig/dmd/mangle.c</path> + <path>dmdorig/dmd/mars.c</path> + <path>dmdorig/dmd/mars.h</path> + <path>dmdorig/dmd/mem.c</path> + <path>dmdorig/dmd/mem.h</path> + <path>dmdorig/dmd/module.c</path> + <path>dmdorig/dmd/module.h</path> + <path>dmdorig/dmd/mtype.c</path> + <path>dmdorig/dmd/mtype.h</path> + <path>dmdorig/dmd/opover.c</path> + <path>dmdorig/dmd/optimize.c</path> + <path>dmdorig/dmd/parse.c</path> + <path>dmdorig/dmd/parse.h</path> + <path>dmdorig/dmd/port.h</path> + <path>dmdorig/dmd/root.c</path> + <path>dmdorig/dmd/root.h</path> + <path>dmdorig/dmd/scope.c</path> + <path>dmdorig/dmd/scope.h</path> + <path>dmdorig/dmd/statement.c</path> + <path>dmdorig/dmd/statement.h</path> + <path>dmdorig/dmd/staticassert.c</path> + <path>dmdorig/dmd/staticassert.h</path> + <path>dmdorig/dmd/stringtable.c</path> + <path>dmdorig/dmd/stringtable.h</path> + <path>dmdorig/dmd/struct.c</path> + <path>dmdorig/dmd/template.c</path> + <path>dmdorig/dmd/template.h</path> + <path>dmdorig/dmd/tocsym.c</path> + <path>dmdorig/dmd/todt.c</path> + <path>dmdorig/dmd/toir.c</path> + <path>dmdorig/dmd/toir.h</path> + <path>dmdorig/dmd/toobj.c</path> + <path>dmdorig/dmd/total.h</path> + <path>dmdorig/dmd/typinf.c</path> + <path>dmdorig/dmd/unialpha.c</path> + <path>dmdorig/dmd/utf.c</path> + <path>dmdorig/dmd/utf.h</path> + <path>dmdorig/dmd/version.c</path> + <path>dmdorig/dmd/version.h</path> + <path>dmdorig/phobos</path> + <path>dmdorig/phobos/errno.c</path> + <path>dmdorig/phobos/etc</path> + <path>dmdorig/phobos/etc/c</path> + <path>dmdorig/phobos/etc/c/zlib</path> + <path>dmdorig/phobos/etc/c/zlib/adler32.c</path> + <path>dmdorig/phobos/etc/c/zlib/compress.c</path> + <path>dmdorig/phobos/etc/c/zlib/crc32.c</path> + <path>dmdorig/phobos/etc/c/zlib/crc32.h</path> + <path>dmdorig/phobos/etc/c/zlib/deflate.c</path> + <path>dmdorig/phobos/etc/c/zlib/deflate.h</path> + <path>dmdorig/phobos/etc/c/zlib/example.c</path> + <path>dmdorig/phobos/etc/c/zlib/gzio.c</path> + <path>dmdorig/phobos/etc/c/zlib/infback.c</path> + <path>dmdorig/phobos/etc/c/zlib/inffast.c</path> + <path>dmdorig/phobos/etc/c/zlib/inffast.h</path> + <path>dmdorig/phobos/etc/c/zlib/inffixed.h</path> + <path>dmdorig/phobos/etc/c/zlib/inflate.c</path> + <path>dmdorig/phobos/etc/c/zlib/inflate.h</path> + <path>dmdorig/phobos/etc/c/zlib/inftrees.c</path> + <path>dmdorig/phobos/etc/c/zlib/inftrees.h</path> + <path>dmdorig/phobos/etc/c/zlib/minigzip.c</path> + <path>dmdorig/phobos/etc/c/zlib/trees.c</path> + <path>dmdorig/phobos/etc/c/zlib/trees.h</path> + <path>dmdorig/phobos/etc/c/zlib/uncompr.c</path> + <path>dmdorig/phobos/etc/c/zlib/zconf.h</path> + <path>dmdorig/phobos/etc/c/zlib/zconf.in.h</path> + <path>dmdorig/phobos/etc/c/zlib/zlib.h</path> + <path>dmdorig/phobos/etc/c/zlib/zutil.c</path> + <path>dmdorig/phobos/etc/c/zlib/zutil.h</path> + <path>dmdorig/phobos/internal</path> + <path>dmdorig/phobos/internal/complex.c</path> + <path>dmdorig/phobos/internal/critical.c</path> + <path>dmdorig/phobos/internal/deh.c</path> + <path>dmdorig/phobos/internal/mars.h</path> + <path>dmdorig/phobos/internal/monitor.c</path> + </blacklist> + <build> + <buildtool>make</buildtool> + <builddir></builddir> + </build> + <other> + <prio>0</prio> + <otherbin></otherbin> + <defaulttarget></defaulttarget> + <otheroptions></otheroptions> + <selectedenvironment>default</selectedenvironment> + <environments> + <default/> + </environments> + </other> + <make> + <abortonerror>false</abortonerror> + <numberofjobs>0</numberofjobs> + <prio>0</prio> + <dontact>false</dontact> + <makebin></makebin> + <defaulttarget></defaulttarget> + <makeoptions></makeoptions> + <selectedenvironment>default</selectedenvironment> + <environments> + <default/> + </environments> + </make> + </kdevcustomproject> + <cppsupportpart> + <filetemplates> + <interfacesuffix>.h</interfacesuffix> + <implementationsuffix>.cpp</implementationsuffix> + </filetemplates> + </cppsupportpart> + <kdevdebugger> + <general> + <gdbpath></gdbpath> + <dbgshell></dbgshell> + <configGdbScript></configGdbScript> + <runShellScript></runShellScript> + <runGdbScript></runGdbScript> + <breakonloadinglibs>true</breakonloadinglibs> + <separatetty>false</separatetty> + <floatingtoolbar>false</floatingtoolbar> + <raiseGDBOnStart>false</raiseGDBOnStart> + </general> + <display> + <staticmembers>false</staticmembers> + <demanglenames>true</demanglenames> + <outputradix>10</outputradix> + </display> + </kdevdebugger> +</kdevelop>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/llvmdc.kdevelop.filelist Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,419 @@ +# KDevelop Custom Project File List +demos +demos/gl.d +demos/glfuncs.d +demos/gltypes.d +demos/lib.d +demos/libtest1.d +demos/qd.d +demos/qd1.d +demos/ray.d +demos/sdl.d +demos/sdldemo1.d +dmd +dmd/access.c +dmd/aggregate.h +dmd/array.c +dmd/arraytypes.h +dmd/attrib.c +dmd/attrib.h +dmd/cast.c +dmd/class.c +dmd/complex_t.h +dmd/cond.c +dmd/cond.h +dmd/constfold.c +dmd/dchar.c +dmd/dchar.h +dmd/declaration.c +dmd/declaration.h +dmd/delegatize.c +dmd/doc.c +dmd/doc.h +dmd/dsymbol.c +dmd/dsymbol.h +dmd/dump.c +dmd/entity.c +dmd/enum.c +dmd/enum.h +dmd/expression.c +dmd/expression.h +dmd/func.c +dmd/gnuc.c +dmd/gnuc.h +dmd/hdrgen.c +dmd/hdrgen.h +dmd/html.c +dmd/html.h +dmd/id.c +dmd/id.h +dmd/identifier.c +dmd/identifier.h +dmd/idgen.c +dmd/impcnvgen.c +dmd/impcnvtab.c +dmd/import.c +dmd/import.h +dmd/inifile.c +dmd/init.c +dmd/init.h +dmd/inline.c +dmd/interpret.c +dmd/lexer.c +dmd/lexer.h +dmd/link.c +dmd/lstring.c +dmd/lstring.h +dmd/macro.c +dmd/macro.h +dmd/mangle.c +dmd/mars.c +dmd/mars.h +dmd/mem.c +dmd/mem.h +dmd/module.c +dmd/module.h +dmd/mtype.c +dmd/mtype.h +dmd/opover.c +dmd/optimize.c +dmd/parse.c +dmd/parse.h +dmd/port.h +dmd/root.c +dmd/root.h +dmd/scope.c +dmd/scope.h +dmd/statement.c +dmd/statement.h +dmd/staticassert.c +dmd/staticassert.h +dmd/stringtable.c +dmd/stringtable.h +dmd/struct.c +dmd/template.c +dmd/template.h +dmd/total.h +dmd/unialpha.c +dmd/utf.c +dmd/utf.h +dmd/version.c +dmd/version.h +gen +gen/arrays.cpp +gen/arrays.h +gen/binops.cpp +gen/dvalue.cpp +gen/dvalue.h +gen/dwarftypes.cpp +gen/elem.cpp +gen/elem.h +gen/enums.h +gen/irstate.cpp +gen/irstate.h +gen/llvm.h +gen/logger.cpp +gen/logger.h +gen/runtime.cpp +gen/runtime.h +gen/statements.cpp +gen/structs.cpp +gen/structs.h +gen/symbol.h +gen/tocsym.cpp +gen/todebug.cpp +gen/todebug.h +gen/todt.cpp +gen/toir.cpp +gen/tollvm.cpp +gen/tollvm.h +gen/toobj.cpp +gen/typinf.cpp +lphobos +lphobos/crc32.d +lphobos/gc +lphobos/gc/gclinux.d +lphobos/gc/gcstub.d +lphobos/gcstats.d +lphobos/internal +lphobos/internal/aApply.d +lphobos/internal/aApplyR.d +lphobos/internal/adi.d +lphobos/internal/arrays.d +lphobos/internal/contract.d +lphobos/internal/mem.d +lphobos/internal/moduleinit.d +lphobos/internal/objectimpl.d +lphobos/internal/qsort2.d +lphobos/llvm +lphobos/llvm/intrinsic.d +lphobos/llvm/va_list.d +lphobos/llvmsupport.d +lphobos/obj +lphobos/object.d +lphobos/phobos.d +lphobos/std +lphobos/std/array.d +lphobos/std/base64.d +lphobos/std/c +lphobos/std/c/fenv.d +lphobos/std/c/linux +lphobos/std/c/linux/linux.d +lphobos/std/c/linux/linuxextern.d +lphobos/std/c/linux/pthread.d +lphobos/std/c/linux/socket.d +lphobos/std/c/locale.d +lphobos/std/c/math.d +lphobos/std/c/process.d +lphobos/std/c/stdarg.d +lphobos/std/c/stddef.d +lphobos/std/c/stdio.d +lphobos/std/c/stdlib.d +lphobos/std/c/string.d +lphobos/std/c/time.d +lphobos/std/compiler.d +lphobos/std/conv.d +lphobos/std/ctype.d +lphobos/std/format.d +lphobos/std/intrinsic.d +lphobos/std/moduleinit.d +lphobos/std/outofmemory.d +lphobos/std/stdarg.d +lphobos/std/stdint.d +lphobos/std/stdio.d +lphobos/std/string.d +lphobos/std/traits.d +lphobos/std/uni.d +lphobos/std/utf.d +lphobos/typeinfo1 +lphobos/typeinfo1/ti_byte.d +lphobos/typeinfo1/ti_char.d +lphobos/typeinfo1/ti_dchar.d +lphobos/typeinfo1/ti_delegate.d +lphobos/typeinfo1/ti_double.d +lphobos/typeinfo1/ti_float.d +lphobos/typeinfo1/ti_idouble.d +lphobos/typeinfo1/ti_ifloat.d +lphobos/typeinfo1/ti_int.d +lphobos/typeinfo1/ti_ireal.d +lphobos/typeinfo1/ti_long.d +lphobos/typeinfo1/ti_ptr.d +lphobos/typeinfo1/ti_real.d +lphobos/typeinfo1/ti_short.d +lphobos/typeinfo1/ti_ubyte.d +lphobos/typeinfo1/ti_uint.d +lphobos/typeinfo1/ti_ulong.d +lphobos/typeinfo1/ti_ushort.d +lphobos/typeinfo1/ti_void.d +lphobos/typeinfo1/ti_wchar.d +lphobos/typeinfo2 +lphobos/typeinfo2/ti_Adouble.d +lphobos/typeinfo2/ti_Afloat.d +lphobos/typeinfo2/ti_Ag.d +lphobos/typeinfo2/ti_Aint.d +lphobos/typeinfo2/ti_Along.d +lphobos/typeinfo2/ti_Areal.d +lphobos/typeinfo2/ti_Ashort.d +lphobos/typeinfos1.d +lphobos/typeinfos2.d +runalltests.d +test +test/a.d +test/alignment.d +test/alloca1.d +test/arrayinit.d +test/arrays.d +test/arrays10.d +test/arrays2.d +test/arrays3.d +test/arrays4.d +test/arrays5.d +test/arrays6.d +test/arrays7.d +test/arrays8.d +test/arrays9.d +test/assign.d +test/b.d +test/bitops.d +test/bug1.d +test/bug10.d +test/bug11.d +test/bug12.d +test/bug13.d +test/bug14.d +test/bug15.d +test/bug16.d +test/bug17.d +test/bug18.d +test/bug19.d +test/bug2.d +test/bug20.d +test/bug21.d +test/bug22.d +test/bug23.d +test/bug24.d +test/bug25.d +test/bug26.d +test/bug27.d +test/bug28.d +test/bug29.d +test/bug3.d +test/bug30.d +test/bug32.d +test/bug33.d +test/bug34.d +test/bug35.d +test/bug36.d +test/bug37.d +test/bug38.d +test/bug39.d +test/bug4.d +test/bug40.d +test/bug41.d +test/bug42.d +test/bug43.d +test/bug44.d +test/bug45.d +test/bug47.d +test/bug48.d +test/bug49.d +test/bug5.d +test/bug50.d +test/bug51.d +test/bug52.d +test/bug53.d +test/bug54.d +test/bug55.d +test/bug56.d +test/bug57.d +test/bug58.d +test/bug59.d +test/bug6.d +test/bug60.d +test/bug61.d +test/bug62.d +test/bug63.d +test/bug64.d +test/bug65.d +test/bug7.d +test/bug8.d +test/bug9.d +test/c.d +test/classes.d +test/classes2.d +test/classes3.d +test/classes4.d +test/classes5.d +test/classes6.d +test/classes7.d +test/classes8.d +test/classinfo1.d +test/comma.d +test/complex1.d +test/cond.d +test/cond1.d +test/condexp.d +test/condexp1.d +test/cyclic.d +test/d.d +test/dgs.d +test/dotproduct.d +test/e.d +test/enum1.d +test/enum2.d +test/enum3.d +test/f.d +test/fail1.d +test/fail2.d +test/floatcmp.d +test/foreach1.d +test/foreach2.d +test/foreach3.d +test/foreach4.d +test/foreach5.d +test/foreach6.d +test/foreach7.d +test/forwdecl.d +test/funcptr.d +test/funcs.d +test/funcs2.d +test/g.d +test/globals1.d +test/globals2.d +test/goto1.d +test/imag1.d +test/imports2.d +test/imports_1of2.d +test/imports_2of2.d +test/intrinsics.d +test/mainargs1.d +test/memory1.d +test/moduleinfo1.d +test/multiarr1.d +test/multiarr2.d +test/multiarr3.d +test/multiarr4.d +test/neg.d +test/nested1.d +test/nested2.d +test/nested3.d +test/nested4.d +test/pointers.d +test/pt.d +test/ptrarith.d +test/ray.d +test/scope1.d +test/scope2.d +test/scope3.d +test/scope4.d +test/scope5.d +test/sieve.d +test/slices.d +test/sqrts.d +test/static_ctor.d +test/staticarrays.d +test/staticvars.d +test/stdiotest.d +test/strings1.d +test/structinit.d +test/structinit2.d +test/structs.d +test/structs2.d +test/structs3.d +test/structs4.d +test/structs5.d +test/structs6.d +test/switch1.d +test/sync1.d +test/templ1.d +test/templ2.d +test/terms.d +test/throw1.d +test/tuple1.d +test/typeinfo.d +test/typeinfo10.d +test/typeinfo2.d +test/typeinfo3.d +test/typeinfo4.d +test/typeinfo5.d +test/typeinfo6.d +test/typeinfo7.d +test/typeinfo8.d +test/typeinfo9.d +test/union1.d +test/union2.d +test/union3.d +test/union4.d +test/union5.d +test/union6.d +test/union7.d +test/unittest1.d +test/unrolled.d +test/v2d.d +test/vararg1.d +test/vararg2.d +test/vararg3.d +test/vararg4.d +test/virtcall.d +test/with1.d +tester.d
--- a/lphobos/build.sh Thu Nov 08 19:21:05 2007 +0100 +++ b/lphobos/build.sh Mon Nov 12 06:32:46 2007 +0100 @@ -35,10 +35,21 @@ llvmdc internal/aApplyR.d -c -odobj || exit 1 llvm-link -f -o=../lib/llvmdcore.bc obj/aApply.bc obj/aApplyR.bc ../lib/llvmdcore.bc || exit 1 +echo "compiling array runtime support" +llvmdc internal/qsort2.d -c -odobj || exit +llvm-link -f -o=../lib/llvmdcore.bc obj/qsort2.bc ../lib/llvmdcore.bc || exit 1 +llvmdc internal/adi.d -c -odobj || exit +llvm-link -f -o=../lib/llvmdcore.bc obj/adi.bc ../lib/llvmdcore.bc || exit 1 + echo "compiling llvm runtime support" -rebuild llvmsupport.d -c -oqobj -dc=llvmdc-posix || exit +rebuild llvmsupport.d -c -oqobj -dc=llvmdc-posix || exit 1 llvm-link -f -o=../lib/llvmdcore.bc `ls obj/llvm.*.bc` ../lib/llvmdcore.bc || exit 1 +echo "compiling garbage collector" +llvmdc gc/gclinux.d -c -odobj || exit 1 +llvmdc gc/gcstub.d -c -odobj -Igc || exit 1 +llvm-link -f -o=../lib/llvmdcore.bc obj/gclinux.bc obj/gcstub.bc ../lib/llvmdcore.bc || exit 1 + echo "compiling phobos" rebuild phobos.d -c -oqobj -dc=llvmdc-posix || exit 1 llvm-link -f -o=../lib/llvmdcore.bc `ls obj/std.*.bc` ../lib/llvmdcore.bc || exit 1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lphobos/gc/gclinux.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,107 @@ + +// Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com +// All Rights Reserved +// Written by Walter Bright + +import std.c.linux.linuxextern; +import std.c.linux.linux; + +/+ +extern (C) +{ + // from <sys/mman.h> + void* mmap(void* addr, uint len, int prot, int flags, int fd, uint offset); + int munmap(void* addr, uint len); + const void* MAP_FAILED = cast(void*)-1; + + // from <bits/mman.h> + enum { PROT_NONE = 0, PROT_READ = 1, PROT_WRITE = 2, PROT_EXEC = 4 } + enum { MAP_SHARED = 1, MAP_PRIVATE = 2, MAP_TYPE = 0x0F, + MAP_FIXED = 0x10, MAP_FILE = 0, MAP_ANON = 0x20 } +} ++/ + +/*********************************** + * Map memory. + */ + +void *os_mem_map(uint nbytes) +{ void *p; + + //errno = 0; + p = mmap(null, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + return (p == MAP_FAILED) ? null : p; +} + +/*********************************** + * Commit memory. + * Returns: + * 0 success + * !=0 failure + */ + +int os_mem_commit(void *base, uint offset, uint nbytes) +{ + return 0; +} + + +/*********************************** + * Decommit memory. + * Returns: + * 0 success + * !=0 failure + */ + +int os_mem_decommit(void *base, uint offset, uint nbytes) +{ + return 0; +} + +/*********************************** + * Unmap memory allocated with os_mem_map(). + * Returns: + * 0 success + * !=0 failure + */ + +int os_mem_unmap(void *base, uint nbytes) +{ + return munmap(base, nbytes); +} + + +/********************************************** + * Determine "bottom" of stack (actually the top on x86 systems). + */ + +void *os_query_stackBottom() +{ + version (none) + { // See discussion: http://autopackage.org/forums/viewtopic.php?t=22 + static void** libc_stack_end; + + if (libc_stack_end == libc_stack_end.init) + { + void* handle = dlopen(null, RTLD_NOW); + libc_stack_end = cast(void **)dlsym(handle, "__libc_stack_end"); + dlclose(handle); + } + return *libc_stack_end; + } + else + { // This doesn't resolve on all versions of Linux + return __libc_stack_end; + } +} + + +/********************************************** + * Determine base address and size of static data segment. + */ + +void os_query_staticdataseg(void **base, uint *nbytes) +{ + *base = cast(void *)&__data_start; + *nbytes = cast(byte *)&_end - cast(byte *)&__data_start; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lphobos/gc/gcstub.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2004 by Digital Mars, www.digitalmars.com + * Written by Walter Bright + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * o The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * o Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * o This notice may not be removed or altered from any source + * distribution. + */ + +// D Garbage Collector stub to prevent linking in gc + +module gcx; + +//debug=PRINTF; + +/***************************************************/ + +import object; + +version (Win32) +{ + import win32; +} + +version (linux) +{ + import gclinux; +} + + +//alias GC* gc_t; +alias GC gc_t; + +struct GCStats { } + +/* ============================ GC =============================== */ + + +//alias int size_t; +alias void (*GC_FINALIZER)(void *p, void *dummy); + +const uint GCVERSION = 1; // increment every time we change interface + // to GC. + +class GC +{ + uint gcversion = GCVERSION; + + void *gcx; // implementation + + void initialize() + { + debug(PRINTF) printf("initialize()\n"); + } + + + void Dtor() + { + debug(PRINTF) printf("Dtor()\n"); + } + + /+invariant + { + debug(PRINTF) printf("invariant()\n"); + }+/ + + void *malloc(size_t size) + { + debug(PRINTF) printf("malloc()\n"); + return null; + } + + void *mallocNoSync(size_t size) + { + debug(PRINTF) printf("mallocNoSync()\n"); + return null; + } + + + void *calloc(size_t size, size_t n) + { + debug(PRINTF) printf("calloc()\n"); + return null; + } + + + void *realloc(void *p, size_t size) + { + debug(PRINTF) printf("realloc()\n"); + return null; + } + + + void free(void *p) + { + debug(PRINTF) printf("free()\n"); + } + + size_t capacity(void *p) + { + debug(PRINTF) printf("capacity()\n"); + return 0; + } + + void check(void *p) + { + debug(PRINTF) printf("check()\n"); + } + + + void setStackBottom(void *p) + { + debug(PRINTF) printf("setStackBottom()\n"); + } + + static void scanStaticData(gc_t g) + { + void *pbot; + void *ptop; + uint nbytes; + + debug(PRINTF) printf("scanStaticData()\n"); + //debug(PRINTF) printf("+GC.scanStaticData()\n"); + os_query_staticdataseg(&pbot, &nbytes); + ptop = pbot + nbytes; + g.addRange(pbot, ptop); + //debug(PRINTF) printf("-GC.scanStaticData()\n"); + } + + static void unscanStaticData(gc_t g) + { + void *pbot; + uint nbytes; + + debug(PRINTF) printf("unscanStaticData()\n"); + os_query_staticdataseg(&pbot, &nbytes); + g.removeRange(pbot); + } + + + void addRoot(void *p) // add p to list of roots + { + debug(PRINTF) printf("addRoot()\n"); + } + + void removeRoot(void *p) // remove p from list of roots + { + debug(PRINTF) printf("removeRoot()\n"); + } + + void addRange(void *pbot, void *ptop) // add range to scan for roots + { + debug(PRINTF) printf("addRange()\n"); + } + + void removeRange(void *pbot) // remove range + { + debug(PRINTF) printf("removeRange()\n"); + } + + void fullCollect() // do full garbage collection + { + debug(PRINTF) printf("fullCollect()\n"); + } + + void fullCollectNoStack() // do full garbage collection + { + debug(PRINTF) printf("fullCollectNoStack()\n"); + } + + void genCollect() // do generational garbage collection + { + debug(PRINTF) printf("genCollect()\n"); + } + + void minimize() // minimize physical memory usage + { + debug(PRINTF) printf("minimize()\n"); + } + + void setFinalizer(void *p, GC_FINALIZER pFn) + { + debug(PRINTF) printf("setFinalizer()\n"); + } + + void enable() + { + debug(PRINTF) printf("enable()\n"); + } + + void disable() + { + debug(PRINTF) printf("disable()\n"); + } + + void getStats(out GCStats stats) + { + debug(PRINTF) printf("getStats()\n"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lphobos/internal/adi.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,803 @@ +//_ adi.d + +/** + * Part of the D programming language runtime library. + * Dynamic array property support routines + */ + +/* + * Copyright (C) 2000-2006 by Digital Mars, www.digitalmars.com + * Written by Walter Bright + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, in both source and binary form, subject to the following + * restrictions: + * + * o The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * o Altered source versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * o This notice may not be removed or altered from any source + * distribution. + */ + +//debug=adi; // uncomment to turn on debugging printf's + +//import std.stdio; +import std.c.stdio; +import std.c.stdlib; +import std.c.string; +//import std.string; +import std.outofmemory; +import std.utf; + +struct Array +{ + size_t length; + void* ptr; +} + +/********************************************** + * Reverse array of chars. + * Handled separately because embedded multibyte encodings should not be + * reversed. + */ + +extern (C) long _adReverseChar(char[] a) +{ + if (a.length > 1) + { + char[6] tmp; + char[6] tmplo; + char* lo = a.ptr; + char* hi = &a[length - 1]; + + while (lo < hi) + { auto clo = *lo; + auto chi = *hi; + + //printf("lo = %d, hi = %d\n", lo, hi); + if (clo <= 0x7F && chi <= 0x7F) + { + //printf("\tascii\n"); + *lo = chi; + *hi = clo; + lo++; + hi--; + continue; + } + + uint stridelo = std.utf.UTF8stride[clo]; + + uint stridehi = 1; + while ((chi & 0xC0) == 0x80) + { + chi = *--hi; + stridehi++; + assert(hi >= lo); + } + if (lo == hi) + break; + + //printf("\tstridelo = %d, stridehi = %d\n", stridelo, stridehi); + if (stridelo == stridehi) + { + + memcpy(tmp.ptr, lo, stridelo); + memcpy(lo, hi, stridelo); + memcpy(hi, tmp.ptr, stridelo); + lo += stridelo; + hi--; + continue; + } + + /* Shift the whole array. This is woefully inefficient + */ + memcpy(tmp.ptr, hi, stridehi); + memcpy(tmplo.ptr, lo, stridelo); + memmove(lo + stridehi, lo + stridelo , (hi - lo) - stridelo); + memcpy(lo, tmp.ptr, stridehi); + memcpy(hi + stridehi - stridelo, tmplo.ptr, stridelo); + + lo += stridehi; + hi = hi - 1 + (stridehi - stridelo); + } + } + return *cast(long*)(&a); +} + +unittest +{ + string a = "abcd"; + string r; + + r = a.dup.reverse; + //writefln(r); + assert(r == "dcba"); + + a = "a\u1235\u1234c"; + //writefln(a); + r = a.dup.reverse; + //writefln(r); + assert(r == "c\u1234\u1235a"); + + a = "ab\u1234c"; + //writefln(a); + r = a.dup.reverse; + //writefln(r); + assert(r == "c\u1234ba"); + + a = "\u3026\u2021\u3061\n"; + r = a.dup.reverse; + assert(r == "\n\u3061\u2021\u3026"); +} + + +/********************************************** + * Reverse array of wchars. + * Handled separately because embedded multiword encodings should not be + * reversed. + */ + +extern (C) long _adReverseWchar(wchar[] a) +{ + if (a.length > 1) + { + wchar[2] tmp; + wchar* lo = a.ptr; + wchar* hi = &a[length - 1]; + + while (lo < hi) + { auto clo = *lo; + auto chi = *hi; + + if ((clo < 0xD800 || clo > 0xDFFF) && + (chi < 0xD800 || chi > 0xDFFF)) + { + *lo = chi; + *hi = clo; + lo++; + hi--; + continue; + } + + int stridelo = 1 + (clo >= 0xD800 && clo <= 0xDBFF); + + int stridehi = 1; + if (chi >= 0xDC00 && chi <= 0xDFFF) + { + chi = *--hi; + stridehi++; + assert(hi >= lo); + } + if (lo == hi) + break; + + if (stridelo == stridehi) + { int stmp; + + assert(stridelo == 2); + assert(stmp.sizeof == 2 * (*lo).sizeof); + stmp = *cast(int*)lo; + *cast(int*)lo = *cast(int*)hi; + *cast(int*)hi = stmp; + lo += stridelo; + hi--; + continue; + } + + /* Shift the whole array. This is woefully inefficient + */ + memcpy(tmp.ptr, hi, stridehi * wchar.sizeof); + memcpy(hi + stridehi - stridelo, lo, stridelo * wchar.sizeof); + memmove(lo + stridehi, lo + stridelo , (hi - (lo + stridelo)) * wchar.sizeof); + memcpy(lo, tmp.ptr, stridehi * wchar.sizeof); + + lo += stridehi; + hi = hi - 1 + (stridehi - stridelo); + } + } + return *cast(long*)(&a); +} + +unittest +{ + wstring a = "abcd"; + wstring r; + + r = a.dup.reverse; + assert(r == "dcba"); + + a = "a\U00012356\U00012346c"; + r = a.dup.reverse; + assert(r == "c\U00012346\U00012356a"); + + a = "ab\U00012345c"; + r = a.dup.reverse; + assert(r == "c\U00012345ba"); +} + + +/********************************************** + * Support for array.reverse property. + */ + +extern (C) long _adReverse(Array a, size_t szelem) + out (result) + { + assert(result is *cast(long*)(&a)); + } + body + { + if (a.length >= 2) + { + byte* tmp; + byte[16] buffer; + + void* lo = a.ptr; + void* hi = a.ptr + (a.length - 1) * szelem; + + tmp = buffer.ptr; + if (szelem > 16) + { + //version (Win32) + tmp = cast(byte*) alloca(szelem); + //else + //tmp = new byte[szelem]; + } + + for (; lo < hi; lo += szelem, hi -= szelem) + { + memcpy(tmp, lo, szelem); + memcpy(lo, hi, szelem); + memcpy(hi, tmp, szelem); + } + + version (Win32) + { + } + else + { + //if (szelem > 16) + // BUG: bad code is generate for delete pointer, tries + // to call delclass. + //delete tmp; + } + } + return *cast(long*)(&a); + } + +unittest +{ + debug(adi) printf("array.reverse.unittest\n"); + + int[] a = new int[5]; + int[] b; + size_t i; + + for (i = 0; i < 5; i++) + a[i] = i; + b = a.reverse; + assert(b is a); + for (i = 0; i < 5; i++) + assert(a[i] == 4 - i); + + struct X20 + { // More than 16 bytes in size + int a; + int b, c, d, e; + } + + X20[] c = new X20[5]; + X20[] d; + + for (i = 0; i < 5; i++) + { c[i].a = i; + c[i].e = 10; + } + d = c.reverse; + assert(d is c); + for (i = 0; i < 5; i++) + { + assert(c[i].a == 4 - i); + assert(c[i].e == 10); + } +} + +/********************************************** + * Support for array.reverse property for bit[]. + */ + +version (none) +{ +extern (C) bit[] _adReverseBit(bit[] a) + out (result) + { + assert(result is a); + } + body + { + if (a.length >= 2) + { + bit t; + int lo, hi; + + lo = 0; + hi = a.length - 1; + for (; lo < hi; lo++, hi--) + { + t = a[lo]; + a[lo] = a[hi]; + a[hi] = t; + } + } + return a; + } + +unittest +{ + debug(adi) printf("array.reverse_Bit[].unittest\n"); + + bit[] b; + b = new bit[5]; + static bit[5] data = [1,0,1,1,0]; + int i; + + b[] = data[]; + b.reverse; + for (i = 0; i < 5; i++) + { + assert(b[i] == data[4 - i]); + } +} +} + +/********************************************** + * Sort array of chars. + */ + +extern (C) long _adSortChar(char[] a) +{ + if (a.length > 1) + { + dstring da = toUTF32(a); + da.sort; + size_t i = 0; + foreach (dchar d; da) + { char[4] buf; + string t = toUTF8(buf, d); + a[i .. i + t.length] = t[]; + i += t.length; + } + delete da; + } + return *cast(long*)(&a); +} + +/********************************************** + * Sort array of wchars. + */ + +extern (C) long _adSortWchar(wchar[] a) +{ + if (a.length > 1) + { + dstring da = toUTF32(a); + da.sort; + size_t i = 0; + foreach (dchar d; da) + { wchar[2] buf; + wstring t = toUTF16(buf, d); + a[i .. i + t.length] = t[]; + i += t.length; + } + delete da; + } + return *cast(long*)(&a); +} + +/********************************************** + * Support for array.sort property for bit[]. + */ + +version (none) +{ +extern (C) bit[] _adSortBit(bit[] a) + out (result) + { + assert(result is a); + } + body + { + if (a.length >= 2) + { + size_t lo, hi; + + lo = 0; + hi = a.length - 1; + while (1) + { + while (1) + { + if (lo >= hi) + goto Ldone; + if (a[lo] == true) + break; + lo++; + } + + while (1) + { + if (lo >= hi) + goto Ldone; + if (a[hi] == false) + break; + hi--; + } + + a[lo] = false; + a[hi] = true; + + lo++; + hi--; + } + Ldone: + ; + } + return a; + } + +unittest +{ + debug(adi) printf("array.sort_Bit[].unittest\n"); +} +} + +/*************************************** + * Support for array equality test. + */ + +extern (C) int _adEq(Array a1, Array a2, TypeInfo ti) +{ + //printf("_adEq(a1.length = %d, a2.length = %d)\n", a1.length, a2.length); + if (a1.length != a2.length) + return 0; // not equal + auto sz = ti.tsize(); + auto p1 = a1.ptr; + auto p2 = a2.ptr; + +/+ + for (int i = 0; i < a1.length; i++) + { + printf("%4x %4x\n", (cast(short*)p1)[i], (cast(short*)p2)[i]); + } ++/ + + if (sz == 1) + // We should really have a ti.isPOD() check for this + return (memcmp(p1, p2, a1.length) == 0); + + for (size_t i = 0; i < a1.length; i++) + { + if (!ti.equals(p1 + i * sz, p2 + i * sz)) + return 0; // not equal + } + return 1; // equal +} + +unittest +{ + debug(adi) printf("array.Eq unittest\n"); + + string a = "hello"; + + assert(a != "hel"); + assert(a != "helloo"); + assert(a != "betty"); + assert(a == "hello"); + assert(a != "hxxxx"); +} + +/*************************************** + * Support for array equality test for bit arrays. + */ + +version (none) +{ +extern (C) int _adEqBit(Array a1, Array a2) +{ size_t i; + + if (a1.length != a2.length) + return 0; // not equal + auto p1 = cast(byte*)a1.ptr; + auto p2 = cast(byte*)a2.ptr; + auto n = a1.length / 8; + for (i = 0; i < n; i++) + { + if (p1[i] != p2[i]) + return 0; // not equal + } + + ubyte mask; + + n = a1.length & 7; + mask = cast(ubyte)((1 << n) - 1); + //printf("i = %d, n = %d, mask = %x, %x, %x\n", i, n, mask, p1[i], p2[i]); + return (mask == 0) || (p1[i] & mask) == (p2[i] & mask); +} + +unittest +{ + debug(adi) printf("array.EqBit unittest\n"); + + static bit[] a = [1,0,1,0,1]; + static bit[] b = [1,0,1]; + static bit[] c = [1,0,1,0,1,0,1]; + static bit[] d = [1,0,1,1,1]; + static bit[] e = [1,0,1,0,1]; + + assert(a != b); + assert(a != c); + assert(a != d); + assert(a == e); +} +} + +/*************************************** + * Support for array compare test. + */ + +extern (C) int _adCmp(Array a1, Array a2, TypeInfo ti) +{ + //printf("adCmp()\n"); + auto len = a1.length; + if (a2.length < len) + len = a2.length; + auto sz = ti.tsize(); + void *p1 = a1.ptr; + void *p2 = a2.ptr; + + if (sz == 1) + { // We should really have a ti.isPOD() check for this + auto c = memcmp(p1, p2, len); + if (c) + return c; + } + else + { + for (size_t i = 0; i < len; i++) + { + auto c = ti.compare(p1 + i * sz, p2 + i * sz); + if (c) + return c; + } + } + if (a1.length == a2.length) + return 0; + return (a1.length > a2.length) ? 1 : -1; +} + +unittest +{ + debug(adi) printf("array.Cmp unittest\n"); + + string a = "hello"; + + assert(a > "hel"); + assert(a >= "hel"); + assert(a < "helloo"); + assert(a <= "helloo"); + assert(a > "betty"); + assert(a >= "betty"); + assert(a == "hello"); + assert(a <= "hello"); + assert(a >= "hello"); +} + +/*************************************** + * Support for array compare test. + */ + +extern (C) int _adCmpChar(Array a1, Array a2) +{ +version (D_InlineAsm_X86) +{ + asm + { naked ; + + push EDI ; + push ESI ; + + mov ESI,a1+4[4+ESP] ; + mov EDI,a2+4[4+ESP] ; + + mov ECX,a1[4+ESP] ; + mov EDX,a2[4+ESP] ; + + cmp ECX,EDX ; + jb GotLength ; + + mov ECX,EDX ; + +GotLength: + cmp ECX,4 ; + jb DoBytes ; + + // Do alignment if neither is dword aligned + test ESI,3 ; + jz Aligned ; + + test EDI,3 ; + jz Aligned ; +DoAlign: + mov AL,[ESI] ; //align ESI to dword bounds + mov DL,[EDI] ; + + cmp AL,DL ; + jnz Unequal ; + + inc ESI ; + inc EDI ; + + test ESI,3 ; + + lea ECX,[ECX-1] ; + jnz DoAlign ; +Aligned: + mov EAX,ECX ; + + // do multiple of 4 bytes at a time + + shr ECX,2 ; + jz TryOdd ; + + repe ; + cmpsd ; + + jnz UnequalQuad ; + +TryOdd: + mov ECX,EAX ; +DoBytes: + // if still equal and not end of string, do up to 3 bytes slightly + // slower. + + and ECX,3 ; + jz Equal ; + + repe ; + cmpsb ; + + jnz Unequal ; +Equal: + mov EAX,a1[4+ESP] ; + mov EDX,a2[4+ESP] ; + + sub EAX,EDX ; + pop ESI ; + + pop EDI ; + ret ; + +UnequalQuad: + mov EDX,[EDI-4] ; + mov EAX,[ESI-4] ; + + cmp AL,DL ; + jnz Unequal ; + + cmp AH,DH ; + jnz Unequal ; + + shr EAX,16 ; + + shr EDX,16 ; + + cmp AL,DL ; + jnz Unequal ; + + cmp AH,DH ; +Unequal: + sbb EAX,EAX ; + pop ESI ; + + or EAX,1 ; + pop EDI ; + + ret ; + } +} +else +{ + int len; + int c; + + //printf("adCmpChar()\n"); + len = a1.length; + if (a2.length < len) + len = a2.length; + c = memcmp(cast(char *)a1.ptr, cast(char *)a2.ptr, len); + if (!c) + c = cast(int)a1.length - cast(int)a2.length; + return c; +} +} + +unittest +{ + debug(adi) printf("array.CmpChar unittest\n"); + + string a = "hello"; + + assert(a > "hel"); + assert(a >= "hel"); + assert(a < "helloo"); + assert(a <= "helloo"); + assert(a > "betty"); + assert(a >= "betty"); + assert(a == "hello"); + assert(a <= "hello"); + assert(a >= "hello"); +} + +/*************************************** + * Support for array compare test. + */ + +version (none) +{ +extern (C) int _adCmpBit(Array a1, Array a2) +{ + int len; + uint i; + + len = a1.length; + if (a2.length < len) + len = a2.length; + ubyte *p1 = cast(ubyte*)a1.ptr; + ubyte *p2 = cast(ubyte*)a2.ptr; + uint n = len / 8; + for (i = 0; i < n; i++) + { + if (p1[i] != p2[i]) + break; // not equal + } + for (uint j = i * 8; j < len; j++) + { ubyte mask = cast(ubyte)(1 << j); + int c; + + c = cast(int)(p1[i] & mask) - cast(int)(p2[i] & mask); + if (c) + return c; + } + return cast(int)a1.length - cast(int)a2.length; +} + +unittest +{ + debug(adi) printf("array.CmpBit unittest\n"); + + static bit[] a = [1,0,1,0,1]; + static bit[] b = [1,0,1]; + static bit[] c = [1,0,1,0,1,0,1]; + static bit[] d = [1,0,1,1,1]; + static bit[] e = [1,0,1,0,1]; + + assert(a > b); + assert(a >= b); + assert(a < c); + assert(a <= c); + assert(a < d); + assert(a <= d); + assert(a == e); + assert(a <= e); + assert(a >= e); +} +}
--- a/lphobos/internal/arrays.d Thu Nov 08 19:21:05 2007 +0100 +++ b/lphobos/internal/arrays.d Mon Nov 12 06:32:46 2007 +0100 @@ -143,11 +143,3 @@ res[i] = v[0 .. strlen(v)]; } } - - - - - - - -
--- a/lphobos/internal/contract.d Thu Nov 08 19:21:05 2007 +0100 +++ b/lphobos/internal/contract.d Mon Nov 12 06:32:46 2007 +0100 @@ -4,10 +4,10 @@ void exit(int); -void _d_assert(bool cond, uint line, char* msg) +void _d_assert(bool cond, uint line, char[] msg) { if (!cond) { - printf("Aborted(%u): %s\n", line, msg); + printf("Aborted(%u): %.*s\n", line, msg.length, msg.ptr); exit(1); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lphobos/internal/qsort2.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,68 @@ + +/* + * Placed into Public Domain + * written by Walter Bright + * www.digitalmars.com + * + * This is a public domain version of qsort.d. + * All it does is call C's qsort(), but runs a little slower since + * it needs to synchronize a global variable. + */ + + +//debug=qsort; + +import std.c.stdlib; + +struct Array +{ + size_t length; + void *ptr; +} + +private TypeInfo tiglobal; + +extern (C) int cmp(void* p1, void* p2) +{ + return tiglobal.compare(p1, p2); +} + +extern (C) long _adSort(Array a, TypeInfo ti) +{ + synchronized + { + tiglobal = ti; + std.c.stdlib.qsort(a.ptr, a.length, cast(size_t)ti.tsize(), &cmp); + } + return *cast(long*)(&a); +} + + + +unittest +{ + debug(qsort) printf("array.sort.unittest()\n"); + + int a[] = new int[10]; + + a[0] = 23; + a[1] = 1; + a[2] = 64; + a[3] = 5; + a[4] = 6; + a[5] = 5; + a[6] = 17; + a[7] = 3; + a[8] = 0; + a[9] = -1; + + a.sort; + + for (int i = 0; i < a.length - 1; i++) + { + //printf("i = %d", i); + //printf(" %d %d\n", a[i], a[i + 1]); + assert(a[i] <= a[i + 1]); + } +} +
--- a/lphobos/std/c/stdlib.d Thu Nov 08 19:21:05 2007 +0100 +++ b/lphobos/std/c/stdlib.d Mon Nov 12 06:32:46 2007 +0100 @@ -42,6 +42,7 @@ int system(char *); + pragma(LLVM_internal, "alloca") void *alloca(uint); /// void *calloc(size_t, size_t); ///
--- a/lphobos/std/stdio.d Thu Nov 08 19:21:05 2007 +0100 +++ b/lphobos/std/stdio.d Mon Nov 12 06:32:46 2007 +0100 @@ -3,23 +3,42 @@ import std.traits; void _writef(T)(T t) { - static if(is(T: Object)) _writef(t.toString()); else - static if(is(T==char)) printf("%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<t.length; ++i) { _writef(','); _writef(t[i]); } - _writef(']'); - } else - static if(is(T: int)) printf("%i", t); else - static if(is(T: real)) printf("%f", t); else - static assert(false, "Cannot print "~T.stringof); + static if (is(T == char)) { + printf("%c", t); + } + else static if (is(T : char[])) { + printf("%.*s", t.length, t.ptr); + } + else static if (is(T : long)) { + printf("%ld", t); + } + else static if (is(T : ulong)) { + printf("%lu", t); + } + else static if (is(T : real)) { + printf("%f", t); + } + else static if (is(T : Object)) { + _writef(t.toString()); + } + else static if(isArray!(T)) { + _writef('['); + if (t.length) { + _writef(t[0]); + foreach(v; t[1..$]) { + _writef(','); _writef(v); + } + } + _writef(']'); + } + else static assert(0, "Cannot writef:"~T.tostring); } -void writef(T...)(T t) { - foreach (v; t) _writef(v); +void writef(T...)(T t) +{ + foreach(v;t) _writef(v); } -void writefln(T...)(T t) { - writef(t, "\n"); +void writefln(T...)(T t) +{ + writef(t, '\n'); }
--- a/lphobos/std/traits.d Thu Nov 08 19:21:05 2007 +0100 +++ b/lphobos/std/traits.d Mon Nov 12 06:32:46 2007 +0100 @@ -1,15 +1,189 @@ + +// Written in the D programming language. + +/** + * Templates with which to extract information about + * types at compile time. + * + * Macros: + * WIKI = Phobos/StdTraits + * Copyright: + * Public Domain + */ + +/* + * Authors: + * Walter Bright, Digital Mars, www.digitalmars.com + * Tomasz Stachowiak (isStaticArray, isExpressionTuple) + */ + module std.traits; -struct TypeHolder(S, T...) { - S _ReturnType; - T _ParameterTypeTuple; + +/*** + * Get the type of the return value from a function, + * a pointer to function, or a delegate. + * Example: + * --- + * import std.traits; + * int foo(); + * ReturnType!(foo) x; // x is declared as int + * --- + */ +template ReturnType(alias dg) +{ + alias ReturnType!(typeof(dg)) ReturnType; +} + +/** ditto */ +template ReturnType(dg) +{ + static if (is(dg R == return)) + alias R ReturnType; + else + static assert(0, "argument has no return type"); +} + +/*** + * Get the types of the paramters to a function, + * a pointer to function, or a delegate as a tuple. + * Example: + * --- + * import std.traits; + * int foo(int, long); + * void bar(ParameterTypeTuple!(foo)); // declares void bar(int, long); + * void abc(ParameterTypeTuple!(foo)[1]); // declares void abc(long); + * --- + */ +template ParameterTypeTuple(alias dg) +{ + alias ParameterTypeTuple!(typeof(dg)) ParameterTypeTuple; +} + +/** ditto */ +template ParameterTypeTuple(dg) +{ + static if (is(dg P == function)) + alias P ParameterTypeTuple; + else static if (is(dg P == delegate)) + alias ParameterTypeTuple!(P) ParameterTypeTuple; + else static if (is(dg P == P*)) + alias ParameterTypeTuple!(P) ParameterTypeTuple; + else + static assert(0, "argument has no parameters"); +} + + +/*** + * Get the types of the fields of a struct or class. + * This consists of the fields that take up memory space, + * excluding the hidden fields like the virtual function + * table pointer. + */ + +template FieldTypeTuple(S) +{ + static if (is(S == struct) || is(S == class)) + alias typeof(S.tupleof) FieldTypeTuple; + else + static assert(0, "argument is not struct or class"); } -TypeHolder!(S, T) *IFTI_gen(S, T...)(S delegate(T) dg) { return null; } -TypeHolder!(S, T) *IFTI_gen(S, T...)(S function(T) dg) { return null; } -template ParameterTypeTuple(T) { - alias typeof(IFTI_gen(T.init)._ParameterTypeTuple) ParameterTypeTuple; + + +/*** + * Get a TypeTuple of the base class and base interfaces of + * this class or interface. + * Example: + * --- + * import std.traits, std.typetuple, std.stdio; + * interface I { } + * class A { } + * class B : A, I { } + * + * void main() + * { + * alias BaseTypeTuple!(B) TL; + * writefln(typeid(TL)); // prints: (A,I) + * } + * --- + */ + +template BaseTypeTuple(A) +{ + static if (is(A P == super)) + alias P BaseTypeTuple; + else + static assert(0, "argument is not a class or interface"); +} + +unittest +{ + interface I { } + class A { } + class B : A, I { } + + alias BaseTypeTuple!(B) TL; + assert(TL.length == 2); + assert(is (TL[0] == A)); + assert(is (TL[1] == I)); } -template ReturnType(T) { - alias typeof(IFTI_gen(T.init)._ReturnType) ReturnType; + +/* ******************************************* + */ +template isStaticArray_impl(T) +{ + const T inst = void; + + static if (is(typeof(T.length))) + { + static if (!is(typeof(T) == typeof(T.init))) + { // abuses the fact that int[5].init == int + static if (is(T == typeof(T[0])[inst.length])) + { // sanity check. this check alone isn't enough because dmd complains about dynamic arrays + const bool res = true; + } + else + const bool res = false; + } + else + const bool res = false; + } + else + { + const bool res = false; + } } -template isArray(T) { const bool isArray=false; } -template isArray(T: T[]) { const bool isArray=true; } +/** + * Detect whether type T is a static array. + */ +template isStaticArray(T) +{ + const bool isStaticArray = isStaticArray_impl!(T).res; +} + + +static assert (isStaticArray!(int[51])); +static assert (isStaticArray!(int[][2])); +//static assert (isStaticArray!(char[][int][11])); +static assert (!isStaticArray!(int[])); +//static assert (!isStaticArray!(int[char])); +static assert (!isStaticArray!(int[1][])); + +template isArray(T) +{ + const bool isArray=false; +} +template isArray(T: T[]) +{ + const bool isArray=true; +} + +/** + * Tells whether the tuple T is an expression tuple. + */ +template isExpressionTuple(T ...) +{ + static if (is(void function(T))) + const bool isExpressionTuple = false; + else + const bool isExpressionTuple = true; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/alloca1.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,15 @@ +module alloca1; + +pragma(LLVM_internal, "alloca") +void* alloca(uint); + +void main() +{ + int n = 16; + int* p = cast(int*)alloca(n*int.sizeof); + int[] a = p[0..n]; + a[] = 0; + foreach(i,v; a) { + printf("a[%2d] = %d\n", i, v); + } +}
--- a/test/arrays5.d Thu Nov 08 19:21:05 2007 +0100 +++ b/test/arrays5.d Mon Nov 12 06:32:46 2007 +0100 @@ -1,14 +1,11 @@ module arrays5; -//import std.stdio; void main() { auto arr = new float[5]; - arr[4] = 1f; - //writefln(arr); - assert(arr[0] !<>= 0f); - assert(arr[1] !<>= 0f); - assert(arr[2] !<>= 0f); - assert(arr[3] !<>= 0f); - assert(arr[4] == 1f); + {arr[4] = 1f;} + {assert(arr[0] !<>= 0f);} + {assert(arr[1] !<>= 0f);} + {assert(arr[2] !<>= 0f);} + {assert(arr[3] !<>= 0f);} + {assert(arr[4] == 1f);} } -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug57.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,10 @@ +import std.stdio; +class Foo {} +void func3() +{ + Foo[1] test=[new Foo]; + writefln(test); +} +void main() { + func3(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug58.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,10 @@ +module bug58; +import std.stdio; +void main() +{ + int[16] arr = [1,16,2,15,3,14,4,13,5,12,6,11,7,10,8,9]; + writefln("arr = ",arr); + arr.sort; + writefln("arr.sort = ",arr); + assert(arr == [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug59.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,20 @@ +module bug59; + +void main() +{ + int[2] a = 0; + //func(a); + a[0] = 1; + int i = a[0]; + int* p = &a[0]; +} + +void func(int[2] a) +{ + int* p = cast(int*)a; +} + +void func2(int[4] a) +{ + int* p = 3+cast(int*)a; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug60.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,16 @@ +module bug60; +void func(T...)(T t) +{ + foreach(v;t) { + if (v.length) { + foreach(i;v) { + printf("%d\n", i); + } + } + } +} +void main() +{ + auto a = [1,2,3]; + func(a); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug61.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,26 @@ +module bug61; + +void main() +{ + int[3] a = [42,4,141414]; + printf("empty:\n"); + foreach(v; a[3..$]) { + printf("int = %d\n", v); + } + printf("one element:\n"); + foreach(v; a[2..$]) { + printf("int = %d\n", v); + } + printf("all elements:\n"); + foreach(v; a) { + printf("int = %d\n", v); + } + printf("empty reversed:\n"); + foreach_reverse(v; a[3..$]) { + printf("int = %d\n", v); + } + printf("all elements reversed:\n"); + foreach_reverse(v; a) { + printf("int = %d\n", v); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug62.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,12 @@ +module bug62; + +void main() +{ + int[] arr = [1,2,5,7,9]; + int i = 0; + foreach(v; arr) { + i += v; + } + printf("sum = %d\n", i); + assert(i == 24); +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/bug64.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,10 @@ +module bug64; + +void main() +{ + float f; + float* p = &f; + float* end1 = p+1; + float* end2 = 1+p; + assert(end1 is end2); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/fail2.d Mon Nov 12 06:32:46 2007 +0100 @@ -0,0 +1,27 @@ +module fail2; + +void a() +{ + b(); +} + +void b() +{ + c(); +} + +void c() +{ + d(); +} + +void d() +{ + int* ip; + int i = *ip; +} + +void main() +{ + a(); +}
--- a/test/multiarr1.d Thu Nov 08 19:21:05 2007 +0100 +++ b/test/multiarr1.d Mon Nov 12 06:32:46 2007 +0100 @@ -4,7 +4,11 @@ { int[16][16] a; a[10][13] = 42; - assert(a[0][0] == 0); - assert(a[10][13] == 42); - {assert(*((cast(int*)a)+10*16+13) == 42);} + //assert(a[0][0] == 0); + //assert(a[10][13] == 42); + { + int* l = cast(int*)a; + l += 10*16+13; + assert(*l == 42); + } }
--- a/test/ray.d Thu Nov 08 19:21:05 2007 +0100 +++ b/test/ray.d Mon Nov 12 06:32:46 2007 +0100 @@ -91,7 +91,8 @@ Scene create(int level, ref Vec c, double r) { auto s = new Sphere(c, r); if (level == 1) return s; - Scene[] children=[s]; + Scene[] children; + children ~= s; double rn = 3*r/sqrt(12.0); for (int dz=-1; dz<=1; dz+=2) for (int dx=-1; dx<=1; dx+=2)