[cfe-commits] r133144 - in /cfe/trunk: include/clang/AST/Type.h lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGClass.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CGObjCRuntime.cpp lib/CodeGen/CGValue.h lib/CodeGen/CodeGenFunction.h test/CodeGenObjCXX/gc.mm
John McCall
rjmccall at apple.com
Wed Jun 15 21:16:24 PDT 2011
Author: rjmccall
Date: Wed Jun 15 23:16:24 2011
New Revision: 133144
URL: http://llvm.org/viewvc/llvm-project?rev=133144&view=rev
Log:
Restore correct use of GC barriers.
Added:
cfe/trunk/test/CodeGenObjCXX/gc.mm
Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/lib/CodeGen/CGBlocks.cpp
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprAgg.cpp
cfe/trunk/lib/CodeGen/CGExprCXX.cpp
cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
cfe/trunk/lib/CodeGen/CGValue.h
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Jun 15 23:16:24 2011
@@ -641,6 +641,10 @@
return withFastQualifiers(Qualifiers::Volatile);
}
+ QualType withCVRQualifiers(unsigned CVR) const {
+ return withFastQualifiers(CVR);
+ }
+
void addFastQualifiers(unsigned TQs) {
assert(!(TQs & ~Qualifiers::FastMask)
&& "non-fast qualifier bits set in mask!");
Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Wed Jun 15 23:16:24 2011
@@ -618,8 +618,11 @@
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);
}
Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed Jun 15 23:16:24 2011
@@ -430,10 +430,8 @@
}
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 @@
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);
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Wed Jun 15 23:16:24 2011
@@ -453,16 +453,23 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
/// 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));
}
}
Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Wed Jun 15 23:16:24 2011
@@ -27,29 +27,26 @@
"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));
}
}
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Jun 15 23:16:24 2011
@@ -313,9 +313,10 @@
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 @@
}
}
+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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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
Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Wed Jun 15 23:16:24 2011
@@ -136,8 +136,8 @@
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 @@
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::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 @@
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 @@
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 @@
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 @@
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
Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Wed Jun 15 23:16:24 2011
@@ -707,9 +707,9 @@
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());
Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp Wed Jun 15 23:16:24 2011
@@ -134,7 +134,7 @@
ContainingTypeSize, ContainingTypeAlign));
return LValue::MakeBitfield(V, *Info,
- IvarTy.getCVRQualifiers() | CVRQualifiers);
+ IvarTy.withCVRQualifiers(CVRQualifiers));
}
namespace {
Modified: cfe/trunk/lib/CodeGen/CGValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGValue.h?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGValue.h (original)
+++ cfe/trunk/lib/CodeGen/CGValue.h Wed Jun 15 23:16:24 2011
@@ -126,6 +126,8 @@
const ObjCPropertyRefExpr *PropertyRefExpr;
};
+ QualType Type;
+
// 'const' is unused here
Qualifiers Quals;
@@ -154,8 +156,9 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
/// 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 @@
R.LVType = PropertyRef;
R.V = Base;
R.PropertyRefExpr = E;
- R.Initialize(Qualifiers());
+ R.Initialize(QualType(), Qualifiers());
return R;
}
};
@@ -367,9 +385,10 @@
}
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 {
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=133144&r1=133143&r2=133144&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Jun 15 23:16:24 2011
@@ -1397,8 +1397,7 @@
/// 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 @@
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 @@
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 @@
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
Added: cfe/trunk/test/CodeGenObjCXX/gc.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/gc.mm?rev=133144&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/gc.mm (added)
+++ cfe/trunk/test/CodeGenObjCXX/gc.mm Wed Jun 15 23:16:24 2011
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fobjc-gc -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+namespace test0 {
+ extern id x;
+
+ struct A {
+ id x;
+ A();
+ };
+ A::A() : x(test0::x) {}
+
+// CHECK: define void @_ZN5test01AC2Ev(
+// CHECK: [[THIS:%.*]] = alloca [[TEST0:%.*]]*, align 8
+// CHECK-NEXT: store
+// CHECK-NEXT: [[T0:%.*]] = load [[TEST0]]** [[THIS]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[TEST0]]* [[T0]], i32 0, i32 0
+// CHECK-NEXT: [[T2:%.*]] = load i8** @_ZN5test01xE
+// CHECK-NEXT: call i8* @objc_assign_strongCast(i8* [[T2]], i8** [[T1]])
+// CHECK-NEXT: ret void
+}
More information about the cfe-commits
mailing list