From f5125d19e7b466a76a5471286ad2e3d038f8cf86 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 18 Nov 2008 21:45:40 +0000 Subject: [PATCH] Generate objc_read_weak for __weak objc loads. llvm-svn: 59553 --- clang/lib/CodeGen/CGExpr.cpp | 8 ++++++++ clang/lib/CodeGen/CGObjCGNU.cpp | 8 ++++++++ clang/lib/CodeGen/CGObjCMac.cpp | 14 +++++++++++++- clang/lib/CodeGen/CGObjCRuntime.h | 2 ++ clang/lib/CodeGen/CGValue.h | 4 ++++ 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 993562592b65..d537c9ca8137 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -151,6 +151,14 @@ 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()) { + // load of a __weak object. + llvm::Value *AddrWeakObj = LV.getAddress(); + llvm::Value *read_weak = CGM.getObjCRuntime().EmitObjCWeakCall(*this, + AddrWeakObj); + return RValue::get(read_weak); + } + if (LV.isSimple()) { llvm::Value *Ptr = LV.getAddress(); const llvm::Type *EltTy = diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 0833b0832d74..d57710c5e519 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -130,6 +130,8 @@ public: const ObjCAtThrowStmt &S); virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S); + virtual llvm::Value * EmitObjCWeakCall(CodeGen::CodeGenFunction &CGF, + llvm::Value *AddrWeakObj); }; } // end anonymous namespace @@ -968,6 +970,12 @@ void CGObjCGNU::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, CGF.ErrorUnsupported(&S, "@synchronized statement"); } +llvm::Value * CGObjCGNU::EmitObjCWeakCall(CodeGen::CodeGenFunction &CGF, + llvm::Value *AddrWeakObj) +{ + return 0; +} + 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 159183145857..f3cf21eb314b 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -454,7 +454,8 @@ public: const ObjCAtThrowStmt &S); virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S); - + virtual llvm::Value * EmitObjCWeakCall(CodeGen::CodeGenFunction &CGF, + llvm::Value *AddrWeakObj); }; } // end anonymous namespace @@ -1775,6 +1776,17 @@ void CodeGenFunction::EmitJumpThroughFinally(ObjCEHEntry *E, EmitBranch(ExecuteTryExit ? E->FinallyBlock : E->FinallyNoExit); } +/// EmitObjCWeakCall - Code gen for loading value of a __weak +/// object: objc_read_weak (id *src) +/// +llvm::Value * CGObjCMac::EmitObjCWeakCall(CodeGen::CodeGenFunction &CGF, + llvm::Value *AddrWeakObj) +{ + llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.GcReadWeakFn, + AddrWeakObj, "weakobj"); + return read_weak; +} + /// 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 435e1483e386..37544e47e1bc 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.h +++ b/clang/lib/CodeGen/CGObjCRuntime.h @@ -145,6 +145,8 @@ public: const ObjCAtThrowStmt &S) = 0; virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtSynchronizedStmt &S) = 0; + virtual llvm::Value * EmitObjCWeakCall(CodeGen::CodeGenFunction &CGF, + llvm::Value *AddrWeakObj) = 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 505381eb41a2..ef2cb033c95a 100644 --- a/clang/lib/CodeGen/CGValue.h +++ b/clang/lib/CodeGen/CGValue.h @@ -138,6 +138,10 @@ private: static void SetQualifiers(unsigned Qualifiers, LValue& R) { R.Volatile = (Qualifiers&QualType::Volatile)!=0; 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; } public: