RValue
CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
llvm::Value *AggLoc,
- bool isAggLocVolatile) {
+ bool IsAggLocVolatile,
+ bool IsInitializer) {
// If we shouldn't destroy the temporaries, just emit the
// child expression.
if (!E->shouldDestroyTemporaries())
- return EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile);
+ return EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
+ /*IgnoreResult=*/false, IsInitializer);
// Keep track of the current cleanup stack depth.
size_t CleanupStackDepth = CleanupEntries.size();
unsigned OldNumLiveTemporaries = LiveTemporaries.size();
- RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile);
+ RValue RV = EmitAnyExpr(E->getSubExpr(), AggLoc, IsAggLocVolatile,
+ /*IgnoreResult=*/false, IsInitializer);
// Pop temporaries.
while (LiveTemporaries.size() > OldNumLiveTemporaries)
Loc = Builder.CreateStructGEP(DeclPtr, needsCopyDispose*2+4, "x");
}
if (Ty->isReferenceType()) {
- llvm::Value *V = EmitReferenceBindingToExpr(Init, Ty).getScalarVal();
- EmitStoreOfScalar(V, Loc, false, Ty);
+ RValue RV = EmitReferenceBindingToExpr(Init, Ty, /*IsInitializer=*/true);
+ EmitStoreOfScalar(RV.getScalarVal(), Loc, false, Ty);
} else if (!hasAggregateLLVMType(Init->getType())) {
llvm::Value *V = EmitScalarExpr(Init);
EmitStoreOfScalar(V, Loc, D.getType().isVolatileQualified(),
/// aggregate expression, the aggloc/agglocvolatile arguments indicate where
/// the result should be returned.
RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc,
- bool isAggLocVolatile, bool IgnoreResult) {
+ bool IsAggLocVolatile, bool IgnoreResult,
+ bool IsInitializer) {
if (!hasAggregateLLVMType(E->getType()))
return RValue::get(EmitScalarExpr(E, IgnoreResult));
else if (E->getType()->isAnyComplexType())
return RValue::getComplex(EmitComplexExpr(E, false, false,
IgnoreResult, IgnoreResult));
- EmitAggExpr(E, AggLoc, isAggLocVolatile, IgnoreResult);
- return RValue::getAggregate(AggLoc, isAggLocVolatile);
+ EmitAggExpr(E, AggLoc, IsAggLocVolatile, IgnoreResult, IsInitializer);
+ return RValue::getAggregate(AggLoc, IsAggLocVolatile);
}
/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result
/// will always be accessible even if no aggregate location is
/// provided.
-RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E, llvm::Value *AggLoc,
- bool isAggLocVolatile) {
- if (!AggLoc && hasAggregateLLVMType(E->getType()) &&
+RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E,
+ bool IsAggLocVolatile,
+ bool IsInitializer) {
+ llvm::Value *AggLoc = 0;
+
+ if (hasAggregateLLVMType(E->getType()) &&
!E->getType()->isAnyComplexType())
AggLoc = CreateTempAlloca(ConvertType(E->getType()), "agg.tmp");
- return EmitAnyExpr(E, AggLoc, isAggLocVolatile);
+ return EmitAnyExpr(E, AggLoc, IsAggLocVolatile, /*IgnoreResult=*/false,
+ IsInitializer);
}
RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,
- QualType DestType) {
+ QualType DestType,
+ bool IsInitializer) {
RValue Val;
if (E->isLvalue(getContext()) == Expr::LV_Valid) {
// Emit the expr as an lvalue.
return RValue::get(LV.getAddress());
Val = EmitLoadOfLValue(LV, E->getType());
} else {
- Val = EmitAnyExprToTemp(E);
+ Val = EmitAnyExprToTemp(E, /*IsAggLocVolatile=*/false,
+ IsInitializer);
}
if (Val.isAggregate()) {
llvm::Value *DestPtr;
bool VolatileDest;
bool IgnoreResult;
-
+ bool IsInitializer;
public:
AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v,
- bool ignore)
+ bool ignore, bool isinit)
: CGF(cgf), Builder(CGF.Builder),
- DestPtr(destPtr), VolatileDest(v), IgnoreResult(ignore) {
+ DestPtr(destPtr), VolatileDest(v), IgnoreResult(ignore),
+ IsInitializer(isinit) {
}
//===--------------------------------------------------------------------===//
void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
CGF.EmitAnyExpr(E->getLHS(), 0, false, true);
- CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest);
+ CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest,
+ /*IgnoreResult=*/false, IsInitializer);
}
void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
} else
Visit(E->getSubExpr());
- CGF.PushCXXTemporary(E->getTemporary(), Val);
+ // Don't make this a live temporary if we're emitting an initializer expr.
+ if (!IsInitializer)
+ CGF.PushCXXTemporary(E->getTemporary(), Val);
}
void
}
void AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
- CGF.EmitCXXExprWithTemporaries(E, DestPtr, VolatileDest);
+ CGF.EmitCXXExprWithTemporaries(E, DestPtr, VolatileDest, IsInitializer);
}
void AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
/// the value of the aggregate expression is not needed. If VolatileDest is
/// true, DestPtr cannot be 0.
void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
- bool VolatileDest, bool IgnoreResult) {
+ bool VolatileDest, bool IgnoreResult,
+ bool IsInitializer) {
assert(E && hasAggregateLLVMType(E->getType()) &&
"Invalid aggregate expression to emit");
assert ((DestPtr != 0 || VolatileDest == false)
&& "volatile aggregate can't be 0");
- AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult)
+ AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult, IsInitializer)
.Visit(const_cast<Expr*>(E));
}
///
/// \param IgnoreResult - True if the resulting value isn't used.
RValue EmitAnyExpr(const Expr *E, llvm::Value *AggLoc = 0,
- bool isAggLocVolatile = false, bool IgnoreResult = false);
+ bool IsAggLocVolatile = false, bool IgnoreResult = false,
+ bool IsInitializer = false);
// EmitVAListRef - Emit a "reference" to a va_list; this is either the address
// or the value of the expression, depending on how va_list is defined.
/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will
/// always be accessible even if no aggregate location is provided.
- RValue EmitAnyExprToTemp(const Expr *E, llvm::Value *AggLoc = 0,
- bool isAggLocVolatile = false);
+ RValue EmitAnyExprToTemp(const Expr *E, bool IsAggLocVolatile = false,
+ bool IsInitializer = false);
/// EmitAggregateCopy - Emit an aggrate copy.
///
/// EmitReferenceBindingToExpr - Emits a reference binding to the passed in
/// expression. Will emit a temporary variable if E is not an LValue.
- RValue EmitReferenceBindingToExpr(const Expr* E, QualType DestType);
+ RValue EmitReferenceBindingToExpr(const Expr* E, QualType DestType,
+ bool IsInitializer = false);
//===--------------------------------------------------------------------===//
// Expression Emission
/// EmitScalarExpr - Emit the computation of the specified expression of LLVM
/// scalar type, returning the result.
- llvm::Value *EmitScalarExpr(const Expr *E , bool IgnoreResultAssign=false);
+ llvm::Value *EmitScalarExpr(const Expr *E , bool IgnoreResultAssign = false);
/// EmitScalarConversion - Emit a conversion from the specified type to the
/// specified destination type, both of which are LLVM scalar types.
/// aggregate type. The result is computed into DestPtr. Note that if
/// DestPtr is null, the value of the aggregate expression is not needed.
void EmitAggExpr(const Expr *E, llvm::Value *DestPtr, bool VolatileDest,
- bool IgnoreResult = false);
+ bool IgnoreResult = false, bool IsInitializer = false);
/// EmitGCMemmoveCollectable - Emit special API for structs with object
/// pointers.
RValue EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
llvm::Value *AggLoc = 0,
- bool isAggLocVolatile = false);
+ bool IsAggLocVolatile = false,
+ bool IsInitializer = false);
//===--------------------------------------------------------------------===//
// Internal Helpers