mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-14 15:16:07 +03:00
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
This commit is contained in:
parent
db2b3d1937
commit
06362014f4
8 changed files with 100 additions and 61 deletions
|
@ -787,8 +787,6 @@ void FuncDeclaration::semantic3(Scope *sc)
|
||||||
parameters->push(v);
|
parameters->push(v);
|
||||||
localsymtab->insert(v);
|
localsymtab->insert(v);
|
||||||
v->parent = this;
|
v->parent = this;
|
||||||
// for llvm d
|
|
||||||
arg->vardecl = v;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5057,7 +5057,6 @@ Argument::Argument(unsigned storageClass, Type *type, Identifier *ident, Express
|
||||||
this->ident = ident;
|
this->ident = ident;
|
||||||
this->storageClass = storageClass;
|
this->storageClass = storageClass;
|
||||||
this->defaultArg = defaultArg;
|
this->defaultArg = defaultArg;
|
||||||
this->vardecl = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Argument *Argument::syntaxCopy()
|
Argument *Argument::syntaxCopy()
|
||||||
|
|
|
@ -674,9 +674,6 @@ struct Argument : Object
|
||||||
static void argsToDecoBuffer(OutBuffer *buf, Arguments *arguments);
|
static void argsToDecoBuffer(OutBuffer *buf, Arguments *arguments);
|
||||||
static size_t dim(Arguments *arguments);
|
static size_t dim(Arguments *arguments);
|
||||||
static Argument *getNth(Arguments *arguments, size_t nth, size_t *pn = NULL);
|
static Argument *getNth(Arguments *arguments, size_t nth, size_t *pn = NULL);
|
||||||
|
|
||||||
// backend
|
|
||||||
VarDeclaration* vardecl;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int PTRSIZE;
|
extern int PTRSIZE;
|
||||||
|
|
|
@ -604,6 +604,17 @@ void DtoCatArrayElement(llvm::Value* arr, Expression* exp1, Expression* exp2)
|
||||||
Type* t1 = DtoDType(exp1->type);
|
Type* t1 = DtoDType(exp1->type);
|
||||||
Type* t2 = DtoDType(exp2->type);
|
Type* t2 = DtoDType(exp2->type);
|
||||||
|
|
||||||
|
// handle reverse case
|
||||||
|
if (t2->next && t1 == DtoDType(t2->next))
|
||||||
|
{
|
||||||
|
Type* tmp = t1;
|
||||||
|
t1 = t2;
|
||||||
|
t2 = tmp;
|
||||||
|
Expression* e = exp1;
|
||||||
|
exp1 = exp2;
|
||||||
|
exp2 = e;
|
||||||
|
}
|
||||||
|
|
||||||
assert(t1->ty == Tarray);
|
assert(t1->ty == Tarray);
|
||||||
assert(t2 == DtoDType(t1->next));
|
assert(t2 == DtoDType(t1->next));
|
||||||
|
|
||||||
|
@ -778,7 +789,7 @@ llvm::Value* DtoDynArrayIs(TOK op, llvm::Value* l, llvm::Value* r)
|
||||||
|
|
||||||
if (r == NULL) {
|
if (r == NULL) {
|
||||||
llvm::Value* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp");
|
llvm::Value* ll = gIR->ir->CreateLoad(DtoGEPi(l, 0,0, "tmp"),"tmp");
|
||||||
llvm::Value* rl = DtoConstSize_t(0);
|
llvm::Value* rl = llvm::Constant::getNullValue(ll->getType());//DtoConstSize_t(0);
|
||||||
llvm::Value* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
|
llvm::Value* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp");
|
||||||
|
|
||||||
llvm::Value* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp");
|
llvm::Value* lp = gIR->ir->CreateLoad(DtoGEPi(l, 0,1, "tmp"),"tmp");
|
||||||
|
|
|
@ -28,8 +28,13 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const llvm::Type* thistype
|
||||||
}
|
}
|
||||||
|
|
||||||
bool typesafeVararg = false;
|
bool typesafeVararg = false;
|
||||||
if (f->linkage == LINKd && f->varargs == 1) {
|
bool arrayVararg = false;
|
||||||
|
if (f->linkage == LINKd)
|
||||||
|
{
|
||||||
|
if (f->varargs == 1)
|
||||||
typesafeVararg = true;
|
typesafeVararg = true;
|
||||||
|
else if (f->varargs == 2)
|
||||||
|
arrayVararg = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return value type
|
// return value type
|
||||||
|
@ -82,6 +87,10 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const llvm::Type* thistype
|
||||||
paramvec.push_back(getPtrToType(t1));
|
paramvec.push_back(getPtrToType(t1));
|
||||||
paramvec.push_back(getPtrToType(llvm::Type::Int8Ty));
|
paramvec.push_back(getPtrToType(llvm::Type::Int8Ty));
|
||||||
}
|
}
|
||||||
|
else if (arrayVararg)
|
||||||
|
{
|
||||||
|
// do nothing?
|
||||||
|
}
|
||||||
|
|
||||||
size_t n = Argument::dim(f->parameters);
|
size_t n = Argument::dim(f->parameters);
|
||||||
|
|
||||||
|
@ -120,7 +129,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const llvm::Type* thistype
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct function type
|
// construct function type
|
||||||
bool isvararg = !typesafeVararg && f->varargs;
|
bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs;
|
||||||
llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
|
llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
|
||||||
|
|
||||||
f->llvmRetInPtr = retinptr;
|
f->llvmRetInPtr = retinptr;
|
||||||
|
@ -383,6 +392,9 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||||
gIR->dtors.push_back(fdecl);
|
gIR->dtors.push_back(fdecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we never reference parameters of function prototypes
|
||||||
|
if (!declareOnly)
|
||||||
|
{
|
||||||
// name parameters
|
// name parameters
|
||||||
llvm::Function::arg_iterator iarg = func->arg_begin();
|
llvm::Function::arg_iterator iarg = func->arg_begin();
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
@ -409,27 +421,22 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||||
|
|
||||||
for (; iarg != func->arg_end(); ++iarg)
|
for (; iarg != func->arg_end(); ++iarg)
|
||||||
{
|
{
|
||||||
Argument* arg = Argument::getNth(f->parameters, k++);
|
if (fdecl->parameters && fdecl->parameters->dim > k)
|
||||||
//arg->llvmValue = iarg;
|
|
||||||
//Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident);
|
|
||||||
if (arg && arg->ident != 0) {
|
|
||||||
if (arg->vardecl) {
|
|
||||||
if (gIR->irDsymbol[arg->vardecl].irLocal)
|
|
||||||
{
|
{
|
||||||
Logger::cout() << "WTF!?!: " << *gIR->irDsymbol[arg->vardecl].irLocal->value << '\n';
|
Dsymbol* argsym = (Dsymbol*)fdecl->parameters->data[k++];
|
||||||
|
VarDeclaration* argvd = argsym->isVarDeclaration();
|
||||||
|
assert(argvd);
|
||||||
|
assert(!gIR->irDsymbol[argvd].irLocal);
|
||||||
|
gIR->irDsymbol[argvd].irLocal = new IrLocal(argvd);
|
||||||
|
gIR->irDsymbol[argvd].irLocal->value = iarg;
|
||||||
|
iarg->setName(argvd->ident->toChars());
|
||||||
}
|
}
|
||||||
assert(!gIR->irDsymbol[arg->vardecl].irLocal);
|
else
|
||||||
assert(!gIR->irDsymbol[arg->vardecl].irGlobal);
|
{
|
||||||
assert(!gIR->irDsymbol[arg->vardecl].irField);
|
|
||||||
gIR->irDsymbol[arg->vardecl].irLocal = new IrLocal(arg->vardecl);
|
|
||||||
gIR->irDsymbol[arg->vardecl].irLocal->value = iarg;
|
|
||||||
}
|
|
||||||
iarg->setName(arg->ident->toChars());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
iarg->setName("unnamed");
|
iarg->setName("unnamed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fdecl->isUnitTestDeclaration())
|
if (fdecl->isUnitTestDeclaration())
|
||||||
gIR->unitTests.push_back(fdecl);
|
gIR->unitTests.push_back(fdecl);
|
||||||
|
@ -500,25 +507,28 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// give arguments storage
|
// give arguments storage
|
||||||
size_t n = Argument::dim(f->parameters);
|
if (fd->parameters)
|
||||||
for (int i=0; i < n; ++i) {
|
{
|
||||||
Argument* arg = Argument::getNth(f->parameters, i);
|
size_t n = fd->parameters->dim;
|
||||||
if (arg && arg->vardecl) {
|
for (int i=0; i < n; ++i)
|
||||||
VarDeclaration* vd = arg->vardecl;
|
{
|
||||||
|
Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i];
|
||||||
|
VarDeclaration* vd = argsym->isVarDeclaration();
|
||||||
|
assert(vd);
|
||||||
|
|
||||||
if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
|
if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
llvm::Value* a = gIR->irDsymbol[vd].irLocal->value;
|
llvm::Value* a = gIR->irDsymbol[vd].irLocal->value;
|
||||||
assert(a);
|
assert(a);
|
||||||
std::string s(a->getName());
|
std::string s(a->getName());
|
||||||
Logger::println("giving argument '%s' storage", s.c_str());
|
Logger::println("giving argument '%s' storage", s.c_str());
|
||||||
s.append("_storage");
|
s.append("_storage");
|
||||||
|
|
||||||
llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
|
llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
|
||||||
gIR->ir->CreateStore(a,v);
|
gIR->ir->CreateStore(a,v);
|
||||||
gIR->irDsymbol[vd].irLocal->value = v;
|
gIR->irDsymbol[vd].irLocal->value = v;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
Logger::attention(fd->loc, "some unknown argument: %s", arg ? arg->toChars() : 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// debug info
|
// debug info
|
||||||
|
|
10
gen/toir.cpp
10
gen/toir.cpp
|
@ -253,6 +253,7 @@ DValue* VarExp::toElem(IRState* p)
|
||||||
assert(sdecltype->ty == Tstruct);
|
assert(sdecltype->ty == Tstruct);
|
||||||
TypeStruct* ts = (TypeStruct*)sdecltype;
|
TypeStruct* ts = (TypeStruct*)sdecltype;
|
||||||
assert(ts->sym);
|
assert(ts->sym);
|
||||||
|
DtoForceConstInitDsymbol(ts->sym);
|
||||||
assert(gIR->irDsymbol[ts->sym].irStruct->init);
|
assert(gIR->irDsymbol[ts->sym].irStruct->init);
|
||||||
return new DVarValue(type, gIR->irDsymbol[ts->sym].irStruct->init, true);
|
return new DVarValue(type, gIR->irDsymbol[ts->sym].irStruct->init, true);
|
||||||
}
|
}
|
||||||
|
@ -2291,6 +2292,15 @@ DValue* IdentityExp::toElem(IRState* p)
|
||||||
}
|
}
|
||||||
eval = DtoDynArrayIs(op,l,r);
|
eval = DtoDynArrayIs(op,l,r);
|
||||||
}
|
}
|
||||||
|
else if (t1->ty == Tdelegate) {
|
||||||
|
if (v->isNull()) {
|
||||||
|
r = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(l->getType() == r->getType());
|
||||||
|
}
|
||||||
|
eval = DtoDynArrayIs(op,l,r);
|
||||||
|
}
|
||||||
else if (t1->isfloating())
|
else if (t1->isfloating())
|
||||||
{
|
{
|
||||||
llvm::FCmpInst::Predicate pred = (op == TOKidentity) ? llvm::FCmpInst::FCMP_OEQ : llvm::FCmpInst::FCMP_ONE;
|
llvm::FCmpInst::Predicate pred = (op == TOKidentity) ? llvm::FCmpInst::FCMP_OEQ : llvm::FCmpInst::FCMP_ONE;
|
||||||
|
|
|
@ -753,6 +753,7 @@ tangotests/constructors.d
|
||||||
tangotests/d.d
|
tangotests/d.d
|
||||||
tangotests/e.d
|
tangotests/e.d
|
||||||
tangotests/f.d
|
tangotests/f.d
|
||||||
|
tangotests/files1.d
|
||||||
tangotests/g.d
|
tangotests/g.d
|
||||||
tangotests/h.d
|
tangotests/h.d
|
||||||
tangotests/i.d
|
tangotests/i.d
|
||||||
|
@ -768,6 +769,7 @@ tangotests/r.d
|
||||||
tangotests/s.d
|
tangotests/s.d
|
||||||
tangotests/stdout1.d
|
tangotests/stdout1.d
|
||||||
tangotests/t.d
|
tangotests/t.d
|
||||||
|
tangotests/vararg1.d
|
||||||
test
|
test
|
||||||
test/a.d
|
test/a.d
|
||||||
test/aa1.d
|
test/aa1.d
|
||||||
|
|
12
tangotests/files1.d
Normal file
12
tangotests/files1.d
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
module tangotests.files1;
|
||||||
|
|
||||||
|
//import tango.io.Stdout;
|
||||||
|
import tango.io.File;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
auto file = new File("files1.output");
|
||||||
|
char[] str = "hello world from files1 test\n";
|
||||||
|
void[] data = cast(void[])str;
|
||||||
|
file.write(str);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue