forked from OSchip/llvm-project
Miscellanous fixes in generatation of objc gc's write-barriers.
llvm-svn: 82472
This commit is contained in:
parent
cf13782fab
commit
38c3ae9bc4
|
@ -697,7 +697,7 @@ void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) {
|
|||
|
||||
if (isa<ObjCIvarRefExpr>(E)) {
|
||||
LV.SetObjCIvar(LV, true);
|
||||
LV.SetObjCIvarArray(LV, E->getType()->isArrayType());
|
||||
LV.SetObjCArray(LV, E->getType()->isArrayType());
|
||||
return;
|
||||
}
|
||||
if (const DeclRefExpr *Exp = dyn_cast<DeclRefExpr>(E)) {
|
||||
|
@ -706,6 +706,7 @@ void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) {
|
|||
VD->isFileVarDecl())
|
||||
LV.SetGlobalObjCRef(LV, true);
|
||||
}
|
||||
LV.SetObjCArray(LV, E->getType()->isArrayType());
|
||||
}
|
||||
else if (const UnaryOperator *Exp = dyn_cast<UnaryOperator>(E))
|
||||
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
|
||||
|
@ -717,17 +718,20 @@ void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) {
|
|||
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
|
||||
else if (const ArraySubscriptExpr *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
|
||||
setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
|
||||
if (LV.isObjCIvar() && !LV.isObjCIvarArray()) {
|
||||
if (LV.isObjCIvar() && !LV.isObjCArray())
|
||||
// Using array syntax to assigning to what an ivar points to is not
|
||||
// same as assigning to the ivar itself. {id *Names;} Names[i] = 0;
|
||||
LV.SetObjCIvar(LV, false);
|
||||
}
|
||||
else if (LV.isGlobalObjCRef() && !LV.isObjCArray())
|
||||
// Using array syntax to assigning to what global points to is not
|
||||
// same as assigning to the global itself. {id *G;} G[i] = 0;
|
||||
LV.SetGlobalObjCRef(LV, false);
|
||||
}
|
||||
else if (const MemberExpr *Exp = dyn_cast<MemberExpr>(E)) {
|
||||
setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
|
||||
// We don't know if member is an 'ivar', but this flag is looked at
|
||||
// only in the context of LV.isObjCIvar().
|
||||
LV.SetObjCIvarArray(LV, E->getType()->isArrayType());
|
||||
LV.SetObjCArray(LV, E->getType()->isArrayType());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1130,19 +1134,11 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
|
|||
}
|
||||
if (Field->getType()->isReferenceType())
|
||||
V = Builder.CreateLoad(V, "tmp");
|
||||
|
||||
QualType::GCAttrTypes attr = QualType::GCNone;
|
||||
if (CGM.getLangOptions().ObjC1 &&
|
||||
CGM.getLangOptions().getGCMode() != LangOptions::NonGC) {
|
||||
QualType Ty = Field->getType();
|
||||
attr = Ty.getObjCGCAttr();
|
||||
if (attr != QualType::GCNone) {
|
||||
// __weak attribute on a field is ignored.
|
||||
if (attr == QualType::Weak)
|
||||
attr = QualType::GCNone;
|
||||
} else if (Ty->isObjCObjectPointerType())
|
||||
attr = QualType::Strong;
|
||||
}
|
||||
QualType::GCAttrTypes attr = getContext().getObjCGCAttrKind(Field->getType());
|
||||
// __weak attribute on a field is ignored.
|
||||
if (attr == QualType::Weak)
|
||||
attr = QualType::GCNone;
|
||||
|
||||
LValue LV =
|
||||
LValue::MakeAddr(V,
|
||||
Field->getType().getCVRQualifiers()|CVRQualifiers,
|
||||
|
|
|
@ -154,7 +154,7 @@ class LValue {
|
|||
bool Ivar:1;
|
||||
|
||||
// objective-c's ivar is an array
|
||||
bool IvarArray:1;
|
||||
bool ObjIsArray:1;
|
||||
|
||||
// LValue is non-gc'able for any reason, including being a parameter or local
|
||||
// variable.
|
||||
|
@ -176,7 +176,7 @@ private:
|
|||
// FIXME: Convenient place to set objc flags to 0. This should really be
|
||||
// done in a user-defined constructor instead.
|
||||
R.ObjCType = None;
|
||||
R.Ivar = R.IvarArray = R.NonGC = R.GlobalObjCRef = false;
|
||||
R.Ivar = R.ObjIsArray = R.NonGC = R.GlobalObjCRef = false;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -195,7 +195,7 @@ public:
|
|||
}
|
||||
|
||||
bool isObjCIvar() const { return Ivar; }
|
||||
bool isObjCIvarArray() const { return IvarArray; }
|
||||
bool isObjCArray() const { return ObjIsArray; }
|
||||
bool isNonGC () const { return NonGC; }
|
||||
bool isGlobalObjCRef() const { return GlobalObjCRef; }
|
||||
bool isObjCWeak() const { return ObjCType == Weak; }
|
||||
|
@ -206,8 +206,8 @@ public:
|
|||
static void SetObjCIvar(LValue& R, bool iValue) {
|
||||
R.Ivar = iValue;
|
||||
}
|
||||
static void SetObjCIvarArray(LValue& R, bool iValue) {
|
||||
R.IvarArray = iValue;
|
||||
static void SetObjCArray(LValue& R, bool iValue) {
|
||||
R.ObjIsArray = iValue;
|
||||
}
|
||||
static void SetGlobalObjCRef(LValue& R, bool iValue) {
|
||||
R.GlobalObjCRef = iValue;
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// RUN: clang-cc -triple x86_64-apple-darwin10 -fblocks -fnext-runtime -fobjc-gc -fobjc-newgc-api -emit-llvm -o %t %s &&
|
||||
// RUN: grep -F '@objc_assign_strongCast' %t | count 4 &&
|
||||
// RUN: true
|
||||
|
||||
@interface DSATextSearch @end
|
||||
|
||||
DSATextSearch **_uniqueIdToIdentifierArray = ((void *)0);
|
||||
void foo (int _nextId)
|
||||
{
|
||||
_uniqueIdToIdentifierArray[_nextId] = 0; // objc_assign_strongCast
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
unsigned long state;
|
||||
id *itemsPtr;
|
||||
void (^bp)();
|
||||
unsigned long *mutationsPtr;
|
||||
unsigned long extra[5];
|
||||
} NSFastEnumerationState;
|
||||
|
||||
void foo1 (NSFastEnumerationState * state)
|
||||
{
|
||||
state->itemsPtr = 0;
|
||||
state->bp = ^{};
|
||||
}
|
||||
|
Loading…
Reference in New Issue