mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-26 08:33:14 +01:00
[svn r149] fixed: a bunch of D-style variadics problems.
fixed: GotoDefaultStatement implemented. fixed: some other minor bugs.
This commit is contained in:
@@ -1955,6 +1955,8 @@ SwitchStatement::SwitchStatement(Loc loc, Expression *c, Statement *b)
|
||||
sdefault = NULL;
|
||||
cases = NULL;
|
||||
hasNoDefault = 0;
|
||||
// LLVMDC
|
||||
defaultBB = NULL;
|
||||
}
|
||||
|
||||
Statement *SwitchStatement::syntaxCopy()
|
||||
|
||||
@@ -416,6 +416,9 @@ struct SwitchStatement : Statement
|
||||
Statement *inlineScan(InlineScanState *iss);
|
||||
|
||||
void toIR(IRState *irs);
|
||||
|
||||
// LLVMDC
|
||||
llvm::BasicBlock* defaultBB;
|
||||
};
|
||||
|
||||
struct CaseStatement : Statement
|
||||
|
||||
@@ -446,6 +446,7 @@ void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src)
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void DtoStaticArrayCopy(llvm::Value* dst, llvm::Value* src)
|
||||
{
|
||||
Logger::cout() << "static array copy: " << *dst << " from " << *src << '\n';
|
||||
assert(dst->getType() == src->getType());
|
||||
size_t arrsz = getABITypeSize(dst->getType()->getContainedType(0));
|
||||
llvm::Value* n = llvm::ConstantInt::get(DtoSize_t(), arrsz, false);
|
||||
|
||||
@@ -321,7 +321,12 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
bool declareOnly = false;
|
||||
bool templInst = fdecl->parent && DtoIsTemplateInstance(fdecl->parent);
|
||||
if (!templInst && fdecl->getModule() != gIR->dmodule)
|
||||
{
|
||||
Logger::println("not template instance, and not in this module. declare only!");
|
||||
Logger::println("current module: %s", gIR->dmodule->ident->toChars());
|
||||
Logger::println("func module: %s", fdecl->getModule()->ident->toChars());
|
||||
declareOnly = true;
|
||||
}
|
||||
else if (fdecl->llvmInternal == LLVMva_start)
|
||||
declareOnly = true;
|
||||
|
||||
@@ -548,11 +553,15 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
||||
}
|
||||
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
|
||||
VarDeclaration* vd = *i;
|
||||
Logger::println("referenced nested variable %s", vd->toChars());
|
||||
if (!vd->irLocal)
|
||||
vd->irLocal = new IrLocal(vd);
|
||||
vd->irLocal->nestedIndex = j++;
|
||||
if (vd->isParameter()) {
|
||||
|
||||
if (!vd->irLocal->value) {
|
||||
assert(vd == fd->vthis);
|
||||
vd->irLocal->value = fd->irFunc->thisVar;
|
||||
}
|
||||
assert(vd->irLocal->value);
|
||||
nestTypes.push_back(vd->irLocal->value->getType());
|
||||
}
|
||||
|
||||
@@ -52,13 +52,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||
|
||||
if (exp)
|
||||
{
|
||||
Logger::println("return type is: %s", exp->type->toChars());
|
||||
|
||||
Type* exptype = DtoDType(exp->type);
|
||||
TY expty = exptype->ty;
|
||||
if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
|
||||
assert(DtoIsPassedByRef(exptype));
|
||||
|
||||
IrFunction* f = p->func();
|
||||
assert(f->type->llvmRetInPtr);
|
||||
assert(f->decl->irFunc->retArg);
|
||||
@@ -320,6 +314,7 @@ void ForStatement::toIR(IRState* p)
|
||||
init->toIR(p);
|
||||
|
||||
// move into the for condition block, ie. start the loop
|
||||
assert(!gIR->scopereturned());
|
||||
new llvm::BranchInst(forbb, gIR->scopebb());
|
||||
|
||||
p->loopbbs.push_back(IRScope(forincbb,endbb));
|
||||
@@ -333,7 +328,8 @@ void ForStatement::toIR(IRState* p)
|
||||
delete cond_e;
|
||||
|
||||
// conditional branch
|
||||
llvm::Value* ifbreak = new llvm::BranchInst(forbodybb, endbb, cond_val, forbb);
|
||||
assert(!gIR->scopereturned());
|
||||
new llvm::BranchInst(forbodybb, endbb, cond_val, gIR->scopebb());
|
||||
|
||||
// rewrite scope
|
||||
gIR->scope() = IRScope(forbodybb,forincbb);
|
||||
@@ -674,6 +670,7 @@ void SwitchStatement::toIR(IRState* p)
|
||||
llvm::BasicBlock* defbb = 0;
|
||||
if (!hasNoDefault) {
|
||||
defbb = new llvm::BasicBlock("default", p->topfunc(), oldend);
|
||||
defaultBB = defbb;
|
||||
}
|
||||
|
||||
// end (break point)
|
||||
@@ -982,6 +979,22 @@ void GotoStatement::toIR(IRState* p)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GotoDefaultStatement::toIR(IRState* p)
|
||||
{
|
||||
Logger::println("GotoDefaultStatement::toIR(): %s", loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
llvm::BasicBlock* oldend = gIR->scopeend();
|
||||
llvm::BasicBlock* bb = new llvm::BasicBlock("aftergotodefault", p->topfunc(), oldend);
|
||||
|
||||
assert(!p->scopereturned());
|
||||
assert(sw->defaultBB);
|
||||
new llvm::BranchInst(sw->defaultBB, p->scopebb());
|
||||
p->scope() = IRScope(bb,oldend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void WithStatement::toIR(IRState* p)
|
||||
{
|
||||
Logger::println("WithStatement::toIR(): %s", loc.toChars());
|
||||
@@ -1085,7 +1098,7 @@ STUBST(Statement);
|
||||
//STUBST(LabelStatement);
|
||||
//STUBST(ThrowStatement);
|
||||
STUBST(GotoCaseStatement);
|
||||
STUBST(GotoDefaultStatement);
|
||||
//STUBST(GotoDefaultStatement);
|
||||
//STUBST(GotoStatement);
|
||||
//STUBST(UnrolledLoopStatement);
|
||||
//STUBST(OnScopeStatement);
|
||||
|
||||
77
gen/toir.cpp
77
gen/toir.cpp
@@ -153,19 +153,25 @@ DValue* VarExp::toElem(IRState* p)
|
||||
if (vd->ident == Id::_arguments)
|
||||
{
|
||||
Logger::println("Id::_arguments");
|
||||
if (!vd->getIrValue())
|
||||
/*if (!vd->getIrValue())
|
||||
vd->getIrValue() = p->func()->decl->irFunc->_arguments;
|
||||
assert(vd->getIrValue());
|
||||
return new DVarValue(vd, vd->getIrValue(), true);
|
||||
return new DVarValue(vd, vd->getIrValue(), true);*/
|
||||
llvm::Value* v = p->func()->decl->irFunc->_arguments;
|
||||
assert(v);
|
||||
return new DVarValue(vd, v, true);
|
||||
}
|
||||
// _argptr
|
||||
else if (vd->ident == Id::_argptr)
|
||||
{
|
||||
Logger::println("Id::_argptr");
|
||||
if (!vd->getIrValue())
|
||||
/*if (!vd->getIrValue())
|
||||
vd->getIrValue() = p->func()->decl->irFunc->_argptr;
|
||||
assert(vd->getIrValue());
|
||||
return new DVarValue(vd, vd->getIrValue(), true);
|
||||
return new DVarValue(vd, vd->getIrValue(), true);*/
|
||||
llvm::Value* v = p->func()->decl->irFunc->_argptr;
|
||||
assert(v);
|
||||
return new DVarValue(vd, v, true);
|
||||
}
|
||||
// _dollar
|
||||
else if (vd->ident == Id::dollar)
|
||||
@@ -1048,9 +1054,14 @@ DValue* CallExp::toElem(IRState* p)
|
||||
std::vector<const llvm::Type*> vtypes;
|
||||
std::vector<llvm::Value*> vtypeinfos;
|
||||
|
||||
// number of non variadic args
|
||||
int begin = tf->parameters->dim;
|
||||
Logger::println("num non vararg params = %d", begin);
|
||||
|
||||
// build struct with argument types
|
||||
for (int i=0; i<arguments->dim; i++)
|
||||
for (int i=begin; i<arguments->dim; i++)
|
||||
{
|
||||
Argument* argu = Argument::getNth(tf->parameters, i);
|
||||
Expression* argexp = (Expression*)arguments->data[i];
|
||||
vtypes.push_back(DtoType(argexp->type));
|
||||
}
|
||||
@@ -1059,30 +1070,30 @@ DValue* CallExp::toElem(IRState* p)
|
||||
llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint());
|
||||
|
||||
// store arguments in the struct
|
||||
for (int i=0; i<arguments->dim; i++)
|
||||
for (int i=begin,k=0; i<arguments->dim; i++,k++)
|
||||
{
|
||||
Expression* argexp = (Expression*)arguments->data[i];
|
||||
if (global.params.llvmAnnotate)
|
||||
DtoAnnotation(argexp->toChars());
|
||||
DtoVariadicArgument(argexp, DtoGEPi(mem,0,i,"tmp"));
|
||||
DtoVariadicArgument(argexp, DtoGEPi(mem,0,k,"tmp"));
|
||||
}
|
||||
|
||||
// build type info array
|
||||
assert(Type::typeinfo->irStruct->constInit);
|
||||
const llvm::Type* typeinfotype = getPtrToType(Type::typeinfo->irStruct->constInit->getType());
|
||||
Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n';
|
||||
const llvm::Type* typeinfotype = DtoType(Type::typeinfo->type);
|
||||
const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
|
||||
|
||||
llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint());
|
||||
for (int i=0; i<arguments->dim; i++)
|
||||
Logger::cout() << "_arguments storage: " << *typeinfomem << '\n';
|
||||
for (int i=begin,k=0; i<arguments->dim; i++,k++)
|
||||
{
|
||||
Expression* argexp = (Expression*)arguments->data[i];
|
||||
TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration();
|
||||
DtoForceDeclareDsymbol(tidecl);
|
||||
assert(tidecl->getIrValue());
|
||||
vtypeinfos.push_back(tidecl->getIrValue());
|
||||
llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp");
|
||||
p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp"));
|
||||
llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[k], typeinfotype, "tmp");
|
||||
p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,k,"tmp"));
|
||||
}
|
||||
|
||||
// put data in d-array
|
||||
@@ -1096,7 +1107,18 @@ DValue* CallExp::toElem(IRState* p)
|
||||
j++;
|
||||
llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp");
|
||||
j++;
|
||||
llargs.resize(nimplicit+2);
|
||||
|
||||
// pass non variadic args
|
||||
for (int i=0; i<begin; i++)
|
||||
{
|
||||
Argument* fnarg = Argument::getNth(tf->parameters, i);
|
||||
DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
|
||||
llargs[j] = argval->getRVal();
|
||||
j++;
|
||||
}
|
||||
|
||||
// make sure arg vector has the right size
|
||||
llargs.resize(nimplicit+begin+2);
|
||||
}
|
||||
// normal function
|
||||
else {
|
||||
@@ -1122,20 +1144,23 @@ DValue* CallExp::toElem(IRState* p)
|
||||
}
|
||||
}
|
||||
}
|
||||
Logger::println("%d params passed", n);
|
||||
for (int i=0; i<n; ++i) {
|
||||
assert(llargs[i]);
|
||||
Logger::cout() << *llargs[i] << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
Logger::println("%d params passed", n);
|
||||
for (int i=0; i<llargs.size(); ++i) {
|
||||
assert(llargs[i]);
|
||||
Logger::cout() << "arg["<<i<<"] = " << *llargs[i] << '\n';
|
||||
}
|
||||
#endif
|
||||
|
||||
// void returns cannot not be named
|
||||
const char* varname = "";
|
||||
if (llfnty->getReturnType() != llvm::Type::VoidTy)
|
||||
varname = "tmp";
|
||||
|
||||
//Logger::cout() << "Calling: " << *funcval << '\n';
|
||||
Logger::cout() << "Calling: " << *funcval << '\n';
|
||||
|
||||
// call the function
|
||||
llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb());
|
||||
@@ -2263,6 +2288,11 @@ DValue* IdentityExp::toElem(IRState* p)
|
||||
}
|
||||
eval = DtoDynArrayIs(op,l,r);
|
||||
}
|
||||
else if (t1->isfloating())
|
||||
{
|
||||
llvm::FCmpInst::Predicate pred = (op == TOKidentity) ? llvm::FCmpInst::FCMP_OEQ : llvm::FCmpInst::FCMP_ONE;
|
||||
eval = new llvm::FCmpInst(pred, l, r, "tmp", p->scopebb());
|
||||
}
|
||||
else {
|
||||
llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
|
||||
if (t1->ty == Tpointer && v->isNull() && l->getType() != r->getType()) {
|
||||
@@ -2283,6 +2313,7 @@ DValue* CommaExp::toElem(IRState* p)
|
||||
|
||||
DValue* u = e1->toElem(p);
|
||||
DValue* v = e2->toElem(p);
|
||||
assert(e2->type == type);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -2991,7 +3022,9 @@ AsmStatement::AsmStatement(Loc loc, Token *tokens) :
|
||||
}
|
||||
Statement *AsmStatement::syntaxCopy()
|
||||
{
|
||||
assert(0);
|
||||
/*error("%s: inline asm is not yet implemented", loc.toChars());
|
||||
fatal();
|
||||
assert(0);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3008,7 +3041,9 @@ void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
|
||||
int AsmStatement::comeFrom()
|
||||
{
|
||||
assert(0);
|
||||
/*error("%s: inline asm is not yet implemented", loc.toChars());
|
||||
fatal();
|
||||
assert(0);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -346,13 +346,16 @@ llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs)
|
||||
|
||||
llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc)
|
||||
{
|
||||
// turns out we can't really make anything internal with the way D works :(
|
||||
// the things we can need much more info than this can extract.
|
||||
// TODO : remove this useless function
|
||||
switch(prot)
|
||||
{
|
||||
case PROTprivate:
|
||||
if (stc & STCextern)
|
||||
//if (stc & STCextern)
|
||||
return llvm::GlobalValue::ExternalLinkage;
|
||||
else
|
||||
return llvm::GlobalValue::InternalLinkage;
|
||||
//else
|
||||
// return llvm::GlobalValue::InternalLinkage;
|
||||
|
||||
case PROTpublic:
|
||||
case PROTpackage:
|
||||
@@ -902,7 +905,12 @@ void DtoAssign(DValue* lhs, DValue* rhs)
|
||||
}
|
||||
}
|
||||
else if (t->ty == Tsarray) {
|
||||
DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal());
|
||||
if (DtoType(lhs->getType()) == DtoType(rhs->getType())) {
|
||||
DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal());
|
||||
}
|
||||
else {
|
||||
DtoArrayInit(lhs->getLVal(), rhs->getRVal());
|
||||
}
|
||||
}
|
||||
else if (t->ty == Tdelegate) {
|
||||
if (rhs->isNull())
|
||||
|
||||
@@ -601,7 +601,7 @@
|
||||
</environments>
|
||||
</make>
|
||||
<general>
|
||||
<activedir>ir</activedir>
|
||||
<activedir>tangotests</activedir>
|
||||
</general>
|
||||
</kdevcustomproject>
|
||||
<cppsupportpart>
|
||||
|
||||
@@ -765,7 +765,9 @@ tangotests/p.d
|
||||
tangotests/q.d
|
||||
tangotests/r.d
|
||||
tangotests/s.d
|
||||
tangotests/stdout1.d
|
||||
tangotests/t.d
|
||||
tangotests/v.d
|
||||
test
|
||||
test/a.d
|
||||
test/aa1.d
|
||||
|
||||
@@ -15,6 +15,33 @@ version( GNU )
|
||||
{
|
||||
public import std.stdarg;
|
||||
}
|
||||
else version( LLVMDC )
|
||||
{
|
||||
/**
|
||||
* The base vararg list type.
|
||||
*/
|
||||
alias void* va_list;
|
||||
|
||||
/**
|
||||
* This function returns the next argument in the sequence referenced by
|
||||
* the supplied argument pointer. The argument pointer will be adjusted
|
||||
* to point to the next arggument in the sequence.
|
||||
*
|
||||
* Params:
|
||||
* vp = The argument pointer.
|
||||
*
|
||||
* Returns:
|
||||
* The next argument in the sequence. The result is undefined if vp
|
||||
* does not point to a valid argument.
|
||||
*/
|
||||
T va_arg(T)(ref va_list vp)
|
||||
{
|
||||
size_t size = T.sizeof > size_t.sizeof ? size_t.sizeof : T.sizeof;
|
||||
va_list vptmp = cast(va_list)((cast(size_t)vp + size - 1) & ~(size - 1));
|
||||
vp = vptmp + T.sizeof;
|
||||
return *cast(T*)vptmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,22 @@ version( GNU )
|
||||
{
|
||||
public import std.c.stdarg;
|
||||
}
|
||||
else version( LLVMDC )
|
||||
{
|
||||
alias void* va_list;
|
||||
|
||||
pragma(LLVM_internal, "va_start")
|
||||
void va_start(T)(va_list ap, ref T);
|
||||
|
||||
pragma(LLVM_internal, "va_arg")
|
||||
T va_arg(T)(va_list ap);
|
||||
|
||||
pragma(LLVM_internal, "va_intrinsic", "llvm.va_end")
|
||||
void va_end(va_list args);
|
||||
|
||||
pragma(LLVM_internal, "va_intrinsic", "llvm.va_copy")
|
||||
void va_copy(va_list dst, va_list src);
|
||||
}
|
||||
else
|
||||
{
|
||||
alias void* va_list;
|
||||
|
||||
@@ -44,6 +44,12 @@ version (DigitalMars)
|
||||
alias void* Arg;
|
||||
alias void* ArgList;
|
||||
}
|
||||
else version(LLVMDC)
|
||||
{
|
||||
private import tango.core.Vararg;
|
||||
alias void* Arg;
|
||||
alias va_list ArgList;
|
||||
}
|
||||
else
|
||||
version (X86_64)
|
||||
{
|
||||
@@ -617,7 +623,7 @@ class Layout(T)
|
||||
|
||||
protected T[] unknown (T[] result, T[] format, TypeInfo type, Arg p)
|
||||
{
|
||||
return "{unhandled argument type: " ~ fromUtf8 (type.toString, result) ~ "}";
|
||||
return cast(T[])("{unhandled argument type: " ~ fromUtf8 (type.toString, result) ~ "}");
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
Reference in New Issue
Block a user