Started work on phobos

This commit is contained in:
Alexey Prokhin
2010-10-27 18:13:46 +04:00
parent eb68fc3d8c
commit b1e5993873
22 changed files with 265 additions and 85 deletions

View File

@@ -525,7 +525,7 @@ void AliasDeclaration::semantic(Scope *sc)
{
FuncAliasDeclaration *fa = new FuncAliasDeclaration(f);
#if IN_LLVM
fa->importprot = importprot;
fa->importprot = importprot;
#endif
if (!fa->overloadInsert(overnext))
ScopeDsymbol::multiplyDefined(0, f, overnext);

View File

@@ -6454,8 +6454,12 @@ Expression *DelegateExp::semantic(Scope *sc)
{
m = sc->module;
e1 = e1->semantic(sc);
// LDC we need a copy as we store the LLVM tpye in TypeFunction, and delegate/members have different types for 'this'
type = new TypeDelegate(func->type->syntaxCopy());
#if IN_LLVM
// LDC we need a copy as we store the LLVM type in TypeFunction, and delegate/members have different types for 'this'
type = new TypeDelegate(func->type->syntaxCopy());
#else
type = new TypeDelegate(func->type);
#endif
type = type->semantic(loc, sc);
AggregateDeclaration *ad = func->toParent()->isAggregateDeclaration();
if (func->needThis())
@@ -7416,7 +7420,7 @@ Expression *AddrExp::semantic(Scope *sc)
if (f)
{
#if !IN_LLVM
#if IN_LLVM
if (f->isIntrinsic())
{
error("cannot take the address of intrinsic function %s", e1->toChars());

View File

@@ -1124,6 +1124,7 @@ struct CallExp : UnaExp
#if IN_LLVM
DValue* toElem(IRState* irs);
void cacheLvalue(IRState* irs);
#endif
};

View File

@@ -880,8 +880,8 @@ void FuncDeclaration::semantic3(Scope *sc)
#if !IN_LLVM
sc2->tf = NULL;
#else
sc2->enclosingFinally = NULL;
sc2->enclosingScopeExit = NULL;
sc2->enclosingFinally = NULL;
sc2->enclosingScopeExit = NULL;
#endif
sc2->noctor = 0;
@@ -1012,7 +1012,7 @@ void FuncDeclaration::semantic3(Scope *sc)
if (f->parameters)
{
for (size_t i = 0; i < Parameter::dim(f->parameters); i++)
{ Parameter *arg = (Parameter *)Parameter::getNth(f->parameters, i);
{ Parameter *arg = (Parameter *)Parameter::getNth(f->parameters, i);
Type* nw = arg->type->semantic(0, sc);
if (arg->type != nw) {
arg->type = nw;

View File

@@ -1252,12 +1252,10 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d)
if (v)
{
#if DMDV2
#if !IN_LLVM // TODO:
/* Magic variable __ctfe always returns true when interpreting
*/
if (v->ident == Id::ctfe)
return new IntegerExp(loc, 1, Type::tbool);
#endif
if ((v->isConst() || v->isImmutable() || v->storage_class & STCmanifest) && v->init && !v->value)
#else
if (v->isConst() && v->init)

View File

@@ -114,7 +114,7 @@ char *Declaration::mangle()
break;
#if IN_LLVM
case LINKintrinsic:
case LINKintrinsic:
#endif
case LINKc:
case LINKwindows:

View File

@@ -1538,7 +1538,7 @@ Type *Type::merge()
//if (next)
//next = next->merge();
toDecoBuffer(&buf, false);
toDecoBuffer(&buf, 0, false);
sv = stringtable.update((char *)buf.data, buf.offset);
if (sv->ptrvalue)
{ t = (Type *) sv->ptrvalue;
@@ -1557,7 +1557,7 @@ Type *Type::merge()
// or Type::equals fails, which breaks a bunch of stuff,
// like covariant member function overloads.
OutBuffer mangle;
toDecoBuffer(&mangle, true);
toDecoBuffer(&mangle, 0, true);
StringValue* sv2 = deco_stringtable.update((char *)mangle.data, mangle.offset);
if (sv2->ptrvalue)
{ Type* t2 = (Type *) sv2->ptrvalue;
@@ -1986,7 +1986,7 @@ Identifier *Type::getTypeInfoIdent(int internal)
buf.writeByte(mangleChar[((TypeArray *)this)->next->ty]);
}
else
toDecoBuffer(&buf, true);
toDecoBuffer(&buf, 0, true);
len = buf.offset;
name = (char *)alloca(19 + sizeof(len) * 3 + len + 1);
buf.writeByte(0);

View File

@@ -557,9 +557,6 @@ Expression *CastExp::optimize(int result)
e1->type->nextOf()->size() == type->nextOf()->size()
)
{
// LDC make a copy before adjusting type to avoid
// messing up the type of an existing initializer
e1 = e1->syntaxCopy();
Expression *e = e1->castTo(NULL, type);
if (X) printf(" returning1 %s\n", e->toChars());
return e;

View File

@@ -1849,39 +1849,39 @@ Lagain:
/* Call:
* _aaApply(aggr, keysize, flde)
*/
//LDC: Build arguments.
static FuncDeclaration *aaApply2_fd = NULL;
static TypeDelegate* aaApply2_dg;
if(!aaApply2_fd) {
Parameters* args = new Parameters;
args->push(new Parameter(STCin, Type::tvoid->pointerTo(), NULL, NULL));
args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL));
Parameters* dgargs = new Parameters;
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
aaApply2_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
args->push(new Parameter(STCin, aaApply2_dg, NULL, NULL));
aaApply2_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply2");
}
static FuncDeclaration *aaApply_fd = NULL;
static TypeDelegate* aaApply_dg;
if(!aaApply_fd) {
Parameters* args = new Parameters;
args->push(new Parameter(STCin, Type::tvoid->pointerTo(), NULL, NULL));
args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL));
Parameters* dgargs = new Parameters;
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
aaApply_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
args->push(new Parameter(STCin, aaApply_dg, NULL, NULL));
aaApply_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply");
}
if (dim == 2) {
fdapply = aaApply2_fd;
fldeTy = aaApply2_dg;
} else {
fdapply = aaApply_fd;
fldeTy = aaApply_dg;
}
//LDC: Build arguments.
static FuncDeclaration *aaApply2_fd = NULL;
static TypeDelegate* aaApply2_dg;
if(!aaApply2_fd) {
Parameters* args = new Parameters;
args->push(new Parameter(STCin, Type::tvoid->pointerTo(), NULL, NULL));
args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL));
Parameters* dgargs = new Parameters;
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
aaApply2_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
args->push(new Parameter(STCin, aaApply2_dg, NULL, NULL));
aaApply2_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply2");
}
static FuncDeclaration *aaApply_fd = NULL;
static TypeDelegate* aaApply_dg;
if(!aaApply_fd) {
Parameters* args = new Parameters;
args->push(new Parameter(STCin, Type::tvoid->pointerTo(), NULL, NULL));
args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL));
Parameters* dgargs = new Parameters;
dgargs->push(new Parameter(STCin, Type::tvoidptr, NULL, NULL));
aaApply_dg = new TypeDelegate(new TypeFunction(dgargs, Type::tindex, 0, LINKd));
args->push(new Parameter(STCin, aaApply_dg, NULL, NULL));
aaApply_fd = FuncDeclaration::genCfunc(args, Type::tindex, "_aaApply");
}
if (dim == 2) {
fdapply = aaApply2_fd;
fldeTy = aaApply2_dg;
} else {
fdapply = aaApply_fd;
fldeTy = aaApply_dg;
}
ec = new VarExp(0, fdapply);
Expressions *exps = new Expressions();
exps->push(aggr);
@@ -1890,12 +1890,12 @@ Lagain:
exps->push(new IntegerExp(0, keysize, Type::tsize_t));
#if IN_LLVM
// LDC paint delegate argument to the type runtime expects
if (!fldeTy->equals(flde->type))
{
flde = new CastExp(loc, flde, flde->type);
flde->type = fldeTy;
}
// LDC paint delegate argument to the type runtime expects
if (!fldeTy->equals(flde->type))
{
flde = new CastExp(loc, flde, flde->type);
flde->type = fldeTy;
}
#endif
exps->push(flde);
e = new CallExp(loc, ec, exps);

View File

@@ -151,6 +151,10 @@ struct X86TargetABI : TargetABI
bool returnInArg(TypeFunction* tf)
{
#if DMDV2
if (tf->isref)
return false;
#endif
Type* rt = tf->next->toBasetype();
// D only returns structs on the stack
if (tf->linkage == LINKd)
@@ -287,6 +291,10 @@ struct UnknownTargetABI : TargetABI
{
bool returnInArg(TypeFunction* tf)
{
#if DMDV2
if (tf->isref)
return false;
#endif
return (tf->next->toBasetype()->ty == Tstruct);
}

View File

@@ -804,6 +804,29 @@ DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2)
}
}
//////////////////////////////////////////////////////////////////////////////////////////
DSliceValue* DtoAppendDChar(DValue* arr, Expression* exp)
{
Logger::println("DtoCatAssignArray");
LOG_SCOPE;
Type *arrayType = arr->getType();
DValue* valueToAppend = exp->toElem(gIR);
// Prepare arguments
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcd");
LLSmallVector<LLValue*,2> args;
// ref char[] x
args.push_back(DtoBitCast(arr->getLVal(), fn->getFunctionType()->getParamType(0)));
// dchar c
args.push_back(DtoBitCast(valueToAppend->getRVal(), fn->getFunctionType()->getParamType(1)));
// Call _d_arrayappendcd
LLValue* newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction();
return getSlice(arrayType, newArray);
}
//////////////////////////////////////////////////////////////////////////////////////////
// helper for eq and cmp
static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue* r, bool useti)
@@ -1127,14 +1150,11 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to)
LLConstant* nul = getNullPtr(ptr->getType());
rval = gIR->ir->CreateICmpNE(ptr, nul, "tmp");
}
else if (fromtype->nextOf()->ty == Tvoid) {
// TODO:
else {
rval = DtoArrayPtr(u);
rval = DtoBitCast(rval, getPtrToType(tolltype));
rval = DtoLoad(rval);
}
else {
assert(0);
if (totype->ty != Tstruct)
rval = DtoLoad(rval);
}
if (isslice) {

View File

@@ -28,6 +28,7 @@ void DtoCatAssignElement(Loc& loc, Type* type, DValue* arr, Expression* exp);
DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp);
DSliceValue* DtoCatArrays(Type* type, Expression* e1, Expression* e2);
DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2);
DSliceValue* DtoAppendDChar(DValue* arr, Expression* exp);
void DtoStaticArrayCopy(LLValue* dst, LLValue* src);

View File

@@ -64,11 +64,21 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest
lidx++;
}
// sext/zext return
else if (unsigned se = DtoShouldExtend(rt))
else
{
a = se;
Type *t = rt;
#if DMDV2
if (f->isref)
t = t->pointerTo();
#endif
if (unsigned se = DtoShouldExtend(t))
a = se;
}
#if DMDV2
fty.ret = new IrFuncTyArg(rt, f->isref, a);
#else
fty.ret = new IrFuncTyArg(rt, false, a);
#endif
}
lidx++;
@@ -146,6 +156,9 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest
TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd);
TypeDelegate *ltd = new TypeDelegate(ltf);
argtype = ltd;
#if DMDV2
byref = byref && arg->type->toBasetype()->ty != Tsarray;
#endif
}
// byval
else if (abi->passByVal(byref ? argtype->pointerTo() : argtype))

View File

@@ -767,7 +767,7 @@ DValue* DtoPaintType(Loc& loc, DValue* val, Type* to)
}
else
{
assert(!val->isLVal());
// assert(!val->isLVal()); TODO: what is it needed for?
assert(DtoType(to) == DtoType(to));
return new DImValue(to, val->getRVal());
}
@@ -912,7 +912,17 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
assert(ex->exp);
AssignExp* as = ex->exp->isAssignExp();
assert(as && "ref vars must be initialized by an assign exp");
vd->ir.irLocal->value = as->e2->toElem(gIR)->getLVal();
DValue *val = as->e2->toElem(gIR);
if (val->isLVal())
{
vd->ir.irLocal->value = val->getLVal();
}
else
{
LLValue *newVal = DtoAlloca(val->type);
DtoStore(val->getRVal(), newVal);
vd->ir.irLocal->value = newVal;
}
}
// referenced by nested delegate?
@@ -1033,6 +1043,12 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
DtoDeclarationExp(exp->s);
}
}
// template
else if (TemplateDeclaration* t = declaration->isTemplateDeclaration())
{
Logger::println("TemplateDeclaration");
// do nothing
}
// unsupported declaration
else
{
@@ -1223,8 +1239,13 @@ static LLConstant* expand_to_sarray(Type *base, Expression* exp)
LLConstant* DtoConstExpInit(Loc loc, Type* type, Expression* exp)
{
#if DMDV2
Type* expbase = exp->type->toBasetype()->mutableOf()->merge();
Type* base = type->toBasetype()->mutableOf()->merge();
#else
Type* expbase = exp->type->toBasetype();
Type* base = type->toBasetype();
#endif
// if not the same basetypes, we won't get the same llvm types either
if (!expbase->equals(base))
@@ -1240,7 +1261,7 @@ LLConstant* DtoConstExpInit(Loc loc, Type* type, Expression* exp)
}
else
{
error("cannot yet convert default initializer %s to type %s to %s", exp->toChars(), exp->type->toChars(), type->toChars());
error("cannot yet convert default initializer %s of type %s to %s", exp->toChars(), exp->type->toChars(), type->toChars());
fatal();
}
assert(0);
@@ -1504,6 +1525,8 @@ size_t realignOffset(size_t offset, Type* type)
Type * stripModifiers( Type * type )
{
#if DMDV2
if (type->ty == Tfunction)
return type;
Type *t = type;
while (t->mod)
{

View File

@@ -534,6 +534,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
}
} else if (FuncDeclaration* parFunc = getParentFunc(fd, true)) {
// Propagate context arg properties if the context arg is passed on unmodified.
DtoDeclareFunction(parFunc);
fd->ir.irFunc->frameType = parFunc->ir.irFunc->frameType;
fd->ir.irFunc->depth = parFunc->ir.irFunc->depth;
}

View File

@@ -381,7 +381,15 @@ static void LLVM_D_BuildRuntimeModule()
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
// void[] _d_arrayappendcd(ref char[] x, dchar c)
{
llvm::StringRef fname("_d_arrayappendcd");
std::vector<const LLType*> types;
types.push_back(getPtrToType(stringTy));
types.push_back(intTy);
const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false);
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
}
// byte[] _d_arraycatT(TypeInfo ti, byte[] x, byte[] y)
{
llvm::StringRef fname("_d_arraycatT");

View File

@@ -97,17 +97,29 @@ void ReturnStatement::toIR(IRState* p)
v = LLConstant::getNullValue(p->mainFunc->getReturnType());
else
// do abi specific transformations on the return value
#if DMDV2
v = p->func()->type->fty.putRet(exp->type, exp->toElem(p), p->func()->type->isref);
#else
v = p->func()->type->fty.putRet(exp->type, exp->toElem(p));
#endif
if (Logger::enabled())
Logger::cout() << "return value is '" <<*v << "'\n";
IrFunction* f = p->func();
// Hack around LDC assuming structs are in memory:
// If the function returns a struct, and the return value is a
// pointer to a struct, load from it before returning.
if (f->type->next->ty == Tstruct && isaPointer(v->getType())) {
Logger::println("Loading struct type for return");
// Hack around LDC assuming structs and static arrays are in memory:
// If the function returns a struct or a static array, and the return
// value is a pointer to a struct or a static array, load from it
// before returning.
int ty = f->type->next->ty;
if (v->getType() != p->topfunc()->getReturnType() &&
(ty == Tstruct
#if DMDV2
|| ty == Tsarray
#endif
) && isaPointer(v->getType()))
{
Logger::println("Loading value for return");
v = DtoLoad(v);
}

View File

@@ -551,10 +551,17 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
retllval = tf->fty.getRet(tf->next, &dretval);
}
// Hack around LDC assuming structs are in memory:
// If the function returns a struct, and the return value is not a
// pointer to a struct, store it to a stack slot before continuing.
if (tf->next->ty == Tstruct && !isaPointer(retllval)) {
// Hack around LDC assuming structs and static arrays are in memory:
// If the function returns a struct or a static array, and the return
// value is not a pointer to a struct or a static array, store it to
// a stack slot before continuing.
int ty = tf->next->ty;
if ((ty == Tstruct && !isaPointer(retllval))
#if DMDV2
|| (ty == Tsarray && isaArray(retllval))
#endif
)
{
Logger::println("Storing return value to stack slot");
LLValue* mem = DtoRawAlloca(retllval->getType(), 0);
DtoStore(retllval, mem);
@@ -608,8 +615,13 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
call.setAttributes(attrlist);
// if we are returning through a pointer arg
// or if we are returning a reference
// make sure we provide a lvalue back!
if (retinptr)
if (retinptr
#if DMDV2
|| tf->isref
#endif
)
return new DVarValue(resulttype, retllval);
return new DImValue(resulttype, retllval);

View File

@@ -92,6 +92,14 @@ DValue* VarExp::toElem(IRState* p)
{
Logger::println("VarDeclaration ' %s ' of type ' %s '", vd->toChars(), vd->type->toChars());
#if DMDV2
/* The magic variable __ctfe is always false at runtime
*/
if (vd->ident == Id::ctfe) {
return new DConstValue(type, DtoConstBool(false));
}
#endif
// this is an error! must be accessed with DotVarExp
if (var->needThis())
{
@@ -763,6 +771,15 @@ DValue* ModExp::toElem(IRState* p)
//////////////////////////////////////////////////////////////////////////////////////////
void CallExp::cacheLvalue(IRState* p)
{
Logger::println("Caching l-value of %s", toChars());
LOG_SCOPE;
cachedLvalue = toElem(p)->getLVal();
}
//////////////////////////////////////////////////////////////////////////////////////////
DValue* CallExp::toElem(IRState* p)
{
Logger::print("CallExp::toElem: %s @ %s\n", toChars(), type->toChars());
@@ -823,7 +840,6 @@ DValue* CallExp::toElem(IRState* p)
return new DImValue(type, p->ir->CreateAlloca(LLType::getInt8Ty(gIR->context()), expv->getRVal(), ".alloca"));
}
}
return DtoCallFunction(loc, type, fnval, arguments);
}
@@ -1439,6 +1455,10 @@ DValue* CmpExp::toElem(IRState* p)
Logger::println("static or dynamic array");
eval = DtoArrayCompare(loc,op,l,r);
}
else if (t->ty == Taarray)
{
eval = LLConstantInt::getFalse(gIR->context());
}
else
{
assert(0 && "Unsupported CmpExp type");
@@ -1804,8 +1824,10 @@ DValue* AssertExp::toElem(IRState* p)
p->scope() = IRScope(endbb,oldend);
}
// no meaningful return value
return NULL;
// DMD allows syntax like this:
// f() == 0 || assert(false)
// TODO: or should we return true?
return new DImValue(type, DtoConstBool(false));
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2239,8 +2261,15 @@ DValue* CatAssignExp::toElem(IRState* p)
DSliceValue* slice = DtoCatAssignArray(l,e2);
DtoAssign(loc, l, slice);
}
else
else if (elemtype->ty == Tchar) {
if (e2type->ty == Tdchar)
DtoAppendDChar(l, e2);
else
assert(0 && "cannot append the element to a string");
}
else {
assert(0 && "only one element at a time right now");
}
return l;
}
@@ -2632,10 +2661,31 @@ DValue* TypeExp::toElem(IRState *p)
//////////////////////////////////////////////////////////////////////////////////////////
DValue* TupleExp::toElem(IRState *p)
{
Logger::print("TupleExp::toElem() %s\n", toChars());
std::vector<const LLType*> types(exps->dim, NULL);
for (size_t i = 0; i < exps->dim; i++)
{
Expression *el = (Expression *)exps->data[i];
DValue* ep = el->toElem(p);
types[i] = ep->getRVal()->getType();
}
LLValue *val = DtoRawAlloca(LLStructType::get(gIR->context(), types),0, "tuple");
for (size_t i = 0; i < exps->dim; i++)
{
Expression *el = (Expression *)exps->data[i];
DValue* ep = el->toElem(p);
DtoStore(ep->getRVal(), DtoGEPi(val,0,i));
}
return new DImValue(type, val);
}
//////////////////////////////////////////////////////////////////////////////////////////
#define STUB(x) DValue *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; }
STUB(Expression);
STUB(ScopeExp);
STUB(TupleExp);
#if DMDV2
STUB(SymbolExp);

View File

@@ -30,7 +30,7 @@ bool IrFuncTyArg::isByVal() const { return (attrs & llvm::Attribute::ByVal) != 0
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
llvm::Value* IrFuncTy::putRet(Type* dty, DValue* val)
llvm::Value* IrFuncTy::putRet(Type* dty, DValue* val, bool isref)
{
assert(!arg_sret);
if (ret->rewrite) {
@@ -38,7 +38,7 @@ llvm::Value* IrFuncTy::putRet(Type* dty, DValue* val)
LOG_SCOPE
return ret->rewrite->put(dty, val);
}
return val->getRVal();
return isref ? val->getLVal() : val->getRVal();
}
llvm::Value* IrFuncTy::getRet(Type* dty, DValue* val)

View File

@@ -101,7 +101,7 @@ struct IrFuncTy : IrBase
reverseParams = false;
}
llvm::Value* putRet(Type* dty, DValue* dval);
llvm::Value* putRet(Type* dty, DValue* dval, bool isref = false);
llvm::Value* getRet(Type* dty, DValue* dval);
llvm::Value* putParam(Type* dty, int idx, DValue* dval);

View File

@@ -75,6 +75,29 @@ elseif(D_VERSION EQUAL 2)
${RUNTIME_DIR}/src/core/stdc/stdarg.d
)
file(GLOB CORE_C ${RUNTIME_DIR}/src/core/stdc/*.c)
if(PHOBOS2_DIR)
file(GLOB PHOBOS2_D ${PHOBOS2_DIR}/std/*.d)
file(GLOB PHOBOS2_D_MATH ${PHOBOS2_DIR}/std/internal/math/*.d)
file(GLOB PHOBOS2_D_C ${PHOBOS2_DIR}/std/c/*.d)
if(UNIX)
file(GLOB PHOBOS2_D_C_SYS ${PHOBOS2_DIR}/std/c/linux/*.d)
elseif(WIN32)
file(GLOB PHOBOS2_D_C_SYS ${PHOBOS2_DIR}/std/c/windows/*.d)
elseif(APPLE)
file(GLOB PHOBOS2_D_C_SYS ${PHOBOS2_DIR}/std/c/osx/*.d)
endif(UNIX)
file(GLOB ZLIB_C ${PHOBOS2_DIR}/etc/c/zlib/*.c)
list(REMOVE_ITEM ZLIB_C
${PHOBOS2_DIR}/etc/c/zlib/minigzip.c
${PHOBOS2_DIR}/etc/c/zlib/example.c
)
if(WIN32)
file(GLOB PHOBOS2_D_WIN ${PHOBOS2_DIR}/std/windows/*.d)
endif(WIN32)
list(APPEND PHOBOS2_D ${PHOBOS2_D_MATH} ${PHOBOS2_D_WIN}
${PHOBOS2_D_C} ${PHOBOS2_D_C_SYS})
endif(PHOBOS2_DIR)
endif(D_VERSION EQUAL 1)
# should only be necessary if run independently from ldc cmake project
@@ -212,3 +235,12 @@ set_target_properties(
# BCLIBS is empty if BUILD_BC_LIBS is not selected
add_custom_target(runtime DEPENDS ${LIBS} ${BCLIBS})
if(PHOBOS2_DIR)
foreach(f ${PHOBOS2_D})
dc(${f} PHOBOS2_O PHOBOS2_BC ${RUNTIME_DIR}/src/ "-I${PHOBOS2_DIR}" ${PHOBOS2_DIR})
endforeach(f)
add_library(phobos2 ${ZLIB_C} ${PHOBOS2_O})
add_dependencies(phobos2 runtime)
endif(PHOBOS2_DIR)