Fix VarDecls for tuples. Closes #99.

I've implemented it this way since it doesn't require any changes in the
frontend. However, I think having TypeTuple expressed as LLVM struct types
would make much more sense and open the door to tuple lvalues.
This commit is contained in:
Christian Kamm
2008-10-05 11:47:47 +02:00
parent 40d0df8769
commit 2a999b72e8
4 changed files with 86 additions and 0 deletions

View File

@@ -1129,6 +1129,12 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
{
Logger::println("VarDeclaration");
// if aliassym is set, this VarDecl is redone as an alias to another symbol
// this seems to be done to rewrite Tuple!(...) v;
// as a TupleDecl that contains a bunch of individual VarDecls
if (vd->aliassym)
return DtoDeclarationExp(vd->aliassym);
// static
if (vd->isDataseg())
{
@@ -1249,6 +1255,22 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
DtoDeclarationExp(mdsym);
}
}
// tuple declaration
else if (TupleDeclaration* tupled = declaration->isTupleDeclaration())
{
Logger::println("TupleDeclaration");
if(!tupled->isexp) {
error(declaration->loc, "don't know how to handle non-expression tuple decls yet");
assert(0);
}
assert(tupled->objects);
for (int i=0; i < tupled->objects->dim; ++i)
{
DsymbolExp* exp = (DsymbolExp*)tupled->objects->data[i];
DtoDeclarationExp(exp->s);
}
}
// unsupported declaration
else
{

View File

@@ -169,6 +169,16 @@ const LLType* DtoType(Type* t)
return getPtrToType(LLStructType::get(DtoType(taa->key), DtoType(taa->next), 0));
}
/*
Not needed atm as VarDecls for tuples are rewritten as a string of
VarDecls for the fields (u -> _u_field_0, ...)
case Ttuple:
{
TypeTuple* ttupl = (TypeTuple*)t;
return DtoStructTypeFromArguments(ttupl->arguments);
}
*/
// opaque type
case Topaque:
return llvm::OpaqueType::get();
@@ -182,6 +192,26 @@ const LLType* DtoType(Type* t)
//////////////////////////////////////////////////////////////////////////////////////////
/*
const LLType* DtoStructTypeFromArguments(Arguments* arguments)
{
if (!arguments)
return LLType::VoidTy;
std::vector<const LLType*> types;
for (size_t i = 0; i < arguments->dim; i++)
{
Argument *arg = (Argument *)arguments->data[i];
assert(arg && arg->type);
types.push_back(DtoType(arg->type));
}
return LLStructType::get(types);
}
*/
//////////////////////////////////////////////////////////////////////////////////////////
const LLType* DtoTypeNotVoid(Type* t)
{
const LLType* lt = DtoType(t);

View File

@@ -23,6 +23,10 @@ bool DtoIsReturnedInArg(Type* type);
unsigned DtoShouldExtend(Type* type);
// tuple helper
// takes a arguments list and makes a struct type out of them
//const LLType* DtoStructTypeFromArguments(Arguments* arguments);
// delegate helpers
const LLStructType* DtoDelegateType(Type* t);
LLValue* DtoDelegateEquals(TOK op, LLValue* lhs, LLValue* rhs);

30
tests/mini/tupleval.d Normal file
View File

@@ -0,0 +1,30 @@
module foo;
template ParameterTupleOf( Fn )
{
static if( is( Fn Params == function ) )
alias Params ParameterTupleOf;
else static if( is( Fn Params == delegate ) )
alias ParameterTupleOf!(Params) ParameterTupleOf;
else static if( is( Fn Params == Params* ) )
alias ParameterTupleOf!(Params) ParameterTupleOf;
else
static assert( false, "Argument has no parameters." );
}
struct S
{
int opApply(T)(T dg)
{
alias ParameterTupleOf!(T) U;
U u;
u[0] = 1;
u[1] = 2;
return 0;
}
}
void main()
{
foreach(int x, int y; S()){}
}