Fix #198 and #199 by making CTFE on static struct initializers work.

Renamed SymbolDeclaration to StaticStructInitDeclaration to make its usage clearer.
This commit is contained in:
Christian Kamm
2009-02-01 20:20:56 +01:00
parent 07649678db
commit 01f19c466c
9 changed files with 64 additions and 29 deletions
+9
View File
@@ -1408,4 +1408,13 @@ Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s)
return NULL; return NULL;
} }
/********************** StaticStructInitDeclaration ***************************/
StaticStructInitDeclaration::StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym)
: Declaration(new Identifier("", TOKidentifier))
{
this->loc = loc;
this->dsym = dsym;
storage_class |= STCconst;
}
+4 -5
View File
@@ -278,19 +278,18 @@ struct VarDeclaration : Declaration
/**************************************************************/ /**************************************************************/
// 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; StructDeclaration *dsym;
SymbolDeclaration(Loc loc, Symbol *s, StructDeclaration *dsym); StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym);
Symbol *toSymbol(); Symbol *toSymbol();
// Eliminate need for dynamic_cast // Eliminate need for dynamic_cast
SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; } StaticStructInitDeclaration *isStaticStructInitDeclaration() { return (StaticStructInitDeclaration *)this; }
}; };
struct ClassInfoDeclaration : VarDeclaration struct ClassInfoDeclaration : VarDeclaration
+2 -2
View File
@@ -65,7 +65,7 @@ struct EnumMember;
struct ScopeDsymbol; struct ScopeDsymbol;
struct WithScopeSymbol; struct WithScopeSymbol;
struct ArrayScopeSymbol; struct ArrayScopeSymbol;
struct SymbolDeclaration; struct StaticStructInitDeclaration;
struct Expression; struct Expression;
struct DeleteDeclaration; struct DeleteDeclaration;
struct HdrGenState; struct HdrGenState;
@@ -216,7 +216,7 @@ struct Dsymbol : Object
#ifdef _DH #ifdef _DH
virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; } virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; }
#endif #endif
virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; } virtual StaticStructInitDeclaration *isStaticStructInitDeclaration() { return NULL; }
virtual AttribDeclaration *isAttribDeclaration() { return NULL; } virtual AttribDeclaration *isAttribDeclaration() { return NULL; }
virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return NULL; } virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return NULL; }
virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; } virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; }
+6 -8
View File
@@ -987,7 +987,7 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d)
{ {
Expression *e = EXP_CANT_INTERPRET; Expression *e = EXP_CANT_INTERPRET;
VarDeclaration *v = d->isVarDeclaration(); VarDeclaration *v = d->isVarDeclaration();
SymbolDeclaration *s = d->isSymbolDeclaration(); StaticStructInitDeclaration *s = d->isStaticStructInitDeclaration();
if (v) if (v)
{ {
#if DMDV2 #if DMDV2
@@ -1011,11 +1011,9 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d)
} }
else if (s) else if (s)
{ {
if (s->dsym->toInitializer() == s->sym) Expressions *exps = new Expressions();
{ Expressions *exps = new Expressions(); e = new StructLiteralExp(0, s->dsym, exps);
e = new StructLiteralExp(0, s->dsym, exps); e = e->semantic(NULL);
e = e->semantic(NULL);
}
} }
return e; return e;
} }
@@ -1466,10 +1464,10 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
if (v->value && v->value->op == TOKvar) if (v->value && v->value->op == TOKvar)
{ {
VarExp *ve2 = (VarExp *)v->value; VarExp *ve2 = (VarExp *)v->value;
if (ve2->var->isSymbolDeclaration()) if (ve2->var->isStaticStructInitDeclaration())
{ {
/* This can happen if v is a struct initialized to /* This can happen if v is a struct initialized to
* 0 using an __initZ SymbolDeclaration from * 0 using an StaticStructInitDeclaration from
* TypeStruct::defaultInit() * TypeStruct::defaultInit()
*/ */
} }
+2 -4
View File
@@ -4584,14 +4584,12 @@ unsigned TypeStruct::memalign(unsigned salign)
} }
Expression *TypeStruct::defaultInit(Loc loc) Expression *TypeStruct::defaultInit(Loc loc)
{ Symbol *s; { Declaration *d;
Declaration *d;
#if LOGDEFAULTINIT #if LOGDEFAULTINIT
printf("TypeStruct::defaultInit() '%s'\n", toChars()); printf("TypeStruct::defaultInit() '%s'\n", toChars());
#endif #endif
s = sym->toInitializer(); d = new StaticStructInitDeclaration(sym->loc, sym);
d = new SymbolDeclaration(sym->loc, s, sym);
assert(d); assert(d);
d->type = this; d->type = this;
return new VarExp(sym->loc, d); return new VarExp(sym->loc, d);
+2 -8
View File
@@ -22,16 +22,10 @@
#include "attrib.h" #include "attrib.h"
#include "lexer.h" #include "lexer.h"
/********************************* SymbolDeclaration ****************************/
SymbolDeclaration::SymbolDeclaration(Loc loc, Symbol *s, StructDeclaration *dsym) Symbol *StaticStructInitDeclaration::toSymbol()
: Declaration(new Identifier("", TOKidentifier))
{ {
} return 0;
Symbol *SymbolDeclaration::toSymbol()
{
return sym;
} }
/************************************* /*************************************
+2 -2
View File
@@ -179,7 +179,7 @@ DValue* VarExp::toElem(IRState* p)
} }
return new DFuncValue(fdecl, func); 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 // this seems to be the static initialiser for structs
Type* sdecltype = sdecl->type->toBasetype(); Type* sdecltype = sdecl->type->toBasetype();
@@ -205,7 +205,7 @@ LLConstant* VarExp::toConstElem(IRState* p)
{ {
Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars()); Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE; LOG_SCOPE;
if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) if (StaticStructInitDeclaration* sdecl = var->isStaticStructInitDeclaration())
{ {
// this seems to be the static initialiser for structs // this seems to be the static initialiser for structs
Type* sdecltype = sdecl->type->toBasetype(); Type* sdecltype = sdecl->type->toBasetype();
+12
View File
@@ -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);
}
+25
View File
@@ -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
}