Restore correct use of GC barriers.

llvm-svn: 133144
This commit is contained in:
John McCall 2011-06-16 04:16:24 +00:00
parent 30f3210242
commit 1553b19067
12 changed files with 188 additions and 133 deletions

View File

@ -641,6 +641,10 @@ public:
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!");

View File

@ -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);
}

View File

@ -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);

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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

View File

@ -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

View File

@ -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());

View File

@ -134,7 +134,7 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
ContainingTypeSize, ContainingTypeAlign));
return LValue::MakeBitfield(V, *Info,
IvarTy.getCVRQualifiers() | CVRQualifiers);
IvarTy.withCVRQualifiers(CVRQualifiers));
}
namespace {

View File

@ -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 {

View File

@ -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

View File

@ -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
}