From 2a999b72e897231a4f8e7b0584cd043ac9466044 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Sun, 5 Oct 2008 11:47:47 +0200 Subject: [PATCH] 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. --- gen/llvmhelpers.cpp | 22 ++++++++++++++++++++++ gen/tollvm.cpp | 30 ++++++++++++++++++++++++++++++ gen/tollvm.h | 4 ++++ tests/mini/tupleval.d | 30 ++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 tests/mini/tupleval.d diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index fa3f73fc..63ae443d 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -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 { diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 95df537b..45d645e4 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -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 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); diff --git a/gen/tollvm.h b/gen/tollvm.h index fdac7677..d01fd221 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -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); diff --git a/tests/mini/tupleval.d b/tests/mini/tupleval.d new file mode 100644 index 00000000..7a7313bf --- /dev/null +++ b/tests/mini/tupleval.d @@ -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()){} +}