[svn r149] fixed: a bunch of D-style variadics problems.

fixed: GotoDefaultStatement implemented.
fixed: some other minor bugs.
This commit is contained in:
Tomas Lindquist Olsen
2008-01-26 17:13:22 +01:00
parent adc75dd377
commit 64537a9478
12 changed files with 158 additions and 36 deletions

View File

@@ -1955,6 +1955,8 @@ SwitchStatement::SwitchStatement(Loc loc, Expression *c, Statement *b)
sdefault = NULL;
cases = NULL;
hasNoDefault = 0;
// LLVMDC
defaultBB = NULL;
}
Statement *SwitchStatement::syntaxCopy()

View File

@@ -416,6 +416,9 @@ struct SwitchStatement : Statement
Statement *inlineScan(InlineScanState *iss);
void toIR(IRState *irs);
// LLVMDC
llvm::BasicBlock* defaultBB;
};
struct CaseStatement : Statement

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -601,7 +601,7 @@
</environments>
</make>
<general>
<activedir>ir</activedir>
<activedir>tangotests</activedir>
</general>
</kdevcustomproject>
<cppsupportpart>

View File

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

View File

@@ -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
{
/**

View File

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

View File

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