Mercurial > projects > ldc
changeset 648:8d850fa25713
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.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sun, 05 Oct 2008 11:47:47 +0200 |
parents | 51c4d1a64da6 |
children | 505f41873d4f |
files | gen/llvmhelpers.cpp gen/tollvm.cpp gen/tollvm.h tests/mini/tupleval.d |
diffstat | 4 files changed, 86 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/gen/llvmhelpers.cpp Sat Oct 04 23:28:49 2008 +0200 +++ b/gen/llvmhelpers.cpp Sun Oct 05 11:47:47 2008 +0200 @@ -1129,6 +1129,12 @@ { 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 @@ 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 {
--- a/gen/tollvm.cpp Sat Oct 04 23:28:49 2008 +0200 +++ b/gen/tollvm.cpp Sun Oct 05 11:47:47 2008 +0200 @@ -169,6 +169,16 @@ 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* 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);
--- a/gen/tollvm.h Sat Oct 04 23:28:49 2008 +0200 +++ b/gen/tollvm.h Sun Oct 05 11:47:47 2008 +0200 @@ -23,6 +23,10 @@ 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);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/tupleval.d Sun Oct 05 11:47:47 2008 +0200 @@ -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()){} +}