mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-02 16:11:08 +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;
|
||||
}
|
||||
|
||||
DLValue::DLValue(Type *t, LLValue *v, bool isSpecialRefVar)
|
||||
: DValue(t, v), isSpecialRefVar(isSpecialRefVar) {
|
||||
assert(v && "Unexpected null llvm::Value.");
|
||||
assert(checkVarValueType(v->getType(), isSpecialRefVar));
|
||||
DLValue::DLValue(Type *t, LLValue *v) : DValue(t, v) {
|
||||
assert(checkVarValueType(v->getType(), false));
|
||||
}
|
||||
|
||||
LLValue *DLValue::getLVal() { return isSpecialRefVar ? DtoLoad(val) : val; }
|
||||
|
||||
LLValue *DLValue::getRVal() {
|
||||
LLValue *storage = val;
|
||||
if (isSpecialRefVar)
|
||||
storage = DtoLoad(storage);
|
||||
|
||||
if (DtoIsInMemoryOnly(type->toBasetype())) {
|
||||
llvm_unreachable("getRVal() for memory-only type");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LLValue *rawValue = DtoLoad(storage);
|
||||
|
||||
if (type->toBasetype()->ty == Tbool) {
|
||||
assert(rawValue->getType() == llvm::Type::getInt8Ty(gIR->context()));
|
||||
return gIR->ir->CreateTrunc(rawValue,
|
||||
llvm::Type::getInt1Ty(gIR->context()));
|
||||
}
|
||||
|
||||
LLValue *rawValue = DtoLoad(val);
|
||||
if (type->toBasetype()->ty != Tbool)
|
||||
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 DNullValue;
|
||||
class DLValue;
|
||||
class DSpecialRefValue;
|
||||
class DFuncValue;
|
||||
class DSliceValue;
|
||||
|
||||
|
@ -58,6 +59,7 @@ public:
|
|||
virtual bool definedInFuncEntryBB();
|
||||
|
||||
virtual DLValue *isLVal() { return nullptr; }
|
||||
virtual DSpecialRefValue *isSpecialRef() { return nullptr; }
|
||||
virtual DImValue *isIm() { return nullptr; }
|
||||
virtual DConstValue *isConst() { return nullptr; }
|
||||
virtual DNullValue *isNull() { return nullptr; }
|
||||
|
@ -102,22 +104,29 @@ public:
|
|||
/// 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
|
||||
/// keep structs and static arrays in memory.
|
||||
// TODO: The isSpecialRefVar case should probably be its own subclass.
|
||||
class DLValue : public DValue {
|
||||
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;
|
||||
|
||||
/// Returns the underlying storage for special internal ref variables.
|
||||
/// Illegal to call on any other value.
|
||||
llvm::Value *getRefStorage();
|
||||
|
||||
DLValue *isLVal() override { return this; }
|
||||
|
||||
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
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -535,7 +535,7 @@ public:
|
|||
// Note that the variable value is accessed directly (instead
|
||||
// of via getLVal(), which would perform a load from the
|
||||
// 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);
|
||||
result = toElem(e->e2);
|
||||
|
||||
|
@ -2291,7 +2291,7 @@ public:
|
|||
|
||||
p->scope() = IRScope(condend);
|
||||
if (retPtr) {
|
||||
result = new DLValue(e->type, retPtr, true);
|
||||
result = new DSpecialRefValue(e->type, retPtr);
|
||||
} else {
|
||||
result = new DConstValue(e->type, getNullValue(DtoMemType(dtype)));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue