mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 02:06:35 +01:00
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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
20
dmd2/mtype.c
20
dmd2/mtype.c
@@ -2068,22 +2068,17 @@ 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;
|
||||
@@ -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);
|
||||
|
||||
27
gen/toir.cpp
27
gen/toir.cpp
@@ -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);
|
||||
|
||||
|
||||
Submodule tests/d2/dmd-testsuite updated: 0424040e52...7d900914cd
Reference in New Issue
Block a user