[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.
This commit is contained in:
Tomas Lindquist Olsen
2007-11-12 06:32:46 +01:00
parent b32e04cacd
commit 3b4c818082
46 changed files with 2817 additions and 254 deletions

96
demos/ray.d Normal file
View File

@@ -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)));
}
}

View File

@@ -879,6 +879,10 @@ void PragmaDeclaration::semantic(Scope *sc)
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 @@ void PragmaDeclaration::semantic(Scope *sc)
case LLVMva_arg:
case LLVMva_start:
case LLVMnotypeinfo:
case LLVMalloca:
break;
default:
@@ -960,6 +965,16 @@ void PragmaDeclaration::semantic(Scope *sc)
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 :/");
}

View File

@@ -1116,7 +1116,7 @@ Expression *BinExp::scaleFactor(Scope *sc)
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 @@ Expression *BinExp::scaleFactor(Scope *sc)
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;

View File

@@ -159,6 +159,9 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
bcfile = new File(bcfilename);
llfile = new File(llfilename);
symfile = new File(symfilename);
// LLVMDC
llvmCompileUnit = 0;
}
void Module::setDocfile()

View File

@@ -29,6 +29,7 @@ struct VarDeclaration;
#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 @@ struct Module : Package
Symbol *toSymbol();
void genmoduleinfo();
// LLVMDC
llvm::GlobalVariable* llvmCompileUnit;
Module *isModule() { return this; }
};

View File

@@ -1514,6 +1514,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
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 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
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 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
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();

View File

@@ -209,6 +209,7 @@ Expression *AddrExp::optimize(int result)
}
return e;
}
#if !IN_LLVM
if (e1->op == TOKvar)
{ VarExp *ve = (VarExp *)e1;
if (!ve->var->isOut() && !ve->var->isRef() &&
@@ -240,6 +241,7 @@ Expression *AddrExp::optimize(int result)
}
}
}
#endif
return this;
}

View File

@@ -21,14 +21,6 @@ const llvm::StructType* DtoArrayType(Type* t)
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* DtoDynArrayCompare(TOK op, llvm::Value* l, llvm::Value* r)
//////////////////////////////////////////////////////////////////////////////////////////
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 @@ llvm::Value* DtoArrayLen(DValue* v)
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);

View File

@@ -5,5 +5,6 @@ enum
LLVMva_arg,
LLVMva_start,
LLVMva_intrinsic,
LLVMnotypeinfo
LLVMnotypeinfo,
LLVMalloca
};

View File

@@ -38,7 +38,6 @@ IRState::IRState()
emitMain = false;
mainFunc = 0;
ir.state = this;
dwarfCompileUnit = 0;
}
IRFunction& IRState::func()

View File

@@ -162,9 +162,6 @@ struct IRState
// builder helper
IRBuilderHelper ir;
// Dwarf debugging info
llvm::GlobalVariable* dwarfCompileUnit;
};
#endif // LLVMDC_GEN_IRSTATE_H

View File

@@ -62,5 +62,13 @@ namespace Logger
{
enabled = false;
}
void attention(const char* fmt,...)
{
printf("***ATTENTION*** ");
va_list va;
va_start(va,fmt);
vprintf(fmt,va);
va_end(va);
printf("\n");
}
}

View File

@@ -12,14 +12,14 @@ namespace Logger
void print(const char* fmt, ...);
void enable();
void disable();
void attention(const char* fmt, ...);
struct LoggerScope
{
LoggerScope()
{
Logger::indent();
}
~LoggerScope()
{

View File

@@ -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 @@ void CompoundStatement::toIR(IRState* p)
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 @@ void ExpStatement::toIR(IRState* p)
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 @@ void WhileStatement::toIR(IRState* p)
// 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 @@ void DoStatement::toIR(IRState* p)
// 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 ForStatement::toIR(IRState* p)
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 BreakStatement::toIR(IRState* p)
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 ContinueStatement::toIR(IRState* p)
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 @@ void OnScopeStatement::toIR(IRState* p)
//////////////////////////////////////////////////////////////////////////////
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 @@ void TryCatchStatement::toIR(IRState* p)
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 @@ void ThrowStatement::toIR(IRState* p)
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 @@ void ForeachStatement::toIR(IRState* p)
//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 @@ void ForeachStatement::toIR(IRState* p)
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());
// condition
p->scope() = IRScope(condbb,bodybb);
// next
p->scope() = IRScope(nexbb,begbb);
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 @@ void ForeachStatement::toIR(IRState* p)
}
// 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 WithStatement::toIR(IRState* p)
//////////////////////////////////////////////////////////////////////////////
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);

View File

@@ -56,7 +56,7 @@ const llvm::StructType* GetDwarfAnchorType()
*/
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 @@ const llvm::StructType* GetDwarfAnchorType()
}
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 @@ const llvm::StructType* GetDwarfAnchorType()
}
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 @@ const llvm::StructType* GetDwarfSubProgramType() {
//////////////////////////////////////////////////////////////////////////////////////////////////
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 @@ llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd)
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 @@ void DtoDwarfStopPoint(unsigned ln)
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());
}

View File

@@ -7,8 +7,8 @@ const llvm::StructType* GetDwarfAnchorType();
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);

View File

@@ -66,9 +66,7 @@ DValue* DeclarationExp::toElem(IRState* p)
//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 @@ DValue* AssignExp::toElem(IRState* p)
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 @@ DValue* AddExp::toElem(IRState* p)
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* MinExp::toElem(IRState* p)
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 @@ DValue* CallExp::toElem(IRState* p)
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 @@ DValue* SymOffExp::toElem(IRState* p)
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 @@ DValue* SymOffExp::toElem(IRState* p)
}
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* ThisExp::toElem(IRState* p)
//////////////////////////////////////////////////////////////////////////////////////////
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 @@ DValue* SliceExp::toElem(IRState* p)
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 @@ DValue* NewExp::toElem(IRState* p)
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 @@ DValue* NewExp::toElem(IRState* p)
}
}
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* AssertExp::toElem(IRState* p)
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 @@ DValue* HaltExp::toElem(IRState* p)
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 @@ DValue* FuncExp::toElem(IRState* p)
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 @@ DValue* FuncExp::toElem(IRState* p)
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 @@ void obj_includelib(char*){}
AsmStatement::AsmStatement(Loc loc, Token *tokens) :
Statement(loc)
{
assert(0);
Logger::println("Ignoring AsmStatement");
}
Statement *AsmStatement::syntaxCopy()
{

View File

@@ -797,15 +797,13 @@ llvm::Constant* DtoConstInitializer(Type* type, Initializer* init)
//////////////////////////////////////////////////////////////////////////////////////////
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 @@ llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* n)
//////////////////////////////////////////////////////////////////////////////////////////
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 @@ void DtoAssign(DValue* lhs, DValue* rhs)
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 @@ llvm::Value* DtoBitCast(llvm::Value* v, const llvm::Type* t)
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 @@ void DtoLazyStaticInit(bool istempl, llvm::Value* gvar, Initializer* init, Type*
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);

View File

@@ -34,7 +34,7 @@ void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance);
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* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::stri
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 @@ llvm::Value* DtoLoad(llvm::Value* src);
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);

View File

@@ -81,7 +81,7 @@ Module::genobjfile()
// 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 @@ void Module::genmoduleinfo()
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 @@ void FuncDeclaration::toObjFile()
}
if (isUnitTestDeclaration()) {
Logger::println("*** ATTENTION: ignoring unittest declaration: %s", toChars());
Logger::attention("ignoring unittest declaration: %s", toChars());
return;
}
@@ -948,7 +948,11 @@ void FuncDeclaration::toObjFile()
// 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 @@ void FuncDeclaration::toObjFile()
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);
}
}

380
llvmdc.kdevelop Normal file
View File

@@ -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>

419
llvmdc.kdevelop.filelist Normal file
View File

@@ -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

View File

@@ -35,10 +35,21 @@ llvmdc internal/aApply.d -c -odobj || exit 1
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

107
lphobos/gc/gclinux.d Normal file
View File

@@ -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;
}

213
lphobos/gc/gcstub.d Normal file
View File

@@ -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");
}
}

803
lphobos/internal/adi.d Normal file
View File

@@ -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);
}
}

View File

@@ -143,11 +143,3 @@ void _d_main_args(uint n, char** args, ref char[][] res)
res[i] = v[0 .. strlen(v)];
}
}

View File

@@ -4,10 +4,10 @@ extern(C):
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);
}
}

68
lphobos/internal/qsort2.d Normal file
View File

@@ -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]);
}
}

View File

@@ -42,6 +42,7 @@ struct lldiv_t { long quot,rem; }
int system(char *);
pragma(LLVM_internal, "alloca")
void *alloca(uint); ///
void *calloc(size_t, size_t); ///

View File

@@ -3,23 +3,42 @@ module std.stdio;
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');
}

View File

@@ -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;
}
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;
/** ditto */
template ReturnType(dg)
{
static if (is(dg R == return))
alias R ReturnType;
else
static assert(0, "argument has no return type");
}
template ReturnType(T) {
alias typeof(IFTI_gen(T.init)._ReturnType) ReturnType;
/***
* 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");
}
/***
* 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 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;
}
}
/**
* 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;
}
template isArray(T) { const bool isArray=false; }
template isArray(T: T[]) { const bool isArray=true; }

15
test/alloca1.d Normal file
View File

@@ -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);
}
}

View File

@@ -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);}
}

10
test/bug57.d Normal file
View File

@@ -0,0 +1,10 @@
import std.stdio;
class Foo {}
void func3()
{
Foo[1] test=[new Foo];
writefln(test);
}
void main() {
func3();
}

10
test/bug58.d Normal file
View File

@@ -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]);
}

20
test/bug59.d Normal file
View File

@@ -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;
}

16
test/bug60.d Normal file
View File

@@ -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);
}

26
test/bug61.d Normal file
View File

@@ -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);
}
}

12
test/bug62.d Normal file
View File

@@ -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);
}

10
test/bug64.d Normal file
View File

@@ -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);
}

27
test/fail2.d Normal file
View File

@@ -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();
}

View File

@@ -4,7 +4,11 @@ void main()
{
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);
}
}

View File

@@ -91,7 +91,8 @@ double ray_trace(ref Vec light, ref Ray ray, Scene s) {
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)

8
test/sync1.d Normal file
View File

@@ -0,0 +1,8 @@
module sync1;
void main()
{
int i;
int j;
synchronized j = i;
}

View File

@@ -12,6 +12,8 @@ U u;
void main()
{
assert(u.f !<>= 0);
uint* p = 1 + cast(uint*)&u.l;
assert(*p == 0);
{
uint* p = 1 + cast(uint*)&u;
{assert(*p == 0);}
}
}