From 32ff7aeefa9b1d2b0cc8046d5fd51ac6ce154215 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 4 May 2009 23:27:20 +0000 Subject: [PATCH] Provide basic support for generation of objc2's objc_assign_global API when assigning to global objective-c object pointer. llvm-svn: 70939 --- clang/lib/CodeGen/CGExpr.cpp | 7 ++++++- clang/lib/CodeGen/CGValue.h | 11 ++++++++++- clang/test/CodeGenObjC/objc2-assign-global.m | 8 ++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGenObjC/objc2-assign-global.m diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 2bcb362f186a..74d736490a24 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -442,7 +442,10 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, else CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst); #endif - CGM.getObjCRuntime().EmitObjCStrongCastAssign(*this, src, LvalueDst); + if (Dst.isGlobalObjCRef()) + CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst); + else + CGM.getObjCRuntime().EmitObjCStrongCastAssign(*this, src, LvalueDst); return; } @@ -666,6 +669,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { LValue LV = LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD), E->getType().getCVRQualifiers(), getContext().getObjCGCAttrKind(E->getType())); + if (LV.isObjCStrong()) + LV.SetGlobalObjCRef(LV, true); return LV; } else if (const FunctionDecl *FD = dyn_cast(E->getDecl())) { return LValue::MakeAddr(CGM.GetAddrOfFunction(FD), diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h index 66cb0037a136..5204c451666f 100644 --- a/clang/lib/CodeGen/CGValue.h +++ b/clang/lib/CodeGen/CGValue.h @@ -149,8 +149,12 @@ class LValue { // variable. bool NonGC: 1; + // Lvalue is a global reference of an objective-c object + bool GlobalObjCRef : 1; + // objective-c's gc attributes unsigned ObjCType : 2; + private: @@ -160,7 +164,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.NonGC = false; + R.Ivar = R.NonGC = R.GlobalObjCRef = false; } public: @@ -180,12 +184,17 @@ public: bool isObjCIvar() const { return Ivar; } bool isNonGC () const { return NonGC; } + bool isGlobalObjCRef() const { return GlobalObjCRef; } bool isObjCWeak() const { return ObjCType == Weak; } bool isObjCStrong() const { return ObjCType == Strong; } static void SetObjCIvar(LValue& R, bool iValue) { R.Ivar = iValue; } + + static void SetGlobalObjCRef(LValue& R, bool iValue) { + R.GlobalObjCRef = iValue; + } static void SetObjCNonGC(LValue& R, bool iValue) { R.NonGC = iValue; diff --git a/clang/test/CodeGenObjC/objc2-assign-global.m b/clang/test/CodeGenObjC/objc2-assign-global.m new file mode 100644 index 000000000000..ae407619093e --- /dev/null +++ b/clang/test/CodeGenObjC/objc2-assign-global.m @@ -0,0 +1,8 @@ +// RUN: clang-cc -fnext-runtime -fobjc-gc -emit-llvm -o %t %s && +// RUN: grep -F '@objc_assign_global' %t | count 2 && +// RUN: true +id a; +int main() { + a = 0; +} +