RValue AtomicInfo::convertTempToRValue(llvm::Value *addr, AggValueSlot resultSlot) const { if (EvaluationKind == TEK_Aggregate) { // Nothing to do if the result is ignored. if (resultSlot.isIgnored()) return resultSlot.asRValue(); assert(resultSlot.getAddr() == addr || hasPadding()); // In these cases, we should have emitted directly into the result slot. if (!hasPadding() || resultSlot.isValueOfAtomic()) return resultSlot.asRValue(); // Otherwise, fall into the common path. } // Drill into the padding structure if we have one. if (hasPadding()) addr = CGF.Builder.CreateStructGEP(addr, 0); // If we're emitting to an aggregate, copy into the result slot. if (EvaluationKind == TEK_Aggregate) { CGF.EmitAggregateCopy(resultSlot.getAddr(), addr, getValueType(), resultSlot.isVolatile()); return resultSlot.asRValue(); } // Otherwise, just convert the temporary to an r-value using the // normal conversion routine. return CGF.convertTempToRValue(addr, getValueType()); }
void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { // For an assignment to work, the value on the right has // to be compatible with the value on the left. assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), E->getRHS()->getType()) && "Invalid assignment"); // FIXME: __block variables need the RHS evaluated first! LValue LHS = CGF.EmitLValue(E->getLHS()); // We have to special case property setters, otherwise we must have // a simple lvalue (no aggregates inside vectors, bitfields). if (LHS.isPropertyRef()) { AggValueSlot Slot = EnsureSlot(E->getRHS()->getType()); CGF.EmitAggExpr(E->getRHS(), Slot); CGF.EmitStoreThroughPropertyRefLValue(Slot.asRValue(), LHS); } else { bool GCollection = false; if (CGF.getContext().getLangOptions().getGCMode()) GCollection = TypeRequiresGCollection(E->getLHS()->getType()); // Codegen the RHS so that it stores directly into the LHS. AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true, GCollection); CGF.EmitAggExpr(E->getRHS(), LHSSlot, false); EmitFinalDestCopy(E, LHS, true); } }
void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { // For an assignment to work, the value on the right has // to be compatible with the value on the left. assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), E->getRHS()->getType()) && "Invalid assignment"); if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getLHS())) if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) if (VD->hasAttr<BlocksAttr>() && E->getRHS()->HasSideEffects(CGF.getContext())) { // When __block variable on LHS, the RHS must be evaluated first // as it may change the 'forwarding' field via call to Block_copy. LValue RHS = CGF.EmitLValue(E->getRHS()); LValue LHS = CGF.EmitLValue(E->getLHS()); bool GCollection = false; if (CGF.getContext().getLangOptions().getGCMode()) GCollection = TypeRequiresGCollection(E->getLHS()->getType()); Dest = AggValueSlot::forLValue(LHS, true, GCollection); EmitFinalDestCopy(E, RHS, true); return; } LValue LHS = CGF.EmitLValue(E->getLHS()); // We have to special case property setters, otherwise we must have // a simple lvalue (no aggregates inside vectors, bitfields). if (LHS.isPropertyRef()) { const ObjCPropertyRefExpr *RE = LHS.getPropertyRefExpr(); QualType ArgType = RE->getSetterArgType(); RValue Src; if (ArgType->isReferenceType()) Src = CGF.EmitReferenceBindingToExpr(E->getRHS(), 0); else { AggValueSlot Slot = EnsureSlot(E->getRHS()->getType()); CGF.EmitAggExpr(E->getRHS(), Slot); Src = Slot.asRValue(); } CGF.EmitStoreThroughPropertyRefLValue(Src, LHS); } else { bool GCollection = false; if (CGF.getContext().getLangOptions().getGCMode()) GCollection = TypeRequiresGCollection(E->getLHS()->getType()); // Codegen the RHS so that it stores directly into the LHS. AggValueSlot LHSSlot = AggValueSlot::forLValue(LHS, true, GCollection); CGF.EmitAggExpr(E->getRHS(), LHSSlot, false); EmitFinalDestCopy(E, LHS, true); } }
RValue AtomicInfo::convertTempToRValue(llvm::Value *addr, AggValueSlot resultSlot, SourceLocation loc) const { if (EvaluationKind == TEK_Aggregate) return resultSlot.asRValue(); // Drill into the padding structure if we have one. if (hasPadding()) addr = CGF.Builder.CreateStructGEP(addr, 0); // Otherwise, just convert the temporary to an r-value using the // normal conversion routine. return CGF.convertTempToRValue(addr, getValueType(), loc); }