# HG changeset patch # User Christian Kamm # Date 1233516056 -3600 # Node ID 29c0d11940331a0ff03e1761daf33445161f8cea # Parent 16264a3973bfb8e7f55358f7f558e07f8d60d858 Fix #198 and #199 by making CTFE on static struct initializers work. Renamed SymbolDeclaration to StaticStructInitDeclaration to make its usage clearer. diff -r 16264a3973bf -r 29c0d1194033 dmd/declaration.c --- a/dmd/declaration.c Fri Jan 30 07:51:50 2009 +0100 +++ b/dmd/declaration.c Sun Feb 01 20:20:56 2009 +0100 @@ -1408,4 +1408,13 @@ return NULL; } +/********************** StaticStructInitDeclaration ***************************/ +StaticStructInitDeclaration::StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym) + : Declaration(new Identifier("", TOKidentifier)) +{ + this->loc = loc; + this->dsym = dsym; + storage_class |= STCconst; +} + diff -r 16264a3973bf -r 29c0d1194033 dmd/declaration.h --- a/dmd/declaration.h Fri Jan 30 07:51:50 2009 +0100 +++ b/dmd/declaration.h Sun Feb 01 20:20:56 2009 +0100 @@ -278,19 +278,18 @@ /**************************************************************/ -// This is a shell around a back end symbol +// LDC uses this to denote static struct initializers -struct SymbolDeclaration : Declaration +struct StaticStructInitDeclaration : Declaration { - Symbol *sym; StructDeclaration *dsym; - SymbolDeclaration(Loc loc, Symbol *s, StructDeclaration *dsym); + StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym); Symbol *toSymbol(); // Eliminate need for dynamic_cast - SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; } + StaticStructInitDeclaration *isStaticStructInitDeclaration() { return (StaticStructInitDeclaration *)this; } }; struct ClassInfoDeclaration : VarDeclaration diff -r 16264a3973bf -r 29c0d1194033 dmd/dsymbol.h --- a/dmd/dsymbol.h Fri Jan 30 07:51:50 2009 +0100 +++ b/dmd/dsymbol.h Sun Feb 01 20:20:56 2009 +0100 @@ -65,7 +65,7 @@ struct ScopeDsymbol; struct WithScopeSymbol; struct ArrayScopeSymbol; -struct SymbolDeclaration; +struct StaticStructInitDeclaration; struct Expression; struct DeleteDeclaration; struct HdrGenState; @@ -216,7 +216,7 @@ #ifdef _DH virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; } #endif - virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; } + virtual StaticStructInitDeclaration *isStaticStructInitDeclaration() { return NULL; } virtual AttribDeclaration *isAttribDeclaration() { return NULL; } virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return NULL; } virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; } diff -r 16264a3973bf -r 29c0d1194033 dmd/interpret.c --- a/dmd/interpret.c Fri Jan 30 07:51:50 2009 +0100 +++ b/dmd/interpret.c Sun Feb 01 20:20:56 2009 +0100 @@ -987,7 +987,7 @@ { Expression *e = EXP_CANT_INTERPRET; VarDeclaration *v = d->isVarDeclaration(); - SymbolDeclaration *s = d->isSymbolDeclaration(); + StaticStructInitDeclaration *s = d->isStaticStructInitDeclaration(); if (v) { #if DMDV2 @@ -1011,11 +1011,9 @@ } else if (s) { - if (s->dsym->toInitializer() == s->sym) - { Expressions *exps = new Expressions(); - e = new StructLiteralExp(0, s->dsym, exps); - e = e->semantic(NULL); - } + Expressions *exps = new Expressions(); + e = new StructLiteralExp(0, s->dsym, exps); + e = e->semantic(NULL); } return e; } @@ -1466,10 +1464,10 @@ if (v->value && v->value->op == TOKvar) { VarExp *ve2 = (VarExp *)v->value; - if (ve2->var->isSymbolDeclaration()) + if (ve2->var->isStaticStructInitDeclaration()) { /* This can happen if v is a struct initialized to - * 0 using an __initZ SymbolDeclaration from + * 0 using an StaticStructInitDeclaration from * TypeStruct::defaultInit() */ } diff -r 16264a3973bf -r 29c0d1194033 dmd/mtype.c --- a/dmd/mtype.c Fri Jan 30 07:51:50 2009 +0100 +++ b/dmd/mtype.c Sun Feb 01 20:20:56 2009 +0100 @@ -4584,14 +4584,12 @@ } Expression *TypeStruct::defaultInit(Loc loc) -{ Symbol *s; - Declaration *d; +{ Declaration *d; #if LOGDEFAULTINIT printf("TypeStruct::defaultInit() '%s'\n", toChars()); #endif - s = sym->toInitializer(); - d = new SymbolDeclaration(sym->loc, s, sym); + d = new StaticStructInitDeclaration(sym->loc, sym); assert(d); d->type = this; return new VarExp(sym->loc, d); diff -r 16264a3973bf -r 29c0d1194033 gen/tocsym.cpp --- a/gen/tocsym.cpp Fri Jan 30 07:51:50 2009 +0100 +++ b/gen/tocsym.cpp Sun Feb 01 20:20:56 2009 +0100 @@ -22,16 +22,10 @@ #include "attrib.h" #include "lexer.h" -/********************************* SymbolDeclaration ****************************/ -SymbolDeclaration::SymbolDeclaration(Loc loc, Symbol *s, StructDeclaration *dsym) - : Declaration(new Identifier("", TOKidentifier)) +Symbol *StaticStructInitDeclaration::toSymbol() { -} - -Symbol *SymbolDeclaration::toSymbol() -{ - return sym; + return 0; } /************************************* diff -r 16264a3973bf -r 29c0d1194033 gen/toir.cpp --- a/gen/toir.cpp Fri Jan 30 07:51:50 2009 +0100 +++ b/gen/toir.cpp Sun Feb 01 20:20:56 2009 +0100 @@ -179,7 +179,7 @@ } return new DFuncValue(fdecl, func); } - else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) + else if (StaticStructInitDeclaration* sdecl = var->isStaticStructInitDeclaration()) { // this seems to be the static initialiser for structs Type* sdecltype = sdecl->type->toBasetype(); @@ -205,7 +205,7 @@ { Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) + if (StaticStructInitDeclaration* sdecl = var->isStaticStructInitDeclaration()) { // this seems to be the static initialiser for structs Type* sdecltype = sdecl->type->toBasetype(); diff -r 16264a3973bf -r 29c0d1194033 tests/mini/bug198_ctfestructinit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/bug198_ctfestructinit.d Sun Feb 01 20:20:56 2009 +0100 @@ -0,0 +1,12 @@ +struct Color { + uint c; + static Color opCall(uint _c) { Color ret; ret.c = _c; return ret; } +} + +// run at compile time +static const Color white = Color(0xffffffff); + +void main() +{ + assert(white.c == 0xffffffff); +} diff -r 16264a3973bf -r 29c0d1194033 tests/mini/bug199_ctfestructinit.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/bug199_ctfestructinit.d Sun Feb 01 20:20:56 2009 +0100 @@ -0,0 +1,25 @@ +struct Color { + uint c; + +} + +struct Vertex { + double x, y; + Color c; + static Vertex opCall(double x, double y, Color c) { + Vertex ret; + ret.x = x; + ret.y = y; + ret.c = c; + return ret; + } +} + +void main() { + Color c = {0xffffffff}; + + auto v = Vertex(1, 5, c); + + assert(v.x == 1 && v.y == 5); // passes + assert(v.c.c == 0xffffffff); // fails in LDC +} \ No newline at end of file