mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 08:30:47 +03:00
Handle internal ref variables in class DSpecialRefValue
This commit is contained in:
parent
de9149f1b6
commit
f70f11fac5
4 changed files with 40 additions and 32 deletions
|
@ -74,38 +74,34 @@ static bool checkVarValueType(LLType *t, bool extraDeref) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLValue::DLValue(Type *t, LLValue *v, bool isSpecialRefVar)
|
DLValue::DLValue(Type *t, LLValue *v) : DValue(t, v) {
|
||||||
: DValue(t, v), isSpecialRefVar(isSpecialRefVar) {
|
assert(checkVarValueType(v->getType(), false));
|
||||||
assert(v && "Unexpected null llvm::Value.");
|
|
||||||
assert(checkVarValueType(v->getType(), isSpecialRefVar));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue *DLValue::getLVal() { return isSpecialRefVar ? DtoLoad(val) : val; }
|
|
||||||
|
|
||||||
LLValue *DLValue::getRVal() {
|
LLValue *DLValue::getRVal() {
|
||||||
LLValue *storage = val;
|
|
||||||
if (isSpecialRefVar)
|
|
||||||
storage = DtoLoad(storage);
|
|
||||||
|
|
||||||
if (DtoIsInMemoryOnly(type->toBasetype())) {
|
if (DtoIsInMemoryOnly(type->toBasetype())) {
|
||||||
llvm_unreachable("getRVal() for memory-only type");
|
llvm_unreachable("getRVal() for memory-only type");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue *rawValue = DtoLoad(storage);
|
LLValue *rawValue = DtoLoad(val);
|
||||||
|
if (type->toBasetype()->ty != Tbool)
|
||||||
if (type->toBasetype()->ty == Tbool) {
|
|
||||||
assert(rawValue->getType() == llvm::Type::getInt8Ty(gIR->context()));
|
|
||||||
return gIR->ir->CreateTrunc(rawValue,
|
|
||||||
llvm::Type::getInt1Ty(gIR->context()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return rawValue;
|
return rawValue;
|
||||||
|
|
||||||
|
assert(rawValue->getType() == llvm::Type::getInt8Ty(gIR->context()));
|
||||||
|
return gIR->ir->CreateTrunc(rawValue, llvm::Type::getInt1Ty(gIR->context()));
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue *DLValue::getRefStorage() {
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
assert(isSpecialRefVar);
|
|
||||||
return val;
|
DSpecialRefValue::DSpecialRefValue(Type *t, LLValue *v) : DLValue(v, t) {
|
||||||
|
assert(checkVarValueType(v->getType(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
LLValue *DSpecialRefValue::getLVal() { return DtoLoad(val); }
|
||||||
|
|
||||||
|
LLValue *DSpecialRefValue::getRVal() {
|
||||||
|
return DLValue(type, getLVal()).getRVal();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
25
gen/dvalue.h
25
gen/dvalue.h
|
@ -35,6 +35,7 @@ class DImValue;
|
||||||
class DConstValue;
|
class DConstValue;
|
||||||
class DNullValue;
|
class DNullValue;
|
||||||
class DLValue;
|
class DLValue;
|
||||||
|
class DSpecialRefValue;
|
||||||
class DFuncValue;
|
class DFuncValue;
|
||||||
class DSliceValue;
|
class DSliceValue;
|
||||||
|
|
||||||
|
@ -58,6 +59,7 @@ public:
|
||||||
virtual bool definedInFuncEntryBB();
|
virtual bool definedInFuncEntryBB();
|
||||||
|
|
||||||
virtual DLValue *isLVal() { return nullptr; }
|
virtual DLValue *isLVal() { return nullptr; }
|
||||||
|
virtual DSpecialRefValue *isSpecialRef() { return nullptr; }
|
||||||
virtual DImValue *isIm() { return nullptr; }
|
virtual DImValue *isIm() { return nullptr; }
|
||||||
virtual DConstValue *isConst() { return nullptr; }
|
virtual DConstValue *isConst() { return nullptr; }
|
||||||
virtual DNullValue *isNull() { return nullptr; }
|
virtual DNullValue *isNull() { return nullptr; }
|
||||||
|
@ -102,22 +104,29 @@ public:
|
||||||
/// Represents a D value in memory via a low-level lvalue.
|
/// Represents a D value in memory via a low-level lvalue.
|
||||||
/// This doesn't imply that the D value is an lvalue too - e.g., we always
|
/// This doesn't imply that the D value is an lvalue too - e.g., we always
|
||||||
/// keep structs and static arrays in memory.
|
/// keep structs and static arrays in memory.
|
||||||
// TODO: The isSpecialRefVar case should probably be its own subclass.
|
|
||||||
class DLValue : public DValue {
|
class DLValue : public DValue {
|
||||||
public:
|
public:
|
||||||
DLValue(Type *t, llvm::Value *v, bool isSpecialRefVar = false);
|
DLValue(Type *t, llvm::Value *v);
|
||||||
|
|
||||||
virtual llvm::Value *getLVal();
|
virtual llvm::Value *getLVal() { return val; }
|
||||||
llvm::Value *getRVal() override;
|
llvm::Value *getRVal() override;
|
||||||
|
|
||||||
/// Returns the underlying storage for special internal ref variables.
|
|
||||||
/// Illegal to call on any other value.
|
|
||||||
llvm::Value *getRefStorage();
|
|
||||||
|
|
||||||
DLValue *isLVal() override { return this; }
|
DLValue *isLVal() override { return this; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const bool isSpecialRefVar;
|
DLValue(llvm::Value *v, Type *t) : DValue(t, v) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents special internal ref variables.
|
||||||
|
class DSpecialRefValue : public DLValue {
|
||||||
|
public:
|
||||||
|
DSpecialRefValue(Type *t, llvm::Value *v);
|
||||||
|
|
||||||
|
llvm::Value *getRefStorage() { return val; }
|
||||||
|
llvm::Value *getLVal() override;
|
||||||
|
llvm::Value *getRVal() override;
|
||||||
|
|
||||||
|
DSpecialRefValue *isSpecialRef() override { return this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// slice d-value
|
// slice d-value
|
||||||
|
|
|
@ -1864,7 +1864,10 @@ DValue *makeVarDValue(Type *type, VarDeclaration *vd, llvm::Value *storage) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DLValue(type, val, isSpecialRefVar(vd));
|
if (isSpecialRefVar(vd))
|
||||||
|
return new DSpecialRefValue(type, val);
|
||||||
|
|
||||||
|
return new DLValue(type, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue *DtoRVal(DValue *v) { return v->getRVal(); }
|
LLValue *DtoRVal(DValue *v) { return v->getRVal(); }
|
||||||
|
|
|
@ -535,7 +535,7 @@ public:
|
||||||
// Note that the variable value is accessed directly (instead
|
// Note that the variable value is accessed directly (instead
|
||||||
// of via getLVal(), which would perform a load from the
|
// of via getLVal(), which would perform a load from the
|
||||||
// uninitialized location), and that rhs is stored as an l-value!
|
// uninitialized location), and that rhs is stored as an l-value!
|
||||||
DLValue *lhs = toElem(e->e1)->isLVal();
|
DSpecialRefValue *lhs = toElem(e->e1)->isSpecialRef();
|
||||||
assert(lhs);
|
assert(lhs);
|
||||||
result = toElem(e->e2);
|
result = toElem(e->e2);
|
||||||
|
|
||||||
|
@ -2291,7 +2291,7 @@ public:
|
||||||
|
|
||||||
p->scope() = IRScope(condend);
|
p->scope() = IRScope(condend);
|
||||||
if (retPtr) {
|
if (retPtr) {
|
||||||
result = new DLValue(e->type, retPtr, true);
|
result = new DSpecialRefValue(e->type, retPtr);
|
||||||
} else {
|
} else {
|
||||||
result = new DConstValue(e->type, getNullValue(DtoMemType(dtype)));
|
result = new DConstValue(e->type, getNullValue(DtoMemType(dtype)));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue