mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-12 22:14:54 +03:00
Different fixes for d2
This commit is contained in:
parent
df87607ba2
commit
4d7a6eda23
35 changed files with 443 additions and 241 deletions
|
@ -168,6 +168,7 @@ set_source_files_properties(
|
||||||
|
|
||||||
file(GLOB FE_SRC ${DMDFE_PATH}/*.c)
|
file(GLOB FE_SRC ${DMDFE_PATH}/*.c)
|
||||||
file(GLOB FE_SRC_ROOT ${DMDFE_PATH}/root/*.c)
|
file(GLOB FE_SRC_ROOT ${DMDFE_PATH}/root/*.c)
|
||||||
|
file(GLOB_RECURSE GEN_HDR gen/*.h)
|
||||||
file(GLOB_RECURSE GEN_SRC gen/*.cpp)
|
file(GLOB_RECURSE GEN_SRC gen/*.cpp)
|
||||||
file(GLOB IR_SRC ir/*.cpp)
|
file(GLOB IR_SRC ir/*.cpp)
|
||||||
# exclude idgen and impcnvgen and generated sources, just in case
|
# exclude idgen and impcnvgen and generated sources, just in case
|
||||||
|
@ -182,6 +183,7 @@ set(LDC_SOURCE_FILES
|
||||||
${FE_SRC}
|
${FE_SRC}
|
||||||
${FE_SRC_ROOT}
|
${FE_SRC_ROOT}
|
||||||
${GEN_SRC}
|
${GEN_SRC}
|
||||||
|
${GEN_HDR}
|
||||||
${IR_SRC}
|
${IR_SRC}
|
||||||
)
|
)
|
||||||
set_source_files_properties(
|
set_source_files_properties(
|
||||||
|
|
|
@ -41,6 +41,7 @@ struct VarDeclaration;
|
||||||
struct dt_t;
|
struct dt_t;
|
||||||
|
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
|
class ClassInfoDeclaration;
|
||||||
namespace llvm
|
namespace llvm
|
||||||
{
|
{
|
||||||
class Type;
|
class Type;
|
||||||
|
@ -251,7 +252,6 @@ struct ClassDeclaration : AggregateDeclaration
|
||||||
|
|
||||||
BaseClasses *vtblInterfaces; // array of base interfaces that have
|
BaseClasses *vtblInterfaces; // array of base interfaces that have
|
||||||
// their own vtbl[]
|
// their own vtbl[]
|
||||||
|
|
||||||
TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
||||||
int com; // !=0 if this is a COM class (meaning
|
int com; // !=0 if this is a COM class (meaning
|
||||||
// it derives from IUnknown)
|
// it derives from IUnknown)
|
||||||
|
|
13
dmd2/cast.c
13
dmd2/cast.c
|
@ -1171,7 +1171,7 @@ Expression *AddrExp::castTo(Scope *sc, Type *t)
|
||||||
{ Dsymbol *s = (Dsymbol *)eo->vars->a.data[i];
|
{ Dsymbol *s = (Dsymbol *)eo->vars->a.data[i];
|
||||||
FuncDeclaration *f2 = s->isFuncDeclaration();
|
FuncDeclaration *f2 = s->isFuncDeclaration();
|
||||||
assert(f2);
|
assert(f2);
|
||||||
if (f2->overloadExactMatch(t->nextOf(), m))
|
if (f2->overloadExactMatch(t->nextOf(), m))
|
||||||
{ if (f)
|
{ if (f)
|
||||||
/* Error if match in more than one overload set,
|
/* Error if match in more than one overload set,
|
||||||
* even if one is a 'better' match than the other.
|
* even if one is a 'better' match than the other.
|
||||||
|
@ -1190,7 +1190,6 @@ Expression *AddrExp::castTo(Scope *sc, Type *t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (type->ty == Tpointer && type->nextOf()->ty == Tfunction &&
|
if (type->ty == Tpointer && type->nextOf()->ty == Tfunction &&
|
||||||
tb->ty == Tpointer && tb->nextOf()->ty == Tfunction &&
|
tb->ty == Tpointer && tb->nextOf()->ty == Tfunction &&
|
||||||
e1->op == TOKvar)
|
e1->op == TOKvar)
|
||||||
|
@ -1199,8 +1198,10 @@ Expression *AddrExp::castTo(Scope *sc, Type *t)
|
||||||
FuncDeclaration *f = ve->var->isFuncDeclaration();
|
FuncDeclaration *f = ve->var->isFuncDeclaration();
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
|
#if !IN_LLVM
|
||||||
assert(0); // should be SymOffExp instead
|
assert(0); // should be SymOffExp instead
|
||||||
f = f->overloadExactMatch(tb->nextOf(), m);
|
#endif
|
||||||
|
f = f->overloadExactMatch(tb->nextOf(), m);
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
e = new VarExp(loc, f);
|
e = new VarExp(loc, f);
|
||||||
|
@ -1211,6 +1212,7 @@ Expression *AddrExp::castTo(Scope *sc, Type *t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e = Expression::castTo(sc, t);
|
e = Expression::castTo(sc, t);
|
||||||
}
|
}
|
||||||
e->type = t;
|
e->type = t;
|
||||||
|
@ -1474,7 +1476,10 @@ Expression *BinExp::scaleFactor(Scope *sc)
|
||||||
stride = t1b->nextOf()->size(loc);
|
stride = t1b->nextOf()->size(loc);
|
||||||
if (!t->equals(t2b))
|
if (!t->equals(t2b))
|
||||||
e2 = e2->castTo(sc, t);
|
e2 = e2->castTo(sc, t);
|
||||||
|
// LDC: llvm uses typesafe pointer arithmetic
|
||||||
|
#if !IN_LLVM
|
||||||
e2 = new MulExp(loc, e2, new IntegerExp(0, stride, t));
|
e2 = new MulExp(loc, e2, new IntegerExp(0, stride, t));
|
||||||
|
#endif
|
||||||
e2->type = t;
|
e2->type = t;
|
||||||
type = e1->type;
|
type = e1->type;
|
||||||
}
|
}
|
||||||
|
@ -1489,7 +1494,9 @@ Expression *BinExp::scaleFactor(Scope *sc)
|
||||||
e = e1->castTo(sc, t);
|
e = e1->castTo(sc, t);
|
||||||
else
|
else
|
||||||
e = e1;
|
e = e1;
|
||||||
|
#if !IN_LLVM
|
||||||
e = new MulExp(loc, e, new IntegerExp(0, stride, t));
|
e = new MulExp(loc, e, new IntegerExp(0, stride, t));
|
||||||
|
#endif
|
||||||
e->type = t;
|
e->type = t;
|
||||||
type = e2->type;
|
type = e2->type;
|
||||||
e1 = e2;
|
e1 = e2;
|
||||||
|
|
|
@ -190,11 +190,13 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
|
||||||
classinfo = this;
|
classinfo = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !MODULEINFO_IS_STRUCT
|
||||||
if (id == Id::ModuleInfo)
|
if (id == Id::ModuleInfo)
|
||||||
{ if (Module::moduleinfo)
|
{ if (Module::moduleinfo)
|
||||||
Module::moduleinfo->error("%s", msg);
|
Module::moduleinfo->error("%s", msg);
|
||||||
Module::moduleinfo = this;
|
Module::moduleinfo = this;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
com = 0;
|
com = 0;
|
||||||
|
|
|
@ -614,7 +614,7 @@ void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||||
{
|
{
|
||||||
if (haliassym)
|
if (haliassym)
|
||||||
{
|
{
|
||||||
buf->writestring(haliassym->toChars());
|
buf->writestring(haliassym->toChars());
|
||||||
buf->writeByte(' ');
|
buf->writeByte(' ');
|
||||||
buf->writestring(ident->toChars());
|
buf->writestring(ident->toChars());
|
||||||
}
|
}
|
||||||
|
@ -626,7 +626,11 @@ void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||||
{
|
{
|
||||||
if (aliassym)
|
if (aliassym)
|
||||||
{
|
{
|
||||||
|
#if !IN_LLVM
|
||||||
aliassym->toCBuffer(buf, hgs);
|
aliassym->toCBuffer(buf, hgs);
|
||||||
|
#else
|
||||||
|
buf->writestring(aliassym->toChars());
|
||||||
|
#endif
|
||||||
buf->writeByte(' ');
|
buf->writeByte(' ');
|
||||||
buf->writestring(ident->toChars());
|
buf->writestring(ident->toChars());
|
||||||
}
|
}
|
||||||
|
@ -876,7 +880,7 @@ void VarDeclaration::semantic(Scope *sc)
|
||||||
//printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
|
//printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
|
||||||
v->semantic(sc);
|
v->semantic(sc);
|
||||||
|
|
||||||
/*
|
#if !IN_LLVM
|
||||||
// removed for LDC since TupleDeclaration::toObj already creates the fields;
|
// removed for LDC since TupleDeclaration::toObj already creates the fields;
|
||||||
// adding them to the scope again leads to duplicates
|
// adding them to the scope again leads to duplicates
|
||||||
if (sc->scopesym)
|
if (sc->scopesym)
|
||||||
|
@ -884,7 +888,7 @@ void VarDeclaration::semantic(Scope *sc)
|
||||||
if (sc->scopesym->members)
|
if (sc->scopesym->members)
|
||||||
sc->scopesym->members->push(v);
|
sc->scopesym->members->push(v);
|
||||||
}
|
}
|
||||||
*/
|
#endif
|
||||||
Expression *e = new DsymbolExp(loc, v);
|
Expression *e = new DsymbolExp(loc, v);
|
||||||
exps->data[i] = e;
|
exps->data[i] = e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,6 +450,7 @@ struct TypeInfoClassDeclaration : TypeInfoDeclaration
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
|
void codegen(Ir*);
|
||||||
void llvmDefine();
|
void llvmDefine();
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -618,6 +619,10 @@ struct TypeInfoSharedDeclaration : TypeInfoDeclaration
|
||||||
#if IN_DMD
|
#if IN_DMD
|
||||||
void toDt(dt_t **pdt);
|
void toDt(dt_t **pdt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if IN_LLVM
|
||||||
|
void llvmDefine();
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeInfoWildDeclaration : TypeInfoDeclaration
|
struct TypeInfoWildDeclaration : TypeInfoDeclaration
|
||||||
|
@ -627,6 +632,10 @@ struct TypeInfoWildDeclaration : TypeInfoDeclaration
|
||||||
#if IN_DMD
|
#if IN_DMD
|
||||||
void toDt(dt_t **pdt);
|
void toDt(dt_t **pdt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if IN_LLVM
|
||||||
|
void llvmDefine();
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -834,12 +834,14 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
|
||||||
|
|
||||||
void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr)
|
void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr)
|
||||||
{
|
{
|
||||||
|
#if !IN_LLVM
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (precedence[e->op] == PREC_zero)
|
if (precedence[e->op] == PREC_zero)
|
||||||
printf("precedence not defined for token '%s'\n",Token::tochars[e->op]);
|
printf("precedence not defined for token '%s'\n",Token::tochars[e->op]);
|
||||||
#endif
|
#endif
|
||||||
assert(precedence[e->op] != PREC_zero);
|
assert(precedence[e->op] != PREC_zero);
|
||||||
assert(pr != PREC_zero);
|
assert(pr != PREC_zero);
|
||||||
|
#endif
|
||||||
|
|
||||||
//if (precedence[e->op] == 0) e->dump(0);
|
//if (precedence[e->op] == 0) e->dump(0);
|
||||||
if (precedence[e->op] < pr ||
|
if (precedence[e->op] < pr ||
|
||||||
|
@ -2489,7 +2491,7 @@ Expression *ThisExp::semantic(Scope *sc)
|
||||||
#if LOGSEMANTIC
|
#if LOGSEMANTIC
|
||||||
printf("ThisExp::semantic()\n");
|
printf("ThisExp::semantic()\n");
|
||||||
#endif
|
#endif
|
||||||
if (type)
|
if (type && var)
|
||||||
{ //assert(global.errors || var);
|
{ //assert(global.errors || var);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -2534,7 +2536,8 @@ Expression *ThisExp::semantic(Scope *sc)
|
||||||
assert(fd->vthis);
|
assert(fd->vthis);
|
||||||
var = fd->vthis;
|
var = fd->vthis;
|
||||||
assert(var->parent);
|
assert(var->parent);
|
||||||
type = var->type;
|
if (!type)
|
||||||
|
type = var->type;
|
||||||
var->isVarDeclaration()->checkNestedReference(sc, loc);
|
var->isVarDeclaration()->checkNestedReference(sc, loc);
|
||||||
if (!sc->intypeof)
|
if (!sc->intypeof)
|
||||||
sc->callSuper |= CSXthis;
|
sc->callSuper |= CSXthis;
|
||||||
|
@ -7402,6 +7405,14 @@ Expression *AddrExp::semantic(Scope *sc)
|
||||||
|
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
|
#if !IN_LLVM
|
||||||
|
if (f->isIntrinsic())
|
||||||
|
{
|
||||||
|
error("cannot take the address of intrinsic function %s", e1->toChars());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!ve->hasOverloads ||
|
if (!ve->hasOverloads ||
|
||||||
/* Because nested functions cannot be overloaded,
|
/* Because nested functions cannot be overloaded,
|
||||||
* mark here that we took its address because castTo()
|
* mark here that we took its address because castTo()
|
||||||
|
@ -7789,6 +7800,9 @@ CastExp::CastExp(Loc loc, Expression *e, Type *t)
|
||||||
{
|
{
|
||||||
to = t;
|
to = t;
|
||||||
this->mod = ~0;
|
this->mod = ~0;
|
||||||
|
#if IN_LLVM
|
||||||
|
disableOptimization = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
|
@ -7799,6 +7813,9 @@ CastExp::CastExp(Loc loc, Expression *e, unsigned mod)
|
||||||
{
|
{
|
||||||
to = NULL;
|
to = NULL;
|
||||||
this->mod = mod;
|
this->mod = mod;
|
||||||
|
#if IN_LLVM
|
||||||
|
disableOptimization = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -7987,7 +8004,6 @@ void CastExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||||
expToCBuffer(buf, hgs, e1, precedence[op]);
|
expToCBuffer(buf, hgs, e1, precedence[op]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
|
|
||||||
SliceExp::SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr)
|
SliceExp::SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr)
|
||||||
|
|
|
@ -1301,6 +1301,7 @@ struct CastExp : UnaExp
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
DValue* toElem(IRState* irs);
|
DValue* toElem(IRState* irs);
|
||||||
llvm::Constant *toConstElem(IRState *irs);
|
llvm::Constant *toConstElem(IRState *irs);
|
||||||
|
bool disableOptimization;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
10
dmd2/func.c
10
dmd2/func.c
|
@ -775,7 +775,9 @@ void FuncDeclaration::semantic(Scope *sc)
|
||||||
|
|
||||||
Ldone:
|
Ldone:
|
||||||
Module::dprogress++;
|
Module::dprogress++;
|
||||||
semanticRun = PASSsemanticdone;
|
//LDC relies on semanticRun variable not being reset here
|
||||||
|
if(semanticRun < PASSsemanticdone)
|
||||||
|
semanticRun = PASSsemanticdone;
|
||||||
|
|
||||||
/* Save scope for possible later use (if we need the
|
/* Save scope for possible later use (if we need the
|
||||||
* function internals)
|
* function internals)
|
||||||
|
@ -1235,7 +1237,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
||||||
else
|
else
|
||||||
{ // Call invariant virtually
|
{ // Call invariant virtually
|
||||||
ThisExp *tv = new ThisExp(0);
|
ThisExp *tv = new ThisExp(0);
|
||||||
tv->type = vthis->type;
|
tv->type = vthis->type;
|
||||||
tv->var = vthis;
|
tv->var = vthis;
|
||||||
Expression* v = tv;
|
Expression* v = tv;
|
||||||
|
|
||||||
|
@ -2771,7 +2773,7 @@ FuncDeclaration *FuncDeclaration::genCfunc(Parameters *args, Type *treturn, Iden
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tf = new TypeFunction(NULL, treturn, 0, LINKc);
|
tf = new TypeFunction(args, treturn, 0, LINKc);
|
||||||
fd = new FuncDeclaration(0, 0, id, STCstatic, tf);
|
fd = new FuncDeclaration(0, 0, id, STCstatic, tf);
|
||||||
fd->protection = PROTpublic;
|
fd->protection = PROTpublic;
|
||||||
fd->linkage = LINKc;
|
fd->linkage = LINKc;
|
||||||
|
@ -3011,7 +3013,7 @@ void CtorDeclaration::semantic(Scope *sc)
|
||||||
// to the function body
|
// to the function body
|
||||||
if (fbody && semanticRun < PASSsemantic)
|
if (fbody && semanticRun < PASSsemantic)
|
||||||
{
|
{
|
||||||
Expression *e = new ThisExp(loc);
|
ThisExp *e = new ThisExp(loc);
|
||||||
if (parent->isClassDeclaration())
|
if (parent->isClassDeclaration())
|
||||||
e->type = tret;
|
e->type = tret;
|
||||||
Statement *s = new ReturnStatement(loc, e);
|
Statement *s = new ReturnStatement(loc, e);
|
||||||
|
|
|
@ -202,7 +202,9 @@ char *ClassDeclaration::mangle()
|
||||||
ident == Id::TypeInfo_Tuple ||
|
ident == Id::TypeInfo_Tuple ||
|
||||||
this == object ||
|
this == object ||
|
||||||
this == classinfo ||
|
this == classinfo ||
|
||||||
|
#if !MODULEINFO_IS_STRUCT
|
||||||
this == Module::moduleinfo ||
|
this == Module::moduleinfo ||
|
||||||
|
#endif
|
||||||
memcmp(ident->toChars(), "TypeInfo_", 9) == 0
|
memcmp(ident->toChars(), "TypeInfo_", 9) == 0
|
||||||
)
|
)
|
||||||
parent = NULL;
|
parent = NULL;
|
||||||
|
|
|
@ -57,7 +57,7 @@ static llvm::cl::opt<bool> fqnNames("oq",
|
||||||
llvm::cl::ZeroOrMore);
|
llvm::cl::ZeroOrMore);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ClassDeclaration *Module::moduleinfo;
|
AggregateDeclaration *Module::moduleinfo;
|
||||||
|
|
||||||
Module *Module::rootModule;
|
Module *Module::rootModule;
|
||||||
DsymbolTable *Module::modules;
|
DsymbolTable *Module::modules;
|
||||||
|
|
|
@ -65,8 +65,7 @@ struct Module : Package
|
||||||
static unsigned dprogress; // progress resolving the deferred list
|
static unsigned dprogress; // progress resolving the deferred list
|
||||||
static void init();
|
static void init();
|
||||||
|
|
||||||
static ClassDeclaration *moduleinfo;
|
static AggregateDeclaration *moduleinfo;
|
||||||
|
|
||||||
|
|
||||||
const char *arg; // original argument name
|
const char *arg; // original argument name
|
||||||
ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration
|
ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration
|
||||||
|
|
229
dmd2/mtype.c
229
dmd2/mtype.c
|
@ -1538,7 +1538,7 @@ Type *Type::merge()
|
||||||
|
|
||||||
//if (next)
|
//if (next)
|
||||||
//next = next->merge();
|
//next = next->merge();
|
||||||
toDecoBuffer(&buf, false);
|
toDecoBuffer(&buf, false);
|
||||||
sv = stringtable.update((char *)buf.data, buf.offset);
|
sv = stringtable.update((char *)buf.data, buf.offset);
|
||||||
if (sv->ptrvalue)
|
if (sv->ptrvalue)
|
||||||
{ t = (Type *) sv->ptrvalue;
|
{ t = (Type *) sv->ptrvalue;
|
||||||
|
@ -1556,19 +1556,19 @@ Type *Type::merge()
|
||||||
// we still need deco strings to be unique
|
// we still need deco strings to be unique
|
||||||
// or Type::equals fails, which breaks a bunch of stuff,
|
// or Type::equals fails, which breaks a bunch of stuff,
|
||||||
// like covariant member function overloads.
|
// like covariant member function overloads.
|
||||||
OutBuffer mangle;
|
OutBuffer mangle;
|
||||||
toDecoBuffer(&mangle, true);
|
toDecoBuffer(&mangle, true);
|
||||||
StringValue* sv2 = deco_stringtable.update((char *)mangle.data, mangle.offset);
|
StringValue* sv2 = deco_stringtable.update((char *)mangle.data, mangle.offset);
|
||||||
if (sv2->ptrvalue)
|
if (sv2->ptrvalue)
|
||||||
{ Type* t2 = (Type *) sv2->ptrvalue;
|
{ Type* t2 = (Type *) sv2->ptrvalue;
|
||||||
assert(t2->deco);
|
assert(t2->deco);
|
||||||
deco = t2->deco;
|
deco = t2->deco;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sv2->ptrvalue = this;
|
sv2->ptrvalue = this;
|
||||||
deco = (char *)sv2->lstring.string;
|
deco = (char *)sv2->lstring.string;
|
||||||
}
|
}
|
||||||
//printf("new value, deco = '%s' %p\n", t->deco, t->deco);
|
//printf("new value, deco = '%s' %p\n", t->deco, t->deco);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1753,7 +1753,11 @@ Expression *Type::getProperty(Loc loc, Identifier *ident)
|
||||||
{
|
{
|
||||||
if (ty == Tvoid)
|
if (ty == Tvoid)
|
||||||
error(loc, "void does not have an initializer");
|
error(loc, "void does not have an initializer");
|
||||||
|
#if IN_LLVM
|
||||||
|
e = defaultInit(loc);
|
||||||
|
#else
|
||||||
e = defaultInitLiteral(loc);
|
e = defaultInitLiteral(loc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (ident == Id::mangleof)
|
else if (ident == Id::mangleof)
|
||||||
{ const char *s;
|
{ const char *s;
|
||||||
|
@ -3123,26 +3127,26 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||||
Expression *ec;
|
Expression *ec;
|
||||||
Expressions *arguments;
|
Expressions *arguments;
|
||||||
|
|
||||||
//LDC: Build arguments.
|
//LDC: Build arguments.
|
||||||
static FuncDeclaration *adReverseChar_fd = NULL;
|
static FuncDeclaration *adReverseChar_fd = NULL;
|
||||||
if(!adReverseChar_fd) {
|
if(!adReverseChar_fd) {
|
||||||
Parameters* args = new Parameters;
|
Parameters* args = new Parameters;
|
||||||
Type* arrty = Type::tchar->arrayOf();
|
Type* arrty = Type::tchar->arrayOf();
|
||||||
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
||||||
adReverseChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseChar");
|
adReverseChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseChar");
|
||||||
}
|
}
|
||||||
static FuncDeclaration *adReverseWchar_fd = NULL;
|
static FuncDeclaration *adReverseWchar_fd = NULL;
|
||||||
if(!adReverseWchar_fd) {
|
if(!adReverseWchar_fd) {
|
||||||
Parameters* args = new Parameters;
|
Parameters* args = new Parameters;
|
||||||
Type* arrty = Type::twchar->arrayOf();
|
Type* arrty = Type::twchar->arrayOf();
|
||||||
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
||||||
adReverseWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseWchar");
|
adReverseWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseWchar");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n->ty == Twchar)
|
if(n->ty == Twchar)
|
||||||
ec = new VarExp(0, adReverseWchar_fd);
|
ec = new VarExp(0, adReverseWchar_fd);
|
||||||
else
|
else
|
||||||
ec = new VarExp(0, adReverseChar_fd);
|
ec = new VarExp(0, adReverseChar_fd);
|
||||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||||
arguments = new Expressions();
|
arguments = new Expressions();
|
||||||
arguments->push(e);
|
arguments->push(e);
|
||||||
|
@ -3154,26 +3158,26 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||||
Expression *ec;
|
Expression *ec;
|
||||||
Expressions *arguments;
|
Expressions *arguments;
|
||||||
|
|
||||||
//LDC: Build arguments.
|
//LDC: Build arguments.
|
||||||
static FuncDeclaration *adSortChar_fd = NULL;
|
static FuncDeclaration *adSortChar_fd = NULL;
|
||||||
if(!adSortChar_fd) {
|
if(!adSortChar_fd) {
|
||||||
Parameters* args = new Parameters;
|
Parameters* args = new Parameters;
|
||||||
Type* arrty = Type::tchar->arrayOf();
|
Type* arrty = Type::tchar->arrayOf();
|
||||||
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
||||||
adSortChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortChar");
|
adSortChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortChar");
|
||||||
}
|
}
|
||||||
static FuncDeclaration *adSortWchar_fd = NULL;
|
static FuncDeclaration *adSortWchar_fd = NULL;
|
||||||
if(!adSortWchar_fd) {
|
if(!adSortWchar_fd) {
|
||||||
Parameters* args = new Parameters;
|
Parameters* args = new Parameters;
|
||||||
Type* arrty = Type::twchar->arrayOf();
|
Type* arrty = Type::twchar->arrayOf();
|
||||||
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
args->push(new Parameter(STCin, arrty, NULL, NULL));
|
||||||
adSortWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortWchar");
|
adSortWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortWchar");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n->ty == Twchar)
|
if(n->ty == Twchar)
|
||||||
ec = new VarExp(0, adSortWchar_fd);
|
ec = new VarExp(0, adSortWchar_fd);
|
||||||
else
|
else
|
||||||
ec = new VarExp(0, adSortChar_fd);
|
ec = new VarExp(0, adSortChar_fd);
|
||||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||||
arguments = new Expressions();
|
arguments = new Expressions();
|
||||||
arguments->push(e);
|
arguments->push(e);
|
||||||
|
@ -3189,37 +3193,39 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||||
|
|
||||||
assert(size);
|
assert(size);
|
||||||
dup = (ident == Id::dup || ident == Id::idup);
|
dup = (ident == Id::dup || ident == Id::idup);
|
||||||
//LDC: Build arguments.
|
//LDC: Build arguments.
|
||||||
static FuncDeclaration *adDup_fd = NULL;
|
static FuncDeclaration *adDup_fd = NULL;
|
||||||
if(!adDup_fd) {
|
if(!adDup_fd) {
|
||||||
Parameters* args = new Parameters;
|
Parameters* args = new Parameters;
|
||||||
args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL));
|
args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL));
|
||||||
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
||||||
adDup_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adDup);
|
adDup_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adDup);
|
||||||
}
|
}
|
||||||
static FuncDeclaration *adReverse_fd = NULL;
|
static FuncDeclaration *adReverse_fd = NULL;
|
||||||
if(!adReverse_fd) {
|
if(!adReverse_fd) {
|
||||||
Parameters* args = new Parameters;
|
Parameters* args = new Parameters;
|
||||||
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
||||||
args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL));
|
args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL));
|
||||||
adReverse_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adReverse);
|
adReverse_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adReverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dup)
|
if(dup)
|
||||||
ec = new VarExp(0, adDup_fd);
|
ec = new VarExp(0, adDup_fd);
|
||||||
else
|
else
|
||||||
ec = new VarExp(0, adReverse_fd);
|
ec = new VarExp(0, adReverse_fd);
|
||||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||||
arguments = new Expressions();
|
arguments = new Expressions();
|
||||||
if (dup)
|
if (dup)
|
||||||
arguments->push(getTypeInfo(sc));
|
arguments->push(getTypeInfo(sc));
|
||||||
|
|
||||||
// LDC repaint array type to void[]
|
// LDC repaint array type to void[]
|
||||||
if (n->ty != Tvoid) {
|
if (n->ty != Tvoid) {
|
||||||
e = new CastExp(e->loc, e, e->type);
|
CastExp *exp = new CastExp(e->loc, e, e->type);
|
||||||
e->type = Type::tvoid->arrayOf();
|
exp->type = Type::tvoid->arrayOf();
|
||||||
}
|
exp->disableOptimization = true;
|
||||||
arguments->push(e);
|
e = exp;
|
||||||
|
}
|
||||||
|
arguments->push(e);
|
||||||
|
|
||||||
if (!dup)
|
if (!dup)
|
||||||
arguments->push(new IntegerExp(0, size, Type::tsize_t));
|
arguments->push(new IntegerExp(0, size, Type::tsize_t));
|
||||||
|
@ -3237,41 +3243,46 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||||
{
|
{
|
||||||
Expression *ec;
|
Expression *ec;
|
||||||
Expressions *arguments;
|
Expressions *arguments;
|
||||||
bool isBit = (n->ty == Tbit);
|
bool isBit = (n->ty == Tbit);
|
||||||
|
|
||||||
//LDC: Build arguments.
|
//LDC: Build arguments.
|
||||||
static FuncDeclaration *adSort_fd = NULL;
|
static FuncDeclaration *adSort_fd = NULL;
|
||||||
if(!adSort_fd) {
|
if(!adSort_fd) {
|
||||||
Parameters* args = new Parameters;
|
Parameters* args = new Parameters;
|
||||||
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
||||||
args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL));
|
args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL));
|
||||||
adSort_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSort");
|
adSort_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSort");
|
||||||
}
|
}
|
||||||
static FuncDeclaration *adSortBit_fd = NULL;
|
static FuncDeclaration *adSortBit_fd = NULL;
|
||||||
if(!adSortBit_fd) {
|
if(!adSortBit_fd) {
|
||||||
Parameters* args = new Parameters;
|
Parameters* args = new Parameters;
|
||||||
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL));
|
||||||
args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL));
|
args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL));
|
||||||
adSortBit_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSortBit");
|
adSortBit_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSortBit");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isBit)
|
if(isBit)
|
||||||
ec = new VarExp(0, adSortBit_fd);
|
ec = new VarExp(0, adSortBit_fd);
|
||||||
else
|
else
|
||||||
ec = new VarExp(0, adSort_fd);
|
ec = new VarExp(0, adSort_fd);
|
||||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||||
arguments = new Expressions();
|
arguments = new Expressions();
|
||||||
|
|
||||||
// LDC repaint array type to void[]
|
// LDC repaint array type to void[]
|
||||||
if (n->ty != Tvoid) {
|
if (n->ty != Tvoid) {
|
||||||
e = new CastExp(e->loc, e, e->type);
|
CastExp *exp = new CastExp(e->loc, e, e->type);
|
||||||
e->type = Type::tvoid->arrayOf();
|
exp->type = Type::tvoid->arrayOf();
|
||||||
}
|
exp->disableOptimization = true;
|
||||||
|
e = exp;
|
||||||
|
}
|
||||||
arguments->push(e);
|
arguments->push(e);
|
||||||
|
|
||||||
if (next->ty != Tbit)
|
if (next->ty != Tbit) {
|
||||||
arguments->push(n->getTypeInfo(sc)); // LDC, we don't support the getInternalTypeInfo
|
// LDC, we don't support the getInternalTypeInfo
|
||||||
// optimization arbitrarily, not yet at least...
|
// optimization arbitrarily, not yet at least...
|
||||||
|
arguments->push(n->getTypeInfo(sc));
|
||||||
|
}
|
||||||
|
|
||||||
e = new CallExp(e->loc, ec, arguments);
|
e = new CallExp(e->loc, ec, arguments);
|
||||||
e->type = next->arrayOf();
|
e->type = next->arrayOf();
|
||||||
}
|
}
|
||||||
|
@ -7499,9 +7510,17 @@ L1:
|
||||||
{ /* The handle to the monitor (call it a void*)
|
{ /* The handle to the monitor (call it a void*)
|
||||||
* *(cast(void**)e + 1)
|
* *(cast(void**)e + 1)
|
||||||
*/
|
*/
|
||||||
|
#if IN_LLVM
|
||||||
|
e = e->castTo(sc, tint8->pointerTo()->pointerTo());
|
||||||
|
e = new AddExp(e->loc, e, new IntegerExp(1));
|
||||||
|
e->type = tint8->pointerTo();
|
||||||
|
e = e->castTo(sc, tvoidptr->pointerTo());
|
||||||
|
e = new PtrExp(e->loc, e);
|
||||||
|
#else
|
||||||
e = e->castTo(sc, tvoidptr->pointerTo());
|
e = e->castTo(sc, tvoidptr->pointerTo());
|
||||||
e = new AddExp(e->loc, e, new IntegerExp(1));
|
e = new AddExp(e->loc, e, new IntegerExp(1));
|
||||||
e = new PtrExp(e->loc, e);
|
e = new PtrExp(e->loc, e);
|
||||||
|
#endif
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,6 +286,8 @@ Expression *AddrExp::optimize(int result)
|
||||||
{ Expression *e;
|
{ Expression *e;
|
||||||
|
|
||||||
//printf("AddrExp::optimize(result = %d) %s\n", result, toChars());
|
//printf("AddrExp::optimize(result = %d) %s\n", result, toChars());
|
||||||
|
// LDC never try to interpret: it could change the semantics by turning
|
||||||
|
// const p = &s; into an something like const p = &(Struct());
|
||||||
|
|
||||||
/* Rewrite &(a,b) as (a,&b)
|
/* Rewrite &(a,b) as (a,&b)
|
||||||
*/
|
*/
|
||||||
|
@ -295,13 +297,13 @@ Expression *AddrExp::optimize(int result)
|
||||||
ae->type = type;
|
ae->type = type;
|
||||||
e = new CommaExp(ce->loc, ce->e1, ae);
|
e = new CommaExp(ce->loc, ce->e1, ae);
|
||||||
e->type = type;
|
e->type = type;
|
||||||
return e->optimize(result);
|
return e->optimize(result & ~WANTinterpret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e1->op == TOKvar)
|
if (e1->op == TOKvar)
|
||||||
{ VarExp *ve = (VarExp *)e1;
|
{ VarExp *ve = (VarExp *)e1;
|
||||||
if (ve->var->storage_class & STCmanifest)
|
if (ve->var->storage_class & STCmanifest)
|
||||||
e1 = e1->optimize(result);
|
e1 = e1->optimize(result & ~WANTinterpret);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
e1 = e1->optimize(result);
|
e1 = e1->optimize(result);
|
||||||
|
@ -523,6 +525,10 @@ Expression *CallExp::optimize(int result)
|
||||||
|
|
||||||
Expression *CastExp::optimize(int result)
|
Expression *CastExp::optimize(int result)
|
||||||
{
|
{
|
||||||
|
#if IN_LLVM
|
||||||
|
if (disableOptimization)
|
||||||
|
return this;
|
||||||
|
#endif
|
||||||
//printf("CastExp::optimize(result = %d) %s\n", result, toChars());
|
//printf("CastExp::optimize(result = %d) %s\n", result, toChars());
|
||||||
//printf("from %s to %s\n", type->toChars(), to->toChars());
|
//printf("from %s to %s\n", type->toChars(), to->toChars());
|
||||||
//printf("from %s\n", type->toChars());
|
//printf("from %s\n", type->toChars());
|
||||||
|
@ -551,6 +557,9 @@ Expression *CastExp::optimize(int result)
|
||||||
e1->type->nextOf()->size() == type->nextOf()->size()
|
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);
|
Expression *e = e1->castTo(NULL, type);
|
||||||
if (X) printf(" returning1 %s\n", e->toChars());
|
if (X) printf(" returning1 %s\n", e->toChars());
|
||||||
return e;
|
return e;
|
||||||
|
|
|
@ -32,6 +32,7 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
|
||||||
protection = PROTpublic;
|
protection = PROTpublic;
|
||||||
type = NULL;
|
type = NULL;
|
||||||
handle = NULL;
|
handle = NULL;
|
||||||
|
scope = 0;
|
||||||
structsize = 0; // size of struct
|
structsize = 0; // size of struct
|
||||||
alignsize = 0; // size of struct for alignment purposes
|
alignsize = 0; // size of struct for alignment purposes
|
||||||
structalign = 0; // struct member alignment in effect
|
structalign = 0; // struct member alignment in effect
|
||||||
|
@ -263,6 +264,15 @@ StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
|
||||||
|
|
||||||
// For forward references
|
// For forward references
|
||||||
type = new TypeStruct(this);
|
type = new TypeStruct(this);
|
||||||
|
|
||||||
|
#if MODULEINFO_IS_STRUCT
|
||||||
|
if (id == Id::ModuleInfo)
|
||||||
|
{
|
||||||
|
if (Module::moduleinfo)
|
||||||
|
Module::moduleinfo->error("only object.d can define this reserved class name");
|
||||||
|
Module::moduleinfo = this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s)
|
Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s)
|
||||||
|
|
|
@ -129,8 +129,12 @@ DValue* DtoAAIn(Loc& loc, Type* type, DValue* aa, DValue* key)
|
||||||
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
|
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
|
||||||
|
|
||||||
// pkey param
|
// pkey param
|
||||||
|
#if DMDV1
|
||||||
LLValue* pkey = makeLValue(loc, key);
|
LLValue* pkey = makeLValue(loc, key);
|
||||||
pkey = DtoBitCast(pkey, funcTy->getParamType(2));
|
pkey = DtoBitCast(pkey, funcTy->getParamType(2));
|
||||||
|
#else
|
||||||
|
LLValue* pkey = getNullValue(getVoidPtrType());
|
||||||
|
#endif
|
||||||
|
|
||||||
// call runtime
|
// call runtime
|
||||||
LLValue* ret = gIR->CreateCallOrInvoke3(func, aaval, keyti, pkey, "aa.in").getInstruction();
|
LLValue* ret = gIR->CreateCallOrInvoke3(func, aaval, keyti, pkey, "aa.in").getInstruction();
|
||||||
|
|
|
@ -209,12 +209,20 @@ void DtoArrayInit(Loc& loc, DValue* array, DValue* value)
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr)
|
void DtoSetArray(DValue* array, LLValue* dim, LLValue* ptr)
|
||||||
{
|
{
|
||||||
Logger::println("SetArray");
|
Logger::println("SetArray");
|
||||||
|
LLValue *arr = array->getLVal();
|
||||||
assert(isaStruct(arr->getType()->getContainedType(0)));
|
assert(isaStruct(arr->getType()->getContainedType(0)));
|
||||||
|
#if 1
|
||||||
DtoStore(dim, DtoGEPi(arr,0,0));
|
DtoStore(dim, DtoGEPi(arr,0,0));
|
||||||
DtoStore(ptr, DtoGEPi(arr,0,1));
|
DtoStore(ptr, DtoGEPi(arr,0,1));
|
||||||
|
#else
|
||||||
|
DSliceValue *slice = DtoResizeDynArray(array->type, array, dim);
|
||||||
|
DtoMemCpy(DtoArrayPtr(array), ptr, dim);
|
||||||
|
DtoStore(dim, DtoGEPi(arr,0,0));
|
||||||
|
DtoStore(slice->ptr, DtoGEPi(arr,0,1));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -498,7 +506,7 @@ DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
|
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, LLValue* newdim)
|
||||||
{
|
{
|
||||||
Logger::println("DtoResizeDynArray : %s", arrayType->toChars());
|
Logger::println("DtoResizeDynArray : %s", arrayType->toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
@ -516,7 +524,7 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
|
||||||
|
|
||||||
LLSmallVector<LLValue*,4> args;
|
LLSmallVector<LLValue*,4> args;
|
||||||
args.push_back(DtoTypeInfoOf(arrayType));
|
args.push_back(DtoTypeInfoOf(arrayType));
|
||||||
args.push_back(newdim->getRVal());
|
args.push_back(newdim);
|
||||||
args.push_back(DtoArrayLen(array));
|
args.push_back(DtoArrayLen(array));
|
||||||
|
|
||||||
LLValue* arrPtr = DtoArrayPtr(array);
|
LLValue* arrPtr = DtoArrayPtr(array);
|
||||||
|
@ -528,7 +536,7 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
|
||||||
if (newptr->getType() != arrPtr->getType())
|
if (newptr->getType() != arrPtr->getType())
|
||||||
newptr = DtoBitCast(newptr, arrPtr->getType(), ".gc_mem");
|
newptr = DtoBitCast(newptr, arrPtr->getType(), ".gc_mem");
|
||||||
|
|
||||||
return new DSliceValue(arrayType, newdim->getRVal(), newptr);
|
return new DSliceValue(arrayType, newdim, newptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -544,7 +552,7 @@ void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* e
|
||||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcT");
|
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcT");
|
||||||
LLSmallVector<LLValue*,3> args;
|
LLSmallVector<LLValue*,3> args;
|
||||||
args.push_back(DtoTypeInfoOf(arrayType));
|
args.push_back(DtoTypeInfoOf(arrayType));
|
||||||
args.push_back(DtoBitCast(array->getLVal(), getVoidPtrType()));
|
args.push_back(DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(1)));
|
||||||
args.push_back(DtoBitCast(valueToAppend, getVoidPtrType()));
|
args.push_back(DtoBitCast(valueToAppend, getVoidPtrType()));
|
||||||
|
|
||||||
gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray");
|
gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray");
|
||||||
|
@ -565,7 +573,7 @@ DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp)
|
||||||
res = gIR->ir->CreateAdd(len1,len2,"tmp");
|
res = gIR->ir->CreateAdd(len1,len2,"tmp");
|
||||||
|
|
||||||
DValue* newdim = new DImValue(Type::tsize_t, res);
|
DValue* newdim = new DImValue(Type::tsize_t, res);
|
||||||
DSliceValue* slice = DtoResizeDynArray(arr->getType(), arr, newdim);
|
DSliceValue* slice = DtoResizeDynArray(arr->getType(), arr, newdim->getRVal());
|
||||||
|
|
||||||
src1 = slice->ptr;
|
src1 = slice->ptr;
|
||||||
src2 = DtoArrayPtr(e);
|
src2 = DtoArrayPtr(e);
|
||||||
|
@ -734,7 +742,7 @@ static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
LLValue* DtoArrayEquals(Loc& loc, TOK op, DValue* l, DValue* r)
|
LLValue* DtoArrayEquals(Loc& loc, TOK op, DValue* l, DValue* r)
|
||||||
{
|
{
|
||||||
LLValue* res = DtoArrayEqCmp_impl(loc, "_adEq", l, r, true);
|
LLValue* res = DtoArrayEqCmp_impl(loc, _adEq, l, r, true);
|
||||||
res = gIR->ir->CreateICmpNE(res, DtoConstInt(0), "tmp");
|
res = gIR->ir->CreateICmpNE(res, DtoConstInt(0), "tmp");
|
||||||
if (op == TOKnotequal)
|
if (op == TOKnotequal)
|
||||||
res = gIR->ir->CreateNot(res, "tmp");
|
res = gIR->ir->CreateNot(res, "tmp");
|
||||||
|
@ -1007,6 +1015,12 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to)
|
||||||
LLConstant* nul = getNullPtr(ptr->getType());
|
LLConstant* nul = getNullPtr(ptr->getType());
|
||||||
rval = gIR->ir->CreateICmpNE(ptr, nul, "tmp");
|
rval = gIR->ir->CreateICmpNE(ptr, nul, "tmp");
|
||||||
}
|
}
|
||||||
|
else if (fromtype->nextOf()->ty == Tvoid) {
|
||||||
|
// TODO:
|
||||||
|
rval = DtoArrayPtr(u);
|
||||||
|
rval = DtoBitCast(rval, getPtrToType(tolltype));
|
||||||
|
rval = DtoLoad(rval);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,12 @@ void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src);
|
||||||
|
|
||||||
void DtoArrayInit(Loc& loc, DValue* array, DValue* value);
|
void DtoArrayInit(Loc& loc, DValue* array, DValue* value);
|
||||||
void DtoArrayAssign(LLValue* l, LLValue* r);
|
void DtoArrayAssign(LLValue* l, LLValue* r);
|
||||||
void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr);
|
void DtoSetArray(DValue* array, LLValue* dim, LLValue* ptr);
|
||||||
void DtoSetArrayToNull(LLValue* v);
|
void DtoSetArrayToNull(LLValue* v);
|
||||||
|
|
||||||
DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool defaultInit=true);
|
DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool defaultInit=true);
|
||||||
DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true);
|
DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true);
|
||||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim);
|
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, llvm::Value* newdim);
|
||||||
|
|
||||||
void DtoCatAssignElement(Loc& loc, Type* type, DValue* arr, Expression* exp);
|
void DtoCatAssignElement(Loc& loc, Type* type, DValue* arr, Expression* exp);
|
||||||
DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp);
|
DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp);
|
||||||
|
|
|
@ -145,7 +145,7 @@ DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp)
|
||||||
// default allocator
|
// default allocator
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocclass");
|
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, _d_allocclass);
|
||||||
LLConstant* ci = DtoBitCast(tc->sym->ir.irStruct->getClassInfoSymbol(), DtoType(ClassDeclaration::classinfo->type));
|
LLConstant* ci = DtoBitCast(tc->sym->ir.irStruct->getClassInfoSymbol(), DtoType(ClassDeclaration::classinfo->type));
|
||||||
mem = gIR->CreateCallOrInvoke(fn, ci, ".newclass_gc_alloc").getInstruction();
|
mem = gIR->CreateCallOrInvoke(fn, ci, ".newclass_gc_alloc").getInstruction();
|
||||||
mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc");
|
mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc");
|
||||||
|
@ -686,7 +686,8 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
||||||
// void *defaultConstructor;
|
// void *defaultConstructor;
|
||||||
// version(D_Version2)
|
// version(D_Version2)
|
||||||
// const(MemberInfo[]) function(string) xgetMembers;
|
// const(MemberInfo[]) function(string) xgetMembers;
|
||||||
// TypeInfo typeinfo; // since dmd 1.045
|
// else
|
||||||
|
// TypeInfo typeinfo; // since dmd 1.045
|
||||||
// }
|
// }
|
||||||
|
|
||||||
Logger::println("DtoDefineClassInfo(%s)", cd->toChars());
|
Logger::println("DtoDefineClassInfo(%s)", cd->toChars());
|
||||||
|
@ -700,11 +701,7 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
||||||
|
|
||||||
ClassDeclaration* cinfo = ClassDeclaration::classinfo;
|
ClassDeclaration* cinfo = ClassDeclaration::classinfo;
|
||||||
|
|
||||||
#if DMDV2
|
|
||||||
if (cinfo->fields.dim != 13)
|
|
||||||
#else
|
|
||||||
if (cinfo->fields.dim != 12)
|
if (cinfo->fields.dim != 12)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
error("object.d ClassInfo class is incorrect");
|
error("object.d ClassInfo class is incorrect");
|
||||||
fatal();
|
fatal();
|
||||||
|
@ -798,7 +795,8 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
||||||
#endif // GENERATE_OFFTI
|
#endif // GENERATE_OFFTI
|
||||||
|
|
||||||
// default constructor
|
// default constructor
|
||||||
b.push_funcptr(cd->defaultCtor, Type::tvoid->pointerTo());
|
VarDeclaration* defConstructorVar = (VarDeclaration*)cinfo->fields.data[10];
|
||||||
|
b.push_funcptr(cd->defaultCtor, defConstructorVar->type);
|
||||||
|
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
|
|
||||||
|
@ -808,11 +806,13 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
||||||
// FIXME: fill it out!
|
// FIXME: fill it out!
|
||||||
b.push_null(xgetVar->type);
|
b.push_null(xgetVar->type);
|
||||||
|
|
||||||
#endif
|
#else
|
||||||
|
|
||||||
// typeinfo - since 1.045
|
// typeinfo - since 1.045
|
||||||
b.push_typeinfo(cd->type);
|
b.push_typeinfo(cd->type);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*size_t n = inits.size();
|
/*size_t n = inits.size();
|
||||||
for (size_t i=0; i<n; ++i)
|
for (size_t i=0; i<n; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -133,7 +133,7 @@ void VarDeclaration::codegen(Ir* p)
|
||||||
llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this);
|
llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this);
|
||||||
std::string _name(mangle());
|
std::string _name(mangle());
|
||||||
|
|
||||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(*gIR->module,_type,_isconst,_linkage,NULL,_name);
|
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(*gIR->module,_type,_isconst,_linkage,NULL,_name,0,isThreadlocal());
|
||||||
this->ir.irGlobal->value = gvar;
|
this->ir.irGlobal->value = gvar;
|
||||||
|
|
||||||
// set the alignment
|
// set the alignment
|
||||||
|
|
|
@ -76,6 +76,9 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest
|
||||||
if (thistype)
|
if (thistype)
|
||||||
{
|
{
|
||||||
bool toref = (thistype->toBasetype()->ty == Tstruct);
|
bool toref = (thistype->toBasetype()->ty == Tstruct);
|
||||||
|
#if STRUCTTHISREF
|
||||||
|
fty.is_arg_this_ref = toref;
|
||||||
|
#endif
|
||||||
fty.arg_this = new IrFuncTyArg(thistype, toref);
|
fty.arg_this = new IrFuncTyArg(thistype, toref);
|
||||||
lidx++;
|
lidx++;
|
||||||
}
|
}
|
||||||
|
@ -475,8 +478,6 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||||
else // fall back to C, it should be the right thing to do
|
else // fall back to C, it should be the right thing to do
|
||||||
func->setCallingConv(llvm::CallingConv::C);
|
func->setCallingConv(llvm::CallingConv::C);
|
||||||
|
|
||||||
fdecl->ir.irFunc->func = func;
|
|
||||||
|
|
||||||
// parameter attributes
|
// parameter attributes
|
||||||
if (!fdecl->isIntrinsic()) {
|
if (!fdecl->isIntrinsic()) {
|
||||||
set_param_attrs(f, func, fdecl);
|
set_param_attrs(f, func, fdecl);
|
||||||
|
@ -607,7 +608,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||||
|
|
||||||
Type* t = fd->type->toBasetype();
|
Type* t = fd->type->toBasetype();
|
||||||
TypeFunction* f = (TypeFunction*)t;
|
TypeFunction* f = (TypeFunction*)t;
|
||||||
assert(f->irtype);
|
// assert(f->irtype);
|
||||||
|
|
||||||
llvm::Function* func = fd->ir.irFunc->func;
|
llvm::Function* func = fd->ir.irFunc->func;
|
||||||
const llvm::FunctionType* functype = func->getFunctionType();
|
const llvm::FunctionType* functype = func->getFunctionType();
|
||||||
|
@ -665,7 +666,10 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||||
|
|
||||||
LLValue* thismem = DtoRawAlloca(thisvar->getType(), 0, "this"); // FIXME: align?
|
LLValue* thismem = DtoRawAlloca(thisvar->getType(), 0, "this"); // FIXME: align?
|
||||||
DtoStore(thisvar, thismem);
|
DtoStore(thisvar, thismem);
|
||||||
irfunction->thisArg = thismem;
|
if (f->fty.is_arg_this_ref)
|
||||||
|
irfunction->thisArg = DtoLoad(thismem, "thisRef");
|
||||||
|
else
|
||||||
|
irfunction->thisArg = thismem;
|
||||||
|
|
||||||
assert(!fd->vthis->ir.irLocal);
|
assert(!fd->vthis->ir.irLocal);
|
||||||
fd->vthis->ir.irLocal = new IrLocal(fd->vthis);
|
fd->vthis->ir.irLocal = new IrLocal(fd->vthis);
|
||||||
|
|
|
@ -378,8 +378,8 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs)
|
||||||
}
|
}
|
||||||
// rhs is slice
|
// rhs is slice
|
||||||
else if (DSliceValue* s = rhs->isSlice()) {
|
else if (DSliceValue* s = rhs->isSlice()) {
|
||||||
assert(s->getType()->toBasetype() == lhs->getType()->toBasetype());
|
//assert(s->getType()->toBasetype() == lhs->getType()->toBasetype());
|
||||||
DtoSetArray(lhs->getLVal(),DtoArrayLen(s),DtoArrayPtr(s));
|
DtoSetArray(lhs,DtoArrayLen(s),DtoArrayPtr(s));
|
||||||
}
|
}
|
||||||
// null
|
// null
|
||||||
else if (rhs->isNull()) {
|
else if (rhs->isNull()) {
|
||||||
|
@ -391,7 +391,7 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs)
|
||||||
}
|
}
|
||||||
// some implicitly converting ref assignment
|
// some implicitly converting ref assignment
|
||||||
else {
|
else {
|
||||||
DtoSetArray(lhs->getLVal(), DtoArrayLen(rhs), DtoArrayPtr(rhs));
|
DtoSetArray(lhs, DtoArrayLen(rhs), DtoArrayPtr(rhs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (t->ty == Tsarray) {
|
else if (t->ty == Tsarray) {
|
||||||
|
@ -1271,12 +1271,7 @@ void DtoAnnotation(const char* str)
|
||||||
|
|
||||||
LLConstant* DtoTypeInfoOf(Type* type, bool base)
|
LLConstant* DtoTypeInfoOf(Type* type, bool base)
|
||||||
{
|
{
|
||||||
#if DMDV2
|
type = type->merge2(); // needed.. getTypeInfo does the same
|
||||||
// FIXME: this is probably wrong, but it makes druntime's genobj.d compile!
|
|
||||||
type = type->mutableOf()->merge(); // needed.. getTypeInfo does the same
|
|
||||||
#else
|
|
||||||
type = type->merge(); // needed.. getTypeInfo does the same
|
|
||||||
#endif
|
|
||||||
type->getTypeInfo(NULL);
|
type->getTypeInfo(NULL);
|
||||||
TypeInfoDeclaration* tidecl = type->vtinfo;
|
TypeInfoDeclaration* tidecl = type->vtinfo;
|
||||||
assert(tidecl);
|
assert(tidecl);
|
||||||
|
@ -1351,7 +1346,7 @@ bool mustDefineSymbol(Dsymbol* s)
|
||||||
if (fd->semanticRun < 4)
|
if (fd->semanticRun < 4)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fd->isArrayOp)
|
if (fd->isArrayOp)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (global.params.useAvailableExternally && fd->availableExternally) {
|
if (global.params.useAvailableExternally && fd->availableExternally) {
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
STATISTIC(NumGcToStack, "Number of calls promoted to constant-size allocas");
|
STATISTIC(NumGcToStack, "Number of calls promoted to constant-size allocas");
|
||||||
|
@ -296,7 +297,7 @@ GarbageCollect2Stack::GarbageCollect2Stack()
|
||||||
KnownFunctions["_d_allocmemoryT"] = &AllocMemoryT;
|
KnownFunctions["_d_allocmemoryT"] = &AllocMemoryT;
|
||||||
KnownFunctions["_d_newarrayvT"] = &NewArrayVT;
|
KnownFunctions["_d_newarrayvT"] = &NewArrayVT;
|
||||||
KnownFunctions["_d_newarrayT"] = &NewArrayT;
|
KnownFunctions["_d_newarrayT"] = &NewArrayT;
|
||||||
KnownFunctions["_d_allocclass"] = &AllocClass;
|
KnownFunctions[_d_allocclass] = &AllocClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RemoveCall(CallSite CS, const Analysis& A) {
|
static void RemoveCall(CallSite CS, const Analysis& A) {
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "gen/runtime.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
STATISTIC(NumSimplified, "Number of runtime calls simplified");
|
STATISTIC(NumSimplified, "Number of runtime calls simplified");
|
||||||
|
@ -332,7 +334,7 @@ void SimplifyDRuntimeCalls::InitOptimizations() {
|
||||||
Optimizations["_d_newarraymT"] = &Allocation;
|
Optimizations["_d_newarraymT"] = &Allocation;
|
||||||
Optimizations["_d_newarraymiT"] = &Allocation;
|
Optimizations["_d_newarraymiT"] = &Allocation;
|
||||||
Optimizations["_d_newarraymvT"] = &Allocation;
|
Optimizations["_d_newarraymvT"] = &Allocation;
|
||||||
Optimizations["_d_allocclass"] = &Allocation;
|
Optimizations[_d_allocclass] = &Allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include "ir/irstruct.h"
|
#include "ir/irstruct.h"
|
||||||
|
|
||||||
RTTIBuilder::RTTIBuilder(ClassDeclaration* base_class)
|
RTTIBuilder::RTTIBuilder(AggregateDeclaration* base_class)
|
||||||
{
|
{
|
||||||
// make sure the base typeinfo class has been processed
|
// make sure the base typeinfo class has been processed
|
||||||
base_class->codegen(Type::sir);
|
base_class->codegen(Type::sir);
|
||||||
|
@ -23,10 +23,12 @@ RTTIBuilder::RTTIBuilder(ClassDeclaration* base_class)
|
||||||
baseir = base->ir.irStruct;
|
baseir = base->ir.irStruct;
|
||||||
assert(baseir && "no IrStruct for TypeInfo base class");
|
assert(baseir && "no IrStruct for TypeInfo base class");
|
||||||
|
|
||||||
// just start with adding the vtbl
|
if (base->isClassDeclaration()) {
|
||||||
inits.push_back(baseir->getVtblSymbol());
|
// just start with adding the vtbl
|
||||||
// and monitor
|
inits.push_back(baseir->getVtblSymbol());
|
||||||
push_null_vp();
|
// and monitor
|
||||||
|
push_null_vp();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTTIBuilder::push(llvm::Constant* C)
|
void RTTIBuilder::push(llvm::Constant* C)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
|
||||||
struct ClassDeclaration;
|
struct ClassDeclaration;
|
||||||
|
struct AggregateDeclaration;
|
||||||
struct TypeClass;
|
struct TypeClass;
|
||||||
struct Type;
|
struct Type;
|
||||||
|
|
||||||
|
@ -12,7 +13,7 @@ struct IrStruct;
|
||||||
|
|
||||||
struct RTTIBuilder
|
struct RTTIBuilder
|
||||||
{
|
{
|
||||||
ClassDeclaration* base;
|
AggregateDeclaration* base;
|
||||||
TypeClass* basetype;
|
TypeClass* basetype;
|
||||||
IrStruct* baseir;
|
IrStruct* baseir;
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ struct RTTIBuilder
|
||||||
// 14 is enough for any D1 ClassInfo
|
// 14 is enough for any D1 ClassInfo
|
||||||
llvm::SmallVector<llvm::Constant*, 14> inits;
|
llvm::SmallVector<llvm::Constant*, 14> inits;
|
||||||
|
|
||||||
RTTIBuilder(ClassDeclaration* base_class);
|
RTTIBuilder(AggregateDeclaration* base_class);
|
||||||
|
|
||||||
void push(llvm::Constant* C);
|
void push(llvm::Constant* C);
|
||||||
void push_null(Type* T);
|
void push_null(Type* T);
|
||||||
|
|
|
@ -339,7 +339,7 @@ static void LLVM_D_BuildRuntimeModule()
|
||||||
|
|
||||||
// Object _d_allocclass(ClassInfo ci)
|
// Object _d_allocclass(ClassInfo ci)
|
||||||
{
|
{
|
||||||
llvm::StringRef fname("_d_allocclass");
|
llvm::StringRef fname(_d_allocclass);
|
||||||
std::vector<const LLType*> types;
|
std::vector<const LLType*> types;
|
||||||
types.push_back(classInfoTy);
|
types.push_back(classInfoTy);
|
||||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
||||||
|
@ -608,7 +608,7 @@ static void LLVM_D_BuildRuntimeModule()
|
||||||
// int _adEq(void[] a1, void[] a2, TypeInfo ti)
|
// int _adEq(void[] a1, void[] a2, TypeInfo ti)
|
||||||
// int _adCmp(void[] a1, void[] a2, TypeInfo ti)
|
// int _adCmp(void[] a1, void[] a2, TypeInfo ti)
|
||||||
{
|
{
|
||||||
llvm::StringRef fname("_adEq");
|
llvm::StringRef fname(_adEq);
|
||||||
llvm::StringRef fname2("_adCmp");
|
llvm::StringRef fname2("_adCmp");
|
||||||
std::vector<const LLType*> types;
|
std::vector<const LLType*> types;
|
||||||
types.push_back(rt_array(byteTy));
|
types.push_back(rt_array(byteTy));
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef LDC_GEN_RUNTIME_H_
|
||||||
|
#define LDC_GEN_RUNTIME_H_
|
||||||
|
|
||||||
// D runtime support helpers
|
// D runtime support helpers
|
||||||
|
|
||||||
bool LLVM_D_InitRuntime();
|
bool LLVM_D_InitRuntime();
|
||||||
|
@ -6,3 +9,13 @@ void LLVM_D_FreeRuntime();
|
||||||
llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name);
|
llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name);
|
||||||
|
|
||||||
llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char* name);
|
llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char* name);
|
||||||
|
|
||||||
|
#if DMDV1
|
||||||
|
#define _d_allocclass "_d_allocclass"
|
||||||
|
#define _adEq "_adEq"
|
||||||
|
#else
|
||||||
|
#define _d_allocclass "_d_newclass"
|
||||||
|
#define _adEq "_adEq2"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // LDC_GEN_RUNTIME_H_
|
||||||
|
|
39
gen/toir.cpp
39
gen/toir.cpp
|
@ -121,6 +121,13 @@ DValue* VarExp::toElem(IRState* p)
|
||||||
LLValue* tmp = DtoArrayLen(p->arrays.back());
|
LLValue* tmp = DtoArrayLen(p->arrays.back());
|
||||||
return new DImValue(type, tmp);
|
return new DImValue(type, tmp);
|
||||||
}
|
}
|
||||||
|
// classinfo
|
||||||
|
else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration())
|
||||||
|
{
|
||||||
|
Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
|
||||||
|
cid->cd->codegen(Type::sir);;
|
||||||
|
return new DVarValue(type, vd, cid->cd->ir.irStruct->getClassInfoSymbol());
|
||||||
|
}
|
||||||
// typeinfo
|
// typeinfo
|
||||||
else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
|
else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
|
||||||
{
|
{
|
||||||
|
@ -133,13 +140,6 @@ DValue* VarExp::toElem(IRState* p)
|
||||||
m = p->ir->CreateBitCast(m, vartype, "tmp");
|
m = p->ir->CreateBitCast(m, vartype, "tmp");
|
||||||
return new DImValue(type, m);
|
return new DImValue(type, m);
|
||||||
}
|
}
|
||||||
// classinfo
|
|
||||||
else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration())
|
|
||||||
{
|
|
||||||
Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
|
|
||||||
cid->cd->codegen(Type::sir);;
|
|
||||||
return new DVarValue(type, vd, cid->cd->ir.irStruct->getClassInfoSymbol());
|
|
||||||
}
|
|
||||||
// nested variable
|
// nested variable
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
else if (vd->nestedrefs.dim) {
|
else if (vd->nestedrefs.dim) {
|
||||||
|
@ -552,7 +552,7 @@ DValue* AssignExp::toElem(IRState* p)
|
||||||
DValue* arr = ale->e1->toElem(p);
|
DValue* arr = ale->e1->toElem(p);
|
||||||
DVarValue arrval(ale->e1->type, arr->getLVal());
|
DVarValue arrval(ale->e1->type, arr->getLVal());
|
||||||
DValue* newlen = e2->toElem(p);
|
DValue* newlen = e2->toElem(p);
|
||||||
DSliceValue* slice = DtoResizeDynArray(arrval.getType(), &arrval, newlen);
|
DSliceValue* slice = DtoResizeDynArray(arrval.getType(), &arrval, newlen->getRVal());
|
||||||
DtoAssign(loc, &arrval, slice);
|
DtoAssign(loc, &arrval, slice);
|
||||||
return newlen;
|
return newlen;
|
||||||
}
|
}
|
||||||
|
@ -648,22 +648,16 @@ DValue* AddExp::toElem(IRState* p)
|
||||||
|
|
||||||
errorOnIllegalArrayOp(this, e1, e2);
|
errorOnIllegalArrayOp(this, e1, e2);
|
||||||
|
|
||||||
if (e1type != e2type) {
|
if (e1type != e2type && e1type->ty == Tpointer) {
|
||||||
if (e1type->ty == Tpointer) {
|
Logger::println("add to pointer");
|
||||||
Logger::println("add to pointer");
|
if (DConstValue* cv = r->isConst()) {
|
||||||
if (DConstValue* cv = r->isConst()) {
|
if (cv->c->isNullValue()) {
|
||||||
if (cv->c->isNullValue()) {
|
Logger::println("is zero");
|
||||||
Logger::println("is zero");
|
return new DImValue(type, l->getRVal());
|
||||||
return new DImValue(type, l->getRVal());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
LLValue* v = llvm::GetElementPtrInst::Create(l->getRVal(), r->getRVal(), "tmp", p->scopebb());
|
|
||||||
return new DImValue(type, v);
|
|
||||||
}
|
}
|
||||||
else if (t->iscomplex()) {
|
LLValue* v = llvm::GetElementPtrInst::Create(l->getRVal(), r->getRVal(), "tmp", p->scopebb());
|
||||||
return DtoComplexAdd(loc, type, l, r);
|
return new DImValue(type, v);
|
||||||
}
|
|
||||||
assert(0);
|
|
||||||
}
|
}
|
||||||
else if (t->iscomplex()) {
|
else if (t->iscomplex()) {
|
||||||
return DtoComplexAdd(loc, type, l, r);
|
return DtoComplexAdd(loc, type, l, r);
|
||||||
|
@ -1785,6 +1779,7 @@ DValue* AssertExp::toElem(IRState* p)
|
||||||
(invdecl = ((TypeStruct*)condty->nextOf())->sym->inv) != NULL)
|
(invdecl = ((TypeStruct*)condty->nextOf())->sym->inv) != NULL)
|
||||||
{
|
{
|
||||||
Logger::print("calling struct invariant");
|
Logger::print("calling struct invariant");
|
||||||
|
((TypeStruct*)condty->nextOf())->sym->codegen(Type::sir);
|
||||||
DFuncValue invfunc(invdecl, invdecl->ir.irFunc->func, cond->getRVal());
|
DFuncValue invfunc(invdecl, invdecl->ir.irFunc->func, cond->getRVal());
|
||||||
DtoCallFunction(loc, NULL, &invfunc, NULL);
|
DtoCallFunction(loc, NULL, &invfunc, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -896,7 +896,11 @@ const LLStructType* DtoModuleReferenceType()
|
||||||
// add members
|
// add members
|
||||||
std::vector<const LLType*> types;
|
std::vector<const LLType*> types;
|
||||||
types.push_back(getPtrToType(opaque));
|
types.push_back(getPtrToType(opaque));
|
||||||
|
#if DMDV1
|
||||||
types.push_back(DtoType(Module::moduleinfo->type));
|
types.push_back(DtoType(Module::moduleinfo->type));
|
||||||
|
#else
|
||||||
|
types.push_back(DtoType(Module::moduleinfo->type->pointerTo()));
|
||||||
|
#endif
|
||||||
|
|
||||||
// resolve type
|
// resolve type
|
||||||
const LLStructType* st = LLStructType::get(gIR->context(), types);
|
const LLStructType* st = LLStructType::get(gIR->context(), types);
|
||||||
|
|
|
@ -635,8 +635,11 @@ void Module::genmoduleinfo()
|
||||||
// void* xgetMembers;
|
// void* xgetMembers;
|
||||||
// void function() ictor;
|
// void function() ictor;
|
||||||
//
|
//
|
||||||
// version(D_Version2)
|
// version(D_Version2) {
|
||||||
// void*[4] reserved; // useless to us
|
// void *sharedctor;
|
||||||
|
// void *shareddtor;
|
||||||
|
// uint index;
|
||||||
|
// void*[1] reserved;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// resolve ModuleInfo
|
// resolve ModuleInfo
|
||||||
|
@ -646,14 +649,18 @@ void Module::genmoduleinfo()
|
||||||
fatal();
|
fatal();
|
||||||
}
|
}
|
||||||
// check for patch
|
// check for patch
|
||||||
#if DMDV2
|
else
|
||||||
else if (moduleinfo->fields.dim != 10)
|
|
||||||
#else
|
|
||||||
else if (moduleinfo->fields.dim != 9)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
error("object.d ModuleInfo class is incorrect");
|
#if DMDV2
|
||||||
fatal();
|
unsigned sizeof_ModuleInfo = 16 * PTRSIZE;
|
||||||
|
#else
|
||||||
|
unsigned sizeof_ModuleInfo = 14 * PTRSIZE;
|
||||||
|
#endif
|
||||||
|
if (sizeof_ModuleInfo != moduleinfo->structsize)
|
||||||
|
{
|
||||||
|
error("object.d ModuleInfo class is incorrect");
|
||||||
|
fatal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// use the RTTIBuilder
|
// use the RTTIBuilder
|
||||||
|
|
109
gen/typinf.cpp
109
gen/typinf.cpp
|
@ -112,43 +112,52 @@ Expression *Type::getInternalTypeInfo(Scope *sc)
|
||||||
|
|
||||||
Expression *Type::getTypeInfo(Scope *sc)
|
Expression *Type::getTypeInfo(Scope *sc)
|
||||||
{
|
{
|
||||||
Expression *e;
|
|
||||||
Type *t;
|
|
||||||
|
|
||||||
//printf("Type::getTypeInfo() %p, %s\n", this, toChars());
|
//printf("Type::getTypeInfo() %p, %s\n", this, toChars());
|
||||||
t = merge(); // do this since not all Type's are merge'd
|
if (!Type::typeinfo)
|
||||||
|
{
|
||||||
|
error(0, "TypeInfo not found. object.d may be incorrectly installed or corrupt, compile with -v switch");
|
||||||
|
fatal();
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression *e = 0;
|
||||||
|
Type *t = merge2(); // do this since not all Type's are merge'd
|
||||||
|
|
||||||
if (!t->vtinfo)
|
if (!t->vtinfo)
|
||||||
{
|
{
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
if (t->isConst())
|
if (t->isShared())
|
||||||
t->vtinfo = new TypeInfoConstDeclaration(t);
|
t->vtinfo = new TypeInfoSharedDeclaration(t);
|
||||||
else if (t->isImmutable())
|
else if (t->isConst())
|
||||||
t->vtinfo = new TypeInfoInvariantDeclaration(t);
|
t->vtinfo = new TypeInfoConstDeclaration(t);
|
||||||
else
|
else if (t->isImmutable())
|
||||||
|
t->vtinfo = new TypeInfoInvariantDeclaration(t);
|
||||||
|
else if (t->isWild())
|
||||||
|
t->vtinfo = new TypeInfoWildDeclaration(t);
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
t->vtinfo = t->getTypeInfoDeclaration();
|
t->vtinfo = t->getTypeInfoDeclaration();
|
||||||
assert(t->vtinfo);
|
assert(t->vtinfo);
|
||||||
|
|
||||||
/* If this has a custom implementation in std/typeinfo, then
|
/* If this has a custom implementation in std/typeinfo, then
|
||||||
* do not generate a COMDAT for it.
|
* do not generate a COMDAT for it.
|
||||||
*/
|
*/
|
||||||
if (!t->builtinTypeInfo())
|
if (!t->builtinTypeInfo())
|
||||||
{ // Generate COMDAT
|
{ // Generate COMDAT
|
||||||
if (sc) // if in semantic() pass
|
if (sc) // if in semantic() pass
|
||||||
{ // Find module that will go all the way to an object file
|
{ // Find module that will go all the way to an object file
|
||||||
Module *m = sc->module->importedFrom;
|
Module *m = sc->module->importedFrom;
|
||||||
m->members->push(t->vtinfo);
|
m->members->push(t->vtinfo);
|
||||||
}
|
}
|
||||||
else // if in obj generation pass
|
else // if in obj generation pass
|
||||||
{
|
{
|
||||||
#if IN_DMD
|
#if IN_DMD
|
||||||
t->vtinfo->toObjFile(0); // TODO: multiobj
|
t->vtinfo->toObjFile(0); // TODO: multiobj
|
||||||
#else
|
#else
|
||||||
t->vtinfo->codegen(sir);
|
t->vtinfo->codegen(sir);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
e = new VarExp(0, t->vtinfo);
|
e = new VarExp(0, t->vtinfo);
|
||||||
e = e->addressOf(sc);
|
e = e->addressOf(sc);
|
||||||
e->type = t->vtinfo->type; // do this so we don't get redundant dereference
|
e->type = t->vtinfo->type; // do this so we don't get redundant dereference
|
||||||
|
@ -239,7 +248,7 @@ int Type::builtinTypeInfo()
|
||||||
int TypeBasic::builtinTypeInfo()
|
int TypeBasic::builtinTypeInfo()
|
||||||
{
|
{
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
return !mod;
|
return mod ? 0 : 1;
|
||||||
#else
|
#else
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -260,7 +269,7 @@ int TypeClass::builtinTypeInfo()
|
||||||
* claim it is built in so it isn't regenerated by each module.
|
* claim it is built in so it isn't regenerated by each module.
|
||||||
*/
|
*/
|
||||||
#if IN_DMD
|
#if IN_DMD
|
||||||
return 1;
|
return mod ? 0 : 1;
|
||||||
#elif IN_LLVM
|
#elif IN_LLVM
|
||||||
// FIXME if I enable this, the way LDC does typeinfo will cause a bunch
|
// FIXME if I enable this, the way LDC does typeinfo will cause a bunch
|
||||||
// of linker errors to missing class typeinfo definitions.
|
// of linker errors to missing class typeinfo definitions.
|
||||||
|
@ -673,8 +682,24 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
|
#if DMDV2
|
||||||
|
void TypeInfoClassDeclaration::codegen(Ir*i)
|
||||||
|
{
|
||||||
|
|
||||||
|
IrGlobal* irg = new IrGlobal(this);
|
||||||
|
ir.irGlobal = irg;
|
||||||
|
assert(tinfo->ty == Tclass);
|
||||||
|
TypeClass *tc = (TypeClass *)tinfo;
|
||||||
|
tc->sym->codegen(Type::sir); // make sure class is resolved
|
||||||
|
irg->value = tc->sym->ir.irStruct->getClassInfoSymbol();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void TypeInfoClassDeclaration::llvmDefine()
|
void TypeInfoClassDeclaration::llvmDefine()
|
||||||
{
|
{
|
||||||
|
#if DMDV2
|
||||||
|
assert(0);
|
||||||
|
#endif
|
||||||
Logger::println("TypeInfoClassDeclaration::llvmDefine() %s", toChars());
|
Logger::println("TypeInfoClassDeclaration::llvmDefine() %s", toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
|
@ -779,4 +804,32 @@ void TypeInfoInvariantDeclaration::llvmDefine()
|
||||||
b.finalize(ir.irGlobal);
|
b.finalize(ir.irGlobal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
|
||||||
|
void TypeInfoSharedDeclaration::llvmDefine()
|
||||||
|
{
|
||||||
|
Logger::println("TypeInfoSharedDeclaration::llvmDefine() %s", toChars());
|
||||||
|
LOG_SCOPE;
|
||||||
|
|
||||||
|
RTTIBuilder b(Type::typeinfoshared);
|
||||||
|
// TypeInfo base
|
||||||
|
b.push_typeinfo(tinfo->unSharedOf()->merge());
|
||||||
|
// finish
|
||||||
|
b.finalize(ir.irGlobal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
|
||||||
|
void TypeInfoWildDeclaration::llvmDefine()
|
||||||
|
{
|
||||||
|
Logger::println("TypeInfoWildDeclaration::llvmDefine() %s", toChars());
|
||||||
|
LOG_SCOPE;
|
||||||
|
|
||||||
|
RTTIBuilder b(Type::typeinfowild);
|
||||||
|
// TypeInfo base
|
||||||
|
b.push_typeinfo(tinfo->mutableOf()->merge());
|
||||||
|
// finish
|
||||||
|
b.finalize(ir.irGlobal);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -55,6 +55,7 @@ LLGlobalVariable * IrStruct::getClassInfoSymbol()
|
||||||
// create the initZ symbol
|
// create the initZ symbol
|
||||||
std::string initname("_D");
|
std::string initname("_D");
|
||||||
initname.append(aggrdecl->mangle());
|
initname.append(aggrdecl->mangle());
|
||||||
|
|
||||||
if (aggrdecl->isInterfaceDeclaration())
|
if (aggrdecl->isInterfaceDeclaration())
|
||||||
initname.append("11__InterfaceZ");
|
initname.append("11__InterfaceZ");
|
||||||
else
|
else
|
||||||
|
@ -69,7 +70,7 @@ LLGlobalVariable * IrStruct::getClassInfoSymbol()
|
||||||
|
|
||||||
// classinfos cannot be constants since they're used a locks for synchronized
|
// classinfos cannot be constants since they're used a locks for synchronized
|
||||||
classInfo = new llvm::GlobalVariable(
|
classInfo = new llvm::GlobalVariable(
|
||||||
*gIR->module, tc->getPA().get(), false, _linkage, NULL, initname);
|
*gIR->module, tc->getPA().get(), false, _linkage, NULL, initname);
|
||||||
|
|
||||||
#if USE_METADATA
|
#if USE_METADATA
|
||||||
// Generate some metadata on this ClassInfo if it's for a class.
|
// Generate some metadata on this ClassInfo if it's for a class.
|
||||||
|
|
|
@ -78,6 +78,9 @@ struct IrFuncTy : IrBase
|
||||||
// range of normal parameters to reverse
|
// range of normal parameters to reverse
|
||||||
bool reverseParams;
|
bool reverseParams;
|
||||||
|
|
||||||
|
// arg_this is reference
|
||||||
|
bool is_arg_this_ref;
|
||||||
|
|
||||||
IrFuncTy()
|
IrFuncTy()
|
||||||
: ret(NULL),
|
: ret(NULL),
|
||||||
arg_sret(NULL),
|
arg_sret(NULL),
|
||||||
|
@ -86,7 +89,8 @@ struct IrFuncTy : IrBase
|
||||||
arg_arguments(NULL),
|
arg_arguments(NULL),
|
||||||
arg_argptr(NULL),
|
arg_argptr(NULL),
|
||||||
c_vararg(false),
|
c_vararg(false),
|
||||||
reverseParams(false)
|
reverseParams(false),
|
||||||
|
is_arg_this_ref(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
|
|
|
@ -50,6 +50,7 @@ if(D_VERSION EQUAL 1)
|
||||||
# set paths to source files, or fill lists directly
|
# set paths to source files, or fill lists directly
|
||||||
set(RUNTIME_DC_DIR ${PROJECT_SOURCE_DIR}/internal)
|
set(RUNTIME_DC_DIR ${PROJECT_SOURCE_DIR}/internal)
|
||||||
set(RUNTIME_GC_DIR ${RUNTIME_DIR}/lib/gc/basic)
|
set(RUNTIME_GC_DIR ${RUNTIME_DIR}/lib/gc/basic)
|
||||||
|
set(RUNTIME_INCLUDE ${RUNTIME_DC_DIR})
|
||||||
file(GLOB CORE_D ${RUNTIME_DIR}/lib/common/tango/core/*.d)
|
file(GLOB CORE_D ${RUNTIME_DIR}/lib/common/tango/core/*.d)
|
||||||
file(GLOB CORE_C ${RUNTIME_DIR}/lib/common/tango/stdc/*.c)
|
file(GLOB CORE_C ${RUNTIME_DIR}/lib/common/tango/stdc/*.c)
|
||||||
elseif(D_VERSION EQUAL 2)
|
elseif(D_VERSION EQUAL 2)
|
||||||
|
@ -57,9 +58,22 @@ elseif(D_VERSION EQUAL 2)
|
||||||
set(RUNTIME_GC druntime-gc-basic)
|
set(RUNTIME_GC druntime-gc-basic)
|
||||||
set(RUNTIME_DC druntime-rt-ldc)
|
set(RUNTIME_DC druntime-rt-ldc)
|
||||||
set(RUNTIME_AIO druntime-ldc)
|
set(RUNTIME_AIO druntime-ldc)
|
||||||
set(RUNTIME_DC_DIR ${RUNTIME_DIR}/src/compiler/ldc)
|
set(RUNTIME_DC_DIR ${RUNTIME_DIR}/src/rt)
|
||||||
set(RUNTIME_GC_DIR ${RUNTIME_DIR}/src/gc)
|
set(RUNTIME_GC_DIR ${RUNTIME_DIR}/src/gc)
|
||||||
|
set(RUNTIME_INCLUDE ${RUNTIME_DIR}/src)
|
||||||
file(GLOB CORE_D ${RUNTIME_DIR}/src/core/*.d )
|
file(GLOB CORE_D ${RUNTIME_DIR}/src/core/*.d )
|
||||||
|
file(GLOB CORE_D_SYNC ${RUNTIME_DIR}/src/core/sync/*.d )
|
||||||
|
if(UNIX)
|
||||||
|
file(GLOB CORE_D_SYS ${RUNTIME_DIR}/src/core/sys/posix/*.d)
|
||||||
|
elseif(WIN32)
|
||||||
|
file(GLOB CORE_D_SYS ${RUNTIME_DIR}/src/core/sys/windows/*.d)
|
||||||
|
elseif(APPLE)
|
||||||
|
file(GLOB CORE_D_SYS ${RUNTIME_DIR}/src/core/sys/osx/*.d)
|
||||||
|
endif(UNIX)
|
||||||
|
list(APPEND CORE_D ${CORE_D_SYNC} ${CORE_D_SYS} ${RUNTIME_DIR}/src/object_.d
|
||||||
|
${RUNTIME_DIR}/src/std/intrinsic.d
|
||||||
|
${RUNTIME_DIR}/src/core/stdc/stdarg.d
|
||||||
|
)
|
||||||
file(GLOB CORE_C ${RUNTIME_DIR}/src/core/stdc/*.c)
|
file(GLOB CORE_C ${RUNTIME_DIR}/src/core/stdc/*.c)
|
||||||
endif(D_VERSION EQUAL 1)
|
endif(D_VERSION EQUAL 1)
|
||||||
|
|
||||||
|
@ -107,20 +121,23 @@ file(GLOB_RECURSE GC_D ${RUNTIME_GC_DIR}/*.d)
|
||||||
file(GLOB_RECURSE DCRT_D ${RUNTIME_DC_DIR}/*.d)
|
file(GLOB_RECURSE DCRT_D ${RUNTIME_DC_DIR}/*.d)
|
||||||
file(GLOB DCRT_C ${RUNTIME_DC_DIR}/*.c)
|
file(GLOB DCRT_C ${RUNTIME_DC_DIR}/*.c)
|
||||||
|
|
||||||
# compile d file into outdir, include incdir, and append names of generated .o and .bc to outlist_o and _bc
|
macro(dc INPUT_D OUTLIST_O OUTLIST_BC INCDIR MOREFLAGS PATH)
|
||||||
macro(dc INPUT_D OUTLIST_O OUTLIST_BC OUTDIR INCDIR MOREFLAGS)
|
if ("${PATH}" STREQUAL "")
|
||||||
get_filename_component(BASENAME ${INPUT_D} NAME_WE)
|
file(RELATIVE_PATH output ${RUNTIME_DIR} ${INPUT_D})
|
||||||
set(OUTPUT_O ${PROJECT_BINARY_DIR}/${OUTDIR}/${BASENAME}.o)
|
else ("${PATH}" STREQUAL "")
|
||||||
set(OUTPUT_BC ${PROJECT_BINARY_DIR}/${OUTDIR}/${BASENAME}.bc)
|
file(RELATIVE_PATH output ${PATH} ${INPUT_D})
|
||||||
|
endif ("${PATH}" STREQUAL "")
|
||||||
|
set(OUTPUT_O ${PROJECT_BINARY_DIR}/${output}.o)
|
||||||
|
set(OUTPUT_BC ${PROJECT_BINARY_DIR}/${output}.bc)
|
||||||
list(APPEND ${OUTLIST_O} ${OUTPUT_O})
|
list(APPEND ${OUTLIST_O} ${OUTPUT_O})
|
||||||
list(APPEND ${OUTLIST_BC} ${OUTPUT_BC})
|
list(APPEND ${OUTLIST_BC} ${OUTPUT_BC})
|
||||||
|
|
||||||
# Compile
|
# Compile
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT
|
OUTPUT
|
||||||
${OUTPUT_O}
|
${OUTPUT_O}
|
||||||
${OUTPUT_BC}
|
#${OUTPUT_BC}
|
||||||
COMMAND ${LDC_LOC} -c -I${INCDIR} -I${RUNTIME_GC_DIR} -output-bc ${INPUT_D} -of${OUTPUT_O} ${D_FLAGS} ${MOREFLAGS}
|
COMMAND ${LDC_LOC} -c -I${INCDIR} -I${RUNTIME_GC_DIR} ${INPUT_D} -of${OUTPUT_O} ${D_FLAGS} ${MOREFLAGS}
|
||||||
DEPENDS ${LDC_LOC}
|
DEPENDS ${LDC_LOC}
|
||||||
${INPUT_D}
|
${INPUT_D}
|
||||||
${LDC_IMPORTS}
|
${LDC_IMPORTS}
|
||||||
|
@ -128,17 +145,20 @@ macro(dc INPUT_D OUTLIST_O OUTLIST_BC OUTDIR INCDIR MOREFLAGS)
|
||||||
)
|
)
|
||||||
endmacro(dc)
|
endmacro(dc)
|
||||||
|
|
||||||
# dc_dir include for core and gc only necessary with druntime
|
|
||||||
foreach(f ${CORE_D})
|
foreach(f ${CORE_D})
|
||||||
dc(${f} CORE_O CORE_BC core ${RUNTIME_DC_DIR} "")
|
dc(${f} CORE_O CORE_BC ${RUNTIME_INCLUDE} "" "")
|
||||||
endforeach(f)
|
endforeach(f)
|
||||||
|
|
||||||
foreach(f ${GC_D})
|
foreach(f ${GC_D})
|
||||||
dc(${f} GC_O GC_BC gc "${RUNTIME_GC_DIR} ${RUNTIME_DC_DIR}" "-disable-invariants")
|
dc(${f} GC_O GC_BC ${RUNTIME_INCLUDE} "-disable-invariants" "")
|
||||||
endforeach(f)
|
endforeach(f)
|
||||||
|
|
||||||
foreach(f ${DCRT_D})
|
foreach(f ${DCRT_D})
|
||||||
dc(${f} DCRT_O DCRT_BC dcrt ${RUNTIME_DC_DIR} "")
|
if(D_VERSION EQUAL 1)
|
||||||
|
dc(${f} DCRT_O DCRT_BC ${RUNTIME_INCLUDE} "" ${RUNTIME_DC_DIR})
|
||||||
|
else(D_VERSION EQUAL 1)
|
||||||
|
dc(${f} DCRT_O DCRT_BC ${RUNTIME_INCLUDE} "" "")
|
||||||
|
endif(D_VERSION EQUAL 1)
|
||||||
endforeach(f)
|
endforeach(f)
|
||||||
|
|
||||||
if(BUILD_SINGLE_LIB)
|
if(BUILD_SINGLE_LIB)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue