changeset 913:29c0d1194033

Fix #198 and #199 by making CTFE on static struct initializers work. Renamed SymbolDeclaration to StaticStructInitDeclaration to make its usage clearer.
author Christian Kamm <kamm incasoftware de>
date Sun, 01 Feb 2009 20:20:56 +0100
parents 16264a3973bf
children a65a6996922f
files dmd/declaration.c dmd/declaration.h dmd/dsymbol.h dmd/interpret.c dmd/mtype.c gen/tocsym.cpp gen/toir.cpp tests/mini/bug198_ctfestructinit.d tests/mini/bug199_ctfestructinit.d
diffstat 9 files changed, 64 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- 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;
+}
+
--- 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
--- 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; }
--- 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()
 		     */
 		}
--- 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);
--- 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;
 }
 
 /*************************************
--- 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();
--- /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);
+}
--- /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