diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 78 | ||||
-rw-r--r-- | lib/CodeGen/CGDeclCXX.cpp | 31 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 38 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 65 | ||||
-rw-r--r-- | lib/CodeGen/CGExprCXX.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCRuntime.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGValue.h | 53 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 8 |
10 files changed, 164 insertions, 133 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index ac47034325..8ad82a614e 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -618,8 +618,11 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) { ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue, declRef, VK_RValue); - EmitExprAsInit(&l2r, &blockFieldPseudoVar, blockField, - getContext().getDeclAlign(variable), + EmitExprAsInit(&l2r, &blockFieldPseudoVar, + LValue::MakeAddr(blockField, type, + getContext().getDeclAlign(variable) + .getQuantity(), + getContext()), /*captured by init*/ false); } diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 066f0d5c7d..77a5be6c96 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -430,10 +430,8 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF, } if (!CGF.hasAggregateLLVMType(T)) { - CGF.EmitScalarInit(MemberInit->getInit(), 0, Dest, false, - LHS.isVolatileQualified(), - CGF.getContext().getTypeAlign(T), - T); + LValue lvalue = CGF.MakeAddrLValue(Dest, T); + CGF.EmitScalarInit(MemberInit->getInit(), /*decl*/ 0, lvalue, false); } else if (T->isAnyComplexType()) { CGF.EmitComplexExprIntoAddr(MemberInit->getInit(), Dest, LHS.isVolatileQualified()); @@ -555,8 +553,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, CGF.EmitNullInitialization(LHS.getAddress(), Field->getType()); } else if (!CGF.hasAggregateLLVMType(Field->getType())) { if (LHS.isSimple()) { - CGF.EmitExprAsInit(MemberInit->getInit(), Field, LHS.getAddress(), - CGF.getContext().getDeclAlign(Field), false); + CGF.EmitExprAsInit(MemberInit->getInit(), Field, LHS, false); } else { RValue RHS = RValue::get(CGF.EmitScalarExpr(MemberInit->getInit())); CGF.EmitStoreThroughLValue(RHS, LHS, FieldType); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index b013446f6b..daa37eea8f 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -453,16 +453,23 @@ static bool isAccessedBy(const ValueDecl *decl, const Expr *e) { return isAccessedBy(*var, e); } +static void drillIntoBlockVariable(CodeGenFunction &CGF, + LValue &lvalue, + const VarDecl *var) { + lvalue.setAddress(CGF.BuildBlockByrefAddress(lvalue.getAddress(), var)); +} + void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D, - llvm::Value *addr, bool capturedByInit, - bool isVolatile, unsigned alignment, - QualType type) { - Qualifiers::ObjCLifetime lifetime = type.getQualifiers().getObjCLifetime(); + LValue lvalue, + bool capturedByInit) { + QualType type = lvalue.getType(); + Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime(); if (!lifetime) { llvm::Value *value = EmitScalarExpr(init); - if (capturedByInit) addr = BuildBlockByrefAddress(addr, cast<VarDecl>(D)); - EmitStoreOfScalar(value, addr, isVolatile, alignment, type); + if (capturedByInit) + drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); + EmitStoreThroughLValue(RValue::get(value), lvalue, lvalue.getType()); return; } @@ -480,27 +487,28 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, if (lifetime != Qualifiers::OCL_ExplicitNone) accessedByInit = isAccessedBy(D, init); if (accessedByInit) { + LValue tempLV = lvalue; // Drill down to the __block object if necessary. - llvm::Value *tempAddr = addr; if (capturedByInit) { // We can use a simple GEP for this because it can't have been // moved yet. - tempAddr = Builder.CreateStructGEP(tempAddr, - getByRefValueLLVMField(cast<VarDecl>(D))); + tempLV.setAddress(Builder.CreateStructGEP(tempLV.getAddress(), + getByRefValueLLVMField(cast<VarDecl>(D)))); } - const llvm::PointerType *ty = cast<llvm::PointerType>(tempAddr->getType()); + const llvm::PointerType *ty + = cast<llvm::PointerType>(tempLV.getAddress()->getType()); ty = cast<llvm::PointerType>(ty->getElementType()); llvm::Value *zero = llvm::ConstantPointerNull::get(ty); // If __weak, we want to use a barrier under certain conditions. if (lifetime == Qualifiers::OCL_Weak) - EmitARCInitWeak(tempAddr, zero); + EmitARCInitWeak(tempLV.getAddress(), zero); // Otherwise just do a simple store. else - EmitStoreOfScalar(zero, tempAddr, isVolatile, alignment, type); + EmitStoreOfScalar(zero, tempLV); } // Emit the initializer. @@ -526,11 +534,11 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, // disappear in the common case. value = EmitScalarExpr(init); - if (capturedByInit) addr = BuildBlockByrefAddress(addr, cast<VarDecl>(D)); + if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); if (accessedByInit) - EmitARCStoreWeak(addr, value, /*ignored*/ true); + EmitARCStoreWeak(lvalue.getAddress(), value, /*ignored*/ true); else - EmitARCInitWeak(addr, value); + EmitARCInitWeak(lvalue.getAddress(), value); return; } @@ -539,22 +547,19 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, break; } - if (capturedByInit) addr = BuildBlockByrefAddress(addr, cast<VarDecl>(D)); - - llvm::MDNode *tbaa = CGM.getTBAAInfo(type); + if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); // If the variable might have been accessed by its initializer, we // might have to initialize with a barrier. We have to do this for // both __weak and __strong, but __weak got filtered out above. if (accessedByInit && lifetime == Qualifiers::OCL_Strong) { - llvm::Value *oldValue - = EmitLoadOfScalar(addr, isVolatile, alignment, type, tbaa); - EmitStoreOfScalar(value, addr, isVolatile, alignment, type, tbaa); + llvm::Value *oldValue = EmitLoadOfScalar(lvalue); + EmitStoreOfScalar(value, lvalue); EmitARCRelease(oldValue, /*precise*/ false); return; } - EmitStoreOfScalar(value, addr, isVolatile, alignment, type, tbaa); + EmitStoreOfScalar(value, lvalue); } /// canEmitInitWithFewStoresAfterMemset - Decide whether we can emit the @@ -860,8 +865,11 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { llvm::Value *Loc = capturedByInit ? emission.Address : emission.getObjectAddress(*this); - if (!emission.IsConstantAggregate) - return EmitExprAsInit(Init, &D, Loc, alignment, capturedByInit); + if (!emission.IsConstantAggregate) { + LValue lv = MakeAddrLValue(Loc, type, alignment.getQuantity()); + lv.setNonGC(true); + return EmitExprAsInit(Init, &D, lv, capturedByInit); + } // If this is a simple aggregate initialization, we can optimize it // in various ways. @@ -924,29 +932,25 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { /// whose address is potentially changed by the initializer void CodeGenFunction::EmitExprAsInit(const Expr *init, const ValueDecl *D, - llvm::Value *loc, - CharUnits alignment, + LValue lvalue, bool capturedByInit) { QualType type = D->getType(); - bool isVolatile = type.isVolatileQualified(); if (type->isReferenceType()) { - RValue RV = EmitReferenceBindingToExpr(init, D); + RValue rvalue = EmitReferenceBindingToExpr(init, D); if (capturedByInit) - loc = BuildBlockByrefAddress(loc, cast<VarDecl>(D)); - EmitStoreOfScalar(RV.getScalarVal(), loc, false, - alignment.getQuantity(), type); + drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); + EmitStoreThroughLValue(rvalue, lvalue, type); } else if (!hasAggregateLLVMType(type)) { - EmitScalarInit(init, D, loc, capturedByInit, isVolatile, - alignment.getQuantity(), type); + EmitScalarInit(init, D, lvalue, capturedByInit); } else if (type->isAnyComplexType()) { ComplexPairTy complex = EmitComplexExpr(init); - if (capturedByInit) loc = BuildBlockByrefAddress(loc, cast<VarDecl>(D)); - StoreComplexToAddr(complex, loc, isVolatile); + if (capturedByInit) + drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); + StoreComplexToAddr(complex, lvalue.getAddress(), lvalue.isVolatile()); } else { // TODO: how can we delay here if D is captured by its initializer? - EmitAggExpr(init, AggValueSlot::forAddr(loc, type.getQualifiers(), true, - false)); + EmitAggExpr(init, AggValueSlot::forLValue(lvalue, true, false)); } } diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index 08e8e0c48e..c305f01fe3 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -27,29 +27,26 @@ static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, "Should not call EmitDeclInit on a reference!"); ASTContext &Context = CGF.getContext(); - - const Expr *Init = D.getInit(); - QualType T = D.getType(); - bool isVolatile = Context.getCanonicalType(T).isVolatileQualified(); - unsigned Alignment = Context.getDeclAlign(&D).getQuantity(); - if (!CGF.hasAggregateLLVMType(T)) { + unsigned alignment = Context.getDeclAlign(&D).getQuantity(); + QualType type = D.getType(); + LValue lv = CGF.MakeAddrLValue(DeclPtr, type, alignment); + + const Expr *Init = D.getInit(); + if (!CGF.hasAggregateLLVMType(type)) { CodeGenModule &CGM = CGF.CGM; - Qualifiers::GC GCAttr = CGM.getContext().getObjCGCAttrKind(T); - if (GCAttr == Qualifiers::Strong) + if (lv.isObjCStrong()) CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init), DeclPtr, D.isThreadSpecified()); - else if (GCAttr == Qualifiers::Weak) - CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init), - DeclPtr); + else if (lv.isObjCWeak()) + CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init), + DeclPtr); else - CGF.EmitScalarInit(Init, &D, DeclPtr, false, isVolatile, Alignment, - D.getType()); - } else if (T->isAnyComplexType()) { - CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile); + CGF.EmitScalarInit(Init, &D, lv, false); + } else if (type->isAnyComplexType()) { + CGF.EmitComplexExprIntoAddr(Init, DeclPtr, lv.isVolatile()); } else { - CGF.EmitAggExpr(Init, AggValueSlot::forAddr(DeclPtr, T.getQualifiers(), - true)); + CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv, true)); } } diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 197bc67881..3e845d2cdc 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -313,9 +313,10 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E, unsigned Alignment = CGF.getContext().getTypeAlignInChars(PointeeType).getQuantity(); - CGF.EmitScalarInit(E, InitVD, ReferenceTemporary, false, - PointeeType.isVolatileQualified(), - Alignment, PointeeType); + LValue lvalue = + CGF.MakeAddrLValue(ReferenceTemporary, PointeeType, Alignment); + + CGF.EmitScalarInit(E, InitVD, lvalue, false); return ReferenceTemporary; } } @@ -669,6 +670,12 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { } } +llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue) { + return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(), + lvalue.getAlignment(), lvalue.getType(), + lvalue.getTBAAInfo()); +} + llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, llvm::MDNode *TBAAInfo) { @@ -724,6 +731,12 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, CGM.DecorateInstruction(Store, TBAAInfo); } +void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue) { + EmitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(), + lvalue.getAlignment(), lvalue.getType(), + lvalue.getTBAAInfo()); +} + /// EmitLoadOfLValue - Given an expression that represents a value lvalue, this /// method emits the address of the lvalue, then loads the result as an rvalue, /// returning the rvalue. @@ -964,9 +977,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, } assert(Src.isScalar() && "Can't emit an agg store with this method"); - EmitStoreOfScalar(Src.getScalarVal(), Dst.getAddress(), - Dst.isVolatileQualified(), Dst.getAlignment(), Ty, - Dst.getTBAAInfo()); + EmitStoreOfScalar(Src.getScalarVal(), Dst); } void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, @@ -1498,7 +1509,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) { assert(LHS.isSimple() && "Can only subscript lvalue vectors here!"); Idx = Builder.CreateIntCast(Idx, Int32Ty, IdxSigned, "vidx"); return LValue::MakeVectorElt(LHS.getAddress(), Idx, - E->getBase()->getType().getCVRQualifiers()); + E->getBase()->getType()); } // Extend or truncate the index type to 32 or 64-bits. @@ -1637,7 +1648,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { Base = EmitLValue(E->getBase()); } else { // Otherwise, the base is a normal rvalue (as in (V+V).x), emit it as such. - assert(E->getBase()->getType()->getAs<VectorType>() && + assert(E->getBase()->getType()->isVectorType() && "Result must be a vector"); llvm::Value *Vec = EmitScalarExpr(E->getBase()); @@ -1646,6 +1657,9 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { Builder.CreateStore(Vec, VecMem); Base = MakeAddrLValue(VecMem, E->getBase()->getType()); } + + QualType type = + E->getType().withCVRQualifiers(Base.getQuals().getCVRQualifiers()); // Encode the element access list into a vector of unsigned indices. llvm::SmallVector<unsigned, 4> Indices; @@ -1653,8 +1667,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { if (Base.isSimple()) { llvm::Constant *CV = GenerateConstantVector(getLLVMContext(), Indices); - return LValue::MakeExtVectorElt(Base.getAddress(), CV, - Base.getVRQualifiers()); + return LValue::MakeExtVectorElt(Base.getAddress(), CV, type); } assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!"); @@ -1668,8 +1681,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) { CElts.push_back(cast<llvm::Constant>(BaseElts->getOperand(Indices[i]))); } llvm::Constant *CV = llvm::ConstantVector::get(CElts); - return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV, - Base.getVRQualifiers()); + return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV, type); } LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { @@ -1720,7 +1732,7 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value *BaseValue, CGM.getTypes().getCGRecordLayout(Field->getParent()); const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field); return LValue::MakeBitfield(BaseValue, Info, - Field->getType().getCVRQualifiers()|CVRQualifiers); + Field->getType().withCVRQualifiers(CVRQualifiers)); } /// EmitLValueForAnonRecordField - Given that the field is a member of diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 6d34499f38..c1ead814b9 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -136,8 +136,8 @@ public: void VisitVAArgExpr(VAArgExpr *E); - void EmitInitializationToLValue(Expr *E, LValue Address, QualType T); - void EmitNullInitializationToLValue(LValue Address, QualType T); + void EmitInitializationToLValue(Expr *E, LValue Address); + void EmitNullInitializationToLValue(LValue Address); // case Expr::ChooseExprClass: void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); } }; @@ -271,8 +271,8 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { QualType PtrTy = CGF.getContext().getPointerType(Ty); llvm::Value *CastPtr = Builder.CreateBitCast(Dest.getAddr(), CGF.ConvertType(PtrTy)); - EmitInitializationToLValue(E->getSubExpr(), CGF.MakeAddrLValue(CastPtr, Ty), - Ty); + EmitInitializationToLValue(E->getSubExpr(), + CGF.MakeAddrLValue(CastPtr, Ty)); break; } @@ -521,13 +521,13 @@ void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) { void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { QualType T = E->getType(); AggValueSlot Slot = EnsureSlot(T); - EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T), T); + EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T)); } void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { QualType T = E->getType(); AggValueSlot Slot = EnsureSlot(T); - EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T), T); + EmitNullInitializationToLValue(CGF.MakeAddrLValue(Slot.getAddr(), T)); } /// isSimpleZero - If emitting this value will obviously just cause a store of @@ -559,46 +559,46 @@ static bool isSimpleZero(const Expr *E, CodeGenFunction &CGF) { void -AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV, QualType T) { +AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) { + QualType type = LV.getType(); // FIXME: Ignore result? // FIXME: Are initializers affected by volatile? if (Dest.isZeroed() && isSimpleZero(E, CGF)) { // Storing "i32 0" to a zero'd memory location is a noop. } else if (isa<ImplicitValueInitExpr>(E)) { - EmitNullInitializationToLValue(LV, T); - } else if (T->isReferenceType()) { + EmitNullInitializationToLValue(LV); + } else if (type->isReferenceType()) { RValue RV = CGF.EmitReferenceBindingToExpr(E, /*InitializedDecl=*/0); - CGF.EmitStoreThroughLValue(RV, LV, T); - } else if (T->isAnyComplexType()) { + CGF.EmitStoreThroughLValue(RV, LV, type); + } else if (type->isAnyComplexType()) { CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false); - } else if (CGF.hasAggregateLLVMType(T)) { - CGF.EmitAggExpr(E, AggValueSlot::forAddr(LV.getAddress(), - T.getQualifiers(), true, - false, Dest.isZeroed())); + } else if (CGF.hasAggregateLLVMType(type)) { + CGF.EmitAggExpr(E, AggValueSlot::forLValue(LV, true, false, + Dest.isZeroed())); } else if (LV.isSimple()) { - CGF.EmitScalarInit(E, /*D=*/0, LV.getAddress(), /*Captured=*/false, - LV.isVolatileQualified(), LV.getAlignment(), - T); + CGF.EmitScalarInit(E, /*D=*/0, LV, /*Captured=*/false); } else { - CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV, T); + CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV, type); } } -void AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) { +void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) { + QualType type = lv.getType(); + // If the destination slot is already zeroed out before the aggregate is // copied into it, we don't have to emit any zeros here. - if (Dest.isZeroed() && CGF.getTypes().isZeroInitializable(T)) + if (Dest.isZeroed() && CGF.getTypes().isZeroInitializable(type)) return; - if (!CGF.hasAggregateLLVMType(T)) { + if (!CGF.hasAggregateLLVMType(type)) { // For non-aggregates, we can store zero - llvm::Value *Null = llvm::Constant::getNullValue(CGF.ConvertType(T)); - CGF.EmitStoreThroughLValue(RValue::get(Null), LV, T); + llvm::Value *null = llvm::Constant::getNullValue(CGF.ConvertType(type)); + CGF.EmitStoreThroughLValue(RValue::get(null), lv, type); } else { // There's a potential optimization opportunity in combining // memsets; that would be easy for arrays, but relatively // difficult for structures with the current code. - CGF.EmitNullInitialization(LV.getAddress(), T); + CGF.EmitNullInitialization(lv.getAddress(), lv.getType()); } } @@ -667,11 +667,11 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { LValue LV = CGF.MakeAddrLValue(NextVal, ElementType); if (i < NumInitElements) - EmitInitializationToLValue(E->getInit(i), LV, ElementType); + EmitInitializationToLValue(E->getInit(i), LV); else if (Expr *filler = E->getArrayFiller()) - EmitInitializationToLValue(filler, LV, ElementType); + EmitInitializationToLValue(filler, LV); else - EmitNullInitializationToLValue(LV, ElementType); + EmitNullInitializationToLValue(LV); // If the GEP didn't get used because of a dead zero init or something // else, clean it up for -O0 builds and general tidiness. @@ -715,10 +715,10 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0); if (NumInitElements) { // Store the initializer into the field - EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType()); + EmitInitializationToLValue(E->getInit(0), FieldLoc); } else { // Default-initialize to null. - EmitNullInitializationToLValue(FieldLoc, Field->getType()); + EmitNullInitializationToLValue(FieldLoc); } return; @@ -749,11 +749,10 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { if (CurInitVal < NumInitElements) { // Store the initializer into the field. - EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc, - Field->getType()); + EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc); } else { // We're out of initalizers; default-initialize to null - EmitNullInitializationToLValue(FieldLoc, Field->getType()); + EmitNullInitializationToLValue(FieldLoc); } // If the GEP didn't get used because of a dead zero init or something diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 434ca1b69f..2e68f8f960 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -707,9 +707,9 @@ static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const CXXNewExpr *E, unsigned Alignment = CGF.getContext().getTypeAlignInChars(AllocType).getQuantity(); - if (!CGF.hasAggregateLLVMType(AllocType)) - CGF.EmitScalarInit(Init, 0, NewPtr, false, AllocType.isVolatileQualified(), - Alignment, AllocType); + if (!CGF.hasAggregateLLVMType(AllocType)) + CGF.EmitScalarInit(Init, 0, CGF.MakeAddrLValue(NewPtr, AllocType, Alignment), + false); else if (AllocType->isAnyComplexType()) CGF.EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified()); diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp index 21150f1f84..a2c3ea591e 100644 --- a/lib/CodeGen/CGObjCRuntime.cpp +++ b/lib/CodeGen/CGObjCRuntime.cpp @@ -134,7 +134,7 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, ContainingTypeSize, ContainingTypeAlign)); return LValue::MakeBitfield(V, *Info, - IvarTy.getCVRQualifiers() | CVRQualifiers); + IvarTy.withCVRQualifiers(CVRQualifiers)); } namespace { diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index 1ad6628ec6..4d0b8410e4 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -126,6 +126,8 @@ class LValue { const ObjCPropertyRefExpr *PropertyRefExpr; }; + QualType Type; + // 'const' is unused here Qualifiers Quals; @@ -154,8 +156,9 @@ class LValue { llvm::MDNode *TBAAInfo; private: - void Initialize(Qualifiers Quals, unsigned Alignment = 0, + void Initialize(QualType Type, Qualifiers Quals, unsigned Alignment = 0, llvm::MDNode *TBAAInfo = 0) { + this->Type = Type; this->Quals = Quals; this->Alignment = Alignment; assert(this->Alignment == Alignment && "Alignment exceeds allowed max!"); @@ -180,6 +183,12 @@ public: return Quals.getCVRQualifiers() & ~Qualifiers::Const; } + QualType getType() const { return Type; } + + Qualifiers::ObjCLifetime getObjCLifetime() const { + return Quals.getObjCLifetime(); + } + bool isObjCIvar() const { return Ivar; } void setObjCIvar(bool Value) { Ivar = Value; } @@ -201,6 +210,10 @@ public: bool isObjCStrong() const { return Quals.getObjCGCAttr() == Qualifiers::Strong; } + + bool isVolatile() const { + return Quals.hasVolatile(); + } Expr *getBaseIvarExp() const { return BaseIvarExp; } void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } @@ -217,6 +230,10 @@ public: // simple lvalue llvm::Value *getAddress() const { assert(isSimple()); return V; } + void setAddress(llvm::Value *address) { + assert(isSimple()); + V = address; + } // vector elt lvalue llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; } @@ -249,36 +266,36 @@ public: return PropertyRefExpr; } - static LValue MakeAddr(llvm::Value *V, QualType T, unsigned Alignment, - ASTContext &Context, + static LValue MakeAddr(llvm::Value *address, QualType type, + unsigned alignment, ASTContext &Context, llvm::MDNode *TBAAInfo = 0) { - Qualifiers Quals = T.getQualifiers(); - Quals.setObjCGCAttr(Context.getObjCGCAttrKind(T)); + Qualifiers qs = type.getQualifiers(); + qs.setObjCGCAttr(Context.getObjCGCAttrKind(type)); LValue R; R.LVType = Simple; - R.V = V; - R.Initialize(Quals, Alignment, TBAAInfo); + R.V = address; + R.Initialize(type, qs, alignment, TBAAInfo); return R; } static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx, - unsigned CVR) { + QualType type) { LValue R; R.LVType = VectorElt; R.V = Vec; R.VectorIdx = Idx; - R.Initialize(Qualifiers::fromCVRMask(CVR)); + R.Initialize(type, type.getQualifiers()); return R; } static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts, - unsigned CVR) { + QualType type) { LValue R; R.LVType = ExtVectorElt; R.V = Vec; R.VectorElts = Elts; - R.Initialize(Qualifiers::fromCVRMask(CVR)); + R.Initialize(type, type.getQualifiers()); return R; } @@ -288,13 +305,14 @@ public: /// bit-field. /// \param Info - The information describing how to perform the bit-field /// access. - static LValue MakeBitfield(llvm::Value *BaseValue, const CGBitFieldInfo &Info, - unsigned CVR) { + static LValue MakeBitfield(llvm::Value *BaseValue, + const CGBitFieldInfo &Info, + QualType type) { LValue R; R.LVType = BitField; R.V = BaseValue; R.BitFieldInfo = &Info; - R.Initialize(Qualifiers::fromCVRMask(CVR)); + R.Initialize(type, type.getQualifiers()); return R; } @@ -307,7 +325,7 @@ public: R.LVType = PropertyRef; R.V = Base; R.PropertyRefExpr = E; - R.Initialize(Qualifiers()); + R.Initialize(QualType(), Qualifiers()); return R; } }; @@ -367,9 +385,10 @@ public: } static AggValueSlot forLValue(LValue LV, bool LifetimeExternallyManaged, - bool RequiresGCollection = false) { + bool RequiresGCollection = false, + bool IsZeroed = false) { return forAddr(LV.getAddress(), LV.getQuals(), - LifetimeExternallyManaged, RequiresGCollection); + LifetimeExternallyManaged, RequiresGCollection, IsZeroed); } bool isLifetimeExternallyManaged() const { diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index f35022810f..dec7736bdc 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1397,8 +1397,7 @@ public: /// EmitExprAsInit - Emits the code necessary to initialize a /// location in memory with the given initializer. void EmitExprAsInit(const Expr *init, const ValueDecl *D, - llvm::Value *loc, CharUnits alignment, - bool capturedByInit); + LValue lvalue, bool capturedByInit); /// EmitAggregateCopy - Emit an aggrate copy. /// @@ -1597,8 +1596,7 @@ public: void EmitVarDecl(const VarDecl &D); void EmitScalarInit(const Expr *init, const ValueDecl *D, - llvm::Value *addr, bool capturedByInit, - bool isVolatile, unsigned alignment, QualType type); + LValue lvalue, bool capturedByInit); typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D, llvm::Value *Address); @@ -1791,6 +1789,7 @@ public: llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, llvm::MDNode *TBAAInfo = 0); + llvm::Value *EmitLoadOfScalar(LValue lvalue); /// EmitStoreOfScalar - Store a scalar value to an address, taking /// care to appropriately convert from the memory representation to @@ -1798,6 +1797,7 @@ public: void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, llvm::MDNode *TBAAInfo = 0); + void EmitStoreOfScalar(llvm::Value *value, LValue lvalue); /// EmitLoadOfLValue - Given an expression that represents a value lvalue, /// this method emits the address of the lvalue, then loads the result as an |