Hack to make nested struct .init results an rvalue.

The code still needs closer scrunity, as the 'nested' test
from the DMD testsuite doesn't fully pass yet.
This commit is contained in:
David Nadlinger
2013-01-11 21:34:45 +01:00
parent 7a4c378788
commit b99b78558b
6 changed files with 46 additions and 15 deletions

View File

@@ -910,14 +910,11 @@ Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2)
break;
}
}
#if !IN_LLVM
// LDC_FIXME: Implement this.
if (cmp && es1->type->needsNested())
{
if ((es1->sinit != NULL) != (es2->sinit != NULL))
cmp = 0;
}
#endif
}
#if 0 // Should handle this
else if (e1->op == TOKarrayliteral && e2->op == TOKstring)

View File

@@ -4156,8 +4156,8 @@ StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *
elements = new Expressions();
this->elements = elements;
this->stype = stype;
#if IN_DMD
this->sinit = NULL;
#if IN_DMD
this->sym = NULL;
#endif
this->soffset = 0;

View File

@@ -52,6 +52,7 @@ struct Initializer;
struct StringExp;
#if IN_LLVM
struct AssignExp;
struct StaticStructInitDeclaration;
#endif
enum TOK;
@@ -606,6 +607,12 @@ struct StructLiteralExp : Expression
DValue* toElem(IRState* irs);
llvm::Constant *toConstElem(IRState *irs);
llvm::StructType *constType;
/// Set if this is really the result of a struct .init access and should be
/// resolved codegen'd as an access to the given StaticStructInitDeclaration.
// LDC_FIXME: Figure out whether this, i.e. imitating the DMD behavior, is
// really the best way to fix the nested struct constant folding issue.
StaticStructInitDeclaration *sinit;
#endif
};

View File

@@ -2068,23 +2068,18 @@ Expression *Type::getProperty(Loc loc, Identifier *ident)
else if (ident == Id::init)
{
Type *tb = toBasetype();
#if IN_LLVM
// LDC_FIXME: Port the below change to LDC.
if (tb->ty == Tstruct && tb->needsNested())
{
e = defaultInit(loc);
}
else
e = defaultInitLiteral(loc);
#else
e = defaultInitLiteral(loc);
if (tb->ty == Tstruct && tb->needsNested())
{
StructLiteralExp *se = (StructLiteralExp *)e;
#if IN_LLVM
se->sinit = (StaticStructInitDeclaration*)
(((VarExp*)defaultInit(loc))->var);
#else
se->sinit = se->sd->toInitializer();
}
#endif
}
}
else if (ident == Id::mangleof)
{ const char *s;
if (!deco)
@@ -8398,7 +8393,12 @@ Expression *TypeStruct::defaultInit(Loc loc)
#if LOGDEFAULTINIT
printf("TypeStruct::defaultInit() '%s'\n", toChars());
#endif
#if IN_LLVM
Declaration *d = new StaticStructInitDeclaration(sym->loc, sym);
#else
Symbol *s = sym->toInitializer();
Declaration *d = new SymbolDeclaration(sym->loc, s, sym);
#endif
assert(d);
d->type = this;
return new VarExp(sym->loc, d);

View File

@@ -2923,6 +2923,21 @@ DValue* StructLiteralExp::toElem(IRState* p)
Logger::print("StructLiteralExp::toElem: %s @ %s\n", toChars(), type->toChars());
LOG_SCOPE;
if (sinit)
{
// Copied from VarExp::toElem, need to clean this mess up.
Type* sdecltype = sinit->type->toBasetype();
Logger::print("Sym: type = %s\n", sdecltype->toChars());
assert(sdecltype->ty == Tstruct);
TypeStruct* ts = static_cast<TypeStruct*>(sdecltype);
assert(ts->sym);
ts->sym->codegen(Type::sir);
LLValue* initsym = ts->sym->ir.irStruct->getInitSymbol();
initsym = DtoBitCast(initsym, DtoType(ts->pointerTo()));
return new DVarValue(type, initsym);
}
// make sure the struct is fully resolved
sd->codegen(Type::sir);
@@ -3020,6 +3035,18 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p)
Logger::print("StructLiteralExp::toConstElem: %s @ %s\n", toChars(), type->toChars());
LOG_SCOPE;
if (sinit)
{
// Copied from VarExp::toConstElem, need to clean this mess up.
Type* sdecltype = sinit->type->toBasetype();
Logger::print("Sym: type=%s\n", sdecltype->toChars());
assert(sdecltype->ty == Tstruct);
TypeStruct* ts = static_cast<TypeStruct*>(sdecltype);
ts->sym->codegen(Type::sir);
return ts->sym->ir.irStruct->getDefaultInit();
}
// make sure the struct is resolved
sd->codegen(Type::sir);