mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-04-12 06:49:02 +02:00
[svn r27] * Fixed bug in aggregate field lookup.
* Fixed structs with no fields. * Added support for NegExp as in -x.
This commit is contained in:
37
gen/toir.c
37
gen/toir.c
@@ -448,7 +448,7 @@ elem* AssignExp::toElem(IRState* p)
|
||||
|
||||
elem* AddExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("AddExp::toElem: %s\n", toChars());
|
||||
Logger::print("AddExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
elem* e = new elem;
|
||||
elem* l = e1->toElem(p);
|
||||
@@ -457,7 +457,6 @@ elem* AddExp::toElem(IRState* p)
|
||||
if (e1->type != e2->type) {
|
||||
if (e1->type->ty == Tpointer && e1->type->next->ty == Tstruct) {
|
||||
//assert(l->field);
|
||||
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
||||
assert(r->type == elem::CONST);
|
||||
llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->val);
|
||||
|
||||
@@ -1150,6 +1149,7 @@ elem* SymOffExp::toElem(IRState* p)
|
||||
if (VarDeclaration* vd = var->isVarDeclaration())
|
||||
{
|
||||
Logger::println("VarDeclaration");
|
||||
assert(vd->llvmValue);
|
||||
if (vd->type->ty == Tstruct && !(type->ty == Tpointer && type->next == vd->type)) {
|
||||
TypeStruct* vdt = (TypeStruct*)vd->type;
|
||||
e = new elem;
|
||||
@@ -2245,6 +2245,37 @@ elem* ComExp::toElem(IRState* p)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
elem* NegExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("NegExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
elem* e = new elem;
|
||||
elem* l = e1->toElem(p);
|
||||
llvm::Value* val = l->getValue();
|
||||
delete l;
|
||||
|
||||
llvm::Value* zero = 0;
|
||||
if (type->isintegral())
|
||||
zero = llvm::ConstantInt::get(val->getType(), 0, true);
|
||||
else if (type->isfloating()) {
|
||||
if (type->ty == Tfloat32)
|
||||
zero = llvm::ConstantFP::get(val->getType(), float(0));
|
||||
else if (type->ty == Tfloat64 || type->ty == Tfloat80)
|
||||
zero = llvm::ConstantFP::get(val->getType(), double(0));
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
|
||||
e->val = llvm::BinaryOperator::createSub(zero,val,"tmp",p->scopebb());
|
||||
e->type = elem::VAL;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define STUB(x) elem *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; }
|
||||
//STUB(IdentityExp);
|
||||
//STUB(CondExp);
|
||||
@@ -2304,7 +2335,7 @@ STUB(BoolExp);
|
||||
|
||||
//STUB(NotExp);
|
||||
//STUB(ComExp);
|
||||
STUB(NegExp);
|
||||
//STUB(NegExp);
|
||||
//STUB(PtrExp);
|
||||
//STUB(AddrExp);
|
||||
//STUB(SliceExp);
|
||||
|
||||
19
gen/toobj.c
19
gen/toobj.c
@@ -145,10 +145,17 @@ void Declaration::toObjFile()
|
||||
/// Returns the LLVM style index from a DMD style offset
|
||||
void AggregateDeclaration::offsetToIndex(unsigned os, std::vector<unsigned>& result)
|
||||
{
|
||||
//Logger::println("checking for offset %u :", os);
|
||||
LOG_SCOPE;
|
||||
unsigned vos = 0;
|
||||
for (unsigned i=0; i<fields.dim; ++i) {
|
||||
VarDeclaration* vd = (VarDeclaration*)fields.data[i];
|
||||
if (vd->type->ty == Tstruct) {
|
||||
//Logger::println("found %u", vd->offset);
|
||||
if (os == vd->offset) {
|
||||
result.push_back(i);
|
||||
return;
|
||||
}
|
||||
else if (vd->type->ty == Tstruct) {
|
||||
if (vos + vd->type->size() > os) {
|
||||
TypeStruct* ts = (TypeStruct*)vd->type;
|
||||
StructDeclaration* sd = ts->sym;
|
||||
@@ -157,10 +164,6 @@ void AggregateDeclaration::offsetToIndex(unsigned os, std::vector<unsigned>& res
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (os == vd->offset) {
|
||||
result.push_back(i);
|
||||
return;
|
||||
}
|
||||
vos += vd->offset;
|
||||
}
|
||||
assert(0 && "Offset not found in any aggregate field");
|
||||
@@ -235,6 +238,12 @@ void StructDeclaration::toObjFile()
|
||||
}
|
||||
}
|
||||
|
||||
if (gIR->topstruct().fields.empty())
|
||||
{
|
||||
gIR->topstruct().fields.push_back(llvm::Type::Int8Ty);
|
||||
gIR->topstruct().inits.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
|
||||
}
|
||||
|
||||
llvm::StructType* structtype = llvm::StructType::get(gIR->topstruct().fields);
|
||||
|
||||
// refine abstract types for stuff like: struct S{S* next;}
|
||||
|
||||
@@ -9,7 +9,7 @@ void _writef(T)(T t) {
|
||||
static if(isArray!(T)) {
|
||||
_writef('[');
|
||||
if (t.length) _writef(t[0]);
|
||||
for (int i=1; i<t.lengthi; ++i) { _writef(','); _writef(t[i]); }
|
||||
for (int i=1; i<t.length; ++i) { _writef(','); _writef(t[i]); }
|
||||
_writef(']');
|
||||
} else
|
||||
static if(is(T==int)) printf("%i", t); else
|
||||
|
||||
5
test/bug1.d
Normal file
5
test/bug1.d
Normal file
@@ -0,0 +1,5 @@
|
||||
module bug1;
|
||||
struct Foo { Foo opSub(ref Foo b) { return Foo(); } }
|
||||
struct Bar { Foo whee; }
|
||||
void test(ref Bar moo) { Foo nngh; auto plonk = nngh - moo.whee; }
|
||||
void main() { Bar bar; test(bar); }
|
||||
13
test/neg.d
Normal file
13
test/neg.d
Normal file
@@ -0,0 +1,13 @@
|
||||
module neg;
|
||||
|
||||
void main()
|
||||
{
|
||||
int i = 32;
|
||||
long l = 55;
|
||||
float f = 23;
|
||||
double d = 4;
|
||||
assert(-i == -32);
|
||||
assert(-l == -55);
|
||||
assert(-f == -23);
|
||||
assert(-d == -4);
|
||||
}
|
||||
Reference in New Issue
Block a user