summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp19
-rw-r--r--clang/lib/CodeGen/CGObjCGNU.cpp16
-rw-r--r--clang/lib/CodeGen/CGObjCMac.cpp26
-rw-r--r--clang/lib/CodeGen/CGObjCRuntime.h4
-rw-r--r--clang/lib/CodeGen/CGValue.h27
5 files changed, 76 insertions, 16 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 98a54c6863f..95733abbab4 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -151,7 +151,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
/// this method emits the address of the lvalue, then loads the result as an
/// rvalue, returning the rvalue.
RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
- if (LV.isObjcWeak()) {
+ if (LV.ObjcWeak()) {
// load of a __weak object.
llvm::Value *AddrWeakObj = LV.getAddress();
llvm::Value *read_weak = CGM.getObjCRuntime().EmitObjCWeakRead(*this,
@@ -335,7 +335,7 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
/// is 'Ty'.
void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
QualType Ty) {
- if (Dst.isObjcWeak()) {
+ if (Dst.ObjcWeak()) {
// load of a __weak object.
llvm::Value *LvalueDst = Dst.getAddress();
llvm::Value *src = Src.getScalarVal();
@@ -343,6 +343,14 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
return;
}
+ if (Dst.ObjcStrong()) {
+ // load of a __strong object.
+ llvm::Value *LvalueDst = Dst.getAddress();
+ llvm::Value *src = Src.getScalarVal();
+ CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst);
+ return;
+ }
+
if (!Dst.isSimple()) {
if (Dst.isVectorElt()) {
// Read/modify/write the vector, inserting the new element.
@@ -510,10 +518,9 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
} else if (VD && VD->isFileVarDecl()) {
LValue LV = LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD),
E->getType().getCVRQualifiers());
- if (VD->getAttr<ObjCGCAttr>())
- {
- ObjCGCAttr::GCAttrTypes attrType = (VD->getAttr<ObjCGCAttr>())->getType();
- LValue::SetObjCGCAttrs(attrType == ObjCGCAttr::Weak, attrType == ObjCGCAttr::Strong, LV);
+ if (const ObjCGCAttr *A = VD->getAttr<ObjCGCAttr>()) {
+ ObjCGCAttr::GCAttrTypes attrType = A->getType();
+ LValue::SetObjCType(attrType == ObjCGCAttr::Weak, attrType == ObjCGCAttr::Strong, LV);
}
return LV;
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index 91b8587e1af..7adbd4a8e75 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -134,6 +134,10 @@ public:
llvm::Value *AddrWeakObj);
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dst);
+ virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *src, llvm::Value *dest);
+ virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *src, llvm::Value *dest);
};
} // end anonymous namespace
@@ -984,6 +988,18 @@ void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
return;
}
+void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *src, llvm::Value *dst)
+{
+ return;
+}
+
+void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *src, llvm::Value *dst)
+{
+ return;
+}
+
CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){
return new CGObjCGNU(CGM);
}
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index e6c2650a2e8..ccfd465c35e 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -458,6 +458,10 @@ public:
llvm::Value *AddrWeakObj);
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dst);
+ virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *src, llvm::Value *dest);
+ virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *src, llvm::Value *dest);
};
} // end anonymous namespace
@@ -1800,6 +1804,28 @@ void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
return;
}
+/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
+/// objc_assign_global (id src, id *dst)
+///
+void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *src, llvm::Value *dst)
+{
+ CGF.Builder.CreateCall2(ObjCTypes.GcAssignGlobalFn,
+ src, dst, "globalassign");
+ return;
+}
+
+/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
+/// objc_assign_strongCast (id src, id *dst)
+///
+void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *src, llvm::Value *dst)
+{
+ CGF.Builder.CreateCall2(ObjCTypes.GcAssignStrongCastFn,
+ src, dst, "weakassign");
+ return;
+}
+
/// EmitSynchronizedStmt - Code gen for @synchronized(expr) stmt;
/// Effectively generating code for:
/// objc_sync_enter(expr);
diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h
index 24288b1e443..675ff340b64 100644
--- a/clang/lib/CodeGen/CGObjCRuntime.h
+++ b/clang/lib/CodeGen/CGObjCRuntime.h
@@ -149,6 +149,10 @@ public:
llvm::Value *AddrWeakObj) = 0;
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
llvm::Value *src, llvm::Value *dest) = 0;
+ virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *src, llvm::Value *dest) = 0;
+ virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+ llvm::Value *src, llvm::Value *dest) = 0;
};
/// Creates an instance of an Objective-C runtime class.
diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h
index ef2cb033c95..c328e35931d 100644
--- a/clang/lib/CodeGen/CGValue.h
+++ b/clang/lib/CodeGen/CGValue.h
@@ -106,6 +106,12 @@ class LValue {
PropertyRef // This is an Objective-C property reference, use
// getPropertyRefExpr
} LVType;
+
+ enum ObjCType {
+ None = 0, // object with no gc attribute.
+ Weak, // __weak object expression
+ Strong // __strong object expression
+ };
llvm::Value *V;
@@ -130,9 +136,9 @@ class LValue {
bool Volatile:1;
// FIXME: set but never used, what effect should it have?
bool Restrict:1;
-
- bool ObjcWeak:1;
- bool ObjcStrong:1;
+
+ // objective-c's gc attributes
+ unsigned ObjCType : 2;
private:
static void SetQualifiers(unsigned Qualifiers, LValue& R) {
@@ -140,8 +146,7 @@ private:
R.Restrict = (Qualifiers&QualType::Restrict)!=0;
// FIXME: Convenient place to set objc flags to 0. This
// should really be done in a user-defined constructor instead.
- R.ObjcWeak = 0;
- R.ObjcStrong = 0;
+ R.ObjCType = None;
}
public:
@@ -154,12 +159,14 @@ public:
bool isVolatileQualified() const { return Volatile; }
bool isRestrictQualified() const { return Restrict; }
- bool isObjcWeak() const { return ObjcWeak; }
- bool isObjcStrong() const { return ObjcStrong; }
+ bool ObjcWeak() const { return ObjCType == Weak; }
+ bool ObjcStrong() const { return ObjCType == Strong; }
- static void SetObjCGCAttrs(unsigned Weak, unsigned Strong, LValue& R) {
- R.ObjcWeak = Weak;
- R.ObjcStrong = Strong;
+ static void SetObjCType(unsigned WeakVal, unsigned StrongVal, LValue& R) {
+ if (WeakVal)
+ R.ObjCType = Weak;
+ else if (StrongVal)
+ R.ObjCType = Strong;
}
// simple lvalue
OpenPOWER on IntegriCloud