mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 09:00:33 +03:00

Previously, we just had a hack to make ref foreach statements work. This commit enables them to work in other cases as well, like the implicit __result variable for functions with out-contracts (which is such a magic ref variable for ref-returning functions). Fixes DMD testcase 'testcontracts'.
84 lines
2.2 KiB
C++
84 lines
2.2 KiB
C++
#include "gen/llvm.h"
|
|
|
|
#include "gen/tollvm.h"
|
|
#include "gen/irstate.h"
|
|
#include "gen/logger.h"
|
|
#include "gen/dvalue.h"
|
|
#include "gen/llvmhelpers.h"
|
|
|
|
#include "declaration.h"
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
DVarValue::DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue)
|
|
: DValue(t), var(vd), val(llvmValue)
|
|
{
|
|
assert(isaPointer(llvmValue));
|
|
assert(!isSpecialRefVar(vd) ||
|
|
isaPointer(isaPointer(llvmValue)->getElementType()));
|
|
}
|
|
|
|
DVarValue::DVarValue(Type* t, LLValue* llvmValue)
|
|
: DValue(t), var(0), val(llvmValue)
|
|
{
|
|
assert(isaPointer(llvmValue));
|
|
}
|
|
|
|
LLValue* DVarValue::getLVal()
|
|
{
|
|
assert(val);
|
|
if (var && isSpecialRefVar(var))
|
|
return DtoLoad(val);
|
|
return val;
|
|
}
|
|
|
|
LLValue* DVarValue::getRVal()
|
|
{
|
|
assert(val);
|
|
Type* bt = type->toBasetype();
|
|
|
|
LLValue* tmp = val;
|
|
if (var && isSpecialRefVar(var))
|
|
tmp = DtoLoad(tmp);
|
|
|
|
if (DtoIsPassedByRef(bt))
|
|
return tmp;
|
|
return DtoLoad(tmp);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
LLValue* DSliceValue::getRVal()
|
|
{
|
|
assert(len);
|
|
assert(ptr);
|
|
return DtoAggrPair(len, ptr);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
DFuncValue::DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt)
|
|
: DValue(fd->type), func(fd), val(v), vthis(vt)
|
|
{}
|
|
|
|
LLValue* DFuncValue::getRVal()
|
|
{
|
|
assert(val);
|
|
return val;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
LLValue* DConstValue::getRVal()
|
|
{
|
|
assert(c);
|
|
return c;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|